Inheritance: Mono.Security.X509.X509Extension
		private void Empty (ExtendedKeyUsageExtension eku)
		{
			Assert.IsFalse (eku.Critical, "Critical");
			Assert.AreEqual ("2.5.29.37", eku.Oid, "Oid");
			Assert.IsNotNull (eku.Name, "Name");
			Assert.IsFalse (eku.Name == eku.Oid, "Name!=Oid");
			Assert.AreEqual (0, eku.KeyPurpose.Count, "KeyPurpose");
		}
		public void KeyPurpose_NotCritical ()
		{
			ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension ();
			foreach (string oid in CommonKeyPurposes) {
				eku.KeyPurpose.Clear ();
				eku.KeyPurpose.Add (oid);
				Assert.AreEqual ("30-13-06-03-55-1D-25-04-0C-30-0A-06-08-2B-06-01-05-05-07-03-0" 
					+ oid [oid.Length - 1].ToString (), BitConverter.ToString (eku.GetBytes ()), oid);
			}
		}
Beispiel #3
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();
        }
Beispiel #4
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();
        }
        internal MSX509.X509Certificate2 GetCertificate(string name)
        {
            List<X509Extension> extensions = new List<X509Extension>();

            BasicConstraintsExtension constraints = new BasicConstraintsExtension();
            constraints.CertificateAuthority = false;
            constraints.Critical = true;
            extensions.Add(constraints);

            KeyUsageExtension keyUsage = new KeyUsageExtension();
            keyUsage.KeyUsage = KeyUsages.digitalSignature | KeyUsages.nonRepudiation | KeyUsages.keyEncipherment;
            extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedUsage = new ExtendedKeyUsageExtension();
            extendedUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            extendedUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.2");
            extensions.Add(extendedUsage);

            return CreateCertificate(name, extensions, GetRootCertificate(), state_.Config.X509.AuthorityName, MSX509.StoreName.My, state_.Config.X509.RootValidity);
        }
