Esempio n. 1
0
 internal RecipientInfoCollection(SafeCryptMsgHandle safeCryptMsgHandle)
 {
     bool flag = PkcsUtils.CmsSupported();
     uint num1 = 0U;
     uint num2 = (uint)Marshal.SizeOf(typeof(uint));
     if (flag)
     {
         if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle, 33U, 0U, new IntPtr((void*)&num1), new IntPtr((void*)&num2)))
             throw new CryptographicException(Marshal.GetLastWin32Error());
     }
     else if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle, 17U, 0U, new IntPtr((void*)&num1), new IntPtr((void*)&num2)))
         throw new CryptographicException(Marshal.GetLastWin32Error());
     this.m_recipientInfos = new ArrayList();
     for (uint index = 0U; index < num1; ++index)
     {
         if (flag)
         {
             SafeLocalAllocHandle pvData;
             uint cbData;
             PkcsUtils.GetParam(safeCryptMsgHandle, 36U, index, out pvData, out cbData);
             CAPI.CMSG_CMS_RECIPIENT_INFO cmsRecipientInfo = (CAPI.CMSG_CMS_RECIPIENT_INFO)Marshal.PtrToStructure(pvData.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_RECIPIENT_INFO));
             switch (cmsRecipientInfo.dwRecipientChoice)
             {
                 case 1U:
                     CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO));
                     this.m_recipientInfos.Add((object)new KeyTransRecipientInfo(pvData, keyTrans, index));
                     continue;
                 case 2U:
                     CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO agreeRecipientInfo = (CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO));
                     switch (agreeRecipientInfo.dwOriginatorChoice)
                     {
                         case 1U:
                             CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO certIdRecipient = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO));
                             for (uint subIndex = 0U; subIndex < certIdRecipient.cRecipientEncryptedKeys; ++subIndex)
                                 this.m_recipientInfos.Add((object)new KeyAgreeRecipientInfo(pvData, certIdRecipient, index, subIndex));
                             continue;
                         case 2U:
                             CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO publicKeyRecipient = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO));
                             for (uint subIndex = 0U; subIndex < publicKeyRecipient.cRecipientEncryptedKeys; ++subIndex)
                                 this.m_recipientInfos.Add((object)new KeyAgreeRecipientInfo(pvData, publicKeyRecipient, index, subIndex));
                             continue;
                         default:
                             throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Originator_Identifier_Choice"), agreeRecipientInfo.dwOriginatorChoice.ToString((IFormatProvider)CultureInfo.CurrentCulture));
                     }
                 default:
                     throw new CryptographicException(-2147483647);
             }
         }
         else
         {
             SafeLocalAllocHandle pvData;
             uint cbData;
             PkcsUtils.GetParam(safeCryptMsgHandle, 19U, index, out pvData, out cbData);
             CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO)Marshal.PtrToStructure(pvData.DangerousGetHandle(), typeof(CAPI.CERT_INFO));
             this.m_recipientInfos.Add((object)new KeyTransRecipientInfo(pvData, certInfo, index));
         }
     }
     this.m_safeCryptMsgHandle = safeCryptMsgHandle;
 }
Esempio n. 2
0
 public static extern bool CryptQueryObject(
     CERT_QUERY_OBJECT dwObjectType,
     [MarshalAs(UnmanagedType.LPWStr)] string pvObject,
     CERT_QUERY_CONTENT dwExpectedContentTypeFlags,
     CERT_QUERY_FORMAT dwExpectedFormatTypeFlags,
     [In]     uint dwFlags,
     out uint pdwMsgAndCertEncodingType,
     out uint pdwContentType,
     out uint pdwFormatType,
     out SafeCertStoreHandle phCertStore,
     out SafeCryptMsgHandle phMsg,
     [In, Out] IntPtr ppvContext);
Esempio n. 3
0
        internal static DecryptorPalWindows Decode(
            byte[] encodedMessage,
            out int version,
            out ContentInfo contentInfo,
            out AlgorithmIdentifier contentEncryptionAlgorithm,
            out X509Certificate2Collection originatorCerts,
            out CryptographicAttributeObjectCollection unprotectedAttributes
            )
        {
            SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToDecode(MsgEncodingType.All, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            if (hCryptMsg == null || hCryptMsg.IsInvalid)
            {
                throw Marshal.GetLastWin32Error().ToCryptographicException();
            }

            if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedMessage, encodedMessage.Length, fFinal: true))
            {
                throw Marshal.GetLastWin32Error().ToCryptographicException();
            }

            CryptMsgType cryptMsgType = hCryptMsg.GetMessageType();

            if (cryptMsgType != CryptMsgType.CMSG_ENVELOPED)
            {
                throw ErrorCode.CRYPT_E_INVALID_MSG_TYPE.ToCryptographicException();
            }

            version = hCryptMsg.GetVersion();

            contentInfo = hCryptMsg.GetContentInfo();

            AlgorithmIdentifierAsn contentEncryptionAlgorithmAsn;

            using (SafeHandle sh = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_ENVELOPE_ALGORITHM_PARAM))
            {
                unsafe
                {
                    CRYPT_ALGORITHM_IDENTIFIER *pCryptAlgorithmIdentifier = (CRYPT_ALGORITHM_IDENTIFIER *)(sh.DangerousGetHandle());
                    contentEncryptionAlgorithm = (*pCryptAlgorithmIdentifier).ToAlgorithmIdentifier();
                    contentEncryptionAlgorithmAsn.Algorithm  = contentEncryptionAlgorithm.Oid;
                    contentEncryptionAlgorithmAsn.Parameters = (*pCryptAlgorithmIdentifier).Parameters.ToByteArray();
                }
            }

            originatorCerts       = hCryptMsg.GetOriginatorCerts();
            unprotectedAttributes = hCryptMsg.GetUnprotectedAttributes();

            RecipientInfoCollection recipientInfos = CreateRecipientInfos(hCryptMsg);

            return(new DecryptorPalWindows(hCryptMsg, recipientInfos, contentEncryptionAlgorithmAsn));
        }
Esempio n. 4
0
 public static unsafe extern bool CryptQueryObject(
     CertQueryObjectType dwObjectType,
     void* pvObject,
     ExpectedContentTypeFlags dwExpectedContentTypeFlags,
     ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
     int dwFlags, // reserved - always pass 0
     out CertEncodingType pdwMsgAndCertEncodingType,
     out ContentType pdwContentType,
     out FormatType pdwFormatType,
     out SafeCertStoreHandle phCertStore,
     out SafeCryptMsgHandle phMsg,
     out SafeCertContextHandle ppvContext
     );
