コード例 #1
0
        static byte[] GenerateCSR(CertificateProvider provider, string hostName, List <string> alternativeNames, out PrivateKey privateKey)
        {
            var csrDetails = new CsrDetails
            {
                CommonName = hostName
            };

            if (alternativeNames.Count > 0)
            {
                csrDetails.AlternativeNames = alternativeNames;
            }

            privateKey = provider.GeneratePrivateKey(new RsaPrivateKeyParams()
            {
                NumBits = Program.GlobalConfiguration.RSAKeyBits
            });
            var csr = provider.GenerateCsr(new CsrParams {
                Details = csrDetails,
            }, privateKey, Crt.MessageDigest.SHA256);

            byte[] derRaw;
            using (var bs = new MemoryStream())
            {
                provider.ExportCsr(csr, EncodingFormat.DER, bs);

                bs.Seek(0, SeekOrigin.Begin);
                derRaw = bs.ToArray();
            }

            return(derRaw);
        }
コード例 #2
0
ファイル: CsrHelper.cs プロジェクト: bjtucker/letsencrypt-win
        public static Csr GenerateCsr(CsrDetails csrDetails, RsaKeyPair rsaKeyPair, string messageDigest = "SHA256")
        {
            var rsaKeys = CryptoKey.FromPrivateKey(rsaKeyPair.Pem, null);

            // Translate from our external form to our OpenSSL internal form
            // Ref:  https://www.openssl.org/docs/manmaster/crypto/X509_NAME_new.html
            var xn = new X509Name();
            if (!string.IsNullOrEmpty(csrDetails.CommonName         /**/)) xn.Common = csrDetails.CommonName;       // CN;
            if (!string.IsNullOrEmpty(csrDetails.Country            /**/)) xn.Common = csrDetails.Country;          // C;
            if (!string.IsNullOrEmpty(csrDetails.StateOrProvince    /**/)) xn.Common = csrDetails.StateOrProvince;  // ST;
            if (!string.IsNullOrEmpty(csrDetails.Locality           /**/)) xn.Common = csrDetails.Locality;         // L;
            if (!string.IsNullOrEmpty(csrDetails.Organization       /**/)) xn.Common = csrDetails.Organization;     // O;
            if (!string.IsNullOrEmpty(csrDetails.OrganizationUnit   /**/)) xn.Common = csrDetails.OrganizationUnit; // OU;
            if (!string.IsNullOrEmpty(csrDetails.Description        /**/)) xn.Common = csrDetails.Description;      // D;
            if (!string.IsNullOrEmpty(csrDetails.Surname            /**/)) xn.Common = csrDetails.Surname;          // S;
            if (!string.IsNullOrEmpty(csrDetails.GivenName          /**/)) xn.Common = csrDetails.GivenName;        // G;
            if (!string.IsNullOrEmpty(csrDetails.Initials           /**/)) xn.Common = csrDetails.Initials;         // I;
            if (!string.IsNullOrEmpty(csrDetails.Title              /**/)) xn.Common = csrDetails.Title;            // T;
            if (!string.IsNullOrEmpty(csrDetails.SerialNumber       /**/)) xn.Common = csrDetails.SerialNumber;     // SN;
            if (!string.IsNullOrEmpty(csrDetails.UniqueIdentifier   /**/)) xn.Common = csrDetails.UniqueIdentifier; // UID;

            var xr = new X509Request(0, xn, rsaKeys);
            var md = MessageDigest.CreateByName(messageDigest); ;
            xr.Sign(rsaKeys, md);
            using (var bio = BIO.MemoryBuffer())
            {
                xr.Write(bio);
                return new Csr(bio.ReadString());
            }
        }
コード例 #3
0
        public static void GetCertificateAutoGen(CertificateGeneratorParam param)
        {
            if (param == null)
            {
                log.Info($" {nameof(param)} is null");
                return;
            }
            param.domains = param.domains.Where(o => o.valid).ToList();
            if (param.domains.Count == 0)
            {
                log.Info($" can't find a valid domain name.");
                return;
            }
            var dnsIdentifier = string.IsNullOrWhiteSpace(param.common_name) ? param.domains.FirstOrDefault().domain : param.common_name.Trim();
            var cp            = CertificateProvider.GetProvider();
            var rsaPkp        = new RsaPrivateKeyParams();

            var rsaKeys    = cp.GeneratePrivateKey(rsaPkp);
            var csrDetails = new CsrDetails
            {
                CommonName       = dnsIdentifier,
                AlternativeNames = param.domains.Select(o => o.domain).ToList(),
            };
            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);

            log.Info($"\nRequesting Certificate");
            var certRequ = param.client.RequestCertificate(derB64u);

            log.Info($" Request Status: {certRequ.StatusCode}");

            //log.Info($"Refreshing Cert Request");
            //client.RefreshCertificateRequest(certRequ);

            if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
            {
                var    keyGenFile = Path.Combine(param.path, $"{dnsIdentifier}-gen-key.json");
                var    keyPemFile = Path.Combine(param.path, $"{dnsIdentifier}-key.pem");
                var    csrGenFile = Path.Combine(param.path, $"{dnsIdentifier}-gen-csr.json");
                var    csrPemFile = Path.Combine(param.path, $"{dnsIdentifier}-csr.pem");
                var    crtDerFile = Path.Combine(param.path, $"{dnsIdentifier}-crt.der");
                var    crtPemFile = Path.Combine(param.path, $"{dnsIdentifier}-crt.pem");
                string crtPfxFile = null;

                crtPfxFile = Path.Combine(param.path, $"{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);

                log.Info($" Saving Certificate to {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, param.account);

                log.Info($" Saving Certificate to {crtPfxFile} (with no password set)");
                using (FileStream source = new FileStream(isuPemFile, FileMode.Open),
                       target = new FileStream(crtPfxFile, FileMode.Create))
                {
                    var isuCrt = cp.ImportCertificate(EncodingFormat.PEM, source);
                    cp.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target);
                }

                cp.Dispose();

                return;
            }

            throw new Exception($"Request status = {certRequ.StatusCode}");
        }
