6
6
7
7
namespace AuthenticodeLint
8
8
{
9
- public abstract class SignatureBase : IDisposable
9
+ public interface ICounterSignature
10
10
{
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 )
15
21
{
16
-
22
+ Oid = data . Oid ;
17
23
}
18
24
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 ; }
31
26
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 ; }
37
32
38
- public virtual void Dispose ( bool disposing )
33
+ internal byte [ ] ReadBlob ( CRYPTOAPI_BLOB blob )
39
34
{
35
+ var buffer = new byte [ blob . cbData ] ;
36
+ Marshal . Copy ( blob . pbData , buffer , 0 , buffer . Length ) ;
37
+ return buffer ;
40
38
}
41
39
42
- ~ SignatureBase ( )
40
+ internal unsafe CryptographicAttributeObjectCollection ReadAttributes ( CRYPT_ATTRIBUTES attributes )
43
41
{
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 ;
45
57
}
46
58
}
47
59
48
- public class AuthenticodeSignature : SignatureBase
60
+ public class AuthenticodeSignature : CounterSignatureBase
49
61
{
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
+
50
69
public unsafe AuthenticodeSignature ( AsnEncodedData data ) : base ( data )
51
70
{
52
71
fixed ( byte * dataPtr = data . RawData )
53
72
{
54
- LocalBufferSafeHandle ptr ;
55
73
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 ) )
57
76
{
58
- using ( ptr )
77
+ using ( localBuffer )
59
78
{
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 ) ;
61
85
}
62
86
}
63
87
else
@@ -68,10 +92,14 @@ public unsafe AuthenticodeSignature(AsnEncodedData data) : base(data)
68
92
}
69
93
}
70
94
71
- public class Rfc3161Signature : SignatureBase
95
+ public class Rfc3161Signature : CounterSignatureBase
72
96
{
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 ; }
75
103
76
104
public unsafe Rfc3161Signature ( AsnEncodedData data ) : base ( data )
77
105
{
@@ -111,39 +139,36 @@ public unsafe Rfc3161Signature(AsnEncodedData data) : base(data)
111
139
}
112
140
try
113
141
{
114
- _certificates = new X509Store ( store . DangerousGetHandle ( ) ) ;
115
- _messageHandle = msgHandle ;
142
+ Certificates = new X509Store ( store . DangerousGetHandle ( ) ) ;
116
143
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 ) )
118
151
{
119
- _messageHandle . Dispose ( ) ;
152
+ Certificates . Dispose ( ) ;
153
+ localBuffer . Dispose ( ) ;
120
154
throw new InvalidOperationException ( "Unable to read signer information." ) ;
121
155
}
122
- using ( var localBuffer = LocalBufferSafeHandle . Alloc ( size ) )
156
+ using ( localBuffer )
123
157
{
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 ) ;
130
164
}
131
165
}
132
166
finally
133
167
{
168
+ msgHandle . Dispose ( ) ;
134
169
store . Dispose ( ) ;
135
170
}
136
171
}
137
172
}
138
-
139
-
140
- public override void Dispose ( bool disposing )
141
- {
142
- if ( disposing )
143
- {
144
- _messageHandle . Dispose ( ) ;
145
- _certificates . Dispose ( ) ;
146
- }
147
- }
148
173
}
149
174
}
0 commit comments