Beispiel #1
0
        /// <summary>This method is called by a CA to sign the provided Certificate
        /// with our RSA key.</summary>
        public Certificate Sign(Certificate Signer, RSA PrivateKey)
        {
            X509CertificateBuilder x509_builder = new X509CertificateBuilder(3);

            x509_builder.IssuerName  = Signer.Subject.DN;
            x509_builder.SubjectName = Subject.DN;
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            // I guess this is reversed for network order or something...
            byte[] tmp = sha1.ComputeHash(Signer.UnsignedData);
            for (int i = 0; i < tmp.Length / 2; i++)
            {
                int  j    = tmp.Length - i - 1;
                byte tmpb = tmp[i];
                tmp[i] = tmp[j];
                tmp[j] = tmpb;
            }
            x509_builder.SerialNumber     = tmp;
            x509_builder.NotBefore        = System.DateTime.MinValue;
            x509_builder.NotAfter         = System.DateTime.MaxValue;
            x509_builder.SubjectPublicKey = _public_key;
            SubjectAltNameExtension sane = new SubjectAltNameExtension(null, null, null, new string[] { NodeAddress });

            x509_builder.Extensions.Add(sane);
            byte[] cert_data = x509_builder.Sign(PrivateKey);
            return(new Certificate(cert_data));
        }
Beispiel #2
0
        public static byte[] CreateServerCert(string subjectName, byte[] rootKey, byte[] rootCert)
        {
            if (!subjectName.StartsWith("CN="))
            {
                subjectName = "CN=" + subjectName;
            }

            // Copy the root key since the PrivateKey constructor will blow away the data
            byte[] rootKeyCopy = new byte[rootKey.Length];
            Buffer.BlockCopy(rootKey, 0, rootKeyCopy, 0, rootKey.Length);

            // Load the server's private key and certificate
            PrivateKey      pvk        = new PrivateKey(rootKeyCopy, null);
            RSA             issuerKey  = pvk.RSA;
            X509Certificate issuerCert = new X509Certificate(rootCert);

            // Serial number MUST be positive
            byte[] sn = Guid.NewGuid().ToByteArray();
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();

            eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1"); // Indicates the cert is intended for server auth

            // Generate a server certificate signed by the server root CA
            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = issuerCert.IssuerName;
            cb.NotBefore        = DateTime.Now;
            cb.NotAfter         = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            cb.SubjectName      = subjectName;
            cb.SubjectPublicKey = issuerKey;
            cb.Hash             = "SHA1";
            cb.Extensions.Add(eku);
            byte[] serverCert = cb.Sign(issuerKey);

            // Generate a PKCS#12 file for the server containing the private key and certificate
            PKCS12 p12 = new PKCS12();

            p12.Password = null;

            ArrayList list = new ArrayList(4);

            // We use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[] { 1, 0, 0, 0 });
            Hashtable attributes = new Hashtable(1);

            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(serverCert), attributes);
            p12.AddCertificate(issuerCert);
            p12.AddPkcs8ShroudedKeyBag(issuerKey, attributes);

            return(p12.GetBytes());
        }
Beispiel #3
0
        //adapted from https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs
        public static PKCS12 GeneratePfx(string certificateName, string password)
        {
            byte[] sn      = GenerateSerialNumber();
            string subject = string.Format("CN={0}", certificateName);

            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = DateTime.Now.AddYears(20);

            var subjectKey = new RSACryptoServiceProvider(2048);
            var hashName   = "SHA512";

            var cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = subject;
            cb.NotBefore        = notBefore;
            cb.NotAfter         = notAfter;
            cb.SubjectName      = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash             = hashName;

            var rawcert = cb.Sign(subjectKey);

            var p12 = new PKCS12();

            p12.Password = password;

            var attributes = GetAttributes();

            p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

            return(p12);
        }
        public void SubjectAltNameGenerator()
        {
            RSACryptoServiceProvider rsa  = new RSACryptoServiceProvider();
            X509CertificateBuilder   x509 = new X509CertificateBuilder();

            x509.IssuerName       = "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server";
            x509.NotAfter         = DateTime.MaxValue;
            x509.NotBefore        = DateTime.MinValue;
            x509.SubjectName      = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org";
            x509.SerialNumber     = new byte[] { 12, 34, 56, 78, 90 };
            x509.Version          = 3;
            x509.SubjectPublicKey = rsa;

            string[] dns = new string[2];
            dns[0] = "one";
            dns[1] = "two";
            string[] uris = new string[3];
            uris[0] = "one:two://three";
            uris[1] = "Here:I:AM://12345";
            uris[2] = "last:one";
            SubjectAltNameExtension sane = new SubjectAltNameExtension(null, dns, null, uris);

            x509.Extensions.Add(sane);
            byte[] data = x509.Sign(rsa);

            X509Certificate         x509_loaded = new X509Certificate(data);
            SubjectAltNameExtension sane_test   = new SubjectAltNameExtension(x509_loaded.Extensions[0]);

            Assert.AreEqual(sane_test.RFC822.Length, 0, "RFC822 count");
            Assert.AreEqual(sane_test.DNSNames.Length, 2, "DNSName count");
            Assert.AreEqual(sane_test.IPAddresses.Length, 0, "IPAddresses count");
            Assert.AreEqual(sane_test.UniformResourceIdentifiers.Length, 3, "URI Count");
            Assert.AreEqual(sane_test.DNSNames[1], "two", "DNSName test");
            Assert.AreEqual(sane_test.UniformResourceIdentifiers[2], "last:one", "URI Test");
        }
Beispiel #5
0
        public static X509Certificate2 CreateSelfSignedCertificate(string subjectName)
        {
            byte[] sn         = Guid.NewGuid().ToByteArray();
            string subject    = "CN=" + subjectName;
            RSA    subjectKey = new RSACryptoServiceProvider(2048);

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = subject;
            cb.NotBefore        = DateTime.Now;
            cb.NotAfter         = new DateTime(643445675990000000);
            cb.SubjectName      = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash             = "SHA1";

            byte[] rawcert = cb.Sign(subjectKey);

            PKCS12 p12 = new PKCS12();

            p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert));
            p12.AddPkcs8ShroudedKeyBag(subjectKey);
            return(new X509Certificate2(p12.GetBytes()));
        }
Beispiel #6
0
        private static byte[] CreateRawCert(string certName, string password)
        {
            if (String.IsNullOrEmpty(certName))
            {
                Log.To.Listener.E(Tag, "An empty certName was received in CreateRawCert, throwing...");
                throw new ArgumentException("Must contain a non-empty name", "certName");
            }

            if (String.IsNullOrEmpty(password))
            {
                Log.To.Listener.E(Tag, "An empty password was received in CreateRawCert, throwing...");
                throw new ArgumentException("Must contain a non-empty password", "password");
            }

            byte[]   sn        = GenerateSerialNumber();
            string   subject   = string.Format("CN={0}", certName);
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = DateTime.Now.AddYears(20);
            string   hashName  = "SHA512";
            var      key       = new RSACryptoServiceProvider(2048);

            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = subject;
            cb.NotBefore        = notBefore;
            cb.NotAfter         = notAfter;
            cb.SubjectName      = subject;
            cb.SubjectPublicKey = key;
            cb.Hash             = hashName;

            Log.To.Listener.I(Tag, "Generating X509 certificate, this is expensive...");
            var sw = System.Diagnostics.Stopwatch.StartNew();

            byte[] rawcert = cb.Sign(key);
            sw.Stop();
            Log.To.Listener.I(Tag, "Finished generating X509 certificate; took {0} sec", sw.ElapsedMilliseconds / 1000.0);
            PKCS12 p12 = new PKCS12();

            if (!String.IsNullOrEmpty(password))
            {
                p12.Password = password;
            }
            Hashtable attributes = GetAttributes();

            p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(key, attributes);

            return(p12.GetBytes());
        }
