UsingTasks are not collected expectedly when imports are involved.
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509 / X501Name.cs
index 283ba71b1a005e3e16cebcc680e0a796f9dd5980..8343e5fb557eab20797796e54a31cb5159cddae4 100644 (file)
@@ -5,7 +5,7 @@
 //     Sebastien Pouliot <sebastien@ximian.com>
 //
 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2006 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
@@ -67,6 +67,11 @@ namespace Mono.Security.X509 {
                static byte[] domainComponent = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 };
                static byte[] userid = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 };
                static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 };
+               static byte[] dnQualifier = { 0x55, 0x04, 0x2E };
+               static byte[] title = { 0x55, 0x04, 0x0C };
+               static byte[] surname = { 0x55, 0x04, 0x04 };
+               static byte[] givenName = { 0x55, 0x04, 0x2A };
+               static byte[] initial = { 0x55, 0x04, 0x2B };
 
                private X501 () 
                {
@@ -77,77 +82,120 @@ namespace Mono.Security.X509 {
                        StringBuilder sb = new StringBuilder ();
                        for (int i = 0; i < seq.Count; i++) {
                                ASN1 entry = seq [i];
-                               // multiple entries are valid
-                               for (int k = 0; k < entry.Count; k++) {
-                                       ASN1 pair = entry [k];
-                                       ASN1 s = pair [1];
-                                       if (s == null)
-                                               continue;
-
-                                       ASN1 poid = pair [0];
-                                       if (poid == null)
-                                               continue;
-
-                                       if (poid.CompareValue (countryName))
-                                               sb.Append ("C=");
-                                       else if (poid.CompareValue (organizationName))
-                                               sb.Append ("O=");
-                                       else if (poid.CompareValue (organizationalUnitName))
-                                               sb.Append ("OU=");
-                                       else if (poid.CompareValue (commonName))
-                                               sb.Append ("CN=");
-                                       else if (poid.CompareValue (localityName))
-                                               sb.Append ("L=");
-                                       else if (poid.CompareValue (stateOrProvinceName))
-                                               sb.Append ("S=");       // NOTE: RFC2253 uses ST=
-                                       else if (poid.CompareValue (streetAddress))
-                                               sb.Append ("STREET=");
-                                       else if (poid.CompareValue (domainComponent))
-                                               sb.Append ("DC=");
-                                       else if (poid.CompareValue (userid))
-                                               sb.Append ("UID=");
-                                       else if (poid.CompareValue (email))
-                                               sb.Append ("E=");       // NOTE: Not part of RFC2253
-                                       else {
-                                               // unknown OID
-                                               sb.Append ("OID.");     // NOTE: Not present as RFC2253
-                                               sb.Append (ASN1Convert.ToOid (poid));
-                                               sb.Append ("=");
-                                       }
+                               AppendEntry (sb, entry, true);
 
-                                       string sValue = null;
-                                       // 16bits or 8bits string ? TODO not complete (+special chars!)
-                                       if (s.Tag == 0x1E) {
-                                               // BMPSTRING
-                                               StringBuilder sb2 = new StringBuilder ();
-                                               for (int j = 1; j < s.Value.Length; j += 2)
-                                                       sb2.Append ((char)s.Value[j]);
-                                               sValue = sb2.ToString ();
-                                       } else {
-                                               sValue = Encoding.UTF8.GetString (s.Value);
-                                               // in some cases we must quote (") the value
-                                               // Note: this doesn't seems to conform to RFC2253
-                                               char[] specials = { ',', '+', '"', '\\', '<', '>', ';' };
-                                               if (sValue.IndexOfAny (specials, 0, sValue.Length) > 0)
-                                                       sValue = "\"" + sValue + "\"";
-                                               else if (sValue.StartsWith (" "))
-                                                       sValue = "\"" + sValue + "\"";
-                                               else if (sValue.EndsWith (" "))
-                                                       sValue = "\"" + sValue + "\"";
-                                       }
+                               // separator (not on last iteration)
+                               if (i < seq.Count - 1)
+                                       sb.Append (", ");
+                       }
+                       return sb.ToString ();
+               }
 
-                                       sb.Append (sValue);
+               static public string ToString (ASN1 seq, bool reversed, string separator, bool quotes)
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       if (reversed) {
+                               for (int i = seq.Count - 1; i >= 0; i--) {
+                                       ASN1 entry = seq [i];
+                                       AppendEntry (sb, entry, quotes);
 
                                        // separator (not on last iteration)
-                                       if (k < entry.Count - 1)
-                                               sb.Append (", ");
+                                       if (i > 0)
+                                               sb.Append (separator);
                                }
+                       } else {
+                               for (int i = 0; i < seq.Count; i++) {
+                                       ASN1 entry = seq [i];
+                                       AppendEntry (sb, entry, quotes);
+
+                                       // separator (not on last iteration)
+                                       if (i < seq.Count - 1)
+                                               sb.Append (separator);
+                               }
+                       }
+                       return sb.ToString ();
+               }
+
+               static private void AppendEntry (StringBuilder sb, ASN1 entry, bool quotes)
+               {
+                       // multiple entries are valid
+                       for (int k = 0; k < entry.Count; k++) {
+                               ASN1 pair = entry [k];
+                               ASN1 s = pair [1];
+                               if (s == null)
+                                       continue;
+
+                               ASN1 poid = pair [0];
+                               if (poid == null)
+                                       continue;
+
+                               if (poid.CompareValue (countryName))
+                                       sb.Append ("C=");
+                               else if (poid.CompareValue (organizationName))
+                                       sb.Append ("O=");
+                               else if (poid.CompareValue (organizationalUnitName))
+                                       sb.Append ("OU=");
+                               else if (poid.CompareValue (commonName))
+                                       sb.Append ("CN=");
+                               else if (poid.CompareValue (localityName))
+                                       sb.Append ("L=");
+                               else if (poid.CompareValue (stateOrProvinceName))
+                                       sb.Append ("S=");       // NOTE: RFC2253 uses ST=
+                               else if (poid.CompareValue (streetAddress))
+                                       sb.Append ("STREET=");
+                               else if (poid.CompareValue (domainComponent))
+                                       sb.Append ("DC=");
+                               else if (poid.CompareValue (userid))
+                                       sb.Append ("UID=");
+                               else if (poid.CompareValue (email))
+                                       sb.Append ("E=");       // NOTE: Not part of RFC2253
+                               else if (poid.CompareValue (dnQualifier))
+                                       sb.Append ("dnQualifier=");
+                               else if (poid.CompareValue (title))
+                                       sb.Append ("T=");
+                               else if (poid.CompareValue (surname))
+                                       sb.Append ("SN=");
+                               else if (poid.CompareValue (givenName))
+                                       sb.Append ("G=");
+                               else if (poid.CompareValue (initial))
+                                       sb.Append ("I=");
+                               else {
+                                       // unknown OID
+                                       sb.Append ("OID.");     // NOTE: Not present as RFC2253
+                                       sb.Append (ASN1Convert.ToOid (poid));
+                                       sb.Append ("=");
+                               }
+
+                               string sValue = null;
+                               // 16bits or 8bits string ? TODO not complete (+special chars!)
+                               if (s.Tag == 0x1E) {
+                                       // BMPSTRING
+                                       StringBuilder sb2 = new StringBuilder ();
+                                       for (int j = 1; j < s.Value.Length; j += 2)
+                                               sb2.Append ((char)s.Value[j]);
+                                       sValue = sb2.ToString ();
+                               } else {
+                                       if (s.Tag == 0x14)
+                                               sValue = Encoding.UTF7.GetString (s.Value);
+                                       else
+                                               sValue = Encoding.UTF8.GetString (s.Value);
+                                       // in some cases we must quote (") the value
+                                       // Note: this doesn't seems to conform to RFC2253
+                                       char[] specials = { ',', '+', '"', '\\', '<', '>', ';' };
+                                       if (quotes) {
+                                               if ((sValue.IndexOfAny (specials, 0, sValue.Length) > 0) ||
+                                                   sValue.StartsWith (" ") || (sValue.EndsWith (" ")))
+                                                       sValue = "\"" + sValue + "\"";
+                                       }
+                               }
+
+                               sb.Append (sValue);
 
                                // separator (not on last iteration)
-                               if (i < seq.Count - 1)
+                               if (k < entry.Count - 1)
                                        sb.Append (", ");
                        }
-                       return sb.ToString ();
                }
 
                static private X520.AttributeTypeAndValue GetAttributeFromOid (string attributeType) 
@@ -173,8 +221,18 @@ namespace Mono.Security.X509 {
                                        return new X520.DomainComponent ();
                                case "UID":     // RFC1274
                                        return new X520.UserId ();
+                               case "DNQUALIFIER":
+                                       return new X520.DnQualifier ();
+                               case "T":
+                                       return new X520.Title ();
+                               case "SN":
+                                       return new X520.Surname ();
+                               case "G":
+                                       return new X520.GivenName ();
+                               case "I":
+                                       return new X520.Initial ();
                                default:
-                                       if (s == "OID.") {
+                                       if (s.StartsWith ("OID.")) {
                                                // MUST support it but it OID may be without it
                                                return new X520.Oid (s.Substring (4));
                                        } else {