Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Pkcs / RecipientInfo.cs / 1305376 / RecipientInfo.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // RecipientInfo.cs // namespace System.Security.Cryptography.Pkcs { using System.Collections; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Globalization; public enum RecipientInfoType { Unknown = 0, KeyTransport = 1, // Must be the same as CAPI.CMSG_KEY_TRANS_RECIPIENT (1) KeyAgreement = 2, // Must be the same as CAPI.CMSG_KEY_AGREE_RECIPIENT (2) } internal enum RecipientSubType { Unknown = 0, Pkcs7KeyTransport = 1, CmsKeyTransport = 2, CertIdKeyAgreement = 3, PublicKeyAgreement = 4, } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public abstract class RecipientInfo { private RecipientInfoType m_recipentInfoType; private RecipientSubType m_recipientSubType; [SecurityCritical] private SafeLocalAllocHandle m_pCmsgRecipientInfo; private Object m_cmsgRecipientInfo; private uint m_index; internal RecipientInfo () {} [SecurityCritical] internal RecipientInfo (RecipientInfoType recipientInfoType, RecipientSubType recipientSubType, SafeLocalAllocHandle pCmsgRecipientInfo, Object cmsgRecipientInfo, uint index) { if (recipientInfoType < RecipientInfoType.Unknown || recipientInfoType > RecipientInfoType.KeyAgreement) recipientInfoType = RecipientInfoType.Unknown; if (recipientSubType < RecipientSubType.Unknown || recipientSubType > RecipientSubType.PublicKeyAgreement) recipientSubType = RecipientSubType.Unknown; m_recipentInfoType = recipientInfoType; m_recipientSubType = recipientSubType; m_pCmsgRecipientInfo = pCmsgRecipientInfo; m_cmsgRecipientInfo = cmsgRecipientInfo; m_index = index; } public RecipientInfoType Type { get { return m_recipentInfoType; } } public abstract int Version { get; } public abstract SubjectIdentifier RecipientIdentifier { get; } public abstract AlgorithmIdentifier KeyEncryptionAlgorithm { get; } public abstract byte[] EncryptedKey { get; } // // Internal methods. // internal RecipientSubType SubType { get { return m_recipientSubType; } } internal SafeLocalAllocHandle pCmsgRecipientInfo { [SecurityCritical] get { return m_pCmsgRecipientInfo; } } internal Object CmsgRecipientInfo { get { return m_cmsgRecipientInfo; } } internal uint Index { get { return m_index; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class KeyTransRecipientInfo : RecipientInfo { private int m_version; private SubjectIdentifier m_recipientIdentifier; private AlgorithmIdentifier m_encryptionAlgorithm; private byte[] m_encryptedKey; [SecurityCritical] internal unsafe KeyTransRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CERT_INFO certInfo, uint index) : base(RecipientInfoType.KeyTransport, RecipientSubType.Pkcs7KeyTransport, pRecipientInfo, certInfo, index) { // If serial number is 0, then it is the special SKI encoding. int version = 2; byte * pb = (byte *) certInfo.SerialNumber.pbData; for (int i = 0; i < certInfo.SerialNumber.cbData; i++) { if (*pb++ != (byte) 0) { version = 0; break; } } Reset(version); } [SecurityCritical] internal KeyTransRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans, uint index) : base(RecipientInfoType.KeyTransport, RecipientSubType.CmsKeyTransport, pRecipientInfo, keyTrans, index) { Reset((int) keyTrans.dwVersion); } public override int Version { get { return m_version; } } public override SubjectIdentifier RecipientIdentifier { [SecuritySafeCritical] get { if (m_recipientIdentifier == null) { if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; m_recipientIdentifier = new SubjectIdentifier(keyTrans.RecipientId); } else { CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) CmsgRecipientInfo; m_recipientIdentifier = new SubjectIdentifier(certInfo); } } return m_recipientIdentifier; } } public override AlgorithmIdentifier KeyEncryptionAlgorithm { [SecuritySafeCritical] get { if (m_encryptionAlgorithm == null) { if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(keyTrans.KeyEncryptionAlgorithm); } else { CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(certInfo.SignatureAlgorithm); } } return m_encryptionAlgorithm; } } public override byte[] EncryptedKey { [SecuritySafeCritical] get { if (m_encryptedKey.Length == 0) { // CAPI does not provide a way to retrieve encrypted key for PKCS 7 message. if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; if (keyTrans.EncryptedKey.cbData > 0) { m_encryptedKey = new byte[keyTrans.EncryptedKey.cbData]; Marshal.Copy(keyTrans.EncryptedKey.pbData, m_encryptedKey, 0, m_encryptedKey.Length); } } } return m_encryptedKey; } } // // Private methods. // private void Reset (int version) { m_version = version; m_recipientIdentifier = null; m_encryptionAlgorithm = null; m_encryptedKey = new byte[0]; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class KeyAgreeRecipientInfo : RecipientInfo { private CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO m_encryptedKeyInfo; private uint m_originatorChoice; private int m_version; private SubjectIdentifierOrKey m_originatorIdentifier; private byte[] m_userKeyMaterial; private AlgorithmIdentifier m_encryptionAlgorithm; private SubjectIdentifier m_recipientIdentifier; private byte[] m_encryptedKey; private DateTime m_date; private CryptographicAttributeObject m_otherKeyAttribute; private uint m_subIndex; private KeyAgreeRecipientInfo () {} [SecurityCritical] internal KeyAgreeRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO certIdRecipient, uint index, uint subIndex) : base(RecipientInfoType.KeyAgreement, RecipientSubType.CertIdKeyAgreement, pRecipientInfo, certIdRecipient, index) { IntPtr pEncryptedKeyInfo = Marshal.ReadIntPtr(new IntPtr((long) certIdRecipient.rgpRecipientEncryptedKeys + (long) (subIndex * Marshal.SizeOf(typeof(IntPtr))))); CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo = (CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO) Marshal.PtrToStructure(pEncryptedKeyInfo, typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO)); Reset(CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT, certIdRecipient.dwVersion, encryptedKeyInfo, subIndex); } [SecurityCritical] internal KeyAgreeRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO publicKeyRecipient, uint index, uint subIndex) : base(RecipientInfoType.KeyAgreement, RecipientSubType.PublicKeyAgreement, pRecipientInfo, publicKeyRecipient, index) { IntPtr pEncryptedKeyInfo = Marshal.ReadIntPtr(new IntPtr((long) publicKeyRecipient.rgpRecipientEncryptedKeys + (long) (subIndex * Marshal.SizeOf(typeof(IntPtr))))); CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo = (CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO) Marshal.PtrToStructure(pEncryptedKeyInfo, typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO)); Reset(CAPI.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY, publicKeyRecipient.dwVersion, encryptedKeyInfo, subIndex); } public override int Version { get { return m_version; } } public SubjectIdentifierOrKey OriginatorIdentifierOrKey { [SecuritySafeCritical] get { if (m_originatorIdentifier == null) { if (m_originatorChoice == CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT) { CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) CmsgRecipientInfo; m_originatorIdentifier = new SubjectIdentifierOrKey(recipientInfo.OriginatorCertId); } else { CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) CmsgRecipientInfo; m_originatorIdentifier = new SubjectIdentifierOrKey(recipientInfo.OriginatorPublicKeyInfo); } } return m_originatorIdentifier; } } public override SubjectIdentifier RecipientIdentifier { [SecuritySafeCritical] get { if (m_recipientIdentifier == null) m_recipientIdentifier = new SubjectIdentifier(m_encryptedKeyInfo.RecipientId); return m_recipientIdentifier; } } public DateTime Date { get { if (m_date == DateTime.MinValue) { if (this.RecipientIdentifier.Type != SubjectIdentifierType.SubjectKeyIdentifier) throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_Key_Agree_Date_Not_Available")); long date = (((long)(uint) m_encryptedKeyInfo.Date.dwHighDateTime) << 32) | ((long)(uint) m_encryptedKeyInfo.Date.dwLowDateTime); m_date = DateTime.FromFileTimeUtc(date); } return m_date; } } public CryptographicAttributeObject OtherKeyAttribute { [SecuritySafeCritical] get { if (m_otherKeyAttribute == null) { if (this.RecipientIdentifier.Type != SubjectIdentifierType.SubjectKeyIdentifier) throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_Key_Agree_Other_Key_Attribute_Not_Available")); if (m_encryptedKeyInfo.pOtherAttr != IntPtr.Zero) { CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE otherKeyAttribute = (CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE) Marshal.PtrToStructure(m_encryptedKeyInfo.pOtherAttr, typeof(CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE)); m_otherKeyAttribute = new CryptographicAttributeObject(otherKeyAttribute); } } return m_otherKeyAttribute; } } public override AlgorithmIdentifier KeyEncryptionAlgorithm { [SecuritySafeCritical] get { if (m_encryptionAlgorithm == null) { if (m_originatorChoice == CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT) { CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(recipientInfo.KeyEncryptionAlgorithm); } else { CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(recipientInfo.KeyEncryptionAlgorithm); } } return m_encryptionAlgorithm; } } public override byte[] EncryptedKey { [SecuritySafeCritical] get { if (m_encryptedKey.Length == 0) { if (m_encryptedKeyInfo.EncryptedKey.cbData > 0) { m_encryptedKey = new byte[m_encryptedKeyInfo.EncryptedKey.cbData]; Marshal.Copy(m_encryptedKeyInfo.EncryptedKey.pbData, m_encryptedKey, 0, m_encryptedKey.Length); } } return m_encryptedKey; } } // // Internal methods. // internal CAPI.CERT_ID RecipientId { get { return m_encryptedKeyInfo.RecipientId; } } internal uint SubIndex { get { return m_subIndex; } } // // Private methods. // private void Reset (uint originatorChoice, uint version, CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo, uint subIndex) { m_encryptedKeyInfo = encryptedKeyInfo; m_originatorChoice = originatorChoice; m_version = (int) version; m_originatorIdentifier = null; m_userKeyMaterial = new byte[0]; m_encryptionAlgorithm = null; m_recipientIdentifier = null; m_encryptedKey = new byte[0]; m_date = DateTime.MinValue; m_otherKeyAttribute = null; m_subIndex = subIndex; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class RecipientInfoCollection : ICollection { [SecurityCritical] private SafeCryptMsgHandle m_safeCryptMsgHandle; private ArrayList m_recipientInfos; [SecuritySafeCritical] internal RecipientInfoCollection () { m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; m_recipientInfos = new ArrayList(); } [SecuritySafeCritical] internal RecipientInfoCollection (RecipientInfo recipientInfo) { m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; m_recipientInfos = new ArrayList(1); m_recipientInfos.Add(recipientInfo); } [SecurityCritical] 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; } public RecipientInfo this[int index] { get { if (index < 0 || index >= m_recipientInfos.Count) throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index")); return (RecipientInfo) m_recipientInfos[index]; } } public int Count { get { return m_recipientInfos.Count; } } public RecipientInfoEnumerator GetEnumerator() { return new RecipientInfoEnumerator(this); } ///IEnumerator IEnumerable.GetEnumerator() { return new RecipientInfoEnumerator(this); } public void CopyTo(Array array, int index) { if (array == null) throw new ArgumentNullException("array"); if (array.Rank != 1) throw new ArgumentException(SecurityResources.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0 || index >= array.Length) throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index")); if (index + this.Count > array.Length) throw new ArgumentException(SecurityResources.GetResourceString("Argument_InvalidOffLen")); for (int i=0; i < this.Count; i++) { array.SetValue(this[i], index); index++; } } public void CopyTo(RecipientInfo[] array, int index) { ((ICollection)this).CopyTo(array, index); } public bool IsSynchronized { get { return false; } } public Object SyncRoot { get { return this; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class RecipientInfoEnumerator : IEnumerator { private RecipientInfoCollection m_recipientInfos; private int m_current; private RecipientInfoEnumerator() {} internal RecipientInfoEnumerator(RecipientInfoCollection RecipientInfos) { m_recipientInfos = RecipientInfos; m_current = -1; } public RecipientInfo Current { get { return m_recipientInfos[m_current]; } } /// Object IEnumerator.Current { get { return (Object) m_recipientInfos[m_current]; } } public bool MoveNext() { if (m_current == ((int) m_recipientInfos.Count - 1)) { return false; } m_current++; return true; } public void Reset() { m_current = -1; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // RecipientInfo.cs // namespace System.Security.Cryptography.Pkcs { using System.Collections; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Globalization; public enum RecipientInfoType { Unknown = 0, KeyTransport = 1, // Must be the same as CAPI.CMSG_KEY_TRANS_RECIPIENT (1) KeyAgreement = 2, // Must be the same as CAPI.CMSG_KEY_AGREE_RECIPIENT (2) } internal enum RecipientSubType { Unknown = 0, Pkcs7KeyTransport = 1, CmsKeyTransport = 2, CertIdKeyAgreement = 3, PublicKeyAgreement = 4, } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public abstract class RecipientInfo { private RecipientInfoType m_recipentInfoType; private RecipientSubType m_recipientSubType; [SecurityCritical] private SafeLocalAllocHandle m_pCmsgRecipientInfo; private Object m_cmsgRecipientInfo; private uint m_index; internal RecipientInfo () {} [SecurityCritical] internal RecipientInfo (RecipientInfoType recipientInfoType, RecipientSubType recipientSubType, SafeLocalAllocHandle pCmsgRecipientInfo, Object cmsgRecipientInfo, uint index) { if (recipientInfoType < RecipientInfoType.Unknown || recipientInfoType > RecipientInfoType.KeyAgreement) recipientInfoType = RecipientInfoType.Unknown; if (recipientSubType < RecipientSubType.Unknown || recipientSubType > RecipientSubType.PublicKeyAgreement) recipientSubType = RecipientSubType.Unknown; m_recipentInfoType = recipientInfoType; m_recipientSubType = recipientSubType; m_pCmsgRecipientInfo = pCmsgRecipientInfo; m_cmsgRecipientInfo = cmsgRecipientInfo; m_index = index; } public RecipientInfoType Type { get { return m_recipentInfoType; } } public abstract int Version { get; } public abstract SubjectIdentifier RecipientIdentifier { get; } public abstract AlgorithmIdentifier KeyEncryptionAlgorithm { get; } public abstract byte[] EncryptedKey { get; } // // Internal methods. // internal RecipientSubType SubType { get { return m_recipientSubType; } } internal SafeLocalAllocHandle pCmsgRecipientInfo { [SecurityCritical] get { return m_pCmsgRecipientInfo; } } internal Object CmsgRecipientInfo { get { return m_cmsgRecipientInfo; } } internal uint Index { get { return m_index; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class KeyTransRecipientInfo : RecipientInfo { private int m_version; private SubjectIdentifier m_recipientIdentifier; private AlgorithmIdentifier m_encryptionAlgorithm; private byte[] m_encryptedKey; [SecurityCritical] internal unsafe KeyTransRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CERT_INFO certInfo, uint index) : base(RecipientInfoType.KeyTransport, RecipientSubType.Pkcs7KeyTransport, pRecipientInfo, certInfo, index) { // If serial number is 0, then it is the special SKI encoding. int version = 2; byte * pb = (byte *) certInfo.SerialNumber.pbData; for (int i = 0; i < certInfo.SerialNumber.cbData; i++) { if (*pb++ != (byte) 0) { version = 0; break; } } Reset(version); } [SecurityCritical] internal KeyTransRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans, uint index) : base(RecipientInfoType.KeyTransport, RecipientSubType.CmsKeyTransport, pRecipientInfo, keyTrans, index) { Reset((int) keyTrans.dwVersion); } public override int Version { get { return m_version; } } public override SubjectIdentifier RecipientIdentifier { [SecuritySafeCritical] get { if (m_recipientIdentifier == null) { if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; m_recipientIdentifier = new SubjectIdentifier(keyTrans.RecipientId); } else { CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) CmsgRecipientInfo; m_recipientIdentifier = new SubjectIdentifier(certInfo); } } return m_recipientIdentifier; } } public override AlgorithmIdentifier KeyEncryptionAlgorithm { [SecuritySafeCritical] get { if (m_encryptionAlgorithm == null) { if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(keyTrans.KeyEncryptionAlgorithm); } else { CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(certInfo.SignatureAlgorithm); } } return m_encryptionAlgorithm; } } public override byte[] EncryptedKey { [SecuritySafeCritical] get { if (m_encryptedKey.Length == 0) { // CAPI does not provide a way to retrieve encrypted key for PKCS 7 message. if (this.SubType == RecipientSubType.CmsKeyTransport) { CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO keyTrans = (CAPI.CMSG_KEY_TRANS_RECIPIENT_INFO) CmsgRecipientInfo; if (keyTrans.EncryptedKey.cbData > 0) { m_encryptedKey = new byte[keyTrans.EncryptedKey.cbData]; Marshal.Copy(keyTrans.EncryptedKey.pbData, m_encryptedKey, 0, m_encryptedKey.Length); } } } return m_encryptedKey; } } // // Private methods. // private void Reset (int version) { m_version = version; m_recipientIdentifier = null; m_encryptionAlgorithm = null; m_encryptedKey = new byte[0]; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class KeyAgreeRecipientInfo : RecipientInfo { private CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO m_encryptedKeyInfo; private uint m_originatorChoice; private int m_version; private SubjectIdentifierOrKey m_originatorIdentifier; private byte[] m_userKeyMaterial; private AlgorithmIdentifier m_encryptionAlgorithm; private SubjectIdentifier m_recipientIdentifier; private byte[] m_encryptedKey; private DateTime m_date; private CryptographicAttributeObject m_otherKeyAttribute; private uint m_subIndex; private KeyAgreeRecipientInfo () {} [SecurityCritical] internal KeyAgreeRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO certIdRecipient, uint index, uint subIndex) : base(RecipientInfoType.KeyAgreement, RecipientSubType.CertIdKeyAgreement, pRecipientInfo, certIdRecipient, index) { IntPtr pEncryptedKeyInfo = Marshal.ReadIntPtr(new IntPtr((long) certIdRecipient.rgpRecipientEncryptedKeys + (long) (subIndex * Marshal.SizeOf(typeof(IntPtr))))); CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo = (CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO) Marshal.PtrToStructure(pEncryptedKeyInfo, typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO)); Reset(CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT, certIdRecipient.dwVersion, encryptedKeyInfo, subIndex); } [SecurityCritical] internal KeyAgreeRecipientInfo (SafeLocalAllocHandle pRecipientInfo, CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO publicKeyRecipient, uint index, uint subIndex) : base(RecipientInfoType.KeyAgreement, RecipientSubType.PublicKeyAgreement, pRecipientInfo, publicKeyRecipient, index) { IntPtr pEncryptedKeyInfo = Marshal.ReadIntPtr(new IntPtr((long) publicKeyRecipient.rgpRecipientEncryptedKeys + (long) (subIndex * Marshal.SizeOf(typeof(IntPtr))))); CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo = (CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO) Marshal.PtrToStructure(pEncryptedKeyInfo, typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO)); Reset(CAPI.CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY, publicKeyRecipient.dwVersion, encryptedKeyInfo, subIndex); } public override int Version { get { return m_version; } } public SubjectIdentifierOrKey OriginatorIdentifierOrKey { [SecuritySafeCritical] get { if (m_originatorIdentifier == null) { if (m_originatorChoice == CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT) { CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) CmsgRecipientInfo; m_originatorIdentifier = new SubjectIdentifierOrKey(recipientInfo.OriginatorCertId); } else { CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) CmsgRecipientInfo; m_originatorIdentifier = new SubjectIdentifierOrKey(recipientInfo.OriginatorPublicKeyInfo); } } return m_originatorIdentifier; } } public override SubjectIdentifier RecipientIdentifier { [SecuritySafeCritical] get { if (m_recipientIdentifier == null) m_recipientIdentifier = new SubjectIdentifier(m_encryptedKeyInfo.RecipientId); return m_recipientIdentifier; } } public DateTime Date { get { if (m_date == DateTime.MinValue) { if (this.RecipientIdentifier.Type != SubjectIdentifierType.SubjectKeyIdentifier) throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_Key_Agree_Date_Not_Available")); long date = (((long)(uint) m_encryptedKeyInfo.Date.dwHighDateTime) << 32) | ((long)(uint) m_encryptedKeyInfo.Date.dwLowDateTime); m_date = DateTime.FromFileTimeUtc(date); } return m_date; } } public CryptographicAttributeObject OtherKeyAttribute { [SecuritySafeCritical] get { if (m_otherKeyAttribute == null) { if (this.RecipientIdentifier.Type != SubjectIdentifierType.SubjectKeyIdentifier) throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_Key_Agree_Other_Key_Attribute_Not_Available")); if (m_encryptedKeyInfo.pOtherAttr != IntPtr.Zero) { CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE otherKeyAttribute = (CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE) Marshal.PtrToStructure(m_encryptedKeyInfo.pOtherAttr, typeof(CAPI.CRYPT_ATTRIBUTE_TYPE_VALUE)); m_otherKeyAttribute = new CryptographicAttributeObject(otherKeyAttribute); } } return m_otherKeyAttribute; } } public override AlgorithmIdentifier KeyEncryptionAlgorithm { [SecuritySafeCritical] get { if (m_encryptionAlgorithm == null) { if (m_originatorChoice == CAPI.CMSG_KEY_AGREE_ORIGINATOR_CERT) { CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_CERT_ID_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(recipientInfo.KeyEncryptionAlgorithm); } else { CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO recipientInfo = (CAPI.CMSG_KEY_AGREE_PUBLIC_KEY_RECIPIENT_INFO) CmsgRecipientInfo; m_encryptionAlgorithm = new AlgorithmIdentifier(recipientInfo.KeyEncryptionAlgorithm); } } return m_encryptionAlgorithm; } } public override byte[] EncryptedKey { [SecuritySafeCritical] get { if (m_encryptedKey.Length == 0) { if (m_encryptedKeyInfo.EncryptedKey.cbData > 0) { m_encryptedKey = new byte[m_encryptedKeyInfo.EncryptedKey.cbData]; Marshal.Copy(m_encryptedKeyInfo.EncryptedKey.pbData, m_encryptedKey, 0, m_encryptedKey.Length); } } return m_encryptedKey; } } // // Internal methods. // internal CAPI.CERT_ID RecipientId { get { return m_encryptedKeyInfo.RecipientId; } } internal uint SubIndex { get { return m_subIndex; } } // // Private methods. // private void Reset (uint originatorChoice, uint version, CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_INFO encryptedKeyInfo, uint subIndex) { m_encryptedKeyInfo = encryptedKeyInfo; m_originatorChoice = originatorChoice; m_version = (int) version; m_originatorIdentifier = null; m_userKeyMaterial = new byte[0]; m_encryptionAlgorithm = null; m_recipientIdentifier = null; m_encryptedKey = new byte[0]; m_date = DateTime.MinValue; m_otherKeyAttribute = null; m_subIndex = subIndex; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class RecipientInfoCollection : ICollection { [SecurityCritical] private SafeCryptMsgHandle m_safeCryptMsgHandle; private ArrayList m_recipientInfos; [SecuritySafeCritical] internal RecipientInfoCollection () { m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; m_recipientInfos = new ArrayList(); } [SecuritySafeCritical] internal RecipientInfoCollection (RecipientInfo recipientInfo) { m_safeCryptMsgHandle = SafeCryptMsgHandle.InvalidHandle; m_recipientInfos = new ArrayList(1); m_recipientInfos.Add(recipientInfo); } [SecurityCritical] 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; } public RecipientInfo this[int index] { get { if (index < 0 || index >= m_recipientInfos.Count) throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index")); return (RecipientInfo) m_recipientInfos[index]; } } public int Count { get { return m_recipientInfos.Count; } } public RecipientInfoEnumerator GetEnumerator() { return new RecipientInfoEnumerator(this); } /// IEnumerator IEnumerable.GetEnumerator() { return new RecipientInfoEnumerator(this); } public void CopyTo(Array array, int index) { if (array == null) throw new ArgumentNullException("array"); if (array.Rank != 1) throw new ArgumentException(SecurityResources.GetResourceString("Arg_RankMultiDimNotSupported")); if (index < 0 || index >= array.Length) throw new ArgumentOutOfRangeException("index", SecurityResources.GetResourceString("ArgumentOutOfRange_Index")); if (index + this.Count > array.Length) throw new ArgumentException(SecurityResources.GetResourceString("Argument_InvalidOffLen")); for (int i=0; i < this.Count; i++) { array.SetValue(this[i], index); index++; } } public void CopyTo(RecipientInfo[] array, int index) { ((ICollection)this).CopyTo(array, index); } public bool IsSynchronized { get { return false; } } public Object SyncRoot { get { return this; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class RecipientInfoEnumerator : IEnumerator { private RecipientInfoCollection m_recipientInfos; private int m_current; private RecipientInfoEnumerator() {} internal RecipientInfoEnumerator(RecipientInfoCollection RecipientInfos) { m_recipientInfos = RecipientInfos; m_current = -1; } public RecipientInfo Current { get { return m_recipientInfos[m_current]; } } /// Object IEnumerator.Current { get { return (Object) m_recipientInfos[m_current]; } } public bool MoveNext() { if (m_current == ((int) m_recipientInfos.Count - 1)) { return false; } m_current++; return true; } public void Reset() { m_current = -1; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebPartMenuStyle.cs
- WindowsScrollBar.cs
- BindingMAnagerBase.cs
- X509SecurityTokenProvider.cs
- ErrorFormatterPage.cs
- HttpListenerResponse.cs
- ReadOnlyObservableCollection.cs
- EncoderExceptionFallback.cs
- MsmqReceiveParameters.cs
- PostBackTrigger.cs
- ByteFacetDescriptionElement.cs
- InputMethod.cs
- DirectoryRedirect.cs
- SafeBitVector32.cs
- VisualStyleInformation.cs
- FormsAuthenticationUser.cs
- _IPv4Address.cs
- Accessors.cs
- ElementProxy.cs
- MultipartIdentifier.cs
- PolyQuadraticBezierSegment.cs
- PermissionListSet.cs
- RenderData.cs
- RuntimeResourceSet.cs
- WorkflowRuntimeService.cs
- BitmapFrame.cs
- ServiceOperationListItem.cs
- UpdateExpressionVisitor.cs
- TextTrailingWordEllipsis.cs
- Directory.cs
- CharacterMetrics.cs
- MimeMapping.cs
- Misc.cs
- SQlBooleanStorage.cs
- SelectedCellsChangedEventArgs.cs
- Debugger.cs
- LoginName.cs
- LowerCaseStringConverter.cs
- DocobjHost.cs
- XPathDescendantIterator.cs
- RadioButtonFlatAdapter.cs
- WindowsNonControl.cs
- AttributeTableBuilder.cs
- SelectionChangedEventArgs.cs
- SqlNode.cs
- ProgressBar.cs
- Psha1DerivedKeyGenerator.cs
- WebPartConnectionsConnectVerb.cs
- PreviewPrintController.cs
- DeferredSelectedIndexReference.cs
- OracleFactory.cs
- TrackingServices.cs
- TableLayoutCellPaintEventArgs.cs
- XmlIncludeAttribute.cs
- AssemblyAttributesGoHere.cs
- ICollection.cs
- SemanticResultValue.cs
- InvalidAsynchronousStateException.cs
- WebBaseEventKeyComparer.cs
- ProjectionPath.cs
- ColumnMapVisitor.cs
- NullableFloatSumAggregationOperator.cs
- NamespaceDisplay.xaml.cs
- CompilationUtil.cs
- ComplusEndpointConfigContainer.cs
- InputChannelAcceptor.cs
- PenThreadPool.cs
- AssociationSetMetadata.cs
- ColorBlend.cs
- ConnectionPoint.cs
- controlskin.cs
- CommentEmitter.cs
- SmtpReplyReaderFactory.cs
- HebrewNumber.cs
- SQLBytes.cs
- CancellationTokenSource.cs
- XmlEncodedRawTextWriter.cs
- EntityCommandDefinition.cs
- Nodes.cs
- MetadataHelper.cs
- TriggerActionCollection.cs
- TextHintingModeValidation.cs
- Int64.cs
- CellTreeNodeVisitors.cs
- EntityTypeEmitter.cs
- SQLBoolean.cs
- SvcMapFileLoader.cs
- OrderByExpression.cs
- DesignerUtility.cs
- DbProviderConfigurationHandler.cs
- validationstate.cs
- Int32RectValueSerializer.cs
- WebPartChrome.cs
- DbLambda.cs
- hresults.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- ImageListUtils.cs
- DataViewSetting.cs
- PeoplePickerWrapper.cs
- FacetEnabledSchemaElement.cs