Exemplo n.º 1
0
        public async Task <StatusMessage> RevokeCertificate(ILog log, ManagedCertificate managedCertificate)
        {
            // get current PFX, extract DER bytes
            try
            {
                var pkcs = new Org.BouncyCastle.Pkcs.Pkcs12Store(File.Open(managedCertificate.CertificatePath, FileMode.Open), "".ToCharArray());

                var certAliases = pkcs.Aliases.GetEnumerator();
                certAliases.MoveNext();

                var certEntry   = pkcs.GetCertificate(certAliases.Current.ToString());
                var certificate = certEntry.Certificate;

                // revoke certificat
                var der = certificate.GetEncoded();
                await _acme.RevokeCertificate(der, RevocationReason.Unspecified, null);
            }
            catch (Exception exp)
            {
                return(new StatusMessage {
                    IsOK = false, Message = $"Failed to revoke certificate: {exp.Message}"
                });
            }

            return(new StatusMessage {
                IsOK = true, Message = "Certificate revoked"
            });
        }
Exemplo n.º 2
0
        public async Task <StatusMessage> RevokeCertificate(ILog log, ManagedCertificate managedCertificate)
        {
            try
            {
                var pkcs = new Org.BouncyCastle.Pkcs.Pkcs12Store(File.Open(managedCertificate.CertificatePath, FileMode.Open), "".ToCharArray());

                var certAliases = pkcs.Aliases.GetEnumerator();
                certAliases.MoveNext();

                var certEntry   = pkcs.GetCertificate(certAliases.Current.ToString());
                var certificate = certEntry.Certificate;

                // revoke certificate
                var der = certificate.GetEncoded();
                await _client.RevokeCertificateAsync(der, RevokeReason.Unspecified);

                return(new StatusMessage {
                    IsOK = true, Message = $"Certificate revoke completed."
                });
            }
            catch (Exception exp)
            {
                return(new StatusMessage {
                    IsOK = false, Message = $"Failed to revoke certificate: {exp.Message}"
                });
            }
        }
        public string AddSignature(string PathSource, string PathTarget, string CertPath, string CertPass, int lx = 100, int ly = 100, int ux = 250, int uy = 150, int page = 1, bool Visible = true)
        {
            try
            {
                Org.BouncyCastle.Crypto.AsymmetricKeyParameter Akp   = null;
                Org.BouncyCastle.X509.X509Certificate[]        Chain = null;

                string alias = null;
                Org.BouncyCastle.Pkcs.Pkcs12Store pk12;


                pk12 = new Org.BouncyCastle.Pkcs.Pkcs12Store(new System.IO.FileStream(CertPath, System.IO.FileMode.Open, System.IO.FileAccess.Read), CertPass.ToCharArray());

                IEnumerable aliases = pk12.Aliases;
                foreach (string aliasTemp in aliases)
                {
                    alias = aliasTemp;
                    if (pk12.IsKeyEntry(alias))
                    {
                        break;
                    }
                }

                Akp = pk12.GetKey(alias).Key;
                Org.BouncyCastle.Pkcs.X509CertificateEntry[] ce = pk12.GetCertificateChain(alias);
                Chain = new Org.BouncyCastle.X509.X509Certificate[ce.Length];
                for (int k = 0; k < ce.Length; ++k)
                {
                    Chain[k] = ce[k].Certificate;
                }

                iTextSharp.text.pdf.PdfReader              reader = new iTextSharp.text.pdf.PdfReader(PathSource);
                iTextSharp.text.pdf.PdfStamper             st     = iTextSharp.text.pdf.PdfStamper.CreateSignature(reader, new System.IO.FileStream(PathTarget, System.IO.FileMode.Create, System.IO.FileAccess.Write), '\0', null, true);
                iTextSharp.text.pdf.PdfSignatureAppearance sap    = st.SignatureAppearance;

                if (Visible == true)
                {
                    page = (page <1 || page> reader.NumberOfPages) ? 1 : page;
                    sap.SetVisibleSignature(new iTextSharp.text.Rectangle(lx, ly, ux, uy), page, null);
                }

                sap.CertificationLevel = iTextSharp.text.pdf.PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;

                // digital signature - http://itextpdf.com/examples/iia.php?id=222

                IExternalSignature es = new PrivateKeySignature(Akp, "SHA-256"); // "BC"
                MakeSignature.SignDetached(sap, es, new X509Certificate[] { pk12.GetCertificate(alias).Certificate }, null, null, null, 0, CryptoStandard.CMS);

                st.Close();
                return("");
            }
            catch (Exception e)
            {
                return(e.Message);
            }
        }
Exemplo n.º 4
0
        private (RsaPrivateCrtKeyParameters rsaPrivateKey, X509Certificate certificate) Extract(Stream stream, string password)
        {
            Org.BouncyCastle.Pkcs.Pkcs12Store p12Store = new Org.BouncyCastle.Pkcs.Pkcs12Store(stream, password.ToCharArray());
            string keyEntryAlias = p12Store.Aliases.Cast <string>().FirstOrDefault(t => p12Store.IsKeyEntry(t));

            Org.BouncyCastle.Pkcs.X509CertificateEntry x509CertEntry = p12Store.GetCertificate(keyEntryAlias);

            Org.BouncyCastle.Pkcs.AsymmetricKeyEntry keyEntry = p12Store.GetKey(keyEntryAlias);
            return(keyEntry.Key as RsaPrivateCrtKeyParameters, x509CertEntry.Certificate);
        }
Exemplo n.º 5
0
        public X509Crl GenerateCRL()
        {
            var coreCApkcs = new Org.BouncyCastle.Pkcs.Pkcs12Store(
                new FileStream(CAConfig.CoreCACertPath, FileMode.Open, FileAccess.Read),
                "".ToCharArray()
                );

            string alias = System.Environment.MachineName;

            Org.BouncyCastle.X509.X509Certificate coreCaCert = coreCApkcs.GetCertificate(alias).Certificate;
            X509V2CrlGenerator crlGen = new X509V2CrlGenerator();

            DateTime now = DateTime.UtcNow;

            crlGen.SetIssuerDN(coreCaCert.SubjectDN);
            crlGen.SetThisUpdate(now);
            crlGen.SetNextUpdate(now.AddMinutes(Constants.CRLNextUpdatedIntervalMinutes));

            var revokedPubCerts = _dbContext.PublicCertificates.Where(p => p.IsRevoked);

            foreach (PublicCertificate pubCert in revokedPubCerts)
            {
                crlGen.AddCrlEntry(
                    new Org.BouncyCastle.Math.BigInteger(pubCert.GetSerialNumber().SerialNrBytes),
                    now,
                    Org.BouncyCastle.Asn1.X509.CrlReason.KeyCompromise
                    );
            }

            crlGen.AddExtension(
                Org.BouncyCastle.Asn1.X509.X509Extensions.AuthorityKeyIdentifier,
                false,
                new Org.BouncyCastle.X509.Extension.AuthorityKeyIdentifierStructure(
                    coreCaCert.GetPublicKey()
                    )
                );

            X509Crl crl = crlGen.Generate(
                new Org.BouncyCastle.Crypto.Operators.Asn1SignatureFactory(
                    "SHA512WITHRSA",
                    coreCApkcs.GetKey(alias).Key
                    )
                );

            _logger.LogInformation(
                string.Format(
                    "Generated CRL at {0} valid for {1} minutes",
                    now,
                    Constants.CRLNextUpdatedIntervalMinutes
                    )
                );

            return(crl);
        }
