public string GetCertificate(AcmeClient client) { IdnMapping idn = new IdnMapping(); var dnsIdentifier = idn.GetAscii(config.Host); CertificateProvider.RegisterProvider <BouncyCastleProvider>(BouncyCastleProvider.PROVIDER_NAME); var cp = CertificateProvider.GetProvider(BouncyCastleProvider.PROVIDER_NAME); var rsaPkp = new RsaPrivateKeyParams(); try { if (config.RSAKeyLength >= 1024) { rsaPkp.NumBits = config.RSAKeyLength; Trace.TraceInformation("RSAKeyBits: {0}", config.RSAKeyLength); } else { Trace.TraceWarning("RSA Key Bits less than 1024 is not secure. Letting ACMESharp default key bits. http://openssl.org/docs/manmaster/crypto/RSA_generate_key_ex.html"); } } catch (Exception ex) { Trace.TraceWarning("Unable to set RSA Key Bits, Letting ACMESharp default key bits, Error: {0}", ex); Console.WriteLine($"Unable to set RSA Key Bits, Letting ACMESharp default key bits, Error: {ex.Message.ToString()}"); } var rsaKeys = cp.GeneratePrivateKey(rsaPkp); var csrDetails = new CsrDetails { CommonName = dnsIdentifier, }; if (config.AlternateNames != null) { if (config.AlternateNames.Count > 0) { csrDetails.AlternativeNames = config.AlternateNames.Select(s => idn.GetAscii(s)); } } var csrParams = new CsrParams { Details = csrDetails, }; var csr = cp.GenerateCsr(csrParams, rsaKeys, Crt.MessageDigest.SHA256); byte[] derRaw; using (var bs = new MemoryStream()) { cp.ExportCsr(csr, EncodingFormat.DER, bs); derRaw = bs.ToArray(); } var derB64u = JwsHelper.Base64UrlEncode(derRaw); Console.WriteLine($"\nRequesting Certificate"); Trace.TraceInformation("Requesting Certificate"); CertificateRequest certRequ = client.RequestCertificate(derB64u); Trace.TraceInformation("certRequ {0}", JsonConvert.SerializeObject(certRequ)); Console.WriteLine($" Request Status: {certRequ.StatusCode}"); Trace.TraceInformation("Request Status: {0}", certRequ.StatusCode); if (certRequ.StatusCode == System.Net.HttpStatusCode.Created) { var keyGenFile = Path.Combine(this.configPath, $"{dnsIdentifier}-gen-key.json"); var keyPemFile = Path.Combine(configPath, $"{dnsIdentifier}-key.pem"); var csrGenFile = Path.Combine(configPath, $"{dnsIdentifier}-gen-csr.json"); var csrPemFile = Path.Combine(configPath, $"{dnsIdentifier}-csr.pem"); var crtDerFile = Path.Combine(configPath, $"{dnsIdentifier}-crt.der"); var crtPemFile = Path.Combine(configPath, $"{dnsIdentifier}-crt.pem"); string crtPfxFile = null; crtPfxFile = Path.Combine(configPath, $"{dnsIdentifier}-all.pfx"); using (var fs = new FileStream(keyGenFile, FileMode.Create)) cp.SavePrivateKey(rsaKeys, fs); using (var fs = new FileStream(keyPemFile, FileMode.Create)) cp.ExportPrivateKey(rsaKeys, EncodingFormat.PEM, fs); using (var fs = new FileStream(csrGenFile, FileMode.Create)) cp.SaveCsr(csr, fs); using (var fs = new FileStream(csrPemFile, FileMode.Create)) cp.ExportCsr(csr, EncodingFormat.PEM, fs); Console.WriteLine($" Saving Certificate to {crtDerFile}"); Trace.TraceInformation("Saving Certificate to {0}", crtDerFile); using (var file = File.Create(crtDerFile)) certRequ.SaveCertificate(file); Crt crt; using (FileStream source = new FileStream(crtDerFile, FileMode.Open), target = new FileStream(crtPemFile, FileMode.Create)) { crt = cp.ImportCertificate(EncodingFormat.DER, source); cp.ExportCertificate(crt, EncodingFormat.PEM, target); } // To generate a PKCS#12 (.PFX) file, we need the issuer's public certificate var isuPemFile = GetIssuerCertificate(certRequ, cp); Console.WriteLine($" Saving Certificate to {crtPfxFile}"); Trace.TraceInformation("Saving Certificate to {0}", crtPfxFile); using (FileStream source = new FileStream(isuPemFile, FileMode.Open), target = new FileStream(crtPfxFile, FileMode.Create)) { try { var isuCrt = cp.ImportCertificate(EncodingFormat.PEM, source); cp.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target, config.PFXPassword); } catch (Exception ex) { Trace.TraceError("Error exporting archive {0}", ex); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"Error exporting archive: {ex.Message.ToString()}"); Console.ResetColor(); } } cp.Dispose(); return(crtPfxFile); } if ((int)certRequ.StatusCode == 429) { Trace.TraceError("Unable to request certificate, too many certificate requests to Let's Encrypt certificate servers for the domain within the last 7 days. Please try again later. (If you are testing, please use the staging enviroment where you can request unlimited number of certificates. During the beta period only 5 certificate requests per domain per week are allowed to the production environment.)"); throw new Exception("Unable to request certificate, too many certificate requests to Let's Encrypt certificate servers for the domain within the last 7 days. Please try again later. (If you are testing, please use the staging enviroment where you can request unlimited number of certificates. During the beta period only 5 certificate requests per domain per week are allowed to the production environment.)"); } Trace.TraceError("Request status = {0}", certRequ.StatusCode); throw new Exception($"Request status = {certRequ.StatusCode}"); }
private string GetCertificate(string host) { Log("\t\t\tGetCertificate started"); var certificateProvider = CertificateProvider.GetProvider(); var rsaPrivateKeyParams = new RsaPrivateKeyParams() { NumBits = Properties.Settings.Default.RSAKeyBits, }; var rsaPrivateKey = certificateProvider.GeneratePrivateKey(rsaPrivateKeyParams); var csrDetails = new CsrDetails { CommonName = host, }; var csrParams = new CsrParams { Details = csrDetails, }; var csr = certificateProvider.GenerateCsr(csrParams, rsaPrivateKey, Crt.MessageDigest.SHA256); byte[] derBytes; using (var ms = new MemoryStream()) { certificateProvider.ExportCsr(csr, EncodingFormat.DER, ms); derBytes = ms.ToArray(); } CertificateRequest requestCertificate = null; var derBase64UrlEncoded = JwsHelper.Base64UrlEncode(derBytes); try { requestCertificate = this.client.RequestCertificate(derBase64UrlEncoded); } catch (Exception ex) { Log("\t\t\t\tGetCertificate error {0}", ex.InnerException.Message); certificateProvider.Dispose(); return(null); } var crtPfxFile = host + "-all.pfx"; if (requestCertificate.StatusCode != System.Net.HttpStatusCode.Created) { crtPfxFile = null; Log("\t\t\t\tGetCertificate certRequ.StatusCode {0}", requestCertificate.StatusCode); } else { var keyGenFile = host + "-gen-key.json"; var keyPemFile = host + "-key.pem"; var csrGenFile = host + "-gen-csr.json"; var csrPemFile = host + "-csr.pem"; var crtDerFile = host + "-crt.der"; var crtPemFile = host + "-crt.pem"; var chainPemFile = host + "-chain.pem"; using (var fs = new FileStream(keyGenFile, FileMode.Create)) certificateProvider.SavePrivateKey(rsaPrivateKey, fs); using (var fs = new FileStream(keyPemFile, FileMode.Create)) certificateProvider.ExportPrivateKey(rsaPrivateKey, EncodingFormat.PEM, fs); using (var fs = new FileStream(csrGenFile, FileMode.Create)) certificateProvider.SaveCsr(csr, fs); using (var fs = new FileStream(csrPemFile, FileMode.Create)) certificateProvider.ExportCsr(csr, EncodingFormat.PEM, fs); using (var file = File.Create(crtDerFile)) requestCertificate.SaveCertificate(file); Crt crt; using (FileStream source = new FileStream(crtDerFile, FileMode.Open), target = new FileStream(crtPemFile, FileMode.Create)) { crt = certificateProvider.ImportCertificate(EncodingFormat.DER, source); certificateProvider.ExportCertificate(crt, EncodingFormat.PEM, target); } // To generate a PKCS#12 (.PFX) file, we need the issuer's public certificate var isuPemFile = GetIssuerCertificate(requestCertificate, certificateProvider); using (FileStream intermediate = new FileStream(isuPemFile, FileMode.Open), certificate = new FileStream(crtPemFile, FileMode.Open), chain = new FileStream(chainPemFile, FileMode.Create)) { certificate.CopyTo(chain); intermediate.CopyTo(chain); } using (FileStream source = new FileStream(isuPemFile, FileMode.Open), target = new FileStream(crtPfxFile, FileMode.Create)) { try { var isuCrt = certificateProvider.ImportCertificate(EncodingFormat.PEM, source); certificateProvider.ExportArchive(rsaPrivateKey, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target, Properties.Settings.Default.PFXPassword); } catch (Exception ex) { Log("\t\t\t\tGetCertificate error {0}", ex.Message); } } } certificateProvider.Dispose(); Log("\t\t\tGetCertificate ended"); return(crtPfxFile); }
private void GetCertificate() { Log.Information("Requesting Certificate"); using (CertificateProvider cp = CertificateProvider.GetProvider()) { RsaPrivateKeyParams rsaPkp = new RsaPrivateKeyParams(); PrivateKey rsaKeys = cp.GeneratePrivateKey(rsaPkp); CsrParams csrParams = new CsrParams { Details = new CsrDetails { CommonName = _options.HostName, }, }; Csr csr = cp.GenerateCsr(csrParams, rsaKeys, Crt.MessageDigest.SHA256); byte[] derRaw; using (MemoryStream bs = new MemoryStream()) { cp.ExportCsr(csr, EncodingFormat.DER, bs); derRaw = bs.ToArray(); } string derB64U = JwsHelper.Base64UrlEncode(derRaw); CertificateRequest certReq = _acmeClient.RequestCertificate(derB64U); if (certReq.StatusCode != HttpStatusCode.Created) { throw new Exception($"Request status = {certReq.StatusCode}"); } using (FileStream fs = new FileStream(_options.WellKnownFilePaths[WellKnownFile.KeyGen], FileMode.Create)) cp.SavePrivateKey(rsaKeys, fs); using (FileStream fs = new FileStream(_options.WellKnownFilePaths[WellKnownFile.KeyPem], FileMode.Create)) cp.ExportPrivateKey(rsaKeys, EncodingFormat.PEM, fs); using (FileStream fs = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CsrGen], FileMode.Create)) cp.SaveCsr(csr, fs); using (FileStream fs = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CsrPem], FileMode.Create)) cp.ExportCsr(csr, EncodingFormat.PEM, fs); Log.Information($"Saving Certificate to {_options.WellKnownFilePaths[WellKnownFile.CrtDer]}"); using (FileStream file = File.Create(_options.WellKnownFilePaths[WellKnownFile.CrtDer])) certReq.SaveCertificate(file); Crt crt; using (FileStream source = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CrtDer], FileMode.Open), target = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CrtPem], FileMode.Create)) { crt = cp.ImportCertificate(EncodingFormat.DER, source); cp.ExportCertificate(crt, EncodingFormat.PEM, target); } // To generate a PKCS#12 (.PFX) file, we need the issuer's public certificate string isuPemFile = GetIssuerCertificate(certReq, cp); using (FileStream intermediate = new FileStream(isuPemFile, FileMode.Open), certificate = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CrtPem], FileMode.Open), chain = new FileStream(_options.WellKnownFilePaths[WellKnownFile.ChainPem], FileMode.Create)) { certificate.CopyTo(chain); intermediate.CopyTo(chain); } Log.Information($"Saving Certificate to {_options.WellKnownFilePaths[WellKnownFile.CrtPfx]}"); using (FileStream source = new FileStream(isuPemFile, FileMode.Open), target = new FileStream(_options.WellKnownFilePaths[WellKnownFile.CrtPfx], FileMode.Create)) { Crt isuCrt = cp.ImportCertificate(EncodingFormat.PEM, source); cp.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target, _options.PfxPassword); } } }
static void GenerateCertFiles(CertificateProvider provider, PrivateKey rsaKeys, Csr csr, CertificateRequest request, string certificatesFolder, string domain) { var crt = default(Crt); var keyGenFile = Path.Combine(certificatesFolder, $"{domain}-gen-key.json"); Log.Debug($"Gerando arquivo: {keyGenFile}"); using (var fs = new FileStream(keyGenFile, FileMode.Create)) provider.SavePrivateKey(rsaKeys, fs); var keyPemFile = Path.Combine(certificatesFolder, $"{domain}-key.pem"); Log.Debug($"Gerando arquivo: {keyPemFile}"); using (var fs = new FileStream(keyPemFile, FileMode.Create)) provider.ExportPrivateKey(rsaKeys, EncodingFormat.PEM, fs); var csrGenFile = Path.Combine(certificatesFolder, $"{domain}-gen-csr.json"); Log.Debug($"Gerando arquivo: {csrGenFile}"); using (var fs = new FileStream(csrGenFile, FileMode.Create)) provider.SaveCsr(csr, fs); var csrPemFile = Path.Combine(certificatesFolder, $"{domain}-csr.pem"); Log.Debug($"Gerando arquivo: {csrPemFile}"); using (var fs = new FileStream(csrPemFile, FileMode.Create)) provider.ExportCsr(csr, EncodingFormat.PEM, fs); var crtDerFile = Path.Combine(certificatesFolder, $"{domain}-crt.der"); Log.Debug($"Gerando arquivo: {crtDerFile}"); using (var file = File.Create(crtDerFile)) request.SaveCertificate(file); var crtPemFile = Path.Combine(certificatesFolder, $"{domain}-crt.pem"); var chainPemFile = Path.Combine(certificatesFolder, $"{domain}-chain.pem"); Log.Debug($"Gerando arquivo: {crtPemFile}"); Log.Debug($"Gerando arquivo: {chainPemFile}"); using (FileStream source = new FileStream(crtDerFile, FileMode.Open), target = new FileStream(crtPemFile, FileMode.Create)) { crt = provider.ImportCertificate(EncodingFormat.DER, source); provider.ExportCertificate(crt, EncodingFormat.PEM, target); } var pemFile = DownloadIssuerCertificate(provider, request, ACME_API, certificatesFolder); using (FileStream intermediate = new FileStream(pemFile, FileMode.Open), certificate = new FileStream(crtPemFile, FileMode.Open), chain = new FileStream(chainPemFile, FileMode.Create)) { certificate.CopyTo(chain); intermediate.CopyTo(chain); } var crtPfxFile = Path.Combine(certificatesFolder, $"{domain}-all.pfx"); Log.Debug($"Gerando arquivo: {crtPfxFile}"); using (FileStream source = new FileStream(pemFile, FileMode.Open), target = new FileStream(crtPfxFile, FileMode.Create)) { try { var isuCrt = provider.ImportCertificate(EncodingFormat.PEM, source); provider.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target, string.Empty); } catch (Exception ex) { Log.Error($"Erro ao exportar o arquivo {crtPfxFile}", ex); } } }