Beispiel #1
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);
        }
Beispiel #2
0
 static RSA GetKeyFromFile(string filename)
 {
     byte[] data = ReadFromFile(filename);
     try {
         // for SNK files (including the ECMA pseudo-key)
         return(new StrongName(data).RSA);
     }
     catch {
         if (data [0] != 0x30)
         {
             throw;
         }
         // this could be a PFX file
         Console.Write("Enter password for private key (will be visible when typed): ");
         PKCS12 pfx = new PKCS12(data, Console.ReadLine());
         // works only if a single key is present
         if (pfx.Keys.Count != 1)
         {
             throw;
         }
         RSA rsa = (pfx.Keys [0] as RSA);
         if (rsa == null)
         {
             throw;
         }
         return(rsa);
     }
 }
Beispiel #3
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 #4
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 #5
0
        private void buttonX1_Click(object sender, EventArgs e)
        {
            try
            {
                if (cadlg.ShowDialog() == DialogResult.OK)
                {
                    if (cadlg.FileName.EndsWith(".p12") || cadlg.FileName.EndsWith(".pfx"))
                    {
                        PassForm frm = new PassForm();
                        frm.ShowDialog();
                        if (frm.pass != null)
                        {
                            textBoxX1.Text = cadlg.FileName;

                            using (var bio = BIO.File(cadlg.FileName, "r"))
                                PFX = new PKCS12(bio, frm.pass);
                            CACert            = new System.Security.Cryptography.X509Certificates.X509Certificate2(PFX.Certificate.DER);
                            stepItem5.Value   = 50;
                            textBoxX3.Enabled = true;
                            buttonX3.Enabled  = true;
                            buttonX2.Enabled  = true;
                        }
                        else
                        {
                            throw new ArgumentException("PKCS12 password was not defined");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBoxEx.Show(ex.Message, "CA Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
Beispiel #6
0
        public static byte[] GetCertificateForBytes(byte[] pfx, string password)
        {
            var pkcs = new PKCS12(pfx, password);
            var cert = pkcs.GetCertificate(GetAttributes());

            return(cert.RawData);
        }
Beispiel #7
0
        /// <summary>
        /// Exports the X.509 certificate and its private key in PKCS#12 (.pfx, .p12) format.
        /// </summary>
        /// <param name="privateKey">The certificate's private key.</param>
        /// <param name="password">The password to use to protect the private key.</param>
        /// <param name="iterations">The iterations to perform to derive encryption keys from the password.</param>
        /// <returns>The certificate.</returns>
        /// <exception cref="InvalidOperationException">The certificate is not signed.</exception>
        /// <remarks>You must call the <see cref="SelfSign"/> of <see cref="Sign"/> method before
        /// exporting the certificate.</remarks>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="iterations"/> is less than 1000.</exception>
        /// <exception cref="ArgumentException"><paramref name="privateKey"/> is not exportable.</exception>
        public byte[] ExportPkcs12(AsymmetricAlgorithm privateKey, string password, int iterations)
        {
            if (_signedCertificate == null)
            {
                throw new InvalidOperationException("The certificate is not signed.");
            }

            if (privateKey == null)
            {
                throw new ArgumentNullException("privateKey");
            }

            if (iterations < 1000)
            {
                throw new ArgumentOutOfRangeException("iterations", iterations, "Must be greater than or equal to 1000.");
            }

            if (privateKey is ICspAsymmetricAlgorithm)
            {
                var container = ((ICspAsymmetricAlgorithm)privateKey).CspKeyContainerInfo;

                if (container.KeyContainerName == null || container.Exportable)
                {
                    // The container is valid
                }
                else
                {
                    throw new ArgumentException("The private key must be exportable.", "privateKey");
                }
            }

            PKCS12 p12 = new PKCS12();

            p12.IterationCount = iterations;

            p12.Password = password ?? string.Empty;

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

            var attributes = new Hashtable(1);

            attributes.Add(PKCS9.localKeyId, list);

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

            p12.AddPkcs8ShroudedKeyBag(privateKey, attributes);

            return(p12.GetBytes());
        }
Beispiel #8
0
 public void CanCreatePKCS12()
 {
     using (BIO bio = new BIO(LoadBytes(Resources.ServerPfx))) {
         using (var pfx = new PKCS12(bio, password)) {
             using (var new_pfx = new PKCS12(password, pfx.PrivateKey, pfx.Certificate, pfx.CACertificates)) {
                 TestCert(new_pfx.Certificate, "CN=localhost", "CN=Root", 1235);
             }
         }
     }
 }
Beispiel #9
0
 public static bool IsPasswordValid(byte[] data, string password)
 {
     try
     {
         var pkcs12 = new PKCS12(data, password);
         return(pkcs12.Keys.Count > 0);
     }
     catch (CryptographicException)
     {
         return(false);
     }
 }
 public void CanCreatePKCS12()
 {
     using (BIO bio = BIO.File(Paths.ServerPfx, "r")) {
         using (var pfx = new PKCS12(bio, password)) {
             using (var new_pfx = new PKCS12(password, pfx.PrivateKey, pfx.Certificate, pfx.CACertificates)) {
                 using (BIO bout = BIO.File(Paths.ServerOutPfx, "w")) {
                     new_pfx.Write(bout);
                 }
                 TestCert(new_pfx.Certificate, "CN=localhost", "CN=Root", 1235);
             }
         }
     }
 }
Beispiel #11
0
 /// <summary>
 /// Extract key pair from PKCS12 certificate.
 /// </summary>
 public static byte[] ExtractKeyPairFromPKCS12(byte[] data, string password)
 {
     try
     {
         var pkcs12 = new PKCS12(data, password);
         var rsa    = pkcs12.Keys[0];
         return(rsa.ToCapiPrivateKeyBlob());
     }
     catch (Exception)
     {
         throw new CryptographicException(SR.InvalidCertificate);
     }
 }
Beispiel #12
0
        private void StoreCertificate(string name, byte[] raw, RSA key, MSX509.StoreName storeName, MSX509.StoreLocation location)
        {
            PKCS12 p12 = BuildPkcs12(raw, key);

            MSX509.X509Certificate2 certificate = new MSX509.X509Certificate2(p12.GetBytes(), "advtools", MSX509.X509KeyStorageFlags.PersistKeySet | MSX509.X509KeyStorageFlags.MachineKeySet | MSX509.X509KeyStorageFlags.Exportable);

            MSX509.X509Store store = new MSX509.X509Store(storeName, location);
            store.Open(MSX509.OpenFlags.ReadWrite);
            store.Add(certificate);
            store.Close();

            certificates_[name] = certificate;
        }
Beispiel #13
0
        static X509CertificateCollection LoadCertificates(string filename)
        {
            X509Certificate           x509 = null;
            X509CertificateCollection coll = new X509CertificateCollection();

            switch (Path.GetExtension(filename).ToUpper())
            {
            case ".P7B":
            case ".SPC":
                SoftwarePublisherCertificate spc = SoftwarePublisherCertificate.CreateFromFile(filename);
                coll.AddRange(spc.Certificates);
                spc = null;
                break;

            case ".CER":
            case ".CRT":
                using (FileStream fs = File.OpenRead(filename)) {
                    byte[] data = new byte [fs.Length];
                    fs.Read(data, 0, data.Length);
                    if (data [0] != 0x30)
                    {
                        // maybe it's ASCII PEM base64 encoded ?
                        data = PEM("CERTIFICATE", data);
                    }
                    if (data != null)
                    {
                        x509 = new X509Certificate(data);
                    }
                }
                if (x509 != null)
                {
                    coll.Add(x509);
                }
                break;

            case ".P12":
            case ".PFX":
                // TODO - support PKCS12 with passwords
                PKCS12 p12 = PKCS12.LoadFromFile(filename);
                coll.AddRange(p12.Certificates);
                p12 = null;
                break;

            default:
                Console.WriteLine("Unknown file extension: {0}",
                                  Path.GetExtension(filename));
                break;
            }
            return(coll);
        }
Beispiel #14
0
        public override void ExportArchive(PrivateKey pk, IEnumerable <Crt> certs, ArchiveFormat fmt, Stream target, string password = "")
        {
            var rsaPk = pk as RsaPrivateKey;

            if (rsaPk == null)
            {
                throw new NotSupportedException("unsupported private key type");
            }

            if (fmt == ArchiveFormat.PKCS12)
            {
                var x509Arr = certs.Select(x =>
                {
                    using (var bio = BIO.MemoryBuffer())
                    {
                        bio.Write(x.Pem);
                        return(new X509Certificate(bio));
                    }
                }).ToArray();

                using (var key = CryptoKey.FromPrivateKey(rsaPk.Pem, null))
                {
                    var caStack = new OpenSSL.Core.Stack <X509Certificate>();
                    for (int i = 1; i < x509Arr.Length; ++i)
                    {
                        caStack.Add(x509Arr[i]);
                    }

                    using (var pfx = new PKCS12(password == string.Empty ? null : password, key, x509Arr[0], caStack))
                    {
                        using (var bio = BIO.MemoryBuffer())
                        {
                            pfx.Write(bio);
                            var count = (int)bio.BytesPending;
                            var array = bio.ReadBytes(count);
                            target.Write(array.Array, 0, count);
                        }
                    }
                }

                foreach (var x in x509Arr)
                {
                    x.Dispose();
                }
            }
            else
            {
                throw new NotSupportedException("unsupported archive format");
            }
        }
Beispiel #15
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 #16
0
 public virtual void Import(byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
 {
     Reset();
     if (password == null)
     {
         try {
             x509 = new Mono.Security.X509.X509Certificate(rawData);
         }
         catch (Exception e) {
             try {
                 PKCS12 pfx = new PKCS12(rawData);
                 if (pfx.Certificates.Count > 0)
                 {
                     x509 = pfx.Certificates [0];
                 }
                 else
                 {
                     x509 = null;
                 }
             }
             catch {
                 string msg = Locale.GetText("Unable to decode certificate.");
                 // inner exception is the original (not second) exception
                 throw new CryptographicException(msg, e);
             }
         }
     }
     else
     {
         // try PKCS#12
         try {
             PKCS12 pfx = new PKCS12(rawData, password);
             if (pfx.Certificates.Count > 0)
             {
                 x509 = pfx.Certificates [0];
             }
             else
             {
                 x509 = null;
             }
         }
         catch {
             // it's possible to supply a (unrequired/unusued) password
             // fix bug #79028
             x509 = new Mono.Security.X509.X509Certificate(rawData);
         }
     }
 }
Beispiel #17
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 #18
0
            /// <summary>
            /// Converts a certificate and private key to a PKCS#12 (.PFX) file.
            /// </summary>
            public static void ConvertToPfx(Stream keyPemSource, Stream crtPemSource, Stream isrPemSource, Stream pfxTarget)
            {
                using (BIO keyBio = BIO.MemoryBuffer(),
                       crtBio = BIO.MemoryBuffer(),
                       isrBio = BIO.MemoryBuffer())
                {
                    using (var ms = new MemoryStream())
                    {
                        keyPemSource.CopyTo(ms);
                        keyBio.Write(ms.ToArray());
                    }
                    using (var ms = new MemoryStream())
                    {
                        crtPemSource.CopyTo(ms);
                        crtBio.Write(ms.ToArray());
                    }
                    using (var ms = new MemoryStream())
                    {
                        isrPemSource.CopyTo(ms);
                        isrBio.Write(ms.ToArray());
                    }

                    using (var key = CryptoKey.FromPrivateKey(keyBio, null))
                    {
                        using (var crt = new X509Certificate(crtBio))
                        {
                            using (var isr = new X509Certificate(isrBio))
                            {
                                var isrStack = new OpenSSL.Core.Stack <X509Certificate>();
                                isrStack.Add(isr);

                                using (var pfx = new PKCS12(null, key, crt, isrStack))
                                {
                                    using (var pfxBio = BIO.MemoryBuffer())
                                    {
                                        pfx.Write(pfxBio);
                                        var arr = pfxBio.ReadBytes((int)pfxBio.BytesPending);
                                        pfxTarget.Write(arr.Array, arr.Offset, arr.Count);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        /// <summary>
        /// Writes the specified Certificate and Crypto key out to the file defined in the fileName parameter. This
        /// file is protected with the specified password. The password is optional.
        /// </summary>
        /// <param name="fileName">The file name and path of the pfx file to be created.</param>
        /// <param name="password">The password to be put on the pfx file if any.</param>
        /// <param name="cryptoKey">The CryptoKey containing the private key that belongs to the certificate parameter.</param>
        /// <param name="certificate">The certificate to write to file.</param>
        public static void WritePfxToFile(string fileName, string password, CryptoKey cryptoKey, X509Certificate certificate)
        {
            if (cryptoKey == null)
            {
                throw new ArgumentNullException("cryptoKey", "CryptoKey is null");
            }
            if (certificate == null)
            {
                throw new ArgumentNullException("certificate", "certificate is null");
            }

            using (var bio = FileHelpers.Write(fileName))
                using (var caStack = new OpenSSL.Core.Stack <X509Certificate>())
                    using (var pfx = new PKCS12(password, cryptoKey, certificate, caStack))
                    {
                        pfx.Write(bio);
                    }
        }
Beispiel #20
0
        private void ImportPkcs12(byte[] rawData, string password)
        {
            PKCS12 pkcs = (password != null) ? new PKCS12(rawData, password) : new PKCS12(rawData);

            if (pkcs.Certificates.Count > 0)
            {
                this._cert = pkcs.Certificates[0];
            }
            else
            {
                this._cert = null;
            }
            if (pkcs.Keys.Count > 0)
            {
                this._cert.RSA = (pkcs.Keys[0] as RSA);
                this._cert.DSA = (pkcs.Keys[0] as DSA);
            }
        }
Beispiel #21
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 #22
0
        private PKCS12 BuildPkcs12(byte[] raw, RSA key)
        {
            PKCS12 p12 = new PKCS12();

            p12.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(raw), attributes);
            p12.AddPkcs8ShroudedKeyBag(key, attributes);

            return(p12);
        }
Beispiel #23
0
        private String BuildPKCS12(String password, CryptoKey key, X509Certificate cert)
        {
            String retCert = "";

            //Copia para memória
            using (MemoryStream ms = new MemoryStream())
            {
                using (PKCS12 pfx = new PKCS12(password, key, cert, new OpenSSL.Core.Stack <X509Certificate>()))
                    using (BinaryWriter bw = new BinaryWriter(ms))
                        using (BIO bio = BIO.MemoryBuffer())
                        {
                            pfx.Write(bio);
                            Byte[] certData = bio.ReadBytes((Int32)bio.NumberWritten).Array;
                            bw.Write(certData);
                            bw.Close();
                        }

                retCert = Convert.ToBase64String(ms.ToArray());
            }

            return(retCert);
        }
Beispiel #24
0
        /// <summary>
        /// Initialize an rsaKey member variable with the specified RSA key.
        /// </summary>
        private void InitializeKey()
        {
            try{
//			PrivateKey prvkey = PrivateKey.CreateFromFile(keyPath.Value);
                PKCS12 pkcs12 = PKCS12.LoadFromFile(keyPath.Value, pvkPass.Value);
                if (pkcs12 != null)
                {
                    foreach (RSA rsa in pkcs12.Keys)
                    {
                        Console.WriteLine("Key {0}", rsa.ToXmlString(true));
                        rsadec = rsa as RSACryptoServiceProvider;
                        break;
                    }
                }
/// Encryption Key
///			eKey = prvkey.RSA;
//			dKey = prvkey.RSA;
            }
            catch (System.Security.Cryptography.CryptographicException e) {
                Console.WriteLine("Exception", e.ToString());
            }
        }
Beispiel #25
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 #26
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 #27
0
        public static RSA GetKey(byte[] data, string password = null)
        {
            try
            {
                // for SNK files (including the ECMA pseudo-key)
                return(new StrongName(data).RSA);
            }
            catch
            {
                if (data.Length == 0 || data[0] != 0x30)
                {
                    throw;
                }

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

                var pfx = new PKCS12(data, password);

                // works only if a single key is present
                if (pfx.Keys.Count != 1)
                {
                    throw;
                }

                var rsa = pfx.Keys[0] as RSA;
                if (rsa == null)
                {
                    throw;
                }

                return(rsa);
            }
        }
Beispiel #28
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 #29
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 #30
0
 public static (EVP_PKEY privateKey, X509 certificate) PKCS12_parse(PKCS12 p12, string password)
 {
     ThrowOnErrorReturnCode(PKCS12_parse(p12, password, out EVP_PKEY privateKey, out X509 cert, IntPtr.Zero));
     return(privateKey, cert);
 }
Beispiel #31
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;
        }