| File: Internal\Cryptography\Pal\Windows\DecryptorPalWindows.DecodeRecipients.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Cryptography.Pkcs\src\System.Security.Cryptography.Pkcs.csproj (System.Security.Cryptography.Pkcs) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security.Cryptography.Pkcs; using Microsoft.Win32.SafeHandles; using static Interop.Crypt32; namespace Internal.Cryptography.Pal.Windows { internal sealed partial class DecryptorPalWindows : DecryptorPal { 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); } private static IEnumerable<RecipientInfo> ToRecipientInfosForThisIndex(SafeHandle pCmsgCmsRecipientInfoMemory, int index) { bool mustRelease = false; pCmsgCmsRecipientInfoMemory.DangerousAddRef(ref mustRelease); try { unsafe { CMSG_CMS_RECIPIENT_INFO* pCMsgCmsRecipientInfo = (CMSG_CMS_RECIPIENT_INFO*)(pCmsgCmsRecipientInfoMemory.DangerousGetHandle()); switch (pCMsgCmsRecipientInfo->dwRecipientChoice) { case CMsgCmsRecipientChoice.CMSG_KEY_TRANS_RECIPIENT: return new KeyTransRecipientInfo[] { new KeyTransRecipientInfo(new KeyTransRecipientInfoPalWindows(pCmsgCmsRecipientInfoMemory, index)) }; case CMsgCmsRecipientChoice.CMSG_KEY_AGREE_RECIPIENT: { CMSG_KEY_AGREE_RECIPIENT_INFO* pCmsKeyAgreeRecipientInfo = pCMsgCmsRecipientInfo->KeyAgree; int numKeys = pCmsKeyAgreeRecipientInfo->cRecipientEncryptedKeys; KeyAgreeRecipientInfo[] recipients = new KeyAgreeRecipientInfo[numKeys]; for (int subIndex = 0; subIndex < numKeys; subIndex++) { recipients[subIndex] = new KeyAgreeRecipientInfo(new KeyAgreeRecipientInfoPalWindows(pCmsgCmsRecipientInfoMemory, index, subIndex)); } return recipients; } default: throw ErrorCode.E_NOTIMPL.ToCryptographicException(); } } } finally { if (mustRelease) { pCmsgCmsRecipientInfoMemory.DangerousRelease(); } } } } }