예제 #1
0
        private static bool IsMatch(
            X509Certificate2 certificate,
            EssCertIdV2 essCertIdV2,
            Errors errors,
            bool isIssuerSerialRequired)
        {
            if (isIssuerSerialRequired)
            {
                if (essCertIdV2.IssuerSerial == null ||
                    essCertIdV2.IssuerSerial.GeneralNames.Count == 0)
                {
                    throw new SignatureException(errors.InvalidSignature, errors.InvalidSignatureString);
                }
            }

            if (essCertIdV2.IssuerSerial != null)
            {
                if (!AreSerialNumbersEqual(essCertIdV2.IssuerSerial, certificate))
                {
                    return(false);
                }

                if (!AreGeneralNamesEqual(essCertIdV2.IssuerSerial, certificate))
                {
                    return(false);
                }
            }

            var hashAlgorithmName = CryptoHashUtility.OidToHashAlgorithmName(essCertIdV2.HashAlgorithm.Algorithm.Value);
            var actualHash        = CertificateUtility.GetHash(certificate, hashAlgorithmName);

            return(essCertIdV2.CertificateHash.SequenceEqual(actualHash));
        }
        public void CreateSigningCertificateV2_WithValidInput_ReturnsAttribute(Common.HashAlgorithmName hashAlgorithmName)
        {
            using (var certificate = _fixture.GetDefaultCertificate())
            {
                var attribute = AttributeUtility.CreateSigningCertificateV2(certificate, hashAlgorithmName);

                Assert.Equal(Oids.SigningCertificateV2, attribute.Oid.Value);
                Assert.Equal(1, attribute.Values.Count);

                var signingCertificateV2 = SigningCertificateV2.Read(attribute.Values[0].RawData);

                Assert.Equal(1, signingCertificateV2.Certificates.Count);

                var essCertIdV2  = signingCertificateV2.Certificates[0];
                var expectedHash = SignTestUtility.GetHash(certificate, hashAlgorithmName);

                SignTestUtility.VerifyByteArrays(expectedHash, essCertIdV2.CertificateHash);
                Assert.Equal(
                    hashAlgorithmName,
                    CryptoHashUtility.OidToHashAlgorithmName(essCertIdV2.HashAlgorithm.Algorithm.Value));
                Assert.Equal(certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name);

                var serialNumber = certificate.GetSerialNumber();

                // Convert from little endian to big endian.
                Array.Reverse(serialNumber);

                SignTestUtility.VerifyByteArrays(
                    serialNumber,
                    essCertIdV2.IssuerSerial.SerialNumber);
            }
        }
예제 #3
0
        public void OidToHashAlgorithmName_WithUnknown_Throws()
        {
            var exception = Assert.Throws <ArgumentException>(
                () => CryptoHashUtility.OidToHashAlgorithmName(Oids.Sha1));

            Assert.Equal("oid", exception.ParamName);
            Assert.StartsWith($"Hash algorithm '{Oids.Sha1}' is unsupported.", exception.Message);
        }
예제 #4
0
        private static BcEssCertIdV2 CreateBcEssCertIdV2(HashAlgorithmName hashAlgorithmName, string text)
        {
            var hash = CryptoHashUtility.ComputeHash(hashAlgorithmName, Encoding.UTF8.GetBytes(text));
            var bcAlgorithmIdentifier = new BcAlgorithmIdentifier(
                new DerObjectIdentifier(hashAlgorithmName.ConvertToOidString()));

            return(new BcEssCertIdV2(bcAlgorithmIdentifier, hash));
        }
        private static BcEssCertId CreateBcEssCertId(string text)
        {
            using (var hashAlgorithm = CryptoHashUtility.GetSha1HashProvider())
            {
                var hash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(text));

                return(new BcEssCertId(hash));
            }
        }