Esempio n. 5
0
 internal static extern bool CryptQueryObject(
     /* _In_                          DWORD        */ [In] CertQueryObject dwObjectType,
     /* _In_                          const void*  */ [In] IntPtr pvObject,
     /* _In_                          DWORD        */ [In] CertQueryContentFlag dwExpectedContentTypeFlags,
     /* _In_                          DWORD        */ [In] CertQueryFormatFlag dwExpectedFormatTypeFlags,
     /* _In_                          DWORD        */ [In] int dwFlags,
     /* _Out_opt_                     DWORD*       */ [Out] out CertEncoding pdwMsgAndCertEncodingType,
     /* _Out_opt_                     DWORD*       */ [Out] out CertQueryContent pdwContentType,
     /* _Out_opt_                     DWORD*       */ [Out] out CertQueryFormat pdwFormatType,
     /* _Out_opt_                     HCERTSTORE*  */ [Out] out SafeCertStoreHandle phCertStore,
     /* _Out_opt_                     HCRYPTMSG*   */ [Out] out SafeCryptMsgHandle phMsg,
     /* _Outptr_opt_result_maybenull_ const void** */ [Out] out SafeCertContextHandle ppvContext
     );
Esempio n. 6
0
 internal static unsafe partial bool CryptQueryObject(
     CertQueryObjectType dwObjectType,
     void* pvObject,
     ExpectedContentTypeFlags dwExpectedContentTypeFlags,
     ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
     int dwFlags, // reserved - always pass 0
     out CertEncodingType pdwMsgAndCertEncodingType,
     out ContentType pdwContentType,
     out FormatType pdwFormatType,
     out SafeCertStoreHandle phCertStore,
     out SafeCryptMsgHandle phMsg,
     out SafeCertContextHandle ppvContext
     );
Esempio n. 7
0
        public sealed override Oid GetEncodedMessageType(byte[] encodedMessage)
        {
            using (SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToDecode(MsgEncodingType.All, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
            {
                if (hCryptMsg == null || hCryptMsg.IsInvalid)
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }

                if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedMessage, encodedMessage.Length, fFinal: true))
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }

                int msgTypeAsInt;
                int cbSize = sizeof(int);
                if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, CryptMsgParamType.CMSG_TYPE_PARAM, 0, out msgTypeAsInt, ref cbSize))
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }

                CryptMsgType msgType = (CryptMsgType)msgTypeAsInt;

                switch (msgType)
                {
                case CryptMsgType.CMSG_DATA:
                    return(Oid.FromOidValue(Oids.Pkcs7Data, OidGroup.ExtensionOrAttribute));

                case CryptMsgType.CMSG_SIGNED:
                    return(Oid.FromOidValue(Oids.Pkcs7Signed, OidGroup.ExtensionOrAttribute));

                case CryptMsgType.CMSG_ENVELOPED:
                    return(Oid.FromOidValue(Oids.Pkcs7Enveloped, OidGroup.ExtensionOrAttribute));

                case CryptMsgType.CMSG_SIGNED_AND_ENVELOPED:
                    return(Oid.FromOidValue(Oids.Pkcs7SignedEnveloped, OidGroup.ExtensionOrAttribute));

                case CryptMsgType.CMSG_HASHED:
                    return(Oid.FromOidValue(Oids.Pkcs7Hashed, OidGroup.ExtensionOrAttribute));

                case CryptMsgType.CMSG_ENCRYPTED:
                    return(Oid.FromOidValue(Oids.Pkcs7Encrypted, OidGroup.ExtensionOrAttribute));

                default:
                    throw ErrorCode.CRYPT_E_INVALID_MSG_TYPE.ToCryptographicException();
                }
            }
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
        private static SafeCryptMsgHandle OpenToDecode(byte[] encodedMessage,
                                                       ContentInfo contentInfo,
                                                       bool detached)
        {
            // Open the message for decode.
            SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CAPISafe.CryptMsgOpenToDecode(
                CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                0,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero);

            if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            // ---- the message.
            if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, encodedMessage, (uint)encodedMessage.Length, true))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            // Make sure this is PKCS7 SignedData type.
            if (CAPI.CMSG_SIGNED != PkcsUtils.GetMessageType(safeCryptMsgHandle))
            {
                throw new CryptographicException(CAPI.CRYPT_E_INVALID_MSG_TYPE);
            }

            // If detached, then update message with content if available.
            if (detached)
            {
                byte[] content = contentInfo.Content;

                if (content != null && content.Length > 0)
                {
                    if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, content, (uint)content.Length, true))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
            }

            return(safeCryptMsgHandle);
        }
Esempio n. 10
0
        // Used for binary blobs without internal pointers.
        public static byte[] GetMsgParamAsByteArray(this SafeCryptMsgHandle hCryptMsg, CryptMsgParamType paramType, int index = 0)
        {
            int cbData = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, null, ref cbData))
            {
                throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
            }

            byte[] pvData = new byte[cbData];
            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, pvData, ref cbData))
            {
                throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
            }

            return(pvData.Resize(cbData));
        }
Esempio n. 11
0
        // Used for binary blobs with internal pointers.
        public static SafeHandle GetMsgParamAsMemory(this SafeCryptMsgHandle hCryptMsg, CryptMsgParamType paramType, int index = 0)
        {
            int cbData = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, null, ref cbData))
            {
                throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
            }

            SafeHandle pvData = SafeHeapAllocHandle.Alloc(cbData);

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, pvData.DangerousGetHandle(), ref cbData))
            {
                throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
            }

            return(pvData);
        }
Esempio n. 12
0
        internal unsafe SignerInfoCollection(SignedCms signedCms)
        {
            uint dwSigners = 0;
            uint cbCount   = (uint)Marshal.SizeOf(typeof(uint));
            SafeCryptMsgHandle safeCryptMsgHandle = signedCms.GetCryptMsgHandle();

            if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                CAPI.CMSG_SIGNER_COUNT_PARAM,
                                                0,
                                                new IntPtr(&dwSigners),
                                                new IntPtr(&cbCount)))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            SignerInfo[] signerInfos = new SignerInfo[dwSigners];
            for (int index = 0; index < dwSigners; index++)
            {
                uint cbCmsgSignerInfo = 0;
                if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                    CAPI.CMSG_SIGNER_INFO_PARAM,
                                                    (uint)index,
                                                    IntPtr.Zero,
                                                    new IntPtr(&cbCmsgSignerInfo)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                SafeLocalAllocHandle pbCmsgSignerInfo = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbCmsgSignerInfo));

                if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                    CAPI.CMSG_SIGNER_INFO_PARAM,
                                                    (uint)index,
                                                    pbCmsgSignerInfo,
                                                    new IntPtr(&cbCmsgSignerInfo)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                signerInfos[index] = new SignerInfo(signedCms, pbCmsgSignerInfo);
            }

            m_signerInfos = signerInfos;
        }
