Browse Source

2005-01-17 Sebastien Pouliot <[email protected]>

	* AsnEncodedData.cs: Added more decoding/formatting code as this class
	is far more intelligent (or bloated) than anticipated.
	* Oid.cs: Added more Oid / FriendlyName definitions required for the
	X.509 extensions and some more for some failing unit tests.
	* OidCollection.cs: Added support to make the collection read-only.


svn path=/trunk/mcs/; revision=39051
Sebastien Pouliot 21 years ago
parent
commit
ea2c8d68a7

+ 152 - 3
mcs/class/System.Security/System.Security.Cryptography/AsnEncodedData.cs

@@ -29,14 +29,24 @@
 
 #if NET_2_0
 
+using System.Security.Cryptography.X509Certificates;
 using System.Text;
 
 namespace System.Security.Cryptography {
 
+	internal enum AsnDecodeStatus {
+		NotDecoded = -1,
+		Ok = 0,
+		BadAsn = 1,
+		BadTag = 2,
+		BadLength = 3,
+		InformationNotAvailable = 4
+	}
+
 	public class AsnEncodedData {
 
-		private Oid _oid;
-		private byte[] _raw;
+		internal Oid _oid;
+		internal byte[] _raw;
 
 		// constructors
 
@@ -62,7 +72,11 @@ namespace System.Security.Cryptography {
 
 		public AsnEncodedData (AsnEncodedData asnEncodedData)
 		{
-			CopyFrom (asnEncodedData);
+			if (asnEncodedData == null)
+				throw new ArgumentNullException ("asnEncodedData");
+
+			Oid = new Oid (asnEncodedData._oid);
+			RawData = asnEncodedData._raw;
 		}
 
 		public AsnEncodedData (byte[] rawData)
@@ -103,6 +117,40 @@ namespace System.Security.Cryptography {
 		}
 
 		public virtual string Format (bool multiLine) 
+		{
+			if (_raw == null)
+				return String.Empty;
+
+			if (_oid == null)
+				return Default (multiLine);
+
+			return ToString (multiLine);
+		}
+
+		// internal decoding/formatting methods
+
+		internal virtual string ToString (bool multiLine)
+		{
+			switch (_oid.Value) {
+			// fx supported objects
+			case X509BasicConstraintsExtension.oid:
+				return BasicConstraintsExtension (multiLine);
+			case X509EnhancedKeyUsageExtension.oid:
+				return EnhancedKeyUsageExtension (multiLine);
+			case X509KeyUsageExtension.oid:
+				return KeyUsageExtension (multiLine);
+			case X509SubjectKeyIdentifierExtension.oid:
+				return SubjectKeyIdentifierExtension (multiLine);
+			// other known objects (i.e. supported structure) - 
+			// but without any corresponding framework class
+			case Oid.oidNetscapeCertType:
+				return NetscapeCertType (multiLine);
+			default:
+				return Default (multiLine);
+			}
+		}
+
+		internal string Default (bool multiLine)
 		{
 			StringBuilder sb = new StringBuilder ();
 			for (int i=0; i < _raw.Length; i++) {
@@ -112,6 +160,107 @@ namespace System.Security.Cryptography {
 			}
 			return sb.ToString ();
 		}
+
+		// Indirectly (undocumented but) supported extensions
+
+		internal string BasicConstraintsExtension (bool multiLine)
+		{
+			try {
+				X509BasicConstraintsExtension bc = new X509BasicConstraintsExtension  (this, false);
+				return bc.ToString (multiLine);
+			}
+			catch {
+				return String.Empty;
+			}
+		}
+
+		internal string EnhancedKeyUsageExtension (bool multiLine)
+		{
+			try {
+				X509EnhancedKeyUsageExtension eku = new X509EnhancedKeyUsageExtension  (this, false);
+				return eku.ToString (multiLine);
+			}
+			catch {
+				return String.Empty;
+			}
+		}
+
+		internal string KeyUsageExtension (bool multiLine)
+		{
+			try {
+				X509KeyUsageExtension ku = new X509KeyUsageExtension  (this, false);
+				return ku.ToString (multiLine);
+			}
+			catch {
+				return String.Empty;
+			}
+		}
+
+		internal string SubjectKeyIdentifierExtension (bool multiLine)
+		{
+			try {
+				X509SubjectKeyIdentifierExtension ski = new X509SubjectKeyIdentifierExtension  (this, false);
+				return ski.ToString (multiLine);
+			}
+			catch {
+				return String.Empty;
+			}
+		}
+
+		// Indirectly (undocumented but) supported extensions
+
+		internal string NetscapeCertType (bool multiLine)
+		{
+			// 4 byte long, BITSTRING (0x03), Value length of 2
+			if ((_raw.Length < 4) || (_raw [0] != 0x03) || (_raw [1] != 0x02))
+				return "Information Not Available";
+			// first value byte is the number of unused bits
+			int value = (_raw [3] >> _raw [2]) << _raw [2];
+
+			StringBuilder sb = new StringBuilder ();
+
+			bool first = false;
+			if ((value & 0x80) == 0x80) {
+				sb.Append ("SSL Client Authentication");
+			}
+			if ((value & 0x40) == 0x40) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("SSL Server Authentication");
+			}
+			if ((value & 0x20) == 0x20) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("SMIME");
+			}
+			if ((value & 0x10) == 0x10) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("Signature"); // a.k.a. Object Signing / Code Signing
+			}
+			if ((value & 0x08) == 0x08) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("Unknown cert type");
+			}
+			if ((value & 0x04) == 0x04) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("SSL CA");	// CA == Certificate Authority
+			}
+			if ((value & 0x02) == 0x02) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("SMIME CA");
+			}
+			if ((value & 0x01) == 0x01) {
+				if (sb.Length > 0)
+					sb.Append (", ");
+				sb.Append ("Signature CA");
+			}
+			sb.AppendFormat (" ({0})", value.ToString ("x2"));
+			return sb.ToString ();
+		}
 	}
 }
 

