// Provides access to the native CMSG_KEY_TRANS_RECIPIENT_INFO* structure. This helper is structured as taking a delegate to // help avoid the easy trap of forgetting to prevent the underlying memory block from being GC'd early. internal T WithCmsgCmsRecipientInfo <T>(KeyAgreeReceiver <T> receiver) { unsafe { CMSG_CMS_RECIPIENT_INFO * pRecipientInfo = (CMSG_CMS_RECIPIENT_INFO *)(_pCmsgCmsRecipientInfoMemory.DangerousGetHandle()); CMSG_KEY_AGREE_RECIPIENT_INFO *pKeyAgree = pRecipientInfo->KeyAgree; T value = receiver(pKeyAgree); GC.KeepAlive(_pCmsgCmsRecipientInfoMemory); return(value); } }
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(); } } }