@@ -552,8 +552,25 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
552
552
// If it's a partial commit obtained from an existing artifact, check if the
553
553
// reconciliation can be skipped if other configurations have not changed.
554
554
if ! git .IsConcreteCommit (* commit ) {
555
+ // If we need to verify a Git object that we previously haven't verified, then
556
+ // we need to do a full reconciliation.
557
+ var verificationRequired bool
558
+ sourceVerifiedCondition := conditions .Get (obj , sourcev1 .SourceVerifiedCondition )
559
+ if obj .Spec .Verification != nil {
560
+ if sourceVerifiedCondition == nil {
561
+ verificationRequired = true
562
+ }
563
+ mode := obj .Spec .Verification .GetMode ()
564
+ if sourceVerifiedCondition .Reason == sourcev1 .VerifiedTagReason && (mode == sourcev1 .ModeHead || mode == sourcev1 .ModeTagAndHead ) {
565
+ verificationRequired = true
566
+ }
567
+ if sourceVerifiedCondition .Reason == sourcev1 .VerifiedCommitReason && (mode == sourcev1 .ModeTag || mode == sourcev1 .ModeTagAndHead ) {
568
+ verificationRequired = true
569
+ }
570
+ }
571
+
555
572
// Check if the content config contributing to the artifact has changed.
556
- if ! gitContentConfigChanged (obj , includes ) {
573
+ if ! gitContentConfigChanged (obj , includes ) && ! verificationRequired {
557
574
ge := serror .NewGeneric (
558
575
fmt .Errorf ("no changes since last reconcilation: observed revision '%s'" ,
559
576
commitReference (obj , commit )), sourcev1 .GitOperationSucceedReason ,
@@ -923,8 +940,8 @@ func (r *GitRepositoryReconciler) fetchIncludes(ctx context.Context, obj *source
923
940
return & artifacts , nil
924
941
}
925
942
926
- // verifyCommitSignature verifies the signature of the given Git commit, if a
927
- // verification mode is specified on the object.
943
+ // verifyCommitSignature verifies the signature of the given Git commit and/or its parent tag
944
+ // depedning on the verification mode specified on the object.
928
945
// If the signature can not be verified or the verification fails, it records
929
946
// v1beta2.SourceVerifiedCondition=False and returns.
930
947
// When successful, it records v1beta2.SourceVerifiedCondition=True.
@@ -957,22 +974,78 @@ func (r *GitRepositoryReconciler) verifyCommitSignature(ctx context.Context, obj
957
974
for _ , v := range secret .Data {
958
975
keyRings = append (keyRings , string (v ))
959
976
}
960
- // Verify commit with GPG data from secret
961
- entity , err := commit .Verify (keyRings ... )
962
- if err != nil {
963
- e := serror .NewGeneric (
964
- fmt .Errorf ("signature verification of commit '%s' failed: %w" , commit .Hash .String (), err ),
965
- "InvalidCommitSignature" ,
966
- )
967
- conditions .MarkFalse (obj , sourcev1 .SourceVerifiedCondition , e .Reason , e .Err .Error ())
968
- // Return error in the hope the secret changes
969
- return sreconcile .ResultEmpty , e
977
+
978
+ // these flags help us later figure out which objects we need to verify
979
+ var verifyHead bool
980
+ var verifyTag bool
981
+ switch obj .Spec .Verification .GetMode () {
982
+ case sourcev1 .ModeHead :
983
+ verifyHead = true
984
+ case sourcev1 .ModeTag :
985
+ verifyTag = true
986
+ case sourcev1 .ModeTagAndHead :
987
+ verifyHead = true
988
+ verifyTag = true
970
989
}
971
990
972
- conditions .MarkTrue (obj , sourcev1 .SourceVerifiedCondition , meta .SucceededReason ,
973
- "verified signature of commit '%s' with key '%s'" , commit .Hash .String (), entity )
974
- r .eventLogf (ctx , obj , eventv1 .EventTypeTrace , "VerifiedCommit" ,
975
- "verified signature of commit '%s' with key '%s'" , commit .Hash .String (), entity )
991
+ if verifyTag && obj .Spec .Reference .Tag == "" {
992
+ err := errors .New ("cannot verify tag object's signature if a tag reference is not specified" )
993
+ conditions .MarkStalled (obj , "InvalidVerificationMode" , err .Error ())
994
+ return sreconcile .ResultEmpty , err
995
+ }
996
+ conditions .Delete (obj , meta .StalledCondition )
997
+
998
+ var err error
999
+ var headEntity string
1000
+ if verifyHead {
1001
+ // Verify commit with GPG data from secret
1002
+ headEntity , err = commit .Verify (keyRings ... )
1003
+ if err != nil {
1004
+ e := serror .NewGeneric (
1005
+ fmt .Errorf ("signature verification of commit '%s' failed: %w" , commit .Hash .String (), err ),
1006
+ "InvalidCommitSignature" ,
1007
+ )
1008
+ conditions .MarkFalse (obj , sourcev1 .SourceVerifiedCondition , e .Reason , e .Err .Error ())
1009
+ // Return error in the hope the secret changes
1010
+ return sreconcile .ResultEmpty , e
1011
+ }
1012
+ }
1013
+
1014
+ var tag * git.AnnotatedTag
1015
+ var tagEntity string
1016
+ if verifyTag {
1017
+ // Verify tag with GPG data from secret
1018
+ if tag = commit .ReferencingTag ; tag != nil {
1019
+ tagEntity , err = tag .Verify (keyRings ... )
1020
+ if err != nil {
1021
+ e := serror .NewGeneric (
1022
+ fmt .Errorf ("signature verification of tag '%s' failed: %w" , tag .String (), err ),
1023
+ "InvalidTagSignature" ,
1024
+ )
1025
+ conditions .MarkFalse (obj , sourcev1 .SourceVerifiedCondition , e .Reason , e .Err .Error ())
1026
+ // Return error in the hope the secret changes
1027
+ return sreconcile .ResultEmpty , e
1028
+ }
1029
+ }
1030
+ }
1031
+
1032
+ var message string
1033
+ var reason string
1034
+ if verifyHead {
1035
+ message = fmt .Sprintf ("verified signature of commit '%s' with key '%s'" , commit .Hash .String (), headEntity )
1036
+ reason = sourcev1 .VerifiedCommitReason
1037
+ }
1038
+ if verifyTag {
1039
+ if message == "" {
1040
+ message = fmt .Sprintf ("verified signature of tag '%s' with key '%s'" , tag .String (), tagEntity )
1041
+ reason = sourcev1 .VerifiedTagReason
1042
+ } else {
1043
+ message = message + fmt .Sprintf (" and signature of tag '%s' with key '%s'" , tag .String (), tagEntity )
1044
+ reason = sourcev1 .VerifiedTagAndCommitReason
1045
+ }
1046
+ }
1047
+ conditions .MarkTrue (obj , sourcev1 .SourceVerifiedCondition , reason , message )
1048
+ r .eventLogf (ctx , obj , eventv1 .EventTypeTrace , reason , message )
976
1049
return sreconcile .ResultSuccess , nil
977
1050
}
978
1051
0 commit comments