private static unsafe int GetCspParams(RecipientInfo recipientInfo, X509Certificate2Collection extraStore, ref CMSG_DECRYPT_PARAM cmsgDecryptParam)
        {
            int num = -2146889717;
            System.Security.Cryptography.SafeCertContextHandle invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle;
            System.Security.Cryptography.SafeCertStoreHandle hCertStore = BuildDecryptorStore(extraStore);
            switch (recipientInfo.Type)
            {
                case RecipientInfoType.KeyTransport:
                    if (recipientInfo.SubType != RecipientSubType.Pkcs7KeyTransport)
                    {
                        System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO cmsgRecipientInfo = (System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) recipientInfo.CmsgRecipientInfo;
                        invalidHandle = System.Security.Cryptography.CAPI.CertFindCertificateInStore(hCertStore, 0x10001, 0, 0x100000, new IntPtr((void*) &cmsgRecipientInfo.RecipientId), System.Security.Cryptography.SafeCertContextHandle.InvalidHandle);
                        break;
                    }
                    invalidHandle = System.Security.Cryptography.CAPI.CertFindCertificateInStore(hCertStore, 0x10001, 0, 0xb0000, recipientInfo.pCmsgRecipientInfo.DangerousGetHandle(), System.Security.Cryptography.SafeCertContextHandle.InvalidHandle);
                    break;

                case RecipientInfoType.KeyAgreement:
                {
                    KeyAgreeRecipientInfo info = (KeyAgreeRecipientInfo) recipientInfo;
                    System.Security.Cryptography.CAPI.CERT_ID recipientId = info.RecipientId;
                    invalidHandle = System.Security.Cryptography.CAPI.CertFindCertificateInStore(hCertStore, 0x10001, 0, 0x100000, new IntPtr((void*) &recipientId), System.Security.Cryptography.SafeCertContextHandle.InvalidHandle);
                    break;
                }
                default:
                    num = -2147483647;
                    break;
            }
            if ((invalidHandle == null) || invalidHandle.IsInvalid)
            {
                return num;
            }
            System.Security.Cryptography.SafeCryptProvHandle hCryptProv = System.Security.Cryptography.SafeCryptProvHandle.InvalidHandle;
            uint pdwKeySpec = 0;
            bool pfCallerFreeProv = false;
            CspParameters parameters = new CspParameters();
            if (!System.Security.Cryptography.X509Certificates.X509Utils.GetPrivateKeyInfo(invalidHandle, ref parameters))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            if ((string.Compare(parameters.ProviderName, "Microsoft Base Cryptographic Provider v1.0", StringComparison.OrdinalIgnoreCase) == 0) && (System.Security.Cryptography.CAPI.CryptAcquireContext(ref hCryptProv, parameters.KeyContainerName, "Microsoft Enhanced Cryptographic Provider v1.0", 1, 0) || System.Security.Cryptography.CAPI.CryptAcquireContext(ref hCryptProv, parameters.KeyContainerName, "Microsoft Strong Cryptographic Provider", 1, 0)))
            {
                cmsgDecryptParam.safeCryptProvHandle = hCryptProv;
            }
            cmsgDecryptParam.safeCertContextHandle = invalidHandle;
            cmsgDecryptParam.keySpec = (uint) parameters.KeyNumber;
            num = 0;
            if ((hCryptProv != null) && !hCryptProv.IsInvalid)
            {
                return num;
            }
            if (System.Security.Cryptography.CAPI.CAPISafe.CryptAcquireCertificatePrivateKey(invalidHandle, 6, IntPtr.Zero, ref hCryptProv, ref pdwKeySpec, ref pfCallerFreeProv))
            {
                if (!pfCallerFreeProv)
                {
                    GC.SuppressFinalize(hCryptProv);
                }
                cmsgDecryptParam.safeCryptProvHandle = hCryptProv;
                return num;
            }
            return Marshal.GetHRForLastWin32Error();
        }
