/// <summary> /// Load certificate and private key /// </summary> /// <param name="certificatePath"></param> /// <param name="certificateKeyPath"></param> /// <returns>Exported x509 Certificate</returns> public static X509Certificate2 LoadCertificateWithKey(string certificatePath, string certificateKeyPath, string password) { using var rsa = RSA.Create(); var keyPem = File.ReadAllText(certificateKeyPath); var keyDer = CertificateHelper.UnPem(keyPem); rsa.ImportPkcs8PrivateKey(keyDer, out _); var certNoKey = new X509Certificate2(certificatePath); var pfxData = certNoKey.CopyWithPrivateKey(rsa).Export(X509ContentType .Pfx); if (string.IsNullOrEmpty(password)) { return(new X509Certificate2(pfxData)); } else { return(new X509Certificate2(pfxData, password)); } }
private X509Certificate2 GetTlsCertificate() { X509Certificate2 cert = null; log.Information("TLS mode: {TLSMode}", serverOptions.CurrentValue.TlsMode); if (serverOptions.CurrentValue.TlsMode != TlsMode.None) { if (!string.IsNullOrEmpty(serverOptions.CurrentValue.TlsCertificate)) { var pfxPassword = serverOptions.CurrentValue.TlsCertificatePassword ?? ""; if (string.IsNullOrEmpty(serverOptions.CurrentValue.TlsCertificatePrivateKey)) { cert = CertificateHelper.LoadCertificate(serverOptions.CurrentValue.TlsCertificate, pfxPassword); } else { cert = CertificateHelper.LoadCertificateWithKey(serverOptions.CurrentValue.TlsCertificate, serverOptions.CurrentValue.TlsCertificatePrivateKey, pfxPassword); } log.Information("Using provided certificate with Subject {SubjectName}, expiry {ExpiryDate}", cert.SubjectName.Name, cert.GetExpirationDateString()); } else { string pfxPath = Path.GetFullPath("selfsigned-certificate.pfx"); string cerPath = Path.GetFullPath("selfsigned-certificate.cer"); if (File.Exists(pfxPath)) { cert = new X509Certificate2(File.ReadAllBytes(pfxPath), "", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); if (cert.Subject != $"CN={serverOptions.CurrentValue.HostName}" || DateTime.Parse(cert.GetExpirationDateString()) < DateTime.Now.AddDays(30)) { cert = null; } else { log.Information( "Using existing self-signed certificate with subject name {Hostname} and expiry date {ExpirationDate}", serverOptions.CurrentValue.HostName, cert.GetExpirationDateString()); } } if (cert == null) { cert = SSCertGenerator.CreateSelfSignedCertificate(serverOptions.CurrentValue.HostName); File.WriteAllBytes(pfxPath, cert.Export(X509ContentType.Pkcs12)); File.WriteAllBytes(cerPath, cert.Export(X509ContentType.Cert)); log.Information("Generated new self-signed certificate with subject name '{Hostname} and expiry date {ExpirationDate}", serverOptions.CurrentValue.HostName, cert.GetExpirationDateString()); } log.Information( "Ensure that the hostname you enter into clients and '{Hostname}' from ServerOptions:HostName configuration match exactly and trust the issuer certificate at {cerPath} in your client/OS to avoid certificate validation errors.", serverOptions.CurrentValue.HostName, cerPath); } } return(cert); }