Skip to content

Commit

Permalink
Use the managed codec for basic constraints and remove entire X.509 e…
Browse files Browse the repository at this point in the history
…xtension PAL
  • Loading branch information
vcsjones authored Oct 8, 2024
1 parent 219126c commit f24eb8a
Show file tree
Hide file tree
Showing 19 changed files with 121 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,5 @@ internal static partial SafeX509ExtensionHandle X509ExtensionCreateByObj(
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509V3ExtPrint")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool X509V3ExtPrint(SafeBioHandle buf, SafeX509ExtensionHandle ext);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_DecodeX509BasicConstraints2Extension")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool DecodeX509BasicConstraints2Extension(
byte[] encoded,
int encodedLength,
[MarshalAs(UnmanagedType.Bool)] out bool certificateAuthority,
[MarshalAs(UnmanagedType.Bool)] out bool hasPathLengthConstraint,
out int pathLengthConstraint);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@
<Compile Include="System\Security\Cryptography\X509Certificates\CertificatePal.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\FindPal.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\LegacyBasicConstraintsDecoder.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\StorePal.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509CertificateLoader.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.NotSupported.cs" />
Expand Down Expand Up @@ -906,8 +907,8 @@
<Compile Include="System\Security\Cryptography\X509Certificates\CertificatePolicy.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\FindPal.OpenSsl.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\LegacyBasicConstraintsDecoder.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedCertificateFinder.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedX509ExtensionProcessor.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\OpenSslCachedDirectoryStoreProvider.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\OpenSslCachedSystemStoreProvider.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\OpenSslCertificateAssetDownloader.cs" />
Expand Down Expand Up @@ -1052,8 +1053,8 @@
<Compile Include="System\Security\Cryptography\X509Certificates\CertificatePolicy.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.Android.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\FindPal.Android.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\LegacyBasicConstraintsDecoder.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedCertificateFinder.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedX509ExtensionProcessor.cs" />
<Compile Include="System\Security\Cryptography\Shake128.NonWindows.cs" />
<Compile Include="System\Security\Cryptography\Shake256.NonWindows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\StorePal.Android.cs" />
Expand Down Expand Up @@ -1183,8 +1184,8 @@
<Compile Include="System\Security\Cryptography\X509Certificates\CertificatePolicy.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.Apple.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\FindPal.Apple.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\LegacyBasicConstraintsDecoder.NotSupported.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedCertificateFinder.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ManagedX509ExtensionProcessor.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\UnixChainVerifier.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\UnixExportProvider.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X500NameEncoder.cs" />
Expand Down Expand Up @@ -1784,6 +1785,7 @@
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.Windows.BuildChain.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\ChainPal.Windows.GetChainStatusInformation.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\FindPal.Windows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\LegacyBasicConstraintsDecoder.Windows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\SafeLocalAllocHandle.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\StorePal.Windows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\StorePal.Windows.Export.cs" />
Expand All @@ -1793,7 +1795,6 @@
<Compile Include="System\Security\Cryptography\X509Certificates\WindowsStructs.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509CertificateLoader.Windows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.Windows.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.Windows.CustomExtensions.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.Windows.GetCertContentType.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.Windows.PublicKey.cs" />
<Compile Include="System\Security\Cryptography\X509Certificates\X509Pal.Windows.X500DistinguishedName.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,5 @@ internal interface IX509Pal
string X500DistinguishedNameFormat(byte[] encodedDistinguishedName, bool multiLine);
X509ContentType GetCertContentType(ReadOnlySpan<byte> rawData);
X509ContentType GetCertContentType(string fileName);
bool SupportsLegacyBasicConstraintsExtension { get; }
byte[] EncodeX509BasicConstraints2Extension(bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint);
void DecodeX509BasicConstraintsExtension(byte[] encoded, out bool certificateAuthority, out bool hasPathLengthConstraint, out int pathLengthConstraint);
void DecodeX509BasicConstraints2Extension(byte[] encoded, out bool certificateAuthority, out bool hasPathLengthConstraint, out int pathLengthConstraint);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Security.Cryptography.X509Certificates
{
internal static class LegacyBasicConstraintsDecoder
{
internal static bool IsSupported => false;

internal static void DecodeX509BasicConstraintsExtension(
byte[] encoded,
out bool certificateAuthority,
out bool hasPathLengthConstraint,
out int pathLengthConstraint)
{
// No RFC nor ITU document describes the layout of the 2.5.29.10 structure,
// and OpenSSL doesn't have a decoder for it, either.
//
// Since it was never published as a standard (2.5.29.19 replaced it before publication)
// there shouldn't be too many people upset that we can't decode it for them on Unix.
throw new PlatformNotSupportedException(SR.NotSupported_LegacyBasicConstraints);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.InteropServices;
using Internal.Cryptography;

namespace System.Security.Cryptography.X509Certificates
{
internal static class LegacyBasicConstraintsDecoder
{
internal static bool IsSupported => true;

internal static void DecodeX509BasicConstraintsExtension(
byte[] encoded,
out bool certificateAuthority,
out bool hasPathLengthConstraint,
out int pathLengthConstraint)
{
unsafe
{
(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint) = encoded.DecodeObject(
CryptDecodeObjectStructType.X509_BASIC_CONSTRAINTS,
static delegate (void* pvDecoded, int cbDecoded)
{
Debug.Assert(cbDecoded >= sizeof(CERT_BASIC_CONSTRAINTS_INFO));
CERT_BASIC_CONSTRAINTS_INFO* pBasicConstraints = (CERT_BASIC_CONSTRAINTS_INFO*)pvDecoded;
return ((Marshal.ReadByte(pBasicConstraints->SubjectType.pbData) & CERT_BASIC_CONSTRAINTS_INFO.CERT_CA_SUBJECT_FLAG) != 0,
pBasicConstraints->fPathLenConstraint != 0,
pBasicConstraints->dwPathLenConstraint);
});
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace System.Security.Cryptography.X509Certificates
{
internal sealed class OpenSslX509Encoder : ManagedX509ExtensionProcessor, IX509Pal
internal sealed class OpenSslX509Encoder : IX509Pal
{
public ECDsa DecodeECDsaPublicKey(ICertificatePal? certificatePal)
{
Expand Down Expand Up @@ -152,23 +152,6 @@ public X509ContentType GetCertContentType(string fileName)
throw new CryptographicException();
}

public override void DecodeX509BasicConstraints2Extension(
byte[] encoded,
out bool certificateAuthority,
out bool hasPathLengthConstraint,
out int pathLengthConstraint)
{
if (!Interop.Crypto.DecodeX509BasicConstraints2Extension(
encoded,
encoded.Length,
out certificateAuthority,
out hasPathLengthConstraint,
out pathLengthConstraint))
{
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
}

private static RSAOpenSsl BuildRsaPublicKey(byte[] encodedData)
{
var rsa = new RSAOpenSsl();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Formats.Asn1;
using System.Security.Cryptography.X509Certificates.Asn1;

namespace System.Security.Cryptography.X509Certificates
{
public sealed class X509BasicConstraintsExtension : X509Extension
Expand Down Expand Up @@ -111,19 +114,63 @@ private static byte[] EncodeExtension(bool certificateAuthority, bool hasPathLen
ArgumentOutOfRangeException.ThrowIfNegative(pathLengthConstraint);
}

return X509Pal.Instance.EncodeX509BasicConstraints2Extension(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint);
return EncodeX509BasicConstraints2Extension(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint);
}

private void DecodeExtension()
{
if (Oid!.Value == Oids.BasicConstraints)
X509Pal.Instance.DecodeX509BasicConstraintsExtension(RawData, out _certificateAuthority, out _hasPathLenConstraint, out _pathLenConstraint);
{
LegacyBasicConstraintsDecoder.DecodeX509BasicConstraintsExtension(
RawData,
out _certificateAuthority,
out _hasPathLenConstraint,
out _pathLenConstraint);
}
else
X509Pal.Instance.DecodeX509BasicConstraints2Extension(RawData, out _certificateAuthority, out _hasPathLenConstraint, out _pathLenConstraint);
{
DecodeX509BasicConstraints2Extension(
RawData,
out _certificateAuthority,
out _hasPathLenConstraint,
out _pathLenConstraint);
}

_decoded = true;
}

private static byte[] EncodeX509BasicConstraints2Extension(
bool certificateAuthority,
bool hasPathLengthConstraint,
int pathLengthConstraint)
{
BasicConstraintsAsn constraints = default;

constraints.CA = certificateAuthority;

if (hasPathLengthConstraint)
{
constraints.PathLengthConstraint = pathLengthConstraint;
}

// Largest possible encoded extension is 11 bytes when pathLenConstraint is int.MaxValue.
AsnWriter writer = new AsnWriter(AsnEncodingRules.DER, initialCapacity: 11);
constraints.Encode(writer);
return writer.Encode();
}

private static void DecodeX509BasicConstraints2Extension(
byte[] encoded,
out bool certificateAuthority,
out bool hasPathLengthConstraint,
out int pathLengthConstraint)
{
BasicConstraintsAsn constraints = BasicConstraintsAsn.Decode(encoded, AsnEncodingRules.BER);
certificateAuthority = constraints.CA;
hasPathLengthConstraint = constraints.PathLengthConstraint.HasValue;
pathLengthConstraint = constraints.PathLengthConstraint.GetValueOrDefault();
}

private bool _certificateAuthority;
private bool _hasPathLenConstraint;
private int _pathLenConstraint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,7 @@ private static X509Certificate2 ExtractKeyFromEncryptedPem<TAlg>(
internal static X509Extension? CreateCustomExtensionIfAny(string? oidValue) =>
oidValue switch
{
Oids.BasicConstraints => X509Pal.Instance.SupportsLegacyBasicConstraintsExtension ? new X509BasicConstraintsExtension() : null,
Oids.BasicConstraints => LegacyBasicConstraintsDecoder.IsSupported ? new X509BasicConstraintsExtension() : null,
Oids.BasicConstraints2 => new X509BasicConstraintsExtension(),
Oids.KeyUsage => new X509KeyUsageExtension(),
Oids.EnhancedKeyUsage => new X509EnhancedKeyUsageExtension(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private static partial IX509Pal BuildSingleton()
return new AndroidX509Pal();
}

private sealed partial class AndroidX509Pal : ManagedX509ExtensionProcessor, IX509Pal
private sealed partial class AndroidX509Pal : IX509Pal
{
public ECDsa DecodeECDsaPublicKey(ICertificatePal? certificatePal)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace System.Security.Cryptography.X509Certificates
{
internal partial class X509Pal
{
private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal
private sealed partial class AppleX509Pal : IX509Pal
{
public ECDsa DecodeECDsaPublicKey(ICertificatePal? certificatePal)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace System.Security.Cryptography.X509Certificates
{
internal partial class X509Pal
{
private sealed partial class AppleX509Pal : ManagedX509ExtensionProcessor, IX509Pal
private sealed partial class AppleX509Pal : IX509Pal
{
public string X500DistinguishedNameDecode(byte[] encodedDistinguishedName, X500DistinguishedNameFlags flag)
{
Expand Down
Loading

0 comments on commit f24eb8a

Please sign in to comment.