private static bool ValidateStrongChain(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter) { var signatureStrength = GetHashStrenghForComparison(signature.DigestAlgorithm.Value !); var strongShaChain = true; var leafCertificateSignatureAlgorithm = chain.ChainElements[0].Certificate.SignatureAlgorithm; var leafCertificateSignatureAlgorithmStrength = GetHashStrenghForComparison(leafCertificateSignatureAlgorithm.Value !); //We use count-1 because we don't want to validate the root certificate. for (var i = 0; i < chain.ChainElements.Count - 1; i++) { var element = chain.ChainElements[i]; var signatureAlgorithm = element.Certificate.SignatureAlgorithm; var certificateHashStrength = GetHashStrenghForComparison(signatureAlgorithm.Value !); if (certificateHashStrength < signatureStrength) { verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}."); strongShaChain = false; } //Check that all intermediates are at least as strong as the leaf. else if (certificateHashStrength < leafCertificateSignatureAlgorithmStrength) { verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}."); } } return(strongShaChain); }
internal unsafe AuthenticodeTimestampCmsSignature(AsnEncodedData data, ICmsSignature owningSignature) { OwningSignature = owningSignature; Kind = SignatureKind.AuthenticodeTimestamp; AdditionalCertificates = owningSignature.AdditionalCertificates; fixed(byte *dataPtr = data.RawData) { uint size = 0; if (Crypt32.CryptDecodeObjectEx(EncodingType.PKCS_7_ASN_ENCODING | EncodingType.X509_ASN_ENCODING, (IntPtr)500, new IntPtr(dataPtr), (uint)data.RawData.Length, CryptDecodeFlags.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, out var localBuffer, ref size)) { using (localBuffer) { var signerInfo = Marshal.PtrToStructure <CMSG_SIGNER_INFO>(localBuffer.DangerousGetHandle()); Signature = ReadBlob(signerInfo.EncryptedHash); DigestAlgorithm = new Oid(signerInfo.HashAlgorithm.pszObjId); HashEncryptionAlgorithm = new Oid(signerInfo.HashEncryptionAlgorithm.pszObjId); SerialNumber = ReadBlob(signerInfo.SerialNumber); UnsignedAttributes = ReadAttributes(signerInfo.UnauthAttrs); SignedAttributes = ReadAttributes(signerInfo.AuthAttrs); var subjectId = new UniversalSubjectIdentifier(signerInfo.Issuer, signerInfo.SerialNumber); if (subjectId.Type == SubjectIdentifierType.SubjectKeyIdentifier) { Certificate = FindCertificate((string)subjectId.Value, OwningSignature.AdditionalCertificates); } else if (subjectId.Type == SubjectIdentifierType.IssuerAndSerialNumber) { Certificate = FindCertificate((X509IssuerSerial)subjectId.Value, OwningSignature.AdditionalCertificates); } } }
internal AuthenticodeSignature(ICmsSignature cmsSignature) { if ((cmsSignature.Kind & SignatureKind.AnySignature) == 0) { throw new ArgumentException("The signature must be a root or nested signature.", nameof(cmsSignature)); } _cmsSignature = cmsSignature; }
private static bool ValidatEKUForChain(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter) { bool signingCertEKU = false; bool chainEKU = false; X509ExtensionCollection extensions = signature.Certificate.Extensions; foreach (X509Extension extension in extensions) { if (extension.Oid.FriendlyName == "Enhanced Key Usage") { signingCertEKU = true; //break; X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension; OidCollection oids = ext.EnhancedKeyUsages; EKUCritical = ext.Critical; foreach (Oid oid in oids) { //if (oid.Equals("1.3.6.1.5.5.7.3.3")) EKU_oidStr = oid.FriendlyName + "(" + oid.Value + ")" + ";" + EKU_oidStr; } Console.WriteLine(EKU_oidStr); } } string EKU = var signatureStrength = GetHashStrenghForComparison(signature.DigestAlgorithm.Value); var strongShaChain = true; var leafCertificateSignatureAlgorithm = chain.ChainElements[0].Certificate.SignatureAlgorithm; var leafCertificateSignatureAlgorithmStrength = GetHashStrenghForComparison(leafCertificateSignatureAlgorithm.Value); //We use count-1 because we don't want to validate the root certificate. for (var i = 0; i < chain.ChainElements.Count - 1; i++) { var element = chain.ChainElements[i]; var signatureAlgorithm = element.Certificate.SignatureAlgorithm; var certificateHashStrength = GetHashStrenghForComparison(signatureAlgorithm.Value); if (certificateHashStrength < signatureStrength) { verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}."); strongShaChain = false; } //Check that all intermediates are at least as strong as the leaf. else if (certificateHashStrength < leafCertificateSignatureAlgorithmStrength) { verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}."); } } return(strongShaChain); }
internal static IEnumerable <ICmsSignature> VisitAll(this ICmsSignature signature, SignatureKind kind, bool deep) { foreach (var nested in signature.GetNestedSignatures()) { if ((nested.Kind & kind) > 0) { yield return(nested); foreach (var nestVisit in nested.VisitAll(kind, deep)) { yield return(nestVisit); } } else if (deep) { foreach (var nestVisit in nested.VisitAll(kind, deep)) { yield return(nestVisit); } } } }
public static byte[]? SignatureDigest(this ICmsSignature signature) { return(signature.SignedAttributes .Cast <CryptographicAttributeObject>() .FirstOrDefault(s => s.Oid.Value == KnownOids.MessageDigest)?.Values[0].RawData); }
public override void LogSignatureMessage(ICmsSignature signature, string message) { var digestString = HashHelpers.GetHashForSignature(signature); Messages.Add($"Signature {digestString}: {message}"); }
public abstract void LogSignatureMessage(ICmsSignature signature, string message);
public override void LogSignatureMessage(ICmsSignature signature, string message) { }
protected abstract bool ValidateChain(ICmsSignature signer, X509Chain chain, SignatureLogger verboseWriter);
protected override bool ValidateChain(ICmsSignature signer, X509Chain chain, SignatureLogger verboseWriter) { return(ValidatEKUForChain(signer, chain, verboseWriter)); }
public static string GetHashForSignature(ICmsSignature signature) { var digest = signature.SignatureDigest(); return(digest.Aggregate(new StringBuilder(), (acc, b) => acc.AppendFormat("{0:x2}", b)).ToString()); }
public void Add(ICmsSignature signature) => _nestedSignatures.Add(signature);
private static TestResult ValidateBasicConstraints(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter) { var pass = false; Boolean BCCritical = false; int BC_extension = 0; Boolean BC_CA = false; Boolean hasPathLength = false; string KU = ""; int pathLength = 0; string issuer = ""; var leafCertificateSignatureAlgorithm = chain.ChainElements[0].Certificate.SignatureAlgorithm; //We use count-1 because we don't want to validate the root certificate. for (var i = 0; i < chain.ChainElements.Count - 1; i++) { var element = chain.ChainElements[i]; var signatureAlgorithm = element.Certificate.SignatureAlgorithm; issuer = element.Certificate.Issuer; X509ExtensionCollection extensions = element.Certificate.Extensions; BC_extension = 0; BC_CA = false; hasPathLength = false; pathLength = 0; KU = ""; foreach (X509Extension extension in extensions) { if (extension.Oid.FriendlyName == "Basic Constraints") { X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension; BCCritical = ext.Critical; BC_extension++; BC_CA = ext.CertificateAuthority; hasPathLength = ext.HasPathLengthConstraint; pathLength = ext.PathLengthConstraint; } } /* if (BC_extension == 0 && i>0) * { * Console.WriteLine(issuer); * Console.WriteLine("No BC."); * Console.WriteLine(KU); * Console.WriteLine(Program.appName); * Console.WriteLine("=================================================================="); * }*/ if (i == 0) { if (BC_extension == 1 && !BC_CA) { pass = true; } else if (BC_extension > 1) { verboseWriter.LogSignatureMessage(signature, $"Signature has duplicate Basic Constraints extension."); pass = false; } else if (BC_extension == 1 && BC_CA) { verboseWriter.LogSignatureMessage(signature, $"Signature has violating CA filed for Basic Constraints."); pass = false; } else { pass = false; } } else { verboseWriter.LogSignatureMessage(signature, $"Not a leaf certificate."); } } return(pass ? TestResult.Pass : TestResult.Fail); }
private protected TimestampSignature(ICmsSignature cmsSignature) { _cmsSignature = cmsSignature; }