Beispiel #7
0
        public static void GenerateSelfSignedServiceCertificate(string filename, string hostname)
        {
            var builder = new X509CertificateBuilder(3);
            var sn      = Guid.NewGuid().ToByteArray();

            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            var rsaKey = RSA.Create();
            var eku    = new ExtendedKeyUsageExtension();

            eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1"); /* SSL Server */

            builder.SerialNumber = sn;
            builder.IssuerName   = "CN=" + hostname;
            builder.NotBefore    = DateTime.Now;
            var notAfter = DateTime.Now;

            builder.NotAfter         = notAfter.AddYears(1000);
            builder.SubjectName      = "CN=" + hostname;
            builder.SubjectPublicKey = rsaKey;
            builder.Hash             = "SHA512";
            builder.Extensions.Add(eku);

            var rawCert = builder.Sign(rsaKey);

            var p12 = new PKCS12
            {
                Password = string.Empty
            };
            var list = new ArrayList
            {
                new byte[4] {
                    1, 0, 0, 0
                }
            };
            var attributes = new Hashtable(1)
            {
                [PKCS9.localKeyId] = list
            };

            p12.AddCertificate(new X509Certificate(rawCert), attributes);
            p12.AddPkcs8ShroudedKeyBag(rsaKey, attributes);
            p12.SaveToFile(filename);
        }
Beispiel #8
0
        public static void CreateServerRootCA(string issuer, out byte[] rootKey, out byte[] rootCert)
        {
            if (!issuer.StartsWith("CN="))
            {
                issuer = "CN=" + issuer;
            }

            // Create a temporary file
            string tempFile = Path.GetTempFileName();

            // Generate a new signing key
            RSA issuerKey = (RSA)RSA.Create();

            // Generate a private key
            PrivateKey key = new PrivateKey();

            key.RSA = issuerKey;

            // Save the private key and load it back into memory
            key.Save(tempFile);
            rootKey = File.ReadAllBytes(tempFile);
            File.Delete(tempFile);

            // Serial number MUST be positive
            byte[] sn = Guid.NewGuid().ToByteArray();
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            // Generate a self-signed certificate
            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = issuer;
            cb.NotBefore        = DateTime.Now;
            cb.NotAfter         = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            cb.SubjectName      = issuer;
            cb.SubjectPublicKey = issuerKey;
            cb.Hash             = "SHA1";

            rootCert = cb.Sign(issuerKey);
        }
Beispiel #9
0
        /// <summary>
        /// Generates a self-signed X509Certificate2.
        /// </summary>
        /// <param name="subjectName">The server name to generate for</param>
        /// <returns>A self-signed certificate</returns>
        public static X509Certificate2 CreateSelfSignedCertificate(string subjectName)
        {
            //Generate a serial number for the certificate.
            byte[] sn      = Guid.NewGuid().ToByteArray();
            string subject = "CN=" + subjectName;

            //Use 2048-bit RSA for the public & private key
            RSA subjectKey = new RSACryptoServiceProvider(2048);

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            //Use the cert builder to create the certificate
            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber = sn;
            cb.IssuerName   = subject;

            //Sets the date created to DateTime.Now
            cb.NotBefore = DateTime.Now;
            //Sets the expire date to some time way in the future
            cb.NotAfter    = new DateTime(643445675990000000);
            cb.SubjectName = subject;

            //Sets the public key to the 2048-bit RSA key generate before
            cb.SubjectPublicKey = subjectKey;
            cb.Hash             = "SHA1";

            //Sign the key with the RSA key
            byte[] rawcert = cb.Sign(subjectKey);

            //Creates a new PKCS12 bag to add the private key to the cert
            PKCS12 p12 = new PKCS12();

            p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert));
            p12.AddPkcs8ShroudedKeyBag(subjectKey);

            //Return the generated certificate
            return(new X509Certificate2(p12.GetBytes()));
        }
Beispiel #10
0
        private MSX509.X509Certificate2 CreateCertificate(string name, List <X509Extension> extensions, MSX509.X509Certificate2 issuerCertificate, string issuer, MSX509.StoreName storeName, int validity)
        {
            MSX509.X509Certificate2 certificate = LoadCertificate(name, storeName, location_);
            if (certificate != null)
            {
                return(certificate);
            }

            state_.Logger.Information("Create X509.v3 certificate for '{0}'", name);

            PrivateKey key = new PrivateKey();

            key.RSA = RSA.Create();

            X509CertificateBuilder builder = new X509CertificateBuilder(3);

            builder.SerialNumber     = GenerateSerial();
            builder.IssuerName       = "CN=" + issuer;
            builder.SubjectName      = "CN=" + name;
            builder.SubjectPublicKey = key.RSA;
            builder.NotBefore        = DateTime.Now;
            builder.NotAfter         = builder.NotBefore.AddDays(validity);
            builder.Hash             = "SHA1";

            foreach (X509Extension extension in extensions)
            {
                builder.Extensions.Add(extension);
            }

            var signator = issuerCertificate == null ? key.RSA : issuerCertificate.PrivateKey;

            byte[] raw = builder.Sign(signator);

            StoreCertificate(name, raw, key.RSA, storeName, location_);

            certificate            = new MSX509.X509Certificate2(raw);
            certificate.PrivateKey = key.RSA;
            return(certificate);
        }
Beispiel #11
0
        /// <summary>
        /// Create a self signed certificate in the specified file.
        /// </summary>
        /// <param name="subjectName">The subject of the certificate to create.</param>
        /// <param name="fileName">The file name to write the certificate to.</param>
        /// <param name="signatureAlgorithm">The signature algorithm to use</param>
        /// <param name="password">True if there is a password, false otherwise.  Note that if there is a password, PFX format is assumed.</param>
        public static void CreateSelfSignedInFile(string subjectName, string fileName, string signatureAlgorithm, string password = "")
        {
            byte[] serialNumber = GenerateSerialNumber();
            string subject      = string.Format("CN={0}", subjectName);

            using (RSA key = new RSACryptoServiceProvider(2048))
            {
                X509CertificateBuilder certificateBuilder = new X509CertificateBuilder
                {
                    SerialNumber     = serialNumber,
                    IssuerName       = subject,
                    NotBefore        = DateTime.Now,
                    NotAfter         = DateTime.Now, //expiry time is now for security purposes
                    SubjectName      = subject,
                    SubjectPublicKey = key,
                    Hash             = signatureAlgorithm
                };

                //Get the raw certificate data
                byte[] rawCert = certificateBuilder.Sign(key);

                //If password is not empty, generate a PKCS#12 formatted file
                if (!string.IsNullOrEmpty(password))
                {
                    PKCS12 p12 = new PKCS12();
                    p12.Password = password;
                    p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawCert));
                    p12.AddPkcs8ShroudedKeyBag(key);

                    p12.SaveToFile(fileName);
                }
                //If password is empty generate a DER formatted file
                else
                {
                    File.WriteAllBytes(fileName, rawCert);
                }
            }
        }
