// 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
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 ()
{
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)
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 {