Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 8b05acb

Browse files
committed
Convert ICertificatePal to use GetRSAPrivateKey instead of the PrivateKey property
1 parent a8f70ba commit 8b05acb

File tree

4 files changed

+12
-123
lines changed

4 files changed

+12
-123
lines changed

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/ICertificatePal.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace Internal.Cryptography
1212
internal interface ICertificatePal : IDisposable
1313
{
1414
bool HasPrivateKey { get; }
15-
AsymmetricAlgorithm PrivateKey { get; }
1615
IntPtr Handle { get; }
1716
string Issuer { get; }
1817
string Subject { get; }
@@ -31,12 +30,7 @@ internal interface ICertificatePal : IDisposable
3130
X500DistinguishedName SubjectName { get; }
3231
X500DistinguishedName IssuerName { get; }
3332
IEnumerable<X509Extension> Extensions { get; }
34-
35-
/// <summary>
36-
/// Set the private key object. The additional "publicKey" argument is used to validate that the private key corresponds to the existing publicKey.
37-
/// </summary>
38-
void SetPrivateKey(AsymmetricAlgorithm privateKey, AsymmetricAlgorithm publicKey);
39-
33+
RSA GetRSAPrivateKey();
4034
string GetNameInfo(X509NameType nameType, bool forIssuer);
4135
void AppendPrivateKeyInfo(StringBuilder sb);
4236
}

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509CertificateReader.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public bool HasPrivateKey
4040
get { return false; }
4141
}
4242

43-
public AsymmetricAlgorithm PrivateKey
44-
{
45-
get { return null; }
46-
}
47-
4843
public IntPtr Handle
4944
{
5045
get { return _cert == null ? IntPtr.Zero : _cert.DangerousGetHandle(); }
@@ -233,9 +228,9 @@ public IEnumerable<X509Extension> Extensions
233228
}
234229
}
235230

236-
public void SetPrivateKey(AsymmetricAlgorithm privateKey, AsymmetricAlgorithm publicKey)
231+
public RSA GetRSAPrivateKey()
237232
{
238-
throw new NotImplementedException();
233+
return null;
239234
}
240235

241236
public string GetNameInfo(X509NameType nameType, bool forIssuer)

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs

Lines changed: 8 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,11 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5-
using System.Text;
6-
using System.Diagnostics;
7-
using System.Globalization;
85
using System.Runtime.InteropServices;
6+
using System.Security.Cryptography;
97

10-
using Internal.NativeCrypto;
11-
using Internal.Cryptography;
128
using Internal.Cryptography.Pal.Native;
139

14-
using FILETIME = Internal.Cryptography.Pal.Native.FILETIME;
15-
16-
using CryptographicUnexpectedOperationException = System.Security.Cryptography.CryptographicException;
17-
18-
using System.Security.Cryptography;
19-
using System.Security.Cryptography.X509Certificates;
20-
2110
namespace Internal.Cryptography.Pal
2211
{
2312
internal sealed partial class CertificatePal : IDisposable, ICertificatePal
@@ -30,104 +19,15 @@ public bool HasPrivateKey
3019
}
3120
}
3221

33-
public AsymmetricAlgorithm PrivateKey
22+
public RSA GetRSAPrivateKey()
3423
{
35-
get
36-
{
37-
CspParameters cspParameters = GetPrivateKey();
38-
if (cspParameters == null)
39-
return null;
40-
41-
// We never want to stomp over certificate private keys.
42-
cspParameters.Flags |= CspProviderFlags.UseExistingKey;
43-
44-
int algId = OidInfo.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, KeyAlgorithm, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId;
45-
switch (algId)
46-
{
47-
case AlgId.CALG_RSA_KEYX:
48-
case AlgId.CALG_RSA_SIGN:
49-
return new RSACryptoServiceProvider(cspParameters);
50-
51-
case AlgId.CALG_DSS_SIGN:
52-
return new DSACryptoServiceProvider(cspParameters);
53-
54-
default:
55-
throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
56-
}
57-
}
58-
}
24+
CspParameters cspParameters = GetPrivateKey();
25+
if (cspParameters == null)
26+
return null;
5927

