Example #1
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));
                }
            }
        }
Example #2
0
        internal static DecryptorPalWindows Decode(
            ReadOnlySpan <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,
                    ref MemoryMarshal.GetReference(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.Value !;
                    contentEncryptionAlgorithmAsn.Parameters = (*pCryptAlgorithmIdentifier).Parameters.ToByteArray();
                }
            }

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

            RecipientInfoCollection recipientInfos = CreateRecipientInfos(hCryptMsg);

            return(new DecryptorPalWindows(hCryptMsg, recipientInfos, contentEncryptionAlgorithmAsn));
        }
Example #3
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));
        }