Beispiel #6
0
        private bool CheckClientCertificateExtensions(X509Certificate cert)
        {
            KeyUsages ku = KeyUsages.digitalSignature | KeyUsages.keyEncipherment | KeyUsages.keyAgreement;
            KeyUsageExtension kux = null;
            ExtendedKeyUsageExtension eku = null;

            X509Extension xtn = cert.Extensions["2.5.29.15"];
            if (xtn != null)
                kux = new KeyUsageExtension (xtn);

            xtn = cert.Extensions["2.5.29.37"];
            if (xtn != null)
                eku = new ExtendedKeyUsageExtension (xtn);

            if ((kux != null) && (eku != null)) {
                // RFC3280 states that when both KeyUsageExtension and
                // ExtendedKeyUsageExtension are present then BOTH should
                // be valid
                return (kux.Support (ku) &&
                    eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.2"));
            } else if (kux != null) {
                return kux.Support (ku);
            } else if (eku != null) {
                // Client Authentication (1.3.6.1.5.5.7.3.2)
                return eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.2");
            }

            // last chance - try with older (deprecated) Netscape extensions
            xtn = cert.Extensions["2.16.840.1.113730.1.1"];
            if (xtn != null) {
                NetscapeCertTypeExtension ct = new NetscapeCertTypeExtension (xtn);
                return ct.Support (NetscapeCertTypeExtension.CertTypes.SslClient);
            }

            // certificate isn't valid for SSL client usage
            return false;
        }
		public void Constructor_ASN1 ()
		{
			ExtendedKeyUsageExtension ext = new ExtendedKeyUsageExtension ();
			ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension (ext.ASN1);
			Empty (eku);
		}
		public void Constructor_Empty ()
		{
			ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension ();
			Empty (eku);
		}
		internal static bool VerifyKeyUsage (MX.X509Certificate certificate, KeyUsages keyUsages, string purpose)
		{
			if (certificate.Extensions == null)
				return true;

			KeyUsageExtension kux = null;
			ExtendedKeyUsageExtension eku = null;

			var xtn = certificate.Extensions [OidKeyUsage];
			if (xtn != null)
				kux = new KeyUsageExtension (xtn);

			xtn = certificate.Extensions [OidExtendedKeyUsage];
			if (xtn != null)
				eku = new ExtendedKeyUsageExtension (xtn);

			if ((kux != null) && (eku != null)) {
				// RFC3280 states that when both KeyUsageExtension and
				// ExtendedKeyUsageExtension are present then BOTH should
				// be valid
				if (!kux.Support (keyUsages))
					return false;
				return eku.KeyPurpose.Contains (purpose);
			} else if (kux != null) {
				return kux.Support (keyUsages);
			} else if (eku != null) {
				return eku.KeyPurpose.Contains (purpose);
			}

			return true;
		}
Beispiel #10
0
		// Note: this method only works for RSA certificates
		// DH certificates requires some changes - does anyone use one ?
		private bool checkCertificateUsage (X509Certificate cert) 
		{
			ClientContext context = (ClientContext)this.Context;

			// certificate extensions are required for this
			// we "must" accept older certificates without proofs
			if (cert.Version < 3)
				return true;

			KeyUsages ku = KeyUsages.none;
			switch (context.Negotiating.Cipher.ExchangeAlgorithmType) 
			{
				case ExchangeAlgorithmType.RsaSign:
					ku = KeyUsages.digitalSignature;
					break;
				case ExchangeAlgorithmType.RsaKeyX:
					ku = KeyUsages.keyEncipherment;
					break;
				case ExchangeAlgorithmType.DiffieHellman:
					ku = KeyUsages.keyAgreement;
					break;
				case ExchangeAlgorithmType.Fortezza:
					return false; // unsupported certificate type
			}

			KeyUsageExtension kux = null;
			ExtendedKeyUsageExtension eku = null;

			X509Extension xtn = cert.Extensions ["2.5.29.15"];
			if (xtn != null)
				kux = new KeyUsageExtension (xtn);

			xtn = cert.Extensions ["2.5.29.37"];
			if (xtn != null)
				eku = new ExtendedKeyUsageExtension (xtn);

			if ((kux != null) && (eku != null)) 
			{
				// RFC3280 states that when both KeyUsageExtension and 
				// ExtendedKeyUsageExtension are present then BOTH should
				// be valid
				if (!kux.Support (ku))
					return false;
				return (eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.1") ||
					eku.KeyPurpose.Contains ("2.16.840.1.113730.4.1"));
			}
			else if (kux != null) 
			{
				return kux.Support (ku);
			}
			else if (eku != null) 
			{
				// Server Authentication (1.3.6.1.5.5.7.3.1) or
				// Netscape Server Gated Crypto (2.16.840.1.113730.4)
				return (eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.1") ||
					eku.KeyPurpose.Contains ("2.16.840.1.113730.4.1"));
			}

			// last chance - try with older (deprecated) Netscape extensions
			xtn = cert.Extensions ["2.16.840.1.113730.1.1"];
			if (xtn != null) 
			{
				NetscapeCertTypeExtension ct = new NetscapeCertTypeExtension (xtn);
				return ct.Support (NetscapeCertTypeExtension.CertTypes.SslServer);
			}

			// if the CN=host (checked later) then we assume this is meant for SSL/TLS
			// e.g. the new smtp.gmail.com certificate
			return true;
		}
Beispiel #11
0
		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;
		}