Beispiel #12
0
        //adapted from https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs
        public static byte[] GeneratePfx(string certificateName, string password)
        {
            byte[] sn      = GenerateSerialNumber();
            string subject = $"CN={certificateName}";

            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = DateTime.Now.AddYears(20);

            RSA subjectKey = new RSACryptoServiceProvider(2048);


            string hashName = "SHA256";

            X509CertificateBuilder cb = new X509CertificateBuilder(3)
            {
                SerialNumber     = sn,
                IssuerName       = subject,
                NotBefore        = notBefore,
                NotAfter         = notAfter,
                SubjectName      = subject,
                SubjectPublicKey = subjectKey,
                Hash             = hashName
            };

            byte[] rawcert = cb.Sign(subjectKey);

            PKCS12 p12 = new PKCS12 {
                Password = password
            };

            Hashtable attributes = GetAttributes();

            p12.AddCertificate(new X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

            return(p12.GetBytes());
        }
Beispiel #13
0
        // TODO : cleanup and reorganization, as the code below is a almost a direct copypaste from Mono project's Makecert tool.
        internal /* byte[]*/ PKCS12 GenerateCertificate(/*string[] args,*/ bool isHubRootCA, bool isHubCert, string subjectName, string[] alternateDnsNames)
        {
            if (isHubRootCA && isHubCert)
            {
                throw new Exception("incompatible options isHubRootCA & isHubCert");
            }
            Logger.Append("HUBRN", Severity.INFO, "Asked to create " + ((isHubCert)?"hub certificate, ":"") + ((isHubRootCA)?"root CA, ":"") + ((!isHubCert && !isHubRootCA)?" node certificate for '" + subjectName + "'":""));
            string rootKey  = ConfigurationManager.AppSettings["Security.CAKey"];
            string rootCert = ConfigurationManager.AppSettings["Security.CACertificate"];

            byte[]   sn        = Guid.NewGuid().ToByteArray();
            string   issuer    = defaultIssuer;
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = DateTime.Now.AddYears(5);

            RSA issuerKey = (RSA)RSA.Create();
            //issuerKey.FromXmlString(MonoTestRootAgency);
            RSA subjectKey = (RSA)RSA.Create();

            bool   selfSigned = isHubRootCA;
            string hashName   = "SHA1";

            BasicConstraintsExtension bce     = null;
            ExtendedKeyUsageExtension eku     = null;
            SubjectAltNameExtension   alt     = null;
            string          p12pwd            = null;
            X509Certificate issuerCertificate = null;

            try{
                if (subjectName == null)
                {
                    throw new Exception("Missing Subject Name");
                }
                if (!subjectName.ToLower().StartsWith("cn="))
                {
                    subjectName = "CN=" + subjectName;
                }

                /*if (alternateDnsNames != null){
                 *      alt = new SubjectAltNameExtension(null, alternateDnsNames, null, null);
                 * }*/
                if (!isHubRootCA)
                {
                    issuerCertificate = LoadCertificate(rootCert);
                    issuer            = issuerCertificate.SubjectName;

                    //case "-iv":
                    // TODO password
                    PrivateKey pvk = PrivateKey.CreateFromFile(rootKey);
                    issuerKey = pvk.RSA;
                }

                // Issuer CspParameters options
                if (isHubRootCA)
                {
                    //subjectName = defaultSubject;
                    string pvkFile = rootKey;
                    if (File.Exists(pvkFile))                       // CA key already exists, reuse
                    {
                        PrivateKey key = PrivateKey.CreateFromFile(pvkFile);
                        subjectKey = key.RSA;
                    }
                    else
                    {
                        PrivateKey key = new PrivateKey();
                        key.RSA = subjectKey;
                        key.Save(pvkFile);
                        // save 'the Mother Of All Keys'
                        //WriteHubMotherCert(issuerKey.ToXmlString(true));
                    }
                }
                else
                {
                    p12pwd = "";
                }

                // serial number MUST be positive
                if ((sn [0] & 0x80) == 0x80)
                {
                    sn [0] -= 0x80;
                }

                if (selfSigned)
                {
                    if (subjectName != defaultSubject)
                    {
                        issuer    = subjectName;
                        issuerKey = subjectKey;
                        //issuerKey = Hub.MotherKey;
                    }
                    else
                    {
                        subjectName = issuer;
                        subjectKey  = issuerKey;
                    }
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber     = sn;
                cb.IssuerName       = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subjectName;
                cb.SubjectPublicKey = subjectKey;

                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }
                // signature
                cb.Hash = hashName;
                byte[] rawcert = cb.Sign(issuerKey);

                if (isHubRootCA)                 // Hub CA
                {
                    WriteCACertificate(rawcert);
                }
                else
                {
                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte [4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new X509Certificate(rawcert), attributes);
                    if (issuerCertificate != null)
                    {
                        p12.AddCertificate(issuerCertificate);
                    }
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

                    /*var x509cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
                     * x509cert2.Import(p12.GetBytes(), "",
                     *      System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet| System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable );
                     * return  x509cert2;*/
                    //return p12.GetBytes();
                    return(p12);
                }
                Logger.Append("HUBRN", Severity.INFO, "Created requested key/cert for '" + subjectName + "'.");
            }
            catch (Exception e) {
                Logger.Append("HUBRN", Severity.ERROR, "Error generating certificate for '" + subjectName + "' : " + e.ToString());
            }
            return(null);
        }
Beispiel #14
0
        byte[] GenerateCertificate(Options options)
        {
            var builder = new X509CertificateBuilder();

            // If the default key container is not used accessing the key will throw a "Key not found" exception
            using (var rsa = new RSACryptoServiceProvider(options.keySize, new CspParameters()
            {
                Flags = CspProviderFlags.UseDefaultKeyContainer | CspProviderFlags.CreateEphemeralKey
            }))
            {
                try
                {
                    #region Key

                    builder.PublicKey = rsa;

                    #endregion

                    builder.SubjectName             = options.subjectName;
                    builder.SubjectAlternativeNames = options.subjectAlternativeNames;
                    builder.SerialNumber            = options.serialNumber;
                    builder.KeyUsages         = options.basicKeyUsages;
                    builder.KeyUsagesCritical = options.basicKeyUsagesCritical;
                    if (options.extendedUsages != null)
                    {
                        builder.ExtendedKeyUsages = options.extendedUsages.ToArray();
                    }
                    builder.ExtendedKeyUsagesCritical = options.extendedUsagesCritical;
                    builder.NotBefore = options.fromDate;
                    builder.NotAfter  = options.toDate;
                    builder.IsCertificateAuthority         = options.isCA;
                    builder.CertificateAuthorityPathLength = options.caLength;

                    if (options.issuerCertificate == null)
                    {
                        builder.SelfSign(rsa);
                    }
                    else
                    {
                        builder.Sign(options.issuerCertificate);
                    }

                    File.WriteAllBytes(options.outputFile, builder.ExportPkcs12(rsa, options.outputPassword, 1000));

                    var certData = builder.Export();

                    if (false == string.IsNullOrEmpty(options.outputCertFile))
                    {
                        File.WriteAllBytes(options.outputCertFile, certData);
                    }

                    return(certData);
                }
                finally
                {
                    // Remove the key from the key container. Otherwise, the key will be kept on the file
                    // system which is completely undesirable.
                    rsa.PersistKeyInCsp = false;
                }
            }
        }
Beispiel #15
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                Help();

                return(0);
            }

            var command = args[0];

            if (command.Equals("-h", StringComparison.OrdinalIgnoreCase) ||
                command.Equals("/h", StringComparison.OrdinalIgnoreCase) ||
                command.Equals("-?", StringComparison.OrdinalIgnoreCase) ||
                command.Equals("/?", StringComparison.OrdinalIgnoreCase) ||
                command.Equals("?", StringComparison.OrdinalIgnoreCase))
            {
                // Display the help screen
                Help();
                return(0);
            }
            else if (command.Equals("c", StringComparison.OrdinalIgnoreCase))
            {
                // Generate a certificate

                if (args.Length < 2)
                {
                    Error("Too few arguments were specified.");
                    return(ExitCode_CommandLineError);
                }

                #region Arguments
                var processCommandLinePath = true;

Arguments:

                var argIndex = 1;

                string         outputFile                 = null;
                string         outputCertFile             = null;
                string         commonOutputName           = null;
                string         outputPassword             = null;
                int            keySize                    = DefaultKeySize;
                string         subjectName                = null;
                IList <string> subjectAlternativeNameList = null;
                var            basicKeyUsages             = BasicKeyUsages.None;
                bool           basicKeyUsagesCritical     = false;
                var            extendedUsages             = new List <string>();
                bool           extendedUsagesCritical     = false;
                DateTime       fromDate                   = DateTime.UtcNow.Date; // The date only
                DateTime       toDate = fromDate.AddYears(1);
                bool           toDateExplicitlySet = false;
                int            years           = 0;
                bool           isCA            = false;
                int            caLength        = -1;
                byte[]         serialNumber    = null;
                string         issuerPath      = null;
                string         issuerPassword  = null;
                string         commandLinePath = null;

                #region Collect

                while (argIndex < args.Length)
                {
                    var argument = args[argIndex++].ToLower();

                    if (argument.Length > 0 && argument[0] == '/')
                    {
                        argument = '-' + argument.Substring(1);
                    }

                    try
                    {
                        switch (argument)
                        {
                            #region Output file
                        case "-o":
                            outputFile = args[argIndex++];
                            break;

                        case "-oc":
                            outputCertFile = args[argIndex++];
                            break;

                        case "-on":
                            commonOutputName = args[argIndex++];
                            break;

                        case "-op":
                            outputPassword = args[argIndex++];
                            break;

                            #endregion
                            #region Basic
                        case "-k":
                            if (int.TryParse(args[argIndex++], out keySize) && keySize > 0)
                            {
                                break;
                            }
                            else
                            {
                                Error("Invalid key size.");
                                return(ExitCode_CommandLineError);
                            }

                        case "-s":
                            subjectName = args[argIndex++];
                            try
                            {
                                X501DistinguishedName.Parse(subjectName);
                            }
                            catch (FormatException exc)
                            {
                                Error("Invalid subject distinguished name: {0}", exc.Message);
                                return(ExitCode_CommandLineError);
                            }
                            break;

                        case "-sa":
                            subjectAlternativeNameList = args[argIndex++].Split(',').Select(x => x.Trim()).Where(x => x.Length > 0).ToList();
                            break;

                        case "-sn":
                            var serialNumberText = args[argIndex++];
                            if (serialNumberText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) ||
                                serialNumberText.StartsWith("x", StringComparison.InvariantCultureIgnoreCase))
                            {
                                // A hexadecimal string
                                try
                                {
                                    serialNumber = ToBytes(serialNumberText.Substring(1));
                                    break;
                                }
                                catch (FormatException)
                                {
                                    Error("Invalid serial number: invalid hexadecimal string.");
                                    return(ExitCode_CommandLineError);
                                }
                            }
                            else
                            {
                                // An integer number
                                long serialNumberLong;
                                if (long.TryParse(serialNumberText, out serialNumberLong))
                                {
                                    serialNumber = BitConverter.GetBytes(serialNumberLong);
                                    // Remove trailing zero bytes
                                    serialNumber = serialNumber.Reverse().SkipWhile(x => x == 0).Reverse().ToArray();
                                    if (serialNumber.Length == 0)
                                    {
                                        serialNumber = new byte[] { 0 };
                                    }
                                    break;
                                }
                                else
                                {
                                    Error("Invalid serial number: the specified value is not an integer or is too large.");
                                    return(ExitCode_CommandLineError);
                                }
                            }

                            #endregion
                            #region Key usage
                        case "-bu":
                        case "-buc":
                            basicKeyUsagesCritical = argument == "-buc";
                            try
                            {
                                basicKeyUsages = (BasicKeyUsages)Enum.Parse(typeof(BasicKeyUsages), args[argIndex++], true);
                            }
                            catch (ArgumentException exc)
                            {
                                Error("Invalid certificate usages: {0}", exc.Message);
                                return(ExitCode_CommandLineError);
                            }
                            break;

                        case "-eu":
                        case "-euc":
                            extendedUsagesCritical = argument == "-euc";
                            foreach (var item in args[argIndex++].Split(','))
                            {
                                var usage = item.Trim();

                                if (item.Length == 0)
                                {
                                    continue;
                                }

                                string result;

                                switch (item.ToLower())
                                {
                                case "serverauthentication":
                                    result = ExtendedKeyUsages.ServerAuthentication;
                                    break;

                                case "clientauthentication":
                                    result = ExtendedKeyUsages.ClientAuthentication;
                                    break;

                                case "codesigning":
                                    result = ExtendedKeyUsages.CodeSigning;
                                    break;

                                case "emailprotection":
                                    result = ExtendedKeyUsages.EmailProtection;
                                    break;

                                case "timestamping":
                                    result = ExtendedKeyUsages.TimeStamping;
                                    break;

                                case "ocspsigning":
                                    result = ExtendedKeyUsages.OCSPSigning;
                                    break;

                                default:
                                    if (item.StartsWith("oid:"))
                                    {
                                        result = item.Substring(4);
                                        break;
                                    }
                                    else
                                    {
                                        Error("Invalid extended usage: '{0}'.", item);
                                        return(ExitCode_CommandLineError);
                                    }
                                }

                                extendedUsages.Add(result);
                            }
                            break;

                            #endregion
                            #region Validity period
                        case "-f":
                            if (DateTime.TryParse(args[argIndex++], out fromDate))
                            {
                                break;
                            }
                            else
                            {
                                Error("Invalid validity period starting date.");
                                return(ExitCode_CommandLineError);
                            }

                        case "-t":
                            if (DateTime.TryParse(args[argIndex++], out toDate))
                            {
                                toDateExplicitlySet = true;
                                break;
                            }
                            else
                            {
                                Error("Invalid validity period ending date.");
                                return(ExitCode_CommandLineError);
                            }

                        case "-y":
                            if (int.TryParse(args[argIndex++], out years) && years > 0)
                            {
                                break;
                            }
                            else
                            {
                                Error("Invalid number of years for which the certificate is valid.");
                                return(ExitCode_CommandLineError);
                            }

                            #endregion
                            #region CA
                        case "-ca":
                            isCA = true;
                            break;

                        case "-calen":
                            if (int.TryParse(args[argIndex++], out caLength) && caLength >= 0)
                            {
                                break;
                            }
                            else
                            {
                                Error("Invalid 'calen' value.");
                                return(ExitCode_CommandLineError);
                            }

                            #endregion
                            #region Issuer
                        case "-i":
                            issuerPath = args[argIndex++];
                            break;

                        case "-ip":
                            issuerPassword = args[argIndex++];
                            break;

                            #endregion
                            #region Other
                        case "-r":
                            commandLinePath = args[argIndex++];
                            break;

                            #endregion
                            #region Basic
                        case "?":
                        case "-?":
                        case "-h":
                            Help();
                            return(ExitCode_CommandLineError);

                        default:
                            Error("Invalid argument: '{0}'.", argument);
                            return(ExitCode_CommandLineError);

                            #endregion
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        Error("'{0}' must be followed by an additional parameter.", argument);

                        return(ExitCode_CommandLineError);
                    }
                }

                #endregion

                #region Process

                if (processCommandLinePath && false == string.IsNullOrEmpty(commandLinePath))
                {
                    if (false == File.Exists(commandLinePath))
                    {
                        Error("The file containing command line arguments was not found.");
                        return(ExitCode_CommandLineError);
                    }

                    string[] readCommandLineArguments;

                    try
                    {
                        readCommandLineArguments = File.ReadAllLines(commandLinePath);
                    }
                    catch (Exception exc)
                    {
                        Error("Could not read the file containing command line arguments: {0}", exc.Message);
                        return(ExitCode_CommandLineError);
                    }

                    try
                    {
                        var readCommandLine = string.Join(" ", readCommandLineArguments);

                        readCommandLineArguments = ParseCommandLine(readCommandLine);
                    }
                    catch (Win32Exception exc)
                    {
                        Error("Could not parse the arguments read from file: {0}", exc.Message);
                        return(ExitCode_CommandLineError);
                    }

                    // Indicate that the command line arguments has been already processed
                    processCommandLinePath = false;

                    // The arguments specified on the command line MUST override the arguments read from the file.
                    // Therefore, they must follow the read arguments in the array.
                    // Move the command argument at the front
                    args = new string[] { args[0] }.Concat(readCommandLineArguments).Concat(args.Skip(1)).ToArray();

                    Console.WriteLine();

                    // Reprocess the command-line arguments
                    goto Arguments;
                }

                if (false == string.IsNullOrEmpty(commonOutputName))
                {
                    // Apply the common name to the other parameters

                    if (string.IsNullOrEmpty(outputFile))
                    {
                        outputFile = Path.ChangeExtension(commonOutputName, ".pfx");
                    }
                    if (string.IsNullOrEmpty(outputCertFile))
                    {
                        outputCertFile = Path.ChangeExtension(commonOutputName, ".cer");
                    }
                }

                if (string.IsNullOrEmpty(outputFile))
                {
                    Error("An output file must be specified.");
                    return(ExitCode_CommandLineError);
                }

                if (string.IsNullOrEmpty(subjectName))
                {
                    Error("A subject distinguished name (DN) must be specified.");
                    return(ExitCode_CommandLineError);
                }

                if (outputPassword == null)
                {
                    Console.Write("Enter OUTPUT file password: "******"Enter ISSUER certificate password: "******"Cannot load the certificate of the issuer: {0}", exc.Message);
                        return(ExitCode_CommandLineError);
                    }

                    if (false == issuerCertificate.Extensions.OfType <X509BasicConstraintsExtension>().Any(x => x.CertificateAuthority))
                    {
                        Error("The certificate of the issuer must be a CA.");
                        return(ExitCode_CommandLineError);
                    }

                    if (false == issuerCertificate.HasPrivateKey)
                    {
                        Error("The certificate of the issuer must has an associated private key.");
                        return(ExitCode_CommandLineError);
                    }
                }
                else
                {
                    issuerCertificate = null;
                }

                if (serialNumber == null)
                {
                    serialNumber = Guid.NewGuid().ToByteArray();
                }

                if (false == toDateExplicitlySet && years > 0)
                {
                    toDate = fromDate.AddYears(years);
                }

                if (fromDate >= toDate)
                {
                    Error("The ending of the validity period must follow its ending.");
                    return(ExitCode_CommandLineError);
                }

                #endregion

                #endregion

                #region Work

                try
                {
                    var builder = new X509CertificateBuilder();

                    Console.Write("Generating RSA key...");

                    // If the default key container is not used accessing the key will throw a "Key not found" exception
                    using (var rsa = new RSACryptoServiceProvider(keySize, new CspParameters()
                    {
                        Flags = CspProviderFlags.UseDefaultKeyContainer | CspProviderFlags.CreateEphemeralKey
                    }))
                    {
                        try
                        {
                            #region Key

                            Console.WriteLine(" Done");

                            builder.PublicKey = rsa;

                            #endregion

                            builder.SubjectName             = subjectName;
                            builder.SubjectAlternativeNames = subjectAlternativeNameList;
                            builder.SerialNumber            = serialNumber;
                            builder.KeyUsages                 = basicKeyUsages;
                            builder.KeyUsagesCritical         = basicKeyUsagesCritical;
                            builder.ExtendedKeyUsages         = extendedUsages.ToArray();
                            builder.ExtendedKeyUsagesCritical = extendedUsagesCritical;
                            builder.NotBefore                 = fromDate;
                            builder.NotAfter = toDate;
                            builder.IsCertificateAuthority         = isCA;
                            builder.CertificateAuthorityPathLength = caLength;

                            if (issuerCertificate == null)
                            {
                                builder.SelfSign(rsa);
                            }
                            else
                            {
                                builder.Sign(issuerCertificate);
                            }

                            File.WriteAllBytes(outputFile, builder.ExportPkcs12(rsa, outputPassword, 1000));

                            var certData = builder.Export();

                            if (false == string.IsNullOrEmpty(outputCertFile))
                            {
                                File.WriteAllBytes(outputCertFile, certData);
                            }

                            // Display the hash of the certificate

                            Console.WriteLine("Certificate hash:");

                            foreach (var alg in HashAlgorithmList)
                            {
                                using (var hash = HashAlgorithm.Create(alg))
                                {
                                    var binaryHash = hash.ComputeHash(certData);
                                    Console.WriteLine("{0,-8}{1}", alg, BitConverter.ToString(binaryHash).Replace("-", ""));
                                }
                            }
                        }
                        finally
                        {
                            // Remove the key from the key container. Otherwise, the key will be kept on the file
                            // system which is completely undesirable.
                            rsa.PersistKeyInCsp = false;
                        }
                    }
                }
                catch (Exception exc)
                {
                    Error("Unexpected error: {0}", exc.Message);

                    return(ExitCode_ProcessingError);
                }

                #endregion

                Console.WriteLine();

                Console.WriteLine("All done.");

                return(0);
            }
            else if (command.Equals("h", StringComparison.OrdinalIgnoreCase))
            {
                // Output the hash of a certificate

                if (args.Length < 2)
                {
                    Error("Too few arguments were specified.");
                    return(ExitCode_CommandLineError);
                }

                #region Arguments

                var argIndex = 1;

                string fileName  = args[argIndex++];
                string password  = null;
                string algorithm = null;

                while (argIndex < args.Length)
                {
                    var argument = args[argIndex++].ToLower();

                    if (argument.Length > 0 && argument[0] == '/')
                    {
                        argument = '-' + argument.Substring(1);
                    }

                    try
                    {
                        switch (argument)
                        {
                        case "-p":
                            password = args[argIndex++];
                            break;

                        case "-a":
                            algorithm = args[argIndex++];
                            if (false == ValidHashAlgorithmList.Contains(algorithm, StringComparer.OrdinalIgnoreCase))
                            {
                                Error("Invalid hash algorithm: '{0}'.", algorithm);
                                return(ExitCode_CommandLineError);
                            }
                            break;

                            #region Basic
                        case "?":
                        case "-?":
                        case "-h":
                            Help();
                            return(ExitCode_CommandLineError);

                        default:
                            Error("Invalid argument: '{0}'.", argument);
                            return(ExitCode_CommandLineError);

                            #endregion
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        Error("'{0}' must be followed by an additional parameter.", argument);

                        return(ExitCode_CommandLineError);
                    }
                }

                #endregion

                #region Processing

                try
                {
                    #region Load file

                    if (false == File.Exists(fileName))
                    {
                        Error("The certificate file was not found.");
                        return(ExitCode_CommandLineError);
                    }

                    X509Certificate2 certificate = null;

                    if (false == fileName.EndsWith(".pfx", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // Assume that the file may be in DER format

                        try
                        {
                            certificate = new X509Certificate2(fileName);
                        }
                        catch (CryptographicException)
                        {
                            // The file may be encrypted so ignore the error
                        }
                    }

                    if (certificate == null)
                    {
                        if (password == null)
                        {
                            // Prompt the user for a password
                            Console.Write("Enter PFX password: "******"Cannot load the certificate: {0}", exc.Message);
                            return(ExitCode_CommandLineError);
                        }
                    }

                    #endregion

                    if (string.Equals(algorithm, "SHA1", StringComparison.OrdinalIgnoreCase))
                    {
                        // Only the SHA1 hash must be displayed
                        Console.WriteLine(certificate.GetCertHashString());
                    }
                    else if (algorithm != null)
                    {
                        // Display the hash only for the specified algorithm

                        using (var hash = HashAlgorithm.Create(algorithm))
                        {
                            var binaryHash = hash.ComputeHash(certificate.GetRawCertData());
                            Console.WriteLine(BitConverter.ToString(binaryHash).Replace("-", ""));
                        }
                    }
                    else
                    {
                        // Display the hash for all supported algorithms

                        var certData = certificate.GetRawCertData();

                        foreach (var alg in HashAlgorithmList)
                        {
                            using (var hash = HashAlgorithm.Create(alg))
                            {
                                var binaryHash = hash.ComputeHash(certData);
                                Console.WriteLine("{0,-8}{1}", alg, BitConverter.ToString(binaryHash).Replace("-", ""));
                            }
                        }
                    }
                }
                catch (Exception exc)
                {
                    Error("Unexpected error: {0}", exc.Message);

                    return(ExitCode_ProcessingError);
                }

                #endregion

                return(0);
            }
            else
            {
                Error("Unknown command '{0}'. Run the program without arguments to see the help screen.", command);
                return(ExitCode_CommandLineError);
            }
        }
Beispiel #16
0
        internal static void CreateSelfSignCertificatePfx(
            string fileName,
            string hostname,
            ILogger logger)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            byte[]   sn        = Guid.NewGuid().ToByteArray();
            string   subject   = string.Format("CN={0}", hostname);
            string   issuer    = subject;
            DateTime notBefore = DateTime.Now.AddDays(-2);
            DateTime notAfter  = DateTime.Now.AddYears(10);

            RSA issuerKey = RSA.Create();

            issuerKey.FromXmlString(MonoTestRootAgency);
            RSA subjectKey = RSA.Create();

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            issuer    = subject;
            issuerKey = subjectKey;

            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = issuer;
            cb.NotBefore        = notBefore;
            cb.NotAfter         = notAfter;
            cb.SubjectName      = subject;
            cb.SubjectPublicKey = subjectKey;

            // signature
            cb.Hash = "SHA256";
            byte[] rawcert = cb.Sign(issuerKey);

            PKCS12 p12 = new PKCS12();


            ArrayList list = new ArrayList();

            // we use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[4] {
                1, 0, 0, 0
            });
            Hashtable attributes = new Hashtable(1);

            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(rawcert), attributes);

            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
            p12.SaveToFile(fileName);
        }