コード例 #4
0
        private Csr GenerateCsr(CsrDetails csrDetails, RsaPrivateKey rsaKeyPair, string messageDigest = "SHA256")
        {
            var rsaKeys = CryptoKey.FromPrivateKey(rsaKeyPair.Pem, null);

            // Translate from our external form to our OpenSSL internal form
            // Ref:  https://www.openssl.org/docs/manmaster/crypto/X509_NAME_new.html
            var xn = new X509Name();

            if (!string.IsNullOrEmpty(csrDetails.CommonName /**/))
            {
                xn.Common = csrDetails.CommonName;                                                                  // CN;
            }
            if (!string.IsNullOrEmpty(csrDetails.Country /**/))
            {
                xn.Country = csrDetails.Country;                                                                     // C;
            }
            if (!string.IsNullOrEmpty(csrDetails.StateOrProvince /**/))
            {
                xn.StateOrProvince = csrDetails.StateOrProvince;                                                             // ST;
            }
            if (!string.IsNullOrEmpty(csrDetails.Locality /**/))
            {
                xn.Locality = csrDetails.Locality;                                                                    // L;
            }
            if (!string.IsNullOrEmpty(csrDetails.Organization /**/))
            {
                xn.Organization = csrDetails.Organization;                                                                // O;
            }
            if (!string.IsNullOrEmpty(csrDetails.OrganizationUnit /**/))
            {
                xn.OrganizationUnit = csrDetails.OrganizationUnit;                                                            // OU;
            }
            if (!string.IsNullOrEmpty(csrDetails.Description /**/))
            {
                xn.Description = csrDetails.Description;                                                                 // D;
            }
            if (!string.IsNullOrEmpty(csrDetails.Surname /**/))
            {
                xn.Surname = csrDetails.Surname;                                                                     // S;
            }
            if (!string.IsNullOrEmpty(csrDetails.GivenName /**/))
            {
                xn.Given = csrDetails.GivenName;                                                                   // G;
            }
            if (!string.IsNullOrEmpty(csrDetails.Initials /**/))
            {
                xn.Initials = csrDetails.Initials;                                                                    // I;
            }
            if (!string.IsNullOrEmpty(csrDetails.Title /**/))
            {
                xn.Title = csrDetails.Title;                                                                       // T;
            }
            if (!string.IsNullOrEmpty(csrDetails.SerialNumber /**/))
            {
                xn.SerialNumber = csrDetails.SerialNumber;                                                                // SN;
            }
            if (!string.IsNullOrEmpty(csrDetails.UniqueIdentifier /**/))
            {
                xn.UniqueIdentifier = csrDetails.UniqueIdentifier;                                                            // UID;
            }
            var xr = new X509Request(0, xn, rsaKeys);
            var md = MessageDigest.CreateByName(messageDigest);

            xr.Sign(rsaKeys, md);
            using (var bio = BIO.MemoryBuffer())
            {
                xr.Write(bio);
                return(new Csr(bio.ReadString()));
            }
        }
コード例 #5
0
        public string RequestCertificateAndConvertToPfx(List <Binding> bindings)
        {
            var keyGenFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-gen-key.json");
            var keyPemFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-key.pem");
            var csrGenFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-gen-csr.json");
            var csrPemFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-csr.pem");
            var crtDerFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-crt.der");
            var crtPemFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-crt.pem");
            var chainPemFile = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-chain.pem");
            var crtPfxFile   = Path.Combine(Config.Path, $"{bindings[0].IPAddress}-all.pfx");

            if (Globals.ShouldCreateCertificate())
            {
                // TODOX Should check if the requested certificate (lowercase and sort hostnames) was issued in previous 10 days

                var cp     = CertificateProvider.GetProvider();
                var rsaPkp = new RsaPrivateKeyParams();
                try {
                    if (Properties.Settings.Default.RSAKeyBits >= 2048)
                    {
                        rsaPkp.NumBits = Properties.Settings.Default.RSAKeyBits;
                    }
                    else
                    {
                        Globals.Log($"Requested key size of {Properties.Settings.Default.RSAKeyBits} is not secure.  Using 2048.");
                        rsaPkp.NumBits = 2048;
                    }
                } catch (Exception ex) {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Globals.Log($"Unable to set RSA key size, letting ACMESharp select default. Error: {ex}");
                    Console.ResetColor();
                }

                var rsaKeys    = cp.GeneratePrivateKey(rsaPkp);
                var csrDetails = new CsrDetails {
                    CommonName       = bindings[0].Hostname,
                    AlternativeNames = bindings.Select(x => x.Hostname).ToList(),
                };
                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);

                Globals.Log();
                Globals.Log("Requesting Certificate");
                var certRequ = _Client.RequestCertificate(derB64U);

                Globals.Log($" - Request Status: {certRequ.StatusCode}");

                if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
                {
                    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);

                    Globals.Log($" - Saving DER certificate to {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);

                    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);
                    }

                    Globals.Log($" - Saving PFX certificate to {crtPfxFile}");
                    using (FileStream source = new FileStream(isuPemFile, FileMode.Open),
                           target = new FileStream(crtPfxFile, FileMode.Create)) {
                        var isuCrt = cp.ImportCertificate(EncodingFormat.PEM, source);
                        cp.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target, "");
                    }

                    cp.Dispose();

                    // TODOX Should store that the requested certificate (lowercase and sort hostnames) was issued

                    return(crtPfxFile);
                }
                else
                {
                    throw new Exception($"Certificate request status = {certRequ.StatusCode}, uri = {certRequ.Uri}");
                }
            }
            else
            {
                // Don't want to request a new cert, so return the filename to the last requested cert
                return(crtPfxFile);
            }
        }
