@@ -104,17 +104,10 @@ public async Task<SignatureValidatorResult> ValidateAsync(
104104
105105 private async Task < SignatureValidatorResult > HandleUnsignedPackageAsync ( Context context )
106106 {
107- var packageRegistration = _corePackageService . FindPackageRegistrationById ( context . Message . PackageId ) ;
108-
109- if ( packageRegistration . IsSigningRequired ( ) )
107+ var validationResult = await ValidatePackageRegistrationSigningRequirementsAsync ( context ) ;
108+ if ( validationResult != null )
110109 {
111- _logger . LogWarning (
112- "Package {PackageId} {PackageVersion} for validation {ValidationId} must be signed but is unsigned." ,
113- context . Message . PackageId ,
114- context . Message . PackageVersion ,
115- context . Message . ValidationId ) ;
116-
117- return await RejectAsync ( context , ValidationIssue . PackageIsNotSigned ) ;
110+ return validationResult ;
118111 }
119112
120113 _logger . LogInformation (
@@ -507,33 +500,21 @@ private async Task<bool> IsValidRepositorySignatureAsync<T>(Context context, T s
507500
508501 private async Task < SignatureValidatorResult > PerformFinalValidationAsync ( Context context )
509502 {
510- var signingCertificate = context . Signature . SignerInfo . Certificate ;
511- var signingFingerprint = signingCertificate . ComputeSHA256Thumbprint ( ) ;
503+ var packageRegistration = _corePackageService . FindPackageRegistrationById ( context . Message . PackageId ) ;
512504
513- if ( context . Signature . Type == SignatureType . Author )
505+ // Ensure the signature matches the package registration's signing requirements.
506+ var validationResult = await ValidatePackageRegistrationSigningRequirementsAsync ( context ) ;
507+ if ( validationResult != null )
514508 {
515- // Block packages with any unknown signing certificates.
516- var packageRegistration = _corePackageService . FindPackageRegistrationById ( context . Message . PackageId ) ;
517-
518- if ( ! packageRegistration . IsAcceptableSigningCertificate ( signingFingerprint ) )
519- {
520- _logger . LogWarning (
521- "Signed package {PackageId} {PackageVersion} is blocked for validation {ValidationId} since it has an unknown certificate fingerprint: {UnknownFingerprint}" ,
522- context . Message . PackageId ,
523- context . Message . PackageVersion ,
524- context . Message . ValidationId ,
525- signingFingerprint ) ;
526-
527- return await RejectAsync (
528- context ,
529- new UnauthorizedCertificateFailure ( signingCertificate . Thumbprint . ToLowerInvariant ( ) ) ) ;
530- }
509+ return validationResult ;
531510 }
532- else if ( context . Signature . Type != SignatureType . Repository )
511+
512+ if ( context . Signature . Type != SignatureType . Author &&
513+ context . Signature . Type != SignatureType . Repository )
533514 {
534515 _logger . LogInformation (
535516 "Signed package {PackageId} {PackageVersion} is blocked for validation {ValidationId} since it " +
536- "is not author signed: {SignatureType}" ,
517+ "is neither author nor repository signed: {SignatureType}" ,
537518 context . Message . PackageId ,
538519 context . Message . PackageVersion ,
539520 context . Message . ValidationId ,
@@ -560,6 +541,9 @@ private async Task<SignatureValidatorResult> PerformFinalValidationAsync(Context
560541 }
561542
562543 // Do a full verification of all signatures.
544+ var signingCertificate = context . Signature . SignerInfo . Certificate ;
545+ var signingFingerprint = signingCertificate . ComputeSHA256Thumbprint ( ) ;
546+
563547 var verifyResult = await _formatValidator . ValidateAllSignaturesAsync (
564548 context . PackageReader ,
565549 context . HasRepositorySignature ,
@@ -593,6 +577,65 @@ await _corePackageService.UpdatePackageSigningCertificateAsync(
593577 return null ;
594578 }
595579
580+ private async Task < SignatureValidatorResult > ValidatePackageRegistrationSigningRequirementsAsync ( Context context )
581+ {
582+ // Skip signing requirement checks if the package is already available. This is needed otherwise revalidating
583+ // a package after its owners have changed their signing requirements may fail.
584+ var package = _corePackageService . FindPackageByIdAndVersionStrict ( context . Message . PackageId , context . Message . PackageVersion ) ;
585+
586+ if ( package . PackageStatusKey == PackageStatus . Available )
587+ {
588+ _logger . LogInformation (
589+ "Package {PackageId} {PackageVersion} for validation {ValidationId} is already available, " +
590+ "skipping the package registration's certificate signing requirements" ,
591+ context . Message . PackageId ,
592+ context . Message . PackageVersion ,
593+ context . Message . ValidationId ) ;
594+
595+ return null ;
596+ }
597+
598+ var packageRegistration = _corePackageService . FindPackageRegistrationById ( context . Message . PackageId ) ;
599+
600+ if ( context . Signature == null || context . Signature . Type == SignatureType . Repository )
601+ {
602+ // Block unsigned packages if the registration requires a signature.
603+ if ( packageRegistration . IsSigningRequired ( ) )
604+ {
605+ _logger . LogWarning (
606+ "Package {PackageId} {PackageVersion} for validation {ValidationId} must be signed but is unsigned." ,
607+ context . Message . PackageId ,
608+ context . Message . PackageVersion ,
609+ context . Message . ValidationId ) ;
610+
611+ return await RejectAsync ( context , ValidationIssue . PackageIsNotSigned ) ;
612+ }
613+ }
614+
615+ if ( context . Signature ? . Type == SignatureType . Author )
616+ {
617+ var signingCertificate = context . Signature . SignerInfo . Certificate ;
618+ var signingFingerprint = signingCertificate . ComputeSHA256Thumbprint ( ) ;
619+
620+ // Block packages with any unknown signing certificates.
621+ if ( ! packageRegistration . IsAcceptableSigningCertificate ( signingFingerprint ) )
622+ {
623+ _logger . LogWarning (
624+ "Signed package {PackageId} {PackageVersion} is blocked for validation {ValidationId} since it has an unknown certificate fingerprint: {UnknownFingerprint}" ,
625+ context . Message . PackageId ,
626+ context . Message . PackageVersion ,
627+ context . Message . ValidationId ,
628+ signingFingerprint ) ;
629+
630+ return await RejectAsync (
631+ context ,
632+ new UnauthorizedCertificateFailure ( signingCertificate . Thumbprint . ToLowerInvariant ( ) ) ) ;
633+ }
634+ }
635+
636+ return null ;
637+ }
638+
596639 private async Task < SignatureValidatorResult > GetVerifyResult (
597640 Context context ,
598641 string verificationName ,
0 commit comments