Ejemplo n.º 2
0
        private unsafe static int /* HRESULT */ GetCspParams (RecipientInfo recipientInfo,
                                                              X509Certificate2Collection extraStore,
                                                              ref CMSG_DECRYPT_PARAM cmsgDecryptParam) {
            int hr = CAPI.CRYPT_E_RECIPIENT_NOT_FOUND;
            SafeCertContextHandle safeCertContextHandle = SafeCertContextHandle.InvalidHandle;
            SafeCertStoreHandle safeCertStoreHandle = BuildDecryptorStore(extraStore);

            switch (recipientInfo.Type) {
            case RecipientInfoType.KeyTransport:
                if (recipientInfo.SubType == RecipientSubType.Pkcs7KeyTransport) {
                    safeCertContextHandle = CAPI.CertFindCertificateInStore(safeCertStoreHandle, 
                                                                            CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                            0, 
                                                                            CAPI.CERT_FIND_SUBJECT_CERT,
                                                                            recipientInfo.pCmsgRecipientInfo.DangerousGetHandle(), 
                                                                            SafeCertContextHandle.InvalidHandle);
                }
                else {
                    CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) recipientInfo.CmsgRecipientInfo;
                    safeCertContextHandle = CAPI.CertFindCertificateInStore(safeCertStoreHandle, 
                                                                            CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                            0, 
                                                                            CAPI.CERT_FIND_CERT_ID,
                                                                            new IntPtr((byte *) &keyTrans.RecipientId), 
                                                                            SafeCertContextHandle.InvalidHandle);
                }
                break;

            case RecipientInfoType.KeyAgreement:
                KeyAgreeRecipientInfo keyAgree = (KeyAgreeRecipientInfo) recipientInfo;
                CAPI.CERT_ID recipientId = keyAgree.RecipientId;
                safeCertContextHandle = CAPI.CertFindCertificateInStore(safeCertStoreHandle, 
                                                                        CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                        0, 
                                                                        CAPI.CERT_FIND_CERT_ID,
                                                                        new IntPtr(&recipientId),
                                                                        SafeCertContextHandle.InvalidHandle);
                break;

            default: // Others not supported.
                hr = CAPI.E_NOTIMPL;
                break;
            }

            // Acquire CSP if the recipient's cert is found.
            if (safeCertContextHandle != null && !safeCertContextHandle.IsInvalid) {
                SafeCryptProvHandle safeCryptProvHandle = SafeCryptProvHandle.InvalidHandle;
                uint keySpec = 0;
                bool freeCsp = false;

                // Check to see if KEY_PROV_INFO contains "MS Base ..."
                // If so, acquire "MS Enhanced..." or "MS Strong".
                // if failed, then use CryptAcquireCertificatePrivateKey
                CspParameters parameters = new CspParameters();
                if (X509Utils.GetPrivateKeyInfo(safeCertContextHandle, ref parameters) == false)
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                
                if (String.Compare(parameters.ProviderName, CAPI.MS_DEF_PROV, StringComparison.OrdinalIgnoreCase) == 0) {
                    if (CAPI.CryptAcquireContext(ref safeCryptProvHandle, parameters.KeyContainerName, CAPI.MS_ENHANCED_PROV, CAPI.PROV_RSA_FULL, 0) ||
                        CAPI.CryptAcquireContext(ref safeCryptProvHandle, parameters.KeyContainerName, CAPI.MS_STRONG_PROV,   CAPI.PROV_RSA_FULL, 0)) {
                            cmsgDecryptParam.safeCryptProvHandle = safeCryptProvHandle;
                    }
                }

                cmsgDecryptParam.safeCertContextHandle = safeCertContextHandle;
                cmsgDecryptParam.keySpec = (uint)parameters.KeyNumber;
                hr = CAPI.S_OK;

                if ((safeCryptProvHandle == null) || (safeCryptProvHandle.IsInvalid)) {
                    if (CAPI.CAPISafe.CryptAcquireCertificatePrivateKey(safeCertContextHandle,
                                                                        CAPI.CRYPT_ACQUIRE_COMPARE_KEY_FLAG | CAPI.CRYPT_ACQUIRE_USE_PROV_INFO_FLAG,
                                                                        IntPtr.Zero,
                                                                        ref safeCryptProvHandle,
                                                                        ref keySpec,
                                                                        ref freeCsp)) {
                        if (!freeCsp) {
                            GC.SuppressFinalize(safeCryptProvHandle);
                        }

                        cmsgDecryptParam.safeCryptProvHandle = safeCryptProvHandle;
                    }
                    else {
                        hr = Marshal.GetHRForLastWin32Error();
                    }
                }
            }

            return hr;
        }
 private unsafe void DecryptContent(RecipientInfoCollection recipientInfos, X509Certificate2Collection extraStore)
 {
     int hr = -2146889717;
     if ((this.m_safeCryptMsgHandle == null) || this.m_safeCryptMsgHandle.IsInvalid)
     {
         throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_NoEncryptedMessageToEncode"));
     }
     for (int i = 0; i < recipientInfos.Count; i++)
     {
         System.Security.Cryptography.SafeCertContextHandle invalidHandle;
         KeyAgreeRecipientInfo info2;
         System.Security.Cryptography.CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA cmsg_ctrl_key_agree_decrypt_para;
         System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO cmsg_key_agree_public_key_recipient_info;
         RecipientInfo recipientInfo = recipientInfos[i];
         CMSG_DECRYPT_PARAM cmsgDecryptParam = new CMSG_DECRYPT_PARAM();
         int num3 = GetCspParams(recipientInfo, extraStore, ref cmsgDecryptParam);
         if (num3 != 0)
         {
             goto Label_02F1;
         }
         CspParameters parameters = new CspParameters();
         if (!System.Security.Cryptography.X509Certificates.X509Utils.GetPrivateKeyInfo(cmsgDecryptParam.safeCertContextHandle, ref parameters))
         {
             throw new CryptographicException(Marshal.GetLastWin32Error());
         }
         KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
         KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Decrypt | KeyContainerPermissionFlags.Open);
         permission.AccessEntries.Add(accessEntry);
         permission.Demand();
         switch (recipientInfo.Type)
         {
             case RecipientInfoType.KeyTransport:
             {
                 System.Security.Cryptography.CAPI.CMSG_CTRL_DECRYPT_PARA cmsg_ctrl_decrypt_para = new System.Security.Cryptography.CAPI.CMSG_CTRL_DECRYPT_PARA(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_CTRL_DECRYPT_PARA))) {
                     hCryptProv = cmsgDecryptParam.safeCryptProvHandle.DangerousGetHandle(),
                     dwKeySpec = cmsgDecryptParam.keySpec,
                     dwRecipientIndex = recipientInfo.Index
                 };
                 if (!System.Security.Cryptography.CAPI.CryptMsgControl(this.m_safeCryptMsgHandle, 0, 2, new IntPtr((void*) &cmsg_ctrl_decrypt_para)))
                 {
                     num3 = Marshal.GetHRForLastWin32Error();
                 }
                 GC.KeepAlive(cmsg_ctrl_decrypt_para);
                 goto Label_02E6;
             }
             case RecipientInfoType.KeyAgreement:
             {
                 invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle;
                 info2 = (KeyAgreeRecipientInfo) recipientInfo;
                 System.Security.Cryptography.CAPI.CMSG_CMS_RECIPIENT_INFO cmsg_cms_recipient_info = (System.Security.Cryptography.CAPI.CMSG_CMS_RECIPIENT_INFO) Marshal.PtrToStructure(info2.pCmsgRecipientInfo.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CMSG_CMS_RECIPIENT_INFO));
                 cmsg_ctrl_key_agree_decrypt_para = new System.Security.Cryptography.CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA))) {
                     hCryptProv = cmsgDecryptParam.safeCryptProvHandle.DangerousGetHandle(),
                     dwKeySpec = cmsgDecryptParam.keySpec,
                     pKeyAgree = cmsg_cms_recipient_info.pRecipientInfo,
                     dwRecipientIndex = info2.Index,
                     dwRecipientEncryptedKeyIndex = info2.SubIndex
                 };
                 if (info2.SubType != RecipientSubType.CertIdKeyAgreement)
                 {
                     goto Label_0286;
                 }
                 System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO cmsgRecipientInfo = (System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) info2.CmsgRecipientInfo;
                 invalidHandle = System.Security.Cryptography.CAPI.CertFindCertificateInStore(BuildOriginatorStore(this.Certificates, extraStore), 0x10001, 0, 0x100000, new IntPtr((void*) &cmsgRecipientInfo.OriginatorCertId), System.Security.Cryptography.SafeCertContextHandle.InvalidHandle);
                 if ((invalidHandle != null) && !invalidHandle.IsInvalid)
                 {
                     break;
                 }
                 num3 = -2146885628;
                 goto Label_02E6;
             }
             default:
                 throw new CryptographicException(-2147483647);
         }
         System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(invalidHandle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
         System.Security.Cryptography.CAPI.CERT_INFO cert_info = (System.Security.Cryptography.CAPI.CERT_INFO) Marshal.PtrToStructure(cert_context.pCertInfo, typeof(System.Security.Cryptography.CAPI.CERT_INFO));
         cmsg_ctrl_key_agree_decrypt_para.OriginatorPublicKey = cert_info.SubjectPublicKeyInfo.PublicKey;
         goto Label_02A7;
     Label_0286:
         cmsg_key_agree_public_key_recipient_info = (System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) info2.CmsgRecipientInfo;
         cmsg_ctrl_key_agree_decrypt_para.OriginatorPublicKey = cmsg_key_agree_public_key_recipient_info.OriginatorPublicKeyInfo.PublicKey;
     Label_02A7:
         if (!System.Security.Cryptography.CAPI.CryptMsgControl(this.m_safeCryptMsgHandle, 0, 0x11, new IntPtr((void*) &cmsg_ctrl_key_agree_decrypt_para)))
         {
             num3 = Marshal.GetHRForLastWin32Error();
         }
         GC.KeepAlive(cmsg_ctrl_key_agree_decrypt_para);
         GC.KeepAlive(invalidHandle);
     Label_02E6:
         GC.KeepAlive(cmsgDecryptParam);
     Label_02F1:
         if (num3 == 0)
         {
             uint cbData = 0;
             System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
             PkcsUtils.GetParam(this.m_safeCryptMsgHandle, 2, 0, out pvData, out cbData);
             if (cbData > 0)
             {
                 Oid contentType = PkcsUtils.GetContentType(this.m_safeCryptMsgHandle);
                 byte[] destination = new byte[cbData];
                 Marshal.Copy(pvData.DangerousGetHandle(), destination, 0, (int) cbData);
                 this.m_contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(contentType, destination);
             }
             pvData.Dispose();
             hr = 0;
             break;
         }
         hr = num3;
     }
     if (hr != 0)
     {
         throw new CryptographicException(hr);
     }
 }