예제 #6
0
        internal static string GenerateFingerprint(X509Certificate certificate)
        {
            using (var hashAlgorithm = CryptoHashUtility.GetSha1HashProvider())
            {
                var hash = hashAlgorithm.ComputeHash(certificate.GetEncoded());

                return(BitConverter.ToString(hash).Replace("-", ""));
            }
        }
예제 #7
0
 /// <summary>
 /// Write the content to a stream.
 /// </summary>
 private void Save(Stream stream)
 {
     using (var writer = new KeyPairFileWriter(stream, _signingSpecifications.Encoding, leaveOpen: true))
     {
         writer.WritePair("Version", _signingSpecifications.Version);
         writer.WriteSectionBreak();
         writer.WritePair(CryptoHashUtility.ConvertToOidString(HashAlgorithm) + "-Hash", HashValue);
         writer.WriteSectionBreak();
     }
 }
        public void Read_WithOnlyCertificateHash_ReturnsEssCertIdV2()
        {
            var hash        = CryptoHashUtility.ComputeHash(HashAlgorithmName.SHA256, Encoding.UTF8.GetBytes("peach"));
            var bcEssCertId = new BcEssCertIdV2(hash);
            var bytes       = bcEssCertId.GetDerEncoded();

            var essCertIdV2 = EssCertIdV2.Read(bytes);

            Assert.Equal(Oids.Sha256, essCertIdV2.HashAlgorithm.Algorithm.Value);
            SigningTestUtility.VerifyByteArrays(hash, essCertIdV2.CertificateHash);
            Assert.Null(essCertIdV2.IssuerSerial);
        }
예제 #9
0
        public void Read_WithValidInput_ReturnsInstance(string oid)
        {
            var data = Encoding.UTF8.GetBytes("peach");
            var hashAlgorithmName = CryptoHashUtility.OidToHashAlgorithmName(oid);
            var hash = hashAlgorithmName.ComputeHash(data);
            var bcAlgorithmIdentifier = new BcAlgorithmIdentifier(new DerObjectIdentifier(oid));
            var bcMessageImprint      = new BcMessageImprint(bcAlgorithmIdentifier, hash);
            var bytes = bcMessageImprint.GetDerEncoded();

            var messageImprint = MessageImprint.Read(bytes);

            Assert.Equal(oid, messageImprint.HashAlgorithm.Algorithm.Value);
            Assert.Equal(hash, messageImprint.HashedMessage);
        }
        private HashAlgorithmName ValidateAndParseFingerprintAlgorithm(string algorithm)
        {
            if (string.IsNullOrEmpty(algorithm))
            {
                return(HashAlgorithmName.SHA256);
            }

            var hashAlgorithm = CryptoHashUtility.GetHashAlgorithmName(algorithm);

            if (hashAlgorithm == HashAlgorithmName.Unknown || !SigningSpecifications.V1.AllowedHashAlgorithms.Contains(hashAlgorithm))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_NotSupportedHashAlgorithm, algorithm));
            }

            return(hashAlgorithm);
        }
예제 #11
0
        public void GetSha1HashProvider_ReturnsCorrectImplementation()
        {
            using (var hashAlgorithm = CryptoHashUtility.GetSha1HashProvider())
            {
                Assert.True(hashAlgorithm is SHA1);

#if !IS_CORECLR
                if (AllowOnlyFipsAlgorithms())
                {
                    Assert.IsType <SHA1CryptoServiceProvider>(hashAlgorithm);
                }
                else
                {
                    Assert.IsType <SHA1Managed>(hashAlgorithm);
                }
#endif
            }
        }
        /// <summary>
        /// Parses a command line argument's value to a supported hash algorithm and validates it is supported in the given specification
        /// </summary>
        /// <param name="optionValue">Value entered by the user in the given command line argument</param>
        /// <param name="optionName">Name of the command line argument</param>
        /// <param name="spec">Signing specification to validate parsed hash algorithm</param>
        /// <returns>Supported hash algorithm</returns>
        internal static HashAlgorithmName ParseAndValidateHashAlgorithm(string optionValue, string optionName, SigningSpecifications spec)
        {
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;

            if (!string.IsNullOrEmpty(optionValue))
            {
                hashAlgorithm = CryptoHashUtility.GetHashAlgorithmName(optionValue);
            }

            if (hashAlgorithm == HashAlgorithmName.Unknown || !spec.AllowedHashAlgorithms.Contains(hashAlgorithm))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Err_InvalidValue,
                                                          optionName, string.Join(",", spec.AllowedHashAlgorithms)));
            }

            return(hashAlgorithm);
        }
