Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Pkcs / PkcsMisc.cs / 5 / 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
- LogAppendAsyncResult.cs
- WrappedIUnknown.cs
- StreamSecurityUpgradeInitiatorAsyncResult.cs
- DateTimeFormatInfoScanner.cs
- Token.cs
- TransformConverter.cs
- DesignerOptions.cs
- GcSettings.cs
- SRGSCompiler.cs
- MinimizableAttributeTypeConverter.cs
- XmlSerializerAssemblyAttribute.cs
- DialogDivider.cs
- BitArray.cs
- FormViewModeEventArgs.cs
- WebPartConnectionsEventArgs.cs
- TdsParameterSetter.cs
- SqlDataSourceQuery.cs
- WebColorConverter.cs
- UIHelper.cs
- FakeModelItemImpl.cs
- MailBnfHelper.cs
- SQLInt16Storage.cs
- ChtmlFormAdapter.cs
- FileDialog_Vista.cs
- Currency.cs
- FixedTextSelectionProcessor.cs
- Polygon.cs
- ProfilePropertyMetadata.cs
- HttpProcessUtility.cs
- DataPointer.cs
- SourceItem.cs
- HtmlInputReset.cs
- Pen.cs
- StreamGeometry.cs
- UrlUtility.cs
- RoleServiceManager.cs
- InvalidOleVariantTypeException.cs
- Function.cs
- PasswordDeriveBytes.cs
- GridViewItemAutomationPeer.cs
- Menu.cs
- PagePropertiesChangingEventArgs.cs
- SchemaMapping.cs
- LogStore.cs
- GroupQuery.cs
- PointAnimationClockResource.cs
- EnvironmentPermission.cs
- BindingList.cs
- MultiByteCodec.cs
- BinaryFormatterWriter.cs
- ZipIOModeEnforcingStream.cs
- WeakReferenceKey.cs
- MgmtConfigurationRecord.cs
- TargetException.cs
- HotSpot.cs
- WindowsButton.cs
- CheckBoxFlatAdapter.cs
- DiagnosticTraceSource.cs
- ContentTypeSettingDispatchMessageFormatter.cs
- UserControl.cs
- HtmlMobileTextWriter.cs
- BuildProviderCollection.cs
- TemporaryBitmapFile.cs
- Material.cs
- Membership.cs
- GlyphsSerializer.cs
- COAUTHINFO.cs
- ClrProviderManifest.cs
- WebBrowser.cs
- XmlSchemaValidationException.cs
- COSERVERINFO.cs
- WinFormsSpinner.cs
- XmlDownloadManager.cs
- AnnotationHelper.cs
- PermissionToken.cs
- DashStyle.cs
- TimeManager.cs
- Command.cs
- UnmanagedMemoryStreamWrapper.cs
- DataRelation.cs
- DecoratedNameAttribute.cs
- TypedReference.cs
- FormatConvertedBitmap.cs
- ServiceBusyException.cs
- BaseDataList.cs
- IdentityNotMappedException.cs
- SemanticTag.cs
- OperatingSystem.cs
- OrderByExpression.cs
- BulletChrome.cs
- TreeView.cs
- StatusBarDrawItemEvent.cs
- XmlMapping.cs
- ServiceModelEnhancedConfigurationElementCollection.cs
- SynchronousChannelMergeEnumerator.cs
- PageSetupDialog.cs
- OrderByLifter.cs
- RepeaterItemCollection.cs
- BitmapSizeOptions.cs
- ConfigXmlText.cs