199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.compackage org.bouncycastle.asn1.x509;
299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport java.io.IOException;
499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport java.util.Enumeration;
599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport java.util.Hashtable;
699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport java.util.Vector;
799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Encodable;
999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1EncodableVector;
1099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Encoding;
1199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Object;
1299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
1399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Primitive;
1499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Sequence;
1599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1Set;
1699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1String;
1799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.asn1.ASN1TaggedObject;
18048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.comimport org.bouncycastle.asn1.DERSequence;
19048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.comimport org.bouncycastle.asn1.DERSet;
20048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.comimport org.bouncycastle.asn1.DERUniversalString;
21048e632be7693f6198bfdd54130a0220a2ccb5abrtoy@google.comimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
2256df947c78b5c65a7d3bc558287602c83ccc793artoy@google.comimport org.bouncycastle.asn1.x500.X500Name;
2399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.comimport org.bouncycastle.util.Strings;
244512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.orgimport org.bouncycastle.util.encoders.Hex;
2599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
2699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com/**
27160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com * <pre>
28160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *     RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
29160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *
30160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *     RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
31160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *
32160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *     AttributeTypeAndValue ::= SEQUENCE {
33160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *                                   type  OBJECT IDENTIFIER,
34160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com *                                   value ANY }
35160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com * </pre>
36160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com * @deprecated use org.bouncycastle.asn1.x500.X500Name.
37160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com */
38160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.compublic class X509Name
39160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    extends ASN1Object
40160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com{
41160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
42160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * country code - StringType(SIZE(2))
43160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * @deprecated use a X500NameStyle
44160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     */
45160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6");
46160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
47160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
48160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * organization - StringType(SIZE(1..64))
494512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @deprecated use a X500NameStyle
504512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10");
524512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
534512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
544d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com     * organizational unit name - StringType(SIZE(1..64))
5599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use a X500NameStyle
5699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
5799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11");
58160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
59160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
6099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Title
6199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use a X500NameStyle
6299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
63160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12");
64160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
654512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
664512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * common name - StringType(SIZE(1..64))
674512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @deprecated use a X500NameStyle
6899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
694512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3");
7099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
71160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
72160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * device serial number name - StringType(SIZE(1..64))
73160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     */
7499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5");
7599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
7699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
77160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * street - StringType(SIZE(1..64))
7899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
7999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9");
8099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
8199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
8299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * device serial number name - StringType(SIZE(1..64))
8399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
8499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier SERIALNUMBER = SN;
8599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
8699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
8756df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com     * locality name - StringType(SIZE(1..64))
8899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
894512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7");
904512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
914512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
9299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * state, or province name - StringType(SIZE(1..64))
9399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
94160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8");
95160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
96160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
97160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * Naming attributes of type X520name
98160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     */
994512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4");
1004512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42");
1014512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43");
1024512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44");
103d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org    public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45");
104d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org
105d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org    /**
106d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org     * businessCategory - DirectoryString(SIZE(1..128)
107d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org     */
108d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org    public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier(
109d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org                    "2.5.4.15");
1104512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
1114512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
1124512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * postalCode - DirectoryString(SIZE(1..40)
1134512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1144512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier(
1154d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com                    "2.5.4.17");
1164512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
117160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
118160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * dnQualifier - DirectoryString(SIZE(1..64)
1194512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1204512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier(
1214512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    "2.5.4.46");
1224512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
123160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
124160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
1254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1264512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier(
1274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    "2.5.4.65");
1284512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
1294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
1304512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
1314512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
1324512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1334512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier(
1344512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    "1.3.6.1.5.5.7.9.1");
1354512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
1364512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
1374512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
1384512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1394512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier(
14099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    "1.3.6.1.5.5.7.9.2");
14199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
14299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
143d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org     * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
14456df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com     */
14599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier(
1464512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    "1.3.6.1.5.5.7.9.3");
14799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
14899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
14999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
15099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * codes only
15199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
15299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier(
15399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    "1.3.6.1.5.5.7.9.4");
15499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
15599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
15699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166
15799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * codes only
15899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
15999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier(
16099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    "1.3.6.1.5.5.7.9.5");
16199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
16299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
16399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
16499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64)
16599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
16699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier NAME_AT_BIRTH =  new ASN1ObjectIdentifier("1.3.36.8.3.14");
16799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
16899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
16999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF
17099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * DirectoryString(SIZE(1..30))
17199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
17299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16");
17399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
17499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
17599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * RFC 2256 dmdName
17699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
17799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54");
17899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
17999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
18099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * id-at-telephoneNumber
18199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
18299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber;
18399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
18499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
18599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * id-at-name
18699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
18799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name;
18899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
18999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
19099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Email address (RSA PKCS#9 extension) - IA5String.
19199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here.
19299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use a X500NameStyle
19399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
19499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress;
19599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
19699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
19799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * more from PKCS#9
19899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
19999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName;
20099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress;
20199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
20299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
20399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * email address in Verisign certificates
20499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
20599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier E = EmailAddress;
20699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
20799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /*
20899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * others...
20999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
21099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25");
21199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
21299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
21399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * LDAP User id.
21499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
21599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
21699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
21799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
21899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * determines whether or not strings should be processed and printed
21999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * from back to front.
2204d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com     */
22199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static boolean DefaultReverse = false;
222160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
22399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
224160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * default look up table translating OID values into their common symbols following
2254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * the convention in RFC 2253 with a few extras
22699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
2274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final Hashtable DefaultSymbols = new Hashtable();
22899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
229160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
23099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * look up table translating OID values into their common symbols following the convention in RFC 2253
23199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     *
2324d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com     */
23399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final Hashtable RFC2253Symbols = new Hashtable();
23499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
23599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
236160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * look up table translating OID values into their common symbols following the convention in RFC 1779
23799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     *
23899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
23999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final Hashtable RFC1779Symbols = new Hashtable();
240160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
24199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
2424512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * look up table translating common symbols into their OIDS.
24399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
24499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final Hashtable DefaultLookUp = new Hashtable();
2454512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
2464512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
24799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * look up table translating OID values into their common symbols
24899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use DefaultSymbols
2494512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
2504512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public static final Hashtable OIDLookUp = DefaultSymbols;
2514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
25299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
25399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * look up table translating string values into their OIDS -
254160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     * @deprecated use DefaultLookUp
25599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
25699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static final Hashtable SymbolLookUp = DefaultLookUp;
25799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
25899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    // BEGIN android-changed
25999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private static final Boolean TRUE = Boolean.TRUE;
26056df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com    private static final Boolean FALSE = Boolean.FALSE;
26156df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com    // END android-changed
26299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
26399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    static
26499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
26599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(C, "C");
26699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(O, "O");
26799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(T, "T");
26899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(OU, "OU");
26999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(CN, "CN");
27099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(L, "L");
27199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(ST, "ST");
27299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(SN, "SERIALNUMBER");
27399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(EmailAddress, "E");
27499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(DC, "DC");
27599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(UID, "UID");
27699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(STREET, "STREET");
27799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(SURNAME, "SURNAME");
27899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(GIVENNAME, "GIVENNAME");
27999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(INITIALS, "INITIALS");
280160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(GENERATION, "GENERATION");
281160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress");
282160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(UnstructuredName, "unstructuredName");
283160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier");
284160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(DN_QUALIFIER, "DN");
285160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(PSEUDONYM, "Pseudonym");
286160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress");
287160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth");
288160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship");
289160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence");
290160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultSymbols.put(GENDER, "Gender");
29199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth");
29299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth");
29399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(POSTAL_CODE, "PostalCode");
29499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory");
29599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber");
29699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultSymbols.put(NAME, "Name");
29799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
29899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(C, "C");
29999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(O, "O");
30099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(OU, "OU");
30199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(CN, "CN");
30299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(L, "L");
30399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(ST, "ST");
30499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(STREET, "STREET");
30599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(DC, "DC");
30699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC2253Symbols.put(UID, "UID");
30799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
30899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(C, "C");
30999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(O, "O");
31099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(OU, "OU");
31199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(CN, "CN");
31299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(L, "L");
31399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(ST, "ST");
31499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        RFC1779Symbols.put(STREET, "STREET");
31599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
31699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("c", C);
31799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("o", O);
31899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("t", T);
31999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("ou", OU);
32099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("cn", CN);
32199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("l", L);
32299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("st", ST);
32399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("sn", SN);
32499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("serialnumber", SN);
325160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        DefaultLookUp.put("street", STREET);
3264d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com        DefaultLookUp.put("emailaddress", E);
32799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("dc", DC);
32899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("e", E);
32999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("uid", UID);
33099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("surname", SURNAME);
33199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("givenname", GIVENNAME);
33299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("initials", INITIALS);
33399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("generation", GENERATION);
33499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("unstructuredaddress", UnstructuredAddress);
33599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("unstructuredname", UnstructuredName);
33699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER);
33799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("dn", DN_QUALIFIER);
33899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("pseudonym", PSEUDONYM);
33999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("postaladdress", POSTAL_ADDRESS);
34099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH);
34199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP);
34299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE);
34399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("gender", GENDER);
34499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH);
34599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH);
34699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("postalcode", POSTAL_CODE);
34799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY);
34899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER);
34999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        DefaultLookUp.put("name", NAME);
35099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
35199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
35299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private X509NameEntryConverter  converter = null;
35399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private Vector                  ordering = new Vector();
35499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private Vector                  values = new Vector();
35599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private Vector                  added = new Vector();
35699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
35799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private ASN1Sequence            seq;
35899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
35999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private boolean                 isHashCodeCalculated;
36099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private int                     hashCodeValue;
36199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
36299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
36399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Return a X509Name based on the passed in tagged object.
36499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     *
36599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param obj tag object holding name.
36699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param explicit true if explicitly tagged false otherwise.
36799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @return the X509Name
36899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
36999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static X509Name getInstance(
37099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1TaggedObject obj,
37156df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com        boolean          explicit)
37299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
37399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return getInstance(ASN1Sequence.getInstance(obj, explicit));
37499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
37599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
37699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public static X509Name getInstance(
37799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Object  obj)
37899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
37999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (obj == null || obj instanceof X509Name)
38099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
38199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return (X509Name)obj;
38299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
38356df947c78b5c65a7d3bc558287602c83ccc793artoy@google.com        else if (obj instanceof X500Name)
38499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
38599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return new X509Name(ASN1Sequence.getInstance(((X500Name)obj).toASN1Primitive()));
38699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
38799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else if (obj != null)
38899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
38999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return new X509Name(ASN1Sequence.getInstance(obj));
39099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
39199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
39299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return null;
39399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
39499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
39599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    protected X509Name()
39699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
39799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        // constructure use by new X500 Name class
39899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
39999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
40099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Constructor from ASN1Sequence
40199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     *
40299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * the principal will be a list of constructed sets, each containing an (OID, String) pair.
40399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name.getInstance()
404160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com     */
40599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
40699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1Sequence  seq)
40799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
40899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this.seq = seq;
40999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
41099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Enumeration e = seq.getObjects();
411160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
41299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        while (e.hasMoreElements())
41399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
41499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1Set         set = ASN1Set.getInstance(((ASN1Encodable)e.nextElement()).toASN1Primitive());
41599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
41699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int i = 0; i < set.size(); i++)
41799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
41899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   ASN1Sequence s = ASN1Sequence.getInstance(set.getObjectAt(i).toASN1Primitive());
41999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
42099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   if (s.size() != 2)
42199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   {
42299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       throw new IllegalArgumentException("badly sized pair");
42399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   }
42499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
42599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   ordering.addElement(ASN1ObjectIdentifier.getInstance(s.getObjectAt(0)));
42699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
42799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   ASN1Encodable value = s.getObjectAt(1);
42899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   if (value instanceof ASN1String && !(value instanceof DERUniversalString))
42999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   {
43099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       String v = ((ASN1String)value).getString();
43199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       if (v.length() > 0 && v.charAt(0) == '#')
43299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       {
43399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                           values.addElement("\\" + v);
43499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       }
43599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       else
43699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       {
43799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                           values.addElement(v);
43899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       }
43999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   }
44099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   else
44199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   {
44299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       try
44399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       {
44499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                           values.addElement("#" + bytesToString(Hex.encode(value.toASN1Primitive().getEncoded(ASN1Encoding.DER))));
44599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       }
44699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       catch (IOException e1)
44799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       {
44899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                           throw new IllegalArgumentException("cannot encode value");
44999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                       }
45099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   }
45199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   // BEGIN android-changed
45299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   added.addElement(Boolean.valueOf(i != 0));
45399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                   // END android-changed
45499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
45599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
45699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
45799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
45899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
45999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * constructor from a table of attributes.
46099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
46199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * it's is assumed the table contains OID/String pairs, and the contents
46299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * of the table are copied into an internal table as part of the
46399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * construction process.
46499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
46599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <b>Note:</b> if the name you are trying to generate should be
46699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * following a specific ordering, you should use the constructor
46799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * with the ordering specified below.
46899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use an ordered constructor! The hashtable ordering is rarely correct
46999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
47099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
47199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable  attributes)
47299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
47399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(null, attributes);
47499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
47599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
47699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
47799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Constructor from a table of attributes with ordering.
47899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
47999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * it's is assumed the table contains OID/String pairs, and the contents
48099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * of the table are copied into an internal table as part of the
48199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * construction process. The ordering vector should contain the OIDs
48299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * in the order they are meant to be encoded or printed in toString.
48399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
48499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
48599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector      ordering,
48699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable   attributes)
48799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
48899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(ordering, attributes, new X509DefaultEntryConverter());
48999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
49099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
491160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    /**
49299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Constructor from a table of attributes with ordering.
49399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
49499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * it's is assumed the table contains OID/String pairs, and the contents
49599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * of the table are copied into an internal table as part of the
49699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * construction process. The ordering vector should contain the OIDs
49799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * in the order they are meant to be encoded or printed in toString.
49899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
49999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * The passed in converter will be used to convert the strings into their
50099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * ASN.1 counterparts.
50199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
50299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
503160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    public X509Name(
50499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector                   ordering,
50599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable                attributes,
50699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        X509NameEntryConverter   converter)
50799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
50899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this.converter = converter;
50999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
51099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (ordering != null)
51199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
51299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int i = 0; i != ordering.size(); i++)
51399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
51499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                this.ordering.addElement(ordering.elementAt(i));
51599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                this.added.addElement(FALSE);
51699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
51799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
51899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else
51999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
52099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            Enumeration     e = attributes.keys();
52199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
52299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            while (e.hasMoreElements())
523160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com            {
524160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com                this.ordering.addElement(e.nextElement());
52599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                this.added.addElement(FALSE);
52699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
52799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
52899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
52999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i != this.ordering.size(); i++)
53099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
531160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com            ASN1ObjectIdentifier     oid = (ASN1ObjectIdentifier)this.ordering.elementAt(i);
53299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
53399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (attributes.get(oid) == null)
53499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
53599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                throw new IllegalArgumentException("No attribute for object id - " + oid.getId() + " - passed to distinguished name");
53699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
53799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
53899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            this.values.addElement(attributes.get(oid)); // copy the hash table
53999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
54099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
54199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
54299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
54399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes two vectors one of the oids and the other of the values.
54499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
54599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
54699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
54799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector  oids,
54899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector  values)
54999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
55099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(oids, values, new X509DefaultEntryConverter());
55199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
55299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
55399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
55499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes two vectors one of the oids and the other of the values.
55599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <p>
55699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * The passed in converter will be used to convert the strings into their
55799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * ASN.1 counterparts.
55899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
55999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
56099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
56199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector                  oids,
56299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector                  values,
56399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        X509NameEntryConverter  converter)
56499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
56599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this.converter = converter;
56699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
56799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (oids.size() != values.size())
56899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
56999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            throw new IllegalArgumentException("oids vector must be same length as values.");
57099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
57199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
57299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i < oids.size(); i++)
57399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
57499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            this.ordering.addElement(oids.elementAt(i));
57599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            this.values.addElement(values.elementAt(i));
57699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            this.added.addElement(FALSE);
57799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
57899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
57999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
58099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//    private Boolean isEncoded(String s)
58199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//    {
58299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//        if (s.charAt(0) == '#')
58399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//        {
58499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//            return TRUE;
58599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//        }
58699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//
58799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//        return FALSE;
58899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com//    }
58999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
59099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
59199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
59299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * some such, converting it into an ordered set of name attributes.
59399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
59499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
59599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
59699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String  dirName)
59799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
59899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(DefaultReverse, DefaultLookUp, dirName);
59999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
60099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
60199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
60299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
60399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * some such, converting it into an ordered set of name attributes with each
60499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * string value being converted to its associated ASN.1 type using the passed
60599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * in converter.
60699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
60799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
60899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
60999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String                  dirName,
61099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        X509NameEntryConverter  converter)
61199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
61299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(DefaultReverse, DefaultLookUp, dirName, converter);
61399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
61499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
61599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
61699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
61799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * some such, converting it into an ordered set of name attributes. If reverse
61899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * is true, create the encoded version of the sequence starting from the
61999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * last element in the string.
62099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
62199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
62299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
62399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean reverse,
62499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String  dirName)
62599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
62699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(reverse, DefaultLookUp, dirName);
62799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
62899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
62999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
63099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
63199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * some such, converting it into an ordered set of name attributes with each
63299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * string value being converted to its associated ASN.1 type using the passed
63399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * in converter. If reverse is true the ASN.1 sequence representing the DN will
63499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * be built by starting at the end of the string, rather than the start.
63599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
63699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
63799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
63899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean                 reverse,
63999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String                  dirName,
64099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        X509NameEntryConverter  converter)
64199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
64299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(reverse, DefaultLookUp, dirName, converter);
64399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
64499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
64599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
64699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
64799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * some such, converting it into an ordered set of name attributes. lookUp
64899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * should provide a table of lookups, indexed by lowercase only strings and
64999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids
65099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * will be processed automatically.
65199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * <br>
65299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * If reverse is true, create the encoded version of the sequence
65399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * starting from the last element in the string.
65499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param reverse true if we should start scanning from the end (RFC 2553).
65599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param lookUp table of names and their oids.
65699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param dirName the X.500 string to be parsed.
65799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @deprecated use X500Name, X500NameBuilder
65899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
65999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public X509Name(
66099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean     reverse,
66199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable   lookUp,
66299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String      dirName)
66399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
66499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        this(reverse, lookUp, dirName, new X509DefaultEntryConverter());
66599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
66699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
66799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private ASN1ObjectIdentifier decodeOID(
66899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String      name,
66999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable   lookUp)
67099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
67199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        name = name.trim();
67299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (Strings.toUpperCase(name).startsWith("OID."))
67399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
67499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return new ASN1ObjectIdentifier(name.substring(4));
67599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
67699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
67799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
67899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return new ASN1ObjectIdentifier(name);
67999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
68099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
68199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
68299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (oid == null)
68399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
68499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
68599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
68699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
68799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return oid;
68899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
68999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
69099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private String unescape(String elt)
69199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
69299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (elt.length() == 0 || (elt.indexOf('\\') < 0 && elt.indexOf('"') < 0))
69399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
69499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return elt.trim();
69599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
69699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
69799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        char[] elts = elt.toCharArray();
69899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean escaped = false;
69999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean quoted = false;
70099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        StringBuffer buf = new StringBuffer(elt.length());
70199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        int start = 0;
70299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
70399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        // if it's an escaped hash string and not an actual encoding in string form
70499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        // we need to leave it escaped.
70599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (elts[0] == '\\')
706160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        {
70799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (elts[1] == '#')
70899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
70999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                start = 2;
71099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                buf.append("\\#");
71199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
71299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
71399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
7144512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        boolean nonWhiteSpaceEncountered = false;
7154512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        int     lastEscaped = 0;
7164512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7174512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        for (int i = start; i != elts.length; i++)
7184512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
7194512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            char c = elts[i];
7204512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7214512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            if (c != ' ')
7224512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7234512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                nonWhiteSpaceEncountered = true;
7244512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
7254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7264512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            if (c == '"')
7274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7284512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                if (!escaped)
7294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
7304512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    quoted = !quoted;
7314512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
7324512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                else
7334512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
7344512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    buf.append(c);
7354512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
7364512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                escaped = false;
7374512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
7384512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            else if (c == '\\' && !(escaped || quoted))
7394512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7404512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                escaped = true;
7414512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                lastEscaped = buf.length();
7424512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
7434512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            else
7444512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7454512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                if (c == ' ' && !escaped && !nonWhiteSpaceEncountered)
7464512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
7474512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    continue;
7484512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
7494512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                buf.append(c);
7504512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                escaped = false;
7514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
7524512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
7534512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7544512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (buf.length() > 0)
7554512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
7564512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            while (buf.charAt(buf.length() - 1) == ' ' && lastEscaped != (buf.length() - 1))
7574512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7584512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                buf.setLength(buf.length() - 1);
7594512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
7604512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
7614512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7624512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        return buf.toString();
7634512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    }
7644512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7654512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
7664512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * Takes an X509 dir name as a string of the format "C=AU, ST=Victoria", or
7674512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * some such, converting it into an ordered set of name attributes. lookUp
7684512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * should provide a table of lookups, indexed by lowercase only strings and
7694512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * yielding a ASN1ObjectIdentifier, other than that OID. and numeric oids
7704512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * will be processed automatically. The passed in converter is used to convert the
7714512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * string values to the right of each equals sign to their ASN.1 counterparts.
7724512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * <br>
7734512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @param reverse true if we should start scanning from the end, false otherwise.
7744512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @param lookUp table of names and oids.
7754512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @param dirName the string dirName
7764512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * @param converter the converter to convert string values into their ASN.1 equivalents
7774512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
7784512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public X509Name(
7794512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        boolean                 reverse,
7804512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        Hashtable               lookUp,
7814512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        String                  dirName,
7824512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        X509NameEntryConverter  converter)
7834512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    {
7844512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        this.converter = converter;
7854512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        X509NameTokenizer   nTok = new X509NameTokenizer(dirName);
7864512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7874512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        while (nTok.hasMoreTokens())
7884512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
7894512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            String  token = nTok.nextToken();
7904512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7914512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            if (token.indexOf('+') > 0)
7924512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
7934512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                X509NameTokenizer   pTok = new X509NameTokenizer(token, '+');
7944512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7954512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                addEntry(lookUp, pTok.nextToken(), FALSE);
7964512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
7974512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                while (pTok.hasMoreTokens())
7984512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
7994512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    addEntry(lookUp, pTok.nextToken(), TRUE);
8004512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
8014512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
802d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org            else
8034512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
8044512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                addEntry(lookUp, token, FALSE);
8054512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
8064512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
8074512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8084512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (reverse)
8094512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
8104512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            Vector  o = new Vector();
8114512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            Vector  v = new Vector();
8124512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            Vector  a = new Vector();
8134512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8144512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            int count = 1;
8154512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8164512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            for (int i = 0; i < this.ordering.size(); i++)
8174512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
8184512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                if (((Boolean)this.added.elementAt(i)).booleanValue())
8194512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
8204512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    o.insertElementAt(this.ordering.elementAt(i), count);
8214512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    v.insertElementAt(this.values.elementAt(i), count);
8224512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    a.insertElementAt(this.added.elementAt(i), count);
8234512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    count++;
8244512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
8254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                else
8264512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
8274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    o.insertElementAt(this.ordering.elementAt(i), 0);
8284512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    v.insertElementAt(this.values.elementAt(i), 0);
8294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    a.insertElementAt(this.added.elementAt(i), 0);
8304512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    count = 1;
8314512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                }
8324512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
8334512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8344512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            this.ordering = o;
8354512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            this.values = v;
8364512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            this.added = a;
8374512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
8384512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    }
8394512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8404512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    private void addEntry(Hashtable lookUp, String token, Boolean isAdded)
8414512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    {
8424512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        X509NameTokenizer vTok;
8434512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        String name;
8444512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        String value;ASN1ObjectIdentifier oid;
845d1f914121e8d05ffc3e2cf5f1c9d96ffb7c99ae6kma@webrtc.org        vTok = new X509NameTokenizer(token, '=');
8464512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8474512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        name = vTok.nextToken();
8484512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8494512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (!vTok.hasMoreTokens())
8504512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
8514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org           throw new IllegalArgumentException("badly formatted directory string");
8524512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
8534512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8544512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        value = vTok.nextToken();
8554512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8564512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        oid = decodeOID(name, lookUp);
8574512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8584512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        this.ordering.addElement(oid);
8594512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        this.values.addElement(unescape(value));
8604512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        this.added.addElement(isAdded);
8614512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    }
8624512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8634512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
8644512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * return a vector of the oids in the name, in the order they were found.
8654512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
8664512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public Vector getOIDs()
8674512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    {
8684512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        Vector  v = new Vector();
8694512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8704512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        for (int i = 0; i != ordering.size(); i++)
8714512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
8724512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            v.addElement(ordering.elementAt(i));
8734512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
8744512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8754512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        return v;
8764512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    }
8774512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8784512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
8794512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * return a vector of the values found in the name, in the order they
8804512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * were found.
8814512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
8824512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    public Vector getValues()
8834512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    {
8844512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        Vector  v = new Vector();
8854512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8864512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        for (int i = 0; i != values.size(); i++)
8874512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
888160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com            v.addElement(values.elementAt(i));
8894512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
8904512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8914512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        return v;
8924512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    }
8934512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
8944512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    /**
8954512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     * return a vector of the values found in the name, in the order they
89699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * were found, with the DN label corresponding to passed in oid.
89799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
89899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public Vector getValues(
89999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1ObjectIdentifier oid)
90099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
90199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector  v = new Vector();
90299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
90399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i != values.size(); i++)
90499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
90599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (ordering.elementAt(i).equals(oid))
90699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
90799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                String val = (String)values.elementAt(i);
90899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
90999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (val.length() > 2 && val.charAt(0) == '\\' && val.charAt(1) == '#')
91099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
91199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    v.addElement(val.substring(1));
91299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
91399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                else
91499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
91599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    v.addElement(val);
91699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
91799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
91899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
91999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
92099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return v;
92199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
92299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
92399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public ASN1Primitive toASN1Primitive()
9244512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org    {
9254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (seq == null)
9264512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
9274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            ASN1EncodableVector  vec = new ASN1EncodableVector();
92899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1EncodableVector  sVec = new ASN1EncodableVector();
9294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            ASN1ObjectIdentifier  lstOid = null;
93099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
93199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int i = 0; i != ordering.size(); i++)
93299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
93399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ASN1EncodableVector     v = new ASN1EncodableVector();
93499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ASN1ObjectIdentifier     oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
93599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
93699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                v.add(oid);
93799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
93899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                String  str = (String)values.elementAt(i);
93999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
94099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                v.add(converter.getConvertedValue(oid, str));
94199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
94299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (lstOid == null
94399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    || ((Boolean)this.added.elementAt(i)).booleanValue())
94499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
94599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    sVec.add(new DERSequence(v));
94699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
94799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                else
94899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
94999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    vec.add(new DERSet(sVec));
95099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    sVec = new ASN1EncodableVector();
9514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
9524512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                    sVec.add(new DERSequence(v));
95399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
95499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
95599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                lstOid = oid;
95699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
95799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
95899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            vec.add(new DERSet(sVec));
95999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
96099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            seq = new DERSequence(vec);
96199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
96299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
96399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return seq;
96499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
96599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
96699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
96799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param inOrder if true the order of both X509 names must be the same,
96899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * as well as the values associated with each element.
96999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
97099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public boolean equals(Object obj, boolean inOrder)
97199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
97299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (!inOrder)
97399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
97499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return this.equals(obj);
97599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
97699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
97799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (obj == this)
97899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
97999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return true;
98099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
98199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
98299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (!(obj instanceof X509Name || obj instanceof ASN1Sequence))
98399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
98499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return false;
98599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
98699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
98799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
98899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
98999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (this.toASN1Primitive().equals(derO))
9904512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
9914512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            return true;
9924512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
9934512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
9944512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        X509Name other;
9954512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
9964512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        try
9974512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
9984512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            other = X509Name.getInstance(obj);
9994512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
10004512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        catch (IllegalArgumentException e)
10014512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
10024512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            return false;
10034512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
100499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
100599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        int      orderingSize = ordering.size();
100699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
100799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (orderingSize != other.ordering.size())
100899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
100999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return false;
101099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
101199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
101299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i < orderingSize; i++)
101399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
101499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1ObjectIdentifier  oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
101599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1ObjectIdentifier  oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(i);
101699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
101799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (oid.equals(oOid))
101899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
101999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                String value = (String)values.elementAt(i);
102099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                String oValue = (String)other.values.elementAt(i);
102199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
102299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (!equivalentStrings(value, oValue))
102399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
102499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    return false;
102599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
10264512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
10274512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            else
10284512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            {
10294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                return false;
10304512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            }
10314512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
10324512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
10334512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        return true;
103499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
103599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
103699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public int hashCode()
103799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
103899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (isHashCodeCalculated)
103999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
104099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return hashCodeValue;
104199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
104299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
104399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        isHashCodeCalculated = true;
104499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
104599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        // this needs to be order independent, like equals
104699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i != ordering.size(); i += 1)
104799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
10484512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            String value = (String)values.elementAt(i);
10494512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
10504512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            value = canonicalize(value);
10514512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            value = stripInternalSpaces(value);
10524512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
10534512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            hashCodeValue ^= ordering.elementAt(i).hashCode();
10544512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            hashCodeValue ^= value.hashCode();
10554512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
105699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
105799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return hashCodeValue;
105899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
105999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
106099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
106199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * test for equality - note: case is ignored.
10624512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org     */
1063160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    public boolean equals(Object obj)
10644d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com    {
10654512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (obj == this)
10664512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
1067160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com            return true;
10684d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com        }
10694512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
107099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (!(obj instanceof X509Name || obj instanceof ASN1Sequence))
107199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
107299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return false;
107399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
107499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
107599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1Primitive derO = ((ASN1Encodable)obj).toASN1Primitive();
107699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
107799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (this.toASN1Primitive().equals(derO))
107899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
107999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return true;
108099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
108199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
108299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        X509Name other;
108399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
108499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        try
108599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
108699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            other = X509Name.getInstance(obj);
108799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
108899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        catch (IllegalArgumentException e)
108999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
109099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return false;
10914512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
10924512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
10934512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        int      orderingSize = ordering.size();
10944512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
10954512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (orderingSize != other.ordering.size())
10964512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
10974512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            return false;
10984512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
109999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
110099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean[] indexes = new boolean[orderingSize];
110199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        int       start, end, delta;
110299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
110399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (ordering.elementAt(0).equals(other.ordering.elementAt(0)))   // guess forward
110499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
110599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            start = 0;
110699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            end = orderingSize;
110799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            delta = 1;
110899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
110999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else  // guess reversed - most common problem
111099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
11114512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            start = orderingSize - 1;
11124512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            end = -1;
11134512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            delta = -1;
11144512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        }
11154512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
11164512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        for (int i = start; i != end; i += delta)
11174512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        {
11184512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            boolean              found = false;
111999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1ObjectIdentifier  oid = (ASN1ObjectIdentifier)ordering.elementAt(i);
112099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            String               value = (String)values.elementAt(i);
112199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
112299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int j = 0; j < orderingSize; j++)
112399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
112499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (indexes[j])
11254512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
1126160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com                    continue;
11274d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com                }
11284512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
11294512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                ASN1ObjectIdentifier oOid = (ASN1ObjectIdentifier)other.ordering.elementAt(j);
1130160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
11314d09f5abfba45163d1296272ac7d2ddc2cd5f9fbrtoy@google.com                if (oid.equals(oOid))
11324512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org                {
113399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    String oValue = (String)other.values.elementAt(j);
113499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
113599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    if (equivalentStrings(value, oValue))
113699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    {
113799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                        indexes[j] = true;
113899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                        found      = true;
113999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                        break;
114099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    }
114199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
114299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
114399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
114499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (!found)
114599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
114699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                return false;
114799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
114899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
114999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
11502a72730ed70dfccfa09942bd172dfe82c9330496kma@webrtc.org        return true;
1151160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    }
1152160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com
115399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private boolean equivalentStrings(String s1, String s2)
115499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
11554512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        String value = canonicalize(s1);
11564512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        String oValue = canonicalize(s2);
11574512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
11584512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org        if (!value.equals(oValue))
1159160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com        {
1160160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com            value = stripInternalSpaces(value);
1161eb596a62ce5e7ba28834c69bf789eff46878b849kma@webrtc.org            oValue = stripInternalSpaces(oValue);
11624512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org
11634512d0eab7697423f5334ad79588f853c7bd80bbkma@webrtc.org            if (!value.equals(oValue))
116499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
116599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                return false;
116699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
116799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
116899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
116999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return true;
117099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
117199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
117299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private String canonicalize(String s)
117399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
117499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String value = Strings.toLowerCase(s.trim());
117599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
117699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (value.length() > 0 && value.charAt(0) == '#')
117799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
117899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ASN1Primitive obj = decodeObject(value);
117999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
118099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (obj instanceof ASN1String)
118199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
118299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                value = Strings.toLowerCase(((ASN1String)obj).getString().trim());
118399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
118499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
118599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
118699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return value;
118799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
118899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
118999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private ASN1Primitive decodeObject(String oValue)
119099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
119199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        try
119299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
119399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            return ASN1Primitive.fromByteArray(Hex.decode(oValue.substring(1)));
119499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
119599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        catch (IOException e)
119699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
119799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            throw new IllegalStateException("unknown encoding in name: " + e);
119899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
119999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
120099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
120199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private String stripInternalSpaces(
120299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String str)
120399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
120499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        StringBuffer res = new StringBuffer();
120599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
120699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (str.length() != 0)
120799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
120899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            char    c1 = str.charAt(0);
120999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
121099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            res.append(c1);
121199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
121299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int k = 1; k < str.length(); k++)
121399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
121499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                char    c2 = str.charAt(k);
121599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (!(c1 == ' ' && c2 == ' '))
121699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
121799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    res.append(c2);
121899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
121999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                c1 = c2;
122099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
122199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
122299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
122399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return res.toString();
122499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
122599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
122699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private void appendValue(
122799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        StringBuffer        buf,
122899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable           oidSymbols,
122999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        ASN1ObjectIdentifier oid,
123099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String              value)
123199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
123299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        String  sym = (String)oidSymbols.get(oid);
123399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
123499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (sym != null)
123599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
123699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            buf.append(sym);
123799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
123899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else
123999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
124099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            buf.append(oid.getId());
124199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
124299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
124399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        buf.append('=');
124499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
124599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        int start = buf.length();
124699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        buf.append(value);
124799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        int end = buf.length();
124899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
124999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (value.length() >= 2 && value.charAt(0) == '\\' && value.charAt(1) == '#')
125099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
125199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            start += 2;
125299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
125399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
125499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        while (start < end && buf.charAt(start) == ' ')
125599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
125699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            buf.insert(start, "\\");
125799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            start += 2;
125899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            ++end;
125999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
126099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
126199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        while (--end > start && buf.charAt(end) == ' ')
126299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
126399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            buf.insert(end, '\\');
126499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
126599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
126699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        while (start <= end)
126799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
126899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            switch (buf.charAt(start))
126999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
127099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case ',':
127199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '"':
127299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '\\':
127399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '+':
127499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '=':
127599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '<':
127699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case '>':
127799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            case ';':
127899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                buf.insert(start, "\\");
127999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                start += 2;
128099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ++end;
128199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                break;
128299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            default:
128399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ++start;
128499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                break;
128599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
128699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
128799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
128899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
128999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    /**
129099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * convert the structure to a string - if reverse is true the
129199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * oids and values are listed out starting with the last element
129299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * in the sequence (ala RFC 2253), otherwise the string will begin
129399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * with the first element of the structure. If no string definition
129499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * for the oid is found in oidSymbols the string value of the oid is
129599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * added. Two standard symbol tables are provided DefaultSymbols, and
129699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * RFC2253Symbols as part of this class.
129799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     *
129899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param reverse if true start at the end of the sequence and work back.
129999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     * @param oidSymbols look up table strings for oids.
130099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com     */
130199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public String toString(
130299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean     reverse,
130399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Hashtable   oidSymbols)
130499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
130599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        StringBuffer            buf = new StringBuffer();
130699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        Vector                  components = new Vector();
130799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        boolean                 first = true;
130899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
130999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        StringBuffer ava = null;
131099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
131199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i < ordering.size(); i++)
131299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
131399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            if (((Boolean)added.elementAt(i)).booleanValue())
131499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
131599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ava.append('+');
131699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                appendValue(ava, oidSymbols,
131799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    (ASN1ObjectIdentifier)ordering.elementAt(i),
131899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    (String)values.elementAt(i));
131999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
132099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            else
132199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
132299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                ava = new StringBuffer();
132399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                appendValue(ava, oidSymbols,
132499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    (ASN1ObjectIdentifier)ordering.elementAt(i),
132599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    (String)values.elementAt(i));
132699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                components.addElement(ava);
132799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
132899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
132999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
133099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        if (reverse)
133199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
133299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int i = components.size() - 1; i >= 0; i--)
133399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
133499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (first)
133599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
133699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    first = false;
133799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
133899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                else
133999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
134099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    buf.append(',');
134199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
134299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
134399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                buf.append(components.elementAt(i).toString());
134499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
134599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
134699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        else
134799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
134899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            for (int i = 0; i < components.size(); i++)
134999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            {
135099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                if (first)
135199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
135299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    first = false;
135399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
135499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                else
135599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                {
135699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                    buf.append(',');
135799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                }
135899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
135999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com                buf.append(components.elementAt(i).toString());
136099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            }
136199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
136299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
136399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return buf.toString();
136499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
136599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
136699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    private String bytesToString(
136799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        byte[] data)
136899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    {
136999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        char[]  cs = new char[data.length];
137099b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
137199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        for (int i = 0; i != cs.length; i++)
137299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        {
137399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com            cs[i] = (char)(data[i] & 0xff);
137499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        }
137599b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
137699b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return new String(cs);
137799b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
137899b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com
137999b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    public String toString()
1380160311f8f0a09062f4360709d2965e71d3f3d749rtoy@google.com    {
138199b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com        return toString(DefaultReverse, DefaultSymbols);
138299b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com    }
138399b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com}
138499b31ea5d0f4629ceddf4852f96757c9c73654artoy@google.com