コード例 #6
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}");
        }
コード例 #7
0
        public static string GetCertificate(Target binding)
        {
            var dnsIdentifier = binding.Host;

            var cp     = CertificateProvider.GetProvider();
            var rsaPkp = new RsaPrivateKeyParams();

            var rsaKeys    = cp.GeneratePrivateKey(rsaPkp);
            var csrDetails = new CsrDetails
            {
                CommonName = dnsIdentifier,
            };
            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");
            var certRequ = client.RequestCertificate(derB64u);

            Console.WriteLine($" Request Status: {certRequ.StatusCode}");

            //Console.WriteLine($"Refreshing Cert Request");
            //client.RefreshCertificateRequest(certRequ);

            if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
            {
                var    keyGenFile = Path.Combine(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;
                if (!CentralSSL)
                {
                    crtPfxFile = Path.Combine(configPath, $"{dnsIdentifier}-all.pfx");
                }
                else
                {
                    crtPfxFile = Path.Combine(Options.CentralSSLStore, $"{dnsIdentifier}.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}");
                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} (with no password set)");
                using (FileStream source = new FileStream(isuPemFile, FileMode.Open),
                       target = new FileStream(crtPfxFile, FileMode.Create))
                {
                    var isuCrt = cp.ImportCertificate(EncodingFormat.PEM, source);
                    cp.ExportArchive(rsaKeys, new[] { crt, isuCrt }, ArchiveFormat.PKCS12, target);
                }

                cp.Dispose();

                return(crtPfxFile);
            }

            throw new Exception($"Request status = {certRequ.StatusCode}");
        }
コード例 #8
0
        private string RequestCertificate()
        {
            var cp     = CertificateProvider.GetProvider("BouncyCastle");
            var rsaPkp = new RsaPrivateKeyParams
            {
                NumBits = this.keyLength
            };
            var rsaKeys = cp.GeneratePrivateKey(rsaPkp);

            var csrDetails = new CsrDetails
            {
                CommonName       = this.mainDomain,
                AlternativeNames = this.alternateNames.Except(new string[] { this.mainDomain })
            };
            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);

            logger.Debug("Requesting Certificate");

            var certRequ = client.RequestCertificate(derB64U);

            logger.Debug("Request Status: {0}", certRequ.StatusCode);

            if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
            {
                var    keyGenFile = Path.Combine(certificatePath, $"{this.mainDomain}-gen-key.json");
                var    keyPemFile = Path.Combine(certificatePath, $"{this.mainDomain}-key.pem");
                var    csrGenFile = Path.Combine(certificatePath, $"{this.mainDomain}-gen-csr.json");
                var    csrPemFile = Path.Combine(certificatePath, $"{this.mainDomain}-csr.pem");
                var    crtDerFile = Path.Combine(certificatePath, $"{this.mainDomain}-crt.der");
                var    crtPemFile = Path.Combine(certificatePath, $"{this.mainDomain}-crt.pem");
                string crtPfxFile = Path.Combine(certificatePath, $"{this.mainDomain}-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);
                }

                logger.Info("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);

                logger.Info($"Saving Certificate to {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);
                    }
                    catch (Exception ex)
                    {
                        logger.Error("Error exporting archive: {0}", ex.Message);
                    }
                }

                cp.Dispose();

                return(crtPfxFile);
            }

            throw new Exception($"Request status = {certRequ.StatusCode}");
        }
コード例 #9
0
        protected Csr GenerateCsr(CsrDetails csrDetails, RsaPrivateKey rsaKeyPair, string messageDigest = "SHA256")
        {
            var rsaKeys = CryptoKey.FromPrivateKey(rsaKeyPair.Pem, null);

            // Translate from our external form to our OpenSSL internal form
            // Ref:  https://www.openssl.org/docs/manmaster/crypto/X509_NAME_new.html
            var xn = new X509Name();

            if (!string.IsNullOrEmpty(csrDetails.CommonName /**/))
            {
                xn.Common = csrDetails.CommonName;                                                                  // CN;
            }
            if (!string.IsNullOrEmpty(csrDetails.Country /**/))
            {
                xn.Country = csrDetails.Country;                                                                     // C;
            }
            if (!string.IsNullOrEmpty(csrDetails.StateOrProvince /**/))
            {
                xn.StateOrProvince = csrDetails.StateOrProvince;                                                             // ST;
            }
            if (!string.IsNullOrEmpty(csrDetails.Locality /**/))
            {
                xn.Locality = csrDetails.Locality;                                                                    // L;
            }
            if (!string.IsNullOrEmpty(csrDetails.Organization /**/))
            {
                xn.Organization = csrDetails.Organization;                                                                // O;
            }
            if (!string.IsNullOrEmpty(csrDetails.OrganizationUnit /**/))
            {
                xn.OrganizationUnit = csrDetails.OrganizationUnit;                                                            // OU;
            }
            if (!string.IsNullOrEmpty(csrDetails.Description /**/))
            {
                xn.Description = csrDetails.Description;                                                                 // D;
            }
            if (!string.IsNullOrEmpty(csrDetails.Surname /**/))
            {
                xn.Surname = csrDetails.Surname;                                                                     // S;
            }
            if (!string.IsNullOrEmpty(csrDetails.GivenName /**/))
            {
                xn.Given = csrDetails.GivenName;                                                                   // G;
            }
            if (!string.IsNullOrEmpty(csrDetails.Initials /**/))
            {
                xn.Initials = csrDetails.Initials;                                                                    // I;
            }
            if (!string.IsNullOrEmpty(csrDetails.Title /**/))
            {
                xn.Title = csrDetails.Title;                                                                       // T;
            }
            if (!string.IsNullOrEmpty(csrDetails.SerialNumber /**/))
            {
                xn.SerialNumber = csrDetails.SerialNumber;                                                                // SN;
            }
            if (!string.IsNullOrEmpty(csrDetails.UniqueIdentifier /**/))
            {
                xn.UniqueIdentifier = csrDetails.UniqueIdentifier;                                                            // UID;
            }
            var xr = new X509Request(0, xn, rsaKeys);

            if (csrDetails.AlternativeNames != null)
            {
                // Format the common name as the first alternative name
                var commonName = $"{EXT_SAN_PREFIX_DNS}:{xn.Common}";

                // Concat with all subsequent alternative names
                var altNames = commonName + string.Join("", csrDetails.AlternativeNames.Select(
                                                            x => $",{EXT_SAN_PREFIX_DNS}:{x}"));

                // Assemble and add the SAN extension value
                var extensions = new OpenSSL.Core.Stack <X509Extension>();
                extensions.Add(new X509Extension(xr, EXT_NAME_SAN, false, altNames));
                xr.AddExtensions(extensions);
            }

            var md = MessageDigest.CreateByName(messageDigest);

            xr.Sign(rsaKeys, md);
            using (var bio = BIO.MemoryBuffer())
            {
                xr.Write(bio);
                return(new Csr(bio.ReadString()));
            }
        }
