public void MoveTo(X509Certificate2Collection collection) { foreach (UnixPkcs12Reader.CertAndKey certAndKey in _pkcs12.EnumerateAll()) { AppleCertificatePal pal = (AppleCertificatePal)certAndKey.Cert !; SafeSecKeyRefHandle?safeSecKeyRefHandle = ApplePkcs12Reader.GetPrivateKey(certAndKey.Key); using (safeSecKeyRefHandle) { ICertificatePal newPal; // SecItemImport doesn't seem to respect non-exportable import for PKCS#8, // only PKCS#12. // // So, as part of reading this PKCS#12 we now need to write the minimum // PKCS#12 in a normalized form, and ask the OS to import it. if (!_exportable && safeSecKeyRefHandle != null) { newPal = AppleCertificatePal.ImportPkcs12NonExportable( pal, safeSecKeyRefHandle, _password, _keychain); } else { newPal = pal.MoveToKeychain(_keychain, safeSecKeyRefHandle) ?? pal; } X509Certificate2 cert = new X509Certificate2(newPal); collection.Add(cert); } } }
private static ICertificatePal ImportPkcs12( byte[] rawData, SafePasswordHandle password, bool exportable, SafeKeychainHandle keychain) { using (ApplePkcs12Reader reader = new ApplePkcs12Reader(rawData)) { reader.Decrypt(password); UnixPkcs12Reader.CertAndKey certAndKey = reader.GetSingleCert(); AppleCertificatePal pal = (AppleCertificatePal)certAndKey.Cert !; SafeSecKeyRefHandle?safeSecKeyRefHandle = ApplePkcs12Reader.GetPrivateKey(certAndKey.Key); AppleCertificatePal?newPal; using (safeSecKeyRefHandle) { // SecItemImport doesn't seem to respect non-exportable import for PKCS#8, // only PKCS#12. // // So, as part of reading this PKCS#12 we now need to write the minimum // PKCS#12 in a normalized form, and ask the OS to import it. if (!exportable && safeSecKeyRefHandle != null) { using (pal) { return(ImportPkcs12NonExportable(pal, safeSecKeyRefHandle, password, keychain)); } } newPal = pal.MoveToKeychain(keychain, safeSecKeyRefHandle); if (newPal != null) { pal.Dispose(); } } // If no new PAL came back, it means we moved the cert, but had no private key. return(newPal ?? pal); } }