}
//
// 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(keyAlgorithm.getId(), privKey, kParams, password);
AlgorithmIdentifier kAlgId = new AlgorithmIdentifier(keyAlgorithm, kParams.getDERObject());
org.bouncycastle2.asn1.pkcs.EncryptedPrivateKeyInfo kInfo = new org.bouncycastle2.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);
}
byte[] keySEncoded = new DERSequence(keyS).getDEREncoded();
BERConstructedOctetString keyString = new BERConstructedOctetString(keySEncoded);
//
// certificate 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(certAlgorithm, 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(
x509Certificate,
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(
x509Certificate,
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();
// a certificate not immediately linked to a key doesn't require
// a localKeyID and will confuse some PKCS12 implementations.
//
// If we find one, we'll prune it out.
if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
{
continue;
}
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(
x509Certificate,
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();
// a certificate not immediately linked to a key doesn't require
// a localKeyID and will confuse some PKCS12 implementations.
//
// If we find one, we'll prune it out.
if (oid.equals(PKCSObjectIdentifiers.pkcs_9_at_localKeyId))
{
continue;
}
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));