Beispiel #17
0
        /// <summary>
        /// Generates an X509 certificate using the Mono.Security assembly.
        /// Potentially could prise out the relevant classes from the Mono
        /// source code in order to reduce plgx size and complexity... one day
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="issuer">The issuer.</param>
        /// <returns></returns>
        public static PKCS12 Generate(string subject, string issuer, string password, KeePassRPCExt KeePassRPCPlugin)
        {
            byte[]   sn        = Guid.NewGuid().ToByteArray();
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z

            subject = "CN=" + subject;
            issuer  = "CN=" + issuer;
            RSA subjectKey = (RSA)RSA.Create();
            RSA issuerKey  = (RSA)RSA.Create();

            subjectKey.KeySize = 2048;
            issuerKey.KeySize  = 2048;

            string hashName = "SHA1";

            CspParameters subjectParams = new CspParameters();
            CspParameters issuerParams  = new CspParameters();

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
            {
                sn[0] -= 0x80;
            }

            //issuer = subject;
            //RSA issuerKey = subjectKey;

            if (subject == null)
            {
                throw new Exception("Missing Subject Name");
            }

            X509CertificateBuilder cb = new X509CertificateBuilder(3);

            cb.SerialNumber     = sn;
            cb.IssuerName       = issuer;
            cb.NotBefore        = notBefore;
            cb.NotAfter         = notAfter;
            cb.SubjectName      = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash             = hashName;

            //X509 extensions
            KeyUsageExtension keyUsage = new KeyUsageExtension();

            keyUsage.KeyUsage = KeyUsages.keyEncipherment | KeyUsages.digitalSignature;
            cb.Extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedKeyUsage = new ExtendedKeyUsageExtension();

            extendedKeyUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            cb.Extensions.Add(extendedKeyUsage);
            byte[] rawcert = cb.Sign(issuerKey);

            PKCS12 p12 = new PKCS12();

            p12.Password = password;

            ArrayList list = new ArrayList();

            // we use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[4] {
                1, 0, 0, 0
            });
            Hashtable attributes = new Hashtable(1);

            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

