// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *EncodeKeyTransRecipientInfo(CmsRecipient recipient, HeapBlockRetainer hb) { // "recipient" is a deep-cloned CmsRecipient object whose lifetime this class controls. Because of this, we can pull out the CERT_CONTEXT* and CERT_INFO* pointers // and embed pointers to them in the memory block we return. Yes, this code is scary. // // (The use of SafeCertContextHandle here is about using a consistent pattern to get the CERT_CONTEXT (rather than the ugly (CERT_CONTEXT*)(recipient.Certificate.Handle) pattern.) // It's not about keeping the context alive.) using (SafeCertContextHandle hCertContext = recipient.Certificate.CreateCertContextHandle()) { CERT_CONTEXT *pCertContext = hCertContext.DangerousGetCertContext(); CERT_INFO * pCertInfo = pCertContext->pCertInfo; CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *pEncodeInfo = (CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); pEncodeInfo->cbSize = sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO); CRYPT_ALGORITHM_IDENTIFIER algId = pCertInfo->SubjectPublicKeyInfo.Algorithm; pEncodeInfo->KeyEncryptionAlgorithm = algId; pEncodeInfo->pvKeyEncryptionAuxInfo = IntPtr.Zero; pEncodeInfo->hCryptProv = IntPtr.Zero; pEncodeInfo->RecipientPublicKey = pCertInfo->SubjectPublicKeyInfo.PublicKey; pEncodeInfo->RecipientId = EncodeRecipientId(recipient, hCertContext, pCertContext, pCertInfo, hb); return(pEncodeInfo); } }
/// <summary> /// A less error-prone wrapper for CertEnumCertificatesInStore(). /// /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle /// and returns "false" to indicate the end of the store has been reached. /// </summary> public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertFindType dwFindType, void *pvFindPara, [NotNull] ref SafeCertContextHandle?pCertContext) { CERT_CONTEXT *pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect(); pCertContext = CertFindCertificateInStore(hCertStore, CertEncodingType.All, CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext); return(!pCertContext.IsInvalid); }
public unsafe CERT_CONTEXT *Disconnect() { CERT_CONTEXT *pCertContext = (CERT_CONTEXT *)handle; SetHandle(IntPtr.Zero); return(pCertContext); }
internal static unsafe partial SafeCertContextHandle CertFindCertificateInStore( SafeCertStoreHandle hCertStore, CertEncodingType dwCertEncodingType, CertFindFlags dwFindFlags, CertFindType dwFindType, void *pvFindPara, CERT_CONTEXT *pPrevCertContext);
public static void TestHandle() { // // Ensure that the Handle property returns a valid CER_CONTEXT pointer. // using (X509Certificate2 c = new X509Certificate2(TestData.MsCertificate)) { IntPtr h = c.Handle; unsafe { CERT_CONTEXT *pCertContext = (CERT_CONTEXT *)h; // Does the blob data match? int cbCertEncoded = pCertContext->cbCertEncoded; Assert.Equal(TestData.MsCertificate.Length, cbCertEncoded); byte[] pCertEncoded = new byte[cbCertEncoded]; Marshal.Copy((IntPtr)(pCertContext->pbCertEncoded), pCertEncoded, 0, cbCertEncoded); Assert.Equal(TestData.MsCertificate, pCertEncoded); // Does the serial number match? CERT_INFO *pCertInfo = pCertContext->pCertInfo; byte[] serialNumber = pCertInfo->SerialNumber.ToByteArray(); byte[] expectedSerial = "b00000000100dd9f3bd08b0aaf11b000000033".HexToByteArray(); Assert.Equal(expectedSerial, serialNumber); } } }
/// <summary> /// A less error-prone wrapper for CertEnumCertificatesInStore(). /// /// To begin the enumeration, set pCertContext to null. Each iteration replaces pCertContext with /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle /// and returns "false" to indicate the end of the store has been reached. /// </summary> public static bool CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, ref SafeCertContextHandle pCertContext) { unsafe { CERT_CONTEXT *pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect(); pCertContext = CertEnumCertificatesInStore(hCertStore, pPrevCertContext); return(!pCertContext.IsInvalid); } }
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(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.CurrentUser, openExistingOnly: true)); candidateCerts.AddRange(Helpers.GetStoreCertificates(StoreName.AddressBook, StoreLocation.LocalMachine, openExistingOnly: true)); candidateCerts.AddRange(originatorCerts); candidateCerts.AddRange(extraStore); SubjectIdentifier originatorId = pKeyAgreeRecipientInfo->OriginatorCertId.ToSubjectIdentifier(); using (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)); } })); } }
public void Remove(ICertificatePal certificate) { unsafe { SafeCertContextHandle existingCertContext = ((CertificatePal)certificate).CertContext; SafeCertContextHandle enumCertContext = null; CERT_CONTEXT * pCertContext = existingCertContext.CertContext; if (!Interop.crypt32.CertFindCertificateInStore(_certStore, CertFindType.CERT_FIND_EXISTING, pCertContext, ref enumCertContext)) { return; // The certificate is not present in the store, simply return. } CERT_CONTEXT *pCertContextToDelete = enumCertContext.Disconnect(); // CertDeleteCertificateFromContext always frees the context (even on error) if (!Interop.crypt32.CertDeleteCertificateFromStore(pCertContextToDelete)) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } GC.KeepAlive(existingCertContext); } }
internal static unsafe partial CERT_CONTEXT *CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT *pPrevCertContext);
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *EncodeKeyTransRecipientInfo(CmsRecipient recipient, HeapBlockRetainer hb) { // "recipient" is a deep-cloned CmsRecipient object whose lifetime this class controls. Because of this, we can pull out the CERT_CONTEXT* and CERT_INFO* pointers // and embed pointers to them in the memory block we return. Yes, this code is scary. // // (The use of SafeCertContextHandle here is about using a consistent pattern to get the CERT_CONTEXT (rather than the ugly (CERT_CONTEXT*)(recipient.Certificate.Handle) pattern.) // It's not about keeping the context alive.) using (SafeCertContextHandle hCertContext = recipient.Certificate.CreateCertContextHandle()) { CERT_CONTEXT *pCertContext = hCertContext.DangerousGetCertContext(); CERT_INFO * pCertInfo = pCertContext->pCertInfo; CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *pEncodeInfo = (CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); pEncodeInfo->cbSize = sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO); RSAEncryptionPadding padding = recipient.RSAEncryptionPadding; if (padding is null) { if (recipient.Certificate.GetKeyAlgorithm() == Oids.RsaOaep) { byte[] parameters = recipient.Certificate.GetKeyAlgorithmParameters(); if (parameters == null || parameters.Length == 0) { padding = RSAEncryptionPadding.OaepSHA1; } else if (!PkcsHelpers.TryGetRsaOaepEncryptionPadding(parameters, out padding, out _)) { throw ErrorCode.CRYPT_E_UNKNOWN_ALGO.ToCryptographicException(); } } else { // gost falls in here padding = RSAEncryptionPadding.Pkcs1; } } if (padding == RSAEncryptionPadding.Pkcs1) { // begin: gost switch (recipient.Certificate.GetKeyAlgorithm()) { case Oids.Gost3410: case Oids.Gost3410_2012_256: case Oids.Gost3410_2012_512: { // copy from cert info explicitly pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(recipient.Certificate.GetKeyAlgorithm()); // uint, копируем pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData; // копируем из памяти и записываем var pbDataBytes = new byte[pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData]; Marshal.Copy(pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData, pbDataBytes, 0, pbDataBytes.Length); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(pbDataBytes); break; } default: { // end: gost pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.Rsa); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaPkcsParameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaPkcsParameters); break; } } } else if (padding == RSAEncryptionPadding.OaepSHA1) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha1Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha1Parameters); } else if (padding == RSAEncryptionPadding.OaepSHA256) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha256Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha256Parameters); } else if (padding == RSAEncryptionPadding.OaepSHA384) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha384Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha384Parameters); } else if (padding == RSAEncryptionPadding.OaepSHA512) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha512Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha512Parameters); } else { throw ErrorCode.CRYPT_E_UNKNOWN_ALGO.ToCryptographicException(); } pEncodeInfo->pvKeyEncryptionAuxInfo = IntPtr.Zero; pEncodeInfo->hCryptProv = IntPtr.Zero; pEncodeInfo->RecipientPublicKey = pCertInfo->SubjectPublicKeyInfo.PublicKey; pEncodeInfo->RecipientId = EncodeRecipientId(recipient, hCertContext, pCertContext, pCertInfo, hb); return(pEncodeInfo); } }
public static unsafe partial bool CertDeleteCertificateFromStore(CERT_CONTEXT *pCertContext);
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *EncodeKeyTransRecipientInfo(CmsRecipient recipient, HeapBlockRetainer hb) { // "recipient" is a deep-cloned CmsRecipient object whose lifetime this class controls. Because of this, we can pull out the CERT_CONTEXT* and CERT_INFO* pointers // and embed pointers to them in the memory block we return. Yes, this code is scary. // // (The use of SafeCertContextHandle here is about using a consistent pattern to get the CERT_CONTEXT (rather than the ugly (CERT_CONTEXT*)(recipient.Certificate.Handle) pattern.) // It's not about keeping the context alive.) using (SafeCertContextHandle hCertContext = recipient.Certificate.CreateCertContextHandle()) { CERT_CONTEXT *pCertContext = hCertContext.DangerousGetCertContext(); CERT_INFO * pCertInfo = pCertContext->pCertInfo; CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *pEncodeInfo = (CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO))); pEncodeInfo->cbSize = sizeof(CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO); if (recipient.RSAEncryptionPadding is null) { CRYPT_ALGORITHM_IDENTIFIER algId = pCertInfo->SubjectPublicKeyInfo.Algorithm; pEncodeInfo->KeyEncryptionAlgorithm = algId; } else if (recipient.RSAEncryptionPadding == RSAEncryptionPadding.Pkcs1) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.Rsa); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaPkcsParameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaPkcsParameters); } else if (recipient.RSAEncryptionPadding == RSAEncryptionPadding.OaepSHA1) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha1Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha1Parameters); } else if (recipient.RSAEncryptionPadding == RSAEncryptionPadding.OaepSHA256) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha256Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha256Parameters); } else if (recipient.RSAEncryptionPadding == RSAEncryptionPadding.OaepSHA384) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha384Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha384Parameters); } else if (recipient.RSAEncryptionPadding == RSAEncryptionPadding.OaepSHA512) { pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.RsaOaep); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = (uint)s_rsaOaepSha512Parameters.Length; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = hb.AllocBytes(s_rsaOaepSha512Parameters); } else { throw ErrorCode.CRYPT_E_UNKNOWN_ALGO.ToCryptographicException(); } pEncodeInfo->pvKeyEncryptionAuxInfo = IntPtr.Zero; pEncodeInfo->hCryptProv = IntPtr.Zero; pEncodeInfo->RecipientPublicKey = pCertInfo->SubjectPublicKeyInfo.PublicKey; pEncodeInfo->RecipientId = EncodeRecipientId(recipient, hCertContext, pCertContext, pCertInfo, hb); return(pEncodeInfo); } }
public static extern unsafe bool CertDeleteCertificateFromStore(CERT_CONTEXT *pCertContext);
private static extern unsafe SafeCertContextHandle CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT *pPrevCertContext);
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO *EncodeKeyAgreeRecipientInfo(CmsRecipient recipient, AlgorithmIdentifier contentEncryptionAlgorithm, HeapBlockRetainer hb) { // "recipient" is a deep-cloned CmsRecipient object whose lifetime this class controls. Because of this, we can pull out the CERT_CONTEXT* and CERT_INFO* pointers without // bringing in all the SafeCertContextHandle machinery, and embed pointers to them in the memory block we return. Yes, this code is scary. using (SafeCertContextHandle hCertContext = recipient.Certificate.CreateCertContextHandle()) { CERT_CONTEXT *pCertContext = hCertContext.DangerousGetCertContext(); CERT_INFO * pCertInfo = pCertContext->pCertInfo; CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO *pEncodeInfo = (CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO))); pEncodeInfo->cbSize = sizeof(CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO); pEncodeInfo->KeyEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(Oids.Esdh); pEncodeInfo->KeyEncryptionAlgorithm.Parameters.cbData = 0; pEncodeInfo->KeyEncryptionAlgorithm.Parameters.pbData = IntPtr.Zero; pEncodeInfo->pvKeyEncryptionAuxInfo = null; string oidValue; AlgId algId = contentEncryptionAlgorithm.Oid.Value.ToAlgId(); if (algId == AlgId.CALG_RC2) { oidValue = Oids.CmsRc2Wrap; } else { oidValue = Oids.Cms3DesWrap; } pEncodeInfo->KeyWrapAlgorithm.pszObjId = hb.AllocAsciiString(oidValue); pEncodeInfo->KeyWrapAlgorithm.Parameters.cbData = 0; pEncodeInfo->KeyWrapAlgorithm.Parameters.pbData = IntPtr.Zero; pEncodeInfo->pvKeyWrapAuxInfo = GenerateEncryptionAuxInfoIfNeeded(contentEncryptionAlgorithm, hb); pEncodeInfo->hCryptProv = IntPtr.Zero; pEncodeInfo->dwKeySpec = 0; pEncodeInfo->dwKeyChoice = CmsKeyAgreeKeyChoice.CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE; pEncodeInfo->pEphemeralAlgorithm = (CRYPT_ALGORITHM_IDENTIFIER *)(hb.Alloc(sizeof(CRYPT_ALGORITHM_IDENTIFIER))); *(pEncodeInfo->pEphemeralAlgorithm) = pCertInfo->SubjectPublicKeyInfo.Algorithm; pEncodeInfo->UserKeyingMaterial.cbData = 0; pEncodeInfo->UserKeyingMaterial.pbData = IntPtr.Zero; CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO *pEncryptedKey = (CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO *)(hb.Alloc(sizeof(CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))); pEncryptedKey->cbSize = sizeof(CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO); pEncryptedKey->RecipientPublicKey = pCertInfo->SubjectPublicKeyInfo.PublicKey; pEncryptedKey->RecipientId = EncodeRecipientId(recipient, hCertContext, pCertContext, pCertInfo, hb); pEncryptedKey->Date = default(FILETIME); pEncryptedKey->pOtherAttr = null; CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO **ppEncryptedKey = (CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO **)(hb.Alloc(sizeof(CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO *))); ppEncryptedKey[0] = pEncryptedKey; pEncodeInfo->cRecipientEncryptedKeys = 1; pEncodeInfo->rgpRecipientEncryptedKeys = ppEncryptedKey; return(pEncodeInfo); } }
public static unsafe extern CERT_CONTEXT *CertEnumCertificatesInStore( #endif IntPtr hCertStore, CERT_CONTEXT *pPrevCertContext);
public static unsafe partial CERT_CONTEXT *CertEnumCertificatesInStore( IntPtr hCertStore, CERT_CONTEXT *pPrevCertContext);
// // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". // private static unsafe CERT_ID EncodeRecipientId(CmsRecipient recipient, SafeCertContextHandle hCertContext, CERT_CONTEXT *pCertContext, CERT_INFO *pCertInfo, HeapBlockRetainer hb) { CERT_ID recipientId = default(CERT_ID); SubjectIdentifierType type = recipient.RecipientIdentifierType; switch (type) { case SubjectIdentifierType.IssuerAndSerialNumber: { recipientId.dwIdChoice = CertIdChoice.CERT_ID_ISSUER_SERIAL_NUMBER; recipientId.u.IssuerSerialNumber.Issuer = pCertInfo->Issuer; recipientId.u.IssuerSerialNumber.SerialNumber = pCertInfo->SerialNumber; break; } case SubjectIdentifierType.SubjectKeyIdentifier: { byte[] ski = hCertContext.GetSubjectKeyIdentifer(); IntPtr pSki = hb.AllocBytes(ski); recipientId.dwIdChoice = CertIdChoice.CERT_ID_KEY_IDENTIFIER; recipientId.u.KeyId.cbData = (uint)(ski.Length); recipientId.u.KeyId.pbData = pSki; break; } default: // The public contract for CmsRecipient guarantees that SubjectKeyIdentifier and IssuerAndSerialNumber are the only two possibilities. Debug.Fail($"Unexpected SubjectIdentifierType: {type}"); throw new NotSupportedException(SR.Format(SR.Cryptography_Cms_Invalid_Subject_Identifier_Type, type)); } return(recipientId); }