private static bool CheckServerIdentity(Mono.Security.X509.X509Certificate cert, string targetHost) { bool result; try { Mono.Security.X509.X509Extension x509Extension = cert.Extensions["2.5.29.17"]; if (x509Extension != null) { SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(x509Extension); foreach (string pattern in subjectAltNameExtension.DNSNames) { if (ServicePointManager.ChainValidationHelper.Match(targetHost, pattern)) { return(true); } } foreach (string a in subjectAltNameExtension.IPAddresses) { if (a == targetHost) { return(true); } } } result = ServicePointManager.ChainValidationHelper.CheckDomainName(cert.SubjectName, targetHost); } catch (Exception arg) { Console.Error.WriteLine("ERROR processing certificate: {0}", arg); Console.Error.WriteLine("Please, report this problem to the Mono team"); result = false; } return(result); }
// RFC2818 - HTTP Over TLS, Section 3.1 // http://www.ietf.org/rfc/rfc2818.txt // // 1. if present MUST use subjectAltName dNSName as identity // 1.1. if multiples entries a match of any one is acceptable // 1.2. wildcard * is acceptable // 2. URI may be an IP address -> subjectAltName.iPAddress // 2.1. exact match is required // 3. Use of the most specific Common Name (CN=) in the Subject // 3.1 Existing practice but DEPRECATED private bool checkServerIdentity(X509Certificate cert) { ClientContext context = (ClientContext)this.Context; string targetHost = context.ClientSettings.TargetHost; X509Extension ext = cert.Extensions ["2.5.29.17"]; // 1. subjectAltName if (ext != null) { SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension(ext); // 1.1 - multiple dNSName foreach (string dns in subjectAltName.DNSNames) { // 1.2 TODO - wildcard support if (Match(targetHost, dns)) { return(true); } } // 2. ipAddress foreach (string ip in subjectAltName.IPAddresses) { // 2.1. Exact match required if (ip == targetHost) { return(true); } } } // 3. Common Name (CN=) return(checkDomainName(cert.SubjectName)); }
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"); }
internal void Initialize(X509Certificate cert) { x509 = cert; thumbprintAlgorithm = defaultThumbprintAlgo; try { // preprocess some informations foreach (X509Extension xe in x509.Extensions) { if ((!extensions.ContainsKey(xe.Oid)) && (xe.Critical)) { status = unknownCriticalExtension; } if (xe.Oid == "2.5.29.17") { SubjectAltNameExtension san = new SubjectAltNameExtension(xe); subjectAltName = san.RFC822; } } if (x509.IsSelfSigned) { status = untrustedRoot; } } catch (Exception e) { status = e.ToString(); } }
private bool checkServerIdentity(Mono.Security.X509.X509Certificate cert) { ClientContext clientContext = (ClientContext)base.Context; string targetHost = clientContext.ClientSettings.TargetHost; Mono.Security.X509.X509Extension x509Extension = cert.Extensions["2.5.29.17"]; if (x509Extension != null) { SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(x509Extension); foreach (string pattern in subjectAltNameExtension.DNSNames) { if (TlsServerCertificate.Match(targetHost, pattern)) { return(true); } } foreach (string a in subjectAltNameExtension.IPAddresses) { if (a == targetHost) { return(true); } } } return(this.checkDomainName(cert.SubjectName)); }
private bool checkServerIdentity(Mono.Security.X509.X509Certificate cert) { string targetHost = this.Context.ClientSettings.TargetHost; Mono.Security.X509.X509Extension extension = cert.Extensions["2.5.29.17"]; if (extension != null) { SubjectAltNameExtension altNameExtension = new SubjectAltNameExtension(extension); foreach (string dnsName in altNameExtension.DNSNames) { if (TlsServerCertificate.Match(targetHost, dnsName)) { return(true); } } foreach (string ipAddress in altNameExtension.IPAddresses) { if (ipAddress == targetHost) { return(true); } } } return(this.checkDomainName(cert.SubjectName)); }
/// <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)); }
// RFC2818 - HTTP Over TLS, Section 3.1 // http://www.ietf.org/rfc/rfc2818.txt // // 1. if present MUST use subjectAltName dNSName as identity // 1.1. if multiples entries a match of any one is acceptable // 1.2. wildcard * is acceptable // 2. URI may be an IP address -> subjectAltName.iPAddress // 2.1. exact match is required // 3. Use of the most specific Common Name (CN=) in the Subject // 3.1 Existing practice but DEPRECATED static bool CheckServerIdentity(Mono.Security.X509.X509Certificate cert, string targetHost) { try { Mono.Security.X509.X509Extension ext = cert.Extensions ["2.5.29.17"]; // 1. subjectAltName if (ext != null) { SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension(ext); // 1.1 - multiple dNSName foreach (string dns in subjectAltName.DNSNames) { // 1.2 TODO - wildcard support if (Match(targetHost, dns)) { return(true); } } // 2. ipAddress foreach (string ip in subjectAltName.IPAddresses) { // 2.1. Exact match required if (ip == targetHost) { return(true); } } } // 3. Common Name (CN=) return(CheckDomainName(cert.SubjectName, targetHost)); } catch (Exception e) { Console.Error.WriteLine("ERROR processing certificate: {0}", e); Console.Error.WriteLine("Please, report this problem to the Mono team"); return(false); } }
public CertificateMaker(X509Certificate x509) { _subject = new DistinguishedName(x509.SubjectName); _public_key = (RSACryptoServiceProvider)x509.RSA; SubjectAltNameExtension sane = new SubjectAltNameExtension(x509.Extensions[0]); _node_address = sane.UniformResourceIdentifiers[0]; }
public void MultipleEntriesInExtension_AsASN1() { X509Certificate cert = new X509Certificate(multiple_entries_cert); SubjectAltNameExtension sane = new SubjectAltNameExtension(cert.Extensions ["2.5.29.17"].ASN1); Assert.AreEqual("www.arzneimittel-bestellcenter.de", sane.DNSNames [0], "0"); Assert.AreEqual("www.xnet-arzneimittel-bestellcenter.de", sane.DNSNames [1], "1"); Assert.AreEqual("www.adg-arzneimittel-bestellcenter.de", sane.DNSNames [2], "2"); Assert.AreEqual("www.a3000-filialapotheke.de", sane.DNSNames [3], "3"); }
public Certificate(X509Certificate Cert) { _x509 = Cert; _issuer = new DistinguishedName(Cert.IssuerName); _subject = new DistinguishedName(Cert.SubjectName); _signature = Cert.Signature; _serial_number = Cert.SerialNumber; _public_key = (RSACryptoServiceProvider)Cert.RSA; SubjectAltNameExtension sane = new SubjectAltNameExtension(Cert.Extensions[0]); _node_address = sane.UniformResourceIdentifiers[0]; }
public void ThirdPartyCertificateParse() { byte[] certificate_with_ip_subjectaltname = new byte[] { 0x30, 0x82, 0x02, 0x78, 0x30, 0x82, 0x01, 0xE1, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xEE, 0xF3, 0xC0, 0x32, 0x13, 0x12, 0x66, 0x06, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x78, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x04, 0x6E, 0x6F, 0x6E, 0x65, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x6E, 0x6F, 0x6E, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x04, 0x6E, 0x6F, 0x6E, 0x65, 0x30, 0x1E, 0x17, 0x0D, 0x30, 0x38, 0x30, 0x36, 0x31, 0x33, 0x30, 0x34, 0x35, 0x39, 0x34, 0x36, 0x5A, 0x17, 0x0D, 0x30, 0x39, 0x30, 0x36, 0x31, 0x33, 0x30, 0x34, 0x35, 0x39, 0x34, 0x36, 0x5A, 0x30, 0x6F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x61, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, 0x01, 0x61, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xA6, 0xD2, 0x03, 0x5D, 0x91, 0x3D, 0xF3, 0x04, 0x4F, 0xB9, 0xF0, 0xE6, 0x40, 0xD0, 0x4E, 0xDF, 0xF7, 0xCE, 0x35, 0x87, 0xC1, 0x95, 0xEA, 0xFD, 0xDF, 0x44, 0x46, 0x20, 0xE4, 0xAF, 0x69, 0xC8, 0x1C, 0xF1, 0x06, 0x6C, 0x46, 0x20, 0x4D, 0xAA, 0xCC, 0x86, 0x40, 0xBB, 0x79, 0xF8, 0x71, 0x22, 0x87, 0x65, 0xBD, 0x20, 0x1D, 0xAD, 0xC6, 0xB0, 0x7C, 0x17, 0xE6, 0x57, 0xE4, 0x3C, 0x55, 0xD7, 0x7C, 0x8A, 0x98, 0xA2, 0xCD, 0x22, 0x85, 0x0E, 0xA2, 0x90, 0x18, 0x44, 0xA9, 0x7F, 0xA6, 0xD8, 0xDB, 0x6D, 0x09, 0x6D, 0x48, 0x6D, 0xD0, 0xDF, 0x94, 0xBF, 0x3B, 0xE5, 0xDA, 0x5F, 0xA2, 0x6F, 0x3C, 0xE5, 0xCE, 0xF3, 0x53, 0x8B, 0x16, 0x39, 0xDD, 0x3B, 0xC7, 0x0E, 0xA5, 0x75, 0xAA, 0x5A, 0x51, 0xD5, 0x7F, 0x31, 0x44, 0xC8, 0x6A, 0x9B, 0x60, 0xEC, 0xA2, 0xB6, 0x42, 0xCA, 0xA3, 0x43, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x13, 0x30, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x08, 0x30, 0x06, 0x87, 0x04, 0xC0, 0xA8, 0x6F, 0x6F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x87, 0x23, 0x47, 0x07, 0x99, 0x69, 0x90, 0x8D, 0x65, 0xF9, 0xE4, 0xF3, 0x03, 0xBB, 0x08, 0x67, 0x29, 0x38, 0x0E, 0xF4, 0x2E, 0x23, 0xFF, 0xC2, 0x05, 0x1C, 0x7B, 0xDD, 0xBD, 0xA6, 0x26, 0x46, 0x99, 0x26, 0xC4, 0x8C, 0xD5, 0xFC, 0x4A, 0x39, 0xE6, 0xF5, 0xD7, 0x9F, 0xE5, 0x80, 0x60, 0x01, 0x30, 0x32, 0xC1, 0x86, 0x5C, 0x2E, 0x7F, 0x01, 0xB2, 0xAE, 0x4D, 0x15, 0xBB, 0x9C, 0xB8, 0xC4, 0xF6, 0x18, 0x48, 0x5F, 0xEF, 0x35, 0x78, 0xE5, 0x7F, 0x35, 0x10, 0xA1, 0xDD, 0x8E, 0x69, 0xCA, 0x52, 0x99, 0xBC, 0x89, 0x42, 0x2F, 0xC3, 0xEF, 0xB6, 0xD1, 0x37, 0xE2, 0xF9, 0x68, 0xC1, 0x3C, 0x10, 0x8C, 0xDE, 0x7A, 0xC9, 0x31, 0x3B, 0x4E, 0xAC, 0x44, 0xA1, 0x9F, 0x7C, 0xA7, 0x41, 0x59, 0xE5, 0x77, 0x12, 0xCB, 0xBE, 0xBB, 0x0F, 0x50, 0x5A, 0x14, 0x3B, 0xA7, 0x86, 0x15, 0x5C, 0x61, 0x0A }; X509Certificate cert = new X509Certificate(certificate_with_ip_subjectaltname); SubjectAltNameExtension sane_test = new SubjectAltNameExtension(cert.Extensions[0]); Assert.AreEqual(sane_test.RFC822.Length, 0, "RFC822 count"); Assert.AreEqual(sane_test.DNSNames.Length, 0, "DNSName count"); Assert.AreEqual(sane_test.IPAddresses.Length, 1, "IPAddresses count"); Assert.AreEqual(sane_test.UniformResourceIdentifiers.Length, 0, "URI Count"); Assert.AreEqual(sane_test.IPAddresses[0], "192.168.111.111", "IPAddress Test"); }
public X509Certificate AddSubjectAltNames(params string[] names) { var ext = Tbs.Extensions.GetExtension <SubjectAltNameExtension>(); if (ext == null) { ext = new SubjectAltNameExtension(); Tbs.Extensions.Add(ext); } foreach (var name in names) { ext.Names.Add(name); } return(this); }
private static bool CheckServerIdentity(Mono.Security.X509.X509Certificate cert, string targetHost) { try { Mono.Security.X509.X509Extension x509Extension = cert.Extensions["2.5.29.17"]; if (x509Extension != null) { SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(x509Extension); string[] dNSNames = subjectAltNameExtension.DNSNames; foreach (string pattern in dNSNames) { if (Match(targetHost, pattern)) { return(true); } } string[] iPAddresses = subjectAltNameExtension.IPAddresses; foreach (string a in iPAddresses) { if (a == targetHost) { return(true); } } } return(CheckDomainName(cert.SubjectName, targetHost)); IL_00a6: bool result; return(result); } catch (Exception arg) { Console.Error.WriteLine("ERROR processing certificate: {0}", arg); Console.Error.WriteLine("Please, report this problem to the Mono team"); return(false); IL_00d5: bool result; return(result); } }
///<summary>Given a string, this looks inside the certificates SANE to see ///if the string is present. This isn't inefficient as it looks, there ///tends to be no entries at most of those places, so this usually has ///runtime of 1.</summary> public bool VerifyCertificateBySubjectAltName(string name) { foreach (X509Extension ext in RemoteCertificate.Value.Extensions) { if (!ext.Oid.Equals("2.5.29.17")) { continue; } SubjectAltNameExtension sane = new SubjectAltNameExtension(ext); foreach (string aname in sane.RFC822) { if (name.Equals(aname)) { return(true); } } foreach (string aname in sane.DNSNames) { if (name.Equals(aname)) { return(true); } } foreach (string aname in sane.IPAddresses) { if (name.Equals(aname)) { return(true); } } foreach (string aname in sane.UniformResourceIdentifiers) { if (name.Equals(aname)) { return(true); } } } return(false); }
///<summary>Given a string, this looks inside the certificates SANE to see ///if the string is present. This isn't inefficient as it looks, there ///tends to be no entries at most of those places, so this usually has ///runtime of 1. Also this doesn't actually verify any other properties ///of the certificate, such as being properly signed.</summary> static public bool Verify(X509Certificate x509, string remote_id) { foreach (X509Extension ext in x509.Extensions) { if (!ext.Oid.Equals("2.5.29.17")) { continue; } SubjectAltNameExtension sane = new SubjectAltNameExtension(ext); foreach (string name in sane.RFC822) { if (name.Equals(remote_id)) { return(true); } } foreach (string name in sane.DNSNames) { if (name.Equals(remote_id)) { return(true); } } foreach (string name in sane.IPAddresses) { if (name.Equals(remote_id)) { return(true); } } foreach (string name in sane.UniformResourceIdentifiers) { if (name.Equals(remote_id)) { return(true); } } } throw new Exception("Missing a valid SubjectAltName!"); }
/// <summary>First makes sure we have a CA that supports this certificate, /// then looks through an x509 certificates SubjectAltName Extension's /// URI list to determine if the given URI (RemoteID) exists in the /// certificate.</summary> /// <param name="x509">The certificate to check</param> /// <param name="RemoteID">The URI to look for</param> /// <returns>True if the URI exists, false otherwise</returns> public virtual bool Verify(X509Certificate x509, string RemoteID) { if (!Verify(x509)) { throw new Exception("Invalid certificate!"); } bool valid_address = false; foreach (X509Extension ex in x509.Extensions) { // SubjectAltName if (ex.Oid != "2.5.29.17") { continue; } SubjectAltNameExtension sane = new SubjectAltNameExtension(ex); foreach (string uri in sane.UniformResourceIdentifiers) { if (uri == RemoteID) { valid_address = true; break; } } if (valid_address) { break; } } if (!valid_address) { throw new Exception("Missing a valid SubjectAltName!"); } return(true); }
// 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); }
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); }
// RFC2818 - HTTP Over TLS, Section 3.1 // http://www.ietf.org/rfc/rfc2818.txt // // 1. if present MUST use subjectAltName dNSName as identity // 1.1. if multiples entries a match of any one is acceptable // 1.2. wildcard * is acceptable // 2. URI may be an IP address -> subjectAltName.iPAddress // 2.1. exact match is required // 3. Use of the most specific Common Name (CN=) in the Subject // 3.1 Existing practice but DEPRECATED static bool CheckServerIdentity (MSX.X509Certificate cert, string targetHost) { try { MSX.X509Extension ext = cert.Extensions ["2.5.29.17"]; // 1. subjectAltName if (ext != null) { SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (ext); // 1.1 - multiple dNSName foreach (string dns in subjectAltName.DNSNames) { // 1.2 TODO - wildcard support if (Match (targetHost, dns)) return true; } // 2. ipAddress foreach (string ip in subjectAltName.IPAddresses) { // 2.1. Exact match required if (ip == targetHost) return true; } } // 3. Common Name (CN=) return CheckDomainName (cert.SubjectName, targetHost); } catch (Exception e) { Console.Error.WriteLine ("ERROR processing certificate: {0}", e); Console.Error.WriteLine ("Please, report this problem to the Mono team"); return false; } }
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) : 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. } })); }
/// <summary> /// Applies the basic constrains and key usages to the underlying certificate builder /// before the certificate is signed. /// </summary> void PrepareSigning() { // Set the signing hashing function _builder.Hash = "SHA256"; // Clear all extensions created during the previous preparation _builder.Extensions.Clear(); #region Subject if (SubjectAlternativeNames != null && SubjectAlternativeNames.Count > 0) { var dnsNameList = new List <string>(); var ipList = new List <string>(); foreach (var item in SubjectAlternativeNames) { IPAddress ipAddress; if (IPAddress.TryParse(item, out ipAddress)) { ipList.Add(item); } else { dnsNameList.Add(item); } } var extension = new SubjectAltNameExtension(null, dnsNameList.ToArray(), ipList.ToArray(), null); _builder.Extensions.Add(extension); } #endregion #region Serial number { var serialNumber = _serialNumber == null ? null : (byte[])_serialNumber.Clone(); if (serialNumber == null) { serialNumber = Guid.NewGuid().ToByteArray(); } /* // The serial number is correctly set and must NOT be reversed * // Convert the serial number to big endian format * Array.Reverse(serialNumber); */ _builder.SerialNumber = serialNumber; } #endregion #region Basic key usages var keyUsages = KeyUsages; if (IsCertificateAuthority) { // Indicate that the public key of the certificate can be used to validate the signatures of // other certificates keyUsages |= BasicKeyUsages.KeyCertSign; var extension = new BasicConstraintsExtension() { CertificateAuthority = true, PathLenConstraint = CertificateAuthorityPathLength, // This extension must be critical Critical = true, }; _builder.Extensions.Add(extension); } else { keyUsages &= ~BasicKeyUsages.KeyCertSign; } if (keyUsages != BasicKeyUsages.None) { #if MONO_BUG // There was a bug in the Mono implementation of the KeyUsageExtension // which is still NOT fixed var buffer = new System.Security.Cryptography.X509Certificates.X509KeyUsageExtension( (System.Security.Cryptography.X509Certificates.X509KeyUsageFlags)keyUsages, false ).RawData; var asn = new ASN1(0x30, buffer); asn.Add(ASN1Convert.FromOid("2.5.29.15")); asn.Add(new ASN1(4, buffer)); _builder.Extensions.Add(new X509Extension(asn) { Critical = KeyUsagesCritical }); #else // This code should be used once the bug is fixed var extension = new KeyUsageExtension() { KeyUsage = (KeyUsages)keyUsages, Critical = KeyUsagesCritical, }; _builder.Extensions.Add(extension); #endif } #endregion #region Extended key usage if (ExtendedKeyUsages != null && ExtendedKeyUsages.Count > 0) { var extension = new ExtendedKeyUsageExtension(); extension.Critical = ExtendedKeyUsagesCritical; foreach (var item in ExtendedKeyUsages) { // Avoid dupliated key usages if (false == extension.KeyPurpose.Contains(item)) { extension.KeyPurpose.Add(item); } } _builder.Extensions.Add(extension); } #endregion #region Custom extensions if (_extensions != null) { _builder.Extensions.AddRange(_extensions); } #endregion }