@@ -14,7 +14,7 @@ import {
1414import {
1515 DiagnosticInformation ,
1616} from './model/types' ;
17- import { UserDefinedVerificationCallback , VerificationAssessment , buildCallback , onCatCheck } from './checkCallback' ;
17+ import { UserDefinedVerificationCallback , VerificationAssessment , VerificationAssessmentId , buildCallback , onCatCheck } from './checkCallback' ;
1818
1919import { parse } from './parser' ;
2020import IssuerAuth from './model/IssuerAuth' ;
@@ -54,11 +54,13 @@ export class Verifier {
5454 onCheck ( {
5555 status : 'PASSED' ,
5656 check : 'Issuer certificate must be valid' ,
57+ id : VerificationAssessmentId . ISSUER_AUTH . IssuerCertificateValidity ,
5758 } ) ;
5859 } catch ( err ) {
5960 onCheck ( {
6061 status : 'FAILED' ,
6162 check : 'Issuer certificate must be valid' ,
63+ id : VerificationAssessmentId . ISSUER_AUTH . IssuerCertificateValidity ,
6264 reason : err . message ,
6365 } ) ;
6466 }
@@ -68,6 +70,7 @@ export class Verifier {
6870 onCheck ( {
6971 status : verificationResult ? 'PASSED' : 'FAILED' ,
7072 check : 'Issuer signature must be valid' ,
73+ id : VerificationAssessmentId . ISSUER_AUTH . IssuerSignatureValidity ,
7174 } ) ;
7275
7376 // Validity
@@ -77,18 +80,21 @@ export class Verifier {
7780 onCheck ( {
7881 status : certificate && validityInfo && ( validityInfo . signed < certificate . notBefore || validityInfo . signed > certificate . notAfter ) ? 'FAILED' : 'PASSED' ,
7982 check : 'The MSO signed date must be within the validity period of the certificate' ,
83+ id : VerificationAssessmentId . ISSUER_AUTH . MsoSignedDateWithinCertificateValidity ,
8084 reason : `The MSO signed date (${ validityInfo . signed . toUTCString ( ) } ) must be within the validity period of the certificate (${ certificate . notBefore . toUTCString ( ) } to ${ certificate . notAfter . toUTCString ( ) } )` ,
8185 } ) ;
8286
8387 onCheck ( {
8488 status : validityInfo && ( now < validityInfo . validFrom || now > validityInfo . validUntil ) ? 'FAILED' : 'PASSED' ,
8589 check : 'The MSO must be valid at the time of verification' ,
90+ id : VerificationAssessmentId . ISSUER_AUTH . MsoValidityAtVerificationTime ,
8691 reason : `The MSO must be valid at the time of verification (${ now . toUTCString ( ) } )` ,
8792 } ) ;
8893
8994 onCheck ( {
9095 status : countryName ? 'PASSED' : 'FAILED' ,
9196 check : 'Country name (C) must be present in the issuer certificate\'s subject distinguished name' ,
97+ id : VerificationAssessmentId . ISSUER_AUTH . IssuerSubjectCountryNamePresence ,
9298 } ) ;
9399 }
94100
@@ -106,6 +112,7 @@ export class Verifier {
106112 onCheck ( {
107113 status : 'FAILED' ,
108114 check : 'The document is not signed by the device.' ,
115+ id : VerificationAssessmentId . DEVICE_AUTH . DocumentDeviceSignaturePresence ,
109116 } ) ;
110117 return ;
111118 }
@@ -119,6 +126,7 @@ export class Verifier {
119126 onCheck ( {
120127 status : 'FAILED' ,
121128 check : 'Device Auth must contain a deviceSignature or deviceMac element' ,
129+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceAuthSignatureOrMacPresence ,
122130 } ) ;
123131 return ;
124132 }
@@ -127,6 +135,7 @@ export class Verifier {
127135 onCheck ( {
128136 status : 'FAILED' ,
129137 check : 'Session Transcript Bytes missing from options, aborting device signature check' ,
138+ id : VerificationAssessmentId . DEVICE_AUTH . SessionTranscriptProvided ,
130139 } ) ;
131140 return ;
132141 }
@@ -141,6 +150,7 @@ export class Verifier {
141150 onCheck ( {
142151 status : 'FAILED' ,
143152 check : 'Issuer signature must contain the device key.' ,
153+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceKeyAvailableInIssuerAuth ,
144154 reason : 'Unable to verify deviceAuth signature: missing device key in issuerAuth' ,
145155 } ) ;
146156 return ;
@@ -163,11 +173,13 @@ export class Verifier {
163173 onCheck ( {
164174 status : verificationResult ? 'PASSED' : 'FAILED' ,
165175 check : 'Device signature must be valid' ,
176+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceSignatureValidity ,
166177 } ) ;
167178 } catch ( err ) {
168179 onCheck ( {
169180 status : 'FAILED' ,
170181 check : 'Device signature must be valid' ,
182+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceSignatureValidity ,
171183 reason : `Unable to verify deviceAuth signature (ECDSA/EdDSA): ${ err . message } ` ,
172184 } ) ;
173185 }
@@ -178,18 +190,21 @@ export class Verifier {
178190 onCheck ( {
179191 status : deviceAuth . deviceMac ? 'PASSED' : 'FAILED' ,
180192 check : 'Device MAC must be present when using MAC authentication' ,
193+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceMacPresence ,
181194 } ) ;
182195 if ( ! deviceAuth . deviceMac ) { return ; }
183196
184197 onCheck ( {
185198 status : deviceAuth . deviceMac . hasSupportedAlg ( ) ? 'PASSED' : 'FAILED' ,
186199 check : 'Device MAC must use alg 5 (HMAC 256/256)' ,
200+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceMacAlgorithmCorrectness ,
187201 } ) ;
188202 if ( ! deviceAuth . deviceMac . hasSupportedAlg ( ) ) { return ; }
189203
190204 onCheck ( {
191205 status : options . ephemeralPrivateKey ? 'PASSED' : 'FAILED' ,
192206 check : 'Ephemeral private key must be present when using MAC authentication' ,
207+ id : VerificationAssessmentId . DEVICE_AUTH . EphemeralKeyPresence ,
193208 } ) ;
194209 if ( ! options . ephemeralPrivateKey ) { return ; }
195210
@@ -209,11 +224,13 @@ export class Verifier {
209224 onCheck ( {
210225 status : isValid ? 'PASSED' : 'FAILED' ,
211226 check : 'Device MAC must be valid' ,
227+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceMacValidity ,
212228 } ) ;
213229 } catch ( err ) {
214230 onCheck ( {
215231 status : 'FAILED' ,
216232 check : 'Device MAC must be valid' ,
233+ id : VerificationAssessmentId . DEVICE_AUTH . DeviceMacValidity ,
217234 reason : `Unable to verify deviceAuth MAC: ${ err . message } ` ,
218235 } ) ;
219236 }
@@ -231,6 +248,7 @@ export class Verifier {
231248 onCheck ( {
232249 status : digestAlgorithm && DIGEST_ALGS [ digestAlgorithm ] ? 'PASSED' : 'FAILED' ,
233250 check : 'Issuer Auth must include a supported digestAlgorithm element' ,
251+ id : VerificationAssessmentId . DATA_INTEGRITY . IssuerAuthDigestAlgorithmSupported ,
234252 } ) ;
235253
236254 const nameSpaces = mdoc . issuerSigned . nameSpaces || { } ;
@@ -239,6 +257,7 @@ export class Verifier {
239257 onCheck ( {
240258 status : valueDigests . has ( ns ) ? 'PASSED' : 'FAILED' ,
241259 check : `Issuer Auth must include digests for namespace: ${ ns } ` ,
260+ id : VerificationAssessmentId . DATA_INTEGRITY . IssuerAuthNamespaceDigestPresence ,
242261 } ) ;
243262
244263 const verifications = await Promise . all ( nameSpaces [ ns ] . map ( async ( ev ) => {
@@ -250,13 +269,15 @@ export class Verifier {
250269 onCheck ( {
251270 status : 'PASSED' ,
252271 check : `The calculated digest for ${ ns } /${ v . ev . elementIdentifier } attribute must match the digest in the issuerAuth element` ,
272+ id : VerificationAssessmentId . DATA_INTEGRITY . AttributeDigestMatch ,
253273 } ) ;
254274 } ) ;
255275
256276 verifications . filter ( ( v ) => ! v . isValid ) . forEach ( ( v ) => {
257277 onCheck ( {
258278 status : 'FAILED' ,
259279 check : `The calculated digest for ${ ns } /${ v . ev . elementIdentifier } attribute must match the digest in the issuerAuth element` ,
280+ id : VerificationAssessmentId . DATA_INTEGRITY . AttributeDigestMatch ,
260281 } ) ;
261282 } ) ;
262283
@@ -266,6 +287,7 @@ export class Verifier {
266287 onCheck ( {
267288 status : 'FAILED' ,
268289 check : "The 'issuing_country' if present must match the 'countryName' in the subject field within the DS certificate" ,
290+ id : VerificationAssessmentId . DATA_INTEGRITY . IssuingCountryMatchesCertificate ,
269291 reason : "The 'issuing_country' and 'issuing_jurisdiction' cannot be verified because the DS certificate was not provided" ,
270292 } ) ;
271293 } else {
@@ -275,6 +297,7 @@ export class Verifier {
275297 onCheck ( {
276298 status : invalidCountry ? 'FAILED' : 'PASSED' ,
277299 check : "The 'issuing_country' if present must match the 'countryName' in the subject field within the DS certificate" ,
300+ id : VerificationAssessmentId . DATA_INTEGRITY . IssuingCountryMatchesCertificate ,
278301 reason : invalidCountry ?
279302 `The 'issuing_country' (${ invalidCountry . ev . elementValue } ) must match the 'countryName' (${ issuerAuth . countryName } ) in the subject field within the issuer certificate` :
280303 undefined ,
@@ -286,6 +309,7 @@ export class Verifier {
286309 onCheck ( {
287310 status : invalidJurisdiction ? 'FAILED' : 'PASSED' ,
288311 check : "The 'issuing_jurisdiction' if present must match the 'stateOrProvinceName' in the subject field within the DS certificate" ,
312+ id : VerificationAssessmentId . DATA_INTEGRITY . IssuingJurisdictionMatchesCertificate ,
289313 reason : invalidJurisdiction ?
290314 `The 'issuing_jurisdiction' (${ invalidJurisdiction . ev . elementValue } ) must match the 'stateOrProvinceName' (${ issuerAuth . stateOrProvince } ) in the subject field within the issuer certificate` :
291315 undefined ,
@@ -318,18 +342,21 @@ export class Verifier {
318342 onCheck ( {
319343 status : dr . version ? 'PASSED' : 'FAILED' ,
320344 check : 'Device Response must include "version" element.' ,
345+ id : VerificationAssessmentId . DOCUMENT_FORMAT . DeviceResponseVersionPresence ,
321346 category : 'DOCUMENT_FORMAT' ,
322347 } ) ;
323348
324349 onCheck ( {
325350 status : compareVersions ( dr . version , '1.0' ) >= 0 ? 'PASSED' : 'FAILED' ,
326351 check : 'Device Response version must be 1.0 or greater' ,
352+ id : VerificationAssessmentId . DOCUMENT_FORMAT . DeviceResponseVersionSupported ,
327353 category : 'DOCUMENT_FORMAT' ,
328354 } ) ;
329355
330356 onCheck ( {
331357 status : dr . documents && dr . documents . length > 0 ? 'PASSED' : 'FAILED' ,
332358 check : 'Device Response must include at least one document.' ,
359+ id : VerificationAssessmentId . DOCUMENT_FORMAT . DeviceResponseDocumentPresence ,
333360 category : 'DOCUMENT_FORMAT' ,
334361 } ) ;
335362
@@ -359,6 +386,7 @@ export class Verifier {
359386 ) : Promise < DiagnosticInformation > {
360387 const dr : VerificationAssessment [ ] = [ ] ;
361388 const decoded = await this . verify (
389+ // @ts -ignore
362390 encodedDeviceResponse ,
363391 {
364392 ...options ,
0 commit comments