Skip to content

Commit a3a282e

Browse files
committed
Change certificate strength check.
The Certificate strength check no longer mandates SHA2, rather it cares that the certs digest algorithm is greater or equal to the file digest algorithm, and that all intermediates are as strong as the leaf.
1 parent e6aeef3 commit a3a282e

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

AuthenticodeLint/Rules/SigningCertificateDigestAlgorithmRule.cs

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,72 @@ public class SigningCertificateDigestAlgorithmRule : CertificateChainRuleBase
77
{
88
public override int RuleId { get; } = 10006;
99

10-
public override string RuleName { get; } = "SHA2 Certificate Chain";
10+
public override string RuleName { get; } = "Strong Certificate Chain";
1111

1212
public override string ShortDescription { get; } = "Checks the signing certificate's and chain's signature algorithm.";
1313

1414
protected override bool ValidateChain(Signature signer, X509Chain chain, SignatureLogger verboseWriter)
1515
{
16-
return ValidateSha2Chain(signer.SignerInfo, chain, verboseWriter);
16+
return ValidateStrongChain(signer.SignerInfo, chain, verboseWriter);
1717
}
1818

19-
private static bool ValidateSha2Chain(SignerInfo signatureInfo, X509Chain chain, SignatureLogger verboseWriter)
19+
private static bool ValidateStrongChain(SignerInfo signatureInfo, X509Chain chain, SignatureLogger verboseWriter)
2020
{
21-
var strongSha2Chain = true;
22-
//We use count-1 because we don't want to validate SHA2 on the root certificate.
23-
for(var i = 0; i < chain.ChainElements.Count-1; i++)
21+
var signatureStrength = GetHashStrenghForComparison(signatureInfo.DigestAlgorithm.Value);
22+
var strongShaChain = true;
23+
var leafCertificateSignatureAlgorithm = chain.ChainElements[0].Certificate.SignatureAlgorithm;
24+
var leafCertificateSignatureAlgorithmStrength = GetHashStrenghForComparison(leafCertificateSignatureAlgorithm.Value);
25+
//We use count-1 because we don't want to validate the root certificate.
26+
for (var i = 0; i < chain.ChainElements.Count - 1; i++)
2427
{
2528
var element = chain.ChainElements[i];
2629
var signatureAlgorithm = element.Certificate.SignatureAlgorithm;
27-
switch (signatureAlgorithm.Value)
30+
var certificateHashStrength = GetHashStrenghForComparison(signatureAlgorithm.Value);
31+
if (certificateHashStrength < signatureStrength)
2832
{
29-
case KnownOids.sha256ECDSA:
30-
case KnownOids.sha384ECDSA:
31-
case KnownOids.sha512ECDSA:
32-
case KnownOids.sha256RSA:
33-
case KnownOids.sha384RSA:
34-
case KnownOids.sha512RSA:
35-
continue;
36-
default:
37-
verboseWriter.LogSignatureMessage(signatureInfo, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of SHA2.");
38-
strongSha2Chain = false;
39-
break;
33+
verboseWriter.LogSignatureMessage(signatureInfo, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signatureInfo.DigestAlgorithm.FriendlyName}.");
34+
strongShaChain = false;
4035
}
36+
//Check that all intermediates are at least as strong as the leaf.
37+
else if (certificateHashStrength < leafCertificateSignatureAlgorithmStrength)
38+
{
39+
verboseWriter.LogSignatureMessage(signatureInfo, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signatureInfo.DigestAlgorithm.FriendlyName}.");
40+
}
41+
}
42+
return strongShaChain;
43+
}
44+
45+
//Returns a value for comparison. These values are not intended to be a bit size, but only used for comparing
46+
//angainst other values.
47+
private static int GetHashStrenghForComparison(string oid)
48+
{
49+
switch (oid)
50+
{
51+
case KnownOids.MD2:
52+
return 2;
53+
case KnownOids.MD4:
54+
return 4;
55+
case KnownOids.MD5:
56+
return 5;
57+
case KnownOids.SHA1:
58+
case KnownOids.sha1ECDSA:
59+
case KnownOids.sha1RSA:
60+
return 10;
61+
case KnownOids.SHA256:
62+
case KnownOids.sha256ECDSA:
63+
case KnownOids.sha256RSA:
64+
return 256;
65+
case KnownOids.SHA384:
66+
case KnownOids.sha384ECDSA:
67+
case KnownOids.sha384RSA:
68+
return 384;
69+
case KnownOids.SHA512:
70+
case KnownOids.sha512ECDSA:
71+
case KnownOids.sha512RSA:
72+
return 512;
73+
default:
74+
return 0;
4175
}
42-
return strongSha2Chain;
4376
}
4477
}
4578
}

0 commit comments

Comments
 (0)