Exemplo n.º 6
0
        public static void Test()
        {
            string pfxLocation = @"D:\lol\certificate.pfx";

            pfxLocation = @"D:\username\Desktop\DesktopArchiv\20180329_Desktop\CORMailService\CORMailService\CORMailService\CORMailService_TemporaryKey.pfx";


            Org.BouncyCastle.Pkcs.Pkcs12Store store = null;

            using (System.IO.Stream pfxStream = System.IO.File.OpenRead(pfxLocation))
            {
                store = new Org.BouncyCastle.Pkcs.Pkcs12Store(pfxStream, "".ToCharArray());
            }

            System.Console.WriteLine(store);

            foreach (string alias in store.Aliases)
            {
                System.Console.WriteLine(alias);

                // https://7thzero.com/blog/bouncy-castle-convert-a-bouncycastle-asymmetrickeyentry-to-a-.ne
                if (store.IsKeyEntry((string)alias))
                {
                    Org.BouncyCastle.Pkcs.AsymmetricKeyEntry keyEntry = store.GetKey(alias);
                    System.Console.WriteLine(keyEntry);
                    AsymmetricKeyParameter privateKey = keyEntry.Key;
                    System.Console.WriteLine(privateKey.IsPrivate);
                } // End if (store.IsKeyEntry((string)alias))


                Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry = store.GetCertificate(alias);
                Org.BouncyCastle.X509.X509Certificate      cert      = certEntry.Certificate;
                System.Console.WriteLine(cert);

                AsymmetricKeyParameter publicKey = cert.GetPublicKey();
                System.Console.WriteLine(publicKey);

                // Org.BouncyCastle.Pkcs.X509CertificateEntry[] chain = store.GetCertificateChain(alias);

                // System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(cert.GetEncoded());
                // Org.BouncyCastle.Security.DotNetUtilities.ToX509Certificate(cert);

                System.Security.Cryptography.X509Certificates.X509Certificate2 cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(pfxLocation);
                // cert2.PrivateKey = null;

                if (cert2.HasPrivateKey)
                {
                    System.Console.WriteLine(cert2.PrivateKey);
                }
            }
        }
        public static byte[] CreatePfxBytes(
            Org.BouncyCastle.X509.X509Certificate certificate
            , Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey
            , string password = "")
        {
            byte[] pfxBytes = null;

            // create certificate entry
            Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry =
                new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate);

            Org.BouncyCastle.Asn1.X509.X509Name name = new Org.BouncyCastle.Asn1.X509.X509Name(certificate.SubjectDN.ToString());
            string friendlyName = (string)name.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.O)[0];

            if (System.StringComparer.InvariantCultureIgnoreCase.Equals("Skynet Earth Inc.", friendlyName))
            {
                friendlyName = "Skynet Certification Authority";
            }

            Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder builder = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);


            Org.BouncyCastle.Pkcs.Pkcs12Store store = builder.Build();

            store.SetCertificateEntry(friendlyName, certEntry);

            // create store entry
            store.SetKeyEntry(
                friendlyName
                , new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(privateKey)
                , new Org.BouncyCastle.Pkcs.X509CertificateEntry[] { certEntry }
                );



            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                // Cert is contained in store
                // null: no password, "": an empty passwords
                // note: Linux needs empty password on null...
                store.Save(stream, password == null ? "".ToCharArray() : password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
                // stream.Position = 0;
                pfxBytes = Org.BouncyCastle.Pkcs.Pkcs12Utilities.ConvertToDefiniteLength(stream.ToArray());
            } // End Using stream

            return(pfxBytes);
        } // End Function CreatePfxBytes
Exemplo n.º 8
0
        // DumpPfx(ee25519Cert, subject, caKey25519);
        public static void DumpPfx(
            Org.BouncyCastle.X509.X509Certificate bouncyCert
            , Org.BouncyCastle.Asn1.X509.X509Name subject
            , Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair pair)
        {
            Org.BouncyCastle.Pkcs.Pkcs12Store          store            = new Org.BouncyCastle.Pkcs.Pkcs12Store();
            Org.BouncyCastle.Pkcs.X509CertificateEntry certificateEntry =
                new Org.BouncyCastle.Pkcs.X509CertificateEntry(bouncyCert);

            store.SetCertificateEntry(subject.ToString(), certificateEntry);

            store.SetKeyEntry(subject.ToString(),
                              new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(pair.Private)
                              , new[] { certificateEntry }
                              );

            Org.BouncyCastle.Security.SecureRandom random =
                new Org.BouncyCastle.Security.SecureRandom(
                    new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator()
                    );

            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                string tempPassword = "******";
                store.Save(stream, tempPassword.ToCharArray(), random);
                using (System.Security.Cryptography.X509Certificates.X509Certificate2 cert =
                           new System.Security.Cryptography.X509Certificates.X509Certificate2(
                               stream.ToArray()
                               , tempPassword
                               , System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet
                               | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable)
                       )
                {
                    System.Text.StringBuilder builder = new System.Text.StringBuilder();

                    builder.AppendLine("-----BEGIN CERTIFICATE-----");
                    builder.AppendLine(System.Convert.ToBase64String(
                                           cert.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert)
                                           , System.Base64FormattingOptions.InsertLineBreaks)
                                       );
                    builder.AppendLine("-----END CERTIFICATE-----");

                    // PFX
                    //builder.ToString().Dump("Self-signed Certificate");
                } // End Using cert
            }     // End Using stream
        }         // End Sub DumpPfx
Exemplo n.º 9
0
        /// <summary>
        /// Imports certificates and private keys from the specified stream.
        /// </summary>
        /// <remarks>
        /// <para>Imports certificates and private keys from the specified pkcs12 stream.</para>
        /// </remarks>
        /// <param name="stream">The stream to import.</param>
        /// <param name="password">The password to unlock the stream.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="password"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An error occurred reading the stream.
        /// </exception>
        public void Import(System.IO.Stream stream, string password)
        {
            if (stream == null)
            {
                throw new System.ArgumentNullException(nameof(stream));
            }

            if (password == null)
            {
                throw new System.ArgumentNullException(nameof(password));
            }

            Org.BouncyCastle.Pkcs.Pkcs12Store pkcs12 =
                new Org.BouncyCastle.Pkcs.Pkcs12Store(stream, password.ToCharArray());

            foreach (string alias in pkcs12.Aliases)
            {
                if (pkcs12.IsKeyEntry(alias))
                {
                    Org.BouncyCastle.Pkcs.X509CertificateEntry[] chain = pkcs12.GetCertificateChain(alias);
                    Org.BouncyCastle.Pkcs.AsymmetricKeyEntry     entry = pkcs12.GetKey(alias);

                    for (int i = 0; i < chain.Length; i++)
                    {
                        if (unique.Add(chain[i].Certificate))
                        {
                            certs.Add(chain[i].Certificate);
                        }
                    }

                    if (entry.Key.IsPrivate)
                    {
                        keys.Add(chain[0].Certificate, entry.Key);
                    }
                }
                else if (pkcs12.IsCertificateEntry(alias))
                {
                    Org.BouncyCastle.Pkcs.X509CertificateEntry entry = pkcs12.GetCertificate(alias);

                    if (unique.Add(entry.Certificate))
                    {
                        certs.Add(entry.Certificate);
                    }
                }
            }
        }
