/// <summary>This method is called by a CA to sign the provided Certificate /// with our RSA key.</summary> public Certificate Sign(Certificate Signer, RSA PrivateKey) { X509CertificateBuilder x509_builder = new X509CertificateBuilder(3); x509_builder.IssuerName = Signer.Subject.DN; x509_builder.SubjectName = Subject.DN; SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); // I guess this is reversed for network order or something... byte[] tmp = sha1.ComputeHash(Signer.UnsignedData); for (int i = 0; i < tmp.Length / 2; i++) { int j = tmp.Length - i - 1; byte tmpb = tmp[i]; tmp[i] = tmp[j]; tmp[j] = tmpb; } x509_builder.SerialNumber = tmp; x509_builder.NotBefore = System.DateTime.MinValue; x509_builder.NotAfter = System.DateTime.MaxValue; x509_builder.SubjectPublicKey = _public_key; SubjectAltNameExtension sane = new SubjectAltNameExtension(null, null, null, new string[] { NodeAddress }); x509_builder.Extensions.Add(sane); byte[] cert_data = x509_builder.Sign(PrivateKey); return(new Certificate(cert_data)); }
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()); }
//adapted from https://github.com/mono/mono/blob/master/mcs/tools/security/makecert.cs public static PKCS12 GeneratePfx(string certificateName, string password) { byte[] sn = GenerateSerialNumber(); string subject = string.Format("CN={0}", certificateName); DateTime notBefore = DateTime.Now; DateTime notAfter = DateTime.Now.AddYears(20); var subjectKey = new RSACryptoServiceProvider(2048); var hashName = "SHA512"; var cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = subject; cb.NotBefore = notBefore; cb.NotAfter = notAfter; cb.SubjectName = subject; cb.SubjectPublicKey = subjectKey; cb.Hash = hashName; var rawcert = cb.Sign(subjectKey); var p12 = new PKCS12(); p12.Password = password; var attributes = GetAttributes(); p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes); p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); return(p12); }
public void SubjectAltNameGenerator() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); X509CertificateBuilder x509 = new X509CertificateBuilder(); x509.IssuerName = "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server"; x509.NotAfter = DateTime.MaxValue; x509.NotBefore = DateTime.MinValue; x509.SubjectName = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org"; x509.SerialNumber = new byte[] { 12, 34, 56, 78, 90 }; x509.Version = 3; x509.SubjectPublicKey = rsa; string[] dns = new string[2]; dns[0] = "one"; dns[1] = "two"; string[] uris = new string[3]; uris[0] = "one:two://three"; uris[1] = "Here:I:AM://12345"; uris[2] = "last:one"; SubjectAltNameExtension sane = new SubjectAltNameExtension(null, dns, null, uris); x509.Extensions.Add(sane); byte[] data = x509.Sign(rsa); X509Certificate x509_loaded = new X509Certificate(data); SubjectAltNameExtension sane_test = new SubjectAltNameExtension(x509_loaded.Extensions[0]); Assert.AreEqual(sane_test.RFC822.Length, 0, "RFC822 count"); Assert.AreEqual(sane_test.DNSNames.Length, 2, "DNSName count"); Assert.AreEqual(sane_test.IPAddresses.Length, 0, "IPAddresses count"); Assert.AreEqual(sane_test.UniformResourceIdentifiers.Length, 3, "URI Count"); Assert.AreEqual(sane_test.DNSNames[1], "two", "DNSName test"); Assert.AreEqual(sane_test.UniformResourceIdentifiers[2], "last:one", "URI Test"); }
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 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 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); }
public static void CreateServerRootCA(string issuer, out byte[] rootKey, out byte[] rootCert) { if (!issuer.StartsWith("CN=")) { issuer = "CN=" + issuer; } // Create a temporary file string tempFile = Path.GetTempFileName(); // Generate a new signing key RSA issuerKey = (RSA)RSA.Create(); // Generate a private key PrivateKey key = new PrivateKey(); key.RSA = issuerKey; // Save the private key and load it back into memory key.Save(tempFile); rootKey = File.ReadAllBytes(tempFile); File.Delete(tempFile); // Serial number MUST be positive byte[] sn = Guid.NewGuid().ToByteArray(); if ((sn[0] & 0x80) == 0x80) { sn[0] -= 0x80; } // Generate a self-signed certificate X509CertificateBuilder cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = issuer; cb.NotBefore = DateTime.Now; cb.NotAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z cb.SubjectName = issuer; cb.SubjectPublicKey = issuerKey; cb.Hash = "SHA1"; rootCert = cb.Sign(issuerKey); }
/// <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 MSX509.X509Certificate2 CreateCertificate(string name, List <X509Extension> extensions, MSX509.X509Certificate2 issuerCertificate, string issuer, MSX509.StoreName storeName, int validity) { MSX509.X509Certificate2 certificate = LoadCertificate(name, storeName, location_); if (certificate != null) { return(certificate); } state_.Logger.Information("Create X509.v3 certificate for '{0}'", name); PrivateKey key = new PrivateKey(); key.RSA = RSA.Create(); X509CertificateBuilder builder = new X509CertificateBuilder(3); builder.SerialNumber = GenerateSerial(); builder.IssuerName = "CN=" + issuer; builder.SubjectName = "CN=" + name; builder.SubjectPublicKey = key.RSA; builder.NotBefore = DateTime.Now; builder.NotAfter = builder.NotBefore.AddDays(validity); builder.Hash = "SHA1"; foreach (X509Extension extension in extensions) { builder.Extensions.Add(extension); } var signator = issuerCertificate == null ? key.RSA : issuerCertificate.PrivateKey; byte[] raw = builder.Sign(signator); StoreCertificate(name, raw, key.RSA, storeName, location_); certificate = new MSX509.X509Certificate2(raw); certificate.PrivateKey = key.RSA; return(certificate); }
/// <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()); }
// TODO : cleanup and reorganization, as the code below is a almost a direct copypaste from Mono project's Makecert tool. internal /* byte[]*/ PKCS12 GenerateCertificate(/*string[] args,*/ bool isHubRootCA, bool isHubCert, string subjectName, string[] alternateDnsNames) { if (isHubRootCA && isHubCert) { throw new Exception("incompatible options isHubRootCA & isHubCert"); } Logger.Append("HUBRN", Severity.INFO, "Asked to create " + ((isHubCert)?"hub certificate, ":"") + ((isHubRootCA)?"root CA, ":"") + ((!isHubCert && !isHubRootCA)?" node certificate for '" + subjectName + "'":"")); string rootKey = ConfigurationManager.AppSettings["Security.CAKey"]; string rootCert = ConfigurationManager.AppSettings["Security.CACertificate"]; byte[] sn = Guid.NewGuid().ToByteArray(); string issuer = defaultIssuer; DateTime notBefore = DateTime.Now; DateTime notAfter = DateTime.Now.AddYears(5); RSA issuerKey = (RSA)RSA.Create(); //issuerKey.FromXmlString(MonoTestRootAgency); RSA subjectKey = (RSA)RSA.Create(); bool selfSigned = isHubRootCA; string hashName = "SHA1"; BasicConstraintsExtension bce = null; ExtendedKeyUsageExtension eku = null; SubjectAltNameExtension alt = null; string p12pwd = null; X509Certificate issuerCertificate = null; try{ if (subjectName == null) { throw new Exception("Missing Subject Name"); } if (!subjectName.ToLower().StartsWith("cn=")) { subjectName = "CN=" + subjectName; } /*if (alternateDnsNames != null){ * alt = new SubjectAltNameExtension(null, alternateDnsNames, null, null); * }*/ if (!isHubRootCA) { issuerCertificate = LoadCertificate(rootCert); issuer = issuerCertificate.SubjectName; //case "-iv": // TODO password PrivateKey pvk = PrivateKey.CreateFromFile(rootKey); issuerKey = pvk.RSA; } // Issuer CspParameters options if (isHubRootCA) { //subjectName = defaultSubject; string pvkFile = rootKey; if (File.Exists(pvkFile)) // CA key already exists, reuse { PrivateKey key = PrivateKey.CreateFromFile(pvkFile); subjectKey = key.RSA; } else { PrivateKey key = new PrivateKey(); key.RSA = subjectKey; key.Save(pvkFile); // save 'the Mother Of All Keys' //WriteHubMotherCert(issuerKey.ToXmlString(true)); } } else { p12pwd = ""; } // serial number MUST be positive if ((sn [0] & 0x80) == 0x80) { sn [0] -= 0x80; } if (selfSigned) { if (subjectName != defaultSubject) { issuer = subjectName; issuerKey = subjectKey; //issuerKey = Hub.MotherKey; } else { subjectName = issuer; subjectKey = issuerKey; } } X509CertificateBuilder cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = issuer; cb.NotBefore = notBefore; cb.NotAfter = notAfter; cb.SubjectName = subjectName; cb.SubjectPublicKey = subjectKey; // extensions if (bce != null) { cb.Extensions.Add(bce); } if (eku != null) { cb.Extensions.Add(eku); } if (alt != null) { cb.Extensions.Add(alt); } // signature cb.Hash = hashName; byte[] rawcert = cb.Sign(issuerKey); if (isHubRootCA) // Hub CA { WriteCACertificate(rawcert); } else { PKCS12 p12 = new PKCS12(); p12.Password = p12pwd; ArrayList list = new ArrayList(); // we use a fixed array to avoid endianess issues // (in case some tools requires the ID to be 1). list.Add(new byte [4] { 1, 0, 0, 0 }); Hashtable attributes = new Hashtable(1); attributes.Add(PKCS9.localKeyId, list); p12.AddCertificate(new X509Certificate(rawcert), attributes); if (issuerCertificate != null) { p12.AddCertificate(issuerCertificate); } p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); /*var x509cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(); * x509cert2.Import(p12.GetBytes(), "", * System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet| System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable ); * return x509cert2;*/ //return p12.GetBytes(); return(p12); } Logger.Append("HUBRN", Severity.INFO, "Created requested key/cert for '" + subjectName + "'."); } catch (Exception e) { Logger.Append("HUBRN", Severity.ERROR, "Error generating certificate for '" + subjectName + "' : " + e.ToString()); } return(null); }
byte[] GenerateCertificate(Options options) { var builder = new X509CertificateBuilder(); // If the default key container is not used accessing the key will throw a "Key not found" exception using (var rsa = new RSACryptoServiceProvider(options.keySize, new CspParameters() { Flags = CspProviderFlags.UseDefaultKeyContainer | CspProviderFlags.CreateEphemeralKey })) { try { #region Key builder.PublicKey = rsa; #endregion builder.SubjectName = options.subjectName; builder.SubjectAlternativeNames = options.subjectAlternativeNames; builder.SerialNumber = options.serialNumber; builder.KeyUsages = options.basicKeyUsages; builder.KeyUsagesCritical = options.basicKeyUsagesCritical; if (options.extendedUsages != null) { builder.ExtendedKeyUsages = options.extendedUsages.ToArray(); } builder.ExtendedKeyUsagesCritical = options.extendedUsagesCritical; builder.NotBefore = options.fromDate; builder.NotAfter = options.toDate; builder.IsCertificateAuthority = options.isCA; builder.CertificateAuthorityPathLength = options.caLength; if (options.issuerCertificate == null) { builder.SelfSign(rsa); } else { builder.Sign(options.issuerCertificate); } File.WriteAllBytes(options.outputFile, builder.ExportPkcs12(rsa, options.outputPassword, 1000)); var certData = builder.Export(); if (false == string.IsNullOrEmpty(options.outputCertFile)) { File.WriteAllBytes(options.outputCertFile, certData); } return(certData); } finally { // Remove the key from the key container. Otherwise, the key will be kept on the file // system which is completely undesirable. rsa.PersistKeyInCsp = false; } } }
static int Main(string[] args) { if (args.Length < 1) { Help(); return(0); } var command = args[0]; if (command.Equals("-h", StringComparison.OrdinalIgnoreCase) || command.Equals("/h", StringComparison.OrdinalIgnoreCase) || command.Equals("-?", StringComparison.OrdinalIgnoreCase) || command.Equals("/?", StringComparison.OrdinalIgnoreCase) || command.Equals("?", StringComparison.OrdinalIgnoreCase)) { // Display the help screen Help(); return(0); } else if (command.Equals("c", StringComparison.OrdinalIgnoreCase)) { // Generate a certificate if (args.Length < 2) { Error("Too few arguments were specified."); return(ExitCode_CommandLineError); } #region Arguments var processCommandLinePath = true; Arguments: var argIndex = 1; string outputFile = null; string outputCertFile = null; string commonOutputName = null; string outputPassword = null; int keySize = DefaultKeySize; string subjectName = null; IList <string> subjectAlternativeNameList = null; var basicKeyUsages = BasicKeyUsages.None; bool basicKeyUsagesCritical = false; var extendedUsages = new List <string>(); bool extendedUsagesCritical = false; DateTime fromDate = DateTime.UtcNow.Date; // The date only DateTime toDate = fromDate.AddYears(1); bool toDateExplicitlySet = false; int years = 0; bool isCA = false; int caLength = -1; byte[] serialNumber = null; string issuerPath = null; string issuerPassword = null; string commandLinePath = null; #region Collect while (argIndex < args.Length) { var argument = args[argIndex++].ToLower(); if (argument.Length > 0 && argument[0] == '/') { argument = '-' + argument.Substring(1); } try { switch (argument) { #region Output file case "-o": outputFile = args[argIndex++]; break; case "-oc": outputCertFile = args[argIndex++]; break; case "-on": commonOutputName = args[argIndex++]; break; case "-op": outputPassword = args[argIndex++]; break; #endregion #region Basic case "-k": if (int.TryParse(args[argIndex++], out keySize) && keySize > 0) { break; } else { Error("Invalid key size."); return(ExitCode_CommandLineError); } case "-s": subjectName = args[argIndex++]; try { X501DistinguishedName.Parse(subjectName); } catch (FormatException exc) { Error("Invalid subject distinguished name: {0}", exc.Message); return(ExitCode_CommandLineError); } break; case "-sa": subjectAlternativeNameList = args[argIndex++].Split(',').Select(x => x.Trim()).Where(x => x.Length > 0).ToList(); break; case "-sn": var serialNumberText = args[argIndex++]; if (serialNumberText.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase) || serialNumberText.StartsWith("x", StringComparison.InvariantCultureIgnoreCase)) { // A hexadecimal string try { serialNumber = ToBytes(serialNumberText.Substring(1)); break; } catch (FormatException) { Error("Invalid serial number: invalid hexadecimal string."); return(ExitCode_CommandLineError); } } else { // An integer number long serialNumberLong; if (long.TryParse(serialNumberText, out serialNumberLong)) { serialNumber = BitConverter.GetBytes(serialNumberLong); // Remove trailing zero bytes serialNumber = serialNumber.Reverse().SkipWhile(x => x == 0).Reverse().ToArray(); if (serialNumber.Length == 0) { serialNumber = new byte[] { 0 }; } break; } else { Error("Invalid serial number: the specified value is not an integer or is too large."); return(ExitCode_CommandLineError); } } #endregion #region Key usage case "-bu": case "-buc": basicKeyUsagesCritical = argument == "-buc"; try { basicKeyUsages = (BasicKeyUsages)Enum.Parse(typeof(BasicKeyUsages), args[argIndex++], true); } catch (ArgumentException exc) { Error("Invalid certificate usages: {0}", exc.Message); return(ExitCode_CommandLineError); } break; case "-eu": case "-euc": extendedUsagesCritical = argument == "-euc"; foreach (var item in args[argIndex++].Split(',')) { var usage = item.Trim(); if (item.Length == 0) { continue; } string result; switch (item.ToLower()) { case "serverauthentication": result = ExtendedKeyUsages.ServerAuthentication; break; case "clientauthentication": result = ExtendedKeyUsages.ClientAuthentication; break; case "codesigning": result = ExtendedKeyUsages.CodeSigning; break; case "emailprotection": result = ExtendedKeyUsages.EmailProtection; break; case "timestamping": result = ExtendedKeyUsages.TimeStamping; break; case "ocspsigning": result = ExtendedKeyUsages.OCSPSigning; break; default: if (item.StartsWith("oid:")) { result = item.Substring(4); break; } else { Error("Invalid extended usage: '{0}'.", item); return(ExitCode_CommandLineError); } } extendedUsages.Add(result); } break; #endregion #region Validity period case "-f": if (DateTime.TryParse(args[argIndex++], out fromDate)) { break; } else { Error("Invalid validity period starting date."); return(ExitCode_CommandLineError); } case "-t": if (DateTime.TryParse(args[argIndex++], out toDate)) { toDateExplicitlySet = true; break; } else { Error("Invalid validity period ending date."); return(ExitCode_CommandLineError); } case "-y": if (int.TryParse(args[argIndex++], out years) && years > 0) { break; } else { Error("Invalid number of years for which the certificate is valid."); return(ExitCode_CommandLineError); } #endregion #region CA case "-ca": isCA = true; break; case "-calen": if (int.TryParse(args[argIndex++], out caLength) && caLength >= 0) { break; } else { Error("Invalid 'calen' value."); return(ExitCode_CommandLineError); } #endregion #region Issuer case "-i": issuerPath = args[argIndex++]; break; case "-ip": issuerPassword = args[argIndex++]; break; #endregion #region Other case "-r": commandLinePath = args[argIndex++]; break; #endregion #region Basic case "?": case "-?": case "-h": Help(); return(ExitCode_CommandLineError); default: Error("Invalid argument: '{0}'.", argument); return(ExitCode_CommandLineError); #endregion } } catch (IndexOutOfRangeException) { Error("'{0}' must be followed by an additional parameter.", argument); return(ExitCode_CommandLineError); } } #endregion #region Process if (processCommandLinePath && false == string.IsNullOrEmpty(commandLinePath)) { if (false == File.Exists(commandLinePath)) { Error("The file containing command line arguments was not found."); return(ExitCode_CommandLineError); } string[] readCommandLineArguments; try { readCommandLineArguments = File.ReadAllLines(commandLinePath); } catch (Exception exc) { Error("Could not read the file containing command line arguments: {0}", exc.Message); return(ExitCode_CommandLineError); } try { var readCommandLine = string.Join(" ", readCommandLineArguments); readCommandLineArguments = ParseCommandLine(readCommandLine); } catch (Win32Exception exc) { Error("Could not parse the arguments read from file: {0}", exc.Message); return(ExitCode_CommandLineError); } // Indicate that the command line arguments has been already processed processCommandLinePath = false; // The arguments specified on the command line MUST override the arguments read from the file. // Therefore, they must follow the read arguments in the array. // Move the command argument at the front args = new string[] { args[0] }.Concat(readCommandLineArguments).Concat(args.Skip(1)).ToArray(); Console.WriteLine(); // Reprocess the command-line arguments goto Arguments; } if (false == string.IsNullOrEmpty(commonOutputName)) { // Apply the common name to the other parameters if (string.IsNullOrEmpty(outputFile)) { outputFile = Path.ChangeExtension(commonOutputName, ".pfx"); } if (string.IsNullOrEmpty(outputCertFile)) { outputCertFile = Path.ChangeExtension(commonOutputName, ".cer"); } } if (string.IsNullOrEmpty(outputFile)) { Error("An output file must be specified."); return(ExitCode_CommandLineError); } if (string.IsNullOrEmpty(subjectName)) { Error("A subject distinguished name (DN) must be specified."); return(ExitCode_CommandLineError); } if (outputPassword == null) { Console.Write("Enter OUTPUT file password: "******"Enter ISSUER certificate password: "******"Cannot load the certificate of the issuer: {0}", exc.Message); return(ExitCode_CommandLineError); } if (false == issuerCertificate.Extensions.OfType <X509BasicConstraintsExtension>().Any(x => x.CertificateAuthority)) { Error("The certificate of the issuer must be a CA."); return(ExitCode_CommandLineError); } if (false == issuerCertificate.HasPrivateKey) { Error("The certificate of the issuer must has an associated private key."); return(ExitCode_CommandLineError); } } else { issuerCertificate = null; } if (serialNumber == null) { serialNumber = Guid.NewGuid().ToByteArray(); } if (false == toDateExplicitlySet && years > 0) { toDate = fromDate.AddYears(years); } if (fromDate >= toDate) { Error("The ending of the validity period must follow its ending."); return(ExitCode_CommandLineError); } #endregion #endregion #region Work try { var builder = new X509CertificateBuilder(); Console.Write("Generating RSA key..."); // If the default key container is not used accessing the key will throw a "Key not found" exception using (var rsa = new RSACryptoServiceProvider(keySize, new CspParameters() { Flags = CspProviderFlags.UseDefaultKeyContainer | CspProviderFlags.CreateEphemeralKey })) { try { #region Key Console.WriteLine(" Done"); builder.PublicKey = rsa; #endregion builder.SubjectName = subjectName; builder.SubjectAlternativeNames = subjectAlternativeNameList; builder.SerialNumber = serialNumber; builder.KeyUsages = basicKeyUsages; builder.KeyUsagesCritical = basicKeyUsagesCritical; builder.ExtendedKeyUsages = extendedUsages.ToArray(); builder.ExtendedKeyUsagesCritical = extendedUsagesCritical; builder.NotBefore = fromDate; builder.NotAfter = toDate; builder.IsCertificateAuthority = isCA; builder.CertificateAuthorityPathLength = caLength; if (issuerCertificate == null) { builder.SelfSign(rsa); } else { builder.Sign(issuerCertificate); } File.WriteAllBytes(outputFile, builder.ExportPkcs12(rsa, outputPassword, 1000)); var certData = builder.Export(); if (false == string.IsNullOrEmpty(outputCertFile)) { File.WriteAllBytes(outputCertFile, certData); } // Display the hash of the certificate Console.WriteLine("Certificate hash:"); foreach (var alg in HashAlgorithmList) { using (var hash = HashAlgorithm.Create(alg)) { var binaryHash = hash.ComputeHash(certData); Console.WriteLine("{0,-8}{1}", alg, BitConverter.ToString(binaryHash).Replace("-", "")); } } } finally { // Remove the key from the key container. Otherwise, the key will be kept on the file // system which is completely undesirable. rsa.PersistKeyInCsp = false; } } } catch (Exception exc) { Error("Unexpected error: {0}", exc.Message); return(ExitCode_ProcessingError); } #endregion Console.WriteLine(); Console.WriteLine("All done."); return(0); } else if (command.Equals("h", StringComparison.OrdinalIgnoreCase)) { // Output the hash of a certificate if (args.Length < 2) { Error("Too few arguments were specified."); return(ExitCode_CommandLineError); } #region Arguments var argIndex = 1; string fileName = args[argIndex++]; string password = null; string algorithm = null; while (argIndex < args.Length) { var argument = args[argIndex++].ToLower(); if (argument.Length > 0 && argument[0] == '/') { argument = '-' + argument.Substring(1); } try { switch (argument) { case "-p": password = args[argIndex++]; break; case "-a": algorithm = args[argIndex++]; if (false == ValidHashAlgorithmList.Contains(algorithm, StringComparer.OrdinalIgnoreCase)) { Error("Invalid hash algorithm: '{0}'.", algorithm); return(ExitCode_CommandLineError); } break; #region Basic case "?": case "-?": case "-h": Help(); return(ExitCode_CommandLineError); default: Error("Invalid argument: '{0}'.", argument); return(ExitCode_CommandLineError); #endregion } } catch (IndexOutOfRangeException) { Error("'{0}' must be followed by an additional parameter.", argument); return(ExitCode_CommandLineError); } } #endregion #region Processing try { #region Load file if (false == File.Exists(fileName)) { Error("The certificate file was not found."); return(ExitCode_CommandLineError); } X509Certificate2 certificate = null; if (false == fileName.EndsWith(".pfx", StringComparison.InvariantCultureIgnoreCase)) { // Assume that the file may be in DER format try { certificate = new X509Certificate2(fileName); } catch (CryptographicException) { // The file may be encrypted so ignore the error } } if (certificate == null) { if (password == null) { // Prompt the user for a password Console.Write("Enter PFX password: "******"Cannot load the certificate: {0}", exc.Message); return(ExitCode_CommandLineError); } } #endregion if (string.Equals(algorithm, "SHA1", StringComparison.OrdinalIgnoreCase)) { // Only the SHA1 hash must be displayed Console.WriteLine(certificate.GetCertHashString()); } else if (algorithm != null) { // Display the hash only for the specified algorithm using (var hash = HashAlgorithm.Create(algorithm)) { var binaryHash = hash.ComputeHash(certificate.GetRawCertData()); Console.WriteLine(BitConverter.ToString(binaryHash).Replace("-", "")); } } else { // Display the hash for all supported algorithms var certData = certificate.GetRawCertData(); foreach (var alg in HashAlgorithmList) { using (var hash = HashAlgorithm.Create(alg)) { var binaryHash = hash.ComputeHash(certData); Console.WriteLine("{0,-8}{1}", alg, BitConverter.ToString(binaryHash).Replace("-", "")); } } } } catch (Exception exc) { Error("Unexpected error: {0}", exc.Message); return(ExitCode_ProcessingError); } #endregion return(0); } else { Error("Unknown command '{0}'. Run the program without arguments to see the help screen.", command); return(ExitCode_CommandLineError); } }
internal static void CreateSelfSignCertificatePfx( string fileName, string hostname, ILogger logger) { if (string.IsNullOrWhiteSpace(fileName)) { throw new ArgumentNullException("fileName"); } byte[] sn = Guid.NewGuid().ToByteArray(); string subject = string.Format("CN={0}", hostname); string issuer = subject; DateTime notBefore = DateTime.Now.AddDays(-2); DateTime notAfter = DateTime.Now.AddYears(10); RSA issuerKey = RSA.Create(); issuerKey.FromXmlString(MonoTestRootAgency); RSA subjectKey = RSA.Create(); // serial number MUST be positive if ((sn[0] & 0x80) == 0x80) { sn[0] -= 0x80; } issuer = subject; issuerKey = subjectKey; X509CertificateBuilder cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = issuer; cb.NotBefore = notBefore; cb.NotAfter = notAfter; cb.SubjectName = subject; cb.SubjectPublicKey = subjectKey; // signature cb.Hash = "SHA256"; byte[] rawcert = cb.Sign(issuerKey); PKCS12 p12 = new PKCS12(); ArrayList list = new ArrayList(); // we use a fixed array to avoid endianess issues // (in case some tools requires the ID to be 1). list.Add(new byte[4] { 1, 0, 0, 0 }); Hashtable attributes = new Hashtable(1); attributes.Add(PKCS9.localKeyId, list); p12.AddCertificate(new X509Certificate(rawcert), attributes); p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); p12.SaveToFile(fileName); }
/// <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); }
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 SelfCertificateDialog(IServiceProvider serviceProvider) : base(serviceProvider) { InitializeComponent(); cbStore.SelectedIndex = 0; cbLength.SelectedIndex = 3; cbHashing.SelectedIndex = 1; txtCommonName.Text = Environment.MachineName; if (Environment.OSVersion.Version.Major < 8) { // IMPORTANT: WebHosting store is available since Windows 8. cbStore.Enabled = false; } if (!Helper.IsRunningOnMono()) { NativeMethods.TryAddShieldToButton(btnOK); } var container = new CompositeDisposable(); FormClosed += (sender, args) => container.Dispose(); container.Add( Observable.FromEventPattern <EventArgs>(txtName, "TextChanged") .Subscribe(evt => { btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text); })); container.Add( Observable.FromEventPattern <EventArgs>(btnOK, "Click") .Subscribe(evt => { // Generate certificate string defaultIssuer = string.Format("CN={0}", txtCommonName.Text); string defaultSubject = defaultIssuer; byte[] sn = Guid.NewGuid().ToByteArray(); string subject = defaultSubject; string issuer = defaultIssuer; DateTime notBefore = DateTime.Now; DateTime notAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z RSA issuerKey = new RSACryptoServiceProvider(int.Parse(cbLength.Text)); RSA subjectKey = null; CspParameters subjectParams = new CspParameters(); CspParameters issuerParams = new CspParameters(); BasicConstraintsExtension bce = new BasicConstraintsExtension { PathLenConstraint = BasicConstraintsExtension.NoPathLengthConstraint, CertificateAuthority = true }; ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension(); eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1"); SubjectAltNameExtension alt = null; string p12File = Path.GetTempFileName(); string p12pwd = "test"; // serial number MUST be positive if ((sn[0] & 0x80) == 0x80) { sn[0] -= 0x80; } if (subject != defaultSubject) { issuer = subject; issuerKey = null; } else { subject = issuer; subjectKey = issuerKey; } if (subject == null) { throw new Exception("Missing Subject Name"); } X509CertificateBuilder cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = issuer; cb.NotBefore = notBefore; cb.NotAfter = notAfter; cb.SubjectName = subject; cb.SubjectPublicKey = subjectKey; // extensions if (bce != null) { cb.Extensions.Add(bce); } if (eku != null) { cb.Extensions.Add(eku); } if (alt != null) { cb.Extensions.Add(alt); } IDigest digest = new Sha1Digest(); byte[] resBuf = new byte[digest.GetDigestSize()]; var spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey)); byte[] bytes = spki.PublicKeyData.GetBytes(); digest.BlockUpdate(bytes, 0, bytes.Length); digest.DoFinal(resBuf, 0); cb.Extensions.Add(new SubjectKeyIdentifierExtension { Identifier = resBuf }); cb.Extensions.Add(new AuthorityKeyIdentifierExtension { Identifier = resBuf }); // signature string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256"; cb.Hash = hashName; byte[] rawcert = cb.Sign(issuerKey); PKCS12 p12 = new PKCS12(); p12.Password = p12pwd; ArrayList list = new ArrayList(); // we use a fixed array to avoid endianess issues // (in case some tools requires the ID to be 1). list.Add(new byte[] { 1, 0, 0, 0 }); Hashtable attributes = new Hashtable(1); attributes.Add(PKCS9.localKeyId, list); p12.AddCertificate(new X509Certificate(rawcert), attributes); p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); p12.SaveToFile(p12File); Item = new X509Certificate2(p12File, p12pwd) { FriendlyName = txtName.Text }; Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting"; try { using (var process = new Process()) { // add certificate var start = process.StartInfo; start.Verb = "runas"; start.FileName = "cmd"; start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"", p12File, p12pwd, txtName.Text, cbStore.SelectedIndex == 0 ? "MY" : "WebHosting", Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe")); start.CreateNoWindow = true; start.WindowStyle = ProcessWindowStyle.Hidden; process.Start(); process.WaitForExit(); File.Delete(p12File); if (process.ExitCode == 0) { this.DialogResult = DialogResult.OK; } else { MessageBox.Show(process.ExitCode.ToString()); } } } catch (Exception) { // elevation is cancelled. } })); }
static void Main(string[] args) { var assembly = Assembly.GetExecutingAssembly(); var title = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute)); Console.WriteLine("{0} version {1}", title.Title, assembly.GetName().Version); var copyright = (AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute)); Console.WriteLine(copyright.Copyright); Console.WriteLine("More information can be found at https://www.jexusmanager.com"); Console.WriteLine(); var baseAddress = args.Length > 0 ? args[0] : "https://*****:*****@"Remote services must be run as root on Linux."); return; } if (!File.Exists("jws")) { Console.WriteLine(@"Remote services must be running in Jexus installation folder."); return; } var loc = baseAddress.LastIndexOf(':'); var port = "443"; if (loc != -1) { port = baseAddress.Substring(loc + 1); } string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); string path = Path.Combine(dirname, ".mono", "httplistener"); if (false == Directory.Exists(path)) { Directory.CreateDirectory(path); } string target_cert = Path.Combine(path, string.Format("{0}.cer", port)); if (File.Exists(target_cert)) { Console.WriteLine("Use {0}", target_cert); } else { Console.WriteLine("Generating a self-signed certificate for Jexus Manager"); // Generate certificate string defaultIssuer = "CN=jexus.lextudio.com"; string defaultSubject = "CN=jexus.lextudio.com"; byte[] sn = Guid.NewGuid().ToByteArray(); string subject = defaultSubject; string issuer = defaultIssuer; DateTime notBefore = DateTime.Now; DateTime notAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z RSA issuerKey = new RSACryptoServiceProvider(2048); RSA subjectKey = null; bool selfSigned = true; string hashName = "SHA1"; CspParameters subjectParams = new CspParameters(); CspParameters issuerParams = new CspParameters(); BasicConstraintsExtension bce = new BasicConstraintsExtension { PathLenConstraint = BasicConstraintsExtension.NoPathLengthConstraint, CertificateAuthority = true }; ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension(); eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1"); SubjectAltNameExtension alt = null; string p12file = Path.Combine(path, "temp.pfx"); string p12pwd = "test"; // serial number MUST be positive if ((sn[0] & 0x80) == 0x80) { sn[0] -= 0x80; } if (selfSigned) { if (subject != defaultSubject) { issuer = subject; issuerKey = subjectKey; } else { subject = issuer; subjectKey = issuerKey; } } if (subject == null) { throw new Exception("Missing Subject Name"); } X509CertificateBuilder cb = new X509CertificateBuilder(3); cb.SerialNumber = sn; cb.IssuerName = issuer; cb.NotBefore = notBefore; cb.NotAfter = notAfter; cb.SubjectName = subject; cb.SubjectPublicKey = subjectKey; // extensions if (bce != null) { cb.Extensions.Add(bce); } if (eku != null) { cb.Extensions.Add(eku); } if (alt != null) { cb.Extensions.Add(alt); } IDigest digest = new Sha1Digest(); byte[] resBuf = new byte[digest.GetDigestSize()]; var spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey)); byte[] bytes = spki.PublicKeyData.GetBytes(); digest.BlockUpdate(bytes, 0, bytes.Length); digest.DoFinal(resBuf, 0); cb.Extensions.Add(new SubjectKeyIdentifierExtension { Identifier = resBuf }); cb.Extensions.Add(new AuthorityKeyIdentifierExtension { Identifier = resBuf }); // signature cb.Hash = hashName; byte[] rawcert = cb.Sign(issuerKey); PKCS12 p12 = new PKCS12(); p12.Password = p12pwd; ArrayList list = new ArrayList(); // we use a fixed array to avoid endianess issues // (in case some tools requires the ID to be 1). list.Add(new byte[4] { 1, 0, 0, 0 }); Hashtable attributes = new Hashtable(1); attributes.Add(PKCS9.localKeyId, list); p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes); p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes); p12.SaveToFile(p12file); var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(p12file, p12pwd, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable); // Install certificate string target_pvk = Path.Combine(path, string.Format("{0}.pvk", port)); using (Stream cer = File.OpenWrite(target_cert)) { byte[] raw = x509.RawData; cer.Write(raw, 0, raw.Length); } PrivateKey pvk = new PrivateKey(); pvk.RSA = subjectKey; pvk.Save(target_pvk); } } JexusServer.Credentials = args.Length > 2 ? args[1] + "|" + args[2] : "jexus|lextudio.com"; JexusServer.Timeout = args.Length > 3 ? double.Parse(args[3]) : 30D; using (WebApp.Start <Startup>(url: baseAddress)) { Console.WriteLine("Remote services have started at {0}.", baseAddress); Console.WriteLine("Credentials is {0}", JexusServer.Credentials); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); } }
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(); })); }
/// <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; }