/*
 *          if (Type.GetType("Mono.Runtime") != null)
 *          {
 *              string fileName = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12");
 *              if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine(fileName);
 *              try
 *              {
 *                  p12.SaveToFile(fileName);
 *              }
 *              catch (Exception)
 *              {
 *                  if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine("Could not write to " + fileName + " security between KPRPC and clients may not be established.");
 *              }
 *          }
 *
 *          return p12.GetBytes();
 */
            return(p12);
        }
Beispiel #18
0
        public static int MakeCertMain(string[] args)
        {
            if (args.Length < 1)
            {
                Header();
                Console.WriteLine("ERROR: Missing output filename {0}", Environment.NewLine);
                Help();
                return(-1);
            }

            string fileName = args [args.Length - 1];

            // default values
            byte[]   sn        = Guid.NewGuid().ToByteArray();
            string   subject   = defaultSubject;
            string   issuer    = defaultIssuer;
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = new DateTime(643445675990000000);             // 12/31/2039 23:59:59Z

            RSA issuerKey = (RSA)RSA.Create();

            issuerKey.FromXmlString(MonoTestRootAgency);
            RSA subjectKey = (RSA)RSA.Create();

            bool   selfSigned = false;
            string hashName   = "SHA1";

            CspParameters             subjectParams = new CspParameters();
            CspParameters             issuerParams  = new CspParameters();
            BasicConstraintsExtension bce           = null;
            ExtendedKeyUsageExtension eku           = null;
            SubjectAltNameExtension   alt           = null;
            string          p12file           = null;
            string          p12pwd            = null;
            X509Certificate issuerCertificate = null;

            Header();
            try {
                int i = 0;
                while (i < args.Length)
                {
                    switch (args [i++])
                    {
                    // Basic options
                    case "-#":
                        // Serial Number
                        sn = BitConverter.GetBytes(Convert.ToInt32(args [i++]));
                        break;

                    case "-n":
                        // Subject Distinguish Name
                        subject = args [i++];
                        break;

                    case "-$":
                        // (authenticode) commercial or individual
                        // CRITICAL KeyUsageRestriction extension
                        // hash algorithm
                        string usageRestriction = args [i++].ToLower();
                        switch (usageRestriction)
                        {
                        case "commercial":
                        case "individual":
                            Console.WriteLine("WARNING: Unsupported deprecated certification extension KeyUsageRestriction not included");
//									Console.WriteLine ("WARNING: ExtendedKeyUsage for codesigning has been included.");
                            break;

                        default:
                            Console.WriteLine("Unsupported restriction " + usageRestriction);
                            return(-1);
                        }
                        break;

                    // Extended Options
                    case "-a":
                        // hash algorithm
                        switch (args [i++].ToLower())
                        {
                        case "sha1":
                            hashName = "SHA1";
                            break;

                        case "md5":
                            Console.WriteLine("WARNING: MD5 is no more safe for this usage.");
                            hashName = "MD5";
                            break;

                        default:
                            Console.WriteLine("Unsupported hash algorithm");
                            break;
                        }
                        break;

                    case "-b":
                        // Validity / notBefore
                        notBefore = DateTime.Parse(args [i++] + " 23:59:59", CultureInfo.InvariantCulture);
                        break;

                    case "-cy":
                        // basic constraints - autority or end-entity
                        switch (args [i++].ToLower())
                        {
                        case "authority":
                            if (bce == null)
                            {
                                bce = new BasicConstraintsExtension();
                            }
                            bce.CertificateAuthority = true;
                            break;

                        case "end":
                            // do not include extension
                            bce = null;
                            break;

                        case "both":
                            Console.WriteLine("ERROR: No more supported in X.509");
                            return(-1);

                        default:
                            Console.WriteLine("Unsupported certificate type");
                            return(-1);
                        }
                        break;

                    case "-d":
                        // CN private extension ?
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-e":
                        // Validity / notAfter
                        notAfter = DateTime.Parse(args [i++] + " 23:59:59", CultureInfo.InvariantCulture);
                        break;

                    case "-eku":
                        // extendedKeyUsage extension
                        char[]   sep      = { ',' };
                        string[] purposes = args [i++].Split(sep);
                        if (eku == null)
                        {
                            eku = new ExtendedKeyUsageExtension();
                        }
                        foreach (string purpose in purposes)
                        {
                            eku.KeyPurpose.Add(purpose);
                        }
                        break;

                    case "-h":
                        // pathLength (basicConstraints)
                        // MS use an old basicConstrains (2.5.29.10) which
                        // allows both CA and End-Entity. This is no
                        // more supported with 2.5.29.19.
                        if (bce == null)
                        {
                            bce = new BasicConstraintsExtension();
                            bce.CertificateAuthority = true;
                        }
                        bce.PathLenConstraint = Convert.ToInt32(args [i++]);
                        break;

                    case "-alt":
                        if (alt == null)
                        {
                            string [] dnsNames = File.ReadAllLines(args [i++]);
                            alt = new SubjectAltNameExtension(null, dnsNames, null, null);
                        }
                        break;

                    case "-ic":
                        issuerCertificate = LoadCertificate(args [i++]);
                        issuer            = issuerCertificate.SubjectName;
                        break;

                    case "-in":
                        issuer = args [i++];
                        break;

                    case "-iv":
                        // TODO password
                        PrivateKey pvk = PrivateKey.CreateFromFile(args [i++]);
                        issuerKey = pvk.RSA;
                        break;

                    case "-l":
                        // link (URL)
                        // spcSpAgencyInfo private extension
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-m":
                        // validity period (in months)
                        notAfter = notBefore.AddMonths(Convert.ToInt32(args [i++]));
                        break;

                    case "-nscp":
                        // Netscape's private extensions - NetscapeCertType
                        // BasicContraints - End Entity
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-r":
                        selfSigned = true;
                        break;

                    case "-sc":
                        // subject certificate ? renew ?
                        Console.WriteLine("Unsupported option");
                        break;

                    // Issuer CspParameters options
                    case "-ik":
                        issuerParams.KeyContainerName = args [i++];
                        break;

                    case "-iky":
                        // select a key in the provider
                        string ikn = args [i++].ToLower();
                        switch (ikn)
                        {
                        case "signature":
                            issuerParams.KeyNumber = 0;
                            break;

                        case "exchange":
                            issuerParams.KeyNumber = 1;
                            break;

                        default:
                            issuerParams.KeyNumber = Convert.ToInt32(ikn);
                            break;
                        }
                        break;

                    case "-ip":
                        issuerParams.ProviderName = args [i++];
                        break;

                    case "-ir":
                        switch (args [i++].ToLower())
                        {
                        case "localmachine":
                            issuerParams.Flags = CspProviderFlags.UseMachineKeyStore;
                            break;

                        case "currentuser":
                            issuerParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
                            break;

                        default:
                            Console.WriteLine("Unknown key store for issuer");
                            return(-1);
                        }
                        break;

                    case "-is":
                        Console.WriteLine("Unsupported option");
                        return(-1);

                    case "-iy":
                        issuerParams.ProviderType = Convert.ToInt32(args [i++]);
                        break;

                    // Subject CspParameters Options
                    case "-sk":
                        subjectParams.KeyContainerName = args [i++];
                        break;

                    case "-sky":
                        // select a key in the provider
                        string skn = args [i++].ToLower();
                        switch (skn)
                        {
                        case "signature":
                            subjectParams.KeyNumber = 0;
                            break;

                        case "exchange":
                            subjectParams.KeyNumber = 1;
                            break;

                        default:
                            subjectParams.KeyNumber = Convert.ToInt32(skn);
                            break;
                        }
                        break;

                    case "-sp":
                        subjectParams.ProviderName = args [i++];
                        break;

                    case "-sr":
                        switch (args [i++].ToLower())
                        {
                        case "localmachine":
                            subjectParams.Flags = CspProviderFlags.UseMachineKeyStore;
                            break;

                        case "currentuser":
                            subjectParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
                            break;

                        default:
                            Console.WriteLine("Unknown key store for subject");
                            return(-1);
                        }
                        break;

                    case "-ss":
                        Console.WriteLine("Unsupported option");
                        return(-1);

                    case "-sv":
                        string pvkFile = args [i++];
                        if (File.Exists(pvkFile))
                        {
                            PrivateKey key = PrivateKey.CreateFromFile(pvkFile);
                            subjectKey = key.RSA;
                        }
                        else
                        {
                            PrivateKey key = new PrivateKey();
                            key.RSA = subjectKey;
                            key.Save(pvkFile);
                        }
                        break;

                    case "-sy":
                        subjectParams.ProviderType = Convert.ToInt32(args [i++]);
                        break;

                    // Mono Specific Options
                    case "-p12":
                        p12file = args [i++];
                        p12pwd  = args [i++];
                        break;

                    // Other options
                    case "-?":
                        Help();
                        return(0);

                    case "-!":
                        ExtendedHelp();
                        return(0);

                    default:
                        if (i != args.Length)
                        {
                            Console.WriteLine("ERROR: Unknown parameter");
                            Help();
                            return(-1);
                        }
                        break;
                    }
                }

                // serial number MUST be positive
                if ((sn [0] & 0x80) == 0x80)
                {
                    sn [0] -= 0x80;
                }

                if (selfSigned)
                {
                    if (subject != defaultSubject)
                    {
                        issuer    = subject;
                        issuerKey = subjectKey;
                    }
                    else
                    {
                        subject    = issuer;
                        subjectKey = issuerKey;
                    }
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber     = sn;
                cb.IssuerName       = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }
                // signature
                cb.Hash = hashName;
                byte[] rawcert = cb.Sign(issuerKey);

                if (p12file == null)
                {
                    WriteCertificate(fileName, rawcert);
                }
                else
                {
                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte [4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new X509Certificate(rawcert), attributes);
                    if (issuerCertificate != null)
                    {
                        p12.AddCertificate(issuerCertificate);
                    }
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                    p12.SaveToFile(p12file);
                }
                return(0);
            }
            catch (Exception e) {
                Console.WriteLine("ERROR: " + e.ToString());
                Help();
            }
            return(1);
        }
