internal static SafeSecCertificateHandle X509ImportCertificate( ReadOnlySpan <byte> bytes, X509ContentType contentType, SafePasswordHandle importPassword, out SafeSecIdentityHandle identityHandle) { SafeCreateHandle?cfPassphrase = null; bool releasePassword = false; try { if (!importPassword.IsInvalid) { importPassword.DangerousAddRef(ref releasePassword); cfPassphrase = CoreFoundation.CFStringCreateFromSpan(importPassword.DangerousGetSpan()); } return(X509ImportCertificate( bytes, contentType, cfPassphrase, out identityHandle)); } finally { if (releasePassword) { importPassword.DangerousRelease(); } cfPassphrase?.Dispose(); } }
internal static byte[] X509ExportPfx(IntPtr[] certHandles, SafePasswordHandle exportPassword) { SafeCreateHandle cfPassphrase = s_emptyExportString; bool releasePassword = false; try { if (!exportPassword.IsInvalid) { exportPassword.DangerousAddRef(ref releasePassword); IntPtr passwordHandle = exportPassword.DangerousGetHandle(); if (passwordHandle != IntPtr.Zero) { cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle); } } return(X509Export(X509ContentType.Pkcs12, cfPassphrase, certHandles)); } finally { if (releasePassword) { exportPassword.DangerousRelease(); } if (cfPassphrase != s_emptyExportString) { cfPassphrase.Dispose(); } } }
public void Decrypt(SafePasswordHandle password) { ReadOnlyMemory <byte> authSafeContents = Helpers.DecodeOctetStringAsMemory(_pfxAsn.AuthSafe.Content); bool hasRef = false; password.DangerousAddRef(ref hasRef); try { ReadOnlySpan <char> passwordChars = password.DangerousGetSpan(); if (_pfxAsn.MacData.HasValue) { VerifyAndDecrypt(passwordChars, authSafeContents); } else if (passwordChars.IsEmpty) { try { // Try the empty password first. // If anything goes wrong, try the null password. // // The same password has to work for the entirety of the file, // null and empty aren't interchangeable between parts. Decrypt("", authSafeContents); } catch (CryptographicException) { ContentInfoAsn[] partialSuccess = _safeContentsValues; _safeContentsValues = null; if (partialSuccess != null) { ReturnRentedContentInfos(partialSuccess); } Decrypt(null, authSafeContents); } } else { Decrypt(passwordChars, authSafeContents); } } catch (Exception e) { throw new CryptographicException(SR.Cryptography_Pfx_BadPassword, e) { HResult = ErrorInvalidPasswordHResult }; } finally { password.DangerousRelease(); } }
public void Dispose() { _pkcs12.Dispose(); // Only dispose the keychain if it's a temporary handle. (_keychain as SafeTemporaryKeychainHandle)?.Dispose(); SafePasswordHandle password = Interlocked.Exchange(ref _password, null); password?.DangerousRelease(); }
internal static SafeCFArrayHandle X509ImportCollection( ReadOnlySpan <byte> bytes, X509ContentType contentType, SafePasswordHandle importPassword) { SafeCreateHandle cfPassphrase = s_emptyExportString; bool releasePassword = false; SafeCFArrayHandle collectionHandle; int osStatus; try { if (!importPassword.IsInvalid) { importPassword.DangerousAddRef(ref releasePassword); IntPtr passwordHandle = importPassword.DangerousGetHandle(); if (passwordHandle != IntPtr.Zero) { cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle); } } osStatus = AppleCryptoNative_X509ImportCollection( ref MemoryMarshal.GetReference(bytes), bytes.Length, contentType, cfPassphrase, out collectionHandle); if (osStatus == 0) { return(collectionHandle); } } finally { if (releasePassword) { importPassword.DangerousRelease(); } if (cfPassphrase != s_emptyExportString) { cfPassphrase.Dispose(); } } collectionHandle.Dispose(); throw CreateExceptionForOSStatus(osStatus); }
internal static SafeCFArrayHandle X509ImportCollection( byte[] bytes, X509ContentType contentType, SafePasswordHandle importPassword, SafeKeychainHandle keychain, bool exportable) { SafeCreateHandle cfPassphrase = s_nullExportString; bool releasePassword = false; int ret; SafeCFArrayHandle collectionHandle; int osStatus; try { if (!importPassword.IsInvalid) { importPassword.DangerousAddRef(ref releasePassword); IntPtr passwordHandle = importPassword.DangerousGetHandle(); if (passwordHandle != IntPtr.Zero) { cfPassphrase = CoreFoundation.CFStringCreateWithCString(passwordHandle); } } ret = AppleCryptoNative_X509ImportCollection( bytes, bytes.Length, contentType, cfPassphrase, keychain, exportable ? 1 : 0, out collectionHandle, out osStatus); if (ret == 1) { return(collectionHandle); } } finally { if (releasePassword) { importPassword.DangerousRelease(); } if (cfPassphrase != s_nullExportString) { cfPassphrase.Dispose(); } } collectionHandle.Dispose(); const int SeeOSStatus = 0; const int ImportReturnedEmpty = -2; const int ImportReturnedNull = -3; switch (ret) { case SeeOSStatus: throw CreateExceptionForOSStatus(osStatus); case ImportReturnedNull: case ImportReturnedEmpty: throw new CryptographicException(); default: Debug.Fail($"Unexpected return value {ret}"); throw new CryptographicException(); } }
private byte[] ExportPfx(SafePasswordHandle password) { int certCount = 1; if (_singleCertPal == null) { Debug.Assert(_certs != null); certCount = _certs.Count; } CertBagAsn[] certBags = ArrayPool <CertBagAsn> .Shared.Rent(certCount); SafeBagAsn[] keyBags = ArrayPool <SafeBagAsn> .Shared.Rent(certCount); AttributeAsn[] certAttrs = ArrayPool <AttributeAsn> .Shared.Rent(certCount); certAttrs.AsSpan(0, certCount).Clear(); AsnWriter tmpWriter = new AsnWriter(AsnEncodingRules.DER); ArraySegment <byte> encodedAuthSafe = default; bool gotRef = false; password.DangerousAddRef(ref gotRef); try { ReadOnlySpan <char> passwordSpan = password.DangerousGetSpan(); int keyIdx = 0; int certIdx = 0; if (_singleCertPal != null) { BuildBags( _singleCertPal, passwordSpan, tmpWriter, certBags, certAttrs, keyBags, ref certIdx, ref keyIdx); } else { foreach (X509Certificate2 cert in _certs !) { BuildBags( cert.Pal, passwordSpan, tmpWriter, certBags, certAttrs, keyBags, ref certIdx, ref keyIdx); } } encodedAuthSafe = EncodeAuthSafe( tmpWriter, keyBags, keyIdx, certBags, certAttrs, certIdx, passwordSpan); return(MacAndEncode(tmpWriter, encodedAuthSafe, passwordSpan)); } finally { password.DangerousRelease(); certAttrs.AsSpan(0, certCount).Clear(); certBags.AsSpan(0, certCount).Clear(); keyBags.AsSpan(0, certCount).Clear(); ArrayPool <AttributeAsn> .Shared.Return(certAttrs); ArrayPool <CertBagAsn> .Shared.Return(certBags); ArrayPool <SafeBagAsn> .Shared.Return(keyBags); if (encodedAuthSafe.Array != null) { CryptoPool.Return(encodedAuthSafe); } } }