コード例 #10
0
        public static string GetCertificate(Target binding)
        {
            List <string> identifiers = new List <string>();

            if (!Options.San)
            {
                identifiers.Add(binding.Host);
            }
            identifiers.AddRange(binding.AlternativeNames);
            identifiers = identifiers.Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().ToList();
            if (identifiers.Count() == 0)
            {
                Log.Error("No DNS identifiers found.");
                throw new Exception("No DNS identifiers found.");
            }

            var identifier = identifiers.First();

            var cp     = CertificateProvider.GetProvider();
            var rsaPkp = new RsaPrivateKeyParams();

            try
            {
                if (Properties.Settings.Default.RSAKeyBits >= 1024)
                {
                    rsaPkp.NumBits = Properties.Settings.Default.RSAKeyBits;
                    Log.Debug("RSAKeyBits: {RSAKeyBits}", Properties.Settings.Default.RSAKeyBits);
                }
                else
                {
                    Log.Warning(
                        "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)
            {
                Log.Warning("Unable to set RSA Key Bits, Letting ACMESharp default key bits, Error: {@ex}", ex);
            }

            var rsaKeys    = cp.GeneratePrivateKey(rsaPkp);
            var csrDetails = new CsrDetails()
            {
                CommonName       = identifiers.FirstOrDefault(),
                AlternativeNames = identifiers
            };

            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);

            Log.Information("Requesting Certificate: {dnsIdentifier}");
            var certRequ = _client.RequestCertificate(derB64U);

            Log.Debug("certRequ {@certRequ}", certRequ);

            Log.Information("Request Status: {StatusCode}", certRequ.StatusCode);

            if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
            {
                var    keyGenFile   = Path.Combine(_certificatePath, $"{identifier}-gen-key.json");
                var    keyPemFile   = Path.Combine(_certificatePath, $"{identifier}-key.pem");
                var    csrGenFile   = Path.Combine(_certificatePath, $"{identifier}-gen-csr.json");
                var    csrPemFile   = Path.Combine(_certificatePath, $"{identifier}-csr.pem");
                var    crtDerFile   = Path.Combine(_certificatePath, $"{identifier}-crt.der");
                var    crtPemFile   = Path.Combine(_certificatePath, $"{identifier}-crt.pem");
                var    chainPemFile = Path.Combine(_certificatePath, $"{identifier}-chain.pem");
                string crtPfxFile   = null;
                if (!Options.CentralSsl)
                {
                    crtPfxFile = Path.Combine(_certificatePath, $"{identifier}-all.pfx");
                }
                else
                {
                    crtPfxFile = Path.Combine(Options.CentralSslStore, $"{identifier}.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);

                Log.Information("Saving Certificate to {crtDerFile}", 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);

                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);
                }

                Log.Debug("CentralSsl {CentralSsl} San {San}", Options.CentralSsl.ToString(), Options.San.ToString());

                if (Options.CentralSsl && Options.San)
                {
                    foreach (var host in identifiers)
                    {
                        Console.WriteLine($"Host: {host}");
                        crtPfxFile = Path.Combine(Options.CentralSslStore, $"{host}.pfx");

                        Log.Information("Saving Certificate to {crtPfxFile}", 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,
                                                 Properties.Settings.Default.PFXPassword);
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Error exporting archive {@ex}", ex);
                            }
                        }
                    }
                }
                else //Central SSL and San need to save the cert for each hostname
                {
                    Log.Information("Saving Certificate to {crtPfxFile}", 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,
                                             Properties.Settings.Default.PFXPassword);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Error exporting archive {@ex}", ex);
                        }
                    }
                }

                cp.Dispose();

                return(crtPfxFile);
            }
            Log.Error("Request status = {StatusCode}", certRequ.StatusCode);
            throw new Exception($"Request status = {certRequ.StatusCode}");
        }
コード例 #11
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);
        }
