From 13481b818862f9448fab02068ae5e835eafd495b Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Sat, 27 Apr 2019 11:48:52 -0700 Subject: [PATCH] Ensure that invalid AIA, CDP, and OCSP extensions don't throw. (dotnet/corefx#37237) Commit migrated from https://github.com/dotnet/corefx/commit/a3ee315cd5e4f4d3ce8fb60a24aa8bd0c9c9ae82 --- .../src/Internal/Cryptography/Pal.Unix/CrlCache.cs | 8 +++-- .../Pal.Unix/OpenSslX509ChainProcessor.cs | 31 +++++++++------- .../tests/DynamicChainTests.cs | 42 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs index 72c2409..3192bd6 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs @@ -237,13 +237,17 @@ namespace Internal.Cryptography.Pal } } } - - return null; + } + catch (CryptographicException) + { + // Treat any ASN errors as if the extension was missing. } finally { ArrayPool.Shared.Return(crlDistributionPoints.Array); } + + return null; } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs index 8689668..e353b16 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs @@ -848,24 +848,31 @@ namespace Internal.Cryptography.Pal private static string FindHttpAiaRecord(ReadOnlyMemory authorityInformationAccess, string recordTypeOid) { - AsnReader reader = new AsnReader(authorityInformationAccess, AsnEncodingRules.DER); - AsnReader sequenceReader = reader.ReadSequence(); - reader.ThrowIfNotEmpty(); - - while (sequenceReader.HasData) + try { - AccessDescriptionAsn.Decode(sequenceReader, out AccessDescriptionAsn description); - if (StringComparer.Ordinal.Equals(description.AccessMethod, recordTypeOid)) + AsnReader reader = new AsnReader(authorityInformationAccess, AsnEncodingRules.DER); + AsnReader sequenceReader = reader.ReadSequence(); + reader.ThrowIfNotEmpty(); + + while (sequenceReader.HasData) { - GeneralNameAsn name = description.AccessLocation; - if (name.Uri != null && - Uri.TryCreate(name.Uri, UriKind.Absolute, out Uri uri) && - uri.Scheme == "http") + AccessDescriptionAsn.Decode(sequenceReader, out AccessDescriptionAsn description); + if (StringComparer.Ordinal.Equals(description.AccessMethod, recordTypeOid)) { - return name.Uri; + GeneralNameAsn name = description.AccessLocation; + if (name.Uri != null && + Uri.TryCreate(name.Uri, UriKind.Absolute, out Uri uri) && + uri.Scheme == "http") + { + return name.Uri; + } } } } + catch (CryptographicException) + { + // Treat any ASN errors as if the extension was missing. + } return null; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs index 1ee948e..a96d80b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/DynamicChainTests.cs @@ -200,6 +200,48 @@ namespace System.Security.Cryptography.X509Certificates.Tests } } + [Fact] + public static void TestInvalidAia() + { + using (RSA key = RSA.Create()) + { + CertificateRequest rootReq = new CertificateRequest( + "CN=Root", + key, + HashAlgorithmName.SHA256, + RSASignaturePadding.Pkcs1); + + rootReq.CertificateExtensions.Add( + new X509BasicConstraintsExtension(true, false, 0, true)); + + CertificateRequest certReq = new CertificateRequest( + "CN=test", + key, + HashAlgorithmName.SHA256, + RSASignaturePadding.Pkcs1); + + certReq.CertificateExtensions.Add( + new X509BasicConstraintsExtension(false, false, 0, false)); + + certReq.CertificateExtensions.Add( + new X509Extension( + "1.3.6.1.5.5.7.1.1", + new byte[] { 5 }, + critical: false)); + + DateTimeOffset notBefore = DateTimeOffset.UtcNow.AddDays(-1); + DateTimeOffset notAfter = notBefore.AddDays(30); + + using (X509Certificate2 root = rootReq.CreateSelfSigned(notBefore, notAfter)) + using (X509Certificate2 ee = certReq.Create(root, notBefore, notAfter, root.GetSerialNumber())) + { + X509Chain chain = new X509Chain(); + Assert.False(chain.Build(ee)); + Assert.Equal(1, chain.ChainElements.Count); + } + } + } + private static X509Certificate2 TamperSignature(X509Certificate2 input) { byte[] cert = input.RawData; -- 2.7.4