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(); } }
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(); } }
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); } } }