コード例 #12
0
ファイル: NewCertificate.cs プロジェクト: xzoth/ACMESharp
        protected override void ProcessRecord()
        {
            using (var vlt = Util.VaultHelper.GetVault(VaultProfile))
            {
                vlt.OpenStorage();
                var v = vlt.LoadVault();

                if (v.Registrations == null || v.Registrations.Count < 1)
                {
                    throw new InvalidOperationException("No registrations found");
                }

                var ri = v.Registrations[0];
                var r  = ri.Registration;

                if (v.Identifiers == null || v.Identifiers.Count < 1)
                {
                    throw new InvalidOperationException("No identifiers found");
                }

                var ii = v.Identifiers.GetByRef(IdentifierRef);
                if (ii == null)
                {
                    throw new Exception("Unable to find an Identifier for the given reference");
                }

                var ci = new CertificateInfo
                {
                    Id            = EntityHelper.NewId(),
                    Alias         = Alias,
                    Label         = Label,
                    Memo          = Memo,
                    IdentifierRef = ii.Id,
                    IdentifierDns = ii.Dns,
                };

                if (Generate)
                {
                    Func <string, string> csrDtlValue = x => null;
                    Func <string, IEnumerable <string> > csrDtlValues = x => null;

                    if (CsrDetails != null)
                    {
                        csrDtlValue = x => CsrDetails.ContainsKey(x)
                                ? CsrDetails[x] as string : null;
                        csrDtlValues = x => !string.IsNullOrEmpty(csrDtlValue(x))
                                ? Regex.Split(csrDtlValue(x).Trim(), "[\\s,;]+") : null;
                    }

                    var csrDetails = new CsrDetails
                    {
                        // Common Name is always pulled from associated Identifier
                        CommonName = ii.Dns,

                        // Remaining elements will be used if defined
                        AlternativeNames /**/ = csrDtlValues(nameof(PKI.CsrDetails.AlternativeNames)),
                        Country /**/          = csrDtlValue(nameof(PKI.CsrDetails.Country)),
                        Description /**/      = csrDtlValue(nameof(PKI.CsrDetails.Description)),
                        Email /**/            = csrDtlValue(nameof(PKI.CsrDetails.Email)),
                        GivenName /**/        = csrDtlValue(nameof(PKI.CsrDetails.GivenName)),
                        Initials /**/         = csrDtlValue(nameof(PKI.CsrDetails.Initials)),
                        Locality /**/         = csrDtlValue(nameof(PKI.CsrDetails.Locality)),
                        Organization /**/     = csrDtlValue(nameof(PKI.CsrDetails.Organization)),
                        OrganizationUnit /**/ = csrDtlValue(nameof(PKI.CsrDetails.OrganizationUnit)),
                        SerialNumber /**/     = csrDtlValue(nameof(PKI.CsrDetails.SerialNumber)),
                        StateOrProvince /**/  = csrDtlValue(nameof(PKI.CsrDetails.StateOrProvince)),
                        Surname /**/          = csrDtlValue(nameof(PKI.CsrDetails.Surname)),
                        Title /**/            = csrDtlValue(nameof(PKI.CsrDetails.Title)),
                        UniqueIdentifier /**/ = csrDtlValue(nameof(PKI.CsrDetails.UniqueIdentifier)),
                    };

                    if (AlternativeIdentifierRefs != null)
                    {
                        if (csrDetails.AlternativeNames != null)
                        {
                            throw new Exception("Alternative names already specified manually")
                                  .With(nameof(csrDetails.AlternativeNames),
                                        string.Join(",", csrDetails.AlternativeNames));
                        }

                        csrDetails.AlternativeNames = AlternativeIdentifierRefs.Select(alternativeIdentifierRef =>
                        {
                            var altId = v.Identifiers.GetByRef($"{alternativeIdentifierRef}");
                            if (altId == null)
                            {
                                throw new Exception("Unable to find an Identifier for the given Alternative Identifier reference")
                                .With(nameof(alternativeIdentifierRef), alternativeIdentifierRef)
                                .With(nameof(AlternativeIdentifierRefs),
                                      string.Join(",", AlternativeIdentifierRefs));
                            }
                            return(altId.Dns);
                        });

                        ci.AlternativeIdentifierDns = csrDetails.AlternativeNames.ToArray();
                    }

                    ci.GenerateDetailsFile = $"{ci.Id}-gen.json";
                    var asset = vlt.CreateAsset(VaultAssetType.CsrDetails, ci.GenerateDetailsFile);
                    using (var s = vlt.SaveAsset(asset))
                    {
                        JsonHelper.Save(s, csrDetails);
                    }
                }
                else
                {
                    if (!File.Exists(KeyPemFile))
                    {
                        throw new FileNotFoundException("Missing specified RSA Key file path");
                    }
                    if (!File.Exists(CsrPemFile))
                    {
                        throw new FileNotFoundException("Missing specified CSR details file path");
                    }

                    var keyPemFile = $"{ci.Id}-key.pem";
                    var csrPemFile = $"{ci.Id}-csr.pem";

                    var keyAsset = vlt.CreateAsset(VaultAssetType.KeyPem, keyPemFile, true);
                    var csrAsset = vlt.CreateAsset(VaultAssetType.CsrPem, csrPemFile);

                    using (Stream fs = new FileStream(KeyPemFile, FileMode.Open),
                           s = vlt.SaveAsset(keyAsset))
                    {
                        fs.CopyTo(s);
                    }
                    using (Stream fs = new FileStream(CsrPemFile, FileMode.Open),
                           s = vlt.SaveAsset(csrAsset))
                    {
                        fs.CopyTo(s);
                    }

                    ci.KeyPemFile = keyPemFile;
                    ci.CsrPemFile = csrPemFile;
                }

                if (v.Certificates == null)
                {
                    v.Certificates = new EntityDictionary <CertificateInfo>();
                }

                v.Certificates.Add(ci);

                vlt.SaveVault(v);

                WriteObject(ci);
            }
        }
