public void setKeyEntry( String alias, AsymmetricKeyEntry keyEntry, X509CertificateEntry[] chain) { if (keyEntry.getKey().isPrivate() && (chain == null)) { throw new ArgumentException("No certificate chain for private key"); } if (keys[alias] != null && !keyEntry.getKey().Equals(keys[alias])) { throw new ArgumentException("There is already a key with the name " + alias + "."); } keys.Add(alias, keyEntry); certs.Add(alias, chain[0]); for (int i = 0; i != chain.Length; i++) { chainCerts.Add(new CertId(chain[i].getCertificate().getPublicKey()), chain[i]); } }
public void save(Stream stream, char[] password, SecureRandom random) { if (password == null) { throw new ArgumentException("No password supplied for PKCS12Store."); } ContentInfo[] c = new ContentInfo[2]; // // handle the key // ASN1EncodableVector keyS = new ASN1EncodableVector(); IEnumerator ks = keys.Keys.GetEnumerator(); while (ks.MoveNext()) { byte[] kSalt = new byte[saltSize]; random.nextBytes(kSalt); String name = (String)ks.Current; AsymmetricKeyEntry privKey = (AsymmetricKeyEntry)keys[name]; EncryptedPrivateKeyInfo kInfo = EncryptedPrivateKeyInfoFactory.createEncryptedPrivateKeyInfo(keyAlgorithm, password, kSalt, minIterations, privKey.getKey()); ASN1EncodableVector kName = new ASN1EncodableVector(); IEnumerator e = privKey.getBagAttributeKeys(); while (e.MoveNext()) { String oid = (String)e.Current; ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(new DERObjectIdentifier(oid)); kSeq.add(new DERSet(privKey.getBagAttribute(new DERObjectIdentifier(oid)))); kName.add(new DERSequence(kSeq)); } // // make sure we have a local key-id // if (privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null) { ASN1EncodableVector kSeq = new ASN1EncodableVector(); X509CertificateEntry ct = getCertificate(name); kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId); kSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(ct.getCertificate().getPublicKey())))); kName.add(new DERSequence(kSeq)); } // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)privKey.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); if (nm == null || !nm.getString().Equals(name)) { ASN1EncodableVector kSeq = new ASN1EncodableVector(); kSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); kSeq.add(new DERSet(new DERBMPString(name))); kName.add(new DERSequence(kSeq)); } SafeBag kBag = new SafeBag(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag, kInfo.toASN1Object(), new DERSet(kName)); keyS.add(kBag); } MemoryStream bOut = new MemoryStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(new DERSequence(keyS)); BEROctetString keyString = new BEROctetString(bOut.ToArray()); // // certficate processing // byte[] cSalt = new byte[saltSize]; random.nextBytes(cSalt); ASN1EncodableVector certSeq = new ASN1EncodableVector(); PKCS12PBEParams cParams = new PKCS12PBEParams(cSalt, minIterations); AlgorithmIdentifier cAlgId = new AlgorithmIdentifier(certAlgorithm, cParams.toASN1Object()); Hashtable doneCerts = new Hashtable(); IEnumerator cs = keys.Keys.GetEnumerator(); while (cs.MoveNext()) { try { String name = (String)cs.Current; X509CertificateEntry cert = getCertificate(name); CertBag cBag = new CertBag( PKCSObjectIdentifiers.x509certType, new DEROctetString(cert.getCertificate().getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); IEnumerator e = cert.getBagAttributeKeys(); while (e.MoveNext()) { String oid = (String)e.Current; ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(new DERObjectIdentifier(oid)); fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid)))); fName.add(new DERSequence(fSeq)); } // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); if (nm == null || !nm.getString().Equals(name)) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(name))); fName.add(new DERSequence(fSeq)); } // // make sure we have a local key-id // if (cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId) == null) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_localKeyId); fSeq.add(new DERSet(new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(cert.getCertificate().getPublicKey())))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); doneCerts.Add(cert, cert); } catch (Exception e) { throw new Exception("Error encoding certificate: " + e.Message); } } cs = certs.Keys.GetEnumerator(); while (cs.MoveNext()) { try { String certId = (String)cs.Current; X509CertificateEntry cert = (X509CertificateEntry)certs[certId]; if (keys[certId] != null) { continue; } CertBag cBag = new CertBag( PKCSObjectIdentifiers.x509certType, new DEROctetString(cert.getCertificate().getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); IEnumerator e = cert.getBagAttributeKeys(); while (e.MoveNext()) { String oid = (String)e.Current; ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(new DERObjectIdentifier(oid)); fSeq.add(new DERSet(cert.getBagAttribute(new DERObjectIdentifier(oid)))); fName.add(new DERSequence(fSeq)); } // // make sure we are using the local alias on store // DERBMPString nm = (DERBMPString)cert.getBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); if (nm == null || !nm.getString().Equals(certId)) { ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(PKCSObjectIdentifiers.pkcs_9_at_friendlyName); fSeq.add(new DERSet(new DERBMPString(certId))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); doneCerts.Add(cert, cert); } catch (Exception e) { throw new Exception("Error encoding certificate: " + e.Message); } } cs = chainCerts.Keys.GetEnumerator(); while (cs.MoveNext()) { try { CertId certId = (CertId)cs.Current; X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId]; if (doneCerts[cert] != null) { continue; } CertBag cBag = new CertBag( PKCSObjectIdentifiers.x509certType, new DEROctetString(cert.getCertificate().getEncoded())); ASN1EncodableVector fName = new ASN1EncodableVector(); IEnumerator e = cert.getBagAttributeKeys(); while (e.MoveNext()) { DERObjectIdentifier oid = (DERObjectIdentifier)e.Current; ASN1EncodableVector fSeq = new ASN1EncodableVector(); fSeq.add(oid); fSeq.add(new DERSet(cert.getBagAttribute(oid))); fName.add(new DERSequence(fSeq)); } SafeBag sBag = new SafeBag(PKCSObjectIdentifiers.certBag, cBag.toASN1Object(), new DERSet(fName)); certSeq.add(sBag); } catch (Exception e) { throw new Exception("Error encoding certificate: " + e.Message); } } bOut = new MemoryStream(); dOut = new DEROutputStream(bOut); dOut.writeObject(new DERSequence(certSeq)); dOut.Close(); byte[] certBytes = encryptData(new AlgorithmIdentifier(certAlgorithm, cParams), bOut.ToArray(), password); EncryptedData cInfo = new EncryptedData(PKCSObjectIdentifiers.data, cAlgId, new BEROctetString(certBytes)); c[0] = new ContentInfo(PKCSObjectIdentifiers.data, keyString); c[1] = new ContentInfo(PKCSObjectIdentifiers.encryptedData, cInfo.toASN1Object()); AuthenticatedSafe auth = new AuthenticatedSafe(c); bOut = new MemoryStream(); BEROutputStream berOut = new BEROutputStream(bOut); berOut.writeObject(auth); byte[] pkg = bOut.ToArray(); ContentInfo mainInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(pkg)); // // create the mac // byte[] mSalt = new byte[20]; int itCount = minIterations; random.nextBytes(mSalt); byte[] data = ((ASN1OctetString)mainInfo.getContent()).getOctets(); MacData mData = null; try { ASN1Encodable parameters = PBEUtil.generateAlgorithmParameters(OIWObjectIdentifiers.id_SHA1, mSalt, itCount); CipherParameters keyParameters = PBEUtil.generateCipherParameters(OIWObjectIdentifiers.id_SHA1, password, parameters); Mac mac = (Mac)PBEUtil.createEngine(OIWObjectIdentifiers.id_SHA1); mac.init(keyParameters); mac.update(data, 0, data.Length); byte[] res = new byte[mac.getMacSize()]; mac.doFinal(res, 0); AlgorithmIdentifier algId = new AlgorithmIdentifier(OIWObjectIdentifiers.id_SHA1, new DERNull()); DigestInfo dInfo = new DigestInfo(algId, res); mData = new MacData(dInfo, mSalt, itCount); } catch (Exception e) { throw new Exception("error constructing MAC: " + e.Message); } // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); berOut = new BEROutputStream(stream); berOut.writeObject(pfx); }