Ejemplo n.º 1
0
            //
            // 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);
                }
            }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        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);
Ejemplo n.º 5
0
        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);
                }
            }
        }
Ejemplo n.º 6
0
 /// <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);
     }
 }
Ejemplo n.º 7
0
        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));
                    }
                }));
            }
        }
Ejemplo n.º 8
0
        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);
Ejemplo n.º 10
0
            //
            // 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);
                }
            }
Ejemplo n.º 11
0
 public static unsafe partial bool CertDeleteCertificateFromStore(CERT_CONTEXT *pCertContext);
Ejemplo n.º 12
0
            //
            // 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);
                }
            }
Ejemplo n.º 13
0
 public static extern unsafe bool CertDeleteCertificateFromStore(CERT_CONTEXT *pCertContext);
Ejemplo n.º 14
0
 private static extern unsafe SafeCertContextHandle CertEnumCertificatesInStore(SafeCertStoreHandle hCertStore, CERT_CONTEXT *pPrevCertContext);
Ejemplo n.º 15
0
            //
            // 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);
                }
            }
Ejemplo n.º 16
0
        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);
Ejemplo n.º 18
0
            //
            // 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);
            }