Esempio n. 13
0
        public static X509Certificate2Collection GetOriginatorCerts(this SafeCryptMsgHandle hCryptMsg)
        {
            int numCertificates   = 0;
            int cbNumCertificates = sizeof(int);

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, CryptMsgParamType.CMSG_CERT_COUNT_PARAM, 0, out numCertificates, ref cbNumCertificates))
            {
                throw Interop.CPError.GetLastWin32Error().ToCryptographicException();
            }
            X509Certificate2Collection certs = new X509Certificate2Collection();

            for (int index = 0; index < numCertificates; index++)
            {
                byte[]           encodedCertificate = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CERT_PARAM, index);
                X509Certificate2 cert = new X509Certificate2(encodedCertificate);
                certs.Add(cert);
            }
            return(certs);
        }
Esempio n. 14
0
        // Used for binary blobs with internal pointers.
        public static SafeHandle GetMsgParamAsMemory(this SafeCryptMsgHandle hCryptMsg, CryptMsgParamType paramType, int index = 0)
        {
            int cbData = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, IntPtr.Zero, ref cbData))
            {
                throw Marshal.GetLastPInvokeError().ToCryptographicException();
            }

            SafeHandle pvData = SafeHeapAllocHandle.Alloc(cbData);

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, pvData.DangerousGetHandle(), ref cbData))
            {
                Exception e = Marshal.GetLastPInvokeError().ToCryptographicException();
                pvData.Dispose();
                throw e;
            }

            return(pvData);
        }
Esempio n. 15
0
        public void Decode(byte[] encodedMessage)
        {
            if (encodedMessage == null)
            {
                throw new ArgumentNullException("encodedMessage");
            }

            if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid)
            {
                m_safeCryptMsgHandle.Dispose();
            }

            m_safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
            if (!this.Detached)
            {
                Oid    contentType = PkcsUtils.GetContentType(m_safeCryptMsgHandle);
                byte[] content     = PkcsUtils.GetContent(m_safeCryptMsgHandle);
                m_contentInfo = new ContentInfo(contentType, content);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Returns the inner content of the CMS.
        ///
        /// Special case: If the CMS is an enveloped CMS that has been decrypted and the inner content type is Oids.Pkcs7Data, the returned
        /// content bytes are the decoded octet bytes, rather than the encoding of those bytes. This is a documented convenience behavior of
        /// CryptMsgGetParam(CMSG_CONTENT_PARAM) that apparently got baked into the behavior of the managed EnvelopedCms class.
        /// </summary>
        public static ContentInfo GetContentInfo(this SafeCryptMsgHandle hCryptMsg)
        {
            byte[] oidBytes = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_INNER_CONTENT_TYPE_PARAM);

            // Desktop compat: If we get a null or non-terminated string back from Crypt32, throwing an exception seems more apropros but
            // for the desktop compat, we throw the result at the ASCII Encoder and let the chips fall where they may.
            int length = oidBytes.Length;

            if (length > 0 && oidBytes[length - 1] == 0)
            {
                length--;
            }

            string oidValue    = Encoding.ASCII.GetString(oidBytes, 0, length);
            Oid    contentType = new Oid(oidValue);

            byte[] content = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM);

            return(new ContentInfo(contentType, content));
        }
Esempio n. 17
0
        public SignedCms (SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached) {
            if (contentInfo == null)
                throw new ArgumentNullException("contentInfo");

            if (contentInfo.Content == null)
                throw new ArgumentNullException("contentInfo.Content");

            // Reset all states.
            if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier && 
                signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber &&
                signerIdentifierType != SubjectIdentifierType.NoSignature) {
                signerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
            }

            m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
            m_signerIdentifierType =  signerIdentifierType;
            m_version = 0;
            m_contentInfo = contentInfo;
            m_detached = detached;
        }
Esempio n. 18
0
        // Used for binary blobs without internal pointers.
        public static unsafe byte[] GetMsgParamAsByteArray(this SafeCryptMsgHandle hCryptMsg, CryptMsgParamType paramType, int index = 0)
        {
            int cbData = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, IntPtr.Zero, ref cbData))
            {
                throw Marshal.GetLastWin32Error().ToCryptographicException();
            }

            byte[] data = new byte[cbData];
            fixed(byte *pvData = data)
            {
                if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, paramType, index, pvData, ref cbData))
                {
                    throw Marshal.GetLastWin32Error().ToCryptographicException();
                }
            }

            return(data.Resize(cbData));
        }
Esempio n. 19
0
        private static RecipientInfoCollection CreateRecipientInfos(SafeCryptMsgHandle hCryptMsg)
        {
            int numRecipients;
            int cbRecipientsCount = sizeof(int);

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, CryptMsgParamType.CMSG_CMS_RECIPIENT_COUNT_PARAM, 0, out numRecipients, ref cbRecipientsCount))
            {
                throw Marshal.GetLastPInvokeError().ToCryptographicException();
            }

            List <RecipientInfo> recipientInfos = new List <RecipientInfo>(numRecipients);

            for (int index = 0; index < numRecipients; index++)
            {
                // Do not dispose this safehandle. The RecipientInfoPal objects we create hold on to these and they get freed through garbage collection.
                SafeHandle pCmsgCmsRecipientInfoMemory = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_CMS_RECIPIENT_INFO_PARAM, index);
                IEnumerable <RecipientInfo> recipientInfosForThisIndex = ToRecipientInfosForThisIndex(pCmsgCmsRecipientInfoMemory, index);
                recipientInfos.AddRange(recipientInfosForThisIndex);
            }

            return(new RecipientInfoCollection(recipientInfos));
        }
Esempio n. 20
0
            public static SafeCryptMsgHandle CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
            {
                using (HeapBlockRetainer hb = new HeapBlockRetainer())
                {
                    // Deep copy the CmsRecipients (and especially their underlying X509Certificate2 objects). This will prevent malicious callers from altering them or disposing them while we're performing
                    // unsafe memory crawling inside them.
                    recipients = recipients.DeepCopy();

                    // We must keep all the certificates inside recipients alive until the call to CryptMsgOpenToEncode() finishes. The CMSG_ENVELOPED_ENCODE_INFO* structure we passed to it
                    // contains direct pointers to memory owned by the CERT_INFO memory block whose lifetime is that of the certificate.
                    hb.KeepAlive(recipients);
                    unsafe
                    {
                        CMSG_ENVELOPED_ENCODE_INFO *pEnvelopedEncodeInfo = CreateCmsEnvelopedEncodeInfo(recipients, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, hb);
                        SafeCryptMsgHandle          hCryptMsg            = Interop.Crypt32.CryptMsgOpenToEncode(MsgEncodingType.All, 0, CryptMsgType.CMSG_ENVELOPED, pEnvelopedEncodeInfo, innerContentType.Value, IntPtr.Zero);
                        if (hCryptMsg == null || hCryptMsg.IsInvalid)
                        {
                            throw Marshal.GetLastWin32Error().ToCryptographicException();
                        }

                        return(hCryptMsg);
                    }
                }
            }
