public override void PerformTest() { Asn1Sequence obj = (Asn1Sequence) Asn1Object.FromByteArray(pkcs12); Pfx bag = new Pfx(obj); ContentInfo info = bag.AuthSafe; MacData mData = bag.MacData; DigestInfo dInfo = mData.Mac; AlgorithmIdentifier algId = dInfo.AlgorithmID; byte[] salt = mData.GetSalt(); int itCount = mData.IterationCount.IntValue; byte[] octets = ((Asn1OctetString) info.Content).GetOctets(); AuthenticatedSafe authSafe = new AuthenticatedSafe( (Asn1Sequence) Asn1Object.FromByteArray(octets)); ContentInfo[] c = authSafe.GetContentInfo(); // // private key section // if (!c[0].ContentType.Equals(PkcsObjectIdentifiers.Data)) { Fail("Failed comparison data test"); } octets = ((Asn1OctetString)c[0].Content).GetOctets(); Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets); SafeBag b = new SafeBag((Asn1Sequence)seq[0]); if (!b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag)) { Fail("Failed comparison shroudedKeyBag test"); } EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(b.BagValue); encInfo = new EncryptedPrivateKeyInfo(encInfo.EncryptionAlgorithm, encInfo.GetEncryptedData()); b = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, encInfo.ToAsn1Object(), b.BagAttributes); byte[] encodedBytes = new DerSequence(b).GetEncoded(); c[0] = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encodedBytes)); // // certificates // if (!c[1].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData)) { Fail("Failed comparison encryptedData test"); } EncryptedData eData = EncryptedData.GetInstance(c[1].Content); c[1] = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, eData); // // create an octet stream to represent the BER encoding of authSafe // authSafe = new AuthenticatedSafe(c); info = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(authSafe.GetEncoded())); mData = new MacData(new DigestInfo(algId, dInfo.GetDigest()), salt, itCount); bag = new Pfx(info, mData); // // comparison test // if (!Arrays.AreEqual(bag.GetEncoded(), pkcs12)) { Fail("Failed comparison test"); } }
public void Save( Stream stream, char[] password, SecureRandom random) { if (stream == null) throw new ArgumentNullException("stream"); if (password == null) throw new ArgumentNullException("password"); if (random == null) throw new ArgumentNullException("random"); ContentInfo[] c = new ContentInfo[2]; // // handle the key // Asn1EncodableVector keyS = new Asn1EncodableVector(); foreach (string name in keys.Keys) { byte[] kSalt = new byte[saltSize]; random.NextBytes(kSalt); AsymmetricKeyEntry privKey = (AsymmetricKeyEntry) keys[name]; EncryptedPrivateKeyInfo kInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo( keyAlgorithm, password, kSalt, minIterations, privKey.Key); Asn1EncodableVector kName = new Asn1EncodableVector(); foreach (string oid in privKey.BagAttributeKeys) { kName.Add( new DerSequence( new DerObjectIdentifier(oid), new DerSet(privKey[oid]))); } // // make sure we have a local key-id // if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { X509CertificateEntry ct = GetCertificate(name); SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( ct.Certificate.GetPublicKey()); kName.Add( new DerSequence( PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(new SubjectKeyIdentifier(info)))); } // // make sure we are using the local alias on store // DerBmpString nm = (DerBmpString) privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName]; if (nm == null || !nm.GetString().Equals(name)) { kName.Add( new DerSequence( PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(name)))); } SafeBag kBag = new SafeBag(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag, kInfo.ToAsn1Object(), new DerSet(kName)); keyS.Add(kBag); } byte[] derEncodedBytes = new DerSequence(keyS).GetDerEncoded(); BerOctetString keyString = new BerOctetString(derEncodedBytes); // // certificate 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(); foreach (string name in keys.Keys) { X509CertificateEntry certEntry = GetCertificate(name); CertBag cBag = new CertBag( PkcsObjectIdentifiers.X509CertType, new DerOctetString(certEntry.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in certEntry.BagAttributeKeys) { fName.Add( new DerSequence( new DerObjectIdentifier(oid), new DerSet(certEntry[oid]))); } // // make sure we are using the local alias on store // DerBmpString nm = (DerBmpString)certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName]; if (nm == null || !nm.GetString().Equals(name)) { fName.Add( new DerSequence( PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(name)))); } // // make sure we have a local key-id // if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) { SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( certEntry.Certificate.GetPublicKey()); fName.Add( new DerSequence( PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(new SubjectKeyIdentifier(info)))); } SafeBag sBag = new SafeBag( PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); doneCerts.Add(certEntry.Certificate, certEntry.Certificate); } foreach (string certId in certs.Keys) { X509CertificateEntry cert = (X509CertificateEntry)certs[certId]; if (keys[certId] != null) { continue; } CertBag cBag = new CertBag( PkcsObjectIdentifiers.X509CertType, new DerOctetString(cert.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in cert.BagAttributeKeys) { fName.Add( new DerSequence( new DerObjectIdentifier(oid), new DerSet(cert[oid]))); } // // make sure we are using the local alias on store // DerBmpString nm = (DerBmpString) cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName]; if (nm == null || !nm.GetString().Equals(certId)) { fName.Add( new DerSequence( PkcsObjectIdentifiers.Pkcs9AtFriendlyName, new DerSet(new DerBmpString(certId)))); } SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); doneCerts.Add(cert, cert); } foreach (CertId certId in chainCerts.Keys) { X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId]; if (doneCerts[cert] != null) { continue; } CertBag cBag = new CertBag( PkcsObjectIdentifiers.X509CertType, new DerOctetString(cert.Certificate.GetEncoded())); Asn1EncodableVector fName = new Asn1EncodableVector(); foreach (string oid in cert.BagAttributeKeys) { fName.Add(new DerSequence(new DerObjectIdentifier(oid), new DerSet(cert[oid]))); } SafeBag sBag = new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)); certSeq.Add(sBag); } derEncodedBytes = new DerSequence(certSeq).GetDerEncoded(); byte[] certBytes = EncryptData(new AlgorithmIdentifier(certAlgorithm, cParams), derEncodedBytes, 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); byte[] pkg = auth.GetEncoded(); 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.Content).GetOctets(); Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(OiwObjectIdentifiers.IdSha1, mSalt, itCount); ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters( OiwObjectIdentifiers.IdSha1, password, parameters); IMac mac = (IMac)PbeUtilities.CreateEngine(OiwObjectIdentifiers.IdSha1); mac.Init(keyParameters); mac.BlockUpdate(data, 0, data.Length); byte[] res = new byte[mac.GetMacSize()]; mac.DoFinal(res, 0); AlgorithmIdentifier algId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); DigestInfo dInfo = new DigestInfo(algId, res); MacData mData = new MacData(dInfo, mSalt, itCount); // // output the Pfx // Pfx pfx = new Pfx(mainInfo, mData); BerOutputStream berOut = new BerOutputStream(stream); berOut.WriteObject(pfx); }