60-
/// <summary>
61-
/// Set the private key object. The additional "publicKey" argument is used to validate that the private key corresponds to the existing publicKey.
62-
/// </summary>
63-
public void SetPrivateKey(AsymmetricAlgorithm privateKey, AsymmetricAlgorithm publicKey)
64-
{
65-
if (privateKey == null)
66-
{
67-
unsafe
68-
{
69-
if (!Interop.crypt32.CertSetCertificateContextProperty(_certContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, CertSetPropertyFlags.None, (CRYPT_KEY_PROV_INFO*)null))
70-
throw new CryptographicException(Marshal.GetLastWin32Error());
71-
}
72-
}
73-
else
74-
{
75-
// we do not support keys in non-CAPI storage for now.
76-
ICspAsymmetricAlgorithm asymmetricAlgorithm = privateKey as ICspAsymmetricAlgorithm;
77-
if (asymmetricAlgorithm == null)
78-
throw new NotSupportedException(SR.NotSupported_InvalidKeyImpl);
79-
if (asymmetricAlgorithm.CspKeyContainerInfo == null)
80-
throw new ArgumentException("CspKeyContainerInfo");
81-
82-
// check that the public key in the certificate corresponds to the private key passed in.
83-
//
84-
// note that it should be legal to set a key which matches in every aspect but the usage
85-
// i.e. to use a CALG_RSA_KEYX private key to match a CALG_RSA_SIGN public key. A
86-
// PUBLICKEYBLOB is defined as:
87-
//
88-
// BLOBHEADER publickeystruc
89-
// RSAPUBKEY rsapubkey
90-
// BYTE modulus[rsapubkey.bitlen/8]
91-
//
92-
// To allow keys which differ by key usage only, we skip over the BLOBHEADER of the key,
93-
// and start comparing bytes at the RSAPUBKEY structure.
94-
unsafe
95-
{
96-
// This cast is safe because via our contract with our caller, "publicKey" is the Key property of a PublicKey object that this Pal class manufactured in the first place.
97-
// Since we manufactured the PublicKey, we know the real types of the object.
98-
ICspAsymmetricAlgorithm cspPublicKey = (ICspAsymmetricAlgorithm)publicKey;
99-
byte[] array1 = cspPublicKey.ExportCspBlob(false);
100-
byte[] array2 = asymmetricAlgorithm.ExportCspBlob(false);
101-
if (array1 == null || array2 == null || array1.Length != array2.Length || array1.Length <= sizeof(BLOBHEADER))
102-
throw new CryptographicUnexpectedOperationException(SR.Cryptography_X509_KeyMismatch);
103-
for (int index = sizeof(BLOBHEADER); index < array1.Length; index++)
104-
{
105-
if (array1[index] != array2[index])
106-
throw new CryptographicUnexpectedOperationException(SR.Cryptography_X509_KeyMismatch);
107-
}
108-
}
109-
110-
unsafe
111-
{
112-
CspKeyContainerInfo keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo;
113-
fixed (char* pKeyContainerName = keyContainerInfo.KeyContainerName, pProviderName = keyContainerInfo.ProviderName)
114-
{
115-
CRYPT_KEY_PROV_INFO keyProvInfo = new CRYPT_KEY_PROV_INFO()
116-
{
117-
pwszContainerName = pKeyContainerName,
118-
pwszProvName = pProviderName,
119-
dwProvType = keyContainerInfo.ProviderType,
120-
dwFlags = keyContainerInfo.MachineKeyStore ? CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : CryptAcquireContextFlags.None,
121-
cProvParam = 0,
122-
rgProvParam = IntPtr.Zero,
123-
dwKeySpec = (int)(keyContainerInfo.KeyNumber),
124-
};
125-
126-
if (!Interop.crypt32.CertSetCertificateContextProperty(_certContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, CertSetPropertyFlags.None, &keyProvInfo))
127-
throw new CryptographicException(Marshal.GetLastWin32Error());
128-
}
129-
}
130-
}
28+
// We never want to stomp over certificate private keys.
29+
cspParameters.Flags |= CspProviderFlags.UseExistingKey;
30+
return new RSACryptoServiceProvider(cspParameters);
13131
}
13232

13333
private CspParameters GetPrivateKey()

src/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/RSACertificateExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static RSA GetRSAPrivateKey(this X509Certificate2 certificate)
5252

5353
// When the CNG contract comes online this needs to return an RsaCng on Windows, unless CNG reports
5454
// an error, then try falling back to CAPI (for CAPI-only smartcards).
55-
return (RSA)certificate.Pal.PrivateKey;
55+
return certificate.Pal.GetRSAPrivateKey();
5656
}
5757

5858
private static bool IsRSA(X509Certificate2 certificate)

0 commit comments

Comments
 (0)