725 lines
19 KiB
C#
725 lines
19 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Org.BouncyCastle.Asn1.Pkcs;
|
|
using Org.BouncyCastle.Utilities;
|
|
using Org.BouncyCastle.Utilities.Encoders;
|
|
|
|
namespace Org.BouncyCastle.Asn1.X509;
|
|
|
|
public class X509Name : Asn1Encodable
|
|
{
|
|
public static readonly DerObjectIdentifier C;
|
|
|
|
public static readonly DerObjectIdentifier O;
|
|
|
|
public static readonly DerObjectIdentifier OU;
|
|
|
|
public static readonly DerObjectIdentifier T;
|
|
|
|
public static readonly DerObjectIdentifier CN;
|
|
|
|
public static readonly DerObjectIdentifier Street;
|
|
|
|
public static readonly DerObjectIdentifier SerialNumber;
|
|
|
|
public static readonly DerObjectIdentifier L;
|
|
|
|
public static readonly DerObjectIdentifier ST;
|
|
|
|
public static readonly DerObjectIdentifier Surname;
|
|
|
|
public static readonly DerObjectIdentifier GivenName;
|
|
|
|
public static readonly DerObjectIdentifier Initials;
|
|
|
|
public static readonly DerObjectIdentifier Generation;
|
|
|
|
public static readonly DerObjectIdentifier UniqueIdentifier;
|
|
|
|
public static readonly DerObjectIdentifier BusinessCategory;
|
|
|
|
public static readonly DerObjectIdentifier PostalCode;
|
|
|
|
public static readonly DerObjectIdentifier DnQualifier;
|
|
|
|
public static readonly DerObjectIdentifier Pseudonym;
|
|
|
|
public static readonly DerObjectIdentifier DateOfBirth;
|
|
|
|
public static readonly DerObjectIdentifier PlaceOfBirth;
|
|
|
|
public static readonly DerObjectIdentifier Gender;
|
|
|
|
public static readonly DerObjectIdentifier CountryOfCitizenship;
|
|
|
|
public static readonly DerObjectIdentifier CountryOfResidence;
|
|
|
|
public static readonly DerObjectIdentifier NameAtBirth;
|
|
|
|
public static readonly DerObjectIdentifier PostalAddress;
|
|
|
|
public static readonly DerObjectIdentifier DmdName;
|
|
|
|
public static readonly DerObjectIdentifier TelephoneNumber;
|
|
|
|
public static readonly DerObjectIdentifier OrganizationIdentifier;
|
|
|
|
public static readonly DerObjectIdentifier Name;
|
|
|
|
public static readonly DerObjectIdentifier EmailAddress;
|
|
|
|
public static readonly DerObjectIdentifier UnstructuredName;
|
|
|
|
public static readonly DerObjectIdentifier UnstructuredAddress;
|
|
|
|
public static readonly DerObjectIdentifier E;
|
|
|
|
public static readonly DerObjectIdentifier DC;
|
|
|
|
public static readonly DerObjectIdentifier UID;
|
|
|
|
private static readonly bool[] defaultReverse;
|
|
|
|
public static readonly Hashtable DefaultSymbols;
|
|
|
|
public static readonly Hashtable RFC2253Symbols;
|
|
|
|
public static readonly Hashtable RFC1779Symbols;
|
|
|
|
public static readonly Hashtable DefaultLookup;
|
|
|
|
private readonly IList ordering = Platform.CreateArrayList();
|
|
|
|
private readonly X509NameEntryConverter converter;
|
|
|
|
private IList values = Platform.CreateArrayList();
|
|
|
|
private IList added = Platform.CreateArrayList();
|
|
|
|
private Asn1Sequence seq;
|
|
|
|
public static bool DefaultReverse
|
|
{
|
|
get
|
|
{
|
|
return defaultReverse[0];
|
|
}
|
|
set
|
|
{
|
|
defaultReverse[0] = value;
|
|
}
|
|
}
|
|
|
|
static X509Name()
|
|
{
|
|
C = new DerObjectIdentifier("2.5.4.6");
|
|
O = new DerObjectIdentifier("2.5.4.10");
|
|
OU = new DerObjectIdentifier("2.5.4.11");
|
|
T = new DerObjectIdentifier("2.5.4.12");
|
|
CN = new DerObjectIdentifier("2.5.4.3");
|
|
Street = new DerObjectIdentifier("2.5.4.9");
|
|
SerialNumber = new DerObjectIdentifier("2.5.4.5");
|
|
L = new DerObjectIdentifier("2.5.4.7");
|
|
ST = new DerObjectIdentifier("2.5.4.8");
|
|
Surname = new DerObjectIdentifier("2.5.4.4");
|
|
GivenName = new DerObjectIdentifier("2.5.4.42");
|
|
Initials = new DerObjectIdentifier("2.5.4.43");
|
|
Generation = new DerObjectIdentifier("2.5.4.44");
|
|
UniqueIdentifier = new DerObjectIdentifier("2.5.4.45");
|
|
BusinessCategory = new DerObjectIdentifier("2.5.4.15");
|
|
PostalCode = new DerObjectIdentifier("2.5.4.17");
|
|
DnQualifier = new DerObjectIdentifier("2.5.4.46");
|
|
Pseudonym = new DerObjectIdentifier("2.5.4.65");
|
|
DateOfBirth = new DerObjectIdentifier("1.3.6.1.5.5.7.9.1");
|
|
PlaceOfBirth = new DerObjectIdentifier("1.3.6.1.5.5.7.9.2");
|
|
Gender = new DerObjectIdentifier("1.3.6.1.5.5.7.9.3");
|
|
CountryOfCitizenship = new DerObjectIdentifier("1.3.6.1.5.5.7.9.4");
|
|
CountryOfResidence = new DerObjectIdentifier("1.3.6.1.5.5.7.9.5");
|
|
NameAtBirth = new DerObjectIdentifier("1.3.36.8.3.14");
|
|
PostalAddress = new DerObjectIdentifier("2.5.4.16");
|
|
DmdName = new DerObjectIdentifier("2.5.4.54");
|
|
TelephoneNumber = X509ObjectIdentifiers.id_at_telephoneNumber;
|
|
OrganizationIdentifier = X509ObjectIdentifiers.id_at_organizationIdentifier;
|
|
Name = X509ObjectIdentifiers.id_at_name;
|
|
EmailAddress = PkcsObjectIdentifiers.Pkcs9AtEmailAddress;
|
|
UnstructuredName = PkcsObjectIdentifiers.Pkcs9AtUnstructuredName;
|
|
UnstructuredAddress = PkcsObjectIdentifiers.Pkcs9AtUnstructuredAddress;
|
|
E = EmailAddress;
|
|
DC = new DerObjectIdentifier("0.9.2342.19200300.100.1.25");
|
|
UID = new DerObjectIdentifier("0.9.2342.19200300.100.1.1");
|
|
bool[] array = new bool[1];
|
|
defaultReverse = array;
|
|
DefaultSymbols = new Hashtable();
|
|
RFC2253Symbols = new Hashtable();
|
|
RFC1779Symbols = new Hashtable();
|
|
DefaultLookup = new Hashtable();
|
|
DefaultSymbols.Add(C, "C");
|
|
DefaultSymbols.Add(O, "O");
|
|
DefaultSymbols.Add(T, "T");
|
|
DefaultSymbols.Add(OU, "OU");
|
|
DefaultSymbols.Add(CN, "CN");
|
|
DefaultSymbols.Add(L, "L");
|
|
DefaultSymbols.Add(ST, "ST");
|
|
DefaultSymbols.Add(SerialNumber, "SERIALNUMBER");
|
|
DefaultSymbols.Add(EmailAddress, "E");
|
|
DefaultSymbols.Add(DC, "DC");
|
|
DefaultSymbols.Add(UID, "UID");
|
|
DefaultSymbols.Add(Street, "STREET");
|
|
DefaultSymbols.Add(Surname, "SURNAME");
|
|
DefaultSymbols.Add(GivenName, "GIVENNAME");
|
|
DefaultSymbols.Add(Initials, "INITIALS");
|
|
DefaultSymbols.Add(Generation, "GENERATION");
|
|
DefaultSymbols.Add(UnstructuredAddress, "unstructuredAddress");
|
|
DefaultSymbols.Add(UnstructuredName, "unstructuredName");
|
|
DefaultSymbols.Add(UniqueIdentifier, "UniqueIdentifier");
|
|
DefaultSymbols.Add(DnQualifier, "DN");
|
|
DefaultSymbols.Add(Pseudonym, "Pseudonym");
|
|
DefaultSymbols.Add(PostalAddress, "PostalAddress");
|
|
DefaultSymbols.Add(NameAtBirth, "NameAtBirth");
|
|
DefaultSymbols.Add(CountryOfCitizenship, "CountryOfCitizenship");
|
|
DefaultSymbols.Add(CountryOfResidence, "CountryOfResidence");
|
|
DefaultSymbols.Add(Gender, "Gender");
|
|
DefaultSymbols.Add(PlaceOfBirth, "PlaceOfBirth");
|
|
DefaultSymbols.Add(DateOfBirth, "DateOfBirth");
|
|
DefaultSymbols.Add(PostalCode, "PostalCode");
|
|
DefaultSymbols.Add(BusinessCategory, "BusinessCategory");
|
|
DefaultSymbols.Add(TelephoneNumber, "TelephoneNumber");
|
|
RFC2253Symbols.Add(C, "C");
|
|
RFC2253Symbols.Add(O, "O");
|
|
RFC2253Symbols.Add(OU, "OU");
|
|
RFC2253Symbols.Add(CN, "CN");
|
|
RFC2253Symbols.Add(L, "L");
|
|
RFC2253Symbols.Add(ST, "ST");
|
|
RFC2253Symbols.Add(Street, "STREET");
|
|
RFC2253Symbols.Add(DC, "DC");
|
|
RFC2253Symbols.Add(UID, "UID");
|
|
RFC1779Symbols.Add(C, "C");
|
|
RFC1779Symbols.Add(O, "O");
|
|
RFC1779Symbols.Add(OU, "OU");
|
|
RFC1779Symbols.Add(CN, "CN");
|
|
RFC1779Symbols.Add(L, "L");
|
|
RFC1779Symbols.Add(ST, "ST");
|
|
RFC1779Symbols.Add(Street, "STREET");
|
|
DefaultLookup.Add("c", C);
|
|
DefaultLookup.Add("o", O);
|
|
DefaultLookup.Add("t", T);
|
|
DefaultLookup.Add("ou", OU);
|
|
DefaultLookup.Add("cn", CN);
|
|
DefaultLookup.Add("l", L);
|
|
DefaultLookup.Add("st", ST);
|
|
DefaultLookup.Add("serialnumber", SerialNumber);
|
|
DefaultLookup.Add("street", Street);
|
|
DefaultLookup.Add("emailaddress", E);
|
|
DefaultLookup.Add("dc", DC);
|
|
DefaultLookup.Add("e", E);
|
|
DefaultLookup.Add("uid", UID);
|
|
DefaultLookup.Add("surname", Surname);
|
|
DefaultLookup.Add("givenname", GivenName);
|
|
DefaultLookup.Add("initials", Initials);
|
|
DefaultLookup.Add("generation", Generation);
|
|
DefaultLookup.Add("unstructuredaddress", UnstructuredAddress);
|
|
DefaultLookup.Add("unstructuredname", UnstructuredName);
|
|
DefaultLookup.Add("uniqueidentifier", UniqueIdentifier);
|
|
DefaultLookup.Add("dn", DnQualifier);
|
|
DefaultLookup.Add("pseudonym", Pseudonym);
|
|
DefaultLookup.Add("postaladdress", PostalAddress);
|
|
DefaultLookup.Add("nameofbirth", NameAtBirth);
|
|
DefaultLookup.Add("countryofcitizenship", CountryOfCitizenship);
|
|
DefaultLookup.Add("countryofresidence", CountryOfResidence);
|
|
DefaultLookup.Add("gender", Gender);
|
|
DefaultLookup.Add("placeofbirth", PlaceOfBirth);
|
|
DefaultLookup.Add("dateofbirth", DateOfBirth);
|
|
DefaultLookup.Add("postalcode", PostalCode);
|
|
DefaultLookup.Add("businesscategory", BusinessCategory);
|
|
DefaultLookup.Add("telephonenumber", TelephoneNumber);
|
|
}
|
|
|
|
public static X509Name GetInstance(Asn1TaggedObject obj, bool explicitly)
|
|
{
|
|
return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
|
|
}
|
|
|
|
public static X509Name GetInstance(object obj)
|
|
{
|
|
if (obj == null || obj is X509Name)
|
|
{
|
|
return (X509Name)obj;
|
|
}
|
|
if (obj != null)
|
|
{
|
|
return new X509Name(Asn1Sequence.GetInstance(obj));
|
|
}
|
|
throw new ArgumentException("null object in factory", "obj");
|
|
}
|
|
|
|
protected X509Name()
|
|
{
|
|
}
|
|
|
|
protected X509Name(Asn1Sequence seq)
|
|
{
|
|
this.seq = seq;
|
|
foreach (Asn1Encodable item in seq)
|
|
{
|
|
Asn1Set instance = Asn1Set.GetInstance(item.ToAsn1Object());
|
|
for (int i = 0; i < instance.Count; i++)
|
|
{
|
|
Asn1Sequence instance2 = Asn1Sequence.GetInstance(instance[i].ToAsn1Object());
|
|
if (instance2.Count != 2)
|
|
{
|
|
throw new ArgumentException("badly sized pair");
|
|
}
|
|
ordering.Add(DerObjectIdentifier.GetInstance(instance2[0].ToAsn1Object()));
|
|
Asn1Object asn1Object = instance2[1].ToAsn1Object();
|
|
if (asn1Object is IAsn1String && !(asn1Object is DerUniversalString))
|
|
{
|
|
string text = ((IAsn1String)asn1Object).GetString();
|
|
if (Platform.StartsWith(text, "#"))
|
|
{
|
|
text = "\\" + text;
|
|
}
|
|
values.Add(text);
|
|
}
|
|
else
|
|
{
|
|
values.Add("#" + Hex.ToHexString(asn1Object.GetEncoded()));
|
|
}
|
|
added.Add(i != 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
public X509Name(IList ordering, IDictionary attributes)
|
|
: this(ordering, attributes, new X509DefaultEntryConverter())
|
|
{
|
|
}
|
|
|
|
public X509Name(IList ordering, IDictionary attributes, X509NameEntryConverter converter)
|
|
{
|
|
this.converter = converter;
|
|
foreach (DerObjectIdentifier item in ordering)
|
|
{
|
|
object obj = attributes[item];
|
|
if (obj == null)
|
|
{
|
|
throw new ArgumentException(string.Concat("No attribute for object id - ", item, " - passed to distinguished name"));
|
|
}
|
|
this.ordering.Add(item);
|
|
added.Add(false);
|
|
values.Add(obj);
|
|
}
|
|
}
|
|
|
|
public X509Name(IList oids, IList values)
|
|
: this(oids, values, new X509DefaultEntryConverter())
|
|
{
|
|
}
|
|
|
|
public X509Name(IList oids, IList values, X509NameEntryConverter converter)
|
|
{
|
|
this.converter = converter;
|
|
if (oids.Count != values.Count)
|
|
{
|
|
throw new ArgumentException("'oids' must be same length as 'values'.");
|
|
}
|
|
for (int i = 0; i < oids.Count; i++)
|
|
{
|
|
ordering.Add(oids[i]);
|
|
this.values.Add(values[i]);
|
|
added.Add(false);
|
|
}
|
|
}
|
|
|
|
public X509Name(string dirName)
|
|
: this(DefaultReverse, DefaultLookup, dirName)
|
|
{
|
|
}
|
|
|
|
public X509Name(string dirName, X509NameEntryConverter converter)
|
|
: this(DefaultReverse, DefaultLookup, dirName, converter)
|
|
{
|
|
}
|
|
|
|
public X509Name(bool reverse, string dirName)
|
|
: this(reverse, DefaultLookup, dirName)
|
|
{
|
|
}
|
|
|
|
public X509Name(bool reverse, string dirName, X509NameEntryConverter converter)
|
|
: this(reverse, DefaultLookup, dirName, converter)
|
|
{
|
|
}
|
|
|
|
public X509Name(bool reverse, IDictionary lookUp, string dirName)
|
|
: this(reverse, lookUp, dirName, new X509DefaultEntryConverter())
|
|
{
|
|
}
|
|
|
|
private DerObjectIdentifier DecodeOid(string name, IDictionary lookUp)
|
|
{
|
|
if (Platform.StartsWith(Platform.ToUpperInvariant(name), "OID."))
|
|
{
|
|
return new DerObjectIdentifier(name.Substring(4));
|
|
}
|
|
if (name[0] >= '0' && name[0] <= '9')
|
|
{
|
|
return new DerObjectIdentifier(name);
|
|
}
|
|
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)lookUp[Platform.ToLowerInvariant(name)];
|
|
if (derObjectIdentifier == null)
|
|
{
|
|
throw new ArgumentException("Unknown object id - " + name + " - passed to distinguished name");
|
|
}
|
|
return derObjectIdentifier;
|
|
}
|
|
|
|
public X509Name(bool reverse, IDictionary lookUp, string dirName, X509NameEntryConverter converter)
|
|
{
|
|
this.converter = converter;
|
|
X509NameTokenizer x509NameTokenizer = new X509NameTokenizer(dirName);
|
|
while (x509NameTokenizer.HasMoreTokens())
|
|
{
|
|
string text = x509NameTokenizer.NextToken();
|
|
int num = text.IndexOf('=');
|
|
if (num == -1)
|
|
{
|
|
throw new ArgumentException("badly formated directory string");
|
|
}
|
|
string name = text.Substring(0, num);
|
|
string text2 = text.Substring(num + 1);
|
|
DerObjectIdentifier value = DecodeOid(name, lookUp);
|
|
if (text2.IndexOf('+') > 0)
|
|
{
|
|
X509NameTokenizer x509NameTokenizer2 = new X509NameTokenizer(text2, '+');
|
|
string value2 = x509NameTokenizer2.NextToken();
|
|
ordering.Add(value);
|
|
values.Add(value2);
|
|
added.Add(false);
|
|
while (x509NameTokenizer2.HasMoreTokens())
|
|
{
|
|
string text3 = x509NameTokenizer2.NextToken();
|
|
int num2 = text3.IndexOf('=');
|
|
string name2 = text3.Substring(0, num2);
|
|
string value3 = text3.Substring(num2 + 1);
|
|
ordering.Add(DecodeOid(name2, lookUp));
|
|
values.Add(value3);
|
|
added.Add(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ordering.Add(value);
|
|
values.Add(text2);
|
|
added.Add(false);
|
|
}
|
|
}
|
|
if (!reverse)
|
|
{
|
|
return;
|
|
}
|
|
IList list = Platform.CreateArrayList();
|
|
IList list2 = Platform.CreateArrayList();
|
|
IList list3 = Platform.CreateArrayList();
|
|
int num3 = 1;
|
|
for (int i = 0; i < ordering.Count; i++)
|
|
{
|
|
if (!(bool)added[i])
|
|
{
|
|
num3 = 0;
|
|
}
|
|
int index = num3++;
|
|
list.Insert(index, ordering[i]);
|
|
list2.Insert(index, values[i]);
|
|
list3.Insert(index, added[i]);
|
|
}
|
|
ordering = list;
|
|
values = list2;
|
|
added = list3;
|
|
}
|
|
|
|
public IList GetOidList()
|
|
{
|
|
return Platform.CreateArrayList(ordering);
|
|
}
|
|
|
|
public IList GetValueList()
|
|
{
|
|
return GetValueList(null);
|
|
}
|
|
|
|
public IList GetValueList(DerObjectIdentifier oid)
|
|
{
|
|
IList list = Platform.CreateArrayList();
|
|
for (int i = 0; i != values.Count; i++)
|
|
{
|
|
if (oid == null || oid.Equals(ordering[i]))
|
|
{
|
|
string text = (string)values[i];
|
|
if (Platform.StartsWith(text, "\\#"))
|
|
{
|
|
text = text.Substring(1);
|
|
}
|
|
list.Add(text);
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public override Asn1Object ToAsn1Object()
|
|
{
|
|
if (seq == null)
|
|
{
|
|
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
|
|
Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector();
|
|
DerObjectIdentifier derObjectIdentifier = null;
|
|
for (int i = 0; i != ordering.Count; i++)
|
|
{
|
|
DerObjectIdentifier derObjectIdentifier2 = (DerObjectIdentifier)ordering[i];
|
|
string value = (string)values[i];
|
|
if (derObjectIdentifier != null && !(bool)added[i])
|
|
{
|
|
asn1EncodableVector.Add(new DerSet(asn1EncodableVector2));
|
|
asn1EncodableVector2 = new Asn1EncodableVector();
|
|
}
|
|
asn1EncodableVector2.Add(new DerSequence(derObjectIdentifier2, converter.GetConvertedValue(derObjectIdentifier2, value)));
|
|
derObjectIdentifier = derObjectIdentifier2;
|
|
}
|
|
asn1EncodableVector.Add(new DerSet(asn1EncodableVector2));
|
|
seq = new DerSequence(asn1EncodableVector);
|
|
}
|
|
return seq;
|
|
}
|
|
|
|
public bool Equivalent(X509Name other, bool inOrder)
|
|
{
|
|
if (!inOrder)
|
|
{
|
|
return Equivalent(other);
|
|
}
|
|
if (other == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (other == this)
|
|
{
|
|
return true;
|
|
}
|
|
int count = ordering.Count;
|
|
if (count != other.ordering.Count)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)ordering[i];
|
|
DerObjectIdentifier obj = (DerObjectIdentifier)other.ordering[i];
|
|
if (!derObjectIdentifier.Equals(obj))
|
|
{
|
|
return false;
|
|
}
|
|
string s = (string)values[i];
|
|
string s2 = (string)other.values[i];
|
|
if (!equivalentStrings(s, s2))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public bool Equivalent(X509Name other)
|
|
{
|
|
if (other == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (other == this)
|
|
{
|
|
return true;
|
|
}
|
|
int count = ordering.Count;
|
|
if (count != other.ordering.Count)
|
|
{
|
|
return false;
|
|
}
|
|
bool[] array = new bool[count];
|
|
int num;
|
|
int num2;
|
|
int num3;
|
|
if (ordering[0].Equals(other.ordering[0]))
|
|
{
|
|
num = 0;
|
|
num2 = count;
|
|
num3 = 1;
|
|
}
|
|
else
|
|
{
|
|
num = count - 1;
|
|
num2 = -1;
|
|
num3 = -1;
|
|
}
|
|
for (int i = num; i != num2; i += num3)
|
|
{
|
|
bool flag = false;
|
|
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)ordering[i];
|
|
string s = (string)values[i];
|
|
for (int j = 0; j < count; j++)
|
|
{
|
|
if (array[j])
|
|
{
|
|
continue;
|
|
}
|
|
DerObjectIdentifier obj = (DerObjectIdentifier)other.ordering[j];
|
|
if (derObjectIdentifier.Equals(obj))
|
|
{
|
|
string s2 = (string)other.values[j];
|
|
if (equivalentStrings(s, s2))
|
|
{
|
|
array[j] = true;
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool equivalentStrings(string s1, string s2)
|
|
{
|
|
string text = canonicalize(s1);
|
|
string text2 = canonicalize(s2);
|
|
if (!text.Equals(text2))
|
|
{
|
|
text = stripInternalSpaces(text);
|
|
text2 = stripInternalSpaces(text2);
|
|
if (!text.Equals(text2))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static string canonicalize(string s)
|
|
{
|
|
string text = Platform.ToLowerInvariant(s).Trim();
|
|
if (Platform.StartsWith(text, "#"))
|
|
{
|
|
Asn1Object asn1Object = decodeObject(text);
|
|
if (asn1Object is IAsn1String)
|
|
{
|
|
text = Platform.ToLowerInvariant(((IAsn1String)asn1Object).GetString()).Trim();
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private static Asn1Object decodeObject(string v)
|
|
{
|
|
try
|
|
{
|
|
return Asn1Object.FromByteArray(Hex.Decode(v.Substring(1)));
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
throw new InvalidOperationException("unknown encoding in name: " + ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
private static string stripInternalSpaces(string str)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
if (str.Length != 0)
|
|
{
|
|
char c = str[0];
|
|
stringBuilder.Append(c);
|
|
for (int i = 1; i < str.Length; i++)
|
|
{
|
|
char c2 = str[i];
|
|
if (c != ' ' || c2 != ' ')
|
|
{
|
|
stringBuilder.Append(c2);
|
|
}
|
|
c = c2;
|
|
}
|
|
}
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
private void AppendValue(StringBuilder buf, IDictionary oidSymbols, DerObjectIdentifier oid, string val)
|
|
{
|
|
string text = (string)oidSymbols[oid];
|
|
if (text != null)
|
|
{
|
|
buf.Append(text);
|
|
}
|
|
else
|
|
{
|
|
buf.Append(oid.Id);
|
|
}
|
|
buf.Append('=');
|
|
int i = buf.Length;
|
|
buf.Append(val);
|
|
int num = buf.Length;
|
|
if (Platform.StartsWith(val, "\\#"))
|
|
{
|
|
i += 2;
|
|
}
|
|
for (; i != num; i++)
|
|
{
|
|
if (buf[i] == ',' || buf[i] == '"' || buf[i] == '\\' || buf[i] == '+' || buf[i] == '=' || buf[i] == '<' || buf[i] == '>' || buf[i] == ';')
|
|
{
|
|
buf.Insert(i++, "\\");
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
public string ToString(bool reverse, IDictionary oidSymbols)
|
|
{
|
|
ArrayList arrayList = new ArrayList();
|
|
StringBuilder stringBuilder = null;
|
|
for (int i = 0; i < ordering.Count; i++)
|
|
{
|
|
if ((bool)added[i])
|
|
{
|
|
stringBuilder.Append('+');
|
|
AppendValue(stringBuilder, oidSymbols, (DerObjectIdentifier)ordering[i], (string)values[i]);
|
|
}
|
|
else
|
|
{
|
|
stringBuilder = new StringBuilder();
|
|
AppendValue(stringBuilder, oidSymbols, (DerObjectIdentifier)ordering[i], (string)values[i]);
|
|
arrayList.Add(stringBuilder);
|
|
}
|
|
}
|
|
if (reverse)
|
|
{
|
|
arrayList.Reverse();
|
|
}
|
|
StringBuilder stringBuilder2 = new StringBuilder();
|
|
if (arrayList.Count > 0)
|
|
{
|
|
stringBuilder2.Append(arrayList[0].ToString());
|
|
for (int j = 1; j < arrayList.Count; j++)
|
|
{
|
|
stringBuilder2.Append(',');
|
|
stringBuilder2.Append(arrayList[j].ToString());
|
|
}
|
|
}
|
|
return stringBuilder2.ToString();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ToString(DefaultReverse, DefaultSymbols);
|
|
}
|
|
}
|