I am currently working on generating a Certificate Request using CertificateEnrollmentManager from Windows.Security.Cryptography.Certificates. The CSR has been successfully generated but its extensions have different attributes than what I specified in the CertificateRequestProperties.
This is the request properties:
var basicConstraint = new CertificateExtension
{
ObjectId = Constants.Oids.BASIC_CONSTRAINT,
IsCritical = false,
Value = new BasicConstraints(false).GetEncoded()
};
var extendedKeyUsage = new CertificateExtension
{
ObjectId = Constants.Oids.EXTENDED_KEY_USAGE,
IsCritical = false,
Value = new ExtendedKeyUsage(
new[] {KeyPurposeID.IdKPClientAuth}
).GetEncoded()
};
var keyUsage = new CertificateExtension
{
ObjectId = Constants.Oids.KEY_USAGE,
IsCritical = false,
Value = new KeyUsage(KeyUsage.DigitalSignature).GetEncoded()
};
var certificateRequestProperties = new CertificateRequestProperties
{
Subject = subject,
KeyUsages = EnrollKeyUsages.Signing,
KeyStorageProviderName = microsoftPlatformCryptoProvider,
Exportable = ExportOption.NotExportable,
KeyProtectionLevel = keyProtectionLevel,
KeyAlgorithmName = keyAlgorithmName,
HashAlgorithmName = hashAlgorithmName,
FriendlyName = CERTIFICATE_FRIENDLY_NAME,
Extensions = {basicConstraint, extendedKeyUsage, keyUsage},
UseExistingKey = false
};
This is how I generate the SCR:
var csr = await CertificateEnrollmentManager.UserCertificateEnrollmentManager
.CreateRequestAsync(certificateRequestProperties);
The CSR is successfully generated but it generated the incorrect extensions:(Excluded some attributes for brevity)
BasicConstraints=ObjectId: 2.5.29.19 Criticality=true
ExtendedKeyUsage=ObjectId: 2.5.29.37 Criticality=false
KeyUsage=ObjectId: 2.5.29.15 Criticality=true
SubjectKeyIdentifier=ObjectId: 2.5.29.14 Criticality=false
What is wrong with the generated CSR:
- It has automatically added SubjectKeyIdentifier, but I only specified 3 extensions.
- The
criticality
is NOT as specified in the properties. I specified false, but it generated true.
My question is, how can I generate the CSR as I specified in the request properties?
PS:
- We can't just modify the received CSR on the server-side.
- I am required to use TPM (MicrosoftPlatformCryptoProvider) for the CSR so private keys are not exportable.