Ejemplo n.º 4
0
        private unsafe void DecryptContent (RecipientInfoCollection recipientInfos, X509Certificate2Collection extraStore) {
            int hr = CAPI.CRYPT_E_RECIPIENT_NOT_FOUND;

            if (m_safeCryptMsgHandle == null || m_safeCryptMsgHandle.IsInvalid)
                throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_NoEncryptedMessageToEncode"));

            for (int index = 0; index < recipientInfos.Count; index++) {
                RecipientInfo recipientInfo = recipientInfos[index];
                CMSG_DECRYPT_PARAM cmsgDecryptParam = new CMSG_DECRYPT_PARAM();

                // Get CSP parameters
                int hr2 = GetCspParams(recipientInfo, extraStore, ref cmsgDecryptParam);

                if (hr2 == CAPI.S_OK) {
                    // 


                    CspParameters parameters = new CspParameters();
                    if (X509Utils.GetPrivateKeyInfo(cmsgDecryptParam.safeCertContextHandle, ref parameters) == false)
                        throw new CryptographicException(Marshal.GetLastWin32Error());

                    KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                    KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Decrypt);
                    kp.AccessEntries.Add(entry);
                    kp.Demand();

                    // Decrypt the content.
                    switch (recipientInfo.Type) {
                    case RecipientInfoType.KeyTransport:
                        CAPI.CMSG_CTRL_DECRYPT_PARA ctrlDecryptPara = new CAPI.CMSG_CTRL_DECRYPT_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_DECRYPT_PARA)));
                        ctrlDecryptPara.hCryptProv = cmsgDecryptParam.safeCryptProvHandle.DangerousGetHandle();
                        ctrlDecryptPara.dwKeySpec = cmsgDecryptParam.keySpec;
                        ctrlDecryptPara.dwRecipientIndex = (uint) recipientInfo.Index;

                        if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle,
                                                  0,
                                                  CAPI.CMSG_CTRL_DECRYPT,
                                                  new IntPtr(&ctrlDecryptPara)))
                            hr2 = Marshal.GetHRForLastWin32Error();

                        GC.KeepAlive(ctrlDecryptPara);
                        break;

                    case RecipientInfoType.KeyAgreement:
                        SafeCertContextHandle pOriginatorCert = SafeCertContextHandle.InvalidHandle;
                        KeyAgreeRecipientInfo keyAgree = (KeyAgreeRecipientInfo) recipientInfo;
                        CAPI.CMSG_CMS_RECIPIENT_INFO cmsRecipientInfo = (CAPI.CMSG_CMS_RECIPIENT_INFO) Marshal.PtrToStructure(keyAgree.pCmsgRecipientInfo.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_RECIPIENT_INFO));

                        CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA keyAgreeDecryptPara = new CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA(Marshal.SizeOf(typeof(CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT_PARA)));
                        keyAgreeDecryptPara.hCryptProv = cmsgDecryptParam.safeCryptProvHandle.DangerousGetHandle();
                        keyAgreeDecryptPara.dwKeySpec = cmsgDecryptParam.keySpec;
                        keyAgreeDecryptPara.pKeyAgree = cmsRecipientInfo.pRecipientInfo;
                        keyAgreeDecryptPara.dwRecipientIndex = keyAgree.Index;
                        keyAgreeDecryptPara.dwRecipientEncryptedKeyIndex = keyAgree.SubIndex;

                        if (keyAgree.SubType == RecipientSubType.CertIdKeyAgreement) {
                            CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO certIdKeyAgree = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) keyAgree.CmsgRecipientInfo;
                            SafeCertStoreHandle hCertStore = BuildOriginatorStore(this.Certificates, extraStore);

                            pOriginatorCert = CAPI.CertFindCertificateInStore(hCertStore, 
                                                                              CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                              0, 
                                                                              CAPI.CERT_FIND_CERT_ID,
                                                                              new IntPtr(&certIdKeyAgree.OriginatorCertId),
                                                                              SafeCertContextHandle.InvalidHandle);
                            if (pOriginatorCert == null || pOriginatorCert.IsInvalid) {
                                hr2 = CAPI.CRYPT_E_NOT_FOUND;
                                break;
                            }

                            CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(pOriginatorCert.DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
                            CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));
                            keyAgreeDecryptPara.OriginatorPublicKey = certInfo.SubjectPublicKeyInfo.PublicKey;
                        }
                        else {
                            CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO publicKeyAgree = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) keyAgree.CmsgRecipientInfo;
                            keyAgreeDecryptPara.OriginatorPublicKey = publicKeyAgree.OriginatorPublicKeyInfo.PublicKey;
                        }
                        
                        if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle,
                                                  0,
                                                  CAPI.CMSG_CTRL_KEY_AGREE_DECRYPT,
                                                  new IntPtr(&keyAgreeDecryptPara)))
                            hr2 = Marshal.GetHRForLastWin32Error();

                        GC.KeepAlive(keyAgreeDecryptPara);
                        GC.KeepAlive(pOriginatorCert);
                        break;

                    default:
                        throw new CryptographicException(CAPI.E_NOTIMPL);
                    }

                    GC.KeepAlive(cmsgDecryptParam);
                }

                // Content decrypted?
                if (hr2 == CAPI.S_OK) {
                    // Yes, so retrieve it.
                    uint cbContent = 0;
                    SafeLocalAllocHandle pbContent = SafeLocalAllocHandle.InvalidHandle;

                    PkcsUtils.GetParam(m_safeCryptMsgHandle, CAPI.CMSG_CONTENT_PARAM, 0, out pbContent, out cbContent);

                    if (cbContent > 0) {
                        Oid contentType = PkcsUtils.GetContentType(m_safeCryptMsgHandle);
                        byte[] content = new byte[cbContent];
                        Marshal.Copy(pbContent.DangerousGetHandle(), content, 0, (int) cbContent);

                        m_contentInfo = new ContentInfo(contentType, content);
                    }

                    pbContent.Dispose();

                    hr = CAPI.S_OK;
                    break;
                }
                else {
                    // Try next recipient.
                    hr = hr2;
                }
            }

            if (hr != CAPI.S_OK)
                throw new CryptographicException(hr);

            return;
        }