Esempio n. 21
0
 internal RecipientInfoCollection()
 {
     this.m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
     this.m_recipientInfos = new ArrayList();
 }
Esempio n. 22
0
 private NativeCms(SafeCryptMsgHandle handle, bool detached)
 {
     _handle = handle;
     _detached = detached;
 }
Esempio n. 23
0
        private static SafeCertContextHandle GetSignerInPKCS7Store(SafeCertStoreHandle hCertStore, SafeCryptMsgHandle hCryptMsg)
        {
            // make sure that there is at least one signer of the certificate store
            int dwSigners;
            int cbSigners = sizeof(int);
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_COUNT_PARAM, 0, out dwSigners, ref cbSigners))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;
            if (dwSigners == 0)
                throw ErrorCode.CRYPT_E_SIGNER_NOT_FOUND.ToCryptographicException();

            // get the first signer from the store, and use that as the loaded certificate
            int cbData = 0;
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_INFO_PARAM, 0, null, ref cbData))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

            byte[] cmsgSignerBytes = new byte[cbData];
            if (!Interop.crypt32.CryptMsgGetParam(hCryptMsg, CryptMessageParameterType.CMSG_SIGNER_INFO_PARAM, 0, cmsgSignerBytes, ref cbData))
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

            CERT_INFO certInfo = default(CERT_INFO);
            unsafe
            {
                fixed (byte* pCmsgSignerBytes = cmsgSignerBytes)
                {
                    CMSG_SIGNER_INFO_Partial* pCmsgSignerInfo = (CMSG_SIGNER_INFO_Partial*)pCmsgSignerBytes;
                    certInfo.Issuer.cbData = pCmsgSignerInfo->Issuer.cbData;
                    certInfo.Issuer.pbData = pCmsgSignerInfo->Issuer.pbData;
                    certInfo.SerialNumber.cbData = pCmsgSignerInfo->SerialNumber.cbData;
                    certInfo.SerialNumber.pbData = pCmsgSignerInfo->SerialNumber.pbData;
                }

                SafeCertContextHandle pCertContext = null;
                if (!Interop.crypt32.CertFindCertificateInStore(hCertStore, CertFindType.CERT_FIND_SUBJECT_CERT, &certInfo, ref pCertContext))
                    throw Marshal.GetHRForLastWin32Error().ToCryptographicException();;

                return pCertContext;
            }
        }
Esempio n. 24
0
 internal RecipientInfoCollection(RecipientInfo recipientInfo)
 {
     this.m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
     this.m_recipientInfos = new ArrayList(1);
     this.m_recipientInfos.Add((object)recipientInfo);
 }
Esempio n. 25
0
 internal RecipientInfoCollection(RecipientInfo recipientInfo)
 {
     m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
     m_recipientInfos     = new ArrayList(1);
     m_recipientInfos.Add(recipientInfo);
 }
Esempio n. 26
0
 public static partial bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMessageParameterType dwParamType, int dwIndex, out int pvData, ref int pcbData);
Esempio n. 27
0
        internal unsafe RecipientInfoCollection(SafeCryptMsgHandle safeCryptMsgHandle)
        {
            bool cmsSupported = PkcsUtils.CmsSupported();
            uint dwRecipients = 0;
            uint cbCount      = (uint)Marshal.SizeOf(typeof(uint));

            // Use CMS if supported.
            if (cmsSupported)
            {
                // CMS.
                if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                    CAPI.CMSG_CMS_RECIPIENT_COUNT_PARAM,
                                                    0,
                                                    new IntPtr(&dwRecipients),
                                                    new IntPtr(&cbCount)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
            else
            {
                // PKCS7.
                if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                    CAPI.CMSG_RECIPIENT_COUNT_PARAM,
                                                    0,
                                                    new IntPtr(&dwRecipients),
                                                    new IntPtr(&cbCount)))
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }

            m_recipientInfos = new ArrayList();

            for (uint index = 0; index < dwRecipients; index++)
            {
                if (cmsSupported)
                {
                    uint cbCmsRecipientInfo;
                    SafeLocalAllocHandle pbCmsRecipientInfo;

                    PkcsUtils.GetParam(safeCryptMsgHandle, CAPI.CMSG_CMS_RECIPIENT_INFO_PARAM, index, out pbCmsRecipientInfo, out cbCmsRecipientInfo);
                    CAPI.CMSG_CMS_RECIPIENT_INFO cmsRecipientInfo = (CAPI.CMSG_CMS_RECIPIENT_INFO)Marshal.PtrToStructure(pbCmsRecipientInfo.DangerousGetHandle(), typeof(CAPI.CMSG_CMS_RECIPIENT_INFO));

                    switch (cmsRecipientInfo.dwRecipientChoice)
                    {
                    case CAPI.CMSG_KEY_TRANS_RECIPIENT:
                        CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO));
                        m_recipientInfos.Add(new KeyTransRecipientInfo(pbCmsRecipientInfo, keyTrans, index));
                        break;

                    case CAPI.CMSG_KEY_AGREE_RECIPIENT:
                        CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO keyAgree = (CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_INFO));
                        switch (keyAgree.dwOriginatorChoice)
                        {
                        case CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT:
                            CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO certIdRecipient = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO));
                            for (uint cRecipient = 0; cRecipient < certIdRecipient.cRecipientEncryptedKeys; cRecipient++)
                            {
                                m_recipientInfos.Add(new KeyAgreeRecipientInfo(pbCmsRecipientInfo, certIdRecipient, index, cRecipient));
                            }
                            break;

                        case CAPI.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY:
                            CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO publicKeyRecipient = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO)Marshal.PtrToStructure(cmsRecipientInfo.pRecipientInfo, typeof(CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO));
                            for (uint cRecipient = 0; cRecipient < publicKeyRecipient.cRecipientEncryptedKeys; cRecipient++)
                            {
                                m_recipientInfos.Add(new KeyAgreeRecipientInfo(pbCmsRecipientInfo, publicKeyRecipient, index, cRecipient));
                            }
                            break;

                        default:
                            throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Originator_Identifier_Choice"), keyAgree.dwOriginatorChoice.ToString(CultureInfo.CurrentCulture));
                        }
                        break;

                    default:
                        throw new CryptographicException(CAPI.E_NOTIMPL);
                    }
                }
                else
                {
                    uint cbCertInfo;
                    SafeLocalAllocHandle pbCertInfo;

                    PkcsUtils.GetParam(safeCryptMsgHandle, CAPI.CMSG_RECIPIENT_INFO_PARAM, index, out pbCertInfo, out cbCertInfo);
                    CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO)Marshal.PtrToStructure(pbCertInfo.DangerousGetHandle(), typeof(CAPI.CERT_INFO));

                    m_recipientInfos.Add(new KeyTransRecipientInfo(pbCertInfo, certInfo, index));
                }
            }

            m_safeCryptMsgHandle = safeCryptMsgHandle;
        }