예제 #13
0
        /// <summary>
        /// Parses a command line argument's value to a supported hash algorithm and validates it is supported in the given specification
        /// </summary>
        /// <param name="argumentValue">Value entered by the user in the given command line argument</param>
        /// <param name="argumentName">Name of the command line argument</param>
        /// <param name="spec">Signing specification to validate parsed hash algorithm</param>
        /// <returns>Supported hash algorithm</returns>
        public static HashAlgorithmName ParseAndValidateHashAlgorithmFromArgument(string argumentValue, string argumentName, SigningSpecifications spec)
        {
            var hashAlgorithm = HashAlgorithmName.SHA256;

            if (!string.IsNullOrEmpty(argumentValue))
            {
                hashAlgorithm = CryptoHashUtility.GetHashAlgorithmName(argumentValue);
            }

            if (hashAlgorithm == HashAlgorithmName.Unknown || !spec.AllowedHashAlgorithms.Contains(hashAlgorithm))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          NuGetCommand.CommandInvalidArgumentException,
                                                          argumentName));
            }

            return(hashAlgorithm);
        }
예제 #14
0
        public void Create_WithValidInput_ReturnsSigningCertificateV2(HashAlgorithmName hashAlgorithmName)
        {
            using (var certificate = _fixture.GetDefaultCertificate())
            {
                var signingCertificateV2 = SigningCertificateV2.Create(certificate, hashAlgorithmName);

                Assert.Equal(1, signingCertificateV2.Certificates.Count);

                var essCertIdV2 = signingCertificateV2.Certificates[0];

                Assert.Equal(hashAlgorithmName, CryptoHashUtility.OidToHashAlgorithmName(essCertIdV2.HashAlgorithm.Algorithm.Value));
                Assert.Equal(SigningTestUtility.GetHash(certificate, hashAlgorithmName), essCertIdV2.CertificateHash);
                Assert.Equal(1, essCertIdV2.IssuerSerial.GeneralNames.Count);
                Assert.Equal(certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name);
                SigningTestUtility.VerifySerialNumber(certificate, essCertIdV2.IssuerSerial);
                Assert.Null(signingCertificateV2.Policies);
            }
        }
예제 #15
0
        public void GetHashProvider_WhenHashAlgorithmNameIsSupported_ReturnsCorrectImplementation()
        {
            using (var hashAlgorithm = CryptoHashUtility.GetHashProvider(HashAlgorithmName.SHA256))
            {
                Assert.True(hashAlgorithm is SHA256);

#if !IS_CORECLR
                if (AllowOnlyFipsAlgorithms())
                {
                    Assert.IsType <SHA256CryptoServiceProvider>(hashAlgorithm);
                }
                else
                {
                    Assert.IsType <SHA256Managed>(hashAlgorithm);
                }
#endif
            }
        }
        public void Read_WithDefaultAlgorithmIdentifier_ReturnsEssCertIdV2()
        {
            var directoryName = new X509Name("CN=test");
            var generalNames  = new GeneralNames(
                new BcGeneralName(BcGeneralName.DirectoryName, directoryName));
            var bcIssuerSerial = new BcIssuerSerial(generalNames, new DerInteger(BigInteger.One));
            var hash           = CryptoHashUtility.ComputeHash(HashAlgorithmName.SHA256, Encoding.UTF8.GetBytes("peach"));
            var bcEssCertId    = new BcEssCertIdV2(hash, bcIssuerSerial);
            var bytes          = bcEssCertId.GetDerEncoded();

            var essCertIdV2 = EssCertIdV2.Read(bytes);

            Assert.Equal(Oids.Sha256, essCertIdV2.HashAlgorithm.Algorithm.Value);
            Assert.Equal(1, essCertIdV2.IssuerSerial.GeneralNames.Count);
            Assert.Equal(directoryName.ToString(), essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name);
            SigningTestUtility.VerifyByteArrays(hash, essCertIdV2.CertificateHash);
            SigningTestUtility.VerifyByteArrays(bcIssuerSerial.Serial.Value.ToByteArray(), essCertIdV2.IssuerSerial.SerialNumber);
        }
