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
- SynchronousChannelMergeEnumerator.cs
- ToolStripMenuItem.cs
- MediaTimeline.cs
- Knowncolors.cs
- WizardPanel.cs
- SqlCommandBuilder.cs
- PngBitmapDecoder.cs
- FigureHelper.cs
- MethodExpr.cs
- UIElement3DAutomationPeer.cs
- IgnoreFileBuildProvider.cs
- LineBreak.cs
- TiffBitmapDecoder.cs
- InProcStateClientManager.cs
- MarkupExtensionReturnTypeAttribute.cs
- StartUpEventArgs.cs
- PathFigureCollection.cs
- PerformanceCounterPermissionEntry.cs
- LabelLiteral.cs
- ValidationRule.cs
- SqlNodeAnnotations.cs
- InheritablePropertyChangeInfo.cs
- Odbc32.cs
- GuidelineCollection.cs
- CharStorage.cs
- SortFieldComparer.cs
- ImageListStreamer.cs
- GridViewRowEventArgs.cs
- ExpressionEditor.cs
- SchemeSettingElementCollection.cs
- SecUtil.cs
- StretchValidation.cs
- CollectionContainer.cs
- ClientEventManager.cs
- DbProviderFactories.cs
- DataGridRow.cs
- StoreAnnotationsMap.cs
- RepeatButton.cs
- VersionedStream.cs
- FrameworkName.cs
- HtmlUtf8RawTextWriter.cs
- XmlSchemaSubstitutionGroup.cs
- SettingsProviderCollection.cs
- contentDescriptor.cs
- ViewBase.cs
- EdmConstants.cs
- NativeMethods.cs
- NumericUpDownAccelerationCollection.cs
- Evidence.cs
- DBCommand.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- InfiniteIntConverter.cs
- ImageListStreamer.cs
- TokenBasedSet.cs
- Timer.cs
- Label.cs
- WebZone.cs
- ExtensibleSyndicationObject.cs
- Point.cs
- WaveHeader.cs
- TraceSection.cs
- XmlEntity.cs
- EntityDataSourceViewSchema.cs
- CreateParams.cs
- RoutedCommand.cs
- CultureInfo.cs
- translator.cs
- DataColumnPropertyDescriptor.cs
- newitemfactory.cs
- VisualTreeUtils.cs
- BlockCollection.cs
- WinFormsUtils.cs
- FunctionGenerator.cs
- CaseInsensitiveOrdinalStringComparer.cs
- AddInStore.cs
- SemanticKeyElement.cs
- UrlRoutingModule.cs
- AmbientEnvironment.cs
- _AutoWebProxyScriptWrapper.cs
- CodeSnippetExpression.cs
- QueryReaderSettings.cs
- ParallelRangeManager.cs
- TouchEventArgs.cs
- FormsAuthenticationUser.cs
- ToolStripHighContrastRenderer.cs
- XmlnsDictionary.cs
- DataGridTable.cs
- ServerValidateEventArgs.cs
- StrokeNodeOperations.cs
- PolicyManager.cs
- DesignerProperties.cs
- Point3DCollection.cs
- XmlSerializerOperationFormatter.cs
- BrowserCapabilitiesFactory.cs
- RegionInfo.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- RegexFCD.cs
- ProcessStartInfo.cs
- PeerCollaboration.cs
- StringFunctions.cs