private AsnWriter WritePkcs8() { PrivateKeyInfoAsn info = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = { Algorithm = AlgorithmId, }, PrivateKey = PrivateKeyBytes, }; if (AlgorithmParameters?.Length > 0) { info.PrivateKeyAlgorithm.Parameters = AlgorithmParameters; } if (Attributes.Count > 0) { info.Attributes = PkcsHelpers.NormalizeAttributeSet(CmsSigner.BuildAttributes(Attributes).ToArray()); } // Write in BER in case any of the provided fields was BER. AsnWriter writer = new AsnWriter(AsnEncodingRules.BER); info.Encode(writer); return(writer); }
public bool MatchesCertificate(X509Certificate2 certificate) { switch (Type) { case SubjectIdentifierType.IssuerAndSerialNumber: { X509IssuerSerial issuerSerial = (X509IssuerSerial)Value; byte[] serialNumber = issuerSerial.SerialNumber.ToSerialBytes(); string issuer = issuerSerial.IssuerName; byte[] certSerialNumber = certificate.GetSerialNumber(); return(PkcsHelpers.AreByteArraysEqual(certSerialNumber, serialNumber) && certificate.Issuer == issuer); } case SubjectIdentifierType.SubjectKeyIdentifier: { string skiString = (string)Value; byte[] ski = skiString.ToSkiBytes(); byte[] candidateSki = PkcsPal.Instance.GetSubjectKeyIdentifier(certificate); return(PkcsHelpers.AreByteArraysEqual(ski, candidateSki)); } default: // SubjectIdentifier can only be created by this package so if this an invalid type, it's the package's fault. Debug.Fail($"Invalid SubjectIdentifierType: {Type}"); throw new CryptographicException(); } }
private bool VerifyData(ReadOnlySpan <byte> data) { Oid hashAlgorithmId = TokenInfo.HashAlgorithmId; HashAlgorithmName hashAlgorithmName = PkcsHelpers.GetDigestAlgorithm(hashAlgorithmId); using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithmName)) { hasher.AppendData(data); // SHA-2-512 is the biggest hash we currently know about. Span <byte> stackSpan = stackalloc byte[512 / 8]; if (hasher.TryGetHashAndReset(stackSpan, out int bytesWritten)) { return(VerifyHash(stackSpan.Slice(0, bytesWritten), hashAlgorithmId.Value)); } // Something we understood, but is bigger than 512-bit. // Allocate at runtime, trip in a debug build so we can re-evaluate this. Debug.Fail( $"TryGetHashAndReset did not fit in {stackSpan.Length} for hash {hashAlgorithmId.Value}"); return(VerifyHash(hasher.GetHashAndReset(), hashAlgorithmId.Value)); } }
internal Pkcs12SafeContents(ContentInfoAsn contentInfoAsn) { IsReadOnly = true; switch (contentInfoAsn.ContentType) { case Oids.Pkcs7Encrypted: ConfidentialityMode = Pkcs12ConfidentialityMode.Password; _encrypted = contentInfoAsn.Content; break; case Oids.Pkcs7Enveloped: ConfidentialityMode = Pkcs12ConfidentialityMode.PublicKey; _encrypted = contentInfoAsn.Content; break; case Oids.Pkcs7Data: ConfidentialityMode = Pkcs12ConfidentialityMode.None; _bags = ReadBags(PkcsHelpers.DecodeOctetStringAsMemory(contentInfoAsn.Content)); break; default: throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } }
public byte[] Encode() { if (!_hasData) { throw new InvalidOperationException(SR.Cryptography_Cms_MessageNotSigned); } return(PkcsHelpers.EncodeContentInfo(_signedData, Oids.Pkcs7Signed)); }
public X509Certificate2 GetCertificate() { if (!IsX509Certificate) { throw new InvalidOperationException(SR.Cryptography_Pkcs12_CertBagNotX509); } return(new X509Certificate2(PkcsHelpers.DecodeOctetString(_decoded.CertValue))); }
// // Private methods. // private static DateTime Decode(byte[]?rawData) { if (rawData == null) { return(default(DateTime)); } return(PkcsHelpers.DecodeUtcTime(rawData)); }
public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes)) { byte[] encodedContent; if (contentInfo.ContentType.Value !.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase)) { encodedContent = PkcsHelpers.EncodeOctetString(contentInfo.Content); }
private static byte[]? Decode(byte[]?rawData) { if (rawData == null) { return(null); } return(PkcsHelpers.DecodeOctetString(rawData)); }
// // Private methods. // private static string Decode(byte[] rawData) { if (rawData == null) { return(null); } byte[] octets = PkcsHelpers.DecodeOctetString(rawData); return(octets.OctetStringToUnicode()); }
private static byte[] Encode(string documentDescription) { if (documentDescription == null) { throw new ArgumentNullException(nameof(documentDescription)); } byte[] octets = documentDescription.UnicodeToOctetString(); return(PkcsHelpers.EncodeOctetString(octets)); }
private static Oid?Decode(byte[]?rawData) { if (rawData == null) { return(null); } string contentTypeValue = PkcsHelpers.DecodeOid(rawData); return(new Oid(contentTypeValue)); }
private Exception?TryDecryptAgree(KeyAgreeRecipientInfo keyAgreeRecipientInfo, SafeProvOrNCryptKeyHandle hKey, CryptKeySpec keySpec, X509Certificate2Collection originatorCerts, X509Certificate2Collection extraStore) { unsafe { KeyAgreeRecipientInfoPalWindows pal = (KeyAgreeRecipientInfoPalWindows)(keyAgreeRecipientInfo.Pal); return(pal.WithCmsgCmsRecipientInfo <Exception?>( delegate(CMSG_KEY_AGREE_RECIPIENT_INFO * pKeyAgreeRecipientInfo) { CMSG_CTRL_KEY_AGREE_DECRYPT_PARA decryptPara = default(CMSG_CTRL_KEY_AGREE_DECRYPT_PARA); decryptPara.cbSize = Marshal.SizeOf <CMSG_CTRL_KEY_AGREE_DECRYPT_PARA>(); decryptPara.hProv = hKey; decryptPara.dwKeySpec = keySpec; decryptPara.pKeyAgree = pKeyAgreeRecipientInfo; decryptPara.dwRecipientIndex = pal.Index; decryptPara.dwRecipientEncryptedKeyIndex = pal.SubIndex; CMsgKeyAgreeOriginatorChoice originatorChoice = pKeyAgreeRecipientInfo->dwOriginatorChoice; switch (originatorChoice) { case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_CERT: { X509Certificate2Collection candidateCerts = new X509Certificate2Collection(); candidateCerts.AddRange(PkcsHelpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.CurrentUser, openExistingOnly: true)); candidateCerts.AddRange(PkcsHelpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.LocalMachine, openExistingOnly: true)); candidateCerts.AddRange(originatorCerts); candidateCerts.AddRange(extraStore); SubjectIdentifier originatorId = pKeyAgreeRecipientInfo->OriginatorCertId.ToSubjectIdentifier(); X509Certificate2?originatorCert = candidateCerts.TryFindMatchingCertificate(originatorId); if (originatorCert == null) { return ErrorCode.CRYPT_E_NOT_FOUND.ToCryptographicException(); } using (SafeCertContextHandle hCertContext = originatorCert.CreateCertContextHandle()) { CERT_CONTEXT *pOriginatorCertContext = hCertContext.DangerousGetCertContext(); decryptPara.OriginatorPublicKey = pOriginatorCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey; // Do not factor this call out of the switch statement as leaving this "using" block will free up // native memory that decryptPara points to. return TryExecuteDecryptAgree(ref decryptPara); } } case CMsgKeyAgreeOriginatorChoice.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY: { decryptPara.OriginatorPublicKey = pKeyAgreeRecipientInfo->OriginatorPublicKeyInfo.PublicKey; return TryExecuteDecryptAgree(ref decryptPara); } default: return new CryptographicException(SR.Format(SR.Cryptography_Cms_Invalid_Originator_Identifier_Choice, originatorChoice)); } })); } }
internal Pkcs12CertBag(X509Certificate2 cert) : base( Oids.Pkcs12CertBag, EncodeBagValue( Oids.Pkcs12X509CertBagType, PkcsHelpers.EncodeOctetString(cert.RawData)), skipCopy: true) { _decoded = CertBagAsn.Decode(EncodedBagValue, AsnEncodingRules.BER); IsX509Certificate = true; }
public byte[] Encode() { if (!_hasData) { throw new InvalidOperationException(SR.Cryptography_Cms_MessageNotSigned); } using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { _signedData.Encode(writer); return(PkcsHelpers.EncodeContentInfo(writer.Encode(), Oids.Pkcs7Signed)); } }
protected Pkcs12SafeBag(string bagIdValue, ReadOnlyMemory <byte> encodedBagValue, bool skipCopy = false) { if (string.IsNullOrEmpty(bagIdValue)) { throw new ArgumentNullException(nameof(bagIdValue)); } // Read to ensure that there is precisely one legally encoded value. PkcsHelpers.EnsureSingleBerValue(encodedBagValue.Span); _bagIdValue = bagIdValue; EncodedBagValue = skipCopy ? encodedBagValue : encodedBagValue.ToArray(); }
public override void AddCertsFromStoreForDecryption(X509Certificate2Collection certs) { certs.AddRange(PkcsHelpers.GetStoreCertificates(StoreName.My, StoreLocation.CurrentUser, openExistingOnly: false)); try { // This store exists on macOS, but not Linux certs.AddRange( PkcsHelpers.GetStoreCertificates(StoreName.My, StoreLocation.LocalMachine, openExistingOnly: false)); } catch (CryptographicException) { } }
private static unsafe void AddCryptAttribute(CryptographicAttributeObjectCollection collection, CRYPT_ATTRIBUTE *pCryptAttribute) { string oidValue = pCryptAttribute->pszObjId.ToStringAnsi(); Oid oid = new Oid(oidValue); AsnEncodedDataCollection attributeCollection = new AsnEncodedDataCollection(); for (int i = 0; i < pCryptAttribute->cValue; i++) { byte[] encodedAttribute = pCryptAttribute->rgValue[i].ToByteArray(); AsnEncodedData attributeObject = PkcsHelpers.CreateBestPkcs9AttributeObjectAvailable(oid, encodedAttribute); attributeCollection.Add(attributeObject); } collection.Add(new CryptographicAttributeObject(oid, attributeCollection)); }
public Pkcs12SecretBag AddSecret(Oid secretType, ReadOnlyMemory <byte> secretValue) { if (secretType is null) { throw new ArgumentNullException(nameof(secretType)); } // Read to ensure that there is precisely one legally encoded value. PkcsHelpers.EnsureSingleBerValue(secretValue.Span); Pkcs12SecretBag bag = new Pkcs12SecretBag(secretType, secretValue); AddSafeBag(bag); return(bag); }
public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes)) { byte[] encodedContent; if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase)) { encodedContent = PkcsHelpers.EncodeOctetString(contentInfo.Content); } else { encodedContent = contentInfo.Content; if (encodedContent.Length > 0) { // Windows will throw if it encounters indefinite length encoding. // Let's reencode if that is the case ReencodeIfUsingIndefiniteLengthEncodingOnOuterStructure(ref encodedContent); } } if (encodedContent.Length > 0) { // Pin to avoid copy during heap compaction fixed(byte *pinnedContent = encodedContent) { try { if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true)) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } } finally { if (!object.ReferenceEquals(encodedContent, contentInfo.Content)) { Array.Clear(encodedContent, 0, encodedContent.Length); } } } } byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM); return(encodedMessage); } }
private static unsafe void AddCryptAttribute(CryptographicAttributeObjectCollection collection, CRYPT_ATTRIBUTE *pCryptAttribute) { string oidValue = pCryptAttribute->pszObjId.ToStringAnsi(); Oid oid = new Oid(oidValue); AsnEncodedDataCollection attributeCollection = new AsnEncodedDataCollection(); for (int i = 0; i < pCryptAttribute->cValue; i++) { // CreateBestPkcs9AttributeObjectAvailable is expected to create a copy of the data so that it has ownership // of the underlying data. ReadOnlySpan <byte> encodedAttribute = pCryptAttribute->rgValue[i].DangerousAsSpan(); AsnEncodedData attributeObject = PkcsHelpers.CreateBestPkcs9AttributeObjectAvailable(oid, encodedAttribute); attributeCollection.Add(attributeObject); } collection.Add(new CryptographicAttributeObject(oid, attributeCollection)); }
private byte[] EncryptContent( ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, out byte[] cek, out byte[] parameterBytes) { using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) using (ICryptoTransform encryptor = alg.CreateEncryptor()) { cek = alg.Key; if (alg is RC2) { Rc2CbcParameters rc2Params = new Rc2CbcParameters(alg.IV, alg.KeySize); using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { rc2Params.Encode(writer); parameterBytes = writer.Encode(); } } else { parameterBytes = PkcsHelpers.EncodeOctetString(alg.IV); } byte[] toEncrypt = contentInfo.Content; if (contentInfo.ContentType.Value == Oids.Pkcs7Data) { return encryptor.OneShot(toEncrypt); } else { if (contentInfo.Content.Length == 0) { return encryptor.OneShot(contentInfo.Content); } else { AsnReader reader = new AsnReader(contentInfo.Content, AsnEncodingRules.BER); return encryptor.OneShot(reader.PeekContentBytes().ToArray()); } } } }
public byte[] Encode() { if (!_hasData) { throw new InvalidOperationException(SR.Cryptography_Cms_MessageNotSigned); } try { using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { _signedData.Encode(writer); return(PkcsHelpers.EncodeContentInfo(writer.Encode(), Oids.Pkcs7Signed)); } } catch (CryptographicException) when(!Detached) { // If we can't write the contents back out then the most likely culprit is an // indefinite length encoding in the content field. To preserve as much input data // as possible while still maintaining our expectations of sorting any SET OF values, // do the following: // * Write the DER normalized version of the SignedData in detached mode. // * BER-decode that structure // * Copy the content field over // * BER-write the modified structure. SignedDataAsn copy = _signedData; copy.EncapContentInfo.Content = null; Debug.Assert(_signedData.EncapContentInfo.Content != null); using (AsnWriter detachedWriter = new AsnWriter(AsnEncodingRules.DER)) { copy.Encode(detachedWriter); copy = SignedDataAsn.Decode(detachedWriter.Encode(), AsnEncodingRules.BER); } copy.EncapContentInfo.Content = _signedData.EncapContentInfo.Content; using (AsnWriter attachedWriter = new AsnWriter(AsnEncodingRules.BER)) { copy.Encode(attachedWriter); return(PkcsHelpers.EncodeContentInfo(attachedWriter.Encode(), Oids.Pkcs7Signed)); } } }
public static Rfc3161TimestampRequest CreateFromHash( ReadOnlyMemory <byte> hash, HashAlgorithmName hashAlgorithm, Oid requestedPolicyId = null, ReadOnlyMemory <byte>?nonce = null, bool requestSignerCertificates = false, X509ExtensionCollection extensions = null) { string oidStr = PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm); return(CreateFromHash( hash, new Oid(oidStr, oidStr), requestedPolicyId, nonce, requestSignerCertificates, extensions)); }
internal static byte[]? DecryptCekCore( X509Certificate2?cert, RSA?privateKey, ReadOnlySpan <byte> encryptedKey, string?keyEncryptionAlgorithm, ReadOnlyMemory <byte>?algorithmParameters, out Exception?exception) { RSAEncryptionPadding?encryptionPadding; switch (keyEncryptionAlgorithm) { case Oids.Rsa: encryptionPadding = RSAEncryptionPadding.Pkcs1; break; case Oids.RsaOaep: if (!PkcsHelpers.TryGetRsaOaepEncryptionPadding(algorithmParameters, out encryptionPadding, out exception)) { return(null); } break; default: exception = new CryptographicException( SR.Cryptography_Cms_UnknownAlgorithm, keyEncryptionAlgorithm); return(null); } if (privateKey != null) { return(DecryptKey(privateKey, encryptionPadding, encryptedKey, out exception)); } else { Debug.Assert(cert != null); using (RSA? rsa = cert.GetRSAPrivateKey()) { return(DecryptKey(rsa, encryptionPadding, encryptedKey, out exception)); } } }
public void RemoveSignature(int index) { if (!_hasData) { throw new InvalidOperationException(SR.Cryptography_Cms_MessageNotSigned); } if (index < 0 || index >= _signedData.SignerInfos.Length) { throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index); } AlgorithmIdentifierAsn signerAlgorithm = _signedData.SignerInfos[index].DigestAlgorithm; PkcsHelpers.RemoveAt(ref _signedData.SignerInfos, index); ConsiderDigestRemoval(signerAlgorithm); UpdateMetadata(); }
public Pkcs8PrivateKeyInfo( Oid algorithmId, ReadOnlyMemory <byte>?algorithmParameters, ReadOnlyMemory <byte> privateKey, bool skipCopies = false) { if (algorithmId == null) { throw new ArgumentNullException(nameof(algorithmId)); } if (algorithmParameters?.Length > 0) { // Read to ensure that there is precisely one legally encoded value. PkcsHelpers.EnsureSingleBerValue(algorithmParameters.Value.Span); } AlgorithmId = algorithmId; AlgorithmParameters = skipCopies ? algorithmParameters : algorithmParameters?.ToArray(); PrivateKeyBytes = skipCopies ? privateKey : privateKey.ToArray(); Attributes = new CryptographicAttributeObjectCollection(); }
public bool VerifySignatureForHash( ReadOnlySpan <byte> hash, HashAlgorithmName hashAlgorithm, [NotNullWhen(true)] out X509Certificate2?signerCertificate, X509Certificate2Collection?extraCandidates = null) { signerCertificate = null; X509Certificate2?cert = GetSignerCertificate(extraCandidates); if (cert == null) { return(false); } if (VerifyHash(hash, PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm))) { signerCertificate = cert; return(true); } return(false); }
public bool VerifySignatureForHash( ReadOnlySpan <byte> hash, HashAlgorithmName hashAlgorithm, out X509Certificate2 signerCertificate, X509Certificate2Collection extraCandidates = null) { signerCertificate = null; X509Certificate2 cert = GetSignerCertificate(extraCandidates); if (cert == null) { return(false); } bool ret = VerifyHash(hash, PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm)); if (ret) { signerCertificate = cert; } return(ret); }
public void SealWithMac( ReadOnlySpan <char> password, HashAlgorithmName hashAlgorithm, int iterationCount) { if (iterationCount < 1) { throw new ArgumentOutOfRangeException(nameof(iterationCount)); } if (IsSealed) { throw new InvalidOperationException(SR.Cryptography_Pkcs12_PfxIsSealed); } byte[]? rentedAuthSafe = null; Span <byte> authSafeSpan = default; byte[]? rentedMac = null; Span <byte> macSpan = default; Span <byte> salt = stackalloc byte[0]; try { AsnWriter contentsWriter = new AsnWriter(AsnEncodingRules.BER); using (IncrementalHash hasher = IncrementalHash.CreateHash(hashAlgorithm)) { contentsWriter.PushSequence(); if (_contents != null) { foreach (ContentInfoAsn contentInfo in _contents) { contentInfo.Encode(contentsWriter); } } contentsWriter.PopSequence(); rentedAuthSafe = CryptoPool.Rent(contentsWriter.GetEncodedLength()); if (!contentsWriter.TryEncode(rentedAuthSafe, out int written)) { Debug.Fail("TryEncode failed with a pre-allocated buffer"); throw new InvalidOperationException(); } authSafeSpan = rentedAuthSafe.AsSpan(0, written); // Get an array of the proper size for the hash. byte[] macKey = hasher.GetHashAndReset(); rentedMac = CryptoPool.Rent(macKey.Length); macSpan = rentedMac.AsSpan(0, macKey.Length); // Since the biggest supported hash is SHA-2-512 (64 bytes), the // 128-byte cap here shouldn't ever come into play. Debug.Assert(macKey.Length <= 128); salt = stackalloc byte[Math.Min(macKey.Length, 128)]; RandomNumberGenerator.Fill(salt); Pkcs12Kdf.DeriveMacKey( password, hashAlgorithm, iterationCount, salt, macKey); using (IncrementalHash mac = IncrementalHash.CreateHMAC(hashAlgorithm, macKey)) { mac.AppendData(authSafeSpan); if (!mac.TryGetHashAndReset(macSpan, out int bytesWritten) || bytesWritten != macSpan.Length) { Debug.Fail($"TryGetHashAndReset wrote {bytesWritten} of {macSpan.Length} bytes"); throw new CryptographicException(); } } } // https://tools.ietf.org/html/rfc7292#section-4 // // PFX ::= SEQUENCE { // version INTEGER {v3(3)}(v3,...), // authSafe ContentInfo, // macData MacData OPTIONAL // } AsnWriter writer = new AsnWriter(AsnEncodingRules.BER); { writer.PushSequence(); writer.WriteInteger(3); writer.PushSequence(); { writer.WriteObjectIdentifierForCrypto(Oids.Pkcs7Data); Asn1Tag contextSpecific0 = new Asn1Tag(TagClass.ContextSpecific, 0); writer.PushSequence(contextSpecific0); { writer.WriteOctetString(authSafeSpan); writer.PopSequence(contextSpecific0); } writer.PopSequence(); } // https://tools.ietf.org/html/rfc7292#section-4 // // MacData ::= SEQUENCE { // mac DigestInfo, // macSalt OCTET STRING, // iterations INTEGER DEFAULT 1 // -- Note: The default is for historical reasons and its use is // -- deprecated. // } writer.PushSequence(); { writer.PushSequence(); { writer.PushSequence(); { writer.WriteObjectIdentifierForCrypto(PkcsHelpers.GetOidFromHashAlgorithm(hashAlgorithm)); writer.PopSequence(); } writer.WriteOctetString(macSpan); writer.PopSequence(); } writer.WriteOctetString(salt); if (iterationCount > 1) { writer.WriteInteger(iterationCount); } writer.PopSequence(); } writer.PopSequence(); _sealedData = writer.Encode(); } } finally { CryptographicOperations.ZeroMemory(macSpan); CryptographicOperations.ZeroMemory(authSafeSpan); if (rentedMac != null) { // Already cleared CryptoPool.Return(rentedMac, clearSize: 0); } if (rentedAuthSafe != null) { // Already cleared CryptoPool.Return(rentedAuthSafe, clearSize: 0); } } }