예제 #17
0
        public void EmitTelemetryEvent(Guid parentId)
        {
            var telemetryEvent = new TelemetryEvent(PackagePreFetcherInformation);

            telemetryEvent["DownloadStartTime"] = _downloadStartTime;
            telemetryEvent["PackageFetchTime"]  = _packageFetchTime;
            telemetryEvent["TaskReturnTime"]    = _taskReturnTime;

            var packageId = CryptoHashUtility.GenerateUniqueToken(Package.ToString());

            telemetryEvent.AddPiiData("PackageId", Package.ToString());

            if (parentId != Guid.Empty)
            {
                telemetryEvent["ParentId"] = parentId.ToString();
            }

            TelemetryActivity.EmitTelemetryEvent(telemetryEvent);
        }
        public void GetESSCertIDv2Entries_ReturnsDecodedHashes(Common.HashAlgorithmName hashAlgorithm)
        {
            // Arrange
            var cert      = TestCertificate.Generate().PublicCert;
            var cert2     = TestCertificate.Generate().PublicCert;
            var attribute = AttributeUtility.GetSigningCertificateV2(
                new[] { cert, cert2 },
                hashAlgorithm);
            var certHash  = CryptoHashUtility.ComputeHash(hashAlgorithm, cert.RawData);
            var cert2Hash = CryptoHashUtility.ComputeHash(hashAlgorithm, cert2.RawData);

            // Act
            var actual = AttributeUtility.GetESSCertIDv2Entries(attribute);

            // Assert
            actual.ShouldBeEquivalentTo(new[]
            {
                new KeyValuePair <Common.HashAlgorithmName, byte[]>(hashAlgorithm, certHash),
                new KeyValuePair <Common.HashAlgorithmName, byte[]>(hashAlgorithm, cert2Hash),
            });
        }
