Inheritance: Mono.Security.X509.X509Extension
		public void SubjectAltNameGenerator ()
		{
			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();
			X509CertificateBuilder x509 = new X509CertificateBuilder ();
			x509.IssuerName = "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server";
			x509.NotAfter = DateTime.MaxValue;
			x509.NotBefore = DateTime.MinValue;
			x509.SubjectName = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org";
			x509.SerialNumber = new byte[] {12, 34, 56, 78, 90};
			x509.Version = 3;
			x509.SubjectPublicKey = rsa;

			string[] dns = new string[2];
			dns[0] = "one";
			dns[1] = "two";
			string[] uris = new string[3];
			uris[0] = "one:two://three";
			uris[1] = "Here:I:AM://12345";
			uris[2] = "last:one";
			SubjectAltNameExtension sane = new SubjectAltNameExtension (null, dns, null, uris);
			x509.Extensions.Add (sane);
			byte[] data = x509.Sign (rsa);

			X509Certificate x509_loaded = new X509Certificate (data);
			SubjectAltNameExtension	sane_test = new SubjectAltNameExtension (x509_loaded.Extensions[0]);
			Assert.AreEqual (sane_test.RFC822.Length, 0, "RFC822 count");
			Assert.AreEqual (sane_test.DNSNames.Length, 2, "DNSName count");
			Assert.AreEqual (sane_test.IPAddresses.Length, 0, "IPAddresses count");
			Assert.AreEqual (sane_test.UniformResourceIdentifiers.Length, 3, "URI Count");
			Assert.AreEqual (sane_test.DNSNames[1], "two", "DNSName test");
			Assert.AreEqual (sane_test.UniformResourceIdentifiers[2], "last:one", "URI Test");
		}
 public 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];
 }
 /// <summary>This method is called by a CA to sign the provided Certificate
 /// with our RSA key.</summary>
 public Certificate Sign(Certificate Signer, RSA PrivateKey)
 {
   X509CertificateBuilder x509_builder = new X509CertificateBuilder(3);
   x509_builder.IssuerName = Signer.Subject.DN;
   x509_builder.SubjectName = Subject.DN;
   SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
   // I guess this is reversed for network order or something...
   byte[] tmp = sha1.ComputeHash(Signer.UnsignedData);
   for(int i = 0; i < tmp.Length / 2; i++) {
     int j = tmp.Length - i - 1;
     byte tmpb = tmp[i];
     tmp[i] = tmp[j];
     tmp[j] = tmpb;
   }
   x509_builder.SerialNumber = tmp;
   x509_builder.NotBefore = System.DateTime.MinValue;
   x509_builder.NotAfter = System.DateTime.MaxValue;
   x509_builder.SubjectPublicKey = _public_key;
   SubjectAltNameExtension sane = new SubjectAltNameExtension(null, null, null, new string[] {NodeAddress});
   x509_builder.Extensions.Add(sane);
   byte[] cert_data = x509_builder.Sign(PrivateKey);
   return new Certificate(cert_data);
 }
 public 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];
 }
    /// <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;
    }
Example #6
0
 ///<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;
 }
Example #7
0
			// 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;
				}
			}
Example #8
0
		// 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);
		}
Example #9
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;
		}
		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");
		}
			// 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 (X509Certificate2 cert, string targetHost) 
			{
				X509Extension ext = cert.Extensions ["2.5.29.17"];
				// 1. subjectAltName
				if (ext != null) {
					ASN1 asn = new ASN1 (ext.RawData);
					SubjectAltNameExtension subjectAltName = new SubjectAltNameExtension (asn);
					// 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.Format (false), targetHost);
			}
Example #12
0
 ///<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!");
 }
Example #13
0
		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 ();
			}
		}
		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");
		}