示例#1
0
        public static byte[] CreateClientCert(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.2"); // Indicates the cert is intended for client auth

            // Generate a client 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[] clientCert = cb.Sign(issuerKey);

            // Generate a PKCS#12 file for the client 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(clientCert), attributes);
            p12.AddCertificate(issuerCert);
            p12.AddPkcs8ShroudedKeyBag(issuerKey, attributes);

            return p12.GetBytes();
        }
示例#2
0
        public static void CreateRootCert(string issuer, out byte[] rootCert)
        {
            if (!issuer.StartsWith("CN="))
                issuer = "CN=" + issuer;

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

            // Generate a private key
            PrivateKey key = new PrivateKey();
            key.RSA = issuerKey;

            // 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
            eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.2"); // Indicates the cert is intended for client auth

            // 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";
            cb.Extensions.Add(eku);

            byte[] serverCert = cb.Sign(issuerKey);

            // Generate a PKCS#12 file containing the certificate and private key
            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.AddPkcs8ShroudedKeyBag(issuerKey, attributes);

            rootCert = p12.GetBytes();
        }
示例#3
0
        public static void CreateServerRootCA(string issuer, out byte[] rootKey, out byte[] rootCert)
        {
            if (!issuer.StartsWith("CN="))
                issuer = "CN=" + issuer;

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

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

            // Generate a private key
            PrivateKey key = new PrivateKey();
            key.RSA = issuerKey;

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

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

            // Generate a self-signed certificate
            X509CertificateBuilder cb = new X509CertificateBuilder(3);
            cb.SerialNumber = sn;
            cb.IssuerName = issuer;
            cb.NotBefore = DateTime.Now;
            cb.NotAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            cb.SubjectName = issuer;
            cb.SubjectPublicKey = issuerKey;
            cb.Hash = "SHA1";

            rootCert = cb.Sign(issuerKey);
        }
	public void Constructor_Null () 
	{
		PrivateKey pvk = new PrivateKey (null, "password");
	}
	public void Save_Null () 
	{
		PrivateKey pvk = new PrivateKey ();
		pvk.Save (null, "mono");
	}
	public void CreatePVK () 
	{
		PrivateKey pvk = new PrivateKey ();
		pvk.KeyType = 2;
		pvk.RSA = RSA.Create ();
		string rsa1 = pvk.RSA.ToXmlString (true);
		pvk.Save (testfile, "mono");

		pvk = PrivateKey.CreateFromFile (testfile, "mono");
		AssertNotNull ("new.RSA", pvk.RSA);
		string rsa2 = pvk.RSA.ToXmlString (true);
		AssertEquals ("new.RSA identical", rsa1, rsa2);
		Assert ("new.Encrypted", pvk.Encrypted);
		Assert ("new.Weak", !pvk.Weak);
	}
        public static X509Certificate2 GetOrCreateClientCert()
        {
            string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string path = Path.Combine(dirname, ".couchbase");
            Directory.CreateDirectory(path);
            path = Path.Combine(path, "client.pfx");
            if (File.Exists(path)) {
                return new X509Certificate2(path);
            }

            byte[] sn = GenerateSerialNumber();
            string subject = string.Format("CN=CouchbaseClient");

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

            RSA subjectKey = new RSACryptoServiceProvider(2048);
            PrivateKey privKey = new PrivateKey();
            privKey.RSA = subjectKey;

            string hashName = "SHA512";

            X509CertificateBuilder 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;

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

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

            rawcert = p12.GetBytes();
            WriteCertificate(path, rawcert);

            return new X509Certificate2(rawcert);
        }
        private static void InstallCertificateMono(X509Certificate2 cert, ushort port)
        {
            string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string path = Path.Combine(dirname, ".mono");
            path = Path.Combine(path, "httplistener");

            string cert_file = Path.Combine(path, String.Format("{0}.cer", port));
            string pvk_file = Path.Combine(path, String.Format("{0}.pvk", port));
            Directory.CreateDirectory(path);
            WriteCertificate(cert_file, cert.GetRawCertData());
            var privKey = new PrivateKey();
            privKey.RSA = (RSA)cert.PrivateKey;
            privKey.Save(pvk_file);
        }
