private void Empty (KeyUsageExtension kue)
		{
			Assert.IsFalse (kue.Critical, "Critical");
			Assert.AreEqual ("2.5.29.15", kue.Oid, "Oid");
			Assert.IsNotNull (kue.Name, "Name");
			Assert.IsFalse (kue.Name == kue.Oid, "Name!=Oid");
			Assert.AreEqual (KeyUsages.none, kue.KeyUsage, "KeyUsage");
			Assert.IsTrue (kue.Support (KeyUsages.none), "Support(none)");
			Assert.IsFalse (kue.Support (KeyUsages.digitalSignature), "Support(digitalSignature)");
			Assert.IsFalse (kue.Support (KeyUsages.decipherOnly), "Support(decipherOnly)");
		}
		public void KeyUsage_MaxValue ()
		{
			KeyUsageExtension kue = new KeyUsageExtension ();
			kue.KeyUsage = (KeyUsages) Int32.MaxValue;
			Assert.IsTrue (kue.Support (KeyUsages.none), "Support(none)");
			Assert.IsTrue (kue.Support (KeyUsages.digitalSignature), "Support(digitalSignature)");
			Assert.IsTrue (kue.Support (KeyUsages.nonRepudiation), "Support(nonRepudiation)");
			Assert.IsTrue (kue.Support (KeyUsages.keyEncipherment), "Support(keyEncipherment)");
			Assert.IsTrue (kue.Support (KeyUsages.dataEncipherment), "Support(dataEncipherment)");
			Assert.IsTrue (kue.Support (KeyUsages.keyAgreement), "Support(keyAgreement)");
			Assert.IsTrue (kue.Support (KeyUsages.keyCertSign), "Support(keyCertSign)");
			Assert.IsTrue (kue.Support (KeyUsages.cRLSign), "Support(cRLSign)");
			Assert.IsTrue (kue.Support (KeyUsages.encipherOnly), "Support(encipherOnly)");
			Assert.IsTrue (kue.Support (KeyUsages.decipherOnly), "Support(decipherOnly)");
		}
		public void KeyUsage ()
		{
			KeyUsageExtension kue = new KeyUsageExtension ();
			foreach (KeyUsages ku in Enum.GetValues (typeof (KeyUsages))) {
				kue.KeyUsage = ku;
				byte[] rawext = kue.GetBytes ();
				int length = 13;
				if ((int) ku > Byte.MaxValue) {
					length++;
					Assert.AreEqual ((byte) ku, rawext[rawext.Length - 2], ku.ToString () + ".Value2");
					Assert.AreEqual ((byte) ((int) ku >> 8), rawext[rawext.Length - 1], ku.ToString () + ".Value1");
				} else {
					Assert.AreEqual ((byte) ku, rawext[rawext.Length - 1], ku.ToString () + ".Value");
				}
				Assert.AreEqual (length, rawext.Length, ku.ToString () + ".Length");
			}
		}
        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);
        }
Example #5
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 ()
		{
			KeyUsageExtension ext = new KeyUsageExtension ();
			KeyUsageExtension kue = new KeyUsageExtension (ext.ASN1);
			Empty (kue);
		}
		public void Constructor_Empty ()
		{
			KeyUsageExtension kue = new KeyUsageExtension ();
			Empty (kue);
		}
		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;
		}
Example #9
0
		public bool VerifySignature (X509Certificate x509) 
		{
			if (x509 == null)
				throw new ArgumentNullException ("x509");

			// 1. x509 certificate must be a CA certificate (unknown for v1 or v2 certs)
			if (x509.Version >= 3) {
				BasicConstraintsExtension basicConstraints = null;
				// 1.2. Check for ca = true in BasicConstraint
				X509Extension ext = x509.Extensions ["2.5.29.19"];
				if (ext != null) {
					basicConstraints = new BasicConstraintsExtension (ext);
					if (!basicConstraints.CertificateAuthority)
						return false;
				}
				// 1.1. Check for "cRLSign" bit in KeyUsage extension
				ext = x509.Extensions ["2.5.29.15"];
				if (ext != null) {
					KeyUsageExtension keyUsage = new KeyUsageExtension (ext);
					if (!keyUsage.Support (KeyUsages.cRLSign)) {
						// 2nd chance if basicConstraints is CertificateAuthority
						// and KeyUsage support digitalSignature
						if ((basicConstraints == null) || !keyUsage.Support (KeyUsages.digitalSignature))
							return false;
					}
				}
			}
			// 2. CRL issuer must match CA subject name
			if (issuer != x509.SubjectName)
				return false;
			// 3. Check the CRL signature with the CA certificate public key
			switch (signatureOID) {
				case "1.2.840.10040.4.3":
					return VerifySignature (x509.DSA);
				default:
					return VerifySignature (x509.RSA);
			}
		}
Example #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;
		}
Example #11
0
        bool KeyUsage(MSX.PKCS12 pfx)
        {
            foreach (MSX.X509Certificate cert in pfx.Certificates) {
                MSX.X509Extension xtn = cert.Extensions ["2.5.29.15"];
                if (xtn == null)
                    continue;

                var ku = new KeyUsageExtension (xtn);
                if (!ku.Support (KeyUsages.digitalSignature) && !ku.Support (KeyUsages.keyEncipherment))
                    continue;

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

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

            // complete ?
            return ((x509 != null) && (key != null));
        }
        private MSX509.X509Certificate2 GetRootCertificate()
        {
            List<X509Extension> extensions = new List<X509Extension>();

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

            KeyUsageExtension keyUsage = new KeyUsageExtension();
            keyUsage.KeyUsage = KeyUsages.keyCertSign | KeyUsages.cRLSign;
            extensions.Add(keyUsage);

            return CreateCertificate(state_.Config.X509.AuthorityName, extensions, null, state_.Config.X509.AuthorityName, MSX509.StoreName.Root, state_.Config.X509.RootValidity);
        }
Example #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;
		}