Esempio n. 28
0
 internal static extern bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMsgParamType dwParamType, int dwIndex, IntPtr pvData, [In, Out] ref int pcbData);
Esempio n. 29
0
 public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
 {
     if (contentInfo == null)
         throw new ArgumentNullException("contentInfo");
     if (contentInfo.Content == null)
         throw new ArgumentNullException("contentInfo.Content");
     if (encryptionAlgorithm == null)
         throw new ArgumentNullException("encryptionAlgorithm");
     this.m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle;
     this.m_version = recipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 2 : 0;
     this.m_recipientIdentifierType = recipientIdentifierType;
     this.m_contentInfo = contentInfo;
     this.m_encryptionAlgorithm = encryptionAlgorithm;
     this.m_encryptionAlgorithm.Parameters = new byte[0];
     this.m_certificates = new X509Certificate2Collection();
     this.m_unprotectedAttributes = new CryptographicAttributeObjectCollection();
 }
        private static ICertificatePal FromBlobOrFile(byte[] rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(rawData != null || fileName != null);
            Debug.Assert(password != null);

            bool loadFromFile = (fileName != null);

            PfxCertStoreFlags pfxCertStoreFlags = MapKeyStorageFlags(keyStorageFlags);
            bool deleteKeyContainer             = false;

            CertEncodingType      msgAndCertEncodingType;
            ContentType           contentType;
            FormatType            formatType;
            SafeCertStoreHandle   hCertStore   = null;
            SafeCryptMsgHandle    hCryptMsg    = null;
            SafeCertContextHandle pCertContext = null;

            try
            {
                unsafe
                {
                    fixed(byte *pRawData = rawData)
                    {
                        fixed(char *pFileName = fileName)
                        {
                            CRYPTOAPI_BLOB certBlob = new CRYPTOAPI_BLOB(loadFromFile ? 0 : rawData.Length, pRawData);

                            CertQueryObjectType objectType = loadFromFile ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : CertQueryObjectType.CERT_QUERY_OBJECT_BLOB;
                            void *pvObject = loadFromFile ? (void *)pFileName : (void *)&certBlob;

                            bool success = Interop.crypt32.CryptQueryObject(
                                objectType,
                                pvObject,
                                X509ExpectedContentTypeFlags,
                                X509ExpectedFormatTypeFlags,
                                0,
                                out msgAndCertEncodingType,
                                out contentType,
                                out formatType,
                                out hCertStore,
                                out hCryptMsg,
                                out pCertContext
                                );

                            if (!success)
                            {
                                int hr = Interop.CPError.GetHRForLastWin32Error();
                                throw hr.ToCryptographicException();
                            }
                        }
                    }

                    if (contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED || contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)
                    {
                        pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg);
                    }
                    else if (contentType == ContentType.CERT_QUERY_CONTENT_PFX)
                    {
                        if (loadFromFile)
                        {
                            rawData = File.ReadAllBytes(fileName);
                        }
                        pCertContext = FilterPFXStore(rawData, password, pfxCertStoreFlags);

                        // If PersistKeySet is set we don't delete the key, so that it persists.
                        // If EphemeralKeySet is set we don't delete the key, because there's no file, so it's a wasteful call.
                        const X509KeyStorageFlags DeleteUnless =
                            X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.EphemeralKeySet |
                            // begin: gost
                            X509KeyStorageFlags.CspNoPersistKeySet;
                        // end gost

                        deleteKeyContainer = ((keyStorageFlags & DeleteUnless) == 0);
                    }

                    CertificatePal pal = new CertificatePal(pCertContext, deleteKeyContainer);

                    pCertContext = null;
                    return(pal);
                }
            }
            finally
            {
                if (hCertStore != null)
                {
                    hCertStore.Dispose();
                }
                if (hCryptMsg != null)
                {
                    hCryptMsg.Dispose();
                }
                if (pCertContext != null)
                {
                    pCertContext.Dispose();
                }
            }
        }
Esempio n. 31
0
 internal void ReopenToDecode () {
     byte[] encodedMessage = PkcsUtils.GetMessage(m_safeCryptMsgHandle);
     if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) {
         m_safeCryptMsgHandle.Dispose();
     }
     m_safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
 }
Esempio n. 32
0
 public void Decode(byte[] encodedMessage)
 {
     if (encodedMessage == null)
         throw new ArgumentNullException("encodedMessage");
     if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
         this.m_safeCryptMsgHandle.Dispose();
     this.m_safeCryptMsgHandle = SignedCms.OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
     if (this.Detached)
         return;
     this.m_contentInfo = new ContentInfo(PkcsUtils.GetContentType(this.m_safeCryptMsgHandle), PkcsUtils.GetContent(this.m_safeCryptMsgHandle));
 }
Esempio n. 33
0
 private unsafe void Sign(CmsSigner signer, bool silent)
 {
     CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO)));
     CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);
     byte[] encodedMessage = (byte[])null;
     try
     {
         SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(0U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));
         try
         {
             Marshal.StructureToPtr((object)signerEncodeInfo, localAllocHandle.DangerousGetHandle(), false);
             X509Certificate2Collection bagOfCertificates = PkcsUtils.CreateBagOfCertificates(signer);
             SafeLocalAllocHandle encodedCertBlob = PkcsUtils.CreateEncodedCertBlob(bagOfCertificates);
             signedEncodeInfo.cSigners = 1U;
             signedEncodeInfo.rgSigners = localAllocHandle.DangerousGetHandle();
             signedEncodeInfo.cCertEncoded = (uint)bagOfCertificates.Count;
             if (bagOfCertificates.Count > 0)
                 signedEncodeInfo.rgCertEncoded = encodedCertBlob.DangerousGetHandle();
             SafeCryptMsgHandle safeCryptMsgHandle = string.Compare(this.ContentInfo.ContentType.Value, "1.2.840.113549.1.7.1", StringComparison.OrdinalIgnoreCase) != 0 ? CAPI.CryptMsgOpenToEncode(65537U, this.Detached ? 4U : 0U, 2U, new IntPtr((void*)&signedEncodeInfo), this.ContentInfo.ContentType.Value, IntPtr.Zero) : CAPI.CryptMsgOpenToEncode(65537U, this.Detached ? 4U : 0U, 2U, new IntPtr((void*)&signedEncodeInfo), IntPtr.Zero, IntPtr.Zero);
             if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                 throw new CryptographicException(Marshal.GetLastWin32Error());
             if (this.ContentInfo.Content.Length > 0 && !CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint)this.ContentInfo.Content.Length, true))
                 throw new CryptographicException(Marshal.GetLastWin32Error());
             encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle);
             safeCryptMsgHandle.Dispose();
             encodedCertBlob.Dispose();
         }
         finally
         {
             Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
             localAllocHandle.Dispose();
         }
     }
     finally
     {
         signerEncodeInfo.Dispose();
     }
     SafeCryptMsgHandle safeCryptMsgHandle1 = SignedCms.OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
     if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
         this.m_safeCryptMsgHandle.Dispose();
     this.m_safeCryptMsgHandle = safeCryptMsgHandle1;
     GC.KeepAlive((object)signer);
 }