コード例 #13
0
        public string GetCertificate(TargetApplication targetApplication)
        {
            using (var pkiTool = PkiToolExtManager.GetPkiTool("BouncyCastle"))
            {
                var rsaKeyParams = new RsaPrivateKeyParams();
                var rsaKeys      = pkiTool.GeneratePrivateKey(rsaKeyParams);

                var certificateName   = targetApplication.Hostnames.First();
                var baseOutPutPath    = _configuration.GetBaseOutPutPath(targetApplication);
                var certificateFolder = Path.Combine(baseOutPutPath, $"{DateTime.Now:yyyyMMdd_HHmmss}");

                if (Directory.Exists(certificateFolder) == false)
                {
                    Directory.CreateDirectory(certificateFolder);
                }

                var csrDetails = new CsrDetails
                {
                    CommonName       = certificateName,
                    AlternativeNames = targetApplication.Hostnames,
                };

                var certificateSigningRequest = pkiTool.GenerateCsr(
                    new CsrParams {
                    Details = csrDetails
                }, rsaKeys, Crt.MessageDigest.SHA256);

                byte[] certificateSigningRequestBytes;
                using (var bs = new MemoryStream())
                {
                    pkiTool.ExportCsr(certificateSigningRequest, EncodingFormat.DER, bs);
                    certificateSigningRequestBytes = bs.ToArray();
                }

                var certificateSigningRequestBytesBase64 = JwsHelper.Base64UrlEncode(certificateSigningRequestBytes);

                _logger.Information("Requesting a certificate");
                var certificateRequest = _acmeClient.RequestCertificate(certificateSigningRequestBytesBase64);

                _logger.Debug("Result of certificate request {certificateRequest}", certificateRequest);
                _logger.Information("Certificate request status is {statusCode}", certificateRequest.StatusCode);

                if (certificateRequest.StatusCode == HttpStatusCode.Created)
                {
                    var keyGenFile   = Path.Combine(certificateFolder, $"{certificateName}-gen-key.json");
                    var keyPemFile   = Path.Combine(certificateFolder, $"{certificateName}-key.pem");
                    var csrGenFile   = Path.Combine(certificateFolder, $"{certificateName}-gen-csr.json");
                    var csrPemFile   = Path.Combine(certificateFolder, $"{certificateName}-csr.pem");
                    var crtDerFile   = Path.Combine(certificateFolder, $"{certificateName}-crt.der");
                    var crtPemFile   = Path.Combine(certificateFolder, $"{certificateName}-crt.pem");
                    var chainPemFile = Path.Combine(certificateFolder, $"{certificateName}-chain.pem");

                    using (var fileStream = new FileStream(keyGenFile, FileMode.Create))
                        pkiTool.SavePrivateKey(rsaKeys, fileStream);
                    using (var fileStream = new FileStream(keyPemFile, FileMode.Create))
                        pkiTool.ExportPrivateKey(rsaKeys, EncodingFormat.PEM, fileStream);
                    using (var fileStream = new FileStream(csrGenFile, FileMode.Create))
                        pkiTool.SaveCsr(certificateSigningRequest, fileStream);
                    using (var fileStream = new FileStream(csrPemFile, FileMode.Create))
                        pkiTool.ExportCsr(certificateSigningRequest, EncodingFormat.PEM, fileStream);

                    _logger.Information("Saving certificate to {crtDerFile}", crtDerFile);
                    using (var file = File.Create(crtDerFile))
                        certificateRequest.SaveCertificate(file);

                    Crt crt;
                    using (FileStream source = new FileStream(crtDerFile, FileMode.Open), target = new FileStream(crtPemFile, FileMode.Create))
                    {
                        crt = pkiTool.ImportCertificate(EncodingFormat.DER, source);
                        pkiTool.ExportCertificate(crt, EncodingFormat.PEM, target);
                    }

                    var issuerCertificate = GetIssuerCertificate(certificateRequest, pkiTool, certificateFolder, targetApplication);
                    using (FileStream intermediate = new FileStream(issuerCertificate, FileMode.Open),
                           certificate = new FileStream(crtPemFile, FileMode.Open), chain = new FileStream(chainPemFile, FileMode.Create))
                    {
                        certificate.CopyTo(chain);
                        intermediate.CopyTo(chain);
                    }

                    var crtPfxFile = Path.Combine(certificateFolder, $"{targetApplication.Hostnames.First()}.pfx");

                    _logger.Information("Saving certificate for hostname {host} and alternative hostnames {@altHostNames} to {crtPfxFile}",
                                        targetApplication.Hostnames.First(), targetApplication.Hostnames.Skip(1), crtPfxFile);

                    using (FileStream source = new FileStream(issuerCertificate, FileMode.Open),
                           target = new FileStream(crtPfxFile, FileMode.Create))
                    {
                        try
                        {
                            var importCertificate = pkiTool.ImportCertificate(EncodingFormat.PEM, source);
                            pkiTool.ExportArchive(rsaKeys, new[] { crt, importCertificate }, ArchiveFormat.PKCS12, target,
                                                  targetApplication.CertificatePassword);
                        }
                        catch (Exception ex)
                        {
                            _logger.Error("Error exporting archive {@ex}", ex);
                        }
                    }

                    pkiTool.Dispose();

                    return(crtPfxFile);
                }

                _logger.Error("Request status is {statusCode}", certificateRequest.StatusCode);
                throw new Exception($"Request status = {certificateRequest.StatusCode}");
            }
        }
