After update to .net core 3.0 (SDK 3.0.100-preview9-014004) we got a problem after generate self signed SSL-certificate.
We generate self signed certificate with start date and end date. But after generate, call method certificate.NotAfter leads to throw exception
System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation.
at Internal.Cryptography.Pal.OpenSslX509CertificateReader.ExtractValidityDateTime(IntPtr validityDatePtr)
at Internal.Cryptography.Pal.OpenSslX509CertificateReader.get_NotAfter()
at System.Security.Cryptography.X509Certificates.X509Certificate.GetNotAfter()
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_NotAfter().
When we used SDK 2.2 it worked correctly.
Generate certificate method:
{
var distinguishedName = new X500DistinguishedName($"CN={SslCertificate.DefaultCertName}");
var keySizeBits = 2048;
using (var rsa = RSA.Create(keySizeBits))
{
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var certificateKeyUsageExtension = new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment , false);
request.CertificateExtensions.Add(
certificateKeyUsageExtension);
var certificateServerValidationUsageExtension = new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false);
request.CertificateExtensions.Add(
certificateServerValidationUsageExtension);
var startCertificateDate = DateTime.UtcNow.AddDays(-1);
var endCertificateDate = DateTime.UtcNow.AddYears(50);
var certificate = request.CreateSelfSigned(startCertificateDate, endCertificateDate);
return certificate;
}
After call _request.CreateSelfSigned(startCertificateDate, endCertificateDate)_ we got a certificate, from which it is impossible to get an end date. Method _certificate.NotAfter_ thrown exception.
The problem appears only on linux (Ubuntu 18.04). On windows it works correclty.
Can you help? How can we fix this problem?
Quick guess: Something went wrong either in the encoding, or the decoding, of a NotAfter value beyond 2049. Trim in the endDate to not be 2050 or later.
If you can share a certificate which is exhibiting this problem that may be useful (though the generator is probably good enough for me to look at it in the morning).
Yes, i can share pfx file with certificate (empty password for open):
example_certificate.zip
I set 2049 year directly and it solved my problem. But after i set 2069 year directly and exception wasn't thrown also. After i found differnce between my cases. If we have milliseconds in our certificate end DateTime, then NotAfter throw exception.
var startCertificateDate = DateTime.UtcNow.AddDays(-1);
var correctEndCertificateDate = new DateTime(year: 2069, month: 9, day: 23, hour: 12, minute: 30, second: 35);
var correctCertificate = request.CreateSelfSigned(startCertificateDate, correctEndCertificateDate);
var incorrectEmdCertificateDate = new DateTime(year: 2069, month: 9, day: 23, hour: 12, minute: 30, second: 35, millisecond: 666);
var incorrectCertificate = request.CreateSelfSigned(startCertificateDate, incorrectEmdCertificateDate);
I solved my problem with cut off time from DateTime:
var endCertificateDate = DateTime.UtcNow.AddYears(50).Date;
Thanks!
Yep, looks like some code cleanup we did in 3.0 accidentally removed the part that trimmed the fractional seconds off of the DateTimeOffset for dates beyond 2049 UTC, and we must not have any tests for it.
The validity structure in this cert is
30 28 17 0D 31 39 30 39 32 32 30 37 33 34 35 35
5A 18 17 32 30 36 39 30 39 32 33 30 37 33 34 35
35 2E 32 37 35 35 31 30 31 5A
Or
asn.1
{
notBefore utcTime : "190922073455Z",
notAfter generalTime : "20690923073455.2755101Z"
}
And X.509 forbids the GeneralTime values from expressing fractional seconds.
4.1.2.5.2. GeneralizedTime
The generalized time type, GeneralizedTime, is a standard ASN.1 type
for variable precision representation of time. Optionally, the
GeneralizedTime field can include a representation of the time
differential between local and Greenwich Mean Time.For the purposes of this profile, GeneralizedTime values MUST be
expressed in Greenwich Mean Time (Zulu) and MUST include seconds
(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds
is zero. _GeneralizedTime values MUST NOT include fractional seconds._
(bold+italic emphasis mine)
fixed and ported