Esempio n. 34
0
 internal void ReopenToDecode()
 {
     byte[] message = PkcsUtils.GetMessage(this.m_safeCryptMsgHandle);
     if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
         this.m_safeCryptMsgHandle.Dispose();
     this.m_safeCryptMsgHandle = SignedCms.OpenToDecode(message, this.ContentInfo, this.Detached);
 }
Esempio n. 35
0
 public NativeCms(IntPtr handle)
 {
     _handle = new SafeCryptMsgHandle(handle, ownsHandle: false);
 }
Esempio n. 36
0
        public void Decode (byte[] encodedMessage) {
            if (encodedMessage == null)
                throw new ArgumentNullException("encodedMessage");

            if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) {
                m_safeCryptMsgHandle.Dispose();
            }

            m_safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
            if (!this.Detached) {
                Oid contentType = PkcsUtils.GetContentType(m_safeCryptMsgHandle);
                byte[] content = PkcsUtils.GetContent(m_safeCryptMsgHandle);
                m_contentInfo = new ContentInfo(contentType, content); 
            }
        }
Esempio n. 37
0
        private static ICertificatePal FromBlobOrFile(byte[] rawData, String fileName, String password, X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(rawData != null || fileName != null);

            bool loadFromFile = (fileName != null);

            PfxCertStoreFlags pfxCertStoreFlags = MapKeyStorageFlags(keyStorageFlags);
            bool persistKeySet = (0 != (keyStorageFlags & X509KeyStorageFlags.PersistKeySet));

            CertEncodingType      msgAndCertEncodingType;
            ContentType           contentType;
            FormatType            formatType;
            SafeCertStoreHandle   hCertStore   = null;
            SafeCryptMsgHandle    hCryptMsg    = null;
            SafeCertContextHandle pCertContext = null;

            try
            {
                unsafe
                {
                    fixed(byte *pRawData = rawData)
                    {
                        fixed(char *pFileName = fileName)
                        {
                            CRYPTOAPI_BLOB certBlob = new CRYPTOAPI_BLOB(loadFromFile ? 0 : rawData.Length, pRawData);

                            CertQueryObjectType objectType = loadFromFile ? CertQueryObjectType.CERT_QUERY_OBJECT_FILE : CertQueryObjectType.CERT_QUERY_OBJECT_BLOB;
                            void *pvObject = loadFromFile ? (void *)pFileName : (void *)&certBlob;

                            bool success = Interop.crypt32.CryptQueryObject(
                                objectType,
                                pvObject,
                                X509ExpectedContentTypeFlags,
                                X509ExpectedFormatTypeFlags,
                                0,
                                out msgAndCertEncodingType,
                                out contentType,
                                out formatType,
                                out hCertStore,
                                out hCryptMsg,
                                out pCertContext
                                );

                            if (!success)
                            {
                                int hr = Marshal.GetHRForLastWin32Error();
                                throw hr.ToCryptographicException();
                            }
                        }
                    }

                    if (contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED || contentType == ContentType.CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)
                    {
                        pCertContext = GetSignerInPKCS7Store(hCertStore, hCryptMsg);
                    }
                    else if (contentType == ContentType.CERT_QUERY_CONTENT_PFX)
                    {
                        if (loadFromFile)
                        {
                            rawData = File.ReadAllBytes(fileName);
                        }
                        pCertContext = FilterPFXStore(rawData, password, pfxCertStoreFlags);
                    }

                    CertificatePal pal = new CertificatePal(pCertContext, deleteKeyContainer: !persistKeySet);

                    pCertContext = null;
                    return(pal);
                }
            }
            finally
            {
                if (hCertStore != null)
                {
                    hCertStore.Dispose();
                }
                if (hCryptMsg != null)
                {
                    hCryptMsg.Dispose();
                }
                if (pCertContext != null)
                {
                    pCertContext.Dispose();
                }
            }
        }
Esempio n. 38
0
        public static Oid GetContentType(byte[] encodedMessage)
        {
            if (encodedMessage == null)
            {
                throw new ArgumentNullException("encodedMessage");
            }

            SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CAPISafe.CryptMsgOpenToDecode(
                CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                0,
                0,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero);

            if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, encodedMessage, (uint)encodedMessage.Length, true))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            Oid contentType;

            switch (PkcsUtils.GetMessageType(safeCryptMsgHandle))
            {
            case CAPI.CMSG_DATA:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_data, OidGroup.ExtensionOrAttribute);
                break;

            case CAPI.CMSG_SIGNED:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_signedData, OidGroup.ExtensionOrAttribute);
                break;

            case CAPI.CMSG_ENVELOPED:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_envelopedData, OidGroup.ExtensionOrAttribute);
                break;

            case CAPI.CMSG_SIGNED_AND_ENVELOPED:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_signEnvData, OidGroup.ExtensionOrAttribute);
                break;

            case CAPI.CMSG_HASHED:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_hashedData, OidGroup.ExtensionOrAttribute);
                break;

            case CAPI.CMSG_ENCRYPTED:
                contentType = Oid.FromOidValue(CAPI.szOID_RSA_encryptedData, OidGroup.ExtensionOrAttribute);
                break;

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

            safeCryptMsgHandle.Dispose();

            return(contentType);
        }
Esempio n. 39
0
 public static extern bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMessageParameterType dwParamType, int dwIndex, out int pvData, [In, Out] ref int pcbData);
