//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); }
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); } }
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()); }
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())); }
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); } }
public static byte[] GetCertificateForBytes(byte[] pfx, string password) { var pkcs = new PKCS12(pfx, password); var cert = pkcs.GetCertificate(GetAttributes()); return(cert.RawData); }
/// <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()); }
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); } } } }
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); } } } }
/// <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); } }
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; }
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); }
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"); } }
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()); }
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); } } }
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); }
/// <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); } }
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); } }
/// <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())); }
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); }
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); }
/// <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()); } }
/// <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); } } }
//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()); }
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); } }
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(); })); }
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); }
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); }
/// <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; }