Source Code Cross Referenced for JDKPKCS12KeyStore.java in  » Security » Bouncy-Castle » org » bouncycastle » jce » provider » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » Bouncy Castle » org.bouncycastle.jce.provider 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.bouncycastle.jce.provider;
0002:
0003:        import org.bouncycastle.asn1.ASN1EncodableVector;
0004:        import org.bouncycastle.asn1.ASN1InputStream;
0005:        import org.bouncycastle.asn1.ASN1Object;
0006:        import org.bouncycastle.asn1.ASN1OctetString;
0007:        import org.bouncycastle.asn1.ASN1Sequence;
0008:        import org.bouncycastle.asn1.ASN1Set;
0009:        import org.bouncycastle.asn1.BERConstructedOctetString;
0010:        import org.bouncycastle.asn1.BEROutputStream;
0011:        import org.bouncycastle.asn1.DERBMPString;
0012:        import org.bouncycastle.asn1.DERNull;
0013:        import org.bouncycastle.asn1.DERObject;
0014:        import org.bouncycastle.asn1.DERObjectIdentifier;
0015:        import org.bouncycastle.asn1.DEROctetString;
0016:        import org.bouncycastle.asn1.DERSequence;
0017:        import org.bouncycastle.asn1.DERSet;
0018:        import org.bouncycastle.asn1.pkcs.AuthenticatedSafe;
0019:        import org.bouncycastle.asn1.pkcs.CertBag;
0020:        import org.bouncycastle.asn1.pkcs.ContentInfo;
0021:        import org.bouncycastle.asn1.pkcs.EncryptedData;
0022:        import org.bouncycastle.asn1.pkcs.MacData;
0023:        import org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
0024:        import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
0025:        import org.bouncycastle.asn1.pkcs.Pfx;
0026:        import org.bouncycastle.asn1.pkcs.SafeBag;
0027:        import org.bouncycastle.asn1.util.ASN1Dump;
0028:        import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
0029:        import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
0030:        import org.bouncycastle.asn1.x509.DigestInfo;
0031:        import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
0032:        import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
0033:        import org.bouncycastle.asn1.x509.X509Extensions;
0034:        import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
0035:        import org.bouncycastle.jce.interfaces.BCKeyStore;
0036:        import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
0037:        import org.bouncycastle.util.Arrays;
0038:        import org.bouncycastle.util.Strings;
0039:        import org.bouncycastle.util.encoders.Hex;
0040:
0041:        import java.io.BufferedInputStream;
0042:        import java.io.ByteArrayInputStream;
0043:        import java.io.ByteArrayOutputStream;
0044:        import java.io.IOException;
0045:        import java.io.InputStream;
0046:        import java.io.OutputStream;
0047:        import java.security.Key;
0048:        import java.security.KeyStoreException;
0049:        import java.security.KeyStoreSpi;
0050:        import java.security.NoSuchAlgorithmException;
0051:        import java.security.Principal;
0052:        import java.security.PrivateKey;
0053:        import java.security.PublicKey;
0054:        import java.security.SecureRandom;
0055:        import java.security.UnrecoverableKeyException;
0056:        import java.security.cert.Certificate;
0057:        import java.security.cert.CertificateEncodingException;
0058:        import java.security.cert.CertificateFactory;
0059:        import java.security.cert.X509Certificate;
0060:        import java.util.Date;
0061:        import java.util.Enumeration;
0062:        import java.util.Hashtable;
0063:        import java.util.Vector;
0064:
0065:        import javax.crypto.Cipher;
0066:        import javax.crypto.Mac;
0067:        import javax.crypto.SecretKey;
0068:        import javax.crypto.SecretKeyFactory;
0069:        import javax.crypto.spec.PBEKeySpec;
0070:        import javax.crypto.spec.PBEParameterSpec;
0071:
0072:        public class JDKPKCS12KeyStore extends KeyStoreSpi implements 
0073:                PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore {
0074:            private static final int SALT_SIZE = 20;
0075:            private static final int MIN_ITERATIONS = 1024;
0076:
0077:            //
0078:            // SHA-1 and 3-key-triple DES.
0079:            //
0080:            private static final DERObjectIdentifier KEY_ALGORITHM = pbeWithSHAAnd3_KeyTripleDES_CBC;
0081:
0082:            //
0083:            // SHA-1 and 40 bit RC2.
0084:            //
0085:            private static final DERObjectIdentifier CERT_ALGORITHM = pbewithSHAAnd40BitRC2_CBC;
0086:
0087:            private IgnoresCaseHashtable keys = new IgnoresCaseHashtable();
0088:            private Hashtable localIds = new Hashtable();
0089:            private IgnoresCaseHashtable certs = new IgnoresCaseHashtable();
0090:            private Hashtable chainCerts = new Hashtable();
0091:            private Hashtable keyCerts = new Hashtable();
0092:
0093:            //
0094:            // generic object types
0095:            //
0096:            static final int NULL = 0;
0097:            static final int CERTIFICATE = 1;
0098:            static final int KEY = 2;
0099:            static final int SECRET = 3;
0100:            static final int SEALED = 4;
0101:
0102:            //
0103:            // key types
0104:            //
0105:            static final int KEY_PRIVATE = 0;
0106:            static final int KEY_PUBLIC = 1;
0107:            static final int KEY_SECRET = 2;
0108:
0109:            protected SecureRandom random = new SecureRandom();
0110:
0111:            private CertificateFactory certFact = null;
0112:
0113:            private class CertId {
0114:                byte[] id;
0115:
0116:                CertId(PublicKey key) {
0117:                    this .id = createSubjectKeyId(key).getKeyIdentifier();
0118:                }
0119:
0120:                CertId(byte[] id) {
0121:                    this .id = id;
0122:                }
0123:
0124:                public int hashCode() {
0125:                    int hash = id[0] & 0xff;
0126:
0127:                    for (int i = 1; i != id.length - 4; i++) {
0128:                        hash ^= ((id[i] & 0xff) << 24)
0129:                                | ((id[i + 1] & 0xff) << 16)
0130:                                | ((id[i + 2] & 0xff) << 8)
0131:                                | (id[i + 3] & 0xff);
0132:                    }
0133:
0134:                    return hash;
0135:                }
0136:
0137:                public boolean equals(Object o) {
0138:                    if (!(o instanceof  CertId)) {
0139:                        return false;
0140:                    }
0141:
0142:                    CertId cId = (CertId) o;
0143:
0144:                    if (cId.id.length != id.length) {
0145:                        return false;
0146:                    }
0147:
0148:                    for (int i = 0; i != id.length; i++) {
0149:                        if (cId.id[i] != id[i]) {
0150:                            return false;
0151:                        }
0152:                    }
0153:
0154:                    return true;
0155:                }
0156:            }
0157:
0158:            public JDKPKCS12KeyStore(String provider) {
0159:                try {
0160:                    if (provider != null) {
0161:                        certFact = CertificateFactory.getInstance("X.509",
0162:                                provider);
0163:                    } else {
0164:                        certFact = CertificateFactory.getInstance("X.509");
0165:                    }
0166:                } catch (Exception e) {
0167:                    throw new IllegalArgumentException(
0168:                            "can't create cert factory - " + e.toString());
0169:                }
0170:            }
0171:
0172:            private SubjectKeyIdentifier createSubjectKeyId(PublicKey pubKey) {
0173:                try {
0174:                    SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
0175:                            (ASN1Sequence) new ASN1InputStream(pubKey
0176:                                    .getEncoded()).readObject());
0177:
0178:                    return new SubjectKeyIdentifier(info);
0179:                } catch (Exception e) {
0180:                    throw new RuntimeException("error creating key");
0181:                }
0182:            }
0183:
0184:            public void setRandom(SecureRandom rand) {
0185:                this .random = rand;
0186:            }
0187:
0188:            public Enumeration engineAliases() {
0189:                Hashtable tab = new Hashtable();
0190:
0191:                Enumeration e = certs.keys();
0192:                while (e.hasMoreElements()) {
0193:                    tab.put(e.nextElement(), "cert");
0194:                }
0195:
0196:                e = keys.keys();
0197:                while (e.hasMoreElements()) {
0198:                    String a = (String) e.nextElement();
0199:                    if (tab.get(a) == null) {
0200:                        tab.put(a, "key");
0201:                    }
0202:                }
0203:
0204:                return tab.keys();
0205:            }
0206:
0207:            public boolean engineContainsAlias(String alias) {
0208:                return (certs.get(alias) != null || keys.get(alias) != null);
0209:            }
0210:
0211:            /**
0212:             * this is quite complete - we should follow up on the chain, a bit
0213:             * tricky if a certificate appears in more than one chain...
0214:             */
0215:            public void engineDeleteEntry(String alias)
0216:                    throws KeyStoreException {
0217:                Key k = (Key) keys.remove(alias);
0218:
0219:                Certificate c = (Certificate) certs.remove(alias);
0220:
0221:                if (c != null) {
0222:                    chainCerts.remove(new CertId(c.getPublicKey()));
0223:                }
0224:
0225:                if (k != null) {
0226:                    String id = (String) localIds.remove(alias);
0227:                    if (id != null) {
0228:                        c = (Certificate) keyCerts.remove(id);
0229:                    }
0230:                    if (c != null) {
0231:                        chainCerts.remove(new CertId(c.getPublicKey()));
0232:                    }
0233:                }
0234:
0235:                if (c == null && k == null) {
0236:                    throw new KeyStoreException("no such entry as " + alias);
0237:                }
0238:            }
0239:
0240:            /**
0241:             * simply return the cert for the private key
0242:             */
0243:            public Certificate engineGetCertificate(String alias) {
0244:                if (alias == null) {
0245:                    throw new IllegalArgumentException(
0246:                            "null alias passed to getCertificate.");
0247:                }
0248:
0249:                Certificate c = (Certificate) certs.get(alias);
0250:
0251:                //
0252:                // look up the key table - and try the local key id
0253:                //
0254:                if (c == null) {
0255:                    String id = (String) localIds.get(alias);
0256:                    if (id != null) {
0257:                        c = (Certificate) keyCerts.get(id);
0258:                    } else {
0259:                        c = (Certificate) keyCerts.get(alias);
0260:                    }
0261:                }
0262:
0263:                return c;
0264:            }
0265:
0266:            public String engineGetCertificateAlias(Certificate cert) {
0267:                Enumeration c = certs.elements();
0268:                Enumeration k = certs.keys();
0269:
0270:                while (c.hasMoreElements()) {
0271:                    Certificate tc = (Certificate) c.nextElement();
0272:                    String ta = (String) k.nextElement();
0273:
0274:                    if (tc.equals(cert)) {
0275:                        return ta;
0276:                    }
0277:                }
0278:
0279:                c = keyCerts.elements();
0280:                k = keyCerts.keys();
0281:
0282:                while (c.hasMoreElements()) {
0283:                    Certificate tc = (Certificate) c.nextElement();
0284:                    String ta = (String) k.nextElement();
0285:
0286:                    if (tc.equals(cert)) {
0287:                        return ta;
0288:                    }
0289:                }
0290:
0291:                return null;
0292:            }
0293:
0294:            public Certificate[] engineGetCertificateChain(String alias) {
0295:                if (alias == null) {
0296:                    throw new IllegalArgumentException(
0297:                            "null alias passed to getCertificateChain.");
0298:                }
0299:
0300:                if (!engineIsKeyEntry(alias)) {
0301:                    return null;
0302:                }
0303:
0304:                Certificate c = engineGetCertificate(alias);
0305:
0306:                if (c != null) {
0307:                    Vector cs = new Vector();
0308:
0309:                    while (c != null) {
0310:                        X509Certificate x509c = (X509Certificate) c;
0311:                        Certificate nextC = null;
0312:
0313:                        byte[] bytes = x509c
0314:                                .getExtensionValue(X509Extensions.AuthorityKeyIdentifier
0315:                                        .getId());
0316:                        if (bytes != null) {
0317:                            try {
0318:                                ASN1InputStream aIn = new ASN1InputStream(bytes);
0319:
0320:                                byte[] authBytes = ((ASN1OctetString) aIn
0321:                                        .readObject()).getOctets();
0322:                                aIn = new ASN1InputStream(authBytes);
0323:
0324:                                AuthorityKeyIdentifier id = new AuthorityKeyIdentifier(
0325:                                        (ASN1Sequence) aIn.readObject());
0326:                                if (id.getKeyIdentifier() != null) {
0327:                                    nextC = (Certificate) chainCerts
0328:                                            .get(new CertId(id
0329:                                                    .getKeyIdentifier()));
0330:                                }
0331:
0332:                            } catch (IOException e) {
0333:                                throw new RuntimeException(e.toString());
0334:                            }
0335:                        }
0336:
0337:                        if (nextC == null) {
0338:                            //
0339:                            // no authority key id, try the Issuer DN
0340:                            //
0341:                            Principal i = x509c.getIssuerDN();
0342:                            Principal s = x509c.getSubjectDN();
0343:
0344:                            if (!i.equals(s)) {
0345:                                Enumeration e = chainCerts.keys();
0346:
0347:                                while (e.hasMoreElements()) {
0348:                                    X509Certificate crt = (X509Certificate) chainCerts
0349:                                            .get(e.nextElement());
0350:                                    Principal sub = crt.getSubjectDN();
0351:                                    if (sub.equals(i)) {
0352:                                        try {
0353:                                            x509c.verify(crt.getPublicKey());
0354:                                            nextC = crt;
0355:                                            break;
0356:                                        } catch (Exception ex) {
0357:                                            // continue
0358:                                        }
0359:                                    }
0360:                                }
0361:                            }
0362:                        }
0363:
0364:                        cs.addElement(c);
0365:                        if (nextC != c) // self signed - end of the chain
0366:                        {
0367:                            c = nextC;
0368:                        } else {
0369:                            c = null;
0370:                        }
0371:                    }
0372:
0373:                    Certificate[] certChain = new Certificate[cs.size()];
0374:
0375:                    for (int i = 0; i != certChain.length; i++) {
0376:                        certChain[i] = (Certificate) cs.elementAt(i);
0377:                    }
0378:
0379:                    return certChain;
0380:                }
0381:
0382:                return null;
0383:            }
0384:
0385:            public Date engineGetCreationDate(String alias) {
0386:                return new Date();
0387:            }
0388:
0389:            public Key engineGetKey(String alias, char[] password)
0390:                    throws NoSuchAlgorithmException, UnrecoverableKeyException {
0391:                if (alias == null) {
0392:                    throw new IllegalArgumentException(
0393:                            "null alias passed to getKey.");
0394:                }
0395:
0396:                return (Key) keys.get(alias);
0397:            }
0398:
0399:            public boolean engineIsCertificateEntry(String alias) {
0400:                return (certs.get(alias) != null && keys.get(alias) == null);
0401:            }
0402:
0403:            public boolean engineIsKeyEntry(String alias) {
0404:                return (keys.get(alias) != null);
0405:            }
0406:
0407:            public void engineSetCertificateEntry(String alias, Certificate cert)
0408:                    throws KeyStoreException {
0409:                if (keys.get(alias) != null) {
0410:                    throw new KeyStoreException(
0411:                            "There is a key entry with the name " + alias + ".");
0412:                }
0413:
0414:                certs.put(alias, cert);
0415:                chainCerts.put(new CertId(cert.getPublicKey()), cert);
0416:            }
0417:
0418:            public void engineSetKeyEntry(String alias, byte[] key,
0419:                    Certificate[] chain) throws KeyStoreException {
0420:                throw new RuntimeException("operation not supported");
0421:            }
0422:
0423:            public void engineSetKeyEntry(String alias, Key key,
0424:                    char[] password, Certificate[] chain)
0425:                    throws KeyStoreException {
0426:                if ((key instanceof  PrivateKey) && (chain == null)) {
0427:                    throw new KeyStoreException(
0428:                            "no certificate chain for private key");
0429:                }
0430:
0431:                if (keys.get(alias) != null) {
0432:                    engineDeleteEntry(alias);
0433:                }
0434:
0435:                keys.put(alias, key);
0436:                certs.put(alias, chain[0]);
0437:
0438:                for (int i = 0; i != chain.length; i++) {
0439:                    chainCerts.put(new CertId(chain[i].getPublicKey()),
0440:                            chain[i]);
0441:                }
0442:            }
0443:
0444:            public int engineSize() {
0445:                Hashtable tab = new Hashtable();
0446:
0447:                Enumeration e = certs.keys();
0448:                while (e.hasMoreElements()) {
0449:                    tab.put(e.nextElement(), "cert");
0450:                }
0451:
0452:                e = keys.keys();
0453:                while (e.hasMoreElements()) {
0454:                    String a = (String) e.nextElement();
0455:                    if (tab.get(a) == null) {
0456:                        tab.put(a, "key");
0457:                    }
0458:                }
0459:
0460:                return tab.size();
0461:            }
0462:
0463:            protected PrivateKey unwrapKey(AlgorithmIdentifier algId,
0464:                    byte[] data, char[] password, boolean wrongPKCS12Zero)
0465:                    throws IOException {
0466:                String algorithm = algId.getObjectId().getId();
0467:                PKCS12PBEParams pbeParams = new PKCS12PBEParams(
0468:                        (ASN1Sequence) algId.getParameters());
0469:
0470:                PBEKeySpec pbeSpec = new PBEKeySpec(password);
0471:                PrivateKey out;
0472:
0473:                try {
0474:                    SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
0475:                            algorithm, "BC");
0476:                    PBEParameterSpec defParams = new PBEParameterSpec(pbeParams
0477:                            .getIV(), pbeParams.getIterations().intValue());
0478:
0479:                    SecretKey k = keyFact.generateSecret(pbeSpec);
0480:
0481:                    ((JCEPBEKey) k).setTryWrongPKCS12Zero(wrongPKCS12Zero);
0482:
0483:                    Cipher cipher = Cipher.getInstance(algorithm, "BC");
0484:
0485:                    cipher.init(Cipher.UNWRAP_MODE, k, defParams);
0486:
0487:                    // we pass "" as the key algorithm type as it is unknown at this point
0488:                    out = (PrivateKey) cipher.unwrap(data, "",
0489:                            Cipher.PRIVATE_KEY);
0490:                } catch (Exception e) {
0491:                    throw new IOException("exception unwrapping private key - "
0492:                            + e.toString());
0493:                }
0494:
0495:                return out;
0496:            }
0497:
0498:            protected byte[] wrapKey(String algorithm, Key key,
0499:                    PKCS12PBEParams pbeParams, char[] password)
0500:                    throws IOException {
0501:                PBEKeySpec pbeSpec = new PBEKeySpec(password);
0502:                byte[] out;
0503:
0504:                try {
0505:                    SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
0506:                            algorithm, "BC");
0507:                    PBEParameterSpec defParams = new PBEParameterSpec(pbeParams
0508:                            .getIV(), pbeParams.getIterations().intValue());
0509:
0510:                    Cipher cipher = Cipher.getInstance(algorithm, "BC");
0511:
0512:                    cipher.init(Cipher.WRAP_MODE, keyFact
0513:                            .generateSecret(pbeSpec), defParams);
0514:
0515:                    out = cipher.wrap(key);
0516:                } catch (Exception e) {
0517:                    throw new IOException("exception encrypting data - "
0518:                            + e.toString());
0519:                }
0520:
0521:                return out;
0522:            }
0523:
0524:            protected byte[] cryptData(boolean forEncryption,
0525:                    AlgorithmIdentifier algId, char[] password,
0526:                    boolean wrongPKCS12Zero, byte[] data) throws IOException {
0527:                String algorithm = algId.getObjectId().getId();
0528:                PKCS12PBEParams pbeParams = new PKCS12PBEParams(
0529:                        (ASN1Sequence) algId.getParameters());
0530:                PBEKeySpec pbeSpec = new PBEKeySpec(password);
0531:
0532:                try {
0533:                    SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
0534:                            algorithm, "BC");
0535:                    PBEParameterSpec defParams = new PBEParameterSpec(pbeParams
0536:                            .getIV(), pbeParams.getIterations().intValue());
0537:                    JCEPBEKey key = (JCEPBEKey) keyFact.generateSecret(pbeSpec);
0538:
0539:                    key.setTryWrongPKCS12Zero(wrongPKCS12Zero);
0540:
0541:                    Cipher cipher = Cipher.getInstance(algorithm, "BC");
0542:                    int mode = forEncryption ? Cipher.ENCRYPT_MODE
0543:                            : Cipher.DECRYPT_MODE;
0544:                    cipher.init(mode, key, defParams);
0545:                    return cipher.doFinal(data);
0546:                } catch (Exception e) {
0547:                    throw new IOException("exception decrypting data - "
0548:                            + e.toString());
0549:                }
0550:            }
0551:
0552:            public void engineLoad(InputStream stream, char[] password)
0553:                    throws IOException {
0554:                if (stream == null) // just initialising
0555:                {
0556:                    return;
0557:                }
0558:
0559:                if (password == null) {
0560:                    throw new NullPointerException(
0561:                            "No password supplied for PKCS#12 KeyStore.");
0562:                }
0563:
0564:                BufferedInputStream bufIn = new BufferedInputStream(stream);
0565:
0566:                bufIn.mark(10);
0567:
0568:                int head = bufIn.read();
0569:
0570:                if (head != 0x30) {
0571:                    throw new IOException(
0572:                            "stream does not represent a PKCS12 key store");
0573:                }
0574:
0575:                bufIn.reset();
0576:
0577:                ASN1InputStream bIn = new ASN1InputStream(bufIn);
0578:                ASN1Sequence obj = (ASN1Sequence) bIn.readObject();
0579:                Pfx bag = new Pfx(obj);
0580:                ContentInfo info = bag.getAuthSafe();
0581:                Vector chain = new Vector();
0582:                boolean unmarkedKey = false;
0583:                boolean wrongPKCS12Zero = false;
0584:
0585:                if (bag.getMacData() != null) // check the mac code
0586:                {
0587:                    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
0588:                    BEROutputStream berOut = new BEROutputStream(bOut);
0589:                    MacData mData = bag.getMacData();
0590:                    DigestInfo dInfo = mData.getMac();
0591:                    AlgorithmIdentifier algId = dInfo.getAlgorithmId();
0592:                    byte[] salt = mData.getSalt();
0593:                    int itCount = mData.getIterationCount().intValue();
0594:
0595:                    berOut.writeObject(info);
0596:
0597:                    byte[] data = ((ASN1OctetString) info.getContent())
0598:                            .getOctets();
0599:
0600:                    try {
0601:                        byte[] res = calculatePbeMac(algId.getObjectId(), salt,
0602:                                itCount, password, false, data);
0603:                        byte[] dig = dInfo.getDigest();
0604:
0605:                        if (!Arrays.areEqual(res, dig)) {
0606:                            if (password.length > 0) {
0607:                                throw new IOException(
0608:                                        "PKCS12 key store mac invalid - wrong password or corrupted file.");
0609:                            }
0610:
0611:                            // Try with incorrect zero length password
0612:                            res = calculatePbeMac(algId.getObjectId(), salt,
0613:                                    itCount, password, true, data);
0614:
0615:                            if (!Arrays.areEqual(res, dig)) {
0616:                                throw new IOException(
0617:                                        "PKCS12 key store mac invalid - wrong password or corrupted file.");
0618:                            }
0619:
0620:                            wrongPKCS12Zero = true;
0621:                        }
0622:                    } catch (IOException e) {
0623:                        throw e;
0624:                    } catch (Exception e) {
0625:                        throw new IOException("error constructing MAC: "
0626:                                + e.toString());
0627:                    }
0628:                }
0629:
0630:                keys = new IgnoresCaseHashtable();
0631:                localIds = new Hashtable();
0632:
0633:                if (info.getContentType().equals(data)) {
0634:                    bIn = new ASN1InputStream(((ASN1OctetString) info
0635:                            .getContent()).getOctets());
0636:
0637:                    AuthenticatedSafe authSafe = new AuthenticatedSafe(
0638:                            (ASN1Sequence) bIn.readObject());
0639:                    ContentInfo[] c = authSafe.getContentInfo();
0640:
0641:                    for (int i = 0; i != c.length; i++) {
0642:                        if (c[i].getContentType().equals(data)) {
0643:                            ASN1InputStream dIn = new ASN1InputStream(
0644:                                    ((ASN1OctetString) c[i].getContent())
0645:                                            .getOctets());
0646:                            ASN1Sequence seq = (ASN1Sequence) dIn.readObject();
0647:
0648:                            for (int j = 0; j != seq.size(); j++) {
0649:                                SafeBag b = new SafeBag((ASN1Sequence) seq
0650:                                        .getObjectAt(j));
0651:                                if (b.getBagId().equals(pkcs8ShroudedKeyBag)) {
0652:                                    org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(
0653:                                            (ASN1Sequence) b.getBagValue());
0654:                                    PrivateKey privKey = unwrapKey(eIn
0655:                                            .getEncryptionAlgorithm(), eIn
0656:                                            .getEncryptedData(), password,
0657:                                            wrongPKCS12Zero);
0658:
0659:                                    //
0660:                                    // set the attributes on the key
0661:                                    //
0662:                                    PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
0663:                                    String alias = null;
0664:                                    ASN1OctetString localId = null;
0665:
0666:                                    if (b.getBagAttributes() != null) {
0667:                                        Enumeration e = b.getBagAttributes()
0668:                                                .getObjects();
0669:                                        while (e.hasMoreElements()) {
0670:                                            ASN1Sequence sq = (ASN1Sequence) e
0671:                                                    .nextElement();
0672:                                            DERObjectIdentifier aOid = (DERObjectIdentifier) sq
0673:                                                    .getObjectAt(0);
0674:                                            ASN1Set attrSet = (ASN1Set) sq
0675:                                                    .getObjectAt(1);
0676:                                            DERObject attr = null;
0677:
0678:                                            if (attrSet.size() > 0) {
0679:                                                attr = (DERObject) attrSet
0680:                                                        .getObjectAt(0);
0681:
0682:                                                bagAttr.setBagAttribute(aOid,
0683:                                                        attr);
0684:                                            }
0685:
0686:                                            if (aOid
0687:                                                    .equals(pkcs_9_at_friendlyName)) {
0688:                                                alias = ((DERBMPString) attr)
0689:                                                        .getString();
0690:                                                keys.put(alias, privKey);
0691:                                            } else if (aOid
0692:                                                    .equals(pkcs_9_at_localKeyId)) {
0693:                                                localId = (ASN1OctetString) attr;
0694:                                            }
0695:                                        }
0696:                                    }
0697:
0698:                                    if (localId != null) {
0699:                                        String name = new String(Hex
0700:                                                .encode(localId.getOctets()));
0701:
0702:                                        if (alias == null) {
0703:                                            keys.put(name, privKey);
0704:                                        } else {
0705:                                            localIds.put(alias, name);
0706:                                        }
0707:                                    } else {
0708:                                        unmarkedKey = true;
0709:                                        keys.put("unmarked", privKey);
0710:                                    }
0711:                                } else if (b.getBagId().equals(certBag)) {
0712:                                    chain.addElement(b);
0713:                                } else {
0714:                                    System.out.println("extra in data "
0715:                                            + b.getBagId());
0716:                                    System.out
0717:                                            .println(ASN1Dump.dumpAsString(b));
0718:                                }
0719:                            }
0720:                        } else if (c[i].getContentType().equals(encryptedData)) {
0721:                            EncryptedData d = new EncryptedData(
0722:                                    (ASN1Sequence) c[i].getContent());
0723:                            byte[] octets = cryptData(false, d
0724:                                    .getEncryptionAlgorithm(), password,
0725:                                    wrongPKCS12Zero, d.getContent().getOctets());
0726:                            ASN1Sequence seq = (ASN1Sequence) ASN1Object
0727:                                    .fromByteArray(octets);
0728:
0729:                            for (int j = 0; j != seq.size(); j++) {
0730:                                SafeBag b = new SafeBag((ASN1Sequence) seq
0731:                                        .getObjectAt(j));
0732:
0733:                                if (b.getBagId().equals(certBag)) {
0734:                                    chain.addElement(b);
0735:                                } else if (b.getBagId().equals(
0736:                                        pkcs8ShroudedKeyBag)) {
0737:                                    org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(
0738:                                            (ASN1Sequence) b.getBagValue());
0739:                                    PrivateKey privKey = unwrapKey(eIn
0740:                                            .getEncryptionAlgorithm(), eIn
0741:                                            .getEncryptedData(), password,
0742:                                            wrongPKCS12Zero);
0743:
0744:                                    //
0745:                                    // set the attributes on the key
0746:                                    //
0747:                                    PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
0748:                                    String alias = null;
0749:                                    ASN1OctetString localId = null;
0750:
0751:                                    Enumeration e = b.getBagAttributes()
0752:                                            .getObjects();
0753:                                    while (e.hasMoreElements()) {
0754:                                        ASN1Sequence sq = (ASN1Sequence) e
0755:                                                .nextElement();
0756:                                        DERObjectIdentifier aOid = (DERObjectIdentifier) sq
0757:                                                .getObjectAt(0);
0758:                                        ASN1Set attrSet = (ASN1Set) sq
0759:                                                .getObjectAt(1);
0760:                                        DERObject attr = null;
0761:
0762:                                        if (attrSet.size() > 0) {
0763:                                            attr = (DERObject) attrSet
0764:                                                    .getObjectAt(0);
0765:
0766:                                            bagAttr.setBagAttribute(aOid, attr);
0767:                                        }
0768:
0769:                                        if (aOid.equals(pkcs_9_at_friendlyName)) {
0770:                                            alias = ((DERBMPString) attr)
0771:                                                    .getString();
0772:                                            keys.put(alias, privKey);
0773:                                        } else if (aOid
0774:                                                .equals(pkcs_9_at_localKeyId)) {
0775:                                            localId = (ASN1OctetString) attr;
0776:                                        }
0777:                                    }
0778:
0779:                                    String name = new String(Hex.encode(localId
0780:                                            .getOctets()));
0781:
0782:                                    if (alias == null) {
0783:                                        keys.put(name, privKey);
0784:                                    } else {
0785:                                        localIds.put(alias, name);
0786:                                    }
0787:                                } else if (b.getBagId().equals(keyBag)) {
0788:                                    org.bouncycastle.asn1.pkcs.PrivateKeyInfo pIn = new org.bouncycastle.asn1.pkcs.PrivateKeyInfo(
0789:                                            (ASN1Sequence) b.getBagValue());
0790:                                    PrivateKey privKey = JDKKeyFactory
0791:                                            .createPrivateKeyFromPrivateKeyInfo(pIn);
0792:
0793:                                    //
0794:                                    // set the attributes on the key
0795:                                    //
0796:                                    PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) privKey;
0797:                                    String alias = null;
0798:                                    ASN1OctetString localId = null;
0799:
0800:                                    Enumeration e = b.getBagAttributes()
0801:                                            .getObjects();
0802:                                    while (e.hasMoreElements()) {
0803:                                        ASN1Sequence sq = (ASN1Sequence) e
0804:                                                .nextElement();
0805:                                        DERObjectIdentifier aOid = (DERObjectIdentifier) sq
0806:                                                .getObjectAt(0);
0807:                                        ASN1Set attrSet = (ASN1Set) sq
0808:                                                .getObjectAt(1);
0809:                                        DERObject attr = null;
0810:
0811:                                        if (attrSet.size() > 0) {
0812:                                            attr = (DERObject) attrSet
0813:                                                    .getObjectAt(0);
0814:
0815:                                            bagAttr.setBagAttribute(aOid, attr);
0816:                                        }
0817:
0818:                                        if (aOid.equals(pkcs_9_at_friendlyName)) {
0819:                                            alias = ((DERBMPString) attr)
0820:                                                    .getString();
0821:                                            keys.put(alias, privKey);
0822:                                        } else if (aOid
0823:                                                .equals(pkcs_9_at_localKeyId)) {
0824:                                            localId = (ASN1OctetString) attr;
0825:                                        }
0826:                                    }
0827:
0828:                                    String name = new String(Hex.encode(localId
0829:                                            .getOctets()));
0830:
0831:                                    if (alias == null) {
0832:                                        keys.put(name, privKey);
0833:                                    } else {
0834:                                        localIds.put(alias, name);
0835:                                    }
0836:                                } else {
0837:                                    System.out
0838:                                            .println("extra in encryptedData "
0839:                                                    + b.getBagId());
0840:                                    System.out
0841:                                            .println(ASN1Dump.dumpAsString(b));
0842:                                }
0843:                            }
0844:                        } else {
0845:                            System.out.println("extra "
0846:                                    + c[i].getContentType().getId());
0847:                            System.out.println("extra "
0848:                                    + ASN1Dump.dumpAsString(c[i].getContent()));
0849:                        }
0850:                    }
0851:                }
0852:
0853:                certs = new IgnoresCaseHashtable();
0854:                chainCerts = new Hashtable();
0855:                keyCerts = new Hashtable();
0856:
0857:                for (int i = 0; i != chain.size(); i++) {
0858:                    SafeBag b = (SafeBag) chain.elementAt(i);
0859:                    CertBag cb = new CertBag((ASN1Sequence) b.getBagValue());
0860:
0861:                    if (!cb.getCertId().equals(x509Certificate)) {
0862:                        throw new RuntimeException(
0863:                                "Unsupported certificate type: "
0864:                                        + cb.getCertId());
0865:                    }
0866:
0867:                    Certificate cert;
0868:
0869:                    try {
0870:                        ByteArrayInputStream cIn = new ByteArrayInputStream(
0871:                                ((ASN1OctetString) cb.getCertValue())
0872:                                        .getOctets());
0873:                        cert = certFact.generateCertificate(cIn);
0874:                    } catch (Exception e) {
0875:                        throw new RuntimeException(e.toString());
0876:                    }
0877:
0878:                    //
0879:                    // set the attributes
0880:                    //
0881:                    ASN1OctetString localId = null;
0882:                    String alias = null;
0883:
0884:                    if (b.getBagAttributes() != null) {
0885:                        Enumeration e = b.getBagAttributes().getObjects();
0886:                        while (e.hasMoreElements()) {
0887:                            ASN1Sequence sq = (ASN1Sequence) e.nextElement();
0888:                            DERObjectIdentifier oid = (DERObjectIdentifier) sq
0889:                                    .getObjectAt(0);
0890:                            DERObject attr = (DERObject) ((ASN1Set) sq
0891:                                    .getObjectAt(1)).getObjectAt(0);
0892:
0893:                            if (cert instanceof  PKCS12BagAttributeCarrier) {
0894:                                PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) cert;
0895:                                bagAttr.setBagAttribute(oid, attr);
0896:                            }
0897:
0898:                            if (oid.equals(pkcs_9_at_friendlyName)) {
0899:                                alias = ((DERBMPString) attr).getString();
0900:                            } else if (oid.equals(pkcs_9_at_localKeyId)) {
0901:                                localId = (ASN1OctetString) attr;
0902:                            }
0903:                        }
0904:                    }
0905:
0906:                    chainCerts.put(new CertId(cert.getPublicKey()), cert);
0907:
0908:                    if (unmarkedKey) {
0909:                        if (keyCerts.isEmpty()) {
0910:                            String name = new String(Hex
0911:                                    .encode(createSubjectKeyId(
0912:                                            cert.getPublicKey())
0913:                                            .getKeyIdentifier()));
0914:
0915:                            keyCerts.put(name, cert);
0916:                            keys.put(name, keys.remove("unmarked"));
0917:                        }
0918:                    } else {
0919:                        //
0920:                        // the local key id needs to override the friendly name
0921:                        //
0922:                        if (localId != null) {
0923:                            String name = new String(Hex.encode(localId
0924:                                    .getOctets()));
0925:
0926:                            keyCerts.put(name, cert);
0927:                        }
0928:                        if (alias != null) {
0929:                            certs.put(alias, cert);
0930:                        }
0931:                    }
0932:                }
0933:            }
0934:
0935:            public void engineStore(OutputStream stream, char[] password)
0936:                    throws IOException {
0937:                if (password == null) {
0938:                    throw new NullPointerException(
0939:                            "No password supplied for PKCS#12 KeyStore.");
0940:                }
0941:
0942:                //
0943:                // handle the key
0944:                //
0945:                ASN1EncodableVector keyS = new ASN1EncodableVector();
0946:
0947:                Enumeration ks = keys.keys();
0948:
0949:                while (ks.hasMoreElements()) {
0950:                    byte[] kSalt = new byte[SALT_SIZE];
0951:
0952:                    random.nextBytes(kSalt);
0953:
0954:                    String name = (String) ks.nextElement();
0955:                    PrivateKey privKey = (PrivateKey) keys.get(name);
0956:                    PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt,
0957:                            MIN_ITERATIONS);
0958:                    byte[] kBytes = wrapKey(KEY_ALGORITHM.getId(), privKey,
0959:                            kParams, password);
0960:                    AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(
0961:                            KEY_ALGORITHM, kParams.getDERObject());
0962:                    org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(
0963:                            kAlgId, kBytes);
0964:                    boolean attrSet = false;
0965:                    ASN1EncodableVector kName = new ASN1EncodableVector();
0966:
0967:                    if (privKey instanceof  PKCS12BagAttributeCarrier) {
0968:                        PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier) privKey;
0969:                        //
0970:                        // make sure we are using the local alias on store
0971:                        //
0972:                        DERBMPString nm = (DERBMPString) bagAttrs
0973:                                .getBagAttribute(pkcs_9_at_friendlyName);
0974:                        if (nm == null || !nm.getString().equals(name)) {
0975:                            bagAttrs.setBagAttribute(pkcs_9_at_friendlyName,
0976:                                    new DERBMPString(name));
0977:                        }
0978:
0979:                        //
0980:                        // make sure we have a local key-id
0981:                        //
0982:                        if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) {
0983:                            Certificate ct = engineGetCertificate(name);
0984:
0985:                            bagAttrs.setBagAttribute(pkcs_9_at_localKeyId,
0986:                                    createSubjectKeyId(ct.getPublicKey()));
0987:                        }
0988:
0989:                        Enumeration e = bagAttrs.getBagAttributeKeys();
0990:
0991:                        while (e.hasMoreElements()) {
0992:                            DERObjectIdentifier oid = (DERObjectIdentifier) e
0993:                                    .nextElement();
0994:                            ASN1EncodableVector kSeq = new ASN1EncodableVector();
0995:
0996:                            kSeq.add(oid);
0997:                            kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
0998:
0999:                            attrSet = true;
1000:
1001:                            kName.add(new DERSequence(kSeq));
1002:                        }
1003:                    }
1004:
1005:                    if (!attrSet) {
1006:                        //
1007:                        // set a default friendly name (from the key id) and local id
1008:                        //
1009:                        ASN1EncodableVector kSeq = new ASN1EncodableVector();
1010:                        Certificate ct = engineGetCertificate(name);
1011:
1012:                        kSeq.add(pkcs_9_at_localKeyId);
1013:                        kSeq.add(new DERSet(createSubjectKeyId(ct
1014:                                .getPublicKey())));
1015:
1016:                        kName.add(new DERSequence(kSeq));
1017:
1018:                        kSeq = new ASN1EncodableVector();
1019:
1020:                        kSeq.add(pkcs_9_at_friendlyName);
1021:                        kSeq.add(new DERSet(new DERBMPString(name)));
1022:
1023:                        kName.add(new DERSequence(kSeq));
1024:                    }
1025:
1026:                    SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo
1027:                            .getDERObject(), new DERSet(kName));
1028:                    keyS.add(kBag);
1029:                }
1030:
1031:                byte[] keySEncoded = new DERSequence(keyS).getDEREncoded();
1032:                BERConstructedOctetString keyString = new BERConstructedOctetString(
1033:                        keySEncoded);
1034:
1035:                //
1036:                // certficate processing
1037:                //
1038:                byte[] cSalt = new byte[SALT_SIZE];
1039:
1040:                random.nextBytes(cSalt);
1041:
1042:                ASN1EncodableVector certSeq = new ASN1EncodableVector();
1043:                PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt,
1044:                        MIN_ITERATIONS);
1045:                AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(
1046:                        CERT_ALGORITHM, cParams.getDERObject());
1047:                Hashtable doneCerts = new Hashtable();
1048:
1049:                Enumeration cs = keys.keys();
1050:                while (cs.hasMoreElements()) {
1051:                    try {
1052:                        String name = (String) cs.nextElement();
1053:                        Certificate cert = engineGetCertificate(name);
1054:                        boolean cAttrSet = false;
1055:                        CertBag cBag = new CertBag(x509Certificate,
1056:                                new DEROctetString(cert.getEncoded()));
1057:                        ASN1EncodableVector fName = new ASN1EncodableVector();
1058:
1059:                        if (cert instanceof  PKCS12BagAttributeCarrier) {
1060:                            PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier) cert;
1061:                            //
1062:                            // make sure we are using the local alias on store
1063:                            //
1064:                            DERBMPString nm = (DERBMPString) bagAttrs
1065:                                    .getBagAttribute(pkcs_9_at_friendlyName);
1066:                            if (nm == null || !nm.getString().equals(name)) {
1067:                                bagAttrs.setBagAttribute(
1068:                                        pkcs_9_at_friendlyName,
1069:                                        new DERBMPString(name));
1070:                            }
1071:
1072:                            //
1073:                            // make sure we have a local key-id
1074:                            //
1075:                            if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) {
1076:                                bagAttrs
1077:                                        .setBagAttribute(pkcs_9_at_localKeyId,
1078:                                                createSubjectKeyId(cert
1079:                                                        .getPublicKey()));
1080:                            }
1081:
1082:                            Enumeration e = bagAttrs.getBagAttributeKeys();
1083:
1084:                            while (e.hasMoreElements()) {
1085:                                DERObjectIdentifier oid = (DERObjectIdentifier) e
1086:                                        .nextElement();
1087:                                ASN1EncodableVector fSeq = new ASN1EncodableVector();
1088:
1089:                                fSeq.add(oid);
1090:                                fSeq.add(new DERSet(bagAttrs
1091:                                        .getBagAttribute(oid)));
1092:                                fName.add(new DERSequence(fSeq));
1093:
1094:                                cAttrSet = true;
1095:                            }
1096:                        }
1097:
1098:                        if (!cAttrSet) {
1099:                            ASN1EncodableVector fSeq = new ASN1EncodableVector();
1100:
1101:                            fSeq.add(pkcs_9_at_localKeyId);
1102:                            fSeq.add(new DERSet(createSubjectKeyId(cert
1103:                                    .getPublicKey())));
1104:                            fName.add(new DERSequence(fSeq));
1105:
1106:                            fSeq = new ASN1EncodableVector();
1107:
1108:                            fSeq.add(pkcs_9_at_friendlyName);
1109:                            fSeq.add(new DERSet(new DERBMPString(name)));
1110:
1111:                            fName.add(new DERSequence(fSeq));
1112:                        }
1113:
1114:                        SafeBag sBag = new SafeBag(certBag,
1115:                                cBag.getDERObject(), new DERSet(fName));
1116:
1117:                        certSeq.add(sBag);
1118:
1119:                        doneCerts.put(cert, cert);
1120:                    } catch (CertificateEncodingException e) {
1121:                        throw new IOException("Error encoding certificate: "
1122:                                + e.toString());
1123:                    }
1124:                }
1125:
1126:                cs = certs.keys();
1127:                while (cs.hasMoreElements()) {
1128:                    try {
1129:                        String certId = (String) cs.nextElement();
1130:                        Certificate cert = (Certificate) certs.get(certId);
1131:                        boolean cAttrSet = false;
1132:
1133:                        if (keys.get(certId) != null) {
1134:                            continue;
1135:                        }
1136:
1137:                        CertBag cBag = new CertBag(x509Certificate,
1138:                                new DEROctetString(cert.getEncoded()));
1139:                        ASN1EncodableVector fName = new ASN1EncodableVector();
1140:
1141:                        if (cert instanceof  PKCS12BagAttributeCarrier) {
1142:                            PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier) cert;
1143:                            //
1144:                            // make sure we are using the local alias on store
1145:                            //
1146:                            DERBMPString nm = (DERBMPString) bagAttrs
1147:                                    .getBagAttribute(pkcs_9_at_friendlyName);
1148:                            if (nm == null || !nm.getString().equals(certId)) {
1149:                                bagAttrs.setBagAttribute(
1150:                                        pkcs_9_at_friendlyName,
1151:                                        new DERBMPString(certId));
1152:                            }
1153:
1154:                            Enumeration e = bagAttrs.getBagAttributeKeys();
1155:
1156:                            while (e.hasMoreElements()) {
1157:                                DERObjectIdentifier oid = (DERObjectIdentifier) e
1158:                                        .nextElement();
1159:                                ASN1EncodableVector fSeq = new ASN1EncodableVector();
1160:
1161:                                fSeq.add(oid);
1162:                                fSeq.add(new DERSet(bagAttrs
1163:                                        .getBagAttribute(oid)));
1164:                                fName.add(new DERSequence(fSeq));
1165:
1166:                                cAttrSet = true;
1167:                            }
1168:                        }
1169:
1170:                        if (!cAttrSet) {
1171:                            ASN1EncodableVector fSeq = new ASN1EncodableVector();
1172:
1173:                            fSeq.add(pkcs_9_at_friendlyName);
1174:                            fSeq.add(new DERSet(new DERBMPString(certId)));
1175:
1176:                            fName.add(new DERSequence(fSeq));
1177:                        }
1178:
1179:                        SafeBag sBag = new SafeBag(certBag,
1180:                                cBag.getDERObject(), new DERSet(fName));
1181:
1182:                        certSeq.add(sBag);
1183:
1184:                        doneCerts.put(cert, cert);
1185:                    } catch (CertificateEncodingException e) {
1186:                        throw new IOException("Error encoding certificate: "
1187:                                + e.toString());
1188:                    }
1189:                }
1190:
1191:                cs = chainCerts.keys();
1192:                while (cs.hasMoreElements()) {
1193:                    try {
1194:                        CertId certId = (CertId) cs.nextElement();
1195:                        Certificate cert = (Certificate) chainCerts.get(certId);
1196:
1197:                        if (doneCerts.get(cert) != null) {
1198:                            continue;
1199:                        }
1200:
1201:                        CertBag cBag = new CertBag(x509Certificate,
1202:                                new DEROctetString(cert.getEncoded()));
1203:                        ASN1EncodableVector fName = new ASN1EncodableVector();
1204:
1205:                        if (cert instanceof  PKCS12BagAttributeCarrier) {
1206:                            PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier) cert;
1207:                            Enumeration e = bagAttrs.getBagAttributeKeys();
1208:
1209:                            while (e.hasMoreElements()) {
1210:                                DERObjectIdentifier oid = (DERObjectIdentifier) e
1211:                                        .nextElement();
1212:                                ASN1EncodableVector fSeq = new ASN1EncodableVector();
1213:
1214:                                fSeq.add(oid);
1215:                                fSeq.add(new DERSet(bagAttrs
1216:                                        .getBagAttribute(oid)));
1217:                                fName.add(new DERSequence(fSeq));
1218:                            }
1219:                        }
1220:
1221:                        SafeBag sBag = new SafeBag(certBag,
1222:                                cBag.getDERObject(), new DERSet(fName));
1223:
1224:                        certSeq.add(sBag);
1225:                    } catch (CertificateEncodingException e) {
1226:                        throw new IOException("Error encoding certificate: "
1227:                                + e.toString());
1228:                    }
1229:                }
1230:
1231:                byte[] certSeqEncoded = new DERSequence(certSeq)
1232:                        .getDEREncoded();
1233:                byte[] certBytes = cryptData(true, cAlgId, password, false,
1234:                        certSeqEncoded);
1235:                EncryptedData cInfo = new EncryptedData(data, cAlgId,
1236:                        new BERConstructedOctetString(certBytes));
1237:
1238:                ContentInfo[] info = new ContentInfo[] {
1239:                        new ContentInfo(data, keyString),
1240:                        new ContentInfo(encryptedData, cInfo.getDERObject()) };
1241:
1242:                AuthenticatedSafe auth = new AuthenticatedSafe(info);
1243:
1244:                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
1245:                BEROutputStream berOut = new BEROutputStream(bOut);
1246:
1247:                berOut.writeObject(auth);
1248:
1249:                byte[] pkg = bOut.toByteArray();
1250:
1251:                ContentInfo mainInfo = new ContentInfo(data,
1252:                        new BERConstructedOctetString(pkg));
1253:
1254:                //
1255:                // create the mac
1256:                //
1257:                byte[] mSalt = new byte[20];
1258:                int itCount = MIN_ITERATIONS;
1259:
1260:                random.nextBytes(mSalt);
1261:
1262:                byte[] data = ((ASN1OctetString) mainInfo.getContent())
1263:                        .getOctets();
1264:
1265:                MacData mData;
1266:
1267:                try {
1268:                    byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount,
1269:                            password, false, data);
1270:
1271:                    AlgorithmIdentifier algId = new AlgorithmIdentifier(
1272:                            id_SHA1, new DERNull());
1273:                    DigestInfo dInfo = new DigestInfo(algId, res);
1274:
1275:                    mData = new MacData(dInfo, mSalt, itCount);
1276:                } catch (Exception e) {
1277:                    throw new IOException("error constructing MAC: "
1278:                            + e.toString());
1279:                }
1280:
1281:                //
1282:                // output the Pfx
1283:                //
1284:                Pfx pfx = new Pfx(mainInfo, mData);
1285:
1286:                berOut = new BEROutputStream(stream);
1287:
1288:                berOut.writeObject(pfx);
1289:            }
1290:
1291:            private static byte[] calculatePbeMac(DERObjectIdentifier oid,
1292:                    byte[] salt, int itCount, char[] password,
1293:                    boolean wrongPkcs12Zero, byte[] data) throws Exception {
1294:                SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid
1295:                        .getId(), "BC");
1296:                PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount);
1297:                PBEKeySpec pbeSpec = new PBEKeySpec(password);
1298:                JCEPBEKey key = (JCEPBEKey) keyFact.generateSecret(pbeSpec);
1299:                key.setTryWrongPKCS12Zero(wrongPkcs12Zero);
1300:
1301:                Mac mac = Mac.getInstance(oid.getId(), "BC");
1302:                mac.init(key, defParams);
1303:                mac.update(data);
1304:                return mac.doFinal();
1305:            }
1306:
1307:            public static class BCPKCS12KeyStore extends JDKPKCS12KeyStore {
1308:                public BCPKCS12KeyStore() {
1309:                    super ("BC");
1310:                }
1311:            }
1312:
1313:            public static class DefPKCS12KeyStore extends JDKPKCS12KeyStore {
1314:                public DefPKCS12KeyStore() {
1315:                    super (null);
1316:                }
1317:            }
1318:
1319:            private static class IgnoresCaseHashtable {
1320:                private Hashtable orig = new Hashtable();
1321:                private Hashtable keys = new Hashtable();
1322:
1323:                public void put(String key, Object value) {
1324:                    String lower = Strings.toLowerCase(key);
1325:                    String k = (String) keys.get(lower);
1326:                    if (k != null) {
1327:                        orig.remove(k);
1328:                    }
1329:
1330:                    keys.put(lower, key);
1331:                    orig.put(key, value);
1332:                }
1333:
1334:                public Enumeration keys() {
1335:                    return orig.keys();
1336:                }
1337:
1338:                public Object remove(String alias) {
1339:                    String k = (String) keys.remove(Strings.toLowerCase(alias));
1340:                    if (k == null) {
1341:                        return null;
1342:                    }
1343:
1344:                    return orig.remove(k);
1345:                }
1346:
1347:                public Object get(String alias) {
1348:                    String k = (String) keys.get(Strings.toLowerCase(alias));
1349:                    if (k == null) {
1350:                        return null;
1351:                    }
1352:
1353:                    return orig.get(k);
1354:                }
1355:
1356:                public Enumeration elements() {
1357:                    return orig.elements();
1358:                }
1359:            }
1360:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.