Esempio n. 40
0
 internal static partial bool CryptMsgControl(
     SafeCryptMsgHandle hCryptMsg,
     int dwFlags,
     MsgControlType dwCtrlType,
     ref CMSG_CTRL_KEY_AGREE_DECRYPT_PARA pvCtrlPara);
Esempio n. 41
0
 private unsafe void EncryptContent(CmsRecipientCollection recipients)
 {
     EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam = new EnvelopedCms.CMSG_ENCRYPT_PARAM();
     if (recipients.Count < 1)
         throw new CryptographicException(-2146889717);
     foreach (CmsRecipient cmsRecipient in recipients)
     {
         if (cmsRecipient.Certificate == null)
             throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound"));
         if (PkcsUtils.GetRecipientInfoType(cmsRecipient.Certificate) == RecipientInfoType.KeyAgreement || cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             encryptParam.useCms = true;
     }
     if (!encryptParam.useCms && (this.Certificates.Count > 0 || this.UnprotectedAttributes.Count > 0))
         encryptParam.useCms = true;
     if (encryptParam.useCms && !PkcsUtils.CmsSupported())
         throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported"));
     CAPI.CMSG_ENVELOPED_ENCODE_INFO envelopedEncodeInfo = new CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)));
     SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO))));
     EnvelopedCms.SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam);
     envelopedEncodeInfo.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value;
     if (encryptParam.pvEncryptionAuxInfo != null && !encryptParam.pvEncryptionAuxInfo.IsInvalid)
         envelopedEncodeInfo.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle();
     envelopedEncodeInfo.cRecipients = (uint)recipients.Count;
     if (encryptParam.useCms)
     {
         EnvelopedCms.SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam);
         envelopedEncodeInfo.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
         if (encryptParam.rgCertEncoded != null && !encryptParam.rgCertEncoded.IsInvalid)
         {
             envelopedEncodeInfo.cCertEncoded = (uint)this.Certificates.Count;
             envelopedEncodeInfo.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle();
         }
         if (encryptParam.rgUnprotectedAttr != null && !encryptParam.rgUnprotectedAttr.IsInvalid)
         {
             envelopedEncodeInfo.cUnprotectedAttr = (uint)this.UnprotectedAttributes.Count;
             envelopedEncodeInfo.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle();
         }
     }
     else
     {
         EnvelopedCms.SetPkcs7RecipientParams(recipients, ref encryptParam);
         envelopedEncodeInfo.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
     }
     Marshal.StructureToPtr((object)envelopedEncodeInfo, localAllocHandle.DangerousGetHandle(), false);
     try
     {
         SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(65537U, 0U, 3U, localAllocHandle.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero);
         if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
             throw new CryptographicException(Marshal.GetLastWin32Error());
         if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
             this.m_safeCryptMsgHandle.Dispose();
         this.m_safeCryptMsgHandle = safeCryptMsgHandle;
     }
     finally
     {
         Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO));
         localAllocHandle.Dispose();
     }
     byte[] encodedData = new byte[0];
     if (string.Compare(this.ContentInfo.ContentType.Value, "1.2.840.113549.1.7.1", StringComparison.OrdinalIgnoreCase) == 0)
     {
         byte[] content = this.ContentInfo.Content;
         fixed (byte* numPtr = content)
         {
             if (!CAPI.EncodeObject(new IntPtr(25L), new IntPtr((void*)&new CAPI.CRYPTOAPI_BLOB()
             {
                 cbData = (uint)content.Length,
                 pbData = new IntPtr((void*)numPtr)
             }), out encodedData))
                 throw new CryptographicException(Marshal.GetLastWin32Error());
         }
     }
     else
         encodedData = this.ContentInfo.Content;
     if (encodedData.Length > 0 && !CAPI.CAPISafe.CryptMsgUpdate(this.m_safeCryptMsgHandle, encodedData, (uint)encodedData.Length, true))
         throw new CryptographicException(Marshal.GetLastWin32Error());
     GC.KeepAlive((object)encryptParam);
     GC.KeepAlive((object)recipients);
 }
Esempio n. 42
0
 private DecryptorPalWindows(SafeCryptMsgHandle hCryptMsg, RecipientInfoCollection recipientInfos)
     : base(recipientInfos)
 {
     _hCryptMsg = hCryptMsg;
 }
Esempio n. 43
0
 public void Decode(byte[] encodedMessage)
 {
     if (encodedMessage == null)
         throw new ArgumentNullException("encodedMessage");
     if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
         this.m_safeCryptMsgHandle.Dispose();
     this.m_safeCryptMsgHandle = EnvelopedCms.OpenToDecode(encodedMessage);
     this.m_version = (int)PkcsUtils.GetVersion(this.m_safeCryptMsgHandle);
     this.m_contentInfo = new ContentInfo(PkcsUtils.GetContentType(this.m_safeCryptMsgHandle), PkcsUtils.GetContent(this.m_safeCryptMsgHandle));
     this.m_encryptionAlgorithm = PkcsUtils.GetAlgorithmIdentifier(this.m_safeCryptMsgHandle);
     this.m_certificates = PkcsUtils.GetCertificates(this.m_safeCryptMsgHandle);
     this.m_unprotectedAttributes = PkcsUtils.GetUnprotectedAttributes(this.m_safeCryptMsgHandle);
 }
Esempio n. 44
0
 public static extern bool CryptMsgGetParam(SafeCryptMsgHandle hCryptMsg, CryptMessageParameterType dwParamType, int dwIndex, out int pvData, [In, Out] ref int pcbData);
Esempio n. 45
0
        public static CryptographicAttributeObjectCollection GetUnprotectedAttributes(this SafeCryptMsgHandle hCryptMsg)
        {
            // For some reason, you can't ask how many attributes there are - you have to ask for the attributes and
            // get a CRYPT_E_ATTRIBUTES_MISSING failure if the count is 0.
            int cbUnprotectedAttr = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, CryptMsgParamType.CMSG_UNPROTECTED_ATTR_PARAM, 0, null, ref cbUnprotectedAttr))
            {
                int lastError = Interop.CPError.GetLastWin32Error();
                if (lastError == (int)ErrorCode.CRYPT_E_ATTRIBUTES_MISSING)
                {
                    return(new CryptographicAttributeObjectCollection());
                }
                throw lastError.ToCryptographicException();
            }

            using (SafeHandle sh = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_UNPROTECTED_ATTR_PARAM))
            {
                unsafe
                {
                    CRYPT_ATTRIBUTES *pCryptAttributes = (CRYPT_ATTRIBUTES *)(sh.DangerousGetHandle());
                    return(ToCryptographicAttributeObjectCollection(pCryptAttributes));
                }
            }
        }