Exemplo n.º 10
0
        private void importbutton_Click(object sender, EventArgs e)
        {
            OpenFileDialog opener = new OpenFileDialog();

            opener.InitialDirectory = Environment.CurrentDirectory;
            opener.Filter           = "公钥证书|*.cer|私钥证书|*.pfx";
            opener.RestoreDirectory = true;
            opener.FilterIndex      = 1;
            if (opener.ShowDialog() == DialogResult.OK)
            {
                var fname     = opener.FileName;
                var cerin     = File.OpenText(fname);
                var txtreader = cerin.ReadToEnd();
                if (Path.GetExtension(fname) == ".cer")
                {
                    certificate.Text = txtreader;
                    txtreader        = txtreader.Replace("-----BEGIN CERTIFICATE-----", "");
                    txtreader        = txtreader.Replace("-----END CERTIFICATE-----", "");
                    txtreader        = txtreader.Replace("\r\n", "");

                    var certb   = Convert.FromBase64String(txtreader);
                    var cholder = new X509CertificateParser();
                    bouncy = cholder.ReadCertificate(certb);
                    cert   = new System.Security.Cryptography.X509Certificates.X509Certificate2(certb);

                    nametxt.Text = bouncy.IssuerDN.ToString();

                    pubtxt.Text = Convert.ToBase64String(cert.GetPublicKey());
                    //Subtxt.Text = cert.Subject;
                }
                else if (Path.GetExtension(fname) == ".pfx")
                {
                    var pfxin  = File.ReadAllBytes(fname);
                    var store  = new Org.BouncyCastle.Pkcs.Pkcs12Store();
                    var stream = new MemoryStream(pfxin);
                    store.Load(stream, pswtxt.Text.ToCharArray());
                    foreach (string al in store.Aliases)
                    {
                        Castlekey = store.GetKey(al).Key;
                        Castle    = store.GetCertificate(al).Certificate;
                    }
                }
            }
        }
Exemplo n.º 11
0
        public async Task Save(CertificateInfo input)
        {
            var dest = PathForIdentifier(input.CommonName.Value);

            _log.Information("Copying certificate to the pfx folder {dest}", dest);
            try
            {
                var collection = new X509Certificate2Collection
                {
                    input.Certificate
                };
                collection.AddRange(input.Chain.ToArray());
                var ms      = new MemoryStream(collection.Export(X509ContentType.Pfx) !);
                var bcPfx   = new bc.Pkcs.Pkcs12Store(ms, Array.Empty <char>());
                var aliases = bcPfx.Aliases.OfType <string>().ToList();
                var key     = default(bc.Pkcs.AsymmetricKeyEntry);
                var chain   = default(bc.Pkcs.X509CertificateEntry[]);
                foreach (var alias in aliases)
                {
                    if (bcPfx.IsKeyEntry(alias))
                    {
                        key   = bcPfx.GetKey(alias);
                        chain = bcPfx.GetCertificateChain(alias);
                        break;
                    }
                }
                using var fs = new FileInfo(dest).OpenWrite();
                bcPfx        = new bc.Pkcs.Pkcs12Store();
                bcPfx.SetKeyEntry(input.CommonName.Value, key, chain);
                bcPfx.Save(fs, _password?.ToCharArray(), new bc.Security.SecureRandom());
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Error copying certificate to pfx path");
            }
            input.StoreInfo.TryAdd(
                GetType(),
                new StoreInfo()
            {
                Name = PfxFileOptions.PluginName,
                Path = _path
            });
        }
Exemplo n.º 12
0
        public static X509Certificate2 OpenCertificate(string pfxPath, string contrasenia)
        {
            var ms = new MemoryStream(File.ReadAllBytes(pfxPath));

            var st = new Org.BouncyCastle.Pkcs.Pkcs12Store(ms, contrasenia.ToCharArray());

            var alias     = st.Aliases.Cast <string>().FirstOrDefault(p => st.IsCertificateEntry(p));
            var keyEntryX = st.GetCertificate(alias);

            var x509 = new X509Certificate2(DotNetUtilities.ToX509Certificate(keyEntryX.Certificate));

            alias = st.Aliases.Cast <string>().FirstOrDefault(p => st.IsKeyEntry(p));
            var keyEntry             = st.GetKey(alias);
            var intermediateProvider = (RSACryptoServiceProvider)DotNetUtilities.ToRSA((Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)keyEntry.Key);

            x509.PrivateKey = intermediateProvider;

            return(x509);
        }
Exemplo n.º 13
0
        } // End Sub WithMsPfx

        public static PfxData Read(string pfxFilePath, string password = "")
        {
            Org.BouncyCastle.Pkcs.Pkcs12Store store = null;

            using (System.IO.Stream pfxStream = System.IO.File.OpenRead(pfxFilePath))
            {
                store = new Org.BouncyCastle.Pkcs.Pkcs12Store(pfxStream, password.ToCharArray());
            }

            // System.Console.WriteLine(store);


            foreach (string alias in store.Aliases)
            {
                Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry = store.GetCertificate(alias);
                Org.BouncyCastle.X509.X509Certificate      cert      = certEntry.Certificate;

                // Org.BouncyCastle.Crypto.AsymmetricKeyParameter publicKey = cert.GetPublicKey();
                // System.Console.WriteLine(publicKey);

                // https://7thzero.com/blog/bouncy-castle-convert-a-bouncycastle-asymmetrickeyentry-to-a-.ne
                if (store.IsKeyEntry(alias))
                {
                    Org.BouncyCastle.Pkcs.AsymmetricKeyEntry       keyEntry   = store.GetKey(alias);
                    Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey = keyEntry.Key;

                    if (privateKey.IsPrivate)
                    {
                        return new PfxData()
                               {
                                   Certificate = cert,
                                   PrivateKey  = privateKey
                               }
                    }
                    ;
                } // End if (store.IsKeyEntry((string)alias))
            }     // Next alias

            return(null);
        } // End Sub Read
