@@ -440,73 +440,9 @@ def verify_dsse(
440
440
entry ._kind_version .kind == "dsse"
441
441
and entry ._kind_version .version == "0.0.2"
442
442
):
443
- try :
444
- v2_body = v2 .Entry ().from_json (base64 .b64decode (entry .body ))
445
- except ValidationError as exc :
446
- raise VerificationError (f"invalid DSSE log entry: { exc } " )
447
-
448
- if v2_body .spec .dsse_v002 is None :
449
- raise VerificationError (
450
- "invalid DSSE log entry: missing dsse_v002 field"
451
- )
452
-
453
- if (
454
- v2_body .spec .dsse_v002 .payload_hash .algorithm
455
- != v1 .HashAlgorithm .SHA2_256
456
- ):
457
- raise VerificationError ("expected SHA256 hash in DSSE entry" )
458
-
459
- digest = sha256_digest (envelope ._inner .payload ).digest
460
- if v2_body .spec .dsse_v002 .payload_hash .digest != digest :
461
- raise VerificationError ("DSSE entry payload hash does not match bundle" )
462
-
463
- v2_signatures = [
464
- v2 .Signature (
465
- content = signature .sig ,
466
- verifier = v2 .Verifier (
467
- x509_certificate = v1 .X509Certificate (
468
- bundle .signing_certificate .public_bytes (
469
- encoding = serialization .Encoding .DER
470
- )
471
- ),
472
- key_details = self ._get_key_details (bundle .signing_certificate ),
473
- ),
474
- )
475
- for signature in envelope ._inner .signatures
476
- ]
477
- if v2_signatures != v2_body .spec .dsse_v002 .signatures :
478
- raise VerificationError ("log entry signatures do not match bundle" )
443
+ validate_dsse_v002_entry_body (bundle )
479
444
else :
480
- try :
481
- entry_body = rekor_types .Dsse .model_validate_json (
482
- base64 .b64decode (entry .body )
483
- )
484
- except ValidationError as exc :
485
- raise VerificationError (f"invalid DSSE log entry: { exc } " )
486
-
487
- payload_hash = sha256_digest (envelope ._inner .payload ).digest .hex ()
488
- if (
489
- entry_body .spec .root .payload_hash .algorithm # type: ignore[union-attr]
490
- != rekor_types .dsse .Algorithm .SHA256
491
- ):
492
- raise VerificationError (
493
- "expected SHA256 payload hash in DSSE log entry"
494
- )
495
- if payload_hash != entry_body .spec .root .payload_hash .value : # type: ignore[union-attr]
496
- raise VerificationError ("log entry payload hash does not match bundle" )
497
-
498
- # NOTE: Like `dsse._verify`: multiple signatures would be frivolous here,
499
- # but we handle them just in case the signer has somehow produced multiple
500
- # signatures for their envelope with the same signing key.
501
- signatures = [
502
- rekor_types .dsse .Signature (
503
- signature = base64 .b64encode (signature .sig ).decode (),
504
- verifier = base64_encode_pem_cert (bundle .signing_certificate ),
505
- )
506
- for signature in envelope ._inner .signatures
507
- ]
508
- if signatures != entry_body .spec .root .signatures :
509
- raise VerificationError ("log entry signatures do not match bundle" )
445
+ validate_dsse_v001_entry_body (bundle )
510
446
511
447
return (envelope ._inner .payload_type , envelope ._inner .payload )
512
448
@@ -551,58 +487,151 @@ def verify_artifact(
551
487
# (8): verify the consistency of the log entry's body against
552
488
# the other bundle materials (and input being verified).
553
489
entry = bundle .log_entry
554
-
555
490
if (
556
491
entry ._kind_version .kind == "hashedrekord"
557
492
and entry ._kind_version .version == "0.0.2"
558
493
):
559
- if bundle ._inner .message_signature is None :
560
- raise VerificationError (
561
- "invalid hashedrekord log entry: missing message signature"
562
- )
494
+ validate_hashedrekord_v002_entry_body (bundle )
495
+ else :
496
+ validate_hashedrekord_v001_entry_body (bundle , hashed_input )
563
497
564
- v2_expected_body = v2 .Entry (
565
- kind = entry ._kind_version .kind ,
566
- api_version = entry ._kind_version .version ,
567
- spec = v2 .Spec (
568
- hashed_rekord_v002 = v2 .HashedRekordLogEntryV002 (
569
- data = v1 .HashOutput (
570
- algorithm = bundle ._inner .message_signature .message_digest .algorithm ,
571
- digest = bundle ._inner .message_signature .message_digest .digest ,
572
- ),
573
- signature = v2 .Signature (
574
- content = bundle ._inner .message_signature .signature ,
575
- verifier = v2 .Verifier (
576
- x509_certificate = v1 .X509Certificate (
577
- bundle .signing_certificate .public_bytes (
578
- encoding = serialization .Encoding .DER
579
- )
580
- ),
581
- key_details = self ._get_key_details (
582
- bundle .signing_certificate
583
- ),
584
- ),
585
- ),
498
+
499
+ def validate_dsse_v001_entry_body (bundle : Bundle ) -> None :
500
+ """
501
+ Valideate the Entry body for dsse v001.
502
+ """
503
+ entry = bundle .log_entry
504
+ envelope = bundle ._dsse_envelope
505
+ if envelope is None :
506
+ raise VerificationError (
507
+ "cannot perform DSSE verification on a bundle without a DSSE envelope"
508
+ )
509
+ try :
510
+ entry_body = rekor_types .Dsse .model_validate_json (base64 .b64decode (entry .body ))
511
+ except ValidationError as exc :
512
+ raise VerificationError (f"invalid DSSE log entry: { exc } " )
513
+
514
+ payload_hash = sha256_digest (envelope ._inner .payload ).digest .hex ()
515
+ if (
516
+ entry_body .spec .root .payload_hash .algorithm # type: ignore[union-attr]
517
+ != rekor_types .dsse .Algorithm .SHA256
518
+ ):
519
+ raise VerificationError ("expected SHA256 payload hash in DSSE log entry" )
520
+ if payload_hash != entry_body .spec .root .payload_hash .value : # type: ignore[union-attr]
521
+ raise VerificationError ("log entry payload hash does not match bundle" )
522
+
523
+ # NOTE: Like `dsse._verify`: multiple signatures would be frivolous here,
524
+ # but we handle them just in case the signer has somehow produced multiple
525
+ # signatures for their envelope with the same signing key.
526
+ signatures = [
527
+ rekor_types .dsse .Signature (
528
+ signature = base64 .b64encode (signature .sig ).decode (),
529
+ verifier = base64_encode_pem_cert (bundle .signing_certificate ),
530
+ )
531
+ for signature in envelope ._inner .signatures
532
+ ]
533
+ if signatures != entry_body .spec .root .signatures :
534
+ raise VerificationError ("log entry signatures do not match bundle" )
535
+
536
+
537
+ def validate_dsse_v002_entry_body (bundle : Bundle ) -> None :
538
+ """
539
+ Valideate the Entry body for dsse v002.
540
+ """
541
+ entry = bundle .log_entry
542
+ envelope = bundle ._dsse_envelope
543
+ if envelope is None :
544
+ raise VerificationError (
545
+ "cannot perform DSSE verification on a bundle without a DSSE envelope"
546
+ )
547
+ try :
548
+ v2_body = v2 .Entry ().from_json (base64 .b64decode (entry .body ))
549
+ except ValidationError as exc :
550
+ raise VerificationError (f"invalid DSSE log entry: { exc } " )
551
+
552
+ if v2_body .spec .dsse_v002 is None :
553
+ raise VerificationError ("invalid DSSE log entry: missing dsse_v002 field" )
554
+
555
+ if v2_body .spec .dsse_v002 .payload_hash .algorithm != v1 .HashAlgorithm .SHA2_256 :
556
+ raise VerificationError ("expected SHA256 hash in DSSE entry" )
557
+
558
+ digest = sha256_digest (envelope ._inner .payload ).digest
559
+ if v2_body .spec .dsse_v002 .payload_hash .digest != digest :
560
+ raise VerificationError ("DSSE entry payload hash does not match bundle" )
561
+
562
+ v2_signatures = [
563
+ v2 .Signature (
564
+ content = signature .sig ,
565
+ verifier = v2 .Verifier (
566
+ x509_certificate = v1 .X509Certificate (
567
+ bundle .signing_certificate .public_bytes (
568
+ encoding = serialization .Encoding .DER
586
569
)
587
570
),
588
- )
589
- v2_actual_body = v2 .Entry ().from_json (base64 .b64decode (entry .body ))
590
- if v2_expected_body != v2_actual_body :
591
- raise VerificationError (
592
- "transparency log entry is inconsistent with other materials"
593
- )
571
+ key_details = Verifier ._get_key_details (bundle .signing_certificate ),
572
+ ),
573
+ )
574
+ for signature in envelope ._inner .signatures
575
+ ]
576
+ if v2_signatures != v2_body .spec .dsse_v002 .signatures :
577
+ raise VerificationError ("log entry signatures do not match bundle" )
594
578
595
- else :
596
- expected_body = _hashedrekord_from_parts (
597
- bundle .signing_certificate ,
598
- bundle ._inner .message_signature .signature , # type: ignore[union-attr]
599
- hashed_input ,
600
- )
601
- actual_body = rekor_types .Hashedrekord .model_validate_json (
602
- base64 .b64decode (entry .body )
603
- )
604
579
605
- if expected_body != actual_body :
606
- raise VerificationError (
607
- "transparency log entry is inconsistent with other materials"
608
- )
580
+ def validate_hashedrekord_v001_entry_body (bundle : Bundle , hashed_input : Hashed ) -> None :
581
+ """
582
+ Valideate the Entry body for hashedrekord v001.
583
+ """
584
+ entry = bundle .log_entry
585
+ expected_body = _hashedrekord_from_parts (
586
+ bundle .signing_certificate ,
587
+ bundle ._inner .message_signature .signature , # type: ignore[union-attr]
588
+ hashed_input ,
589
+ )
590
+ actual_body = rekor_types .Hashedrekord .model_validate_json (
591
+ base64 .b64decode (entry .body )
592
+ )
593
+ if expected_body != actual_body :
594
+ raise VerificationError (
595
+ "transparency log entry is inconsistent with other materials"
596
+ )
597
+
598
+
599
+ def validate_hashedrekord_v002_entry_body (bundle : Bundle ) -> None :
600
+ """
601
+ Valideate the Entry body for hashedrekord v002.
602
+ """
603
+ entry = bundle .log_entry
604
+ if bundle ._inner .message_signature is None :
605
+ raise VerificationError (
606
+ "invalid hashedrekord log entry: missing message signature"
607
+ )
608
+ v2_expected_body = v2 .Entry (
609
+ kind = entry ._kind_version .kind ,
610
+ api_version = entry ._kind_version .version ,
611
+ spec = v2 .Spec (
612
+ hashed_rekord_v002 = v2 .HashedRekordLogEntryV002 (
613
+ data = v1 .HashOutput (
614
+ algorithm = bundle ._inner .message_signature .message_digest .algorithm ,
615
+ digest = bundle ._inner .message_signature .message_digest .digest ,
616
+ ),
617
+ signature = v2 .Signature (
618
+ content = bundle ._inner .message_signature .signature ,
619
+ verifier = v2 .Verifier (
620
+ x509_certificate = v1 .X509Certificate (
621
+ bundle .signing_certificate .public_bytes (
622
+ encoding = serialization .Encoding .DER
623
+ )
624
+ ),
625
+ key_details = Verifier ._get_key_details (
626
+ bundle .signing_certificate
627
+ ),
628
+ ),
629
+ ),
630
+ )
631
+ ),
632
+ )
633
+ v2_actual_body = v2 .Entry ().from_json (base64 .b64decode (entry .body ))
634
+ if v2_expected_body != v2_actual_body :
635
+ raise VerificationError (
636
+ "transparency log entry is inconsistent with other materials"
637
+ )
0 commit comments