JDKPKCS12KeyStorepublic class JDKPKCS12KeyStore extends KeyStoreSpi implements org.bouncycastle.asn1.x509.X509ObjectIdentifiers, org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers, org.bouncycastle.jce.interfaces.BCKeyStore
Fields Summary |
---|
private static final int | SALT_SIZE | private static final int | MIN_ITERATIONS | private static final String | KEY_ALGORITHM | private static final String | CERT_ALGORITHM | private Hashtable | keys | private Hashtable | localIds | private Hashtable | certs | private Hashtable | chainCerts | private Hashtable | keyCerts | static final int | NULL | static final int | CERTIFICATE | static final int | KEY | static final int | SECRET | static final int | SEALED | static final int | KEY_PRIVATE | static final int | KEY_PUBLIC | static final int | KEY_SECRET | protected SecureRandom | random | private CertificateFactory | certFact |
Constructors Summary |
---|
public JDKPKCS12KeyStore(String provider)
try
{
if (provider != null)
{
certFact = CertificateFactory.getInstance("X.509", provider);
}
else
{
certFact = CertificateFactory.getInstance("X.509");
}
}
catch (Exception e)
{
throw new IllegalArgumentException("can't create cert factory - " + e.toString());
}
|
Methods Summary |
---|
private org.bouncycastle.asn1.x509.SubjectKeyIdentifier | createSubjectKeyId(java.security.PublicKey pubKey)
try
{
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
(ASN1Sequence)new ASN1InputStream(pubKey.getEncoded()).readObject());
return new SubjectKeyIdentifier(info);
}
catch (Exception e)
{
throw new RuntimeException("error creating key");
}
| protected org.bouncycastle.asn1.ASN1Sequence | decryptData(org.bouncycastle.asn1.x509.AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero)
String algorithm = algId.getObjectId().getId();
PKCS12PBEParams pbeParams = new PKCS12PBEParams((ASN1Sequence)algId.getParameters());
PBEKeySpec pbeSpec = new PBEKeySpec(password);
byte[] out = null;
try
{
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
algorithm, "BC");
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
SecretKey k = keyFact.generateSecret(pbeSpec);
((JCEPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero);
Cipher cipher = Cipher.getInstance(algorithm, "BC");
cipher.init(Cipher.DECRYPT_MODE, k, defParams);
out = cipher.doFinal(data);
}
catch (Exception e)
{
throw new IOException("exception decrypting data - " + e.toString());
}
ASN1InputStream aIn = new ASN1InputStream(out);
return (ASN1Sequence)aIn.readObject();
| protected byte[] | encryptData(java.lang.String algorithm, byte[] data, org.bouncycastle.asn1.pkcs.PKCS12PBEParams pbeParams, char[] password)
PBEKeySpec pbeSpec = new PBEKeySpec(password);
byte[] out;
try
{
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
algorithm, "BC");
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
Cipher cipher = Cipher.getInstance(algorithm, "BC");
cipher.init(Cipher.ENCRYPT_MODE, keyFact.generateSecret(pbeSpec), defParams);
out = cipher.doFinal(data);
}
catch (Exception e)
{
throw new IOException("exception encrypting data - " + e.toString());
}
return out;
| public java.util.Enumeration | engineAliases()
Hashtable tab = new Hashtable();
Enumeration e = certs.keys();
while (e.hasMoreElements())
{
tab.put(e.nextElement(), "cert");
}
e = keys.keys();
while (e.hasMoreElements())
{
String a = (String)e.nextElement();
if (tab.get(a) == null)
{
tab.put(a, "key");
}
}
return tab.keys();
| public boolean | engineContainsAlias(java.lang.String alias)
return (certs.get(alias) != null || keys.get(alias) != null);
| public void | engineDeleteEntry(java.lang.String alias)this is quite complete - we should follow up on the chain, a bit
tricky if a certificate appears in more than one chain...
Key k = (Key)keys.remove(alias);
Certificate c = (Certificate)certs.remove(alias);
if (c != null)
{
chainCerts.remove(new CertId(c.getPublicKey()));
}
if (k != null)
{
String id = (String)localIds.remove(alias);
if (id != null)
{
c = (Certificate)keyCerts.remove(id);
}
if (c != null)
{
chainCerts.remove(new CertId(c.getPublicKey()));
}
}
if (c == null && k == null)
{
throw new KeyStoreException("no such entry as " + alias);
}
| public java.security.cert.Certificate | engineGetCertificate(java.lang.String alias)simply return the cert for the private key
if (alias == null)
{
throw new IllegalArgumentException("null alias passed to getCertificate.");
}
Certificate c = (Certificate)certs.get(alias);
//
// look up the key table - and try the local key id
//
if (c == null)
{
String id = (String)localIds.get(alias);
if (id != null)
{
c = (Certificate)keyCerts.get(id);
}
else
{
c = (Certificate)keyCerts.get(alias);
}
}
return c;
| public java.lang.String | engineGetCertificateAlias(java.security.cert.Certificate cert)
Enumeration c = certs.elements();
Enumeration k = certs.keys();
while (c.hasMoreElements())
{
Certificate tc = (Certificate)c.nextElement();
String ta = (String)k.nextElement();
if (tc.equals(cert))
{
return ta;
}
}
c = keyCerts.elements();
k = keyCerts.keys();
while (c.hasMoreElements())
{
Certificate tc = (Certificate)c.nextElement();
String ta = (String)k.nextElement();
if (tc.equals(cert))
{
return ta;
}
}
return null;
| public java.security.cert.Certificate[] | engineGetCertificateChain(java.lang.String alias)
if (alias == null)
{
throw new IllegalArgumentException("null alias passed to getCertificateChain.");
}
if (!engineIsKeyEntry(alias))
{
return null;
}
Certificate c = engineGetCertificate(alias);
if (c != null)
{
Vector cs = new Vector();
while (c != null)
{
X509Certificate x509c = (X509Certificate)c;
Certificate nextC = null;
byte[] bytes = x509c.getExtensionValue(X509Extensions.AuthorityKeyIdentifier.getId());
if (bytes != null)
{
try
{
ASN1InputStream aIn = new ASN1InputStream(bytes);
byte[] authBytes = ((ASN1OctetString)aIn.readObject()).getOctets();
aIn = new ASN1InputStream(authBytes);
AuthorityKeyIdentifier id = new AuthorityKeyIdentifier((ASN1Sequence)aIn.readObject());
if (id.getKeyIdentifier() != null)
{
nextC = (Certificate)chainCerts.get(new CertId(id.getKeyIdentifier()));
}
}
catch (IOException e)
{
throw new RuntimeException(e.toString());
}
}
if (nextC == null)
{
//
// no authority key id, try the Issuer DN
//
Principal i = x509c.getIssuerDN();
Principal s = x509c.getSubjectDN();
if (!i.equals(s))
{
Enumeration e = chainCerts.keys();
while (e.hasMoreElements())
{
X509Certificate crt = (X509Certificate)chainCerts.get(e.nextElement());
Principal sub = crt.getSubjectDN();
if (sub.equals(i))
{
try
{
x509c.verify(crt.getPublicKey());
nextC = crt;
break;
}
catch (Exception ex)
{
// continue
}
}
}
}
}
cs.addElement(c);
if (nextC != c) // self signed - end of the chain
{
c = nextC;
}
else
{
c = null;
}
}
Certificate[] certChain = new Certificate[cs.size()];
for (int i = 0; i != certChain.length; i++)
{
certChain[i] = (Certificate)cs.elementAt(i);
}
return certChain;
}
return null;
| public java.util.Date | engineGetCreationDate(java.lang.String alias)
return new Date();
| public java.security.Key | engineGetKey(java.lang.String alias, char[] password)
if (alias == null)
{
throw new IllegalArgumentException("null alias passed to getKey.");
}
return (Key)keys.get(alias);
| public boolean | engineIsCertificateEntry(java.lang.String alias)
return (certs.get(alias) != null && keys.get(alias) == null);
| public boolean | engineIsKeyEntry(java.lang.String alias)
return (keys.get(alias) != null);
| public void | engineLoad(java.io.InputStream stream, char[] password)
if (stream == null) // just initialising
{
return;
}
if (password == null)
{
throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
}
// BEGIN android-modified
BufferedInputStream bufIn = new BufferedInputStream(stream, 8192);
// END android-modified
bufIn.mark(10);
int head = bufIn.read();
if (head != 0x30)
{
throw new IOException("stream does not represent a PKCS12 key store");
}
bufIn.reset();
ASN1InputStream bIn = new ASN1InputStream(bufIn);
ASN1Sequence obj = (ASN1Sequence)bIn.readObject();
Pfx bag = new Pfx(obj);
ContentInfo info = bag.getAuthSafe();
Vector chain = new Vector();
boolean unmarkedKey = false;
boolean wrongPKCS12Zero = false;
if (bag.getMacData() != null) // check the mac code
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
BEROutputStream berOut = new BEROutputStream(bOut);
MacData mData = bag.getMacData();
DigestInfo dInfo = mData.getMac();
AlgorithmIdentifier algId = dInfo.getAlgorithmId();
byte[] salt = mData.getSalt();
int itCount = mData.getIterationCount().intValue();
berOut.writeObject(info);
byte[] data = ((ASN1OctetString)info.getContent()).getOctets();
try
{
Mac mac = Mac.getInstance(algId.getObjectId().getId(), "BC");
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(algId.getObjectId().getId(), "BC");
PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount);
PBEKeySpec pbeSpec = new PBEKeySpec(password);
mac.init(keyFact.generateSecret(pbeSpec), defParams);
mac.update(data);
byte[] res = mac.doFinal();
byte[] dig = dInfo.getDigest();
if (res.length != dInfo.getDigest().length)
{
throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
}
boolean okay = true;
for (int i = 0; i != res.length; i++)
{
if (res[i] != dig[i])
{
if (password.length != 0) // may be dodgey zero password
{
throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
}
else
{
okay = false;
break;
}
}
}
//
// may be incorrect zero length password
//
if (!okay)
{
SecretKey k = keyFact.generateSecret(pbeSpec);
((JCEPBEKey)k).setTryWrongPKCS12Zero(true);
mac.init(k, defParams);
mac.update(data);
res = mac.doFinal();
dig = dInfo.getDigest();
for (int i = 0; i != res.length; i++)
{
if (res[i] != dig[i])
{
throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
}
}
wrongPKCS12Zero = true;
}
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new IOException("error constructing MAC: " + e.toString());
}
}
keys = new Hashtable();
localIds = new Hashtable();
if (info.getContentType().equals(data))
{
bIn = new ASN1InputStream(((ASN1OctetString)info.getContent()).getOctets());
AuthenticatedSafe authSafe = new AuthenticatedSafe((ASN1Sequence)bIn.readObject());
ContentInfo[] c = authSafe.getContentInfo();
for (int i = 0; i != c.length; i++)
{
if (c[i].getContentType().equals(data))
{
ASN1InputStream dIn = new ASN1InputStream(((ASN1OctetString)c[i].getContent()).getOctets());
ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
for (int j = 0; j != seq.size(); j++)
{
SafeBag b = new SafeBag((ASN1Sequence)seq.getObjectAt(j));
if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo((ASN1Sequence)b.getBagValue());
PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
//
// set the attributes on the key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
String alias = null;
ASN1OctetString localId = null;
if (b.getBagAttributes() != null)
{
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements())
{
ASN1Sequence sq = (ASN1Sequence)e.nextElement();
DERObjectIdentifier aOid = (DERObjectIdentifier)sq.getObjectAt(0);
ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
DERObject attr = null;
if (attrSet.size() > 0)
{
attr = (DERObject)attrSet.getObjectAt(0);
bagAttr.setBagAttribute(aOid, attr);
}
if (aOid.equals(pkcs_9_at_friendlyName))
{
alias = ((DERBMPString)attr).getString();
keys.put(alias, privKey);
}
else if (aOid.equals(pkcs_9_at_localKeyId))
{
localId = (ASN1OctetString)attr;
}
}
}
if (localId != null)
{
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null)
{
keys.put(name, privKey);
}
else
{
localIds.put(alias, name);
}
}
else
{
unmarkedKey = true;
keys.put("unmarked", privKey);
}
}
else if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
else
{
System.out.println("extra in data " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
}
}
else if (c[i].getContentType().equals(encryptedData))
{
EncryptedData d = new EncryptedData((ASN1Sequence)c[i].getContent());
ASN1Sequence seq = decryptData(d.getEncryptionAlgorithm(), d.getContent().getOctets(), password, wrongPKCS12Zero);
for (int j = 0; j != seq.size(); j++)
{
SafeBag b = new SafeBag((ASN1Sequence)seq.getObjectAt(j));
if (b.getBagId().equals(certBag))
{
chain.addElement(b);
}
else if (b.getBagId().equals(pkcs8ShroudedKeyBag))
{
org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo((ASN1Sequence)b.getBagValue());
PrivateKey privKey = unwrapKey(eIn.getEncryptionAlgorithm(), eIn.getEncryptedData(), password, wrongPKCS12Zero);
//
// set the attributes on the key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
String alias = null;
ASN1OctetString localId = null;
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements())
{
ASN1Sequence sq = (ASN1Sequence)e.nextElement();
DERObjectIdentifier aOid = (DERObjectIdentifier)sq.getObjectAt(0);
ASN1Set attrSet= (ASN1Set)sq.getObjectAt(1);
DERObject attr = null;
if (attrSet.size() > 0)
{
attr = (DERObject)attrSet.getObjectAt(0);
bagAttr.setBagAttribute(aOid, attr);
}
if (aOid.equals(pkcs_9_at_friendlyName))
{
alias = ((DERBMPString)attr).getString();
keys.put(alias, privKey);
}
else if (aOid.equals(pkcs_9_at_localKeyId))
{
localId = (ASN1OctetString)attr;
}
}
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null)
{
keys.put(name, privKey);
}
else
{
localIds.put(alias, name);
}
}
else if (b.getBagId().equals(keyBag))
{
org.bouncycastle.asn1.pkcs.PrivateKeyInfo pIn = new org.bouncycastle.asn1.pkcs.PrivateKeyInfo((ASN1Sequence)b.getBagValue());
PrivateKey privKey = JDKKeyFactory.createPrivateKeyFromPrivateKeyInfo(pIn);
//
// set the attributes on the key
//
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)privKey;
String alias = null;
ASN1OctetString localId = null;
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements())
{
ASN1Sequence sq = (ASN1Sequence)e.nextElement();
DERObjectIdentifier aOid = (DERObjectIdentifier)sq.getObjectAt(0);
ASN1Set attrSet = (ASN1Set)sq.getObjectAt(1);
DERObject attr = null;
if (attrSet.size() > 0)
{
attr = (DERObject)attrSet.getObjectAt(0);
bagAttr.setBagAttribute(aOid, attr);
}
if (aOid.equals(pkcs_9_at_friendlyName))
{
alias = ((DERBMPString)attr).getString();
keys.put(alias, privKey);
}
else if (aOid.equals(pkcs_9_at_localKeyId))
{
localId = (ASN1OctetString)attr;
}
}
String name = new String(Hex.encode(localId.getOctets()));
if (alias == null)
{
keys.put(name, privKey);
}
else
{
localIds.put(alias, name);
}
}
else
{
System.out.println("extra in encryptedData " + b.getBagId());
System.out.println(ASN1Dump.dumpAsString(b));
}
}
}
else
{
System.out.println("extra " + c[i].getContentType().getId());
System.out.println("extra " + ASN1Dump.dumpAsString(c[i].getContent()));
}
}
}
certs = new Hashtable();
chainCerts = new Hashtable();
keyCerts = new Hashtable();
for (int i = 0; i != chain.size(); i++)
{
SafeBag b = (SafeBag)chain.elementAt(i);
CertBag cb = new CertBag((ASN1Sequence)b.getBagValue());
Certificate cert = null;
try
{
ByteArrayInputStream cIn = new ByteArrayInputStream(
((ASN1OctetString)cb.getCertValue()).getOctets());
cert = certFact.generateCertificate(cIn);
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
//
// set the attributes
//
ASN1OctetString localId = null;
String alias = null;
if (b.getBagAttributes() != null)
{
Enumeration e = b.getBagAttributes().getObjects();
while (e.hasMoreElements())
{
ASN1Sequence sq = (ASN1Sequence)e.nextElement();
DERObjectIdentifier oid = (DERObjectIdentifier)sq.getObjectAt(0);
DERObject attr = (DERObject)((ASN1Set)sq.getObjectAt(1)).getObjectAt(0);
if (cert instanceof PKCS12BagAttributeCarrier)
{
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)cert;
bagAttr.setBagAttribute(oid, attr);
}
if (oid.equals(pkcs_9_at_friendlyName))
{
alias = ((DERBMPString)attr).getString();
}
else if (oid.equals(pkcs_9_at_localKeyId))
{
localId = (ASN1OctetString)attr;
}
}
}
chainCerts.put(new CertId(cert.getPublicKey()), cert);
if (unmarkedKey)
{
if (keyCerts.isEmpty())
{
String name = new String(Hex.encode(createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier()));
keyCerts.put(name, cert);
keys.put(name, keys.remove("unmarked"));
}
}
else
{
//
// the local key id needs to override the friendly name
//
if (localId != null)
{
String name = new String(Hex.encode(localId.getOctets()));
keyCerts.put(name, cert);
}
if (alias != null)
{
certs.put(alias, cert);
}
}
}
| public void | engineSetCertificateEntry(java.lang.String alias, java.security.cert.Certificate cert)
if (certs.get(alias) != null)
{
throw new KeyStoreException("There is already a certificate with the name " + alias + ".");
}
certs.put(alias, cert);
chainCerts.put(new CertId(cert.getPublicKey()), cert);
| public void | engineSetKeyEntry(java.lang.String alias, byte[] key, java.security.cert.Certificate[] chain)
throw new RuntimeException("operation not supported");
| public void | engineSetKeyEntry(java.lang.String alias, java.security.Key key, char[] password, java.security.cert.Certificate[] chain)
if ((key instanceof PrivateKey) && (chain == null))
{
throw new KeyStoreException("no certificate chain for private key");
}
if (keys.get(alias) != null && !key.equals(keys.get(alias)))
{
throw new KeyStoreException("There is already a key with the name " + alias + ".");
}
keys.put(alias, key);
certs.put(alias, chain[0]);
for (int i = 0; i != chain.length; i++)
{
chainCerts.put(new CertId(chain[i].getPublicKey()), chain[i]);
}
| public int | engineSize()
Hashtable tab = new Hashtable();
Enumeration e = certs.keys();
while (e.hasMoreElements())
{
tab.put(e.nextElement(), "cert");
}
e = keys.keys();
while (e.hasMoreElements())
{
String a = (String)e.nextElement();
if (tab.get(a) == null)
{
tab.put(a, "key");
}
}
return tab.size();
| public void | engineStore(java.io.OutputStream stream, char[] password)
if (password == null)
{
throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
}
ContentInfo[] c = new ContentInfo[2];
//
// handle the key
//
ASN1EncodableVector keyS = new ASN1EncodableVector();
Enumeration ks = keys.keys();
while (ks.hasMoreElements())
{
byte[] kSalt = new byte[SALT_SIZE];
random.nextBytes(kSalt);
String name = (String)ks.nextElement();
PrivateKey privKey = (PrivateKey)keys.get(name);
PKCS12PBEParams kParams = new PKCS12PBEParams(kSalt, MIN_ITERATIONS);
byte[] kBytes = wrapKey(KEY_ALGORITHM, privKey, kParams, password);
AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(new DERObjectIdentifier(KEY_ALGORITHM), kParams.getDERObject());
org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo(kAlgId, kBytes);
boolean attrSet = false;
ASN1EncodableVector kName = new ASN1EncodableVector();
if (privKey instanceof PKCS12BagAttributeCarrier)
{
PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)privKey;
//
// make sure we are using the local alias on store
//
DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
}
//
// make sure we have a local key-id
//
if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null)
{
Certificate ct = engineGetCertificate(name);
bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(ct.getPublicKey()));
}
Enumeration e = bagAttrs.getBagAttributeKeys();
while (e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
ASN1EncodableVector kSeq = new ASN1EncodableVector();
kSeq.add(oid);
kSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
attrSet = true;
kName.add(new DERSequence(kSeq));
}
}
if (!attrSet)
{
//
// set a default friendly name (from the key id) and local id
//
ASN1EncodableVector kSeq = new ASN1EncodableVector();
Certificate ct = engineGetCertificate(name);
kSeq.add(pkcs_9_at_localKeyId);
kSeq.add(new DERSet(createSubjectKeyId(ct.getPublicKey())));
kName.add(new DERSequence(kSeq));
kSeq = new ASN1EncodableVector();
kSeq.add(pkcs_9_at_friendlyName);
kSeq.add(new DERSet(new DERBMPString(name)));
kName.add(new DERSequence(kSeq));
}
SafeBag kBag = new SafeBag(pkcs8ShroudedKeyBag, kInfo.getDERObject(), new DERSet(kName));
keyS.add(kBag);
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
dOut.writeObject(new DERSequence(keyS));
BERConstructedOctetString keyString = new BERConstructedOctetString(bOut.toByteArray());
//
// certficate processing
//
byte[] cSalt = new byte[SALT_SIZE];
random.nextBytes(cSalt);
ASN1EncodableVector certSeq = new ASN1EncodableVector();
PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, MIN_ITERATIONS);
AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(new DERObjectIdentifier(CERT_ALGORITHM), cParams.getDERObject());
Hashtable doneCerts = new Hashtable();
Enumeration cs = keys.keys();
while (cs.hasMoreElements())
{
try
{
String name = (String)cs.nextElement();
Certificate cert = engineGetCertificate(name);
boolean cAttrSet = false;
CertBag cBag = new CertBag(
x509certType,
new DEROctetString(cert.getEncoded()));
ASN1EncodableVector fName = new ASN1EncodableVector();
if (cert instanceof PKCS12BagAttributeCarrier)
{
PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
//
// make sure we are using the local alias on store
//
DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(name))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(name));
}
//
// make sure we have a local key-id
//
if (bagAttrs.getBagAttribute(pkcs_9_at_localKeyId) == null)
{
bagAttrs.setBagAttribute(pkcs_9_at_localKeyId, createSubjectKeyId(cert.getPublicKey()));
}
Enumeration e = bagAttrs.getBagAttributeKeys();
while (e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
ASN1EncodableVector fSeq = new ASN1EncodableVector();
fSeq.add(oid);
fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
fName.add(new DERSequence(fSeq));
cAttrSet = true;
}
}
if (!cAttrSet)
{
ASN1EncodableVector fSeq = new ASN1EncodableVector();
fSeq.add(pkcs_9_at_localKeyId);
fSeq.add(new DERSet(createSubjectKeyId(cert.getPublicKey())));
fName.add(new DERSequence(fSeq));
fSeq = new ASN1EncodableVector();
fSeq.add(pkcs_9_at_friendlyName);
fSeq.add(new DERSet(new DERBMPString(name)));
fName.add(new DERSequence(fSeq));
}
SafeBag sBag = new SafeBag(certBag, cBag.getDERObject(), new DERSet(fName));
certSeq.add(sBag);
doneCerts.put(cert, cert);
}
catch (CertificateEncodingException e)
{
throw new IOException("Error encoding certificate: " + e.toString());
}
}
cs = certs.keys();
while (cs.hasMoreElements())
{
try
{
String certId = (String)cs.nextElement();
Certificate cert = (Certificate)certs.get(certId);
boolean cAttrSet = false;
if (keys.get(certId) != null)
{
continue;
}
CertBag cBag = new CertBag(
x509certType,
new DEROctetString(cert.getEncoded()));
ASN1EncodableVector fName = new ASN1EncodableVector();
if (cert instanceof PKCS12BagAttributeCarrier)
{
PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
//
// make sure we are using the local alias on store
//
DERBMPString nm = (DERBMPString)bagAttrs.getBagAttribute(pkcs_9_at_friendlyName);
if (nm == null || !nm.getString().equals(certId))
{
bagAttrs.setBagAttribute(pkcs_9_at_friendlyName, new DERBMPString(certId));
}
Enumeration e = bagAttrs.getBagAttributeKeys();
while (e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
ASN1EncodableVector fSeq = new ASN1EncodableVector();
fSeq.add(oid);
fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
fName.add(new DERSequence(fSeq));
cAttrSet = true;
}
}
if (!cAttrSet)
{
ASN1EncodableVector fSeq = new ASN1EncodableVector();
fSeq.add(pkcs_9_at_friendlyName);
fSeq.add(new DERSet(new DERBMPString(certId)));
fName.add(new DERSequence(fSeq));
}
SafeBag sBag = new SafeBag(certBag, cBag.getDERObject(), new DERSet(fName));
certSeq.add(sBag);
doneCerts.put(cert, cert);
}
catch (CertificateEncodingException e)
{
throw new IOException("Error encoding certificate: " + e.toString());
}
}
cs = chainCerts.keys();
while (cs.hasMoreElements())
{
try
{
CertId certId = (CertId)cs.nextElement();
Certificate cert = (Certificate)chainCerts.get(certId);
if (doneCerts.get(cert) != null)
{
continue;
}
CertBag cBag = new CertBag(
x509certType,
new DEROctetString(cert.getEncoded()));
ASN1EncodableVector fName = new ASN1EncodableVector();
if (cert instanceof PKCS12BagAttributeCarrier)
{
PKCS12BagAttributeCarrier bagAttrs = (PKCS12BagAttributeCarrier)cert;
Enumeration e = bagAttrs.getBagAttributeKeys();
while (e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
ASN1EncodableVector fSeq = new ASN1EncodableVector();
fSeq.add(oid);
fSeq.add(new DERSet(bagAttrs.getBagAttribute(oid)));
fName.add(new DERSequence(fSeq));
}
}
SafeBag sBag = new SafeBag(certBag, cBag.getDERObject(), new DERSet(fName));
certSeq.add(sBag);
}
catch (CertificateEncodingException e)
{
throw new IOException("Error encoding certificate: " + e.toString());
}
}
bOut.reset();
dOut = new DEROutputStream(bOut);
dOut.writeObject(new DERSequence(certSeq));
dOut.close();
byte[] certBytes = encryptData(CERT_ALGORITHM, bOut.toByteArray(), cParams, password);
EncryptedData cInfo = new EncryptedData(data, cAlgId, new BERConstructedOctetString(certBytes));
c[0] = new ContentInfo(data, keyString);
c[1] = new ContentInfo(encryptedData, cInfo.getDERObject());
AuthenticatedSafe auth = new AuthenticatedSafe(c);
bOut.reset();
BEROutputStream berOut = new BEROutputStream(bOut);
berOut.writeObject(auth);
byte[] pkg = bOut.toByteArray();
ContentInfo mainInfo = new ContentInfo(data, new BERConstructedOctetString(pkg));
//
// create the mac
//
byte[] mSalt = new byte[20];
int itCount = MIN_ITERATIONS;
random.nextBytes(mSalt);
byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets();
MacData mData = null;
try
{
Mac mac = Mac.getInstance(id_SHA1.getId(), "BC");
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(id_SHA1.getId(), "BC");
PBEParameterSpec defParams = new PBEParameterSpec(mSalt, itCount);
PBEKeySpec pbeSpec = new PBEKeySpec(password);
mac.init(keyFact.generateSecret(pbeSpec), defParams);
mac.update(data);
byte[] res = mac.doFinal();
// BEGIN android-changed
AlgorithmIdentifier algId = new AlgorithmIdentifier(id_SHA1, DERNull.THE_ONE);
// END android-changed
DigestInfo dInfo = new DigestInfo(algId, res);
mData = new MacData(dInfo, mSalt, itCount);
}
catch (Exception e)
{
throw new IOException("error constructing MAC: " + e.toString());
}
//
// output the Pfx
//
Pfx pfx = new Pfx(mainInfo, mData);
berOut = new BEROutputStream(stream);
berOut.writeObject(pfx);
| public void | setRandom(java.security.SecureRandom rand)
this.random = rand;
| protected java.security.PrivateKey | unwrapKey(org.bouncycastle.asn1.x509.AlgorithmIdentifier algId, byte[] data, char[] password, boolean wrongPKCS12Zero)
String algorithm = algId.getObjectId().getId();
PKCS12PBEParams pbeParams = new PKCS12PBEParams((ASN1Sequence)algId.getParameters());
PBEKeySpec pbeSpec = new PBEKeySpec(password);
PrivateKey out = null;
try
{
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
algorithm, "BC");
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
SecretKey k = keyFact.generateSecret(pbeSpec);
((JCEPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero);
Cipher cipher = Cipher.getInstance(algorithm, "BC");
cipher.init(Cipher.UNWRAP_MODE, k, defParams);
// we pass "" as the key algorithm type as it is unknown at this point
out = (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY);
}
catch (Exception e)
{
throw new IOException("exception unwrapping private key - " + e.toString());
}
return out;
| protected byte[] | wrapKey(java.lang.String algorithm, java.security.Key key, org.bouncycastle.asn1.pkcs.PKCS12PBEParams pbeParams, char[] password)
PBEKeySpec pbeSpec = new PBEKeySpec(password);
byte[] out;
try
{
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(
algorithm, "BC");
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
Cipher cipher = Cipher.getInstance(algorithm, "BC");
cipher.init(Cipher.WRAP_MODE, keyFact.generateSecret(pbeSpec), defParams);
out = cipher.wrap(key);
}
catch (Exception e)
{
throw new IOException("exception encrypting data - " + e.toString());
}
return out;
|
|