示例#9
0
文件: makecert.cs 项目: nobled/mono
		static int Main (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);
				}
				Console.WriteLine ("Success");
				return 0;
			}
			catch (Exception e) {
				Console.WriteLine ("ERROR: " + e.ToString ());
				Help ();
			}
			return 1;
		}
示例#10
0
	public void CreatePVK () 
	{
		PrivateKey pvk = new PrivateKey ();
		pvk.KeyType = 2;
		pvk.RSA = RSA.Create ();
		string rsa1 = pvk.RSA.ToXmlString (true);
		pvk.Save (testfile, "mono");

		pvk = PrivateKey.CreateFromFile (testfile, "mono");
		Assert.IsNotNull (pvk.RSA, "new.RSA");
		string rsa2 = pvk.RSA.ToXmlString (true);
		Assert.AreEqual (rsa1, rsa2, "new.RSA identical");
		Assert.IsTrue (pvk.Encrypted, "new.Encrypted");
		Assert.IsTrue (!pvk.Weak, "new.Weak");
	}
示例#11
0
        public static byte[] CreateSignedCert(string subjectName, byte[] issuerKey, byte[] issuerCert)
        {
            // Copy the root key since the PrivateKey constructor will blow away the data
            byte[] issuerKeyCopy = new byte[issuerKey.Length];
            Buffer.BlockCopy(issuerKey, 0, issuerKeyCopy, 0, issuerKey.Length);

            // Load the server's private key and certificate
            PrivateKey pvk = new PrivateKey(issuerKeyCopy, null);
            RSA issuerKeyRSA = pvk.RSA;

            // Parse the certificate data
            X509Certificate issuerCertX509 = new X509Certificate(issuerCert);

            return CreateSignedCert(subjectName, issuerKeyRSA, issuerCertX509);
        }
        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;
        }
示例#13
0
文件: httpcfg.cs 项目: nobled/mono
		static void AddP12 (string path, string filename, string password, ushort port)
		{
			X509Certificate2 x509 = null;
			try {
				x509 = new X509Certificate2 (filename, password);
			} catch (Exception e) {
				Console.Error.WriteLine ("error loading certificate [{0}]", e.Message);
				Help (true);
			}

			string target_cert = Path.Combine (path, String.Format ("{0}.cer", port));
			if (File.Exists (target_cert)) {
				Console.Error.WriteLine ("error: there is already a certificate for that port.");
				Help (true);
			}
			string target_pvk = Path.Combine (path, String.Format ("{0}.pvk", port));
			if (File.Exists (target_pvk)) {
				Console.Error.WriteLine ("error: there is already a certificate for that port.");
				Help (true);
			}

			using (Stream cer = File.OpenWrite (target_cert)) {
				byte [] raw = x509.RawData;
				cer.Write (raw, 0, raw.Length);
			}
			
			PrivateKey pvk = new PrivateKey();
			pvk.RSA = x509.PrivateKey as RSA;
			pvk.Save(target_pvk);			
		}
示例#14
0
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var title = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute));
            Console.WriteLine("{0} version {1}", title.Title, assembly.GetName().Version);
            var copyright = (AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute));
            Console.WriteLine(copyright.Copyright);
            Console.WriteLine("More information can be found at https://Jexus.codeplex.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();
            }
        }
		private AsymmetricAlgorithm PrivateKeySelectionCallback(X509Certificate certificate, string targetHost) {
			Console.WriteLine("SslStream.PrivateKeyCertSelectionDelegate");
			try {
				PrivateKey key;
				if (_serverKeyFilename == String.Empty) {
					Assembly assembly = Assembly.GetExecutingAssembly();
					Stream stream = assembly.GetManifestResourceStream("localhost.pvk");
					byte[] privateKeyBytes = new byte[stream.Length];
					stream.Read(privateKeyBytes, 0, Convert.ToInt32(stream.Length));
					key = new PrivateKey(privateKeyBytes, "");
					Console.WriteLine("foo");
					return key.RSA;
				} else {
					key = PrivateKey.CreateFromFile(_serverKeyFilename);
					Console.WriteLine("foo");
					return key.RSA;
				}
			} catch(Exception ex) {
				Console.WriteLine("Exception: " + ex.Message);
			}
			Console.WriteLine("null");
			return null;
		}