1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.jce.provider; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.BufferedInputStream; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayInputStream; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.ByteArrayOutputStream; 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.InputStream; 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.OutputStream; 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.Key; 106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.KeyStore; 114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.KeyStore.LoadStoreParameter; 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.KeyStore.ProtectionParameter; 13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.KeyStoreException; 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.KeyStoreSpi; 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchAlgorithmException; 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.Principal; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PrivateKey; 18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.Provider; 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PublicKey; 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SecureRandom; 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.UnrecoverableKeyException; 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.Certificate; 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateEncodingException; 246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.security.cert.CertificateException; 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateFactory; 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.X509Certificate; 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Date; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration; 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Hashtable; 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Vector; 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.Cipher; 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.Mac; 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.SecretKey; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.SecretKeyFactory; 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.spec.PBEKeySpec; 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport javax.crypto.spec.PBEParameterSpec; 38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable; 40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector; 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encoding; 42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1InputStream; 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1OctetString; 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive; 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence; 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Set; 4870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.asn1.BEROctetString; 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.BEROutputStream; 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERBMPString; 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERNull; 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DEROctetString; 536e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport org.bouncycastle.asn1.DEROutputStream; 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence; 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSet; 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.AuthenticatedSafe; 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.CertBag; 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.ContentInfo; 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.EncryptedData; 60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.MacData; 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PKCS12PBEParams; 62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.Pfx; 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.pkcs.SafeBag; 65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.util.ASN1Dump; 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.AlgorithmIdentifier; 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; 68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.DigestInfo; 6970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.asn1.x509.Extension; 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.SubjectKeyIdentifier; 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.X509ObjectIdentifiers; 734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey; 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.jce.interfaces.BCKeyStore; 75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.Arrays; 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.Strings; 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.util.encoders.Hex; 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class JDKPKCS12KeyStore 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends KeyStoreSpi 82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam implements PKCSObjectIdentifiers, X509ObjectIdentifiers, BCKeyStore 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final int SALT_SIZE = 20; 85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final int MIN_ITERATIONS = 1024; 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final Provider bcProvider = new BouncyCastleProvider(); 88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private IgnoresCaseHashtable keys = new IgnoresCaseHashtable(); 90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private Hashtable localIds = new Hashtable(); 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private IgnoresCaseHashtable certs = new IgnoresCaseHashtable(); 92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private Hashtable chainCerts = new Hashtable(); 93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private Hashtable keyCerts = new Hashtable(); 94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // generic object types 97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int NULL = 0; 99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int CERTIFICATE = 1; 100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int KEY = 2; 101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int SECRET = 3; 102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int SEALED = 4; 103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // key types 106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int KEY_PRIVATE = 0; 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int KEY_PUBLIC = 1; 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final int KEY_SECRET = 2; 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected SecureRandom random = new SecureRandom(); 112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // use of final causes problems with JDK 1.2 compiler 114c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private CertificateFactory certFact; 1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private ASN1ObjectIdentifier keyAlgorithm; 1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private ASN1ObjectIdentifier certAlgorithm; 117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private class CertId 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] id; 121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertId( 123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PublicKey key) 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.id = createSubjectKeyId(key).getKeyIdentifier(); 126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertId( 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] id) 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.id = id; 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int hashCode() 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 136c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return Arrays.hashCode(id); 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public boolean equals( 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object o) 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (o == this) 143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return true; 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 147c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!(o instanceof CertId)) 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 152c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom CertId cId = (CertId)o; 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return Arrays.areEqual(id, cId.id); 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public JDKPKCS12KeyStore( 159c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Provider provider, 1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier keyAlgorithm, 1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier certAlgorithm) 162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.keyAlgorithm = keyAlgorithm; 164c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this.certAlgorithm = certAlgorithm; 165c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (provider != null) 169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certFact = CertificateFactory.getInstance("X.509", provider); 171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certFact = CertificateFactory.getInstance("X.509"); 175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("can't create cert factory - " + e.toString()); 180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private SubjectKeyIdentifier createSubjectKeyId( 184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PublicKey pubKey) 185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( 1894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom (ASN1Sequence) ASN1Primitive.fromByteArray(pubKey.getEncoded())); 190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new SubjectKeyIdentifier(info); 192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("error creating key"); 196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void setRandom( 200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecureRandom rand) 201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam this.random = rand; 203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Enumeration engineAliases() 206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Hashtable tab = new Hashtable(); 208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = certs.keys(); 210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tab.put(e.nextElement(), "cert"); 213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam e = keys.keys(); 216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String a = (String)e.nextElement(); 219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tab.get(a) == null) 220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tab.put(a, "key"); 222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return tab.keys(); 226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public boolean engineContainsAlias( 229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (certs.get(alias) != null || keys.get(alias) != null); 232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * this is not quite complete - we should follow up on the chain, a bit 236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tricky if a certificate appears in more than one chain... 237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineDeleteEntry( 239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws KeyStoreException 241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key k = (Key)keys.remove(alias); 243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate c = (Certificate)certs.remove(alias); 245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c != null) 247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chainCerts.remove(new CertId(c.getPublicKey())); 249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (k != null) 252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String id = (String)localIds.remove(alias); 254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (id != null) 255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = (Certificate)keyCerts.remove(id); 257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c != null) 259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chainCerts.remove(new CertId(c.getPublicKey())); 261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * simply return the cert for the private key 267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Certificate engineGetCertificate( 269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("null alias passed to getCertificate."); 274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate c = (Certificate)certs.get(alias); 277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // look up the key table - and try the local key id 280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c == null) 282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String id = (String)localIds.get(alias); 284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (id != null) 285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = (Certificate)keyCerts.get(id); 287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = (Certificate)keyCerts.get(alias); 291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return c; 295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String engineGetCertificateAlias( 298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert) 299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration c = certs.elements(); 301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration k = certs.keys(); 302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (c.hasMoreElements()) 304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate tc = (Certificate)c.nextElement(); 306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String ta = (String)k.nextElement(); 307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tc.equals(cert)) 309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return ta; 311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = keyCerts.elements(); 315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam k = keyCerts.keys(); 316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (c.hasMoreElements()) 318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate tc = (Certificate)c.nextElement(); 320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String ta = (String)k.nextElement(); 321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tc.equals(cert)) 323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return ta; 325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Certificate[] engineGetCertificateChain( 332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("null alias passed to getCertificateChain."); 337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!engineIsKeyEntry(alias)) 340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate c = engineGetCertificate(alias); 345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c != null) 347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Vector cs = new Vector(); 349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (c != null) 351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate x509c = (X509Certificate)c; 353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate nextC = null; 354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 35570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom byte[] bytes = x509c.getExtensionValue(Extension.authorityKeyIdentifier.getId()); 356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bytes != null) 357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream aIn = new ASN1InputStream(bytes); 361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets(); 363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam aIn = new ASN1InputStream(authBytes); 364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 36570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom AuthorityKeyIdentifier id = AuthorityKeyIdentifier.getInstance(aIn.readObject()); 366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (id.getKeyIdentifier() != null) 367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier())); 369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException(e.toString()); 375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 376b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (nextC == null) 379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // no authority key id, try the Issuer DN 382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Principal i = x509c.getIssuerDN(); 384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Principal s = x509c.getSubjectDN(); 385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!i.equals(s)) 387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = chainCerts.keys(); 389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 392b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement()); 393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Principal sub = crt.getSubjectDN(); 394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (sub.equals(i)) 395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam x509c.verify(crt.getPublicKey()); 399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam nextC = crt; 400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam break; 401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception ex) 403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // continue 405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 407b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 408b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 409b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 410b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 411b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cs.addElement(c); 412b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (nextC != c) // self signed - end of the chain 413b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 414b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = nextC; 415b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 416b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 417b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 418b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam c = null; 419b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 420b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 421b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 422b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate[] certChain = new Certificate[cs.size()]; 423b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 424b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != certChain.length; i++) 425b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 426b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certChain[i] = (Certificate)cs.elementAt(i); 427b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 428b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 429b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return certChain; 430b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 431b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 432b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return null; 433b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 434b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 435b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Date engineGetCreationDate(String alias) 436b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 43770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (alias == null) 43870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 4398e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new NullPointerException("alias == null"); 4408e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 44170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (keys.get(alias) == null && certs.get(alias) == null) 44270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 4438e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom return null; 4448e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 445b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return new Date(); 446b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 447b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 448b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public Key engineGetKey( 449b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias, 450b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password) 451b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws NoSuchAlgorithmException, UnrecoverableKeyException 452b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 453b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 454b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 455b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("null alias passed to getKey."); 456b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 457b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 458b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (Key)keys.get(alias); 459b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 460b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 461b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public boolean engineIsCertificateEntry( 462b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 463b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 464b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (certs.get(alias) != null && keys.get(alias) == null); 465b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 466b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 467b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public boolean engineIsKeyEntry( 468b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias) 469b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 470b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (keys.get(alias) != null); 471b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 472b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 473b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineSetCertificateEntry( 474b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias, 475b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert) 476b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws KeyStoreException 477b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 478c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (keys.get(alias) != null) 479b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 480c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new KeyStoreException("There is a key entry with the name " + alias + "."); 481b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 482b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 483b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certs.put(alias, cert); 484b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chainCerts.put(new CertId(cert.getPublicKey()), cert); 485b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 486b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 487b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineSetKeyEntry( 488b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias, 489b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] key, 490b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate[] chain) 491b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws KeyStoreException 492b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 493b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException("operation not supported"); 494b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 495b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 496b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineSetKeyEntry( 497b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias, 498b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 499b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password, 500b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate[] chain) 501b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws KeyStoreException 502b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 50370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (!(key instanceof PrivateKey)) 50470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 5058e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom throw new KeyStoreException("PKCS12 does not support non-PrivateKeys"); 5068e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 50770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 508b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if ((key instanceof PrivateKey) && (chain == null)) 509b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 510b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new KeyStoreException("no certificate chain for private key"); 511b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 512b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 513c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (keys.get(alias) != null) 514b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 515c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom engineDeleteEntry(alias); 516b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 517b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 518b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(alias, key); 51970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (chain != null) 520b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 52170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom certs.put(alias, chain[0]); 52270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 52370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom for (int i = 0; i != chain.length; i++) 52470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 52570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]); 52670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 5278e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom } 528b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 529b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 530b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int engineSize() 531b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 532b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Hashtable tab = new Hashtable(); 533b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 534b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = certs.keys(); 535b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 536b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 537b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tab.put(e.nextElement(), "cert"); 538b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 539b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 540b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam e = keys.keys(); 541b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 542b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 543b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String a = (String)e.nextElement(); 544b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (tab.get(a) == null) 545b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 546b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam tab.put(a, "key"); 547b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 548b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 549b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 550b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return tab.size(); 551b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 552b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 553b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected PrivateKey unwrapKey( 554b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier algId, 555b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data, 556b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password, 557b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean wrongPKCS12Zero) 558b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 559b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 5604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom String algorithm = algId.getAlgorithm().getId(); 5614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); 562b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 563b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEKeySpec pbeSpec = new PBEKeySpec(password); 564c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PrivateKey out; 565b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 566b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 567b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 568b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecretKeyFactory keyFact = SecretKeyFactory.getInstance( 569c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom algorithm, bcProvider); 570b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEParameterSpec defParams = new PBEParameterSpec( 571b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pbeParams.getIV(), 572b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pbeParams.getIterations().intValue()); 573b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 574b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecretKey k = keyFact.generateSecret(pbeSpec); 575b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 5764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero); 577b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 578c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Cipher cipher = Cipher.getInstance(algorithm, bcProvider); 579b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 580b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cipher.init(Cipher.UNWRAP_MODE, k, defParams); 581b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 582b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // we pass "" as the key algorithm type as it is unknown at this point 583b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out = (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY); 584b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 585b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 586b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 587b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("exception unwrapping private key - " + e.toString()); 588b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 589b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 590b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return out; 591b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 592b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 593b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam protected byte[] wrapKey( 594b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String algorithm, 595b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Key key, 596b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12PBEParams pbeParams, 597b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password) 598b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 599b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 600b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEKeySpec pbeSpec = new PBEKeySpec(password); 601b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] out; 602b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 603b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 604b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 605b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SecretKeyFactory keyFact = SecretKeyFactory.getInstance( 606c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom algorithm, bcProvider); 607b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PBEParameterSpec defParams = new PBEParameterSpec( 608b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pbeParams.getIV(), 609b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam pbeParams.getIterations().intValue()); 610b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 611c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Cipher cipher = Cipher.getInstance(algorithm, bcProvider); 612b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 613b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams); 614b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 615b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam out = cipher.wrap(key); 616b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 617b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 618b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 619b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("exception encrypting data - " + e.toString()); 620b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 621b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 622b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return out; 623b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 624b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 625c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom protected byte[] cryptData( 626c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean forEncryption, 627b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier algId, 628b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password, 629c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean wrongPKCS12Zero, 630c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] data) 631b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 632b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 6334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom String algorithm = algId.getAlgorithm().getId(); 6344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters()); 635c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PBEKeySpec pbeSpec = new PBEKeySpec(password); 636b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 637b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 638b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 639c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algorithm, bcProvider); 640c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PBEParameterSpec defParams = new PBEParameterSpec( 641c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom pbeParams.getIV(), 642c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom pbeParams.getIterations().intValue()); 6434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); 644c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 645c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom key.setTryWrongPKCS12Zero(wrongPKCS12Zero); 646c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 647c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Cipher cipher = Cipher.getInstance(algorithm, bcProvider); 648c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int mode = forEncryption ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; 649c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom cipher.init(mode, key, defParams); 650c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return cipher.doFinal(data); 651b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 652b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 653b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 654b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("exception decrypting data - " + e.toString()); 655b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 656b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 657b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 658b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineLoad( 659b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam InputStream stream, 660b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam char[] password) 661b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 662b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 663b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (stream == null) // just initialising 664b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 665b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return; 666b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 667b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 668b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (password == null) 669b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 670b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); 671b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 672b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 673b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam BufferedInputStream bufIn = new BufferedInputStream(stream); 674b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 675b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bufIn.mark(10); 676b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 677b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int head = bufIn.read(); 678b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 679b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (head != 0x30) 680b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 681b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("stream does not represent a PKCS12 key store"); 682b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 683b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 684b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bufIn.reset(); 685b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 686b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream bIn = new ASN1InputStream(bufIn); 687b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence obj = (ASN1Sequence)bIn.readObject(); 6884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom Pfx bag = Pfx.getInstance(obj); 689b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ContentInfo info = bag.getAuthSafe(); 690b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Vector chain = new Vector(); 691b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean unmarkedKey = false; 692b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean wrongPKCS12Zero = false; 693b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 694b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bag.getMacData() != null) // check the mac code 695b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 696b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam MacData mData = bag.getMacData(); 697b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DigestInfo dInfo = mData.getMac(); 698b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam AlgorithmIdentifier algId = dInfo.getAlgorithmId(); 699b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] salt = mData.getSalt(); 700b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int itCount = mData.getIterationCount().intValue(); 701b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 702b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data = ((ASN1OctetString)info.getContent()).getOctets(); 703b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 704b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 705b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 706c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, false, data); 707c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] dig = dInfo.getDigest(); 708b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 709c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!Arrays.constantTimeAreEqual(res, dig)) 710b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 711c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (password.length > 0) 712b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 713c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); 714b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 715c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 716c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // Try with incorrect zero length password 717c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom res = calculatePbeMac(algId.getObjectId(), salt, itCount, password, true, data); 718c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 719c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!Arrays.constantTimeAreEqual(res, dig)) 720b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 721c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file."); 722b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 723c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 724b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam wrongPKCS12Zero = true; 725b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 726b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 727b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (IOException e) 728b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 729b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw e; 730b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 731b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 732b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 733b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("error constructing MAC: " + e.toString()); 734b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 735b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 736b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 737c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom keys = new IgnoresCaseHashtable(); 738b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localIds = new Hashtable(); 739b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 740b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (info.getContentType().equals(data)) 741b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 742b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets()); 743b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 7444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom AuthenticatedSafe authSafe = AuthenticatedSafe.getInstance(bIn.readObject()); 745b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ContentInfo[] c = authSafe.getContentInfo(); 746b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 747b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != c.length; i++) 748b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 749b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (c[i].getContentType().equals(data)) 750b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 751b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets()); 752b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence seq = (ASN1Sequence)dIn.readObject(); 753b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 754b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int j = 0; j != seq.size(); j++) 755b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 7564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); 757b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (b.getBagId().equals(pkcs8ShroudedKeyBag)) 758b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 7594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); 760b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); 761b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 762b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 763b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // set the attributes on the key 764b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 765b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; 766b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias = null; 767b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1OctetString localId = null; 768b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 769b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (b.getBagAttributes() != null) 770b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 771b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = b.getBagAttributes().getObjects(); 772b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 773b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 774b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence sq = (ASN1Sequence)e.nextElement(); 7754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); 776b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); 7774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive attr = null; 778b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 779b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (attrSet.size() > 0) 780b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 7814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom attr = (ASN1Primitive)attrSet.getObjectAt(0); 782c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 7834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable existing = bagAttr.getBagAttribute(aOid); 784c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (existing != null) 785c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 786c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // OK, but the value has to be the same 7874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!existing.toASN1Primitive().equals(attr)) 788c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 789c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException( 790c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom "attempt to add existing attribute with different value"); 791c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 792c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 793c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 794c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 795c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bagAttr.setBagAttribute(aOid, attr); 796c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 797b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 798b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 799b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (aOid.equals(pkcs_9_at_friendlyName)) 800b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 801b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam alias = ((DERBMPString)attr).getString(); 802b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(alias, privKey); 803b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 804b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (aOid.equals(pkcs_9_at_localKeyId)) 805b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 806b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localId = (ASN1OctetString)attr; 807b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 808b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 809b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 810b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 811b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (localId != null) 812b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 813b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = new String(Hex.encode(localId.getOctets())); 814b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 815b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 816b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 817b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(name, privKey); 818b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 819b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 820b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 821b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localIds.put(alias, name); 822b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 823b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 824b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 825b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 826b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam unmarkedKey = true; 827b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put("unmarked", privKey); 828b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 829b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 830b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (b.getBagId().equals(certBag)) 831b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 832b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chain.addElement(b); 833b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 834b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 835b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 836b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("extra in data " + b.getBagId()); 837b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println(ASN1Dump.dumpAsString(b)); 838b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 839b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 840b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 841b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (c[i].getContentType().equals(encryptedData)) 842b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 8434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom EncryptedData d = EncryptedData.getInstance(c[i].getContent()); 844c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] octets = cryptData(false, d.getEncryptionAlgorithm(), 845c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom password, wrongPKCS12Zero, d.getContent().getOctets()); 8464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Sequence seq = (ASN1Sequence) ASN1Primitive.fromByteArray(octets); 847b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 848b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int j = 0; j != seq.size(); j++) 849b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 8504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag b = SafeBag.getInstance(seq.getObjectAt(j)); 851b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 852b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (b.getBagId().equals(certBag)) 853b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 854b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chain.addElement(b); 855b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 856b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (b.getBagId().equals(pkcs8ShroudedKeyBag)) 857b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 8584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo.getInstance(b.getBagValue()); 859b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero); 860b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 861b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 862b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // set the attributes on the key 863b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 864b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; 865b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias = null; 866b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1OctetString localId = null; 867b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 868b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = b.getBagAttributes().getObjects(); 869b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 870b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 871b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence sq = (ASN1Sequence)e.nextElement(); 8724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); 873b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Set attrSet= (ASN1Set)sq.getObjectAt(1); 8744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive attr = null; 875b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 876b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (attrSet.size() > 0) 877b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 8784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom attr = (ASN1Primitive)attrSet.getObjectAt(0); 879b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 8804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable existing = bagAttr.getBagAttribute(aOid); 881c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (existing != null) 882c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 883c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // OK, but the value has to be the same 8844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!existing.toASN1Primitive().equals(attr)) 885c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 886c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException( 887c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom "attempt to add existing attribute with different value"); 888c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 889c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 890c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 891c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 892c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bagAttr.setBagAttribute(aOid, attr); 893c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 894b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 895b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 896b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (aOid.equals(pkcs_9_at_friendlyName)) 897b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 898b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam alias = ((DERBMPString)attr).getString(); 899b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(alias, privKey); 900b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 901b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (aOid.equals(pkcs_9_at_localKeyId)) 902b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 903b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localId = (ASN1OctetString)attr; 904b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 905b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 906b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 907b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = new String(Hex.encode(localId.getOctets())); 908b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 909b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 910b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 911b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(name, privKey); 912b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 913b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 914b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 915b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localIds.put(alias, name); 916b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 917b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 918b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (b.getBagId().equals(keyBag)) 919b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 9204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom org.bouncycastle.asn1.pkcs.PrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.PrivateKeyInfo((ASN1Sequence)b.getBagValue()); 9214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom PrivateKey privKey = BouncyCastleProvider.getPrivateKey(kInfo); 922b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 923b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 924b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // set the attributes on the key 925b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 926b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey; 927b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String alias = null; 928b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1OctetString localId = null; 929b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 930b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = b.getBagAttributes().getObjects(); 931b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 932b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 933b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence sq = (ASN1Sequence)e.nextElement(); 9344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier aOid = (ASN1ObjectIdentifier)sq.getObjectAt(0); 935b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1); 9364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive attr = null; 937b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 938b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (attrSet.size() > 0) 939b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 9404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom attr = (ASN1Primitive)attrSet.getObjectAt(0); 941b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 9424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable existing = bagAttr.getBagAttribute(aOid); 943c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (existing != null) 944c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 945c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // OK, but the value has to be the same 9464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!existing.toASN1Primitive().equals(attr)) 947c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 948c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException( 949c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom "attempt to add existing attribute with different value"); 950c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 951c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 952c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 953c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 954c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bagAttr.setBagAttribute(aOid, attr); 955c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 956b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 957b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 958b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (aOid.equals(pkcs_9_at_friendlyName)) 959b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 960b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam alias = ((DERBMPString)attr).getString(); 961b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(alias, privKey); 962b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 963b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (aOid.equals(pkcs_9_at_localKeyId)) 964b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 965b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localId = (ASN1OctetString)attr; 966b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 967b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 968b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 969b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = new String(Hex.encode(localId.getOctets())); 970b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 971b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias == null) 972b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 973b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(name, privKey); 974b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 975b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 976b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 977b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localIds.put(alias, name); 978b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 979b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 980b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 981b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 982b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("extra in encryptedData " + b.getBagId()); 983b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println(ASN1Dump.dumpAsString(b)); 984b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 985b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 986b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 987b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 988b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 989b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("extra " + c[i].getContentType().getId()); 990b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent())); 991b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 992b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 993b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 994b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 995c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom certs = new IgnoresCaseHashtable(); 996b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chainCerts = new Hashtable(); 997b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyCerts = new Hashtable(); 998b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 999b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam for (int i = 0; i != chain.size(); i++) 1000b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1001b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam SafeBag b = (SafeBag)chain.elementAt(i); 10024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom CertBag cb = CertBag.getInstance(b.getBagValue()); 1003c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1004c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (!cb.getCertId().equals(x509Certificate)) 1005c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1006c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new RuntimeException("Unsupported certificate type: " + cb.getCertId()); 1007c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1008c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1009c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Certificate cert; 1010b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1011b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 1012b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1013b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ByteArrayInputStream cIn = new ByteArrayInputStream( 1014b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ((ASN1OctetString)cb.getCertValue()).getOctets()); 1015b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cert = certFact.generateCertificate(cIn); 1016b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1017b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 1018b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1019b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new RuntimeException(e.toString()); 1020b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1021b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1022b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1023b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // set the attributes 1024b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1025c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ASN1OctetString localId = null; 1026c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String alias = null; 1027b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1028b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (b.getBagAttributes() != null) 1029b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1030b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = b.getBagAttributes().getObjects(); 1031b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 1032b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1033b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1Sequence sq = (ASN1Sequence)e.nextElement(); 10344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)sq.getObjectAt(0); 10354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive attr = (ASN1Primitive)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0); 1036c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PKCS12BagAttributeCarrier bagAttr = null; 1037b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1038b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (cert instanceof PKCS12BagAttributeCarrier) 1039b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1040c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bagAttr = (PKCS12BagAttributeCarrier)cert; 1041c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 10424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Encodable existing = bagAttr.getBagAttribute(oid); 1043c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (existing != null) 1044c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1045c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // OK, but the value has to be the same 10464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (!existing.toASN1Primitive().equals(attr)) 1047c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1048c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IOException( 1049c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom "attempt to add existing attribute with different value"); 1050c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1051c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1052c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 1053c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1054c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bagAttr.setBagAttribute(oid, attr); 1055c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1056b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1057b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1058b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (oid.equals(pkcs_9_at_friendlyName)) 1059b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1060b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam alias = ((DERBMPString)attr).getString(); 1061b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1062b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else if (oid.equals(pkcs_9_at_localKeyId)) 1063b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1064b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam localId = (ASN1OctetString)attr; 1065b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1066b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1067b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1068b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1069b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam chainCerts.put(new CertId(cert.getPublicKey()), cert); 1070b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1071b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (unmarkedKey) 1072b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1073b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (keyCerts.isEmpty()) 1074b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1075b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier())); 1076b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1077b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyCerts.put(name, cert); 1078b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keys.put(name, keys.remove("unmarked")); 1079b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1080b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1081b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam else 1082b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1083b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1084b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // the local key id needs to override the friendly name 1085b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1086b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (localId != null) 1087b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1088b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = new String(Hex.encode(localId.getOctets())); 1089b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1090b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyCerts.put(name, cert); 1091b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1092b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (alias != null) 1093b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1094b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certs.put(alias, cert); 1095b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1096b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1097b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1098b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1099b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 11006e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom public void engineStore(LoadStoreParameter param) throws IOException, 11016e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom NoSuchAlgorithmException, CertificateException 11026e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11036e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (param == null) 11046e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11056e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException("'param' arg cannot be null"); 11066e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11076e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11086e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (!(param instanceof JDKPKCS12StoreParameter)) 11096e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException( 11116e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom "No support for 'param' of type " + param.getClass().getName()); 11126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom JDKPKCS12StoreParameter bcParam = (JDKPKCS12StoreParameter)param; 11156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom char[] password; 11176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom ProtectionParameter protParam = param.getProtectionParameter(); 11186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (protParam == null) 11196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom password = null; 11216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else if (protParam instanceof KeyStore.PasswordProtection) 11236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom password = ((KeyStore.PasswordProtection)protParam).getPassword(); 11256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 11276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 11286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throw new IllegalArgumentException( 11296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom "No support for protection parameter of type " + protParam.getClass().getName()); 11306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom doStore(bcParam.getOutputStream(), password, bcParam.isUseDEREncoding()); 11336e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 1135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public void engineStore(OutputStream stream, char[] password) 1136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 1137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 11386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom doStore(stream, password, false); 11396e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 11406e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 11416e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom private void doStore(OutputStream stream, char[] password, boolean useDEREncoding) 11426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom throws IOException 11436e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 1144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (password == null) 1145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new NullPointerException("No password supplied for PKCS#12 KeyStore."); 1147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // handle the key 1151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector keyS = new ASN1EncodableVector(); 1153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration ks = keys.keys(); 1156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (ks.hasMoreElements()) 1158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] kSalt = new byte[SALT_SIZE]; 1160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam random.nextBytes(kSalt); 1162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = (String)ks.nextElement(); 1164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PrivateKey privKey = (PrivateKey)keys.get(name); 1165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS); 1166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] kBytes = wrapKey(keyAlgorithm.getId(), privKey, kParams, password); 11674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.toASN1Primitive()); 1168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes); 1169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean attrSet = false; 1170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector kName = new ASN1EncodableVector(); 1171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (privKey instanceof PKCS12BagAttributeCarrier) 1173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey; 1175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure we are using the local alias on store 1177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); 1179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (nm == null || !nm.getString().equals(name)) 1180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); 1182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure we have a local key-id 1186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) 1188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate ct = engineGetCertificate(name); 1190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey())); 1192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = bagAttrs.getBagAttributeKeys(); 1195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 1197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 11984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 1199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector kSeq = new ASN1EncodableVector(); 1200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(oid); 1202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); 1203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam attrSet = true; 1205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kName.add(new DERSequence(kSeq)); 1207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!attrSet) 1211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // set a default friendly name (from the key id) and local id 1214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector kSeq = new ASN1EncodableVector(); 1216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate ct = engineGetCertificate(name); 1217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(pkcs_9_at_localKeyId); 1219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey()))); 1220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kName.add(new DERSequence(kSeq)); 1222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq = new ASN1EncodableVector(); 1224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(pkcs_9_at_friendlyName); 1226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kSeq.add(new DERSet(new DERBMPString(name))); 1227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam kName.add(new DERSequence(kSeq)); 1229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 12314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.toASN1Primitive(), new DERSet(kName)); 1232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam keyS.add(kBag); 1233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 12354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] keySEncoded = new DERSequence(keyS).getEncoded(ASN1Encoding.DER); 123670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom BEROctetString keyString = new BEROctetString(keySEncoded); 1237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // certificate processing 1240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] cSalt = new byte[SALT_SIZE]; 1242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam random.nextBytes(cSalt); 1244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector certSeq = new ASN1EncodableVector(); 1246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS); 12474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Primitive()); 1248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Hashtable doneCerts = new Hashtable(); 1249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration cs = keys.keys(); 1251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (cs.hasMoreElements()) 1252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 1254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String name = (String)cs.nextElement(); 1256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert = engineGetCertificate(name); 1257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean cAttrSet = false; 1258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertBag cBag = new CertBag( 1259c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom x509Certificate, 1260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DEROctetString(cert.getEncoded())); 1261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fName = new ASN1EncodableVector(); 1262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (cert instanceof PKCS12BagAttributeCarrier) 1264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; 1266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure we are using the local alias on store 1268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); 1270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (nm == null || !nm.getString().equals(name)) 1271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name)); 1273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure we have a local key-id 1277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null) 1279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey())); 1281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = bagAttrs.getBagAttributeKeys(); 1284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 1286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 12874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 1288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fSeq = new ASN1EncodableVector(); 1289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(oid); 1291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); 1292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cAttrSet = true; 1295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!cAttrSet) 1299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fSeq = new ASN1EncodableVector(); 1301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(pkcs_9_at_localKeyId); 1303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey()))); 1304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq = new ASN1EncodableVector(); 1307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(pkcs_9_at_friendlyName); 1309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(new DERBMPString(name))); 1310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 13144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); 1315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certSeq.add(sBag); 1317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam doneCerts.put(cert, cert); 1319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (CertificateEncodingException e) 1321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("Error encoding certificate: " + e.toString()); 1323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cs = certs.keys(); 1327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (cs.hasMoreElements()) 1328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 1330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String certId = (String)cs.nextElement(); 1332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert = (Certificate)certs.get(certId); 1333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean cAttrSet = false; 1334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (keys.get(certId) != null) 1336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam continue; 1338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertBag cBag = new CertBag( 1341c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom x509Certificate, 1342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DEROctetString(cert.getEncoded())); 1343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fName = new ASN1EncodableVector(); 1344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (cert instanceof PKCS12BagAttributeCarrier) 1346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; 1348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // make sure we are using the local alias on store 1350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName); 1352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (nm == null || !nm.getString().equals(certId)) 1353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId)); 1355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = bagAttrs.getBagAttributeKeys(); 1358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 1360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 13614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 1362c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1363c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // a certificate not immediately linked to a key doesn't require 1364c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // a localKeyID and will confuse some PKCS12 implementations. 1365c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 1366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // If we find one, we'll prune it out. 1367c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) 1368c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1369c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 1370c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1371c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fSeq = new ASN1EncodableVector(); 1373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(oid); 1375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); 1376b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cAttrSet = true; 1379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!cAttrSet) 1383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fSeq = new ASN1EncodableVector(); 1385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(pkcs_9_at_friendlyName); 1387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(new DERBMPString(certId))); 1388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 13924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); 1393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certSeq.add(sBag); 1395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam doneCerts.put(cert, cert); 1397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (CertificateEncodingException e) 1399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("Error encoding certificate: " + e.toString()); 1401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam cs = chainCerts.keys(); 1405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (cs.hasMoreElements()) 1406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1407b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 1408b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1409b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertId certId = (CertId)cs.nextElement(); 1410b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Certificate cert = (Certificate)chainCerts.get(certId); 1411b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1412b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (doneCerts.get(cert) != null) 1413b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1414b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam continue; 1415b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1416b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1417b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam CertBag cBag = new CertBag( 1418c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom x509Certificate, 1419b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam new DEROctetString(cert.getEncoded())); 1420b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fName = new ASN1EncodableVector(); 1421b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1422b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (cert instanceof PKCS12BagAttributeCarrier) 1423b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1424b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert; 1425b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Enumeration e = bagAttrs.getBagAttributeKeys(); 1426b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1427b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam while (e.hasMoreElements()) 1428b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 14294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)e.nextElement(); 1430c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1431c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // a certificate not immediately linked to a key doesn't require 1432c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // a localKeyID and will confuse some PKCS12 implementations. 1433c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // 1434c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // If we find one, we'll prune it out. 1435c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId)) 1436c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1437c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 1438c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1439c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1440b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1EncodableVector fSeq = new ASN1EncodableVector(); 1441b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1442b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(oid); 1443b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid))); 1444b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam fName.add(new DERSequence(fSeq)); 1445b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1446b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1447b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom SafeBag sBag = new SafeBag(certBag, cBag.toASN1Primitive(), new DERSet(fName)); 1449b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1450b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam certSeq.add(sBag); 1451b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1452b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (CertificateEncodingException e) 1453b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1454b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("Error encoding certificate: " + e.toString()); 1455b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1456b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1457b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom byte[] certSeqEncoded = new DERSequence(certSeq).getEncoded(ASN1Encoding.DER); 1459c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] certBytes = cryptData(true, cAlgId, password, false, certSeqEncoded); 146070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom EncryptedData cInfo = new EncryptedData(data, cAlgId, new BEROctetString(certBytes)); 1461b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1462c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ContentInfo[] info = new ContentInfo[] 1463c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1464c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom new ContentInfo(data, keyString), 14654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom new ContentInfo(encryptedData, cInfo.toASN1Primitive()) 1466c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom }; 1467b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1468c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom AuthenticatedSafe auth = new AuthenticatedSafe(info); 1469b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1470c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 14716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom DEROutputStream asn1Out; 14726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (useDEREncoding) 14736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 14746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out = new DEROutputStream(bOut); 14756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 14766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 14776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 14786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out = new BEROutputStream(bOut); 14796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1480b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 14816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out.writeObject(auth); 1482b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1483b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] pkg = bOut.toByteArray(); 1484b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 148570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom ContentInfo mainInfo = new ContentInfo(data, new BEROctetString(pkg)); 1486b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1487b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1488b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // create the mac 1489b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1490b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] mSalt = new byte[20]; 1491b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam int itCount = MIN_ITERATIONS; 1492b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1493b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam random.nextBytes(mSalt); 1494b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1495b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); 1496b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1497c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom MacData mData; 1498b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1499b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam try 1500b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1501c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] res = calculatePbeMac(id_SHA1, mSalt, itCount, password, false, data); 1502b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1503c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.INSTANCE); 1504b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DigestInfo dInfo = new DigestInfo(algId, res); 1505b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1506b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam mData = new MacData(dInfo, mSalt, itCount); 1507b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1508b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam catch (Exception e) 1509b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1510b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IOException("error constructing MAC: " + e.toString()); 1511b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1512b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1513b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1514b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // output the Pfx 1515b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // 1516b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Pfx pfx = new Pfx(mainInfo, mData); 1517b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 15186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (useDEREncoding) 15196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 15206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out = new DEROutputStream(stream); 15216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 15226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 15236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 15246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out = new BEROutputStream(stream); 15256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 1526b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 15276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom asn1Out.writeObject(pfx); 1528b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1529b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1530c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static byte[] calculatePbeMac( 15314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1ObjectIdentifier oid, 1532c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] salt, 1533c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int itCount, 1534c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom char[] password, 1535c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean wrongPkcs12Zero, 1536c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] data) 1537c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws Exception 1538c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1539c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom SecretKeyFactory keyFact = SecretKeyFactory.getInstance(oid.getId(), bcProvider); 1540c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount); 1541c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom PBEKeySpec pbeSpec = new PBEKeySpec(password); 15424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom BCPBEKey key = (BCPBEKey) keyFact.generateSecret(pbeSpec); 1543c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom key.setTryWrongPKCS12Zero(wrongPkcs12Zero); 1544c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1545c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom Mac mac = Mac.getInstance(oid.getId(), bcProvider); 1546c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom mac.init(key, defParams); 1547c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom mac.update(data); 1548c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return mac.doFinal(); 1549c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1550c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1551b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static class BCPKCS12KeyStore 1552b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam extends JDKPKCS12KeyStore 1553b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1554b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public BCPKCS12KeyStore() 1555b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 15564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); 1557b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1558b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1559b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1560c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // BEGIN android-removed 1561c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // public static class BCPKCS12KeyStore3DES 1562c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // extends JDKPKCS12KeyStore 1563c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // { 1564c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // public BCPKCS12KeyStore3DES() 1565c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // { 1566c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // super(bcProvider, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); 1567c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // } 1568c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // } 15697a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // 15707a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // public static class DefPKCS12KeyStore 15717a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // extends JDKPKCS12KeyStore 15727a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // { 15737a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // public DefPKCS12KeyStore() 15747a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // { 15754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd40BitRC2_CBC); 15767a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // } 15777a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // } 15787a6b43b187fb942402daa61e0b92496746f5bc1cBrian Carlstrom // 1579c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // public static class DefPKCS12KeyStore3DES 1580c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // extends JDKPKCS12KeyStore 1581c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // { 1582c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // public DefPKCS12KeyStore3DES() 1583c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // { 1584c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // super(null, pbeWithSHAAnd3_KeyTripleDES_CBC, pbeWithSHAAnd3_KeyTripleDES_CBC); 1585c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // } 1586c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // } 1587c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // END android-removed 1588c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1589c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static class IgnoresCaseHashtable 1590c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1591c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private Hashtable orig = new Hashtable(); 1592c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private Hashtable keys = new Hashtable(); 1593c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1594c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public void put(String key, Object value) 1595c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 15968e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom String lower = (key == null) ? null : Strings.toLowerCase(key); 1597c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String k = (String)keys.get(lower); 1598c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (k != null) 1599c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1600c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom orig.remove(k); 1601c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1602c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1603c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom keys.put(lower, key); 1604c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom orig.put(key, value); 1605c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1606c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1607c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public Enumeration keys() 1608c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1609c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig.keys(); 1610c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1611c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1612c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public Object remove(String alias) 1613c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 16148e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom String k = (String)keys.remove(alias == null ? null : Strings.toLowerCase(alias)); 1615c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (k == null) 1616c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1617c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 1618c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1619c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1620c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig.remove(k); 1621c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1622c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1623c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public Object get(String alias) 1624c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 16258e551503a8d09fb57fd4efe9a2aa0392e7ba56e9Brian Carlstrom String k = (String)keys.get(alias == null ? null : Strings.toLowerCase(alias)); 1626c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (k == null) 1627c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1628c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return null; 1629c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1630c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1631c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig.get(k); 1632c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 1633c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1634c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public Enumeration elements() 1635c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 1636c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return orig.elements(); 1637b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1638b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 1639b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 1640