Skip to content

Commit

Permalink
Add the ability to load a PKCS10 into CertificateRequest
Browse files Browse the repository at this point in the history
PKCS#10 CertificateRequest objects can now be loaded into the .NET CertificateRequest object form.

By default, the proof-of-key signature is validated during load.  Callers can disable the check if they think that is appropriate, such as when certifying a(n IFC) Diffie-Hellman key (as that algorithm cannot sign itself).

Another default behavior is that the extensions request attribute is ignored, other than being checked for structural validity.  Callers who wish to load the extensions request attribute are cautioned to inspect them before signing/completing the request, and in that case the requested extensions populate directly into the `CertificateExtensions` collection.

Any attributes from the request, such as the PKCS#9 ChallengePassword attribute, will populate the `OtherRequestAttributes` collection.  This collection does not filter out duplicates, or check that the attributes are valid per their OID.  And, since the collection populates on load, it's also respected on save.
  • Loading branch information
bartonjs authored Aug 3, 2022
1 parent 5ed2442 commit 761f774
Show file tree
Hide file tree
Showing 20 changed files with 2,163 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// 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 Internal.Cryptography;

namespace System.Security.Cryptography.Asn1
{
internal partial struct PssParamsAsn
{
internal RSASignaturePadding GetSignaturePadding(
int? digestValueLength = null)
{
if (TrailerField != 1)
{
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
}

if (MaskGenAlgorithm.Algorithm != Oids.Mgf1)
{
throw new CryptographicException(
SR.Cryptography_Pkcs_PssParametersMgfNotSupported,
MaskGenAlgorithm.Algorithm);
}

if (MaskGenAlgorithm.Parameters == null)
{
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
}

AlgorithmIdentifierAsn mgfParams = AlgorithmIdentifierAsn.Decode(
MaskGenAlgorithm.Parameters.Value,
AsnEncodingRules.DER);

if (mgfParams.Algorithm != HashAlgorithm.Algorithm)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_Pkcs_PssParametersMgfHashMismatch,
mgfParams.Algorithm,
HashAlgorithm.Algorithm));
}

int saltSize = digestValueLength.GetValueOrDefault();

if (!digestValueLength.HasValue)
{
saltSize = Helpers.HashOidToByteLength(HashAlgorithm.Algorithm);
}

if (SaltLength != saltSize)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_Pkcs_PssParametersSaltMismatch,
SaltLength,
HashAlgorithm.Algorithm));
}

// When RSASignaturePadding supports custom salt sizes this return will look different.
return RSASignaturePadding.Pss;
}
}
}
14 changes: 14 additions & 0 deletions src/libraries/Common/src/System/Security/Cryptography/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,19 @@ internal static bool TryCopyToDestination(this ReadOnlySpan<byte> source, Span<b
bytesWritten = 0;
return false;
}

internal static int HashOidToByteLength(string hashOid)
{
// This file is compiled in netstandard2.0, can't use the HashSizeInBytes consts.
return hashOid switch
{
Oids.Sha256 => 256 >> 3,
Oids.Sha384 => 384 >> 3,
Oids.Sha512 => 512 >> 3,
Oids.Sha1 => 160 >> 3,
Oids.Md5 => 128 >> 3,
_ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashOid)),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ internal static class PemLabels
internal const string X509Certificate = "CERTIFICATE";
internal const string Pkcs7Certificate = "PKCS7";
internal const string X509CertificateRevocationList = "X509 CRL";
internal const string Pkcs10CertificateRequest = "CERTIFICATE REQUEST";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ System.Security.Cryptography.Pkcs.EnvelopedCms</PackageDescription>
<AsnXml Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.xml">
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</Link>
</AsnXml>
<Compile Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.manual.cs">
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.manual.cs</Link>
<DependentUpon>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</DependentUpon>
</Compile>
<Compile Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs">
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs</Link>
<DependentUpon>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</DependentUpon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,47 +309,8 @@ protected override RSASignaturePadding GetSignaturePadding(
digestAlgorithmOid));
}

if (pssParams.TrailerField != 1)
{
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
}

if (pssParams.SaltLength != digestValueLength)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_Pkcs_PssParametersSaltMismatch,
pssParams.SaltLength,
digestAlgorithmName.Name));
}

if (pssParams.MaskGenAlgorithm.Algorithm != Oids.Mgf1)
{
throw new CryptographicException(
SR.Cryptography_Pkcs_PssParametersMgfNotSupported,
pssParams.MaskGenAlgorithm.Algorithm);
}

if (pssParams.MaskGenAlgorithm.Parameters == null)
{
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
}

AlgorithmIdentifierAsn mgfParams = AlgorithmIdentifierAsn.Decode(
pssParams.MaskGenAlgorithm.Parameters.Value,
AsnEncodingRules.DER);

if (mgfParams.Algorithm != digestAlgorithmOid)
{
throw new CryptographicException(
SR.Format(
SR.Cryptography_Pkcs_PssParametersMgfHashMismatch,
mgfParams.Algorithm,
digestAlgorithmOid));
}

// When RSASignaturePadding supports custom salt sizes this return will look different.
return RSASignaturePadding.Pss;
RSASignaturePadding padding = pssParams.GetSignaturePadding(digestValueLength);
return padding;
}

protected override bool Sign(
Expand Down
Loading

0 comments on commit 761f774

Please sign in to comment.