Beispiel #19
0
        public SelfCertificateDialog(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;

            if (Environment.OSVersion.Version.Major < 8)
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .Subscribe(evt =>
            {
                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", txtCommonName.Text);
                string defaultSubject = defaultIssuer;
                byte[] sn             = Guid.NewGuid().ToByteArray();
                string subject        = defaultSubject;
                string issuer         = defaultIssuer;
                DateTime notBefore    = DateTime.Now;
                DateTime notAfter     = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z

                RSA issuerKey  = new RSACryptoServiceProvider(int.Parse(cbLength.Text));
                RSA subjectKey = null;

                CspParameters subjectParams   = new CspParameters();
                CspParameters issuerParams    = new CspParameters();
                BasicConstraintsExtension bce = new BasicConstraintsExtension
                {
                    PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                    CertificateAuthority = true
                };
                ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                SubjectAltNameExtension alt = null;
                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                // serial number MUST be positive
                if ((sn[0] & 0x80) == 0x80)
                {
                    sn[0] -= 0x80;
                }

                if (subject != defaultSubject)
                {
                    issuer    = subject;
                    issuerKey = null;
                }
                else
                {
                    subject    = issuer;
                    subjectKey = issuerKey;
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber           = sn;
                cb.IssuerName             = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }

                IDigest digest = new Sha1Digest();
                byte[] resBuf  = new byte[digest.GetDigestSize()];
                var spki       = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                byte[] bytes   = spki.PublicKeyData.GetBytes();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                digest.DoFinal(resBuf, 0);

                cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                    Identifier = resBuf
                });
                cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                    Identifier = resBuf
                });
                // signature
                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256";
                cb.Hash         = hashName;
                byte[] rawcert  = cb.Sign(issuerKey);

                PKCS12 p12   = new PKCS12();
                p12.Password = p12pwd;

                ArrayList list = new ArrayList();
                // we use a fixed array to avoid endianess issues
                // (in case some tools requires the ID to be 1).
                list.Add(new byte[] { 1, 0, 0, 0 });
                Hashtable attributes = new Hashtable(1);
                attributes.Add(PKCS9.localKeyId, list);

                p12.AddCertificate(new X509Certificate(rawcert), attributes);
                p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                p12.SaveToFile(p12File);

                Item = new X509Certificate2(p12File, p12pwd)
                {
                    FriendlyName = txtName.Text
                };
                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    using (var process = new Process())
                    {
                        // add certificate
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            this.DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            MessageBox.Show(process.ExitCode.ToString());
                        }
                    }
                }
                catch (Exception)
                {
                    // elevation is cancelled.
                }
            }));
        }
