Skip to content

Commit 761f774

Browse files
authored
Add the ability to load a PKCS10 into CertificateRequest
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.
1 parent 5ed2442 commit 761f774

File tree

20 files changed

+2163
-104
lines changed

20 files changed

+2163
-104
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Formats.Asn1;
5+
using Internal.Cryptography;
6+
7+
namespace System.Security.Cryptography.Asn1
8+
{
9+
internal partial struct PssParamsAsn
10+
{
11+
internal RSASignaturePadding GetSignaturePadding(
12+
int? digestValueLength = null)
13+
{
14+
if (TrailerField != 1)
15+
{
16+
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
17+
}
18+
19+
if (MaskGenAlgorithm.Algorithm != Oids.Mgf1)
20+
{
21+
throw new CryptographicException(
22+
SR.Cryptography_Pkcs_PssParametersMgfNotSupported,
23+
MaskGenAlgorithm.Algorithm);
24+
}
25+
26+
if (MaskGenAlgorithm.Parameters == null)
27+
{
28+
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
29+
}
30+
31+
AlgorithmIdentifierAsn mgfParams = AlgorithmIdentifierAsn.Decode(
32+
MaskGenAlgorithm.Parameters.Value,
33+
AsnEncodingRules.DER);
34+
35+
if (mgfParams.Algorithm != HashAlgorithm.Algorithm)
36+
{
37+
throw new CryptographicException(
38+
SR.Format(
39+
SR.Cryptography_Pkcs_PssParametersMgfHashMismatch,
40+
mgfParams.Algorithm,
41+
HashAlgorithm.Algorithm));
42+
}
43+
44+
int saltSize = digestValueLength.GetValueOrDefault();
45+
46+
if (!digestValueLength.HasValue)
47+
{
48+
saltSize = Helpers.HashOidToByteLength(HashAlgorithm.Algorithm);
49+
}
50+
51+
if (SaltLength != saltSize)
52+
{
53+
throw new CryptographicException(
54+
SR.Format(
55+
SR.Cryptography_Pkcs_PssParametersSaltMismatch,
56+
SaltLength,
57+
HashAlgorithm.Algorithm));
58+
}
59+
60+
// When RSASignaturePadding supports custom salt sizes this return will look different.
61+
return RSASignaturePadding.Pss;
62+
}
63+
}
64+
}

src/libraries/Common/src/System/Security/Cryptography/Helpers.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,19 @@ internal static bool TryCopyToDestination(this ReadOnlySpan<byte> source, Span<b
6464
bytesWritten = 0;
6565
return false;
6666
}
67+
68+
internal static int HashOidToByteLength(string hashOid)
69+
{
70+
// This file is compiled in netstandard2.0, can't use the HashSizeInBytes consts.
71+
return hashOid switch
72+
{
73+
Oids.Sha256 => 256 >> 3,
74+
Oids.Sha384 => 384 >> 3,
75+
Oids.Sha512 => 512 >> 3,
76+
Oids.Sha1 => 160 >> 3,
77+
Oids.Md5 => 128 >> 3,
78+
_ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashOid)),
79+
};
80+
}
6781
}
6882
}

src/libraries/Common/src/System/Security/Cryptography/PemLabels.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ internal static class PemLabels
1414
internal const string X509Certificate = "CERTIFICATE";
1515
internal const string Pkcs7Certificate = "PKCS7";
1616
internal const string X509CertificateRevocationList = "X509 CRL";
17+
internal const string Pkcs10CertificateRequest = "CERTIFICATE REQUEST";
1718
}
1819
}

src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ System.Security.Cryptography.Pkcs.EnvelopedCms</PackageDescription>
415415
<AsnXml Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.xml">
416416
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</Link>
417417
</AsnXml>
418+
<Compile Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.manual.cs">
419+
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.manual.cs</Link>
420+
<DependentUpon>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</DependentUpon>
421+
</Compile>
418422
<Compile Include="$(CommonPath)System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs">
419423
<Link>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml.cs</Link>
420424
<DependentUpon>Common\System\Security\Cryptography\Asn1\PssParamsAsn.xml</DependentUpon>

src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -309,47 +309,8 @@ protected override RSASignaturePadding GetSignaturePadding(
309309
digestAlgorithmOid));
310310
}
311311

312-
if (pssParams.TrailerField != 1)
313-
{
314-
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
315-
}
316-
317-
if (pssParams.SaltLength != digestValueLength)
318-
{
319-
throw new CryptographicException(
320-
SR.Format(
321-
SR.Cryptography_Pkcs_PssParametersSaltMismatch,
322-
pssParams.SaltLength,
323-
digestAlgorithmName.Name));
324-
}
325-
326-
if (pssParams.MaskGenAlgorithm.Algorithm != Oids.Mgf1)
327-
{
328-
throw new CryptographicException(
329-
SR.Cryptography_Pkcs_PssParametersMgfNotSupported,
330-
pssParams.MaskGenAlgorithm.Algorithm);
331-
}
332-
333-
if (pssParams.MaskGenAlgorithm.Parameters == null)
334-
{
335-
throw new CryptographicException(SR.Cryptography_Pkcs_InvalidSignatureParameters);
336-
}
337-
338-
AlgorithmIdentifierAsn mgfParams = AlgorithmIdentifierAsn.Decode(
339-
pssParams.MaskGenAlgorithm.Parameters.Value,
340-
AsnEncodingRules.DER);
341-
342-
if (mgfParams.Algorithm != digestAlgorithmOid)
343-
{
344-
throw new CryptographicException(
345-
SR.Format(
346-
SR.Cryptography_Pkcs_PssParametersMgfHashMismatch,
347-
mgfParams.Algorithm,
348-
digestAlgorithmOid));
349-
}
350-
351-
// When RSASignaturePadding supports custom salt sizes this return will look different.
352-
return RSASignaturePadding.Pss;
312+
RSASignaturePadding padding = pssParams.GetSignaturePadding(digestValueLength);
313+
return padding;
353314
}
354315

355316
protected override bool Sign(

0 commit comments

Comments
 (0)