/// <summary> /// Load content from a stream. /// </summary> private static SignatureContent Load(Stream stream, SigningSpecifications signingSpecifications) { var hashAlgorithm = HashAlgorithmName.Unknown; string hash = null; using (var reader = new KeyPairFileReader(stream, signingSpecifications.Encoding)) { // Read header-section. var properties = reader.ReadSection(); ThrowIfEmpty(properties); ThrowIfSignatureFormatVersionIsUnsupported(properties, signingSpecifications); // Read only the first section. properties = reader.ReadSection(); ThrowIfEmpty(properties); foreach (var property in properties) { if (TryReadPackageHashProperty(property, signingSpecifications, out hashAlgorithm)) { hash = property.Value; break; } } if (string.IsNullOrEmpty(hash)) { throw new SignatureException(Strings.UnableToReadPackageHashInformation); } } return(new SignatureContent(signingSpecifications, hashAlgorithm, hash)); }
internal static IReadOnlyList <X509Certificate2> GetPrimarySignatureCertificates( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications) { return(GetPrimarySignatureCertificates(signedCms, signerInfo, signingSpecifications, includeChain: false)); }
private static IX509CertificateChain GetTimestampCertificates( SignedCms signedCms, SigningSpecifications signingSpecifications, string signatureFriendlyName, bool includeChain) { var errors = new Errors( noCertificate: NuGetLogCode.NU3020, noCertificateString: string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampNoCertificate, signatureFriendlyName), invalidSignature: NuGetLogCode.NU3021, invalidSignatureString: string.Format(CultureInfo.CurrentCulture, Strings.VerifyError_TimestampInvalid, signatureFriendlyName), chainBuildingFailed: NuGetLogCode.NU3028); if (signedCms.SignerInfos.Count != 1) { throw new SignatureException(errors.InvalidSignature, errors.InvalidSignatureString); } const bool isIssuerSerialRequired = false; return(GetCertificates( signedCms, signedCms.SignerInfos[0], SigningCertificateRequirement.EitherOrBoth, isIssuerSerialRequired, errors, signingSpecifications, includeChain)); }
private static IX509CertificateChain GetRepositoryCountersignatureCertificates( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications, bool includeChain) { if (signedCms == null) { throw new ArgumentNullException(nameof(signedCms)); } if (signerInfo == null) { throw new ArgumentNullException(nameof(signerInfo)); } var errors = new Errors( noCertificate: NuGetLogCode.NU3034, noCertificateString: Strings.RepositoryCountersignatureHasNoCertificate, invalidSignature: NuGetLogCode.NU3031, invalidSignatureString: Strings.InvalidRepositoryCountersignature, chainBuildingFailed: NuGetLogCode.NU3035); var isIssuerSerialRequired = true; return(GetCertificates( signedCms, signerInfo, SigningCertificateRequirement.OnlyV2, isIssuerSerialRequired, errors, signingSpecifications, includeChain)); }
private static void VerifyAuthorSignatureRequirements( SignerInfo signerInfo, SigningSpecifications signingSpecifications) { VerifySigningCertificateV2Attribute(signerInfo, signingSpecifications); VerifySigningTimeAttribute(signerInfo); }
internal static IReadOnlyList <X509Certificate2> GetTimestampCertificates( SignedCms signedCms, SigningSpecifications signingSpecifications, bool includeChain) { var errors = new Errors( noCertificate: NuGetLogCode.NU3020, noCertificateString: Strings.TimestampNoCertificate, invalidSignature: NuGetLogCode.NU3021, invalidSignatureString: Strings.TimestampInvalid, chainBuildingFailed: NuGetLogCode.NU3028); if (signedCms.SignerInfos.Count != 1) { throw new SignatureException(errors.InvalidSignature, errors.InvalidSignatureString); } const bool isIssuerSerialRequired = false; return(GetCertificates( signedCms, signedCms.SignerInfos[0], SigningCertificateRequirement.EitherOrBoth, isIssuerSerialRequired, errors, signingSpecifications, includeChain)); }
private static void ValidateTimestampCms(SigningSpecifications spec, SignedCms timestampCms) { var signerInfo = timestampCms.SignerInfos[0]; try { signerInfo.CheckSignature(verifySignatureOnly: true); } catch (Exception e) { throw new TimestampException(NuGetLogCode.NU3021, Strings.TimestampSignatureValidationFailed, e); } if (!CertificateUtility.IsSignatureAlgorithmSupported(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3022, Strings.TimestampUnsupportedSignatureAlgorithm); } if (!CertificateUtility.IsCertificatePublicKeyValid(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3023, Strings.TimestampCertificateFailsPublicKeyLengthRequirement); } if (!spec.AllowedHashAlgorithmOids.Contains(signerInfo.DigestAlgorithm.Value)) { throw new TimestampException(NuGetLogCode.NU3024, Strings.TimestampUnsupportedSignatureAlgorithm); } if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3025, Strings.TimestampNotYetValid); } }
public TimestampRequest(SigningSpecifications signingSpecifications, byte[] hashedMessage, HashAlgorithmName hashAlgorithm, SignaturePlacement target) { SigningSpecifications = signingSpecifications ?? throw new ArgumentNullException(nameof(signingSpecifications)); HashedMessage = hashedMessage ?? throw new ArgumentNullException(nameof(hashedMessage)); HashAlgorithm = hashAlgorithm; Target = target; }
internal static IX509CertificateChain GetCertificateChain( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications, string signatureFriendlyName) { return(GetPrimarySignatureCertificates(signedCms, signerInfo, signingSpecifications, signatureFriendlyName, includeChain: false)); }
internal static IReadOnlyList <X509Certificate2> GetTimestampCertificates( SignedCms signedCms, SigningSpecifications signingSpecifications) { return(GetTimestampCertificates( signedCms, signingSpecifications, includeChain: false)); }
internal static IX509CertificateChain GetTimestampCertificates( SignedCms signedCms, SigningSpecifications signingSpecifications, string signatureFriendlyName) { return(GetTimestampCertificates( signedCms, signingSpecifications, signatureFriendlyName, includeChain: false)); }
/// <summary> /// Verify a signing-certificate-v2 attribute. /// </summary> public static bool IsValidSigningCertificateV2( X509Certificate2 signatureCertificate, IReadOnlyList <X509Certificate2> chain, CryptographicAttributeObject signingCertV2Attribute, SigningSpecifications signingSpecifications) { return(IsValidSigningCertificateV2( signatureCertificate: signatureCertificate, localCertificateChain: chain, attributeCertificateChain: GetESSCertIDv2Entries(signingCertV2Attribute), signingSpecifications: signingSpecifications)); }
/// <summary> /// Verify a signing-certificate-v2 attribute. /// </summary> public static bool IsValidSigningCertificateV2( X509Certificate2 signatureCertificate, X509Chain chain, CryptographicAttributeObject signingCertV2Attribute, SigningSpecifications signingSpecifications) { return(IsValidSigningCertificateV2( signatureCertificate: signatureCertificate, chain: SigningUtility.GetCertificateChain(chain), signingCertV2Attribute: signingCertV2Attribute, signingSpecifications: signingSpecifications)); }
private static IX509CertificateChain GetPrimarySignatureCertificates( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications, string signatureFriendlyName, bool includeChain) { if (signedCms == null) { throw new ArgumentNullException(nameof(signedCms)); } if (signerInfo == null) { throw new ArgumentNullException(nameof(signerInfo)); } var errors = new Errors( noCertificate: NuGetLogCode.NU3010, noCertificateString: string.Format(CultureInfo.CurrentCulture, Strings.Verify_ErrorNoCertificate, signatureFriendlyName), invalidSignature: NuGetLogCode.NU3011, invalidSignatureString: Strings.InvalidPrimarySignature, chainBuildingFailed: NuGetLogCode.NU3018); var signatureType = AttributeUtility.GetSignatureType(signerInfo.SignedAttributes); SigningCertificateRequirement signingCertificateRequirement; bool isIssuerSerialRequired; switch (signatureType) { case SignatureType.Author: case SignatureType.Repository: signingCertificateRequirement = SigningCertificateRequirement.OnlyV2; isIssuerSerialRequired = true; break; default: signingCertificateRequirement = SigningCertificateRequirement.NoRequirement; isIssuerSerialRequired = false; break; } return(GetCertificates( signedCms, signerInfo, signingCertificateRequirement, isIssuerSerialRequired, errors, signingSpecifications, includeChain)); }
/// <summary> /// Verify components of a signing-certificate-v2 attribute. /// </summary> public static bool IsValidSigningCertificateV2( X509Certificate2 signatureCertificate, IReadOnlyList <X509Certificate2> localCertificateChain, IReadOnlyList <KeyValuePair <Common.HashAlgorithmName, byte[]> > attributeCertificateChain, SigningSpecifications signingSpecifications) { // Verify chain counts to avoid unneeded hashing if (localCertificateChain.Count != attributeCertificateChain.Count || attributeCertificateChain.Count < 1) { return(false); } // Check each entry in the chain for (var i = 0; i < attributeCertificateChain.Count; i++) { var attributeEntry = attributeCertificateChain[i]; var localEntry = localCertificateChain[i]; // Verify hash algorithm is allowed if (!signingSpecifications.AllowedHashAlgorithmOids.Contains( attributeEntry.Key.ConvertToOidString(), StringComparer.Ordinal)) { return(false); } // Hash the local cert using the attribute hash algorithm var localValue = GetESSCertIDv2Entry(localEntry, attributeEntry.Key); // Verify the hashes match if (!VerifyHash(localValue, attributeEntry)) { return(false); } // Verify the first entry is the leaf cert used if (i == 0) { var leafHash = GetESSCertIDv2Entry(signatureCertificate, attributeEntry.Key); if (!VerifyHash(leafHash, attributeEntry)) { return(false); } } } return(true); }
private static void VerifySigningCertificate( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications) { var certificates = SignatureUtility.GetPrimarySignatureCertificates( signedCms, signerInfo, signingSpecifications); if (certificates == null || certificates.Count == 0) { ThrowForInvalidPrimarySignature(); } }
private static void VerifySigningCertificate( SignedCms signedCms, SignerInfo signerInfo, SigningSpecifications signingSpecifications) { using (var certificates = SignatureUtility.GetCertificateChain( signedCms, signerInfo, signingSpecifications, Strings.PrimarySignatureFriendlyName)) { if (certificates == null || certificates.Count == 0) { ThrowForInvalidPrimarySignature(); } } }
/// <summary> /// Load from a byte array. /// </summary> public static SignatureContent Load(byte[] bytes, SigningSpecifications signingSpecifications) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } if (signingSpecifications == null) { throw new ArgumentNullException(nameof(signingSpecifications)); } using (var ms = new MemoryStream(bytes)) { ms.Position = 0; return(Load(ms, signingSpecifications)); } }
public SignatureContent( SigningSpecifications signingSpecifications, HashAlgorithmName hashAlgorithm, string hashValue) { if (signingSpecifications == null) { throw new ArgumentNullException(nameof(signingSpecifications)); } if (string.IsNullOrEmpty(hashValue)) { throw new ArgumentException(Strings.StringCannotBeNullOrEmpty, nameof(hashValue)); } _signingSpecifications = signingSpecifications; HashAlgorithm = hashAlgorithm; HashValue = hashValue; }
private static void VerifySigningCertificateV2Attribute( SignerInfo signerInfo, SigningSpecifications signingSpecifications) { var attribute = signerInfo.SignedAttributes.GetAttributeOrDefault(Oids.SigningCertificateV2); if (attribute != null) { var entries = AttributeUtility.GetESSCertIDv2Entries(attribute); if (entries != null && entries.Count > 0) { if (entries.All( kvp => signingSpecifications.AllowedHashAlgorithmOids.Contains(kvp.Key.ConvertToOidString()))) { return; } } } ThrowForInvalidAuthorSignature(); }
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); }
private static void ValidateTimestampCms(SigningSpecifications spec, SignedCms timestampCms, IRfc3161TimestampToken timestampToken) { var signerInfo = timestampCms.SignerInfos[0]; try { signerInfo.CheckSignature(verifySignatureOnly: true); } catch (Exception e) { throw new TimestampException(NuGetLogCode.NU3021, Strings.SignError_TimestampSignatureValidationFailed, e); } if (signerInfo.Certificate == null) { throw new TimestampException(NuGetLogCode.NU3020, Strings.SignError_TimestampNoCertificate); } if (!CertificateUtility.IsSignatureAlgorithmSupported(signerInfo.Certificate)) { var certificateSignatureAlgorithm = GetNameOrOidString(signerInfo.Certificate.SignatureAlgorithm); var supportedSignatureAlgorithms = string.Join(", ", spec.AllowedSignatureAlgorithms); var errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.TimestampCertificateUnsupportedSignatureAlgorithm, certificateSignatureAlgorithm, supportedSignatureAlgorithms); throw new TimestampException(NuGetLogCode.NU3022, errorMessage); } if (!CertificateUtility.IsCertificatePublicKeyValid(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3023, Strings.SignError_TimestampCertificateFailsPublicKeyLengthRequirement); } if (!spec.AllowedHashAlgorithmOids.Contains(signerInfo.DigestAlgorithm.Value)) { var digestAlgorithm = GetNameOrOidString(signerInfo.DigestAlgorithm); var supportedSignatureAlgorithms = string.Join(", ", spec.AllowedHashAlgorithms); var errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.TimestampSignatureUnsupportedDigestAlgorithm, digestAlgorithm, supportedSignatureAlgorithms); throw new TimestampException(NuGetLogCode.NU3024, errorMessage); } if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3025, Strings.SignError_TimestampNotYetValid); } if (!CertificateUtility.IsDateInsideValidityPeriod(signerInfo.Certificate, timestampToken.TokenInfo.Timestamp)) { throw new TimestampException(NuGetLogCode.NU3036, Strings.SignError_TimestampGeneralizedTimeInvalid); } }
internal static bool IsTimestampValid(Timestamp timestamp, byte[] data, bool treatIssuesAsErrors, List <SignatureLog> issues, SigningSpecifications spec) { var isValid = true; var signerInfo = timestamp.SignerInfo; if (!timestamp.TstInfo.HasMessageHash(data)) { issues.Add(SignatureLog.Issue(treatIssuesAsErrors, NuGetLogCode.NU3019, Strings.TimestampIntegrityCheckFailed)); isValid = false; } 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; } 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); }
private static void ThrowIfSignatureFormatVersionIsUnsupported(Dictionary <string, string> properties, SigningSpecifications signingSpecifications) { const string Version = "Version"; string signatureFormatVersion; if (!properties.TryGetValue(Version, out signatureFormatVersion)) { throw new SignatureException(Strings.InvalidSignatureContent); } if (signingSpecifications.Version != signatureFormatVersion) { throw new SignatureException(NuGetLogCode.NU3007, Strings.UnsupportedSignatureFormatVersion); } }
private static IX509CertificateChain GetCertificates( SignedCms signedCms, SignerInfo signerInfo, SigningCertificateRequirement signingCertificateRequirement, bool isIssuerSerialRequired, Errors errors, SigningSpecifications signingSpecifications, bool includeChain) { if (signedCms == null) { throw new ArgumentNullException(nameof(signedCms)); } if (signingSpecifications == null) { throw new ArgumentNullException(nameof(signingSpecifications)); } if (signerInfo.Certificate == null) { throw new SignatureException(errors.NoCertificate, errors.NoCertificateString); } /* * The signing-certificate and signing-certificate-v2 attributes are described in RFC 2634 and RFC 5035. * * Timestamps * -------------------------------------------------- * RFC 3161 requires the signing-certificate attribute. The RFC 5816 update introduces the newer * signing-certificate-v2 attribute, which may replace or, for backwards compatibility, be present * alongside the older signing-certificate attribute. * * The issuerSerial field is not required, but should be validated if present. * * * Author and repository signatures * -------------------------------------------------- * RFC 5126 (CAdES) requires that exactly one of either of these attributes be present, and also requires that * the issuerSerial field be present. * * * Validation * -------------------------------------------------- * For author and repository signatures: * * the signing-certificate attribute must not be present * the signing-certificate-v2 attribute be present * the issuerSerial field must be present * * * References: * * "Signing Certificate Attribute Definition", RFC 2634 section 5.4 (https://tools.ietf.org/html/rfc2634#section-5.4) * "Certificate Identification", RFC 2634 section 5.4 (https://tools.ietf.org/html/rfc2634#section-5.4.1) * "Enhanced Security Services (ESS) Update: Adding CertID Algorithm Agility", RFC 5035 (https://tools.ietf.org/html/rfc5035) * "Request Format", RFC 3161 section 2.4.1 (https://tools.ietf.org/html/rfc3161#section-2.4.1) * "Signature of Time-Stamp Token", RFC 5816 section 2.2.1 (https://tools.ietf.org/html/rfc5816#section-2.2.1) * "Signing Certificate Reference Attributes", RFC 5126 section 5.7.3 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3) * "ESS signing-certificate Attribute Definition", RFC 5126 section 5.7.3.1 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3.1) * "ESS signing-certificate-v2 Attribute Definition", RFC 5126 section 5.7.3.2 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3.2) */ const string signingCertificateName = "signing-certificate"; const string signingCertificateV2Name = "signing-certificate-v2"; CryptographicAttributeObject signingCertificateAttribute = null; CryptographicAttributeObject signingCertificateV2Attribute = null; foreach (var attribute in signerInfo.SignedAttributes) { switch (attribute.Oid.Value) { case Oids.SigningCertificate: if (signingCertificateAttribute != null) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.MultipleAttributesDisallowed, signingCertificateName)); } if (attribute.Values.Count != 1) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeValueRequired, signingCertificateName)); } signingCertificateAttribute = attribute; break; case Oids.SigningCertificateV2: if (signingCertificateV2Attribute != null) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.MultipleAttributesDisallowed, signingCertificateV2Name)); } if (attribute.Values.Count != 1) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeValueRequired, signingCertificateV2Name)); } signingCertificateV2Attribute = attribute; break; } } switch (signingCertificateRequirement) { case SigningCertificateRequirement.OnlyV2: { if (signingCertificateAttribute != null) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateAttributeMustNotBePresent); } if (signingCertificateV2Attribute == null) { throw new SignatureException( errors.InvalidSignature, string.Format(CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeRequired, signingCertificateV2Name)); } } break; case SigningCertificateRequirement.EitherOrBoth: if (signingCertificateAttribute == null && signingCertificateV2Attribute == null) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV1OrV2AttributeMustBePresent); } break; } if (signingCertificateV2Attribute != null) { var reader = CreateDerSequenceReader(signingCertificateV2Attribute); var signingCertificateV2 = SigningCertificateV2.Read(reader); if (signingCertificateV2.Certificates.Count == 0) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2Invalid); } foreach (var essCertIdV2 in signingCertificateV2.Certificates) { if (!signingSpecifications.AllowedHashAlgorithmOids.Contains( essCertIdV2.HashAlgorithm.Algorithm.Value, StringComparer.Ordinal)) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2UnsupportedHashAlgorithm); } } if (!IsMatch(signerInfo.Certificate, signingCertificateV2.Certificates[0], errors, isIssuerSerialRequired)) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2CertificateNotFound); } } if (signingCertificateAttribute != null) { var reader = CreateDerSequenceReader(signingCertificateAttribute); var signingCertificate = SigningCertificate.Read(reader); if (signingCertificate.Certificates.Count == 0) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateInvalid); } if (!IsMatch(signerInfo.Certificate, signingCertificate.Certificates[0])) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateCertificateNotFound); } } var certificates = GetCertificateChain(signerInfo.Certificate, signedCms.Certificates, includeChain); if (certificates == null || certificates.Count == 0) { throw new SignatureException(errors.ChainBuildingFailed, Strings.CertificateChainBuildFailed); } return(certificates); }
internal static bool IsTimestampValid(Timestamp timestamp, byte[] messageHash, bool failIfInvalid, List <SignatureLog> issues, SigningSpecifications spec) { var isValid = true; if (!timestamp.TstInfo.HasMessageHash(messageHash)) { issues.Add(SignatureLog.Issue(failIfInvalid, NuGetLogCode.NU3019, Strings.TimestampIntegrityCheckFailed)); isValid = false; } if (!spec.AllowedHashAlgorithmOids.Contains(timestamp.SignerInfo.DigestAlgorithm.Value)) { issues.Add(SignatureLog.Issue(failIfInvalid, NuGetLogCode.NU3022, Strings.TimestampUnsupportedSignatureAlgorithm)); isValid = false; } if (IsCertificateValidityPeriodInTheFuture(timestamp.SignerInfo.Certificate)) { issues.Add(SignatureLog.Issue(failIfInvalid, NuGetLogCode.NU3025, Strings.TimestampNotYetValid)); isValid = false; } return(isValid); }
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); }
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); }