Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Pkcs / PkcsMisc.cs / 1 / PkcsMisc.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // PkcsMisc.cs // // 02/09/2003 // namespace System.Security.Cryptography.Pkcs { using System.Collections; using System.Globalization; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; public enum KeyAgreeKeyChoice { Unknown = 0, EphemeralKey = 1, StaticKey = 2, } public enum SubjectIdentifierType { Unknown = 0, // Use any of the following as appropriate IssuerAndSerialNumber = 1, // X509IssuerSerial SubjectKeyIdentifier = 2, // SKI hex string NoSignature = 3 // NoSignature } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class SubjectIdentifier { private SubjectIdentifierType m_type; private Object m_value; private SubjectIdentifier () {} internal SubjectIdentifier (CAPI.CERT_INFO certInfo) : this(certInfo.Issuer, certInfo.SerialNumber) {} internal SubjectIdentifier (CAPI.CMSG_SIGNER_INFO signerInfo) : this(signerInfo.Issuer, signerInfo.SerialNumber) {} internal SubjectIdentifier (SubjectIdentifierType type, Object value) { Reset(type, value); } internal unsafe SubjectIdentifier (CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte * pb = (byte *) serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte) 0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) throw new CryptographicException(Marshal.GetLastWin32Error()); using (pbCertNameInfo) { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO) Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN) Marshal.PtrToStructure(new IntPtr((long) certNameInfo.rgRDN + (long) (i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR) Marshal.PtrToStructure(new IntPtr((long) certRdn.rgRDNAttr + (long) (j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } throw new CryptographicException(CAPI.CRYPT_E_ISSUER_SERIALNUMBER); } else { CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); } } internal SubjectIdentifier (CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case CAPI.CERT_ID_ISSUER_SERIAL_NUMBER: X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); break; case CAPI.CERT_ID_KEY_IDENTIFIER: byte[] ski = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); } } public SubjectIdentifierType Type { get { return m_type; } } public Object Value { get { return m_value; } } // // Internal methods. // internal void Reset (SubjectIdentifierType type, Object value) { switch (type) { case SubjectIdentifierType.NoSignature: case SubjectIdentifierType.Unknown: break; case SubjectIdentifierType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString()); } m_type = type; m_value = value; } } public enum SubjectIdentifierOrKeyType { Unknown = 0, // Use any of the following as appropriate IssuerAndSerialNumber = 1, // X509IssuerSerial SubjectKeyIdentifier = 2, // SKI hex string PublicKeyInfo = 3, // PublicKeyInfo } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class PublicKeyInfo { private AlgorithmIdentifier m_algorithm; private byte[] m_keyValue; private PublicKeyInfo () {} internal PublicKeyInfo (CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { m_algorithm = new AlgorithmIdentifier(keyInfo); m_keyValue = new byte[keyInfo.PublicKey.cbData]; if (m_keyValue.Length > 0) { Marshal.Copy(keyInfo.PublicKey.pbData, m_keyValue, 0, m_keyValue.Length); } } public AlgorithmIdentifier Algorithm { get { return m_algorithm; } } public byte[] KeyValue { get { return m_keyValue; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class SubjectIdentifierOrKey { private SubjectIdentifierOrKeyType m_type; private Object m_value; private SubjectIdentifierOrKey () {} internal SubjectIdentifierOrKey (SubjectIdentifierOrKeyType type, Object value) { Reset(type, value); } internal SubjectIdentifierOrKey (CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case CAPI.CERT_ID_ISSUER_SERIAL_NUMBER: X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); Reset(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, issuerSerial); break; case CAPI.CERT_ID_KEY_IDENTIFIER: byte[] ski = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); } } internal SubjectIdentifierOrKey (CAPI.CERT_PUBLIC_KEY_INFO publicKeyInfo) { Reset(SubjectIdentifierOrKeyType.PublicKeyInfo, new PublicKeyInfo(publicKeyInfo)); } public SubjectIdentifierOrKeyType Type { get { return m_type; } } public Object Value { get { return m_value; } } // // Internal methods. // internal void Reset (SubjectIdentifierOrKeyType type, Object value) { switch (type) { case SubjectIdentifierOrKeyType.Unknown: break; case SubjectIdentifierOrKeyType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierOrKeyType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierOrKeyType.PublicKeyInfo: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(PublicKeyInfo)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString()); } m_type = type; m_value = value; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class AlgorithmIdentifier { private Oid m_oid; private int m_keyLength; private byte[] m_parameters; public AlgorithmIdentifier () { Reset(new Oid(CAPI.szOID_RSA_DES_EDE3_CBC), 0, new byte[0]); } public AlgorithmIdentifier (Oid oid) { Reset(oid, 0, new byte[0]); } public AlgorithmIdentifier (Oid oid, int keyLength) { Reset(oid, keyLength, new byte[0]); } internal AlgorithmIdentifier (string oidValue) { Reset(new Oid(oidValue), 0, new byte[0]); } internal unsafe AlgorithmIdentifier (CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { SafeLocalAllocHandle pKeyInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO)))); Marshal.StructureToPtr(keyInfo, pKeyInfo.DangerousGetHandle(), false); int keyLength = (int) CAPI.CertGetPublicKeyLength(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pKeyInfo.DangerousGetHandle()); byte[] parameters = new byte[keyInfo.Algorithm.Parameters.cbData]; if (parameters.Length > 0) { Marshal.Copy(keyInfo.Algorithm.Parameters.pbData, parameters, 0, parameters.Length); } Marshal.DestroyStructure(pKeyInfo.DangerousGetHandle(), typeof(CAPI.CERT_PUBLIC_KEY_INFO)); pKeyInfo.Dispose(); Reset(new Oid(keyInfo.Algorithm.pszObjId), keyLength, parameters); } internal unsafe AlgorithmIdentifier (CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier) { int keyLength = 0; uint cbParameters = 0; SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle; byte[] parameters = new byte[0]; uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId); if (algId == CAPI.CALG_RC2) { if (algorithmIdentifier.Parameters.cbData > 0) { if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out pbParameters, out cbParameters)) throw new CryptographicException(Marshal.GetLastWin32Error()); CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS) Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS)); switch (rc2Parameters.dwVersion) { case CAPI.CRYPT_RC2_40BIT_VERSION: keyLength = 40; break; case CAPI.CRYPT_RC2_56BIT_VERSION: keyLength = 56; break; case CAPI.CRYPT_RC2_128BIT_VERSION: keyLength = 128; break; } // Retrieve IV if available. if (rc2Parameters.fIV) { parameters = (byte[]) rc2Parameters.rgbIV.Clone(); } } } else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES) { // Retrieve the IV if available. For non RC2, the parameter contains the IV // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8 // bytes of RC4 salt. if (algorithmIdentifier.Parameters.cbData > 0) { if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out pbParameters, out cbParameters)) throw new CryptographicException(Marshal.GetLastWin32Error()); if (cbParameters > 0) { if (algId == CAPI.CALG_RC4) { CAPI.CRYPTOAPI_BLOB saltBlob = (CAPI.CRYPTOAPI_BLOB) Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB)); if (saltBlob.cbData > 0) { parameters = new byte[saltBlob.cbData]; Marshal.Copy(saltBlob.pbData, parameters, 0, parameters.Length); } } else { parameters = new byte[cbParameters]; Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length); } } } // Determine key length. if (algId == CAPI.CALG_RC4) { // For RC4, keyLength = 128 - (salt length * 8). keyLength = 128 - ((int) parameters.Length * 8); } else if (algId == CAPI.CALG_DES) { // DES key length is fixed at 64 (or 56 without the parity bits). keyLength = 64; } else { // 3DES key length is fixed at 192 (or 168 without the parity bits). keyLength = 192; } } else { // Everything else, don't decode it as CAPI may not expose or know how. if (algorithmIdentifier.Parameters.cbData > 0) { parameters = new byte[algorithmIdentifier.Parameters.cbData]; Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length); } } Reset(new Oid(algorithmIdentifier.pszObjId), keyLength, parameters); pbParameters.Dispose(); } public Oid Oid { get { return m_oid; } set { m_oid = value; } } public int KeyLength { get { return m_keyLength; } set { m_keyLength = value; } } public byte[] Parameters { get { return m_parameters; } set { m_parameters = value; } } // // Private methods. // private void Reset (Oid oid, int keyLength, byte[] parameters) { m_oid = oid; m_keyLength = keyLength; m_parameters = parameters; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class ContentInfo { private Oid m_contentType; private byte[] m_content; private IntPtr m_pContent = IntPtr.Zero; private GCHandle m_gcHandle; // // Constructors // private ContentInfo () : this(new Oid(CAPI.szOID_RSA_data), new byte[0]) {} public ContentInfo (byte[] content) : this(new Oid(CAPI.szOID_RSA_data), content) {} internal ContentInfo (string contentType, byte[] content) : this(new Oid(contentType), content) {} public ContentInfo (Oid contentType, byte[] content) { if (contentType == null) throw new ArgumentNullException("contentType"); if (content == null) throw new ArgumentNullException("content"); m_contentType = contentType; m_content = content; } public Oid ContentType { get { return m_contentType; } } public byte[] Content { get { return m_content; } } ~ContentInfo() { if (m_gcHandle.IsAllocated) { m_gcHandle.Free(); } } internal IntPtr pContent { get { if (IntPtr.Zero == m_pContent) { if (m_content != null && m_content.Length != 0) { m_gcHandle = GCHandle.Alloc(m_content, GCHandleType.Pinned); //m_pContent = handle.AddrOfPinnedObject(); m_pContent = Marshal.UnsafeAddrOfPinnedArrayElement(m_content, 0); } } return m_pContent; } } public static Oid GetContentType (byte[] encodedMessage) { if (encodedMessage == null) throw new ArgumentNullException("encodedMessage"); SafeCryptMsgHandle safeCryptMsgHandle = CAPI.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.CryptMsgUpdate(safeCryptMsgHandle, encodedMessage, (uint) encodedMessage.Length, true)) throw new CryptographicException(Marshal.GetLastWin32Error()); Oid contentType; switch (PkcsUtils.GetMessageType(safeCryptMsgHandle)) { case CAPI.CMSG_DATA: contentType = new Oid(CAPI.szOID_RSA_data); break; case CAPI.CMSG_SIGNED: contentType = new Oid(CAPI.szOID_RSA_signedData); break; case CAPI.CMSG_ENVELOPED: contentType = new Oid(CAPI.szOID_RSA_envelopedData); break; case CAPI.CMSG_SIGNED_AND_ENVELOPED: contentType = new Oid(CAPI.szOID_RSA_signEnvData); break; case CAPI.CMSG_HASHED: contentType = new Oid(CAPI.szOID_RSA_hashedData); break; case CAPI.CMSG_ENCRYPTED: contentType = new Oid(CAPI.szOID_RSA_encryptedData); break; default: throw new CryptographicException(CAPI.CRYPT_E_INVALID_MSG_TYPE); } safeCryptMsgHandle.Dispose(); return contentType; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // PkcsMisc.cs // // 02/09/2003 // namespace System.Security.Cryptography.Pkcs { using System.Collections; using System.Globalization; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; public enum KeyAgreeKeyChoice { Unknown = 0, EphemeralKey = 1, StaticKey = 2, } public enum SubjectIdentifierType { Unknown = 0, // Use any of the following as appropriate IssuerAndSerialNumber = 1, // X509IssuerSerial SubjectKeyIdentifier = 2, // SKI hex string NoSignature = 3 // NoSignature } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class SubjectIdentifier { private SubjectIdentifierType m_type; private Object m_value; private SubjectIdentifier () {} internal SubjectIdentifier (CAPI.CERT_INFO certInfo) : this(certInfo.Issuer, certInfo.SerialNumber) {} internal SubjectIdentifier (CAPI.CMSG_SIGNER_INFO signerInfo) : this(signerInfo.Issuer, signerInfo.SerialNumber) {} internal SubjectIdentifier (SubjectIdentifierType type, Object value) { Reset(type, value); } internal unsafe SubjectIdentifier (CAPI.CRYPTOAPI_BLOB issuer, CAPI.CRYPTOAPI_BLOB serialNumber) { // If serial number is 0, then it is the special SKI encoding or NoSignature bool isSKIorHashOnly = true; byte * pb = (byte *) serialNumber.pbData; for (uint i = 0; i < serialNumber.cbData; i++) { if (*pb++ != (byte) 0) { isSKIorHashOnly = false; break; } } if (isSKIorHashOnly) { byte[] issuerBytes = new byte[issuer.cbData]; Marshal.Copy(issuer.pbData, issuerBytes, 0, issuerBytes.Length); X500DistinguishedName dummyName = new X500DistinguishedName(issuerBytes); if (String.Compare(CAPI.DummySignerCommonName, dummyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { Reset(SubjectIdentifierType.NoSignature, null); return; } } if (isSKIorHashOnly) { // Decode disguised SKI in issuer field (See WinCrypt.h for more info). m_type = SubjectIdentifierType.SubjectKeyIdentifier; m_value = String.Empty; uint cbCertNameInfo = 0; SafeLocalAllocHandle pbCertNameInfo = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_NAME), issuer.pbData, issuer.cbData, out pbCertNameInfo, out cbCertNameInfo)) throw new CryptographicException(Marshal.GetLastWin32Error()); using (pbCertNameInfo) { CAPI.CERT_NAME_INFO certNameInfo = (CAPI.CERT_NAME_INFO) Marshal.PtrToStructure(pbCertNameInfo.DangerousGetHandle(), typeof(CAPI.CERT_NAME_INFO)); for (uint i = 0; i < certNameInfo.cRDN; i++) { CAPI.CERT_RDN certRdn = (CAPI.CERT_RDN) Marshal.PtrToStructure(new IntPtr((long) certNameInfo.rgRDN + (long) (i * Marshal.SizeOf(typeof(CAPI.CERT_RDN)))), typeof(CAPI.CERT_RDN)); for (uint j = 0; j < certRdn.cRDNAttr; j++) { CAPI.CERT_RDN_ATTR certRdnAttr = (CAPI.CERT_RDN_ATTR) Marshal.PtrToStructure(new IntPtr((long) certRdn.rgRDNAttr + (long) (j * Marshal.SizeOf(typeof(CAPI.CERT_RDN_ATTR)))), typeof(CAPI.CERT_RDN_ATTR)); if (String.Compare(CAPI.szOID_KEYID_RDN, certRdnAttr.pszObjId, StringComparison.OrdinalIgnoreCase) == 0) { if (certRdnAttr.dwValueType == CAPI.CERT_RDN_OCTET_STRING) { byte[] ski = new byte[certRdnAttr.Value.cbData]; Marshal.Copy(certRdnAttr.Value.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); return; } } } } } throw new CryptographicException(CAPI.CRYPT_E_ISSUER_SERIALNUMBER); } else { CAPI.CERT_ISSUER_SERIAL_NUMBER IssuerAndSerial; IssuerAndSerial.Issuer = issuer; IssuerAndSerial.SerialNumber = serialNumber; X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(IssuerAndSerial); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); } } internal SubjectIdentifier (CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case CAPI.CERT_ID_ISSUER_SERIAL_NUMBER: X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); Reset(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial); break; case CAPI.CERT_ID_KEY_IDENTIFIER: byte[] ski = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); } } public SubjectIdentifierType Type { get { return m_type; } } public Object Value { get { return m_value; } } // // Internal methods. // internal void Reset (SubjectIdentifierType type, Object value) { switch (type) { case SubjectIdentifierType.NoSignature: case SubjectIdentifierType.Unknown: break; case SubjectIdentifierType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString()); } m_type = type; m_value = value; } } public enum SubjectIdentifierOrKeyType { Unknown = 0, // Use any of the following as appropriate IssuerAndSerialNumber = 1, // X509IssuerSerial SubjectKeyIdentifier = 2, // SKI hex string PublicKeyInfo = 3, // PublicKeyInfo } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class PublicKeyInfo { private AlgorithmIdentifier m_algorithm; private byte[] m_keyValue; private PublicKeyInfo () {} internal PublicKeyInfo (CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { m_algorithm = new AlgorithmIdentifier(keyInfo); m_keyValue = new byte[keyInfo.PublicKey.cbData]; if (m_keyValue.Length > 0) { Marshal.Copy(keyInfo.PublicKey.pbData, m_keyValue, 0, m_keyValue.Length); } } public AlgorithmIdentifier Algorithm { get { return m_algorithm; } } public byte[] KeyValue { get { return m_keyValue; } } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class SubjectIdentifierOrKey { private SubjectIdentifierOrKeyType m_type; private Object m_value; private SubjectIdentifierOrKey () {} internal SubjectIdentifierOrKey (SubjectIdentifierOrKeyType type, Object value) { Reset(type, value); } internal SubjectIdentifierOrKey (CAPI.CERT_ID certId) { switch (certId.dwIdChoice) { case CAPI.CERT_ID_ISSUER_SERIAL_NUMBER: X509IssuerSerial issuerSerial = PkcsUtils.DecodeIssuerSerial(certId.Value.IssuerSerialNumber); Reset(SubjectIdentifierOrKeyType.IssuerAndSerialNumber, issuerSerial); break; case CAPI.CERT_ID_KEY_IDENTIFIER: byte[] ski = new byte[certId.Value.KeyId.cbData]; Marshal.Copy(certId.Value.KeyId.pbData, ski, 0, ski.Length); Reset(SubjectIdentifierOrKeyType.SubjectKeyIdentifier, X509Utils.EncodeHexString(ski)); break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), certId.dwIdChoice.ToString(CultureInfo.InvariantCulture)); } } internal SubjectIdentifierOrKey (CAPI.CERT_PUBLIC_KEY_INFO publicKeyInfo) { Reset(SubjectIdentifierOrKeyType.PublicKeyInfo, new PublicKeyInfo(publicKeyInfo)); } public SubjectIdentifierOrKeyType Type { get { return m_type; } } public Object Value { get { return m_value; } } // // Internal methods. // internal void Reset (SubjectIdentifierOrKeyType type, Object value) { switch (type) { case SubjectIdentifierOrKeyType.Unknown: break; case SubjectIdentifierOrKeyType.IssuerAndSerialNumber: if (value.GetType() != typeof(X509IssuerSerial)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierOrKeyType.SubjectKeyIdentifier: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(string)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; case SubjectIdentifierOrKeyType.PublicKeyInfo: if (!PkcsUtils.CmsSupported()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported")); } if (value.GetType() != typeof(PublicKeyInfo)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type_Value_Mismatch"), value.GetType().ToString()); } break; default: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Invalid_Subject_Identifier_Type"), type.ToString()); } m_type = type; m_value = value; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class AlgorithmIdentifier { private Oid m_oid; private int m_keyLength; private byte[] m_parameters; public AlgorithmIdentifier () { Reset(new Oid(CAPI.szOID_RSA_DES_EDE3_CBC), 0, new byte[0]); } public AlgorithmIdentifier (Oid oid) { Reset(oid, 0, new byte[0]); } public AlgorithmIdentifier (Oid oid, int keyLength) { Reset(oid, keyLength, new byte[0]); } internal AlgorithmIdentifier (string oidValue) { Reset(new Oid(oidValue), 0, new byte[0]); } internal unsafe AlgorithmIdentifier (CAPI.CERT_PUBLIC_KEY_INFO keyInfo) { SafeLocalAllocHandle pKeyInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CERT_PUBLIC_KEY_INFO)))); Marshal.StructureToPtr(keyInfo, pKeyInfo.DangerousGetHandle(), false); int keyLength = (int) CAPI.CertGetPublicKeyLength(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pKeyInfo.DangerousGetHandle()); byte[] parameters = new byte[keyInfo.Algorithm.Parameters.cbData]; if (parameters.Length > 0) { Marshal.Copy(keyInfo.Algorithm.Parameters.pbData, parameters, 0, parameters.Length); } Marshal.DestroyStructure(pKeyInfo.DangerousGetHandle(), typeof(CAPI.CERT_PUBLIC_KEY_INFO)); pKeyInfo.Dispose(); Reset(new Oid(keyInfo.Algorithm.pszObjId), keyLength, parameters); } internal unsafe AlgorithmIdentifier (CAPI.CRYPT_ALGORITHM_IDENTIFIER algorithmIdentifier) { int keyLength = 0; uint cbParameters = 0; SafeLocalAllocHandle pbParameters = SafeLocalAllocHandle.InvalidHandle; byte[] parameters = new byte[0]; uint algId = X509Utils.OidToAlgId(algorithmIdentifier.pszObjId); if (algId == CAPI.CALG_RC2) { if (algorithmIdentifier.Parameters.cbData > 0) { if (!CAPI.DecodeObject(new IntPtr(CAPI.PKCS_RC2_CBC_PARAMETERS), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out pbParameters, out cbParameters)) throw new CryptographicException(Marshal.GetLastWin32Error()); CAPI.CRYPT_RC2_CBC_PARAMETERS rc2Parameters = (CAPI.CRYPT_RC2_CBC_PARAMETERS) Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPT_RC2_CBC_PARAMETERS)); switch (rc2Parameters.dwVersion) { case CAPI.CRYPT_RC2_40BIT_VERSION: keyLength = 40; break; case CAPI.CRYPT_RC2_56BIT_VERSION: keyLength = 56; break; case CAPI.CRYPT_RC2_128BIT_VERSION: keyLength = 128; break; } // Retrieve IV if available. if (rc2Parameters.fIV) { parameters = (byte[]) rc2Parameters.rgbIV.Clone(); } } } else if (algId == CAPI.CALG_RC4 || algId == CAPI.CALG_DES || algId == CAPI.CALG_3DES) { // Retrieve the IV if available. For non RC2, the parameter contains the IV // (for RC4 the IV is really the salt). There are (128 - KeyLength) / 8 // bytes of RC4 salt. if (algorithmIdentifier.Parameters.cbData > 0) { if (!CAPI.DecodeObject(new IntPtr(CAPI.X509_OCTET_STRING), algorithmIdentifier.Parameters.pbData, algorithmIdentifier.Parameters.cbData, out pbParameters, out cbParameters)) throw new CryptographicException(Marshal.GetLastWin32Error()); if (cbParameters > 0) { if (algId == CAPI.CALG_RC4) { CAPI.CRYPTOAPI_BLOB saltBlob = (CAPI.CRYPTOAPI_BLOB) Marshal.PtrToStructure(pbParameters.DangerousGetHandle(), typeof(CAPI.CRYPTOAPI_BLOB)); if (saltBlob.cbData > 0) { parameters = new byte[saltBlob.cbData]; Marshal.Copy(saltBlob.pbData, parameters, 0, parameters.Length); } } else { parameters = new byte[cbParameters]; Marshal.Copy(pbParameters.DangerousGetHandle(), parameters, 0, parameters.Length); } } } // Determine key length. if (algId == CAPI.CALG_RC4) { // For RC4, keyLength = 128 - (salt length * 8). keyLength = 128 - ((int) parameters.Length * 8); } else if (algId == CAPI.CALG_DES) { // DES key length is fixed at 64 (or 56 without the parity bits). keyLength = 64; } else { // 3DES key length is fixed at 192 (or 168 without the parity bits). keyLength = 192; } } else { // Everything else, don't decode it as CAPI may not expose or know how. if (algorithmIdentifier.Parameters.cbData > 0) { parameters = new byte[algorithmIdentifier.Parameters.cbData]; Marshal.Copy(algorithmIdentifier.Parameters.pbData, parameters, 0, parameters.Length); } } Reset(new Oid(algorithmIdentifier.pszObjId), keyLength, parameters); pbParameters.Dispose(); } public Oid Oid { get { return m_oid; } set { m_oid = value; } } public int KeyLength { get { return m_keyLength; } set { m_keyLength = value; } } public byte[] Parameters { get { return m_parameters; } set { m_parameters = value; } } // // Private methods. // private void Reset (Oid oid, int keyLength, byte[] parameters) { m_oid = oid; m_keyLength = keyLength; m_parameters = parameters; } } [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class ContentInfo { private Oid m_contentType; private byte[] m_content; private IntPtr m_pContent = IntPtr.Zero; private GCHandle m_gcHandle; // // Constructors // private ContentInfo () : this(new Oid(CAPI.szOID_RSA_data), new byte[0]) {} public ContentInfo (byte[] content) : this(new Oid(CAPI.szOID_RSA_data), content) {} internal ContentInfo (string contentType, byte[] content) : this(new Oid(contentType), content) {} public ContentInfo (Oid contentType, byte[] content) { if (contentType == null) throw new ArgumentNullException("contentType"); if (content == null) throw new ArgumentNullException("content"); m_contentType = contentType; m_content = content; } public Oid ContentType { get { return m_contentType; } } public byte[] Content { get { return m_content; } } ~ContentInfo() { if (m_gcHandle.IsAllocated) { m_gcHandle.Free(); } } internal IntPtr pContent { get { if (IntPtr.Zero == m_pContent) { if (m_content != null && m_content.Length != 0) { m_gcHandle = GCHandle.Alloc(m_content, GCHandleType.Pinned); //m_pContent = handle.AddrOfPinnedObject(); m_pContent = Marshal.UnsafeAddrOfPinnedArrayElement(m_content, 0); } } return m_pContent; } } public static Oid GetContentType (byte[] encodedMessage) { if (encodedMessage == null) throw new ArgumentNullException("encodedMessage"); SafeCryptMsgHandle safeCryptMsgHandle = CAPI.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.CryptMsgUpdate(safeCryptMsgHandle, encodedMessage, (uint) encodedMessage.Length, true)) throw new CryptographicException(Marshal.GetLastWin32Error()); Oid contentType; switch (PkcsUtils.GetMessageType(safeCryptMsgHandle)) { case CAPI.CMSG_DATA: contentType = new Oid(CAPI.szOID_RSA_data); break; case CAPI.CMSG_SIGNED: contentType = new Oid(CAPI.szOID_RSA_signedData); break; case CAPI.CMSG_ENVELOPED: contentType = new Oid(CAPI.szOID_RSA_envelopedData); break; case CAPI.CMSG_SIGNED_AND_ENVELOPED: contentType = new Oid(CAPI.szOID_RSA_signEnvData); break; case CAPI.CMSG_HASHED: contentType = new Oid(CAPI.szOID_RSA_hashedData); break; case CAPI.CMSG_ENCRYPTED: contentType = new Oid(CAPI.szOID_RSA_encryptedData); break; default: throw new CryptographicException(CAPI.CRYPT_E_INVALID_MSG_TYPE); } safeCryptMsgHandle.Dispose(); return contentType; } } } // 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
- Button.cs
- DeviceSpecificDesigner.cs
- SafeSecurityHelper.cs
- RemotingSurrogateSelector.cs
- SecureConversationServiceElement.cs
- GridView.cs
- ConfigXmlText.cs
- UpdateProgress.cs
- HtmlSelect.cs
- QuaternionRotation3D.cs
- _UncName.cs
- Matrix.cs
- SafeLocalMemHandle.cs
- WebControlParameterProxy.cs
- HttpRuntime.cs
- uribuilder.cs
- HtmlInputHidden.cs
- SQLChars.cs
- EventMappingSettingsCollection.cs
- Trace.cs
- HttpCacheParams.cs
- MD5CryptoServiceProvider.cs
- ISAPIApplicationHost.cs
- NamespaceInfo.cs
- MimeBasePart.cs
- PathFigureCollectionConverter.cs
- SqlRowUpdatingEvent.cs
- FlowDocumentView.cs
- TextEditorParagraphs.cs
- CodeValidator.cs
- SchemaCompiler.cs
- _SSPIWrapper.cs
- DecodeHelper.cs
- PathStreamGeometryContext.cs
- WeakHashtable.cs
- WebPartUtil.cs
- MultiByteCodec.cs
- TablePattern.cs
- ProfileParameter.cs
- XmlSiteMapProvider.cs
- Package.cs
- DateTimeConverter.cs
- TextServicesLoader.cs
- MsmqIntegrationProcessProtocolHandler.cs
- OutputCacheProfile.cs
- ThreadPool.cs
- DesignerForm.cs
- CounterSampleCalculator.cs
- WebPartCatalogAddVerb.cs
- TypeElementCollection.cs
- NavigationService.cs
- ProfilePropertyNameValidator.cs
- VoiceSynthesis.cs
- ConstraintStruct.cs
- MouseCaptureWithinProperty.cs
- RowTypePropertyElement.cs
- XMLDiffLoader.cs
- ToolStripItem.cs
- CodeGen.cs
- SafeCancelMibChangeNotify.cs
- ExtensionDataReader.cs
- RuntimeWrappedException.cs
- _PooledStream.cs
- TimeSpanValidator.cs
- OutputCacheSettingsSection.cs
- Triplet.cs
- ClientSettingsProvider.cs
- Certificate.cs
- SolidColorBrush.cs
- IPAddressCollection.cs
- XmlSchemaAttributeGroupRef.cs
- Empty.cs
- PagedDataSource.cs
- Message.cs
- StringFunctions.cs
- DataControlPagerLinkButton.cs
- IDReferencePropertyAttribute.cs
- _SecureChannel.cs
- MetadataSource.cs
- EventProviderWriter.cs
- OrderedDictionaryStateHelper.cs
- XPathPatternParser.cs
- Pts.cs
- MultiSelectRootGridEntry.cs
- ThicknessAnimationUsingKeyFrames.cs
- ManagementScope.cs
- RegexTree.cs
- CookielessHelper.cs
- CellTreeNodeVisitors.cs
- NamedPipeConnectionPoolSettings.cs
- MimeWriter.cs
- TextRangeEditLists.cs
- DeobfuscatingStream.cs
- ArrayElementGridEntry.cs
- OdbcHandle.cs
- XmlSchemas.cs
- CodeDirectoryCompiler.cs
- Attributes.cs
- CompModSwitches.cs
- WebSysDescriptionAttribute.cs