<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

Pkcs12Store

public class Pkcs12Store
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Misc; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Operators.Utilities; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Encoders; using Org.BouncyCastle.X509; using Org.BouncyCastle.X509.Extension; using System; using System.Collections.Generic; using System.IO; namespace Org.BouncyCastle.Pkcs { public class Pkcs12Store { private struct CertID : IEquatable<CertID> { private readonly byte[] m_id; internal byte[] ID => m_id; internal CertID(X509CertificateEntry certEntry) { this = new CertID(certEntry.Certificate); } internal CertID(X509Certificate cert) { this = new CertID(CreateLocalKeyID(cert)); } internal CertID(Asn1OctetString id) { m_id = id.GetOctets(); } public bool Equals(CertID other) { return Arrays.AreEqual(m_id, other.m_id); } public override bool Equals(object obj) { if (obj is CertID) { CertID other = (CertID)obj; return Equals(other); } return false; } public override int GetHashCode() { return Arrays.GetHashCode(m_id); } } public const string IgnoreUselessPasswordProperty = "Org.BouncyCastle.Pkcs12.IgnoreUselessPassword"; private readonly Dictionary<string, AsymmetricKeyEntry> m_keys = new Dictionary<string, AsymmetricKeyEntry>(StringComparer.OrdinalIgnoreCase); private readonly List<string> m_keysOrder = new List<string>(); private readonly Dictionary<string, string> m_localIDs = new Dictionary<string, string>(); private readonly Dictionary<string, X509CertificateEntry> m_certs = new Dictionary<string, X509CertificateEntry>(StringComparer.OrdinalIgnoreCase); private readonly List<string> m_certsOrder = new List<string>(); private readonly Dictionary<CertID, X509CertificateEntry> m_chainCerts = new Dictionary<CertID, X509CertificateEntry>(); private readonly List<CertID> m_chainCertsOrder = new List<CertID>(); private readonly Dictionary<string, X509CertificateEntry> m_keyCerts = new Dictionary<string, X509CertificateEntry>(StringComparer.OrdinalIgnoreCase); private readonly DerObjectIdentifier certAlgorithm; private readonly DerObjectIdentifier certPrfAlgorithm; private readonly DerObjectIdentifier keyAlgorithm; private readonly DerObjectIdentifier keyPrfAlgorithm; private readonly bool useDerEncoding; private readonly bool reverseCertificates; private readonly bool overwriteFriendlyName; private readonly bool enableOracleTrustedKeyUsage; private AsymmetricKeyEntry unmarkedKeyEntry; private const int MinIterations = 1024; private const int SaltSize = 20; public IEnumerable<string> Aliases { get { HashSet<string> hashSet = new HashSet<string>(m_certs.Keys); hashSet.UnionWith(m_keys.Keys); return CollectionUtilities.Proxy(hashSet); } } public int Count { get { int num = m_certs.Count; foreach (string key in m_keys.Keys) { if (!m_certs.ContainsKey(key)) num++; } return num; } } internal Pkcs12Store(DerObjectIdentifier certAlgorithm, DerObjectIdentifier certPrfAlgorithm, DerObjectIdentifier keyAlgorithm, DerObjectIdentifier keyPrfAlgorithm, bool useDerEncoding, bool reverseCertificates, bool overwriteFriendlyName, bool enableOracleTrustedKeyUsage) { this.certAlgorithm = certAlgorithm; this.certPrfAlgorithm = certPrfAlgorithm; this.keyAlgorithm = keyAlgorithm; this.keyPrfAlgorithm = keyPrfAlgorithm; this.useDerEncoding = useDerEncoding; this.reverseCertificates = reverseCertificates; this.overwriteFriendlyName = overwriteFriendlyName; this.enableOracleTrustedKeyUsage = enableOracleTrustedKeyUsage; } protected virtual void LoadKeyBag(PrivateKeyInfo privKeyInfo, Asn1Set bagAttributes) { AsymmetricKeyParameter key = PrivateKeyFactory.CreateKey(privKeyInfo); Dictionary<DerObjectIdentifier, Asn1Encodable> dictionary = new Dictionary<DerObjectIdentifier, Asn1Encodable>(); AsymmetricKeyEntry v = new AsymmetricKeyEntry(key, dictionary); string text = null; Asn1OctetString asn1OctetString = null; if (bagAttributes != null) { foreach (Asn1Encodable bagAttribute in bagAttributes) { Asn1Sequence instance = Asn1Sequence.GetInstance(bagAttribute); DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(instance[0]); Asn1Set instance3 = Asn1Set.GetInstance(instance[1]); if (instance3.Count >= 1) { Asn1Encodable asn1Encodable = instance3[0]; if (dictionary.TryGetValue(instance2, out Asn1Encodable value)) { if (!value.Equals(asn1Encodable)) throw new IOException("attempt to add existing attribute with different value"); } else dictionary[instance2] = asn1Encodable; if (PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Equals(instance2)) { text = DerBmpString.GetInstance(asn1Encodable).GetString(); Map(m_keys, m_keysOrder, text, v); } else if (PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Equals(instance2)) { asn1OctetString = Asn1OctetString.GetInstance(asn1Encodable); } } } } if (asn1OctetString != null) { string text2 = Hex.ToHexString(asn1OctetString.GetOctets()); if (text == null) Map(m_keys, m_keysOrder, text2, v); else m_localIDs[text] = text2; } else unmarkedKeyEntry = v; } protected virtual void LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo encPrivKeyInfo, Asn1Set bagAttributes, char[] password, bool wrongPkcs12Zero) { PrivateKeyInfo privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, wrongPkcs12Zero, encPrivKeyInfo); LoadKeyBag(privKeyInfo, bagAttributes); } public void Load(Stream input, char[] password) { if (input == null) throw new ArgumentNullException("input"); Pfx instance = Pfx.GetInstance(Asn1Object.FromStream(input)); ContentInfo authSafe = instance.AuthSafe; bool wrongPkcs12Zero = false; bool flag = false; MacData macData = instance.MacData; if (macData != null) { flag = true; if (password == null) throw new ArgumentNullException("password", "no password supplied when one expected"); byte[] octets = Asn1OctetString.GetInstance(authSafe.Content).GetOctets(); if (!VerifyPbeMac(macData, password, false, octets)) { if (password.Length != 0 || !VerifyPbeMac(macData, password, true, octets)) throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file."); wrongPkcs12Zero = true; } } Clear(m_keys, m_keysOrder); m_localIDs.Clear(); unmarkedKeyEntry = null; List<SafeBag> list = new List<SafeBag>(); if (PkcsObjectIdentifiers.Data.Equals(authSafe.ContentType)) { ContentInfo[] contentInfo = AuthenticatedSafe.GetInstance(Asn1OctetString.GetInstance(authSafe.Content).GetOctets()).GetContentInfo(); foreach (ContentInfo contentInfo2 in contentInfo) { DerObjectIdentifier contentType = contentInfo2.ContentType; byte[] array = null; if (PkcsObjectIdentifiers.Data.Equals(contentType)) array = Asn1OctetString.GetInstance(contentInfo2.Content).GetOctets(); else if (PkcsObjectIdentifiers.EncryptedData.Equals(contentType)) { flag = true; EncryptedData instance2 = EncryptedData.GetInstance(contentInfo2.Content); array = CryptPbeData(false, instance2.EncryptionAlgorithm, password, wrongPkcs12Zero, instance2.Content.GetOctets()); } if (array != null) { foreach (Asn1Encodable item in Asn1Sequence.GetInstance(array)) { SafeBag instance3 = SafeBag.GetInstance(item); DerObjectIdentifier bagID = instance3.BagID; if (PkcsObjectIdentifiers.CertBag.Equals(bagID)) list.Add(instance3); else if (PkcsObjectIdentifiers.KeyBag.Equals(bagID)) { LoadKeyBag(PrivateKeyInfo.GetInstance(instance3.BagValueEncodable), instance3.BagAttributes); } else if (PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag.Equals(bagID)) { flag = true; LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(instance3.BagValueEncodable), instance3.BagAttributes, password, wrongPkcs12Zero); } } } } } Clear(m_certs, m_certsOrder); Clear(m_chainCerts, m_chainCertsOrder); m_keyCerts.Clear(); foreach (SafeBag item2 in list) { CertBag instance4 = CertBag.GetInstance(item2.BagValueEncodable); if (!PkcsObjectIdentifiers.X509Certificate.Equals(instance4.CertID)) throw new Exception("Unsupported certificate type: " + instance4.CertID?.ToString()); X509Certificate cert = new X509Certificate(Asn1OctetString.GetInstance(instance4.CertValueEncodable).GetOctets()); Dictionary<DerObjectIdentifier, Asn1Encodable> dictionary = new Dictionary<DerObjectIdentifier, Asn1Encodable>(); Asn1OctetString asn1OctetString = null; string text = null; if (item2.BagAttributes != null) { foreach (Asn1Encodable bagAttribute in item2.BagAttributes) { Asn1Sequence instance5 = Asn1Sequence.GetInstance(bagAttribute); DerObjectIdentifier instance6 = DerObjectIdentifier.GetInstance(instance5[0]); Asn1Set instance7 = Asn1Set.GetInstance(instance5[1]); if (instance7.Count >= 1) { Asn1Encodable asn1Encodable = instance7[0]; if (dictionary.TryGetValue(instance6, out Asn1Encodable value)) { if (PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Equals(instance6)) { string key = Hex.ToHexString(Asn1OctetString.GetInstance(asn1Encodable).GetOctets()); if (!m_keys.ContainsKey(key) && !m_localIDs.ContainsKey(key)) continue; } if (!value.Equals(asn1Encodable)) throw new IOException("attempt to add existing attribute with different value"); } else dictionary[instance6] = asn1Encodable; if (PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Equals(instance6)) text = DerBmpString.GetInstance(asn1Encodable).GetString(); else if (PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Equals(instance6)) { asn1OctetString = Asn1OctetString.GetInstance(asn1Encodable); } } } } CertID k = new CertID(cert); X509CertificateEntry x509CertificateEntry = new X509CertificateEntry(cert, dictionary); Map(m_chainCerts, m_chainCertsOrder, k, x509CertificateEntry); if (unmarkedKeyEntry != null) { if (m_keyCerts.Count == 0) { string text2 = Hex.ToHexString(k.ID); m_keyCerts[text2] = x509CertificateEntry; Map(m_keys, m_keysOrder, text2, unmarkedKeyEntry); } else Map(m_keys, m_keysOrder, "unmarked", unmarkedKeyEntry); } else { if (asn1OctetString != null) { string key2 = Hex.ToHexString(asn1OctetString.GetOctets()); m_keyCerts[key2] = x509CertificateEntry; } if (text != null) Map(m_certs, m_certsOrder, text, x509CertificateEntry); } } if (!flag && password != null) { string environmentVariable = Platform.GetEnvironmentVariable("Org.BouncyCastle.Pkcs12.IgnoreUselessPassword"); if (environmentVariable == null || !Platform.EqualsIgnoreCase("true", environmentVariable)) throw new IOException("password supplied for keystore that does not require one"); } } public AsymmetricKeyEntry GetKey(string alias) { if (alias == null) throw new ArgumentNullException("alias"); return CollectionUtilities.GetValueOrNull(m_keys, alias); } public bool IsCertificateEntry(string alias) { if (alias == null) throw new ArgumentNullException("alias"); if (m_certs.ContainsKey(alias)) return !m_keys.ContainsKey(alias); return false; } public bool IsKeyEntry(string alias) { if (alias == null) throw new ArgumentNullException("alias"); return m_keys.ContainsKey(alias); } public bool ContainsAlias(string alias) { if (alias == null) throw new ArgumentNullException("alias"); if (!m_certs.ContainsKey(alias)) return m_keys.ContainsKey(alias); return true; } public X509CertificateEntry GetCertificate(string alias) { if (alias == null) throw new ArgumentNullException("alias"); if (m_certs.TryGetValue(alias, out X509CertificateEntry value)) return value; string k = alias; if (m_localIDs.TryGetValue(alias, out string value2)) k = value2; return CollectionUtilities.GetValueOrNull(m_keyCerts, k); } public string GetCertificateAlias(X509Certificate cert) { if (cert == null) throw new ArgumentNullException("cert"); Dictionary<string, X509CertificateEntry>.Enumerator enumerator = m_certs.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyValuePair<string, X509CertificateEntry> current = enumerator.Current; if (current.Value.Certificate.Equals(cert)) return current.Key; } } finally { ((IDisposable)enumerator).Dispose(); } enumerator = m_keyCerts.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyValuePair<string, X509CertificateEntry> current2 = enumerator.Current; if (current2.Value.Certificate.Equals(cert)) return current2.Key; } } finally { ((IDisposable)enumerator).Dispose(); } return null; } public X509CertificateEntry[] GetCertificateChain(string alias) { if (alias == null) throw new ArgumentNullException("alias"); if (!IsKeyEntry(alias)) return null; X509CertificateEntry x509CertificateEntry = GetCertificate(alias); if (x509CertificateEntry == null) return null; List<X509CertificateEntry> list = new List<X509CertificateEntry>(); while (x509CertificateEntry != null) { X509Certificate certificate = x509CertificateEntry.Certificate; X509CertificateEntry x509CertificateEntry2 = null; AuthorityKeyIdentifier authorityKeyIdentifier = X509ExtensionUtilities.GetAuthorityKeyIdentifier(certificate); if (authorityKeyIdentifier != null) { Asn1OctetString keyIdentifier = authorityKeyIdentifier.KeyIdentifier; if (keyIdentifier != null) x509CertificateEntry2 = CollectionUtilities.GetValueOrNull(m_chainCerts, new CertID(keyIdentifier)); } if (x509CertificateEntry2 == null) { X509Name issuerDN = certificate.IssuerDN; X509Name subjectDN = certificate.SubjectDN; if (!issuerDN.Equivalent(subjectDN)) { foreach (KeyValuePair<CertID, X509CertificateEntry> chainCert in m_chainCerts) { X509Certificate certificate2 = chainCert.Value.Certificate; if (certificate2.SubjectDN.Equivalent(issuerDN)) { try { certificate.Verify(certificate2.GetPublicKey()); x509CertificateEntry2 = chainCert.Value; } catch (InvalidKeyException) { continue; } break; } } } } list.Add(x509CertificateEntry); x509CertificateEntry = ((x509CertificateEntry2 == x509CertificateEntry) ? null : x509CertificateEntry2); } return list.ToArray(); } public void SetCertificateEntry(string alias, X509CertificateEntry certEntry) { if (alias == null) throw new ArgumentNullException("alias"); if (certEntry == null) throw new ArgumentNullException("certEntry"); if (m_keys.ContainsKey(alias)) throw new ArgumentException("There is a key entry with the name " + alias + "."); Map(m_certs, m_certsOrder, alias, certEntry); Map(m_chainCerts, m_chainCertsOrder, new CertID(certEntry), certEntry); } public void SetFriendlyName(string alias, string newFriendlyName) { if (alias == null) throw new ArgumentNullException("alias"); if (newFriendlyName == null) throw new ArgumentNullException("newFriendlyName"); if (!alias.Equals(newFriendlyName) && !overwriteFriendlyName) { if (CollectionUtilities.Remove(m_certs, alias, out X509CertificateEntry v)) { DeleteCertsEntry(newFriendlyName); v.SetFriendlyName(newFriendlyName); m_certs.Add(newFriendlyName, v); ReplaceOrdering(m_certs.Comparer, m_certsOrder, alias, newFriendlyName); } if (CollectionUtilities.Remove(m_keys, alias, out AsymmetricKeyEntry v2)) { DeleteKeysEntry(newFriendlyName); v2.SetFriendlyName(newFriendlyName); m_keys.Add(newFriendlyName, v2); ReplaceOrdering(m_keys.Comparer, m_keysOrder, alias, newFriendlyName); X509CertificateEntry v4; if (CollectionUtilities.Remove(m_localIDs, alias, out string v3)) m_localIDs.Add(newFriendlyName, v3); else if (CollectionUtilities.Remove(m_keyCerts, alias, out v4)) { v4.SetFriendlyName(newFriendlyName); m_keyCerts.Add(newFriendlyName, v4); } } } } public void SetKeyEntry(string alias, AsymmetricKeyEntry keyEntry, X509CertificateEntry[] chain) { if (alias == null) throw new ArgumentNullException("alias"); if (keyEntry == null) throw new ArgumentNullException("keyEntry"); bool flag = !Arrays.IsNullOrEmpty(chain); if (keyEntry.Key.IsPrivate && !flag) throw new ArgumentException("No certificate chain for private key", "chain"); if (m_keys.ContainsKey(alias)) DeleteEntry(alias); Map(m_keys, m_keysOrder, alias, keyEntry); if (flag) { Map(m_certs, m_certsOrder, alias, chain[0]); foreach (X509CertificateEntry x509CertificateEntry in chain) { Map(m_chainCerts, m_chainCertsOrder, new CertID(x509CertificateEntry), x509CertificateEntry); } } } public void DeleteEntry(string alias) { if (alias == null) throw new ArgumentNullException("alias"); DeleteCertsEntry(alias); DeleteKeysEntry(alias); } private void DeleteCertsEntry(string alias) { if (Remove(m_certs, m_certsOrder, alias, out X509CertificateEntry v)) Remove(m_chainCerts, m_chainCertsOrder, new CertID(v)); } private void DeleteKeysEntry(string alias) { if (Remove(m_keys, m_keysOrder, alias)) { string k = alias; if (CollectionUtilities.Remove(m_localIDs, alias, out string v)) k = v; if (CollectionUtilities.Remove(m_keyCerts, k, out X509CertificateEntry v2)) Remove(m_chainCerts, m_chainCertsOrder, new CertID(v2)); } } public bool IsEntryOfType(string alias, Type entryType) { if (entryType == typeof(X509CertificateEntry)) return IsCertificateEntry(alias); if (entryType == typeof(AsymmetricKeyEntry)) { if (IsKeyEntry(alias)) return GetCertificate(alias) != null; return false; } return false; } public void Save(Stream stream, char[] password, SecureRandom random) { if (stream == null) throw new ArgumentNullException("stream"); if (random == null) throw new ArgumentNullException("random"); Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(m_keys.Count); for (uint num = (uint)(reverseCertificates ? (m_keysOrder.Count - 1) : 0); num < m_keysOrder.Count; num = (reverseCertificates ? (num - 1) : (num + 1))) { string text = m_keysOrder[(int)num]; AsymmetricKeyEntry asymmetricKeyEntry = m_keys[text]; byte[] nextBytes = SecureRandom.GetNextBytes(random, 20); DerObjectIdentifier bagID; Asn1Encodable bagValue; if (password == null || keyAlgorithm == null) { bagID = PkcsObjectIdentifiers.KeyBag; bagValue = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymmetricKeyEntry.Key); } else { bagID = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag; bagValue = ((keyPrfAlgorithm == null) ? EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm, password, nextBytes, 1024, asymmetricKeyEntry.Key) : EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(keyAlgorithm, keyPrfAlgorithm, password, nextBytes, 1024, random, asymmetricKeyEntry.Key)); } Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(); foreach (DerObjectIdentifier bagAttributeKey in asymmetricKeyEntry.BagAttributeKeys) { if (!PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Equals(bagAttributeKey)) asn1EncodableVector2.Add(new DerSequence(bagAttributeKey, new DerSet(asymmetricKeyEntry[bagAttributeKey]))); } asn1EncodableVector2.Add(CreateEntryFriendlyName(text, asymmetricKeyEntry)); if (asymmetricKeyEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) AddLocalKeyID(asn1EncodableVector2, GetCertificate(text)); asn1EncodableVector.Add(new SafeBag(bagID, bagValue, DerSet.FromVector(asn1EncodableVector2))); } byte[] derEncoded = new DerSequence(asn1EncodableVector).GetDerEncoded(); ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded)); Asn1EncodableVector asn1EncodableVector3 = new Asn1EncodableVector(m_keys.Count); HashSet<X509Certificate> hashSet = new HashSet<X509Certificate>(); for (uint num2 = (uint)(reverseCertificates ? (m_keysOrder.Count - 1) : 0); num2 < m_keysOrder.Count; num2 = (reverseCertificates ? (num2 - 1) : (num2 + 1))) { string alias = m_keysOrder[(int)num2]; X509CertificateEntry certificate = GetCertificate(alias); CertBag bagValue2 = CreateCertBag(certificate.Certificate); Asn1EncodableVector asn1EncodableVector4 = new Asn1EncodableVector(); foreach (DerObjectIdentifier bagAttributeKey2 in certificate.BagAttributeKeys) { if (!PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Equals(bagAttributeKey2)) asn1EncodableVector4.Add(new DerSequence(bagAttributeKey2, new DerSet(certificate[bagAttributeKey2]))); } asn1EncodableVector4.Add(CreateEntryFriendlyName(alias, certificate)); if (certificate[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null) AddLocalKeyID(asn1EncodableVector4, certificate); asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, bagValue2, DerSet.FromVector(asn1EncodableVector4))); hashSet.Add(certificate.Certificate); } for (uint num3 = (uint)(reverseCertificates ? (m_certsOrder.Count - 1) : 0); num3 < m_certsOrder.Count; num3 = (reverseCertificates ? (num3 - 1) : (num3 + 1))) { string text2 = m_certsOrder[(int)num3]; X509CertificateEntry x509CertificateEntry = m_certs[text2]; if (!m_keys.ContainsKey(text2)) { CertBag bagValue3 = CreateCertBag(x509CertificateEntry.Certificate); Asn1EncodableVector asn1EncodableVector5 = new Asn1EncodableVector(); foreach (DerObjectIdentifier bagAttributeKey3 in x509CertificateEntry.BagAttributeKeys) { if (!PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Equals(bagAttributeKey3) && !PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Equals(bagAttributeKey3) && !MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage.Equals(bagAttributeKey3)) asn1EncodableVector5.Add(new DerSequence(bagAttributeKey3, new DerSet(x509CertificateEntry[bagAttributeKey3]))); } asn1EncodableVector5.Add(CreateEntryFriendlyName(text2, x509CertificateEntry)); if (enableOracleTrustedKeyUsage) { Asn1Object extensionParsedValue = x509CertificateEntry.Certificate.GetExtensionParsedValue(X509Extensions.ExtendedKeyUsage); DerSet element; if (extensionParsedValue != null) { Asn1Encodable[] allUsagesArray = ExtendedKeyUsage.GetInstance(extensionParsedValue).GetAllUsagesArray(); element = new DerSet(allUsagesArray); } else element = new DerSet(KeyPurposeID.AnyExtendedKeyUsage); asn1EncodableVector5.Add(new DerSequence(MiscObjectIdentifiers.id_oracle_pkcs12_trusted_key_usage, element)); } asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, bagValue3, DerSet.FromVector(asn1EncodableVector5))); hashSet.Add(x509CertificateEntry.Certificate); } } for (uint num4 = (uint)(reverseCertificates ? (m_chainCertsOrder.Count - 1) : 0); num4 < m_chainCertsOrder.Count; num4 = (reverseCertificates ? (num4 - 1) : (num4 + 1))) { CertID key = m_chainCertsOrder[(int)num4]; X509CertificateEntry x509CertificateEntry2 = m_chainCerts[key]; X509Certificate certificate2 = x509CertificateEntry2.Certificate; if (!hashSet.Contains(certificate2)) { CertBag bagValue4 = CreateCertBag(certificate2); Asn1EncodableVector asn1EncodableVector6 = new Asn1EncodableVector(); foreach (DerObjectIdentifier bagAttributeKey4 in x509CertificateEntry2.BagAttributeKeys) { if (!PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Equals(bagAttributeKey4)) asn1EncodableVector6.Add(new DerSequence(bagAttributeKey4, new DerSet(x509CertificateEntry2[bagAttributeKey4]))); } asn1EncodableVector3.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, bagValue4, DerSet.FromVector(asn1EncodableVector6))); } } byte[] derEncoded2 = new DerSequence(asn1EncodableVector3).GetDerEncoded(); ContentInfo contentInfo2; if (password == null || certAlgorithm == null) contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded2)); else { byte[] nextBytes2 = SecureRandom.GetNextBytes(random, 20); int num5 = 1024; AlgorithmIdentifier algorithmIdentifier; if (certPrfAlgorithm != null) { Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(certAlgorithm, certPrfAlgorithm, nextBytes2, num5, random); algorithmIdentifier = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPbeS2, parameters); } else { Pkcs12PbeParams parameters2 = new Pkcs12PbeParams(nextBytes2, num5); algorithmIdentifier = new AlgorithmIdentifier(certAlgorithm, parameters2); } byte[] contents = CryptPbeData(true, algorithmIdentifier, password, false, derEncoded2); contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, new EncryptedData(PkcsObjectIdentifiers.Data, algorithmIdentifier, new BerOctetString(contents))); } byte[] encoded = new AuthenticatedSafe(new ContentInfo[2] { contentInfo, contentInfo2 }).GetEncoded(useDerEncoding ? "DER" : "BER"); ContentInfo contentInfo3 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encoded)); MacData macData = null; if (password != null) { AlgorithmIdentifier algorithmIdentifier2 = DefaultDigestAlgorithmFinder.Instance.Find(OiwObjectIdentifiers.IdSha1); byte[] nextBytes3 = SecureRandom.GetNextBytes(random, 20); int num6 = 1024; byte[] contents2 = CalculatePbeMac(algorithmIdentifier2, nextBytes3, num6, password, false, encoded); macData = new MacData(new DigestInfo(algorithmIdentifier2, new DerOctetString(contents2)), nextBytes3, num6); } new Pfx(contentInfo3, macData).EncodeTo(stream, useDerEncoding ? "DER" : "BER"); } private DerSequence CreateEntryFriendlyName(string alias, Pkcs12Entry entry) { DerSet element = DerSet.Empty; Asn1Encodable attribute; if (overwriteFriendlyName) element = new DerSet(new DerBmpString(alias)); else if (entry.TryGetAttribute(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, out attribute)) { element = new DerSet(attribute); } return new DerSequence(PkcsObjectIdentifiers.Pkcs9AtFriendlyName, element); } internal static byte[] CalculatePbeMac(AlgorithmIdentifier macDigestAlgorithm, byte[] salt, int iterations, char[] password, bool wrongPkcs12Zero, byte[] data) { DerObjectIdentifier algorithm = macDigestAlgorithm.Algorithm; Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters(algorithm, salt, iterations); ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algorithm, password, wrongPkcs12Zero, pbeParameters); IMac obj = (IMac)PbeUtilities.CreateEngine(algorithm); obj.Init(parameters); return MacUtilities.DoFinal(obj, data); } internal static bool VerifyPbeMac(MacData macData, char[] password, bool wrongPkcs12Zero, byte[] data) { DigestInfo mac = macData.Mac; return Arrays.FixedTimeEquals(CalculatePbeMac(mac.DigestAlgorithm, macData.MacSalt.GetOctets(), macData.Iterations.IntValueExact, password, wrongPkcs12Zero, data), mac.Digest.GetOctets()); } private static void AddLocalKeyID(Asn1EncodableVector v, X509CertificateEntry certEntry) { AddLocalKeyID(v, certEntry.Certificate); } private static void AddLocalKeyID(Asn1EncodableVector v, X509Certificate c) { v.Add(new DerSequence(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID, new DerSet(CreateLocalKeyID(c)))); } private static CertBag CreateCertBag(X509Certificate c) { return new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(c.GetEncoded())); } private static Asn1OctetString CreateLocalKeyID(X509Certificate certificate) { return X509ExtensionUtilities.CalculateKeyIdentifier(certificate); } private static byte[] CryptPbeData(bool forEncryption, AlgorithmIdentifier algID, char[] password, bool wrongPkcs12Zero, byte[] data) { IBufferedCipher obj = PbeUtilities.CreateEngine(algID) as IBufferedCipher; if (obj == null) throw new Exception("Unknown encryption algorithm: " + algID.Algorithm?.ToString()); Asn1Encodable instance; if (PkcsObjectIdentifiers.IdPbeS2.Equals(algID.Algorithm)) { wrongPkcs12Zero = false; instance = PbeS2Parameters.GetInstance(algID.Parameters); } else instance = Pkcs12PbeParams.GetInstance(algID.Parameters); ICipherParameters parameters = PbeUtilities.GenerateCipherParameters(algID.Algorithm, password, wrongPkcs12Zero, instance); obj.Init(forEncryption, parameters); return obj.DoFinal(data); } private static void Clear<K, V>(Dictionary<K, V> d, List<K> o) { d.Clear(); o.Clear(); } private static void Map<K, V>(Dictionary<K, V> d, List<K> o, K k, V v) { if (d.ContainsKey(k)) RemoveOrdering(d.Comparer, o, k); o.Add(k); d[k] = v; } private static bool Remove<K, V>(Dictionary<K, V> d, List<K> o, K k) { bool num = d.Remove(k); if (num) RemoveOrdering(d.Comparer, o, k); return num; } private static bool Remove<K, V>(Dictionary<K, V> d, List<K> o, K k, out V v) { bool num = CollectionUtilities.Remove(d, k, out v); if (num) RemoveOrdering(d.Comparer, o, k); return num; } private static void RemoveOrdering<K>(IEqualityComparer<K> c, List<K> o, K k) { int num = o.FindIndex((Predicate<K>)((K e) => c.Equals(k, e))); if (num >= 0) o.RemoveAt(num); } private static void ReplaceOrdering<K>(IEqualityComparer<K> c, List<K> o, K oldKey, K newKey) { int num = o.FindIndex((Predicate<K>)((K e) => c.Equals(oldKey, e))); if (num >= 0) o[num] = newKey; } } }