Esempio n. 46
0
        private unsafe void Sign (CmsSigner signer, bool silent) {

            SafeCryptMsgHandle safeCryptMsgHandle = null;
            CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO)));
            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);

            byte[] encodedMessage = null;
            try {
                SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

                try {
                    Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);
                    X509Certificate2Collection bagOfCerts = PkcsUtils.CreateBagOfCertificates(signer);
                    SafeLocalAllocHandle pEncodedBagOfCerts = PkcsUtils.CreateEncodedCertBlob(bagOfCerts);

                    signedEncodeInfo.cSigners = 1;
                    signedEncodeInfo.rgSigners = pSignerEncodeInfo.DangerousGetHandle();
                    signedEncodeInfo.cCertEncoded = (uint) bagOfCerts.Count;
                    if (bagOfCerts.Count > 0)
                        signedEncodeInfo.rgCertEncoded = pEncodedBagOfCerts.DangerousGetHandle();

                    // Because of the way CAPI treats inner content OID, we should pass NULL
                    // for data type, otherwise detached will not work.
                    if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0) {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       IntPtr.Zero,
                                                                       IntPtr.Zero);
                    }
                    else {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       this.ContentInfo.ContentType.Value,
                                                                       IntPtr.Zero);
                    }

                    if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                        throw new CryptographicException(Marshal.GetLastWin32Error());


                    if (this.ContentInfo.Content.Length > 0) {
                        if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint) this.ContentInfo.Content.Length, true))
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    // Retrieve encoded message.
                    encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle);
                    safeCryptMsgHandle.Dispose();

                    pEncodedBagOfCerts.Dispose();
                }
                finally {
                    Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    pSignerEncodeInfo.Dispose();
                }
            }
            finally {
                // Don't forget to free all the resource still held inside signerEncodeInfo.
                signerEncodeInfo.Dispose();
            }

            // Re-open to decode.
            safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
            if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) {
                m_safeCryptMsgHandle.Dispose();
            }
            m_safeCryptMsgHandle = safeCryptMsgHandle;
            GC.KeepAlive(signer);
        }
Esempio n. 47
0
        private static unsafe SafeCertContextHandle GetSignerInPKCS7Store(SafeCertStoreHandle hCertStore, SafeCryptMsgHandle hCryptMsg)
        {
            // make sure that there is at least one signer of the certificate store
            int dwSigners;
            int cbSigners = sizeof(int);

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, Interop.Crypt32.CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, out dwSigners, ref cbSigners))
            {
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
            }
            if (dwSigners == 0)
            {
                throw ErrorCode.CRYPT_E_SIGNER_NOT_FOUND.ToCryptographicException();
            }

            // get the first signer from the store, and use that as the loaded certificate
            int cbData = 0;

            if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, Interop.Crypt32.CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, 0, default(byte *), ref cbData))
            {
                throw Marshal.GetHRForLastWin32Error().ToCryptographicException();

                fixed(byte *pCmsgSignerBytes = new byte[cbData])
                {
                    if (!Interop.Crypt32.CryptMsgGetParam(hCryptMsg, Interop.Crypt32.CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, 0, pCmsgSignerBytes, ref cbData))
                    {
                        throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
                    }

                    CMSG_SIGNER_INFO_Partial *pCmsgSignerInfo = (CMSG_SIGNER_INFO_Partial *)pCmsgSignerBytes;

                    Interop.Crypt32.CERT_INFO certInfo = default(Interop.Crypt32.CERT_INFO);
                    certInfo.Issuer.cbData       = pCmsgSignerInfo->Issuer.cbData;
                    certInfo.Issuer.pbData       = pCmsgSignerInfo->Issuer.pbData;
                    certInfo.SerialNumber.cbData = pCmsgSignerInfo->SerialNumber.cbData;
                    certInfo.SerialNumber.pbData = pCmsgSignerInfo->SerialNumber.pbData;

                    SafeCertContextHandle?pCertContext = null;

                    if (!Interop.crypt32.CertFindCertificateInStore(hCertStore, Interop.Crypt32.CertFindType.CERT_FIND_SUBJECT_CERT, &certInfo, ref pCertContext))
                    {
                        throw Marshal.GetHRForLastWin32Error().ToCryptographicException();
                    }
                    return(pCertContext);
                }
        }
Esempio n. 48
0
        private unsafe void Sign(CmsSigner signer, bool silent)
        {
            SafeCryptMsgHandle safeCryptMsgHandle = null;

            CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO)));
            SafeCryptProvHandle          safeCryptProvHandle;

            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent, out safeCryptProvHandle);

            byte[] encodedMessage = null;
            try {
                SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));

                try {
                    Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false);
                    X509Certificate2Collection bagOfCerts         = PkcsUtils.CreateBagOfCertificates(signer);
                    SafeLocalAllocHandle       pEncodedBagOfCerts = PkcsUtils.CreateEncodedCertBlob(bagOfCerts);

                    signedEncodeInfo.cSigners     = 1;
                    signedEncodeInfo.rgSigners    = pSignerEncodeInfo.DangerousGetHandle();
                    signedEncodeInfo.cCertEncoded = (uint)bagOfCerts.Count;
                    if (bagOfCerts.Count > 0)
                    {
                        signedEncodeInfo.rgCertEncoded = pEncodedBagOfCerts.DangerousGetHandle();
                    }

                    // Because of the way CAPI treats inner content OID, we should pass NULL
                    // for data type, otherwise detached will not work.
                    if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       IntPtr.Zero,
                                                                       IntPtr.Zero);
                    }
                    else
                    {
                        safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       Detached ? CAPI.CMSG_DETACHED_FLAG : 0,
                                                                       CAPI.CMSG_SIGNED,
                                                                       new IntPtr(&signedEncodeInfo),
                                                                       this.ContentInfo.ContentType.Value,
                                                                       IntPtr.Zero);
                    }

                    if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }


                    if (this.ContentInfo.Content.Length > 0)
                    {
                        if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint)this.ContentInfo.Content.Length, true))
                        {
                            throw new CryptographicException(Marshal.GetLastWin32Error());
                        }
                    }

                    // Retrieve encoded message.
                    encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle);
                    safeCryptMsgHandle.Dispose();

                    pEncodedBagOfCerts.Dispose();
                }
                finally {
                    Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    pSignerEncodeInfo.Dispose();
                }
            }
            finally {
                // Don't forget to free all the resource still held inside signerEncodeInfo.
                signerEncodeInfo.Dispose();
                safeCryptProvHandle.Dispose();
            }

            // Re-open to decode.
            safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);
            if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid)
            {
                m_safeCryptMsgHandle.Dispose();
            }
            m_safeCryptMsgHandle = safeCryptMsgHandle;
            GC.KeepAlive(signer);
        }