예제 #19
0
        private static bool TryReadPackageHashProperty(
            KeyValuePair <string, string> property,
            SigningSpecifications signingSpecifications,
            out HashAlgorithmName hashAlgorithmName)
        {
            hashAlgorithmName = HashAlgorithmName.Unknown;

            if (property.Key.EndsWith("-Hash", StringComparison.Ordinal))
            {
                foreach (var hashAlgorithmOid in signingSpecifications.AllowedHashAlgorithmOids)
                {
                    if (property.Key == $"{hashAlgorithmOid}-Hash")
                    {
                        hashAlgorithmName = CryptoHashUtility.OidToHashAlgorithmName(hashAlgorithmOid);

                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #20
0
        private static bool IsMatch(X509Certificate2 certificate, EssCertId essCertId)
        {
            if (essCertId.IssuerSerial != null)
            {
                if (!AreSerialNumbersEqual(essCertId.IssuerSerial, certificate))
                {
                    return(false);
                }

                if (!AreGeneralNamesEqual(essCertId.IssuerSerial, certificate))
                {
                    return(false);
                }
            }

            byte[] actualHash;

            using (var hashAlgorithm = CryptoHashUtility.GetSha1HashProvider())
            {
                actualHash = hashAlgorithm.ComputeHash(certificate.RawData);
            }

            return(essCertId.CertificateHash.SequenceEqual(actualHash));
        }
예제 #21
0
        internal static SignatureVerificationStatusFlags ValidateTimestamp(Timestamp timestamp, Signature signature, bool treatIssuesAsErrors, List <SignatureLog> issues, SigningSpecifications spec)
        {
            if (timestamp == null)
            {
                throw new ArgumentNullException(nameof(timestamp));
            }
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (issues == null)
            {
                throw new ArgumentNullException(nameof(issues));
            }

            // Default to specification v1
            spec = spec ?? SigningSpecifications.V1;

            var validationFlags = SignatureVerificationStatusFlags.NoErrors;
            var signerInfo      = timestamp.SignerInfo;

            if (timestamp.SignerInfo.Certificate != null)
            {
                try
                {
                    signerInfo.CheckSignature(verifySignatureOnly: true);
                }
                catch (Exception e)
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3021, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampSignatureValidationFailed, signature.FriendlyName)));
                    issues.Add(SignatureLog.DebugLog(e.ToString()));
                    validationFlags |= SignatureVerificationStatusFlags.SignatureCheckFailed;
                }

                if (!CertificateUtility.IsSignatureAlgorithmSupported(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3022, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampUnsupportedSignatureAlgorithm, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.SignatureAlgorithmUnsupported;
                }

                if (!CertificateUtility.IsCertificatePublicKeyValid(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3023, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampCertificateFailsPublicKeyLengthRequirement, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.CertificatePublicKeyInvalid;
                }

                if (!spec.AllowedHashAlgorithmOids.Contains(signerInfo.DigestAlgorithm.Value))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3024, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampUnsupportedSignatureAlgorithm, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.HashAlgorithmUnsupported;
                }

                try
                {
                    var hashAlgorithm  = CryptoHashUtility.OidToHashAlgorithmName(timestamp.TstInfo.HashAlgorithmId.Value);
                    var signatureValue = signature.GetSignatureValue();
                    var messageHash    = hashAlgorithm.ComputeHash(signatureValue);

                    if (!timestamp.TstInfo.HasMessageHash(messageHash))
                    {
                        issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3019, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampIntegrityCheckFailed, signature.FriendlyName)));
                        validationFlags |= SignatureVerificationStatusFlags.IntegrityCheckFailed;
                    }
                }
                catch
                {
                    // If the hash algorithm is not supported OidToHashAlgorithmName will throw
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3030, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampMessageImprintUnsupportedHashAlgorithm, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.MessageImprintUnsupportedAlgorithm;
                }

                if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3025, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampNotYetValid, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.CertificateValidityInTheFuture;
                }

                if (!CertificateUtility.IsDateInsideValidityPeriod(signerInfo.Certificate, timestamp.GeneralizedTime))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3036, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampGeneralizedTimeInvalid, signature.FriendlyName)));
                    validationFlags |= SignatureVerificationStatusFlags.GeneralizedTimeOutsideValidity;
                }
            }
            else
            {
                issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3020, string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampNoCertificate, signature.FriendlyName)));
                validationFlags |= SignatureVerificationStatusFlags.NoCertificate;
            }

            return(validationFlags);
        }
 public CryptoHashProcessor(string cryptoHashKey)
 {
     _cryptoHashKey      = cryptoHashKey;
     _cryptoHashFunction = (input) => CryptoHashUtility.ComputeHmacSHA256Hash(input, _cryptoHashKey);
 }
예제 #23
0
        public void OidToHashAlgorithmName_WithValidInput_Succeeds(string oid, HashAlgorithmName expectedHashAlgorithmName)
        {
            var actualHashAlgorithmName = CryptoHashUtility.OidToHashAlgorithmName(oid);

            Assert.Equal(expectedHashAlgorithmName, actualHashAlgorithmName);
        }
예제 #24
0
        public void GivenAString_WhenComputeHmac_CorrectHashShouldBeReturned(string input, string expectedHash)
        {
            string hash = CryptoHashUtility.ComputeHmacSHA256Hash(input, TestHashKey);

            Assert.Equal(expectedHash, hash);
        }