Beispiel #20
0
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var title    = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute));

            Console.WriteLine("{0} version {1}", title.Title, assembly.GetName().Version);
            var copyright = (AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute));

            Console.WriteLine(copyright.Copyright);
            Console.WriteLine("More information can be found at https://www.jexusmanager.com");
            Console.WriteLine();

            var baseAddress = args.Length > 0 ? args[0] : "https://*****:*****@"Remote services must be run as root on Linux.");
                    return;
                }

                if (!File.Exists("jws"))
                {
                    Console.WriteLine(@"Remote services must be running in Jexus installation folder.");
                    return;
                }

                var loc  = baseAddress.LastIndexOf(':');
                var port = "443";
                if (loc != -1)
                {
                    port = baseAddress.Substring(loc + 1);
                }

                string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                string path    = Path.Combine(dirname, ".mono", "httplistener");
                if (false == Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string target_cert = Path.Combine(path, string.Format("{0}.cer", port));
                if (File.Exists(target_cert))
                {
                    Console.WriteLine("Use {0}", target_cert);
                }
                else
                {
                    Console.WriteLine("Generating a self-signed certificate for Jexus Manager");

                    // Generate certificate
                    string   defaultIssuer  = "CN=jexus.lextudio.com";
                    string   defaultSubject = "CN=jexus.lextudio.com";
                    byte[]   sn             = Guid.NewGuid().ToByteArray();
                    string   subject        = defaultSubject;
                    string   issuer         = defaultIssuer;
                    DateTime notBefore      = DateTime.Now;
                    DateTime notAfter       = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z

                    RSA issuerKey  = new RSACryptoServiceProvider(2048);
                    RSA subjectKey = null;

                    bool   selfSigned = true;
                    string hashName   = "SHA1";

                    CspParameters             subjectParams = new CspParameters();
                    CspParameters             issuerParams  = new CspParameters();
                    BasicConstraintsExtension bce           = new BasicConstraintsExtension
                    {
                        PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                        CertificateAuthority = true
                    };
                    ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                    eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                    SubjectAltNameExtension alt = null;
                    string p12file = Path.Combine(path, "temp.pfx");
                    string p12pwd  = "test";

                    // serial number MUST be positive
                    if ((sn[0] & 0x80) == 0x80)
                    {
                        sn[0] -= 0x80;
                    }

                    if (selfSigned)
                    {
                        if (subject != defaultSubject)
                        {
                            issuer    = subject;
                            issuerKey = subjectKey;
                        }
                        else
                        {
                            subject    = issuer;
                            subjectKey = issuerKey;
                        }
                    }

                    if (subject == null)
                    {
                        throw new Exception("Missing Subject Name");
                    }

                    X509CertificateBuilder cb = new X509CertificateBuilder(3);
                    cb.SerialNumber     = sn;
                    cb.IssuerName       = issuer;
                    cb.NotBefore        = notBefore;
                    cb.NotAfter         = notAfter;
                    cb.SubjectName      = subject;
                    cb.SubjectPublicKey = subjectKey;
                    // extensions
                    if (bce != null)
                    {
                        cb.Extensions.Add(bce);
                    }
                    if (eku != null)
                    {
                        cb.Extensions.Add(eku);
                    }
                    if (alt != null)
                    {
                        cb.Extensions.Add(alt);
                    }

                    IDigest digest = new Sha1Digest();
                    byte[]  resBuf = new byte[digest.GetDigestSize()];
                    var     spki   = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                    byte[]  bytes  = spki.PublicKeyData.GetBytes();
                    digest.BlockUpdate(bytes, 0, bytes.Length);
                    digest.DoFinal(resBuf, 0);

                    cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                        Identifier = resBuf
                    });
                    cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                        Identifier = resBuf
                    });
                    // signature
                    cb.Hash = hashName;
                    byte[] rawcert = cb.Sign(issuerKey);

                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte[4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes);
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                    p12.SaveToFile(p12file);

                    var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(p12file, p12pwd, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);

                    // Install certificate
                    string target_pvk = Path.Combine(path, string.Format("{0}.pvk", port));

                    using (Stream cer = File.OpenWrite(target_cert))
                    {
                        byte[] raw = x509.RawData;
                        cer.Write(raw, 0, raw.Length);
                    }

                    PrivateKey pvk = new PrivateKey();
                    pvk.RSA = subjectKey;
                    pvk.Save(target_pvk);
                }
            }

            JexusServer.Credentials = args.Length > 2 ? args[1] + "|" + args[2] : "jexus|lextudio.com";
            JexusServer.Timeout     = args.Length > 3 ? double.Parse(args[3]) : 30D;

            using (WebApp.Start <Startup>(url: baseAddress))
            {
                Console.WriteLine("Remote services have started at {0}.", baseAddress);
                Console.WriteLine("Credentials is {0}", JexusServer.Credentials);
                Console.WriteLine("Press Enter to quit.");
                Console.ReadLine();
            }
        }