コード例 #14
0
        public static string GetCertificate(Target binding)
        {
            var           dnsIdentifier     = binding.Host;
            var           SANList           = binding.AlternativeNames;
            List <string> allDnsIdentifiers = new List <string>();

            if (!Options.SAN)
            {
                allDnsIdentifiers.Add(binding.Host);
            }
            if (binding.AlternativeNames != null)
            {
                allDnsIdentifiers.AddRange(binding.AlternativeNames);
            }

            var cp     = CertificateProvider.GetProvider();
            var rsaPkp = new RsaPrivateKeyParams();

            try
            {
                if (Properties.Settings.Default.RSAKeyBits >= 1024)
                {
                    rsaPkp.NumBits = Properties.Settings.Default.RSAKeyBits;
                    Log.Debug("RSAKeyBits: {RSAKeyBits}", Properties.Settings.Default.RSAKeyBits);
                }
                else
                {
                    Log.Warning("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)
            {
                Log.Warning("Unable to set RSA Key Bits, Letting ACMESharp default key bits, Error: {@ex}", ex);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"Unable to set RSA Key Bits, Letting ACMESharp default key bits, Error: {ex.Message.ToString()}");
                Console.ResetColor();
            }

            var rsaKeys    = cp.GeneratePrivateKey(rsaPkp);
            var csrDetails = new CsrDetails
            {
                CommonName = allDnsIdentifiers[0],
            };

            if (SANList != null)
            {
                if (SANList.Count > 0)
                {
                    csrDetails.AlternativeNames = SANList;
                }
            }
            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");
            Log.Information("Requesting Certificate");
            var certRequ = client.RequestCertificate(derB64u);

            Log.Debug("certRequ {@certRequ}", certRequ);

            Console.WriteLine($" Request Status: {certRequ.StatusCode}");
            Log.Information("Request Status: {StatusCode}", certRequ.StatusCode);

            if (certRequ.StatusCode == System.Net.HttpStatusCode.Created)
            {
                var    keyGenFile = Path.Combine(certificatePath, $"{dnsIdentifier}-gen-key.json");
                var    keyPemFile = Path.Combine(certificatePath, $"{dnsIdentifier}-key.pem");
                var    csrGenFile = Path.Combine(certificatePath, $"{dnsIdentifier}-gen-csr.json");
                var    csrPemFile = Path.Combine(certificatePath, $"{dnsIdentifier}-csr.pem");
                var    crtDerFile = Path.Combine(certificatePath, $"{dnsIdentifier}-crt.der");
                var    crtPemFile = Path.Combine(certificatePath, $"{dnsIdentifier}-crt.pem");
                string crtPfxFile = null;
                if (!CentralSSL)
                {
                    crtPfxFile = Path.Combine(certificatePath, $"{dnsIdentifier}-all.pfx");
                }
                else
                {
                    crtPfxFile = Path.Combine(Options.CentralSSLStore, $"{dnsIdentifier}.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}");
                Log.Information("Saving Certificate to {crtDerFile}", 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);

                Log.Debug("CentralSSL {CentralSSL} SAN {SAN}", CentralSSL.ToString(), Options.SAN.ToString());

                if (CentralSSL && Options.SAN)
                {
                    foreach (var host in allDnsIdentifiers)
                    {
                        Console.WriteLine($"Host: {host}");
                        crtPfxFile = Path.Combine(Options.CentralSSLStore, $"{host}.pfx");

                        Console.WriteLine($" Saving Certificate to {crtPfxFile}");
                        Log.Information("Saving Certificate to {crtPfxFile}", 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, Properties.Settings.Default.PFXPassword);
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Error exporting archive {@ex}", ex);
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine($"Error exporting archive: {ex.Message.ToString()}");
                                Console.ResetColor();
                            }
                        }
                    }
                }
                else //Central SSL and SAN need to save the cert for each hostname
                {
                    Console.WriteLine($" Saving Certificate to {crtPfxFile}");
                    Log.Information("Saving Certificate to {crtPfxFile}", 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, Properties.Settings.Default.PFXPassword);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("Error exporting archive {@ex}", ex);
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine($"Error exporting archive: {ex.Message.ToString()}");
                            Console.ResetColor();
                        }
                    }
                }

                cp.Dispose();

                return(crtPfxFile);
            }
            Log.Error("Request status = {StatusCode}", certRequ.StatusCode);
            throw new Exception($"Request status = {certRequ.StatusCode}");
        }
