예제 #1
0
        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}");
        }
예제 #2
0
        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);
                }
            }
        }
예제 #4
0
        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);
                }
            }
        }