66
77namespace AuthenticodeLint
88{
9- public abstract class SignatureBase : IDisposable
9+ public interface ICounterSignature
1010 {
11- internal CMSG_SIGNER_INFO _signerInfo ;
12-
13-
14- protected SignatureBase ( AsnEncodedData data )
11+ Oid Oid { get ; }
12+ Oid DigestAlgorithm { get ; }
13+ Oid HashEncryptionAlgorithm { get ; }
14+ CryptographicAttributeObjectCollection UnsignedAttributes { get ; }
15+ CryptographicAttributeObjectCollection SignedAttributes { get ; }
16+ }
17+ public abstract class CounterSignatureBase : ICounterSignature
18+ {
19+
20+ protected CounterSignatureBase ( AsnEncodedData data )
1521 {
16-
22+ Oid = data . Oid ;
1723 }
1824
19- public Oid DigestAlgorithm => new Oid ( _signerInfo . HashAlgorithm . pszObjId ) ;
20- public Oid HashEncryptionAlgorithm => new Oid ( _signerInfo . HashEncryptionAlgorithm . pszObjId ) ;
21-
22- public byte [ ] SerialNumber
23- {
24- get
25- {
26- var buffer = new byte [ _signerInfo . SerialNumber . cbData ] ;
27- Marshal . Copy ( _signerInfo . SerialNumber . pbData , buffer , 0 , buffer . Length ) ;
28- return buffer ;
29- }
30- }
25+ public Oid Oid { get ; }
3126
32- public void Dispose ( )
33- {
34- Dispose ( true ) ;
35- GC . SuppressFinalize ( this ) ;
36- }
27+ public abstract Oid DigestAlgorithm { get ; }
28+ public abstract Oid HashEncryptionAlgorithm { get ; }
29+ public abstract CryptographicAttributeObjectCollection UnsignedAttributes { get ; }
30+ public abstract CryptographicAttributeObjectCollection SignedAttributes { get ; }
31+ public abstract byte [ ] SerialNumber { get ; }
3732
38- public virtual void Dispose ( bool disposing )
33+ internal byte [ ] ReadBlob ( CRYPTOAPI_BLOB blob )
3934 {
35+ var buffer = new byte [ blob . cbData ] ;
36+ Marshal . Copy ( blob . pbData , buffer , 0 , buffer . Length ) ;
37+ return buffer ;
4038 }
4139
42- ~ SignatureBase ( )
40+ internal unsafe CryptographicAttributeObjectCollection ReadAttributes ( CRYPT_ATTRIBUTES attributes )
4341 {
44- Dispose ( false ) ;
42+ var collection = new CryptographicAttributeObjectCollection ( ) ;
43+ var attributeSize = Marshal . SizeOf < CRYPT_ATTRIBUTE > ( ) ;
44+ var blobSize = Marshal . SizeOf < CRYPTOAPI_BLOB > ( ) ;
45+ for ( var i = 0 ; i < attributes . cAttr ; i ++ )
46+ {
47+ var structure = Marshal . PtrToStructure < CRYPT_ATTRIBUTE > ( attributes . rgAttr + ( i * attributeSize ) ) ;
48+ var asnValues = new AsnEncodedDataCollection ( ) ;
49+ for ( var j = 0 ; j < structure . cValue ; j ++ )
50+ {
51+ var blob = Marshal . PtrToStructure < CRYPTOAPI_BLOB > ( structure . rgValue + j * blobSize ) ;
52+ asnValues . Add ( new AsnEncodedData ( structure . pszObjId , ReadBlob ( blob ) ) ) ;
53+ }
54+ collection . Add ( new CryptographicAttributeObject ( new Oid ( structure . pszObjId ) , asnValues ) ) ;
55+ }
56+ return collection ;
4557 }
4658 }
4759
48- public class AuthenticodeSignature : SignatureBase
60+ public class AuthenticodeSignature : CounterSignatureBase
4961 {
62+
63+ public override Oid DigestAlgorithm { get ; }
64+ public override Oid HashEncryptionAlgorithm { get ; }
65+ public override CryptographicAttributeObjectCollection UnsignedAttributes { get ; }
66+ public override CryptographicAttributeObjectCollection SignedAttributes { get ; }
67+ public override byte [ ] SerialNumber { get ; }
68+
5069 public unsafe AuthenticodeSignature ( AsnEncodedData data ) : base ( data )
5170 {
5271 fixed ( byte * dataPtr = data . RawData )
5372 {
54- LocalBufferSafeHandle ptr ;
5573 uint size = 0 ;
56- if ( Crypt32 . CryptDecodeObjectEx ( EncodingType . PKCS_7_ASN_ENCODING | EncodingType . X509_ASN_ENCODING , ( IntPtr ) 500 , new IntPtr ( dataPtr ) , ( uint ) data . RawData . Length , CryptDecodeFlags . CRYPT_DECODE_ALLOC_FLAG , IntPtr . Zero , out ptr , ref size ) )
74+ LocalBufferSafeHandle localBuffer ;
75+ if ( Crypt32 . CryptDecodeObjectEx ( EncodingType . PKCS_7_ASN_ENCODING | EncodingType . X509_ASN_ENCODING , ( IntPtr ) 500 , new IntPtr ( dataPtr ) , ( uint ) data . RawData . Length , CryptDecodeFlags . CRYPT_DECODE_ALLOC_FLAG , IntPtr . Zero , out localBuffer , ref size ) )
5776 {
58- using ( ptr )
77+ using ( localBuffer )
5978 {
60- _signerInfo = Marshal . PtrToStructure < CMSG_SIGNER_INFO > ( ptr . DangerousGetHandle ( ) ) ;
79+ var signerInfo = Marshal . PtrToStructure < CMSG_SIGNER_INFO > ( localBuffer . DangerousGetHandle ( ) ) ;
80+ DigestAlgorithm = new Oid ( signerInfo . HashAlgorithm . pszObjId ) ;
81+ HashEncryptionAlgorithm = new Oid ( signerInfo . HashEncryptionAlgorithm . pszObjId ) ;
82+ SerialNumber = ReadBlob ( signerInfo . SerialNumber ) ;
83+ UnsignedAttributes = ReadAttributes ( signerInfo . UnauthAttrs ) ;
84+ SignedAttributes = ReadAttributes ( signerInfo . AuthAttrs ) ;
6185 }
6286 }
6387 else
@@ -68,10 +92,14 @@ public unsafe AuthenticodeSignature(AsnEncodedData data) : base(data)
6892 }
6993 }
7094
71- public class Rfc3161Signature : SignatureBase
95+ public class Rfc3161Signature : CounterSignatureBase
7296 {
73- private readonly X509Store _certificates ;
74- private readonly CryptMsgSafeHandle _messageHandle ;
97+ public override Oid DigestAlgorithm { get ; }
98+ public override Oid HashEncryptionAlgorithm { get ; }
99+ public override CryptographicAttributeObjectCollection UnsignedAttributes { get ; }
100+ public override CryptographicAttributeObjectCollection SignedAttributes { get ; }
101+ public override byte [ ] SerialNumber { get ; }
102+ public X509Store Certificates { get ; }
75103
76104 public unsafe Rfc3161Signature ( AsnEncodedData data ) : base ( data )
77105 {
@@ -111,39 +139,36 @@ public unsafe Rfc3161Signature(AsnEncodedData data) : base(data)
111139 }
112140 try
113141 {
114- _certificates = new X509Store ( store . DangerousGetHandle ( ) ) ;
115- _messageHandle = msgHandle ;
142+ Certificates = new X509Store ( store . DangerousGetHandle ( ) ) ;
116143 var size = 0u ;
117- if ( ! Crypt32 . CryptMsgGetParam ( _messageHandle , CryptMsgParamType . CMSG_SIGNER_INFO_PARAM , 0 , LocalBufferSafeHandle . Zero , ref size ) )
144+ if ( ! Crypt32 . CryptMsgGetParam ( msgHandle , CryptMsgParamType . CMSG_SIGNER_INFO_PARAM , 0 , LocalBufferSafeHandle . Zero , ref size ) )
145+ {
146+ Certificates . Dispose ( ) ;
147+ throw new InvalidOperationException ( "Unable to read signer information." ) ;
148+ }
149+ var localBuffer = LocalBufferSafeHandle . Alloc ( size ) ;
150+ if ( ! Crypt32 . CryptMsgGetParam ( msgHandle , CryptMsgParamType . CMSG_SIGNER_INFO_PARAM , 0 , localBuffer , ref size ) )
118151 {
119- _messageHandle . Dispose ( ) ;
152+ Certificates . Dispose ( ) ;
153+ localBuffer . Dispose ( ) ;
120154 throw new InvalidOperationException ( "Unable to read signer information." ) ;
121155 }
122- using ( var localBuffer = LocalBufferSafeHandle . Alloc ( size ) )
156+ using ( localBuffer )
123157 {
124- if ( ! Crypt32 . CryptMsgGetParam ( _messageHandle , CryptMsgParamType . CMSG_SIGNER_INFO_PARAM , 0 , localBuffer , ref size ) )
125- {
126- _messageHandle . Dispose ( ) ;
127- throw new InvalidOperationException ( "Unable to read signer information." ) ;
128- }
129- _signerInfo = Marshal . PtrToStructure < CMSG_SIGNER_INFO > ( localBuffer . DangerousGetHandle ( ) ) ;
158+ var signerInfo = Marshal . PtrToStructure < CMSG_SIGNER_INFO > ( localBuffer . DangerousGetHandle ( ) ) ;
159+ DigestAlgorithm = new Oid ( signerInfo . HashAlgorithm . pszObjId ) ;
160+ HashEncryptionAlgorithm = new Oid ( signerInfo . HashEncryptionAlgorithm . pszObjId ) ;
161+ SerialNumber = ReadBlob ( signerInfo . SerialNumber ) ;
162+ UnsignedAttributes = ReadAttributes ( signerInfo . UnauthAttrs ) ;
163+ SignedAttributes = ReadAttributes ( signerInfo . AuthAttrs ) ;
130164 }
131165 }
132166 finally
133167 {
168+ msgHandle . Dispose ( ) ;
134169 store . Dispose ( ) ;
135170 }
136171 }
137172 }
138-
139-
140- public override void Dispose ( bool disposing )
141- {
142- if ( disposing )
143- {
144- _messageHandle . Dispose ( ) ;
145- _certificates . Dispose ( ) ;
146- }
147- }
148173 }
149174}
0 commit comments