@@ -99,12 +99,60 @@ export async function sha256Hash(buffer: Uint8Array): Promise<string> {
99
99
export async function verifyCertificateSignature ( certificate : string , publicKey : CryptoKey ) : Promise < boolean > {
100
100
let cert = new x509 . X509Certificate ( certificate )
101
101
102
- const verificationResult = await self . crypto . subtle . verify (
103
- cert . signatureAlgorithm ,
104
- publicKey ,
105
- cert . signature ,
106
- new Uint8Array ( cert . tbs ) ,
102
+ return cert . verify ( { publicKey } , getPatchedCrypto ( ) )
103
+ }
104
+
105
+ export async function verifyCMSSignature ( signedData : Uint8Array , cmsBuffer : Uint8Array , users : { userId : string , certificate : string } [ ] ) : Promise < boolean > {
106
+ // Parse the CMS buffer
107
+ const cmsContent = ContentInfo . fromBER ( cmsBuffer )
108
+ const originalSignedData = new SignedData ( { schema : cmsContent . content } ) ;
109
+
110
+ // Get the signer certificate from the users array
111
+ const commonNameOID = '2.5.4.3'
112
+ const signerInfo = originalSignedData . signerInfos [ 0 ]
113
+ const signerUserId = signerInfo . sid . issuer . typesAndValues . find ( ( { type} ) => type === commonNameOID ) . value . valueBlock . value
114
+ const signer = users . find ( ( { userId} ) => userId === signerUserId )
115
+ if ( signer === undefined ) {
116
+ throw new Error ( 'Signer not found in the users array' )
117
+ }
118
+
119
+ const asn1Cert = fromBER ( pemToBuffer ( signer . certificate ) )
120
+ const certificate = new Certificate ( { schema : asn1Cert . result } )
121
+
122
+ const verificationResult = await originalSignedData . verify (
123
+ {
124
+ signer : 0 ,
125
+ trustedCerts : [ certificate ] ,
126
+ data : signedData as unknown as ArrayBuffer ,
127
+ checkChain : true ,
128
+ } ,
129
+ getPatchedCryptoEngine ( )
107
130
)
108
131
109
132
return verificationResult
133
+
110
134
}
135
+
136
+ class CustomCryptoEngine extends pkijs . CryptoEngine {
137
+ verify ( algorithm : globalThis . AlgorithmIdentifier | RsaPssParams | EcdsaParams , key : CryptoKey , signature : BufferSource , data : ArrayBuffer ) : Promise < boolean > {
138
+ return super . verify ( algorithm , key , signature , new Uint8Array ( data ) )
139
+ }
140
+ }
141
+
142
+ // Return a patched crypto engine because pkijs' default engine does not give the correct data type to the subtle.verify method
143
+ function getPatchedCryptoEngine ( ) {
144
+ return new CustomCryptoEngine ( { crypto : self . crypto } )
145
+ }
146
+
147
+ // Return a patched crypto because x509's default does not give the correct data type to the subtle.verify method
148
+ function getPatchedCrypto ( ) : Crypto {
149
+ return {
150
+ ...self . crypto ,
151
+ subtle : {
152
+ ...self . crypto . subtle ,
153
+ async verify ( algorithm : globalThis . AlgorithmIdentifier | RsaPssParams | EcdsaParams , key : CryptoKey , signature : ArrayBuffer , data : ArrayBuffer ) : Promise < boolean > {
154
+ return self . crypto . subtle . verify ( algorithm , key , new Uint8Array ( signature ) , new Uint8Array ( data ) )
155
+ }
156
+ } ,
157
+ }
158
+ }
0 commit comments