+ 8 - 0
mcs/class/System.Security/System.Security.Cryptography/ChangeLog

@@ -1,3 +1,11 @@
+2005-01-17  Sebastien Pouliot  <[email protected]>
+
+	* AsnEncodedData.cs: Added more decoding/formatting code as this class
+	is far more intelligent (or bloated) than anticipated.
+	* Oid.cs: Added more Oid / FriendlyName definitions required for the
+	X.509 extensions and some more for some failing unit tests.
+	* OidCollection.cs: Added support to make the collection read-only.
+
 2005-01-13  Sebastien Pouliot  <[email protected]>
 
 	* AsnEncodedData.cs: Completed/fixed implementation.

+ 70 - 21
mcs/class/System.Security/System.Security.Cryptography/Oid.cs

@@ -29,6 +29,9 @@
 
 #if NET_2_0
 
+using System.Security.Cryptography.Pkcs;
+using System.Security.Cryptography.X509Certificates;
+
 namespace System.Security.Cryptography {
 
 	public sealed class Oid {
@@ -84,22 +87,52 @@ namespace System.Security.Cryptography {
 			}
 		}
 
-		// private methods
+		// internal stuff
+
+		// Known OID/Names not defined anywhere else (by OID order)
+		internal const string oidRSA = "1.2.840.113549.1.1.1";
+		internal const string nameRSA = "RSA";
+		internal const string oidPkcs7Data = "1.2.840.113549.1.7.1";
+		internal const string namePkcs7Data = "PKCS 7 Data";
+		internal const string oidMd5 = "1.2.840.113549.2.5";
+		internal const string nameMd5 = "md5";
+		internal const string oid3Des = "1.2.840.113549.3.7";
+		internal const string name3Des = "3des";
+		internal const string oidSha1 = "1.3.14.3.2.26";
+		internal const string nameSha1 = "sha1";
+		internal const string oidNetscapeCertType = "2.16.840.1.113730.1.1";
+		internal const string nameNetscapeCertType = "Netscape Cert Type";
 
 		// TODO - find the complete list
 		private string GetName (string oid) 
 		{
-			if (oid == null)
-				return null;
 			switch (oid) {
-				case "1.2.840.113549.1.1.1":
-					return "RSA";
-				case "1.2.840.113549.1.7.1":
-					return "PKCS 7 Data";
-				case "1.2.840.113549.1.9.5":
-					return "Signing Time";
-				case "1.2.840.113549.3.7":
-					return "3des";
+				case oidRSA:
+					return nameRSA;
+				case oidPkcs7Data:
+					return namePkcs7Data;
+				case Pkcs9ContentType.oid:
+					return Pkcs9ContentType.friendlyName;
+				case Pkcs9MessageDigest.oid:
+					return Pkcs9MessageDigest.friendlyName;
+				case Pkcs9SigningTime.oid:
+					return Pkcs9SigningTime.friendlyName;
+				case oid3Des:
+					return name3Des;
+				case X509BasicConstraintsExtension.oid:
+					return X509BasicConstraintsExtension.friendlyName;
+				case X509KeyUsageExtension.oid:
+					return X509KeyUsageExtension.friendlyName;
+				case X509EnhancedKeyUsageExtension.oid:
+					return X509EnhancedKeyUsageExtension.friendlyName;
+				case X509SubjectKeyIdentifierExtension.oid:
+					return X509SubjectKeyIdentifierExtension.friendlyName;
+				case oidNetscapeCertType:
+					return nameNetscapeCertType;
+				case oidMd5:
+					return nameMd5;
+				case oidSha1:
+					return nameSha1;
 				default:
 					return _name;
 			}
@@ -108,17 +141,33 @@ namespace System.Security.Cryptography {
 		// TODO - find the complete list
 		private string GetValue (string name) 
 		{
-			if (name == null)
-				return null;
 			switch (name) {
-				case "RSA":
-					return "1.2.840.113549.1.1.1";
-				case "PKCS 7 Data":
-					return "1.2.840.113549.1.7.1";
-				case "Signing Time":
-					return "1.2.840.113549.1.9.5";
-				case "3des":
-					return "1.2.840.113549.3.7";
+				case nameRSA:
+					return oidRSA;
+				case namePkcs7Data:
+					return oidPkcs7Data;
+				case Pkcs9ContentType.friendlyName:
+					return Pkcs9ContentType.oid;
+				case Pkcs9MessageDigest.friendlyName:
+					return Pkcs9MessageDigest.oid;
+				case Pkcs9SigningTime.friendlyName:
+					return Pkcs9SigningTime.oid;
+				case name3Des:
+					return oid3Des;
+				case X509BasicConstraintsExtension.friendlyName:
+					return X509BasicConstraintsExtension.oid;
+				case X509KeyUsageExtension.friendlyName:
+					return X509KeyUsageExtension.oid;
+				case X509EnhancedKeyUsageExtension.friendlyName:
+					return X509EnhancedKeyUsageExtension.oid;
+				case X509SubjectKeyIdentifierExtension.friendlyName:
+					return X509SubjectKeyIdentifierExtension.oid;
+				case nameNetscapeCertType:
+					return oidNetscapeCertType;
+				case nameMd5:
+					return oidMd5;
+				case nameSha1:
+					return oidSha1;
 				default:
 					return _value;
 			}

+ 22 - 8
mcs/class/System.Security/System.Security.Cryptography/OidCollection.cs

@@ -2,11 +2,10 @@
 // OidCollection.cs - System.Security.Cryptography.OidCollection
 //
 // Author:
-//	Sebastien Pouliot ([email protected])
+//	Sebastien Pouliot  <[email protected]>
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-//
-
+// Copyright (C) 2005 Novell Inc. (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,16 +29,14 @@
 
 #if NET_2_0
 
-using System;
 using System.Collections;
 
 namespace System.Security.Cryptography {
 
-	// Note: Match the definition of framework version 1.2.3400.0 on http://longhorn.msdn.microsoft.com
-
 	public sealed class OidCollection : ICollection, IEnumerable {
 
 		private ArrayList _list;
+		private bool _readOnly;
 
 		// constructors
 
@@ -80,7 +77,7 @@ namespace System.Security.Cryptography {
 
 		public int Add (Oid oid)
 		{
-			return _list.Add (oid);
+			return (_readOnly ? 0 : _list.Add (oid));
 		}
 
 		public void CopyTo (Oid[] array, int index)
@@ -104,7 +101,24 @@ namespace System.Security.Cryptography {
 		{
 			return new OidEnumerator (this);
 		}
+
+		// internal stuff
+
+		internal bool ReadOnly {
+			get { return _readOnly; }
+			set { _readOnly = value; }
+		}
+
+		internal OidCollection ReadOnlyCopy ()
+		{
+			OidCollection copy = new OidCollection ();
+			foreach (Oid oid in _list) {
+				copy.Add (oid);
+			}
+			copy._readOnly = true;
+			return copy;
+		}
 	}
 }
 
-#endif
+#endif