@originator-profile/verify 0.4.0 → 0.5.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4,6 +4,7 @@ var securingMechanism = require('@originator-profile/securing-mechanism');
4
4
  var sign = require('@originator-profile/sign');
5
5
  var cryptography = require('@originator-profile/cryptography');
6
6
  var model = require('@originator-profile/model');
7
+ var zod = require('zod');
7
8
 
8
9
  class CaInvalid extends Error {
9
10
  constructor(message, result) {
@@ -26,34 +27,6 @@ class CaVerifyFailed extends Error {
26
27
  code = CaVerifyFailed.code;
27
28
  }
28
29
 
29
- function verifyAllowedOrigin(origin, allowedOrigins) {
30
- if (origin === "null") {
31
- return false;
32
- }
33
- return [allowedOrigins].flat().includes(origin);
34
- }
35
-
36
- async function importURLPatternPolyfill() {
37
- if (typeof URLPattern === "undefined") {
38
- await Promise.resolve().then(function () { return require('./index-D-j8gXz_.cjs'); });
39
- }
40
- }
41
- function ReplaceEncode(url) {
42
- return url.replace(/(%[0-9a-f]{2}?)+/g, function(match) {
43
- return match.toUpperCase();
44
- });
45
- }
46
- async function verifyAllowedUrl(url, allowedUrl) {
47
- await importURLPatternPolyfill();
48
- return [allowedUrl].flat().some((value) => {
49
- if (!value) {
50
- return false;
51
- }
52
- const pattern = new URLPattern(ReplaceEncode(value));
53
- return pattern.test(ReplaceEncode(url));
54
- });
55
- }
56
-
57
30
  const supportedHashAlgorithms = {
58
31
  /** SHA-256 hash algorithm */
59
32
  sha256: "SHA-256",
@@ -328,12 +301,62 @@ async function createIntegrityMetadataSet(hashAlgorithms, data, options = {
328
301
  return new IntegrityMetadataSet(set, options);
329
302
  }
330
303
 
304
+ const WARN_SUFFIX = `This will become an error after 2027. See: https://docs.originator-profile.org/en/opb/context/#the-image-datatype`;
331
305
  async function verifyDigestSri(content, fetcher = fetch) {
332
306
  const integrity = new IntegrityMetadataSet(content.digestSRI);
333
307
  const alg = integrity.strongestHashAlgorithms.filter(Boolean);
334
308
  if (alg.length === 0) return false;
335
- const { digestSRI } = await sign.createDigestSri(alg[0], content, fetcher);
336
- return integrity.match(digestSRI);
309
+ try {
310
+ const result = await sign.createDigestSri(alg[0], content, fetcher);
311
+ return "digestSRI" in result && integrity.match(result.digestSRI);
312
+ } catch (error) {
313
+ console.error(
314
+ "Failed to access content for digestSRI verification:",
315
+ error
316
+ );
317
+ return false;
318
+ }
319
+ }
320
+ async function verifyImageDigestSri(value, fetcher = fetch) {
321
+ if (!value) return;
322
+ if (!value.digestSRI) {
323
+ console.warn(`digestSRI is missing. ${WARN_SUFFIX}`);
324
+ return;
325
+ }
326
+ const valid = await verifyDigestSri(
327
+ { id: value.id, digestSRI: value.digestSRI },
328
+ fetcher
329
+ );
330
+ if (!valid) {
331
+ console.warn(`digestSRI verification failed. ${WARN_SUFFIX}`);
332
+ }
333
+ }
334
+
335
+ class IntegrityFetchFailed extends Error {
336
+ static get code() {
337
+ return "ERR_INTEGRITY_FETCH_FAILED";
338
+ }
339
+ code = IntegrityFetchFailed.code;
340
+ ok = false;
341
+ /** 取得結果 */
342
+ result;
343
+ constructor(message, result) {
344
+ super(message);
345
+ this.result = result;
346
+ }
347
+ }
348
+ class IntegrityVerificationFailed extends Error {
349
+ static get code() {
350
+ return "ERR_INTEGRITY_VERIFICATION_FAILED";
351
+ }
352
+ code = IntegrityVerificationFailed.code;
353
+ ok = false;
354
+ /** 取得結果 */
355
+ result;
356
+ constructor(message, result) {
357
+ super(message);
358
+ this.result = result;
359
+ }
337
360
  }
338
361
 
339
362
  class IntegrityVerifier {
@@ -382,7 +405,47 @@ async function verifyIntegrity(content, doc = document, fetcher = fetch) {
382
405
  (content2) => contentFetcher(content2, fetcher),
383
406
  elementSelector
384
407
  );
385
- return await integrityVerifier.verify(content, doc);
408
+ try {
409
+ return await integrityVerifier.verify(content, doc);
410
+ } catch (e) {
411
+ if (e instanceof sign.FetchFailed) {
412
+ return new IntegrityFetchFailed("Verify integrity failed", e.error);
413
+ }
414
+ return new IntegrityVerificationFailed("Verify integrity failed", e);
415
+ }
416
+ }
417
+
418
+ function verifyAllowedOrigin(origin, allowedOrigins) {
419
+ if (origin === "null") {
420
+ return false;
421
+ }
422
+ return [allowedOrigins].flat().includes(origin);
423
+ }
424
+
425
+ async function importURLPatternPolyfill() {
426
+ if (typeof URLPattern === "undefined") {
427
+ await Promise.resolve().then(function () { return require('./index-D-j8gXz_.cjs'); });
428
+ }
429
+ }
430
+ function ReplaceEncode(url) {
431
+ return url.replace(/(%[0-9a-f]{2}?)+/g, function(match) {
432
+ return match.toUpperCase();
433
+ });
434
+ }
435
+ async function verifyAllowedUrl(url, allowedUrl) {
436
+ await importURLPatternPolyfill();
437
+ return [allowedUrl].flat().some((value) => {
438
+ if (!value) {
439
+ return false;
440
+ }
441
+ try {
442
+ const pattern = new URLPattern(ReplaceEncode(value));
443
+ return pattern.test(ReplaceEncode(url));
444
+ } catch (e) {
445
+ console.error(`Invalid URLPattern: ${value} (url: ${url})`);
446
+ }
447
+ return false;
448
+ });
386
449
  }
387
450
 
388
451
  async function checkUrlAndOrigin(result, url) {
@@ -408,6 +471,32 @@ async function checkUrlAndOrigin(result, url) {
408
471
  }
409
472
  return result;
410
473
  }
474
+ function checkIntegrityResults(integrityResults, urlResult) {
475
+ const fetchFailedResults = integrityResults.filter(
476
+ (r) => r.verifyResult instanceof Error && r.verifyResult.code === IntegrityFetchFailed.code
477
+ );
478
+ if (fetchFailedResults.length > 0) {
479
+ const failedIntegritiesMessage = fetchFailedResults.map((result) => {
480
+ return `target[${result.index}] Expected: ${result.expectedIntegrity}`;
481
+ }).join(", ");
482
+ return new CaVerifyFailed(
483
+ `Content Attestation Target integrity fetch failed for element(s): ${failedIntegritiesMessage}`,
484
+ urlResult
485
+ );
486
+ }
487
+ const verificationFailedResults = integrityResults.filter(
488
+ (r) => r.verifyResult instanceof Error && r.verifyResult.code === IntegrityVerificationFailed.code
489
+ );
490
+ if (verificationFailedResults.length > 0) {
491
+ const failedIntegritiesMessage = verificationFailedResults.map((result) => {
492
+ return `target[${result.index}] Expected: ${result.expectedIntegrity}`;
493
+ }).join(", ");
494
+ return new CaVerifyFailed(
495
+ `Content Attestation Target integrity verification failed for element(s): ${failedIntegritiesMessage}`,
496
+ urlResult
497
+ );
498
+ }
499
+ }
411
500
  function CaVerifier(ca, keys, issuer, url, verifyIntegrity$1 = verifyIntegrity, validator) {
412
501
  const verifyCa = securingMechanism.JwtVcVerifier(keys, issuer, validator);
413
502
  return async () => {
@@ -422,6 +511,9 @@ function CaVerifier(ca, keys, issuer, url, verifyIntegrity$1 = verifyIntegrity,
422
511
  if (urlResult instanceof Error) {
423
512
  return urlResult;
424
513
  }
514
+ await verifyImageDigestSri(
515
+ urlResult.doc.credentialSubject.image
516
+ );
425
517
  if (urlResult.doc.target) {
426
518
  if (urlResult.doc.target.length === 0) {
427
519
  return new CaInvalid("Target is empty", urlResult);
@@ -433,12 +525,19 @@ function CaVerifier(ca, keys, issuer, url, verifyIntegrity$1 = verifyIntegrity,
433
525
  expectedIntegrity: t.integrity
434
526
  }))
435
527
  );
436
- const failedIndices = integrityResults.filter((result2) => !result2.verifyResult.valid).map((result2) => result2.index);
528
+ const error = checkIntegrityResults(integrityResults, urlResult);
529
+ if (error) {
530
+ return error;
531
+ }
532
+ const failedIndices = integrityResults.filter(
533
+ (result2) => !(result2.verifyResult instanceof Error) && !result2.verifyResult.valid
534
+ ).map((result2) => result2.index);
437
535
  if (failedIndices.length > 0) {
438
536
  const failedIntegritiesMessage = failedIndices.map((integrityResultIndex) => {
439
537
  const integrityResult = integrityResults[integrityResultIndex];
440
538
  if (integrityResult) {
441
- const calculatedIntegrities = integrityResult.verifyResult.failedIntegrities.join();
539
+ const verifyResult = integrityResult.verifyResult;
540
+ const calculatedIntegrities = verifyResult.failedIntegrities.join();
442
541
  return `target[${integrityResultIndex}] Expected: ${integrityResult.expectedIntegrity}, Calculated: ${calculatedIntegrities}`;
443
542
  }
444
543
  return void 0;
@@ -514,91 +613,6 @@ async function verifyCas(cas, verifiedOps, url, verifyIntegrity, validator) {
514
613
  return resultCas;
515
614
  }
516
615
 
517
- class ProfileGenericError extends Error {
518
- static get code() {
519
- return "ERR_PROFILE_GENERIC";
520
- }
521
- code = ProfileGenericError.code;
522
- }
523
- class ProfileClaimsValidationFailed extends ProfileGenericError {
524
- static get code() {
525
- return "ERR_PROFILE_CLAIMS_VALIDATION_FAILED";
526
- }
527
- code = ProfileClaimsValidationFailed.code;
528
- /** 復号結果 */
529
- result;
530
- constructor(message, result) {
531
- super(message);
532
- this.result = result;
533
- }
534
- }
535
- class ProfileTokenVerifyFailed extends ProfileGenericError {
536
- static get code() {
537
- return "ERR_PROFILE_TOKEN_VERIFY_FAILED";
538
- }
539
- code = ProfileTokenVerifyFailed.code;
540
- /** 検証結果 */
541
- result;
542
- constructor(message, result) {
543
- super(message);
544
- this.result = result;
545
- }
546
- }
547
- class ProfileBodyExtractFailed extends ProfileGenericError {
548
- static get code() {
549
- return "ERR_PROFILE_BODY_EXTRACT_FAILED";
550
- }
551
- code = ProfileBodyExtractFailed.code;
552
- }
553
- class ProfileBodyVerifyFailed extends ProfileGenericError {
554
- static get code() {
555
- return "ERR_PROFILE_BODY_VERIFY_FAILED";
556
- }
557
- code = ProfileBodyVerifyFailed.code;
558
- /** 検証結果 */
559
- result;
560
- constructor(message, result) {
561
- super(message);
562
- this.result = result;
563
- }
564
- }
565
- class ProfilesResolveFailed extends ProfileGenericError {
566
- static get code() {
567
- return "ERR_PROFILES_RESOLVE_FAILED";
568
- }
569
- code = ProfilesResolveFailed.code;
570
- /** 検証結果 */
571
- result;
572
- constructor(message, result) {
573
- super(message);
574
- this.result = result;
575
- }
576
- }
577
- class ProfilesVerifyFailed extends ProfileGenericError {
578
- static get code() {
579
- return "ERR_PROFILES_VERIFY_FAILED";
580
- }
581
- code = ProfilesVerifyFailed.code;
582
- /** 検証結果 */
583
- result;
584
- constructor(message, result) {
585
- super(message);
586
- this.result = result;
587
- }
588
- }
589
- class CertificationSystemValidationFailed extends ProfileGenericError {
590
- static get code() {
591
- return "ERR_CERTIFICATION_SYSTEM_VALIDATION_FAILED";
592
- }
593
- code = CertificationSystemValidationFailed.code;
594
- /** 検証結果 */
595
- result;
596
- constructor(message, result) {
597
- super(message);
598
- this.result = result;
599
- }
600
- }
601
-
602
616
  var REMOVE = "remove";
603
617
  var REPLACE = "replace";
604
618
  var ADD = "add";
@@ -887,8 +901,44 @@ class OpVerifyFailed extends Error {
887
901
  }
888
902
  code = OpVerifyFailed.code;
889
903
  }
904
+ class CertificateExpired extends Error {
905
+ constructor(message, result) {
906
+ super(message);
907
+ this.result = result;
908
+ }
909
+ static get code() {
910
+ return "ERR_CERTIFICATE_EXPIRED";
911
+ }
912
+ code = CertificateExpired.code;
913
+ }
890
914
 
891
915
  const isEveryDecodedPa = (annotations) => annotations.every((annotation) => "doc" in annotation);
916
+ const isEveryDecodedWmp = (media) => media.every((m) => "doc" in m);
917
+ const validateDecodedOp = (core, annotations, media, resultOp) => {
918
+ if (annotations && !isEveryDecodedPa(annotations)) {
919
+ return new OpInvalid("Profile Annotation decode failed", resultOp);
920
+ }
921
+ if (media && !isEveryDecodedWmp(media)) {
922
+ return new OpInvalid("Web Media Profile decode failed", resultOp);
923
+ }
924
+ if (media && media.some(
925
+ (m) => core.doc.credentialSubject.id !== m.doc.credentialSubject.id
926
+ )) {
927
+ return new OpInvalid(
928
+ "Subject mismatch between Core Profile and Web Media Profile",
929
+ resultOp
930
+ );
931
+ }
932
+ if (annotations && annotations.some(
933
+ (annotation) => core.doc.credentialSubject.id !== annotation.doc.credentialSubject.id
934
+ )) {
935
+ return new OpInvalid(
936
+ "Subject mismatch between Core Profile and Profile Annotation",
937
+ resultOp
938
+ );
939
+ }
940
+ return { type: "valid", annotations, media };
941
+ };
892
942
  const isDecodedOps = (ops) => ops.every((op) => !(op instanceof OpInvalid));
893
943
  function decodeOps(ops) {
894
944
  const decodeCp = securingMechanism.JwtVcDecoder();
@@ -897,32 +947,22 @@ function decodeOps(ops) {
897
947
  const resultOps = ops.map((op) => {
898
948
  const core = decodeCp(op.core);
899
949
  const annotations = op.annotations ? op.annotations.map(decodePa) : void 0;
900
- const media = op.media ? decodeWmp(op.media) : void 0;
950
+ const mediaInput = op.media;
951
+ const mediaArray = mediaInput ? Array.isArray(mediaInput) ? mediaInput : [mediaInput] : void 0;
952
+ const media = mediaArray ? mediaArray.map(decodeWmp) : void 0;
901
953
  const resultOp = { core, annotations, media };
902
954
  if (core instanceof Error) {
903
955
  return new OpInvalid("Core Profile decode failed", resultOp);
904
956
  }
905
- if (annotations && !isEveryDecodedPa(annotations)) {
906
- return new OpInvalid("Profile Annotation decode failed", resultOp);
907
- }
908
- if (media instanceof Error) {
909
- return new OpInvalid("Web Media Profile decode failed", resultOp);
910
- }
911
- if (media && core.doc.credentialSubject.id !== media.doc.credentialSubject.id) {
912
- return new OpInvalid(
913
- "Subject mismatch between Core Profile and Web Media Profile",
914
- resultOp
915
- );
916
- }
917
- if (annotations && annotations.some(
918
- (annotation) => core.doc.credentialSubject.id !== annotation.doc.credentialSubject.id
919
- )) {
920
- return new OpInvalid(
921
- "Subject mismatch between Core Profile and Profile Annotation",
922
- resultOp
923
- );
957
+ const validated = validateDecodedOp(core, annotations, media, resultOp);
958
+ if (validated instanceof OpInvalid) {
959
+ return validated;
924
960
  }
925
- return resultOp;
961
+ return {
962
+ core,
963
+ annotations: validated.annotations,
964
+ media: validated.media
965
+ };
926
966
  });
927
967
  if (!isDecodedOps(resultOps)) {
928
968
  return new OpsInvalid("Invalid Originator Profile Set", resultOps);
@@ -939,29 +979,59 @@ function OpVerifier(paOrWmpIssuerKeys, vc, validator) {
939
979
  const cpKeys = cryptography.LocalKeys(jwks);
940
980
  return securingMechanism.JwtVcVerifier(cpKeys, issuer, validator);
941
981
  }
982
+ function validateCertificateExpiry(verifiedVc) {
983
+ const now = /* @__PURE__ */ new Date();
984
+ const validFrom = verifiedVc.doc.validFrom ? new Date(verifiedVc.doc.validFrom) : null;
985
+ const validUntil = verifiedVc.doc.validUntil ? new Date(verifiedVc.doc.validUntil) : null;
986
+ if (validFrom && now < validFrom) {
987
+ return new CertificateExpired("Certificate not yet valid", verifiedVc);
988
+ }
989
+ if (validUntil && now > validUntil) {
990
+ return new CertificateExpired("Certificate expired", verifiedVc);
991
+ }
992
+ return verifiedVc;
993
+ }
942
994
  async function verifyAnnotations(paIssuerKeys, annotations, validator) {
943
995
  if (!annotations) return;
944
996
  return await Promise.all(
945
- annotations.map((annotation) => {
997
+ annotations.map(async (annotation) => {
946
998
  const verify = OpVerifier(
947
999
  paIssuerKeys,
948
1000
  annotation,
949
- validator?.({
950
- oneOf: [model.Certificate, model.JapaneseExistenceCertificate]
951
- })
1001
+ validator?.(zod.z.union([model.Certificate, model.JapaneseExistenceCertificate]))
1002
+ );
1003
+ const result = await verify(annotation.source);
1004
+ if (result instanceof Error) {
1005
+ return result;
1006
+ }
1007
+ const valid = validateCertificateExpiry(result);
1008
+ if (valid instanceof CertificateExpired) {
1009
+ return valid;
1010
+ }
1011
+ await verifyImageDigestSri(
1012
+ valid.doc.credentialSubject.image
952
1013
  );
953
- return verify(annotation.source);
1014
+ return valid;
954
1015
  })
955
1016
  );
956
1017
  }
957
1018
  async function verifyMedia(wmpIssuerKeys, media, validator) {
958
1019
  if (!media) return;
959
- const verify = OpVerifier(
960
- wmpIssuerKeys,
961
- media,
962
- validator?.(model.WebMediaProfile)
1020
+ return await Promise.all(
1021
+ media.map(async (m) => {
1022
+ const verify = OpVerifier(
1023
+ wmpIssuerKeys,
1024
+ m,
1025
+ validator?.(model.WebMediaProfile)
1026
+ );
1027
+ const result = await verify(m.source);
1028
+ if (result instanceof Error) {
1029
+ return result;
1030
+ }
1031
+ await verifyImageDigestSri(result.doc.credentialSubject.logo);
1032
+ return result;
1033
+ })
963
1034
  );
964
- return await verify(media.source);
965
1035
  }
966
1036
  const isVerifiedOps = (ops) => ops.every((op) => !(op instanceof OpVerifyFailed));
967
1037
  function OpsVerifier(ops, keys, issuer, validator) {
@@ -995,7 +1065,7 @@ function OpsVerifier(ops, keys, issuer, validator) {
995
1065
  resultOp
996
1066
  );
997
1067
  }
998
- if (media instanceof Error) {
1068
+ if (media && media.some((m) => m instanceof Error)) {
999
1069
  return new OpVerifyFailed(
1000
1070
  "Web Media Profile verify failed",
1001
1071
  resultOp
@@ -1036,146 +1106,120 @@ class SiteProfileVerifyFailed extends Error {
1036
1106
  code = SiteProfileVerifyFailed.code;
1037
1107
  }
1038
1108
 
1109
+ const decodeWebsiteProfiles = (sp, opsVerified) => {
1110
+ const wspSources = sp.sites || (sp.credential ? [sp.credential] : []);
1111
+ if (wspSources.length === 0) {
1112
+ return new SiteProfileInvalid("No Website Profile found", {
1113
+ originators: opsVerified,
1114
+ sites: []
1115
+ });
1116
+ }
1117
+ const decodeWsp = securingMechanism.JwtVcDecoder();
1118
+ const decodedWsps = wspSources.map(decodeWsp);
1119
+ const decodeErrors = decodedWsps.filter((wsp) => wsp instanceof Error);
1120
+ if (decodeErrors.length > 0) {
1121
+ return new SiteProfileInvalid("Website Profile invalid", {
1122
+ originators: opsVerified,
1123
+ sites: decodeErrors
1124
+ });
1125
+ }
1126
+ return {
1127
+ decodedWsps,
1128
+ wspSources
1129
+ };
1130
+ };
1039
1131
  function SpVerifier(sp, keys, issuer, origin, verifyOrigin = true, validator) {
1040
1132
  async function verify() {
1041
1133
  const verifyOps = OpsVerifier(sp.originators, keys, issuer, validator);
1042
1134
  const opsVerified = await verifyOps();
1043
1135
  if (opsVerified instanceof OpsInvalid) {
1044
1136
  return new SiteProfileInvalid("Originator Profile Set invalid", {
1045
- originators: opsVerified
1137
+ originators: opsVerified,
1138
+ sites: []
1046
1139
  });
1047
1140
  }
1048
1141
  if (opsVerified instanceof OpsVerifyFailed) {
1049
1142
  return new SiteProfileVerifyFailed(
1050
1143
  "Originator Profile Set verify failed",
1051
- { originators: opsVerified }
1144
+ { originators: opsVerified, sites: [] }
1052
1145
  );
1053
1146
  }
1054
- const decodeWsp = securingMechanism.JwtVcDecoder();
1055
- const decodedWsp = decodeWsp(sp.credential);
1056
- if (decodedWsp instanceof Error) {
1057
- return new SiteProfileInvalid("Website Profile invalid", {
1058
- originators: opsVerified,
1059
- credential: decodedWsp
1060
- });
1147
+ const decoded = decodeWebsiteProfiles(sp, opsVerified);
1148
+ if (decoded instanceof SiteProfileInvalid) {
1149
+ return decoded;
1061
1150
  }
1062
- const wspIssuer = decodedWsp.doc.issuer;
1063
- const cp = opsVerified.find(
1064
- (op) => op.core.doc.credentialSubject.id === wspIssuer
1151
+ const { decodedWsps, wspSources } = decoded;
1152
+ const verifiedWsps = await Promise.all(
1153
+ decodedWsps.map(async (decodedWsp, index) => {
1154
+ if (decodedWsp instanceof Error) {
1155
+ return decodedWsp;
1156
+ }
1157
+ const wspIssuer = decodedWsp.doc.issuer;
1158
+ const cp = opsVerified.find(
1159
+ (op) => op.core.doc.credentialSubject.id === wspIssuer
1160
+ );
1161
+ if (!cp) {
1162
+ return new CoreProfileNotFound(
1163
+ `Missing Core Profile (${wspIssuer})`,
1164
+ decodedWsp
1165
+ );
1166
+ }
1167
+ const verifyWsp = securingMechanism.JwtVcVerifier(
1168
+ cryptography.LocalKeys(cp.core.doc.credentialSubject.jwks),
1169
+ cp.core.doc.credentialSubject.id,
1170
+ validator?.(model.WebsiteProfile)
1171
+ );
1172
+ const verified = await verifyWsp(wspSources[index]);
1173
+ if (verified instanceof Error) {
1174
+ return verified;
1175
+ }
1176
+ if (verifyOrigin) {
1177
+ const allowedOrigin = "allowedOrigin" in verified.doc.credentialSubject ? verified.doc.credentialSubject.allowedOrigin : verified.doc.credentialSubject.url;
1178
+ if (!verifyAllowedOrigin(origin, allowedOrigin)) {
1179
+ return new Error("Origin not allowed");
1180
+ }
1181
+ }
1182
+ await verifyImageDigestSri(verified.doc.credentialSubject.image);
1183
+ return verified;
1184
+ })
1065
1185
  );
1066
- if (!cp) {
1186
+ const hasCoreProfileNotFound = verifiedWsps.some(
1187
+ (wsp) => wsp instanceof CoreProfileNotFound
1188
+ );
1189
+ if (hasCoreProfileNotFound) {
1067
1190
  return new SiteProfileInvalid("Appropriate Core Profile not found", {
1068
1191
  originators: opsVerified,
1069
- credential: new CoreProfileNotFound(
1070
- `Missing Core Profile (${wspIssuer})`,
1071
- decodedWsp
1072
- )
1192
+ sites: verifiedWsps
1073
1193
  });
1074
1194
  }
1075
- const verifyWsp = securingMechanism.JwtVcVerifier(
1076
- cryptography.LocalKeys(cp.core.doc.credentialSubject.jwks),
1077
- cp.core.doc.credentialSubject.id,
1078
- validator?.(model.WebsiteProfile)
1079
- );
1080
- const credential = await verifyWsp(sp.credential);
1081
- if (credential instanceof Error) {
1195
+ const hasError = verifiedWsps.some((wsp) => wsp instanceof Error);
1196
+ if (hasError) {
1082
1197
  return new SiteProfileVerifyFailed("Website Profile verify failed", {
1083
1198
  originators: opsVerified,
1084
- credential
1199
+ sites: verifiedWsps
1085
1200
  });
1086
1201
  }
1087
- if (verifyOrigin) {
1088
- const allowedOrigin = "allowedOrigin" in decodedWsp.doc.credentialSubject ? decodedWsp.doc.credentialSubject.allowedOrigin : decodedWsp.doc.credentialSubject.url;
1089
- if (!verifyAllowedOrigin(origin, allowedOrigin)) {
1090
- return new SiteProfileVerifyFailed("Origin not allowed", {
1091
- originators: opsVerified,
1092
- credential
1093
- });
1094
- }
1095
- }
1096
- return { originators: opsVerified, credential };
1202
+ return {
1203
+ originators: opsVerified,
1204
+ sites: verifiedWsps
1205
+ };
1097
1206
  }
1098
1207
  return verify;
1099
1208
  }
1100
1209
 
1101
- var objectTypeof = typeOf;
1102
- function typeOf(obj) {
1103
- if (obj === null) {
1104
- return "null";
1105
- }
1106
- if (obj !== Object(obj)) {
1107
- return typeof obj;
1108
- }
1109
- var result = {}.toString.call(obj).slice(8, -1).toLowerCase();
1110
- return result.indexOf("function") > -1 ? "function" : result;
1111
- }
1112
-
1113
- function CertificationSystemValidator() {
1114
- return function validate(payload) {
1115
- if (objectTypeof(payload) !== "object") {
1116
- return new CertificationSystemValidationFailed("should be an object", {
1117
- payload
1118
- });
1119
- }
1120
- const keys = Object.keys(payload);
1121
- const entries = Object.entries(payload);
1122
- if (!model.CertificationSystem.required.every((k) => keys.includes(k))) {
1123
- return new CertificationSystemValidationFailed(
1124
- "should be contain required properties",
1125
- { payload }
1126
- );
1127
- }
1128
- for (const entry of entries) {
1129
- const [key, value] = entry;
1130
- const propertySchema = model.CertificationSystem.properties[key];
1131
- if (objectTypeof(propertySchema) !== "object") {
1132
- return new CertificationSystemValidationFailed(
1133
- "should not contain additional properties",
1134
- { payload }
1135
- );
1136
- }
1137
- if ("const" in propertySchema && value !== propertySchema.const)
1138
- return new CertificationSystemValidationFailed(
1139
- `should be contain value of '${value}' in '${key}' property`,
1140
- { payload }
1141
- );
1142
- if ("type" in propertySchema && typeof value !== propertySchema.type)
1143
- return new CertificationSystemValidationFailed(
1144
- `should be contain ${propertySchema.type} value in '${key}' property`,
1145
- { payload }
1146
- );
1147
- }
1148
- return true;
1149
- };
1150
- }
1151
- function validateCertificationSystem(payload) {
1152
- const validator = CertificationSystemValidator();
1153
- const result = validator(payload);
1154
- if (result !== true) {
1155
- return result;
1156
- }
1157
- return payload;
1158
- }
1159
-
1160
1210
  exports.CaInvalid = CaInvalid;
1161
1211
  exports.CaVerifier = CaVerifier;
1162
1212
  exports.CaVerifyFailed = CaVerifyFailed;
1163
1213
  exports.CasVerifyFailed = CasVerifyFailed;
1164
- exports.CertificationSystemValidationFailed = CertificationSystemValidationFailed;
1165
- exports.CertificationSystemValidator = CertificationSystemValidator;
1214
+ exports.CertificateExpired = CertificateExpired;
1166
1215
  exports.CoreProfileNotFound = CoreProfileNotFound;
1216
+ exports.IntegrityFetchFailed = IntegrityFetchFailed;
1217
+ exports.IntegrityVerificationFailed = IntegrityVerificationFailed;
1167
1218
  exports.OpInvalid = OpInvalid;
1168
1219
  exports.OpVerifyFailed = OpVerifyFailed;
1169
1220
  exports.OpsInvalid = OpsInvalid;
1170
1221
  exports.OpsVerifier = OpsVerifier;
1171
1222
  exports.OpsVerifyFailed = OpsVerifyFailed;
1172
- exports.ProfileBodyExtractFailed = ProfileBodyExtractFailed;
1173
- exports.ProfileBodyVerifyFailed = ProfileBodyVerifyFailed;
1174
- exports.ProfileClaimsValidationFailed = ProfileClaimsValidationFailed;
1175
- exports.ProfileGenericError = ProfileGenericError;
1176
- exports.ProfileTokenVerifyFailed = ProfileTokenVerifyFailed;
1177
- exports.ProfilesResolveFailed = ProfilesResolveFailed;
1178
- exports.ProfilesVerifyFailed = ProfilesVerifyFailed;
1179
1223
  exports.SiteProfileInvalid = SiteProfileInvalid;
1180
1224
  exports.SiteProfileVerifyFailed = SiteProfileVerifyFailed;
1181
1225
  exports.SpVerifier = SpVerifier;
@@ -1192,10 +1236,10 @@ exports.getTupledKeys = getTupledKeys;
1192
1236
  exports.normalizeCasItem = normalizeCasItem;
1193
1237
  exports.opId = opId;
1194
1238
  exports.patch = patch;
1195
- exports.validateCertificationSystem = validateCertificationSystem;
1196
1239
  exports.verifyAllowedOrigin = verifyAllowedOrigin;
1197
1240
  exports.verifyCas = verifyCas;
1198
1241
  exports.verifyDigestSri = verifyDigestSri;
1242
+ exports.verifyImageDigestSri = verifyImageDigestSri;
1199
1243
  exports.verifyIntegrity = verifyIntegrity;
1200
1244
  exports.wmp = wmp;
1201
1245
  exports.wsp = wsp;