예제 #25
0
        private async Task UpdateTrustedSourceAsync(PackageSource packageSource)
        {
            var sourceRepositoryProvider    = new CommandLineSourceRepositoryProvider(SourceProvider);
            var repositorySignatureResource = await sourceRepositoryProvider.CreateRepository(packageSource).GetResourceAsync <RepositorySignatureResource>() ??
                                              throw new CommandLineException(LocalizedResourceManager.GetString("SourcesCommandSourceNotSupportRepoSign"), packageSource.Name);

            var trustedSource = new TrustedSource(packageSource.Name);

            foreach (var cert in repositorySignatureResource.RepositoryCertificateInfos)
            {
                foreach (var fingerprint in cert.Fingerprints)
                {
                    trustedSource.Certificates.Add(new CertificateTrustEntry(fingerprint.Value, cert.Subject, CryptoHashUtility.OidToHashAlgorithmName(fingerprint.Key)));
                }
            }

            packageSource.TrustedSource = trustedSource;
        }
예제 #26
0
        private static Hash MakeHash(HashAlgorithmName algorithm, string hashInput)
        {
            var digest = CryptoHashUtility.ComputeHash(algorithm, Encoding.ASCII.GetBytes(hashInput));

            return(new Hash(algorithm, digest));
        }
예제 #27
0
        internal static bool IsTimestampValid(Timestamp timestamp, Signature signature, bool treatIssuesAsErrors, List <SignatureLog> issues, SigningSpecifications spec)
        {
            if (timestamp == null)
            {
                throw new ArgumentNullException(nameof(timestamp));
            }
            if (signature == null)
            {
                throw new ArgumentNullException(nameof(signature));
            }
            if (issues == null)
            {
                throw new ArgumentNullException(nameof(issues));
            }

            // Default to specification v1
            spec = spec ?? SigningSpecifications.V1;

            var isValid    = true;
            var signerInfo = timestamp.SignerInfo;

            if (timestamp.SignerInfo.Certificate != null)
            {
                try
                {
                    signerInfo.CheckSignature(verifySignatureOnly: true);
                }
                catch (Exception e)
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3021, Strings.TimestampSignatureValidationFailed));
                    issues.Add(SignatureLog.DebugLog(e.ToString()));
                    isValid = false;
                }

                if (!CertificateUtility.IsSignatureAlgorithmSupported(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3022, Strings.TimestampUnsupportedSignatureAlgorithm));
                    isValid = false;
                }

                if (!CertificateUtility.IsCertificatePublicKeyValid(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3023, Strings.TimestampCertificateFailsPublicKeyLengthRequirement));
                    isValid = false;
                }

                if (!spec.AllowedHashAlgorithmOids.Contains(signerInfo.DigestAlgorithm.Value))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3024, Strings.TimestampUnsupportedSignatureAlgorithm));
                    isValid = false;
                }

                try
                {
                    var hashAlgorithm  = CryptoHashUtility.OidToHashAlgorithmName(timestamp.TstInfo.HashAlgorithmId.Value);
                    var signatureValue = signature.GetSignatureValue();
                    var messageHash    = hashAlgorithm.ComputeHash(signatureValue);

                    if (!timestamp.TstInfo.HasMessageHash(messageHash))
                    {
                        issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3019, Strings.TimestampIntegrityCheckFailed));
                        isValid = false;
                    }
                }
                catch
                {
                    // If the hash algorithm is not supported OidToHashAlgorithmName will throw
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3030, Strings.TimestampMessageImprintUnsupportedHashAlgorithm));
                    isValid = false;
                }

                if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(signerInfo.Certificate))
                {
                    issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3025, Strings.TimestampNotYetValid));
                    isValid = false;
                }
            }
            else
            {
                issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3020, Strings.TimestampNoCertificate));
                isValid = false;
            }

            return(isValid);
        }