コード例 #15
0
        protected override void ProcessRecord()
        {
            using (var vp = InitializeVault.GetVaultProvider(VaultProfile))
            {
                vp.OpenStorage();
                var v = vp.LoadVault();

                if (v.Registrations == null || v.Registrations.Count < 1)
                {
                    throw new InvalidOperationException("No registrations found");
                }

                var ri = v.Registrations[0];
                var r  = ri.Registration;

                if (v.Identifiers == null || v.Identifiers.Count < 1)
                {
                    throw new InvalidOperationException("No identifiers found");
                }

                var ii = v.Identifiers.GetByRef(Identifier);
                if (ii == null)
                {
                    throw new Exception("Unable to find an Identifier for the given reference");
                }

                var ci = new CertificateInfo
                {
                    Id            = EntityHelper.NewId(),
                    Alias         = Alias,
                    Label         = Label,
                    Memo          = Memo,
                    IdentifierRef = ii.Id,
                };

                if (Generate)
                {
                    var csrDetails = new CsrDetails
                    {
                        CommonName = ii.Dns,
                    };

                    ci.GenerateDetailsFile = $"{ci.Id}-gen.json";
                    var asset = vp.CreateAsset(VaultAssetType.CsrDetails, ci.GenerateDetailsFile);
                    using (var s = vp.SaveAsset(asset))
                    {
                        JsonHelper.Save(s, csrDetails);
                    }
                }
                else
                {
                    if (!File.Exists(KeyPemFile))
                    {
                        throw new FileNotFoundException("Missing specified RSA Key file path");
                    }
                    if (!File.Exists(CsrPemFile))
                    {
                        throw new FileNotFoundException("Missing specified CSR details file path");
                    }

                    var keyPemFile = $"{ci.Id}-key.pem";
                    var csrPemFile = $"{ci.Id}-csr.pem";

                    var keyAsset = vp.CreateAsset(VaultAssetType.KeyPem, keyPemFile, true);
                    var csrAsset = vp.CreateAsset(VaultAssetType.CsrPem, csrPemFile);

                    using (Stream fs = new FileStream(KeyPemFile, FileMode.Open),
                           s = vp.SaveAsset(keyAsset))
                    {
                        fs.CopyTo(s);
                    }
                    using (Stream fs = new FileStream(KeyPemFile, FileMode.Open),
                           s = vp.SaveAsset(csrAsset))
                    {
                        fs.CopyTo(s);
                    }

                    ci.KeyPemFile = keyPemFile;
                    ci.CsrPemFile = csrPemFile;
                }

                if (v.Certificates == null)
                {
                    v.Certificates = new EntityDictionary <CertificateInfo>();
                }

                v.Certificates.Add(ci);

                vp.SaveVault(v);

                WriteObject(ci);
            }
        }
コード例 #16
0
        /// <summary>
        /// Generate a certificate request
        /// </summary>
        /// <param name="certificatename"></param>
        /// <param name="mainhost">Main host: www.google.com</param>
        /// <param name="certificatePath">Path to store the generated certificates</param>
        /// <param name="alternatehosts">Alterante hosts: list of alterante hosts for this certificate</param>
        /// <returns></returns>
        public CertificatePaths DownloadCertificate(
            string certificatename,
            string mainhost,
            string certificatePath,
            List <string> alternatehosts = null)
        {
            if (alternatehosts != null && alternatehosts.Any())
            {
                throw new NotSupportedException("Alternate host provisioning not supported yet.");
            }

            List <string> allDnsIdentifiers = new List <string>()
            {
                mainhost
            };

            if (alternatehosts != null)
            {
                allDnsIdentifiers.AddRange(alternatehosts);
            }

            // Tomado de app.config
            var rsaKeyBits = 2048; // 1024;//

            if (Environment.Is64BitProcess)
            {
                CertificateProvider.RegisterProvider(typeof(ACMESharp.PKI.Providers.OpenSslLib64Provider));
            }
            else
            {
                CertificateProvider.RegisterProvider(typeof(ACMESharp.PKI.Providers.OpenSslLib32Provider));
            }

            var cp     = CertificateProvider.GetProvider();
            var rsaPkp = new RsaPrivateKeyParams();

            try
            {
                if (rsaKeyBits >= 1024)
                {
                    rsaPkp.NumBits = rsaKeyBits;

                    // Log.Debug("RSAKeyBits: {RSAKeyBits}", Properties.Settings.Default.RSAKeyBits);
                }
                else
                {
                    // Log.Warning(
                    //    "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)
            {
                this.Logger.LogInfo(true, $"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 = allDnsIdentifiers[0]
            };

            if (alternatehosts != null)
            {
                if (alternatehosts.Count > 0)
                {
                    csrDetails.AlternativeNames = alternatehosts;
                }
            }

            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);

            this.Logger.LogInfo(true, $"Requesting Certificate");

            // Log.Information("Requesting Certificate");
            var certRequ = this.AcmeClient.RequestCertificate(derB64U);

            // Log.Debug("certRequ {@certRequ}", certRequ);

            this.Logger.LogInfo(true, $"Request Status: {certRequ.StatusCode}");

            if (certRequ.StatusCode != System.Net.HttpStatusCode.Created)
            {
                throw new Exception($"Could not create certificate request, response code: = {certRequ.StatusCode}");
            }

            var keyGenFile   = Path.Combine(certificatePath, $"{certificatename}-gen-key.json");
            var keyPemFile   = Path.Combine(certificatePath, $"{certificatename}-key.pem");
            var csrGenFile   = Path.Combine(certificatePath, $"{certificatename}-gen-csr.json");
            var csrPemFile   = Path.Combine(certificatePath, $"{certificatename}-csr.pem");
            var crtDerFile   = Path.Combine(certificatePath, $"{certificatename}-crt.der");
            var crtPemFile   = Path.Combine(certificatePath, $"{certificatename}-crt.pem");
            var chainPemFile = Path.Combine(certificatePath, $"{certificatename}-chain.pem");
            var pfxPemFile   = Path.Combine(certificatePath, $"{certificatename}.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);
            }

            this.Logger.LogInfo(true, $"Saving Certificate to {crtDerFile}");

            // Log.Information("Saving Certificate to {crtDerFile}", 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);
            }

            cp.Dispose();

            var ret = new CertificatePaths()
            {
                chainPemFile = chainPemFile,
                crtDerFile   = crtDerFile,
                crtPemFile   = crtPemFile,
                csrGenFile   = csrGenFile,
                csrPemFile   = csrPemFile,
                keyGenFile   = keyGenFile,
                keyPemFile   = keyPemFile,
                name         = certificatename,
                pfxPemFile   = pfxPemFile
            };

            // Generate the PFX version manually
            UtilsCertificate.CreatePfXfromPem(ret.crtPemFile, ret.keyPemFile, ret.pfxPemFile, null);

            return(ret);
        }