Exemplo n.º 14
0
        public static Org.BouncyCastle.X509.X509Certificate LoadPfx(string path, string password)
        {
            Org.BouncyCastle.X509.X509Certificate      cert = null;
            Org.BouncyCastle.Pkcs.X509CertificateEntry ce   = null;

            using (System.IO.FileStream fs = System.IO.File.Open(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
            {
                Org.BouncyCastle.Pkcs.Pkcs12Store store = new Org.BouncyCastle.Pkcs.Pkcs12Store(fs, password.ToCharArray());

                foreach (string thisAlias in store.Aliases)
                {
                    System.Console.WriteLine(thisAlias);

                    ce   = store.GetCertificate(thisAlias);
                    cert = ce.Certificate;
                    break;
                } // Next thisAlias
            }     // End Using fs

            System.Console.WriteLine(cert);
            return(cert);
        } // End Function LoadPfx
Exemplo n.º 15
0
        /// <summary>
        /// Parse bytes to a usable certificate
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="friendlyName"></param>
        /// <param name="pk"></param>
        /// <returns></returns>
        private X509Certificate2Collection ParseCertificate(byte[] bytes, string friendlyName, AsymmetricKeyParameter?pk)
        {
            // Build pfx archive including any intermediates provided
            _log.Verbose("Parsing certificate from {bytes} bytes received", bytes.Length);
            var          text        = Encoding.UTF8.GetString(bytes);
            var          pfx         = new bc.Pkcs.Pkcs12Store();
            var          startIndex  = 0;
            const string startString = "-----BEGIN CERTIFICATE-----";
            const string endString   = "-----END CERTIFICATE-----";

            while (true)
            {
                startIndex = text.IndexOf(startString, startIndex);
                if (startIndex < 0)
                {
                    break;
                }
                var endIndex = text.IndexOf(endString, startIndex);
                if (endIndex < 0)
                {
                    break;
                }
                endIndex += endString.Length;
                var pem = text[startIndex..endIndex];
Exemplo n.º 16
0
        /// <summary>
        /// Request certificate from the ACME server
        /// </summary>
        /// <param name="binding"></param>
        /// <returns></returns>
        public CertificateInfo RequestCertificate(ICsrPlugin csrPlugin, RunLevel runLevel, Renewal renewal, Target target, OrderDetails order)
        {
            // What are we going to get?
            var pfxFileInfo = new FileInfo(PfxFilePath(renewal));

            // Determine/check the common name
            var identifiers     = target.GetHosts(false);
            var commonNameUni   = target.CommonName;
            var commonNameAscii = string.Empty;

            if (!string.IsNullOrWhiteSpace(commonNameUni))
            {
                var idn = new IdnMapping();
                commonNameAscii = idn.GetAscii(commonNameUni);
                if (!identifiers.Contains(commonNameAscii, StringComparer.InvariantCultureIgnoreCase))
                {
                    _log.Warning($"Common name {commonNameUni} provided is invalid.");
                    commonNameAscii = identifiers.First();
                    commonNameUni   = idn.GetUnicode(commonNameAscii);
                }
            }

            // Determine the friendly name
            var friendlyName = renewal.FriendlyName;

            if (string.IsNullOrEmpty(friendlyName))
            {
                friendlyName = target.FriendlyName;
            }
            if (string.IsNullOrEmpty(friendlyName))
            {
                friendlyName = commonNameUni;
            }

            // Try using cached certificate first to avoid rate limiting during
            // (initial?) deployment troubleshooting. Real certificate requests
            // will only be done once per day maximum unless the --force parameter
            // is used.
            var cache = CachedInfo(renewal);

            if (cache != null &&
                cache.CacheFile.LastWriteTime > DateTime.Now.AddDays(Settings.Default.CertificateCacheDays * -1) &&
                cache.Match(target))
            {
                if (runLevel.HasFlag(RunLevel.IgnoreCache))
                {
                    _log.Warning("Cached certificate available but not used with --{switch}. Use 'Renew specific' or " +
                                 "'Renew all' in the main menu to run unscheduled renewals without hitting rate limits.",
                                 nameof(MainArguments.Force).ToLower());
                }
                else
                {
                    _log.Warning("Using cached certificate for {friendlyName}. To force issue of a new certificate within " +
                                 "24 hours, delete the .pfx file from the CertificatePath or run with the --{switch} switch. " +
                                 "Be ware that you might run into rate limits doing so.",
                                 friendlyName,
                                 nameof(MainArguments.Force).ToLower());
                    return(cache);
                }
            }

            var csr      = csrPlugin.GenerateCsr(commonNameAscii, identifiers);
            var csrBytes = csr.CreateSigningRequest();

            order = _client.SubmitCsr(order, csrBytes);
            File.WriteAllText(GetPath(renewal, "-csr.pem"), _pemService.GetPem("CERTIFICATE REQUEST", csrBytes));

            _log.Information("Requesting certificate {friendlyName}", friendlyName);
            var rawCertificate = _client.GetCertificate(order);

            if (rawCertificate == null)
            {
                throw new Exception($"Unable to get certificate");
            }

            var certificate       = new X509Certificate2(rawCertificate);
            var certificateExport = certificate.Export(X509ContentType.Cert);
            var crtPem            = _pemService.GetPem("CERTIFICATE", certificateExport);

            // Get issuer certificate
            var issuerCertificate       = new X509Certificate2(rawCertificate.Skip(certificateExport.Length).ToArray());
            var issuerCertificateExport = issuerCertificate.Export(X509ContentType.Cert);
            var issuerPem = _pemService.GetPem("CERTIFICATE", issuerCertificateExport);

            // Build pfx archive
            var pfx                = new bc.Pkcs.Pkcs12Store();
            var bcCertificate      = _pemService.ParsePem <bc.X509.X509Certificate>(crtPem);
            var bcCertificateEntry = new bc.Pkcs.X509CertificateEntry(bcCertificate);
            var bcCertificateAlias = bcCertificate.SubjectDN.ToString();
            var bcPrivateKeyEntry  = new bc.Pkcs.AsymmetricKeyEntry(csrPlugin.GetPrivateKey());

            pfx.SetCertificateEntry(bcCertificateAlias, bcCertificateEntry);
            pfx.SetKeyEntry(bcCertificateAlias, bcPrivateKeyEntry, new[] { bcCertificateEntry });

            var bcIssuer      = _pemService.ParsePem <bc.X509.X509Certificate>(issuerPem);
            var bcIssuerEntry = new bc.Pkcs.X509CertificateEntry(bcIssuer);
            var bcIssuerAlias = bcIssuer.SubjectDN.ToString();

            pfx.SetCertificateEntry(bcIssuerAlias, bcIssuerEntry);

            var pfxStream = new MemoryStream();

            pfx.Save(pfxStream, null, new bc.Security.SecureRandom());
            pfxStream.Position = 0;
            using (var pfxStreamReader = new BinaryReader(pfxStream))
            {
                var tempPfx = new X509Certificate2(
                    pfxStreamReader.ReadBytes((int)pfxStream.Length),
                    (string)null,
                    X509KeyStorageFlags.MachineKeySet |
                    X509KeyStorageFlags.PersistKeySet |
                    X509KeyStorageFlags.Exportable);
                if (csrPlugin.CanConvert())
                {
                    try
                    {
                        var converted = csrPlugin.Convert(tempPfx.PrivateKey);
                        if (converted != null)
                        {
                            tempPfx.PrivateKey = converted;
                        }
                    }
                    catch
                    {
                        _log.Warning("Private key conversion error.");
                    }
                }

                tempPfx.FriendlyName = $"{friendlyName} {DateTime.Now.ToUserString()}";
                File.WriteAllBytes(pfxFileInfo.FullName, tempPfx.Export(X509ContentType.Pfx, renewal.PfxPassword?.Value));
                pfxFileInfo.Refresh();
            }

            // Update LastFriendlyName so that the user sees
            // the most recently issued friendlyName in
            // the WACS GUI
            renewal.LastFriendlyName = friendlyName;

            // Recreate X509Certificate2 with correct flags for Store/Install
            return(new CertificateInfo()
            {
                Certificate = ReadForUse(pfxFileInfo, renewal.PfxPassword?.Value),
                CacheFile = pfxFileInfo,
                CacheFilePassword = renewal.PfxPassword?.Value
            });
        }
Exemplo n.º 17
0
        void ValidateParameters(Common.ParametersValidation validationRequest, ref string logMessage, ref bool passed, XmlNode test)
        {
            foreach (Common.ValidationRule rule in validationRequest.ValidationRules)
            {
                string parameterPath = string.Format("RequestParameters/{0}", rule.ParameterPath);

                switch (rule.Type)
                {
                case ParameterType.String:
                    CommonCompare.StringCompare(parameterPath, rule.ParameterName, (string)rule.Value,
                                                ref logMessage, ref passed, test);
                    break;

                case ParameterType.Int:
                    CommonCompare.IntCompare(parameterPath, rule.ParameterName, (int)rule.Value,
                                             ref logMessage, ref passed, test);
                    break;

                case ParameterType.OptionalInt:
                    int?value = (int?)rule.Value;
                    if (CommonCompare.Exist2(parameterPath, rule.ParameterName, value.HasValue, ref logMessage, ref passed, test))
                    {
                        CommonCompare.IntCompare(parameterPath, rule.ParameterName, value.Value, ref logMessage, ref passed, test);
                    }
                    break;

                case ParameterType.OptionalBool:
                    if (rule.ValueSpecified)
                    {
                        CommonCompare.StringCompare(parameterPath, rule.ParameterName, ((bool)rule.Value).ToString(),
                                                    ref logMessage, ref passed, test);
                    }
                    else
                    {
                        CommonCompare.Exist2(parameterPath, rule.ParameterName, rule.ValueSpecified,
                                             ref logMessage, ref passed, test);
                    }
                    break;

                case ParameterType.OptionalString:
                {
                    string stringValue = (string)rule.Value;
                    if (CommonCompare.Exist2(parameterPath, rule.ParameterName, stringValue != null, ref logMessage, ref passed, test))
                    {
                        CommonCompare.StringCompare(parameterPath, rule.ParameterName, (string)rule.Value,
                                                    ref logMessage, ref passed, test);
                    }
                }
                break;

                case ParameterType.OptionalElement:
                {
                    CommonCompare.Exist2(parameterPath, rule.ParameterName, rule.Value != null, ref logMessage, ref passed, test);
                }
                break;

                case ParameterType.OptionalElementBoolFlag:
                {
                    CommonCompare.Exist2(parameterPath, rule.ParameterName, (bool)rule.Value, ref logMessage, ref passed, test);
                }
                break;

                case ParameterType.StringArray:
                {
                    CommonCompare.StringArrayCompare(parameterPath, rule.ParameterName, (string[])rule.Value,
                                                     ref logMessage, ref passed, test);
                }
                break;

                case ParameterType.Log:
                {
                    if (rule.Value.GetType().ToString() == "System.Byte[]")
                    {
                        logMessage = logMessage + rule.ParameterName + " = [Check it manually!]";
                    }
                    else
                    {
                        logMessage = logMessage + rule.ParameterName + " = " + rule.Value.ToString();
                    }
                }
                break;

                case ParameterType.OptionalQName:
                {
                    XmlQualifiedName QNameValue = (XmlQualifiedName)rule.Value;
                    if (CommonCompare.Exist2(parameterPath, rule.ParameterName, QNameValue != null, ref logMessage, ref passed, test))
                    {
                        CommonCompare.StringCompare(parameterPath + "/Namespace", rule.ParameterName + "/Namespace", QNameValue.Namespace,
                                                    ref logMessage, ref passed, test);
                        CommonCompare.StringCompare(parameterPath + "/Name", rule.ParameterName + "/Name", QNameValue.Name,
                                                    ref logMessage, ref passed, test);
                    }
                }
                break;

                case ParameterType.X509Cert:
                {
                    Org.BouncyCastle.X509.X509Certificate cert = (new Org.BouncyCastle.X509.X509CertificateParser()).ReadCertificate((byte[])rule.Value);
                    logMessage = logMessage + "\r\n";
                    logMessage = logMessage + rule.ParameterName + ": " + "\r\n" + cert.ToString();
                    logMessage = logMessage + "\r\n";
                    //TextWriter textWriter = new StringWriter();
                    //Org.BouncyCastle.Utilities.IO.Pem.PemWriter pemWriter = new Org.BouncyCastle.Utilities.IO.Pem.PemWriter(textWriter);
                    //pemWriter.WriteObject(cert.CertificateStructure.SubjectPublicKeyInfo.PublicKeyData);
                    //pemWriter.Writer.Flush();

                    //string privateKey = textWriter.ToString();
                    logMessage = logMessage + rule.ParameterName + "(PubK): " + "\r\n" + cert.CertificateStructure.SubjectPublicKeyInfo.PublicKeyData.ToString();
                    logMessage = logMessage + "\r\n";
                    logMessage = logMessage + rule.ParameterName + "(SignatureAlgorithm): " + "\r\n" + cert.CertificateStructure.SignatureAlgorithm.ObjectID.ToString();
                    logMessage = logMessage + "\r\n";
                }
                break;

                case ParameterType.PKCS10:
                {
                    Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest pkcs10 = new Org.BouncyCastle.Pkcs.Pkcs10CertificationRequest((byte[])rule.Value);
                    logMessage = logMessage + "\r\n";
                    logMessage = logMessage + rule.ParameterName + ": " + "\r\n" + pkcs10.ToString();
                    logMessage = logMessage + "\r\n";
                }
                break;

                case ParameterType.PKCS12WithoutPassphrase:
                {
                    Org.BouncyCastle.Pkcs.Pkcs12Store pkcs12Store = new Org.BouncyCastle.Pkcs.Pkcs12Store();
                    pkcs12Store.Load(new MemoryStream((byte[])rule.Value), ("").ToArray());

                    logMessage = logMessage + rule.ParameterName + ": " + "\r\n";


                    foreach (string alias in pkcs12Store.Aliases)
                    {
                        logMessage = logMessage + "\r\n";
                        logMessage = logMessage + "Alias = " + alias + "\r\n";
                        logMessage = logMessage + "Certificate = " + pkcs12Store.GetCertificate(alias).Certificate.ToString();
                    }

                    logMessage = logMessage + "\r\n";
                }
                break;

                case ParameterType.CRL:
                {
                    Org.BouncyCastle.X509.X509Crl crl = (new Org.BouncyCastle.X509.X509CrlParser()).ReadCrl((byte[])rule.Value);
                    logMessage = logMessage + "\r\n";
                    logMessage = logMessage + rule.ParameterName + ": " + "\r\n" + crl.ToString();
                    logMessage = logMessage + "\r\n";
                }
                break;

                case ParameterType.Float:
                {
                    CommonCompare.FloatCompare(parameterPath, rule.ParameterName, (float)rule.Value,
                                               ref logMessage, ref passed, test);
                }
                break;

                case ParameterType.OptionalFloat:
                    float?fvalue = (float?)rule.Value;
                    if (CommonCompare.Exist2(parameterPath, rule.ParameterName, fvalue.HasValue, ref logMessage, ref passed, test))
                    {
                        CommonCompare.FloatCompare(parameterPath, rule.ParameterName, (float)rule.Value,
                                                   ref logMessage, ref passed, test);
                    }
                    break;
                }
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Request certificate from the ACME server
        /// </summary>
        /// <param name="csrPlugin">Plugin used to generate CSR if it has not been provided in the target</param>
        /// <param name="runLevel"></param>
        /// <param name="renewal"></param>
        /// <param name="target"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public async Task <CertificateInfo> RequestCertificate(ICsrPlugin?csrPlugin, RunLevel runLevel, Order order)
        {
            if (order.Details == null)
            {
                throw new InvalidOperationException();
            }

            // What are we going to get?
            var cacheKey    = CacheKey(order);
            var pfxFileInfo = new FileInfo(GetPath(order.Renewal, $"-{cacheKey}{PfxPostFix}"));

            // Determine/check the common name
            var identifiers     = order.Target.GetHosts(false);
            var commonNameUni   = order.Target.CommonName;
            var commonNameAscii = string.Empty;

            if (!string.IsNullOrWhiteSpace(commonNameUni))
            {
                var idn = new IdnMapping();
                commonNameAscii = idn.GetAscii(commonNameUni);
                if (!identifiers.Contains(commonNameAscii, StringComparer.InvariantCultureIgnoreCase))
                {
                    _log.Warning($"Common name {commonNameUni} provided is invalid.");
                    commonNameAscii = identifiers.First();
                    commonNameUni   = idn.GetUnicode(commonNameAscii);
                }
            }

            // Determine the friendly name base (for the renewal)
            var friendlyNameBase = order.Renewal.FriendlyName;

            if (string.IsNullOrEmpty(friendlyNameBase))
            {
                friendlyNameBase = order.Target.FriendlyName;
            }
            if (string.IsNullOrEmpty(friendlyNameBase))
            {
                friendlyNameBase = commonNameUni;
            }

            // Determine the friendly name for this specific certificate
            var friendlyNameIntermediate = friendlyNameBase;

            if (!string.IsNullOrEmpty(order.FriendlyNamePart))
            {
                friendlyNameIntermediate += $" [{order.FriendlyNamePart}]";
            }
            var friendlyName = $"{friendlyNameIntermediate} @ {_inputService.FormatDate(DateTime.Now)}";

            // Try using cached certificate first to avoid rate limiting during
            // (initial?) deployment troubleshooting. Real certificate requests
            // will only be done once per day maximum unless the --force parameter
            // is used.
            var cache = CachedInfo(order);

            if (cache != null && cache.CacheFile != null)
            {
                if (cache.CacheFile.LastWriteTime > DateTime.Now.AddDays(_settings.Cache.ReuseDays * -1))
                {
                    if (runLevel.HasFlag(RunLevel.IgnoreCache))
                    {
                        _log.Warning("Cached certificate available on disk but not used due to --{switch} switch.",
                                     nameof(MainArguments.Force).ToLower());
                    }
                    else
                    {
                        _log.Warning("Using cached certificate for {friendlyName}. To force a new request of the " +
                                     "certificate within {days} days, run with the --{switch} switch.",
                                     friendlyNameIntermediate,
                                     _settings.Cache.ReuseDays,
                                     nameof(MainArguments.Force).ToLower());
                        return(cache);
                    }
                }
            }

            if (order.Details.Payload.Status != AcmeClient.OrderValid)
            {
                // Clear cache and write new cert
                ClearCache(order.Renewal, postfix: CsrPostFix);

                if (order.Target.CsrBytes == null)
                {
                    if (csrPlugin == null)
                    {
                        throw new InvalidOperationException("Missing csrPlugin");
                    }
                    // Backwards compatible with existing keys, which are not split per order yet.
                    var keyFile = new FileInfo(GetPath(order.Renewal, $".keys"));
                    if (!keyFile.Exists)
                    {
                        keyFile = new FileInfo(GetPath(order.Renewal, $"-{cacheKey}.keys"));
                    }
                    var csr = await csrPlugin.GenerateCsr(keyFile.FullName, commonNameAscii, identifiers);

                    var keySet = await csrPlugin.GetKeys();

                    order.Target.CsrBytes   = csr.GetDerEncoded();
                    order.Target.PrivateKey = keySet.Private;
                    var csrPath = GetPath(order.Renewal, $"-{cacheKey}{CsrPostFix}");
                    File.WriteAllText(csrPath, _pemService.GetPem("CERTIFICATE REQUEST", order.Target.CsrBytes));
                    _log.Debug("CSR stored at {path} in certificate cache folder {folder}", Path.GetFileName(csrPath), Path.GetDirectoryName(csrPath));
                }

                _log.Verbose("Submitting CSR");
                order.Details = await _client.SubmitCsr(order.Details, order.Target.CsrBytes);

                if (order.Details.Payload.Status != AcmeClient.OrderValid)
                {
                    _log.Error("Unexpected order status {status}", order.Details.Payload.Status);
                    throw new Exception($"Unable to complete order");
                }
            }

            _log.Information("Requesting certificate {friendlyName}", friendlyNameIntermediate);
            var rawCertificate = await _client.GetCertificate(order.Details);

            if (rawCertificate == null)
            {
                throw new Exception($"Unable to get certificate");
            }

            // Build pfx archive including any intermediates provided
            var          text        = Encoding.UTF8.GetString(rawCertificate);
            var          pfx         = new bc.Pkcs.Pkcs12Store();
            var          startIndex  = 0;
            var          endIndex    = 0;
            const string startString = "-----BEGIN CERTIFICATE-----";
            const string endString   = "-----END CERTIFICATE-----";

            while (true)
            {
                startIndex = text.IndexOf(startString, startIndex);
                if (startIndex < 0)
                {
                    break;
                }
                endIndex = text.IndexOf(endString, startIndex);
                if (endIndex < 0)
                {
                    break;
                }
                endIndex += endString.Length;
                var pem           = text[startIndex..endIndex];
Exemplo n.º 19
0
        // System.Security.Cryptography.X509Certificates.X509Certificate2.Import (string fileName);

        // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2.import?view=netframework-4.7.2
        // https://gist.github.com/yutopio/a217a4af63cf6bcf0a530c14c074cf8f
        // https://gist.githubusercontent.com/yutopio/a217a4af63cf6bcf0a530c14c074cf8f/raw/42b2f8cb27f6d22b7e22d65da5bbd0f1ce9b2fff/cert.cs
        // https://stackoverflow.com/questions/44755155/store-pkcs12-container-pfx-with-bouncycastle
        // https://github.com/Worlaf/RSADemo/blob/328692e28e48db92340d55563480c8724d916384/RSADemo_WinForms/frmRsaDemo.cs
        public static void Create(
            string fileName
            , Org.BouncyCastle.X509.X509Certificate certificate
            , Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey
            , string password = "")
        {
            // create certificate entry
            Org.BouncyCastle.Pkcs.X509CertificateEntry certEntry =
                new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate);

            Org.BouncyCastle.Asn1.X509.X509Name name = new Org.BouncyCastle.Asn1.X509.X509Name(certificate.SubjectDN.ToString());
            string friendlyName = name
                                  .GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.O)
                                  .OfType <string>()
                                  .FirstOrDefault();

            if (System.StringComparer.InvariantCultureIgnoreCase.Equals("Skynet Earth Inc.", friendlyName))
            {
                friendlyName = "Skynet Certification Authority";
            }

            // get bytes of private key.
            Org.BouncyCastle.Asn1.Pkcs.PrivateKeyInfo keyInfo = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
            //byte[] keyBytes = keyInfo.ToAsn1Object().GetEncoded();

            Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder builder = new Org.BouncyCastle.Pkcs.Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);



            Org.BouncyCastle.Pkcs.Pkcs12Store store = builder.Build();

            store.SetCertificateEntry(friendlyName, certEntry);

            // create store entry
            store.SetKeyEntry(
                //keyFriendlyName
                friendlyName
                , new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(privateKey)
                , new Org.BouncyCastle.Pkcs.X509CertificateEntry[] { certEntry }
                );


            byte[] pfxBytes = null;

            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                // Cert is contained in store
                // null: no password, "": an empty passwords
                // note: Linux needs empty password on null...
                store.Save(stream, password == null ? "".ToCharArray() : password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
                // stream.Position = 0;
                pfxBytes = stream.ToArray();
            } // End Using stream


#if WITH_MS_PFX
            WithMsPfx(pfxBytes, fileName, password);
#else
            byte[] result = Org.BouncyCastle.Pkcs.Pkcs12Utilities.ConvertToDefiniteLength(pfxBytes);
            // this.StoreCertificate(System.Convert.ToBase64String(result));

            using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(System.IO.File.Open(fileName, System.IO.FileMode.Create)))
            {
                writer.Write(result);
            } // End Using writer
#endif
        }     // End Sub Create
Exemplo n.º 20
0
        private void button1_Click(object sender, EventArgs e)
        {
            string signatureAlgorithm = algtxt.Text;
            var    rsaGenerator       = new RsaKeyPairGenerator();
            var    randomGenerator    = new CryptoApiRandomGenerator();
            var    secureRandom       = new SecureRandom(randomGenerator);
            var    keyParameters      = new KeyGenerationParameters(secureRandom, 1024);

            rsaGenerator.Init(keyParameters);
            var keyPair    = rsaGenerator.GenerateKeyPair();
            var attributes = new System.Collections.Hashtable();

            attributes[X509Name.E]  = emailtxt.Text;  //设置dn信息的邮箱地址
            attributes[X509Name.CN] = towhomtxt.Text; //设置证书的用户,也就是颁发给谁
            attributes[X509Name.O]  = Issuertxt.Text; //设置证书的办法者
            attributes[X509Name.C]  = "Zh";           //证书的语言
            var ordering = new System.Collections.ArrayList();

            ordering.Add(X509Name.E);
            ordering.Add(X509Name.CN);
            ordering.Add(X509Name.O);
            ordering.Add(X509Name.C);
            var generater = new X509V3CertificateGenerator();

            //设置证书序列化号
            generater.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
            //设置颁发者dn信息
            generater.SetIssuerDN(new X509Name(ordering, attributes));
            //设置证书生效时间
            generater.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0)));
            //设置证书失效时间
            generater.SetNotAfter(DateTime.Today.AddDays(365));
            //设置接受者dn信息
            generater.SetSubjectDN(new X509Name(ordering, attributes));
            //设置证书的公钥
            generater.SetPublicKey(keyPair.Public);
            //设置证书的加密算法
            generater.SetSignatureAlgorithm(signatureAlgorithm);
            generater.AddExtension(X509Extensions.BasicConstraints,
                                   true,
                                   new BasicConstraints(false));
            generater.AddExtension(X509Extensions.AuthorityKeyIdentifier,
                                   true,
                                   new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public)));
            // Key usage: Client authentication
            generater.AddExtension(X509Extensions.ExtendedKeyUsage.Id,
                                   false,
                                   new ExtendedKeyUsage(new System.Collections.ArrayList()
            {
                new DerObjectIdentifier("1.3.6.1.5.5.7.3.2")
            }));

            Castle = generater.Generate(keyPair.Private);
            var    store        = new Org.BouncyCastle.Pkcs.Pkcs12Store();
            string friendlyname = Castle.SubjectDN.ToString();
            var    ccentry      = new Org.BouncyCastle.Pkcs.X509CertificateEntry(Castle);

            store.SetCertificateEntry(friendlyname, ccentry);
            store.SetKeyEntry(friendlyname, new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(keyPair.Private), new[] { ccentry });

            certificate.Text = "-----BEGIN CERTIFICATE-----\r\n" + Convert.ToBase64String(Castle.GetEncoded()) + "\r\n-----END CERTIFICATE-----";

            string password = pswtxt.Text;

            Castlekey = keyPair.Private;
            var stream = new MemoryStream();

            store.Save(stream, password.ToCharArray(), secureRandom);
            nametxt.Text = Castle.IssuerDN.ToString();
            TextWriter textWriter = new StringWriter();
            PemWriter  pemWriter  = new PemWriter(textWriter);

            pemWriter.WriteObject(Castle.GetPublicKey());
            pemWriter.Writer.Flush();
            pubtxt.Text = textWriter.ToString();
            SaveFileDialog output = new SaveFileDialog();

            output.Filter           = "pfx file|*.pfx";
            output.RestoreDirectory = true;
            output.InitialDirectory = Environment.CurrentDirectory;
            output.FilterIndex      = 1;
            if (output.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllBytes(output.FileName, stream.ToArray());
            }
            else
            {
                MessageBox.Show("pfx证书不导出!");
            }
            output.Filter = "cer file|*.cer";
            if (output.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllText(output.FileName, certificate.Text);
            }
            else
            {
                MessageBox.Show("cer证书没导出!");
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Request certificate from the ACME server
        /// </summary>
        /// <param name="binding"></param>
        /// <returns></returns>
        public CertificateInfo RequestCertificate(ICsrPlugin csrPlugin, Renewal renewal, Target target, OrderDetails order)
        {
            // What are we going to get?
            var pfxFileInfo = new FileInfo(PfxFilePath(renewal));

            // Determine/check the common name
            var identifiers = target.GetHosts(false);
            var commonName  = target.CommonName;

            if (!string.IsNullOrWhiteSpace(commonName))
            {
                var idn = new IdnMapping();
                commonName = idn.GetAscii(commonName);
                if (!identifiers.Contains(commonName, StringComparer.InvariantCultureIgnoreCase))
                {
                    _log.Warning($"Common name {commonName} provided is invalid.");
                    commonName = identifiers.First();
                }
            }

            // Try using cached certificate first to avoid rate limiting during
            // (initial?) deployment troubleshooting. Real certificate requests
            // will only be done once per day maximum.
            if (pfxFileInfo.Exists && pfxFileInfo.LastWriteTime > DateTime.Now.AddDays(-1))
            {
                try
                {
                    var cached = new CertificateInfo()
                    {
                        Certificate = ReadForUse(pfxFileInfo, renewal.PfxPassword),
                        PfxFile     = pfxFileInfo
                    };
                    var idn = new IdnMapping();
                    if (cached.SubjectName == commonName &&
                        cached.HostNames.Count == identifiers.Count() &&
                        cached.HostNames.All(h => identifiers.Contains(idn.GetAscii(h))))
                    {
                        if (_options.Force)
                        {
                            _log.Warning("Cached certificate available but not used with --{switch}. Use 'Renew specific' or 'Renew all' in the main menu to run unscheduled renewals without hitting rate limits.", nameof(MainArguments.Force).ToLower());
                        }
                        else
                        {
                            _log.Warning("Using cached certificate for {friendlyName}. To force issue of a new certificate within 24 hours, delete the .pfx file from the CertificatePath or run with the --{switch} switch. Be ware that you might run into rate limits doing so.", renewal.FriendlyName, nameof(MainArguments.Force).ToLower());
                            return(cached);
                        }
                    }
                }
                catch
                {
                    // File corrupt or invalid password?
                    _log.Warning("Unable to read from certificate cache");
                }
            }

            var csr      = csrPlugin.GenerateCsr(commonName, identifiers);
            var csrBytes = csr.CreateSigningRequest();

            order = _client.SubmitCsr(order, csrBytes);

            if (Settings.Default.SavePrivateKeyPem)
            {
                File.WriteAllText(GetPath(renewal, "-key.pem"), GetPem(csrPlugin.GeneratePrivateKey()));
            }
            File.WriteAllText(GetPath(renewal, "-csr.pem"), GetPem("CERTIFICATE REQUEST", csrBytes));

            _log.Information("Requesting certificate {friendlyName}", renewal.FriendlyName);
            var rawCertificate = _client.GetCertificate(order);

            if (rawCertificate == null)
            {
                throw new Exception($"Unable to get certificate");
            }

            var certificate       = new X509Certificate2(rawCertificate);
            var certificateExport = certificate.Export(X509ContentType.Cert);

            var crtDerFile = GetPath(renewal, $"-crt.der");
            var crtPemFile = GetPath(renewal, $"-crt.pem");
            var crtPem     = GetPem("CERTIFICATE", certificateExport);

            _log.Information("Saving certificate to {crtDerFile}", _certificatePath);
            File.WriteAllBytes(crtDerFile, certificateExport);
            File.WriteAllText(crtPemFile, crtPem);

            // Get issuer certificate and save in DER and PEM formats
            var chain = new X509Chain();

            chain.Build(certificate);
            X509Certificate2 issuerCertificate = chain.ChainElements[1].Certificate;
            var issuerCertificateExport        = issuerCertificate.Export(X509ContentType.Cert);
            var issuerPem = GetPem("CERTIFICATE", issuerCertificateExport);

            File.WriteAllBytes(GetPath(renewal, "-crt.der", "ca-"), issuerCertificateExport);
            File.WriteAllText(GetPath(renewal, "-crt.pem", "ca-"), issuerPem);

            // Generate combined files
            File.WriteAllText(GetPath(renewal, "-chain.pem", "ca-"), crtPem + issuerPem);

            // Build pfx archive
            var pfx                = new bc.Pkcs.Pkcs12Store();
            var bcCertificate      = ParsePem <bc.X509.X509Certificate>(crtPem);
            var bcCertificateEntry = new bc.Pkcs.X509CertificateEntry(bcCertificate);
            var bcCertificateAlias = bcCertificate.SubjectDN.ToString();
            var bcPrivateKeyEntry  = new bc.Pkcs.AsymmetricKeyEntry(csrPlugin.GeneratePrivateKey());

            pfx.SetCertificateEntry(bcCertificateAlias, bcCertificateEntry);
            pfx.SetKeyEntry(bcCertificateAlias, bcPrivateKeyEntry, new[] { bcCertificateEntry });

            var bcIssuer      = ParsePem <bc.X509.X509Certificate>(issuerPem);
            var bcIssuerEntry = new bc.Pkcs.X509CertificateEntry(bcIssuer);
            var bcIssuerAlias = bcIssuer.SubjectDN.ToString();

            pfx.SetCertificateEntry(bcIssuerAlias, bcIssuerEntry);

            using (var pfxStream = new MemoryStream())
            {
                pfx.Save(pfxStream, null, new bc.Security.SecureRandom());
                pfxStream.Position = 0;
                using (var pfxStreamReader = new BinaryReader(pfxStream))
                {
                    var tempPfx = new X509Certificate2(
                        pfxStreamReader.ReadBytes((int)pfxStream.Length),
                        (string)null,
                        X509KeyStorageFlags.MachineKeySet |
                        X509KeyStorageFlags.PersistKeySet |
                        X509KeyStorageFlags.Exportable);
                    if (csrPlugin.CanConvert())
                    {
                        try
                        {
                            var converted = csrPlugin.Convert(tempPfx.PrivateKey);
                            if (converted != null)
                            {
                                tempPfx.PrivateKey = converted;
                            }
                        }
                        catch
                        {
                            _log.Warning("Private key conversion error.");
                        }
                    }

                    tempPfx.FriendlyName = FriendlyName(renewal);
                    File.WriteAllBytes(pfxFileInfo.FullName, tempPfx.Export(X509ContentType.Pfx, renewal.PfxPassword));
                    pfxFileInfo.Refresh();
                }
            }

            // Recreate X509Certificate2 with correct flags for Store/Install
            return(new CertificateInfo()
            {
                Certificate = ReadForUse(pfxFileInfo, renewal.PfxPassword),
                PfxFile = pfxFileInfo
            });
        }
Exemplo n.º 22
0
        /// <summary>
        /// Exports the specified stream and password to a pkcs12 encrypted file.
        /// </summary>
        /// <remarks>
        /// Exports the specified stream and password to a pkcs12 encrypted file.
        /// </remarks>
        /// <param name="stream">The output stream.</param>
        /// <param name="password">The password to use to lock the private keys.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="stream"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="password"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An error occurred while writing to the stream.
        /// </exception>
        public void Export(System.IO.Stream stream, string password)
        {
            if (stream == null)
            {
                throw new System.ArgumentNullException(nameof(stream));
            }

            if (password == null)
            {
                throw new System.ArgumentNullException(nameof(password));
            }

            Org.BouncyCastle.Pkcs.Pkcs12Store store = new Org.BouncyCastle.Pkcs.Pkcs12Store();
            foreach (Org.BouncyCastle.X509.X509Certificate certificate in certs)
            {
                if (keys.ContainsKey(certificate))
                {
                    continue;
                }

                string alias = GetCommonName(certificate);

                if (alias == null)
                {
                    continue;
                }

                Org.BouncyCastle.Pkcs.X509CertificateEntry entry =
                    new Org.BouncyCastle.Pkcs.X509CertificateEntry(certificate);

                store.SetCertificateEntry(alias, entry);
            }

            foreach (
                System.Collections.Generic.KeyValuePair <
                    Org.BouncyCastle.X509.X509Certificate,
                    Org.BouncyCastle.Crypto.AsymmetricKeyParameter
                    > kvp in keys)
            {
                string alias = GetCommonName(kvp.Key);

                if (alias == null)
                {
                    continue;
                }

                Org.BouncyCastle.Pkcs.AsymmetricKeyEntry entry =
                    new Org.BouncyCastle.Pkcs.AsymmetricKeyEntry(kvp.Value);

                Org.BouncyCastle.Pkcs.X509CertificateEntry cert =
                    new Org.BouncyCastle.Pkcs.X509CertificateEntry(kvp.Key);

                System.Collections.Generic.List <Org.BouncyCastle.Pkcs.X509CertificateEntry> chain =
                    new System.Collections.Generic.List <Org.BouncyCastle.Pkcs.X509CertificateEntry>();

                chain.Add(cert);

                store.SetKeyEntry(alias, entry, chain.ToArray());
            }

            store.Save(stream, password.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
        }