Click here to Skip to main content
15,891,943 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I need to get data from crl file: Valid from 02.11.2012, Next update 02.01.2013. How to get this information from crl file?

Here is some class WinCrypt32
C#
public static class WinCrypt32
        {
            #region APIs

            [DllImport("CRYPT32.DLL", EntryPoint = "CryptQueryObject", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern Boolean CryptQueryObject(
                Int32 dwObjectType,
                IntPtr pvObject,
                Int32 dwExpectedContentTypeFlags,
                Int32 dwExpectedFormatTypeFlags,
                Int32 dwFlags,
                IntPtr pdwMsgAndCertEncodingType,
                IntPtr pdwContentType,
                IntPtr pdwFormatType,
                ref IntPtr phCertStore,
                IntPtr phMsg,
                ref IntPtr ppvContext
                );

            [DllImport("CRYPT32.DLL", EntryPoint = "CertFreeCRLContext", SetLastError = true)]
            public static extern Boolean CertFreeCRLContext(
                IntPtr pCrlContext
            );

            [DllImport("CRYPT32.DLL", EntryPoint = "CertNameToStr", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern Int32 CertNameToStr(
                Int32 dwCertEncodingType,
                ref CRYPTOAPI_BLOB pName,
                Int32 dwStrType,
                StringBuilder psz,
                Int32 csz
            );

            [DllImport("CRYPT32.DLL", EntryPoint = "CertFindExtension", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr CertFindExtension(
                [MarshalAs(UnmanagedType.LPStr)]String pszObjId,
                Int32 cExtensions,
                IntPtr rgExtensions
            );

            [DllImport("CRYPT32.DLL", EntryPoint = "CryptFormatObject", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern Boolean CryptFormatObject(
                Int32 dwCertEncodingType,
                Int32 dwFormatType,
                Int32 dwFormatStrType,
                IntPtr pFormatStruct,
                [MarshalAs(UnmanagedType.LPStr)]String lpszStructType,
                IntPtr pbEncoded,
                Int32 cbEncoded,
                StringBuilder pbFormat,
                ref Int32 pcbFormat
            );

            #endregion APIs

            #region Structs
            [StructLayout(LayoutKind.Sequential)]
            public struct CRYPT_OBJID_BLOB
            {
                public uint cbData;
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
                public byte[] pbData;
            }

            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            public struct CERT_PUBLIC_KEY_INFO
            {
                public CRYPT_ALGORITHM_IDENTIFIER Algorithm;
                public CRYPTOAPI_BLOB PublicKey;
            }

            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct CERT_EXTENSION
            {
                [MarshalAs(UnmanagedType.LPStr)]
                public string pszObjId;
                public bool fCritical;
                public CRYPTOAPI_BLOB Value;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CERT_CONTEXT
            {
                public uint dwCertEncodingType;
                public IntPtr pbCertEncoded;
                public uint cbCertEncoded;
                public IntPtr pCertInfo;
                public IntPtr hCertStore;
            }

            public struct CERT_INFO
            {
                public int dwVersion;
                public CRYPTOAPI_BLOB SerialNumber;
                public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
                public CRYPTOAPI_BLOB Issuer;
                public FILETIME NotBefore;
                public FILETIME NotAfter;
                public CRYPTOAPI_BLOB Subject;
                public CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
                public CRYPTOAPI_BLOB IssuerUniqueId;
                public CRYPTOAPI_BLOB SubjectUniqueId;
                public int cExtension;
                public CERT_EXTENSION rgExtension;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CRL_CONTEXT
            {
                public Int32 dwCertEncodingType;
                public IntPtr pbCrlEncoded;
                public Int32 cbCrlEncoded;
                public IntPtr pCrlInfo;
                public IntPtr hCertStore;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CRL_INFO
            {
                public Int32 dwVersion;
                public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
                public CRYPTOAPI_BLOB Issuer;
                public FILETIME ThisUpdate;
                public FILETIME NextUpdate;
                public Int32 cCRLEntry;
                public IntPtr rgCRLEntry;
                public Int32 cExtension;
                public IntPtr rgExtension;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CRYPT_ALGORITHM_IDENTIFIER
            {
                [MarshalAs(UnmanagedType.LPStr)]
                public String pszObjId;
                public CRYPTOAPI_BLOB Parameters;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CRYPTOAPI_BLOB
            {
                public Int32 cbData;
                public IntPtr pbData;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct FILETIME
            {
                public Int32 dwLowDateTime;
                public Int32 dwHighDateTime;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct CRL_ENTRY
            {
                public CRYPTOAPI_BLOB SerialNumber;
                public FILETIME RevocationDate;
                public Int32 cExtension;
                public IntPtr rgExtension;
            }

            #endregion Structs

            #region Consts

            public const Int32 CERT_QUERY_OBJECT_FILE = 0x00000001;
            public const Int32 CERT_QUERY_OBJECT_BLOB = 0x00000002;
            public const Int32 CERT_QUERY_CONTENT_CRL = 3;
            public const Int32 CERT_QUERY_CONTENT_FLAG_CRL = 1 << CERT_QUERY_CONTENT_CRL;
            public const Int32 CERT_QUERY_FORMAT_BINARY = 1;
            public const Int32 CERT_QUERY_FORMAT_BASE64_ENCODED = 2;
            public const Int32 CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED = 3;
            public const Int32 CERT_QUERY_FORMAT_FLAG_BINARY = 1 << CERT_QUERY_FORMAT_BINARY;
            public const Int32 CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED = 1 << CERT_QUERY_FORMAT_BASE64_ENCODED;
            public const Int32 CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED = 1 << CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED;
            public const Int32 CERT_QUERY_FORMAT_FLAG_ALL = CERT_QUERY_FORMAT_FLAG_BINARY | CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED | CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED;

            public const Int32 X509_ASN_ENCODING = 0x00000001;
            public const Int32 PKCS_7_ASN_ENCODING = 0x00010000;

            public const Int32 X509_NAME = 7;

            public const Int32 CERT_SIMPLE_NAME_STR = 1;
            public const Int32 CERT_OID_NAME_STR = 2;
            public const Int32 CERT_X500_NAME_STR = 3;

            public const String szOID_CRL_REASON_CODE = "2.5.29.21";

            public enum Disposition : uint
            {
                CERT_STORE_ADD_NEW = 1,
                CERT_STORE_ADD_USE_EXISTING = 2,
                CERT_STORE_ADD_REPLACE_EXISTING = 3,
                CERT_STORE_ADD_ALWAYS = 4,
                CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES = 5,
                CERT_STORE_ADD_NEWER = 6,
                CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES = 7,
            }

            [Flags]
            public enum FindFlags : int
            {
                CRL_FIND_ISSUED_BY_AKI_FLAG = 0x1,
                CRL_FIND_ISSUED_BY_SIGNATURE_FLAG = 0x2,
                CRL_FIND_ISSUED_BY_DELTA_FLAG = 0x4,
                CRL_FIND_ISSUED_BY_BASE_FLAG = 0x8,
            }

            public enum FindType : int
            {
                CRL_FIND_ANY = 0,
                CRL_FIND_ISSUED_BY = 1,
                CRL_FIND_EXISTING = 2,
                CRL_FIND_ISSUED_FOR = 3
            }

            #endregion
        }


Sohow it can help me?
Posted
Comments
quwenchao 4-Jul-13 19:30pm    
I want to get Email Address from PE files too.

This topic is a bit old but I created a simple project to read from CRL file. The actual logic to read isn't mine but I'ved made it easy to expose the important property of the CRL.

janmchan/CrlCsReader · GitHub[^]
 
Share this answer
 
Comments
sagardiscovery 18-Dec-16 2:00am    
Thanks a lot. Your project helped me a lot.
You can use CryptQueryObject to get an object of type CRL_CONTEXT. This has pCrlInfo member (CRL_INFO structure), which contains the info you are looking for.

However, you may find it easier to use CertCreateCRLContext API. But you need to add it in the above WinCrypt32 class.

See MSDN for details on these two API.
 
Share this answer
 
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Cryptography.Pkcs;

namespace MyNamespace.Win32
{
static class WinCrypt
{
[StructLayout(LayoutKind.Sequential)]
public struct BLOB
{
public int cbData;
public IntPtr pbData;
}

[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ALGORITHM_IDENTIFIER
{
public String pszObjId;
BLOB Parameters;
}

[StructLayout(LayoutKind.Sequential)]
public struct CERT_ID
{
public int dwIdChoice;
public BLOB IssuerSerialNumberOrKeyIdOrHashId;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SIGNER_SUBJECT_INFO
{
/// DWORD->unsigned int
public uint cbSize;

/// DWORD*
public System.IntPtr pdwIndex;

/// DWORD->unsigned int
public uint dwSubjectChoice;

/// SubjectChoiceUnion
public SubjectChoiceUnion Union1;
}

[StructLayoutAttribute(LayoutKind.Explicit)]
public struct SubjectChoiceUnion
{

/// SIGNER_FILE_INFO*
[FieldOffsetAttribute(0)]
public System.IntPtr pSignerFileInfo;

/// SIGNER_BLOB_INFO*
[FieldOffsetAttribute(0)]
public System.IntPtr pSignerBlobInfo;
}

[StructLayout(LayoutKind.Sequential)]
public struct CERT_NAME_BLOB
{
public uint cbData;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
public byte[] pbData;
}

[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_INTEGER_BLOB
{
public UInt32 cbData;
public IntPtr pbData;
}

[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ATTR_BLOB
{
public uint cbData;
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
public byte[] pbData;
}

[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ATTRIBUTE
{
[MarshalAs(UnmanagedType.LPStr)]
public string pszObjId;
public uint cValue;
[MarshalAs(UnmanagedType.LPStruct)]
public CRYPT_ATTR_BLOB rgValue;
}

[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNER_INFO
{
public int dwVersion;
private CERT_NAME_BLOB Issuer;
CRYPT_INTEGER_BLOB SerialNumber;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
BLOB EncryptedHash;
CRYPT_ATTRIBUTE[] AuthAttrs;
CRYPT_ATTRIBUTE[] UnauthAttrs;
}

[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CryptQueryObject(
int dwObjectType,
IntPtr pvObject,
int dwExpectedContentTypeFlags,
int dwExpectedFormatTypeFlags,
int dwFlags,
out int pdwMsgAndCertEncodingType,
out int pdwContentType,
out int pdwFormatType,
ref IntPtr phCertStore,
ref IntPtr phMsg,
ref IntPtr ppvContext);


[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CryptMsgGetParam(
IntPtr hCryptMsg,
int dwParamType,
int dwIndex,
IntPtr pvData,
ref int pcbData
);

[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CryptMsgGetParam(
IntPtr hCryptMsg,
int dwParamType,
int dwIndex,
[In, Out] byte[] vData,
ref int pcbData
);

[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecodeObject(
uint CertEncodingType,
UIntPtr lpszStructType,
byte[] pbEncoded,
uint cbEncoded,
uint flags,
[In, Out] byte[] pvStructInfo,
ref uint cbStructInfo);


public const int CRYPT_ASN_ENCODING = 0x00000001;
public const int CRYPT_NDR_ENCODING = 0x00000002;
public const int X509_ASN_ENCODING = 0x00000001;
public const int X509_NDR_ENCODING = 0x00000002;
public const int PKCS_7_ASN_ENCODING = 0x00010000;
public const int PKCS_7_NDR_ENCODING = 0x00020000;

public static UIntPtr PKCS7_SIGNER_INFO = new UIntPtr(500);
public static UIntPtr CMS_SIGNER_INFO = new UIntPtr(501);

public static string szOID_RSA_signingTime = "1.2.840.113549.1.9.5";
public static string szOID_RSA_counterSign = "1.2.840.113549.1.9.6";

//+-------------------------------------------------------------------------
// Get parameter types and their corresponding data structure definitions.
//--------------------------------------------------------------------------
public const int CMSG_TYPE_PARAM = 1;
public const int CMSG_CONTENT_PARAM = 2;
public const int CMSG_BARE_CONTENT_PARAM = 3;
public const int CMSG_INNER_CONTENT_TYPE_PARAM = 4;
public const int CMSG_SIGNER_COUNT_PARAM = 5;
public const int CMSG_SIGNER_INFO_PARAM = 6;
public const int CMSG_SIGNER_CERT_INFO_PARAM = 7;
public const int CMSG_SIGNER_HASH_ALGORITHM_PARAM = 8;
public const int CMSG_SIGNER_AUTH_ATTR_PARAM = 9;
public const int CMSG_SIGNER_UNAUTH_ATTR_PARAM = 10;
public const int CMSG_CERT_COUNT_PARAM = 11;
public const int CMSG_CERT_PARAM = 12;
public const int CMSG_CRL_COUNT_PARAM = 13;
public const int CMSG_CRL_PARAM = 14;
public const int CMSG_ENVELOPE_ALGORITHM_PARAM = 15;
public const int CMSG_RECIPIENT_COUNT_PARAM = 17;
public const int CMSG_RECIPIENT_INDEX_PARAM = 18;
public const int CMSG_RECIPIENT_INFO_PARAM = 19;
public const int CMSG_HASH_ALGORITHM_PARAM = 20;
public const int CMSG_HASH_DATA_PARAM = 21;
public const int CMSG_COMPUTED_HASH_PARAM = 22;
public const int CMSG_ENCRYPT_PARAM = 26;
public const int CMSG_ENCRYPTED_DIGEST = 27;
public const int CMSG_ENCODED_SIGNER = 28;
public const int CMSG_ENCODED_MESSAGE = 29;
public const int CMSG_VERSION_PARAM = 30;
public const int CMSG_ATTR_CERT_COUNT_PARAM = 31;
public const int CMSG_ATTR_CERT_PARAM = 32;
public const int CMSG_CMS_RECIPIENT_COUNT_PARAM = 33;
public const int CMSG_CMS_RECIPIENT_INDEX_PARAM = 34;
public const int CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM = 35;
public const int CMSG_CMS_RECIPIENT_INFO_PARAM = 36;
public const int CMSG_UNPROTECTED_ATTR_PARAM = 37;
public const int CMSG_SIGNER_CERT_ID_PARAM = 38;
public const int CMSG_CMS_SIGNER_INFO_PARAM = 39;


//-------------------------------------------------------------------------
//dwObjectType for CryptQueryObject
//-------------------------------------------------------------------------
public const int CERT_QUERY_OBJECT_FILE = 0x00000001;
public const int CERT_QUERY_OBJECT_BLOB = 0x00000002;

//-------------------------------------------------------------------------
//dwContentType for CryptQueryObject
//-------------------------------------------------------------------------
//encoded single certificate
public const int CERT_QUERY_CONTENT_CERT = 1;
//encoded single CTL
public const int CERT_QUERY_CONTENT_CTL = 2;
//encoded single CRL
public const int CERT_QUERY_CONTENT_CRL = 3;
//serialized store
public const int CERT_QUERY_CONTENT_SERIALIZED_STORE = 4;
//serialized single certificate
public const int CERT_QUERY_CONTENT_SERIALIZED_CERT = 5;
//serialized single CTL
public const int CERT_QUERY_CONTENT_SERIALIZED_CTL = 6;
//serialized single CRL
public const int CERT_QUERY_CONTENT_SERIALIZED_CRL = 7;
//a PKCS#7 signed message
public const int CERT_QUERY_CONTENT_PKCS7_SIGNED = 8;
//a PKCS#7 message, such as enveloped message. But it is not a signed message,
public const int CERT_QUERY_CONTENT_PKCS7_UNSIGNED = 9;
//a PKCS7 signed message embedded in a file
public const int CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED = 10;
//an encoded PKCS#10
public const int CERT_QUERY_CONTENT_PKCS10 = 11;
//an encoded PKX BLOB
public const int CERT_QUERY_CONTENT_PFX = 12;
//an encoded CertificatePair (contains forward and/or reverse cross certs)
public const int CERT_QUERY_CONTENT_CERT_PAIR = 13;

//-------------------------------------------------------------------------
//dwExpectedConentTypeFlags for CryptQueryObject
//-------------------------------------------------------------------------
//encoded single certificate
public const int CERT_QUERY_CONTENT_FLAG_CERT = (1 << CERT_QUERY_CONTENT_CERT);

//encoded single CTL
public const int CERT_QUERY_CONTENT_FLAG_CTL = (1 << CERT_QUERY_CONTENT_CTL);

//encoded single CRL
public const int CERT_QUERY_CONTENT_FLAG_CRL = (1 << CERT_QUERY_CONTENT_CRL);

//serialized store
public const int CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE = (1 << CERT_QUERY_CONTENT_SERIALIZED_STORE);

//serialized single certificate
public const int CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT = (1 << CERT_QUERY_CONTENT_SERIALIZED_CERT);

//serialized single CTL
public const int CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL = (1 << CERT_QUERY_CONTENT_SERIALIZED_CTL);

//serialized single CRL
public const int CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL = (1 << CERT_QUERY_CONTENT_SERIALIZED_CRL);

//an encoded PKCS#7 signed message
public const int CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED);

//an encoded PKCS#7 message. But it is not a signed message
public const int CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED = (1 << CERT_QUERY_CONTENT_PKCS7_UNSIGNED);

//the content includes an embedded PKCS7 signed message
public const int CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = (1 << CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED);

//an encoded PKCS#10
public const int CERT_QUERY_CONTENT_FLAG_PKCS10 = (1 << CERT_QUERY_CONTENT_PKCS10);

//an encoded PFX BLOB
public const int CERT_QUERY_CONTENT_FLAG_PFX = (1 << CERT_QUERY_CONTENT_PFX);

//an encoded CertificatePair (contains forward and/or reverse cross certs)
public const int CERT_QUERY_CONTENT_FLAG_CERT_PAIR = (1 << CERT_QUERY_CONTENT_CERT_PAIR);

//content can be any type
public const int CERT_QUERY_CONTENT_FLAG_ALL =
CERT_QUERY_CONTENT_FLAG_CERT |
CERT_QUERY_CONTENT_FLAG_CTL |
CERT_QUERY_CONTENT_FLAG_CRL |
CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT |
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL |
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL |
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED |
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED |
CERT_QUERY_CONTENT_FLAG_PKCS10 |
CERT_QUERY_CONTENT_FLAG_PFX |
CERT_QUERY_CONTENT_FLAG_CERT_PAIR;

//-------------------------------------------------------------------------
//dwFormatType for CryptQueryObject
//-------------------------------------------------------------------------
//the content is in binary format
public const int CERT_QUERY_FORMAT_BINARY = 1;

//the content is base64 encoded
public const int CERT_QUERY_FORMAT_BASE64_ENCODED = 2;

//the content is ascii hex encoded with "{ASN}" prefix
public const int CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED = 3;

//-------------------------------------------------------------------------
//dwExpectedFormatTypeFlags for CryptQueryObject
//-------------------------------------------------------------------------
//the content is in binary format
public const int CERT_QUERY_FORMAT_FLAG_BINARY = (1 << CERT_QUERY_FORMAT_BINARY);

//the content is base64 encoded
public const int CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED = (1 << CERT_QUERY_FORMAT_BASE64_ENCODED);

//the content is ascii hex encoded with "{ASN}" prefix
public const int CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED = (1 << CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED);

//the content can be of any format
public const int CERT_QUERY_FORMAT_FLAG_ALL =
CERT_QUERY_FORMAT_FLAG_BINARY |
CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED |
CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED;

public static void Main()
{
string filename = @"C:\Users\QU\Desktop\QPGF.dll";
IsTimestamped(filename);
Console.ReadLine();
}

public static bool IsTimestamped(string filename)
{
try
{
int encodingType;
int contentType;
int formatType;
IntPtr certStore = IntPtr.Zero;
IntPtr cryptMsg = IntPtr.Zero;
IntPtr context = IntPtr.Zero;

if (!WinCrypt.CryptQueryObject(
WinCrypt.CERT_QUERY_OBJECT_FILE,
Marshal.StringToHGlobalUni(filename),
WinCrypt.CERT_QUERY_CONTENT_FLAG_ALL,
WinCrypt.CERT_QUERY_FORMAT_FLAG_ALL,
0,
out encodingType,
out contentType,
out formatType,
ref certStore,
ref cryptMsg,
ref context))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
// Get size of the encoded message.
int cbData = 0;
if (!WinCrypt.CryptMsgGetParam(
cryptMsg,
WinCrypt.CMSG_SIGNER_INFO_PARAM,//Crypt32.CMSG_SIGNER_INFO_PARAM,
0,
IntPtr.Zero,
ref cbData))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

var vData = new byte[cbData];

// Get the encoded message.
if (!WinCrypt.CryptMsgGetParam(
cryptMsg,
WinCrypt.CMSG_SIGNER_INFO_PARAM,
0,
vData,
ref cbData))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

var signedCms = new SignedCms();
signedCms.Decode(vData);
foreach (var signerInfo in signedCms.SignerInfos)
{
foreach (var unsignedAttribute in signerInfo.UnsignedAttributes)
{
if (unsignedAttribute.Oid.Value == WinCrypt.szOID_RSA_counterSign)
{
foreach (var counterSignInfo in signerInfo.CounterSignerInfos)
{
foreach (var signedAttribute in counterSignInfo.SignedAttributes)
{
if (signedAttribute.Oid.Value == WinCrypt.szOID_RSA_counterSign)
{
System.Runtime.InteropServices.ComTypes.FILETIME fileTime = new System.Runtime.InteropServices.ComTypes.FILETIME();
int fileTimeSize = Marshal.SizeOf(fileTime);
IntPtr fileTimePtr = Marshal.AllocCoTaskMem(fileTimeSize);
Marshal.StructureToPtr(fileTime, fileTimePtr, true);
byte[] buffdata = new byte[fileTimeSize];
Marshal.Copy(fileTimePtr, buffdata, 0, fileTimeSize);
uint buffSize = (uint)buffdata.Length;
uint encoding = WinCrypt.X509_ASN_ENCODING | WinCrypt.PKCS_7_ASN_ENCODING;
UIntPtr rsaSigningTime = (UIntPtr)(uint)Marshal.StringToHGlobalAnsi(WinCrypt.szOID_RSA_counterSign);
byte[] pbData = signedAttribute.Values[0].RawData;
uint ucbData = (uint)pbData.Length;
bool workie = WinCrypt.CryptDecodeObject(encoding, rsaSigningTime, pbData, ucbData, 0, buffdata, ref buffSize);
if (workie)
{
IntPtr fileTimePtr2 = Marshal.AllocCoTaskMem(buffdata.Length);
Marshal.Copy(buffdata, 0, fileTimePtr2, buffdata.Length);
System.Runtime.InteropServices.ComTypes.FILETIME fileTime2 = (System.Runtime.InteropServices.ComTypes.FILETIME)Marshal.PtrToStructure(fileTimePtr2, typeof(System.Runtime.InteropServices.ComTypes.FILETIME));
long hFT2 = (((long)fileTime2.dwHighDateTime) << 32) + ((uint)fileTime2.dwLowDateTime);
DateTime dte = DateTime.FromFileTime(hFT2);
Console.WriteLine(dte.ToString());
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}

}
}

}

return true;
}

}
}
}
catch (Exception)
{
// no logging
}
return false;
}
}
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900