Beispiel #21
0
        public SelfCertificateDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;
            dtpFrom.Value           = DateTime.Now;
            dtpTo.Value             = dtpFrom.Value.AddYears(1);

            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var names = txtCommonName.Text;
                if (string.IsNullOrWhiteSpace(names))
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                var dnsNames = names.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(item => item.Trim()).ToArray();
                if (dnsNames.Length == 0)
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", dnsNames[0]);
                string defaultSubject = defaultIssuer;
                byte[] sn             = Guid.NewGuid().ToByteArray();
                string subject        = defaultSubject;
                string issuer         = defaultIssuer;
                DateTime notBefore    = dtpFrom.Value;
                DateTime notAfter     = dtpTo.Value;

                RSA issuerKey  = new RSACryptoServiceProvider(int.Parse(cbLength.Text));
                RSA subjectKey = null;

                CspParameters subjectParams   = new CspParameters();
                CspParameters issuerParams    = new CspParameters();
                BasicConstraintsExtension bce = new BasicConstraintsExtension
                {
                    PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                    CertificateAuthority = true
                };
                ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                SubjectAltNameExtension alt = null;
                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                // serial number MUST be positive
                if ((sn[0] & 0x80) == 0x80)
                {
                    sn[0] -= 0x80;
                }

                if (subject != defaultSubject)
                {
                    issuer    = subject;
                    issuerKey = null;
                }
                else
                {
                    subject    = issuer;
                    subjectKey = issuerKey;
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber           = sn;
                cb.IssuerName             = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }

                IDigest digest = new Sha1Digest();
                byte[] resBuf  = new byte[digest.GetDigestSize()];
                var spki       = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                byte[] bytes   = spki.PublicKeyData.GetBytes();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                digest.DoFinal(resBuf, 0);

                cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                    Identifier = resBuf
                });
                cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                    Identifier = resBuf
                });
                if (cbGenerate.Checked)
                {
                    SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(
                        new string[0],
                        dnsNames,
                        new string[0],
                        new string[0])
                    {
                        Critical = false
                    };
                    cb.Extensions.Add(subjectAltNameExtension);
                }

                // signature
                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256";
                cb.Hash         = hashName;
                byte[] rawcert  = null;
                try
                {
                    rawcert = cb.Sign(issuerKey);
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    ShowError(ex, "Certificate generation error", false);
                    return;
                }

                PKCS12 p12   = new PKCS12();
                p12.Password = p12pwd;

                ArrayList list = new ArrayList();
                // we use a fixed array to avoid endianess issues
                // (in case some tools requires the ID to be 1).
                list.Add(new byte[] { 1, 0, 0, 0 });
                Hashtable attributes = new Hashtable(1);
                attributes.Add(PKCS9.localKeyId, list);

                p12.AddCertificate(new X509Certificate(rawcert), attributes);
                p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                p12.SaveToFile(p12File);

                Item = new X509Certificate2(p12File, p12pwd)
                {
                    FriendlyName = txtName.Text
                };
                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    using (var process = new Process())
                    {
                        // add certificate
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            ShowMessage(process.ExitCode.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        }
                    }
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (ex.NativeErrorCode != Microsoft.Web.Administration.NativeMethods.ErrorCancelled)
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        // throw;
                    }
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
Beispiel #22
0
        /// <summary>
        /// Generates an X509 certificate using the Mono.Security assembly.
        /// Potentially could prise out the relevant classes from the Mono
        /// source code in order to reduce plgx size and complexity... one day
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="issuer">The issuer.</param>
        /// <returns></returns>
        public static PKCS12 Generate(string subject, string issuer, string password, KeePassRPCExt KeePassRPCPlugin)
        {
            byte[] sn = Guid.NewGuid().ToByteArray();
            DateTime notBefore = DateTime.Now;
            DateTime notAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            subject = "CN=" + subject;
            issuer = "CN=" + issuer;
            RSA subjectKey = (RSA)RSA.Create();
            RSA issuerKey = (RSA)RSA.Create();
            subjectKey.KeySize = 2048;
            issuerKey.KeySize = 2048;

            string hashName = "SHA1";

            CspParameters subjectParams = new CspParameters();
            CspParameters issuerParams = new CspParameters();

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
                sn[0] -= 0x80;

            //issuer = subject;
            //RSA issuerKey = subjectKey;

            if (subject == null)
                throw new Exception("Missing Subject Name");

            X509CertificateBuilder cb = new X509CertificateBuilder(3);
            cb.SerialNumber = sn;
            cb.IssuerName = issuer;
            cb.NotBefore = notBefore;
            cb.NotAfter = notAfter;
            cb.SubjectName = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash = hashName;

            //X509 extensions
            KeyUsageExtension keyUsage = new KeyUsageExtension();
            keyUsage.KeyUsage = KeyUsages.keyEncipherment | KeyUsages.digitalSignature;
            cb.Extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedKeyUsage = new ExtendedKeyUsageExtension();
            extendedKeyUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            cb.Extensions.Add(extendedKeyUsage);
            byte[] rawcert = cb.Sign(issuerKey);

            PKCS12 p12 = new PKCS12();
            p12.Password = password;

            ArrayList list = new ArrayList();
            // we use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[4] { 1, 0, 0, 0 });
            Hashtable attributes = new Hashtable(1);
            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

            /*
            if (Type.GetType("Mono.Runtime") != null)
            {
                string fileName = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12");
                if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine(fileName);
                try
                {
                    p12.SaveToFile(fileName);
                }
                catch (Exception)
                {
                    if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine("Could not write to " + fileName + " security between KPRPC and clients may not be established.");
                }
            }

            return p12.GetBytes();
            */
            return p12;
        }