private async Task <ValidatorStatus> GetStatusAsync(IValidationRequest request)
        {
            // Look up this validator's state in the database.
            var status = await _validatorStateService.GetStatusAsync(request);

            if (status.State != ValidationStatus.Incomplete)
            {
                return(status);
            }

            // Wait until ALL certificate validations kicked off by this validation request have finished.
            if (!await AllCertificateValidationsAreFinishedAsync(request))
            {
                // We know this status is incomplete.
                return(status);
            }

            // All of the requested certificate validations have finished. At this point, the signature
            // may have a status of "Unknown" if the package is at ingestion and its signature has passed
            // all validations, "Invalid" if one or more of the signature's certificates has failed validations,
            // or "InGracePeriod" or "Valid" if this is a revalidation request.
            var signature = await FindAuthorSignatureAsync(request);

            if (signature == null)
            {
                _logger.LogError(
                    "Could not find author signature for {PackageKey} {PackageId} {PackageVersion} {ValidationId}",
                    request.PackageKey,
                    request.PackageId,
                    request.PackageVersion,
                    request.ValidationId);

                throw new InvalidOperationException($"Package with key {request.PackageKey} does not have an author signature");
            }

            if (signature.Status == PackageSignatureStatus.Invalid)
            {
                _logger.LogWarning(
                    "Failing validation {ValidationId} ({PackageId} {PackageVersion}) due to invalidated signature: {SignatureKey}",
                    request.ValidationId,
                    request.PackageId,
                    request.PackageVersion,
                    signature.Key);

                return(await _validatorStateService.TryUpdateValidationStatusAsync(request, status, ValidationStatus.Failed));
            }
            else
            {
                _logger.LogInformation(
                    "Successful validation {ValidationId} ({PackageId} {PackageVersion})",
                    request.ValidationId,
                    request.PackageId,
                    request.PackageVersion);

                PromoteSignature(request, signature);

                return(await _validatorStateService.TryUpdateValidationStatusAsync(request, status, ValidationStatus.Succeeded));
            }
        }
Пример #2
0
        public async Task <ValidationStatus> GetStatusAsync(IValidationRequest request)
        {
            // Look up this validator's state in the database.
            var status = await _validatorStateService.GetStatusAsync(request);

            if (status.State != ValidationStatus.Incomplete)
            {
                return(status.State);
            }

            // Wait until ALL certificate validations kicked off by this validation request have finished.
            if (!await AllCertificateValidationsAreFinishedAsync(request))
            {
                return(ValidationStatus.Incomplete);
            }

            // All of the requested certificate validations have finished. Fail the validation if any
            // signatures have been invalidated.
            var signatures = await FindSignaturesAsync(request);

            foreach (var signature in signatures)
            {
                // Signatures at this point MUST have a state of either "Unknown" or "Invalid" at this point as the
                // PackageSigningValidator will set all signatures to an "Unknown" status, and the ValidateCertificate
                // job may set signatures to the "Invalid" state.
                if (signature.Status == PackageSignatureStatus.Invalid)
                {
                    _logger.LogWarning(
                        "Failing validation {ValidationId} ({PackageId} {PackageVersion}) due to invalidated signature: {SignatureKey}",
                        request.ValidationId,
                        request.PackageId,
                        request.PackageVersion,
                        signature.Key);

                    return(await _validatorStateService.TryUpdateValidationStatusAsync(request, status, ValidationStatus.Failed));
                }

                if (signature.Status != PackageSignatureStatus.Unknown)
                {
                    _logger.LogError(
                        Error.PackageCertificateValidationInvalidSignatureState,
                        "Failing validation {ValidationId} ({PackageId} {PackageVersion}) due to invalid signature status: {SignatureStatus}",
                        request.ValidationId,
                        request.PackageId,
                        request.PackageVersion,
                        signature.Status);

                    return(await _validatorStateService.TryUpdateValidationStatusAsync(request, status, ValidationStatus.Failed));
                }
            }

            // All signatures are valid. Promote signatures out of the "Unknown" state to either "Valid" or "InGracePeriod".
            PromoteSignatures(signatures);

            return(await _validatorStateService.TryUpdateValidationStatusAsync(request, status, ValidationStatus.Succeeded));
        }