Beispiel #12
0
        bool ExtendedKeyUsage(MSX.PKCS12 pfx)
        {
            foreach (MSX.X509Certificate cert in pfx.Certificates) {
                MSX.X509Extension xtn = cert.Extensions ["2.5.29.37"];
                if (xtn == null)
                    continue;

                var eku = new ExtendedKeyUsageExtension (xtn);
                if (!eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.1"))
                    continue;

                key = GetKeyMatchingCertificate (pfx, cert);
                if (key == null)
                    continue;

                x509 = new X509Certificate (cert.RawData);
                break;
            }

            // complete ?
            return ((x509 != null) && (key != null));
        }
Beispiel #13
0
        /// <summary>
        /// Generates an X509 certificate using the Mono.Security assembly.
        /// Potentially could prise out the relevant classes from the Mono
        /// source code in order to reduce plgx size and complexity... one day
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="issuer">The issuer.</param>
        /// <returns></returns>
        public static PKCS12 Generate(string subject, string issuer, string password, KeePassRPCExt KeePassRPCPlugin)
        {
            byte[] sn = Guid.NewGuid().ToByteArray();
            DateTime notBefore = DateTime.Now;
            DateTime notAfter = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z
            subject = "CN=" + subject;
            issuer = "CN=" + issuer;
            RSA subjectKey = (RSA)RSA.Create();
            RSA issuerKey = (RSA)RSA.Create();
            subjectKey.KeySize = 2048;
            issuerKey.KeySize = 2048;

            string hashName = "SHA1";

            CspParameters subjectParams = new CspParameters();
            CspParameters issuerParams = new CspParameters();

            // serial number MUST be positive
            if ((sn[0] & 0x80) == 0x80)
                sn[0] -= 0x80;

            //issuer = subject;
            //RSA issuerKey = subjectKey;

            if (subject == null)
                throw new Exception("Missing Subject Name");

            X509CertificateBuilder cb = new X509CertificateBuilder(3);
            cb.SerialNumber = sn;
            cb.IssuerName = issuer;
            cb.NotBefore = notBefore;
            cb.NotAfter = notAfter;
            cb.SubjectName = subject;
            cb.SubjectPublicKey = subjectKey;
            cb.Hash = hashName;

            //X509 extensions
            KeyUsageExtension keyUsage = new KeyUsageExtension();
            keyUsage.KeyUsage = KeyUsages.keyEncipherment | KeyUsages.digitalSignature;
            cb.Extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedKeyUsage = new ExtendedKeyUsageExtension();
            extendedKeyUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            cb.Extensions.Add(extendedKeyUsage);
            byte[] rawcert = cb.Sign(issuerKey);

            PKCS12 p12 = new PKCS12();
            p12.Password = password;

            ArrayList list = new ArrayList();
            // we use a fixed array to avoid endianess issues
            // (in case some tools requires the ID to be 1).
            list.Add(new byte[4] { 1, 0, 0, 0 });
            Hashtable attributes = new Hashtable(1);
            attributes.Add(PKCS9.localKeyId, list);

            p12.AddCertificate(new X509Certificate(rawcert), attributes);
            p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

            /*
            if (Type.GetType("Mono.Runtime") != null)
            {
                string fileName = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "KeePassRPC"), "cert.p12");
                if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine(fileName);
                try
                {
                    p12.SaveToFile(fileName);
                }
                catch (Exception)
                {
                    if (KeePassRPCPlugin.logger != null) KeePassRPCPlugin.logger.WriteLine("Could not write to " + fileName + " security between KPRPC and clients may not be established.");
                }
            }

            return p12.GetBytes();
            */
            return p12;
        }
		private bool checkCertificateUsage (X509Certificate cert)
		{
			ServerContext context = (ServerContext)this.Context;

			// certificate extensions are required for this
			// we "must" accept older certificates without proofs
			if (cert.Version < 3)
				return true;

			KeyUsages ku = KeyUsages.none;
			switch (context.Negotiating.Cipher.ExchangeAlgorithmType)
			{
				case ExchangeAlgorithmType.RsaSign:
				case ExchangeAlgorithmType.RsaKeyX:
					ku = KeyUsages.digitalSignature;
					break;
				case ExchangeAlgorithmType.DiffieHellman:
					ku = KeyUsages.keyAgreement;
					break;
				case ExchangeAlgorithmType.Fortezza:
					return false; // unsupported certificate type
			}

			KeyUsageExtension kux = null;
			ExtendedKeyUsageExtension eku = null;

			X509Extension xtn = cert.Extensions["2.5.29.15"];
			if (xtn != null)
				kux = new KeyUsageExtension (xtn);

			xtn = cert.Extensions["2.5.29.37"];
			if (xtn != null)
				eku = new ExtendedKeyUsageExtension (xtn);

			if ((kux != null) && (eku != null))
			{
				// RFC3280 states that when both KeyUsageExtension and 
				// ExtendedKeyUsageExtension are present then BOTH should
				// be valid
				return (kux.Support (ku) &&
					eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.2"));
			}
			else if (kux != null)
			{
				return kux.Support (ku);
			}
			else if (eku != null)
			{
				// Client Authentication (1.3.6.1.5.5.7.3.2)
				return eku.KeyPurpose.Contains ("1.3.6.1.5.5.7.3.2");
			}

			// last chance - try with older (deprecated) Netscape extensions
			xtn = cert.Extensions["2.16.840.1.113730.1.1"];
			if (xtn != null)
			{
				NetscapeCertTypeExtension ct = new NetscapeCertTypeExtension (xtn);
				return ct.Support (NetscapeCertTypeExtension.CertTypes.SslClient);
			}

			// certificate isn't valid for SSL server usage
			return false;
		}
Beispiel #15
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();
            }
        }