1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.security.auth.x500;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectInputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.ObjectOutputStream;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Principal;
26018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilsonimport java.util.Map;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x501.Name;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Represents an X.500 principal, which holds the distinguished name of some
3113970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * network entity. An example of a distinguished name is {@code "O=SomeOrg,
3213970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson * OU=SomeOrgUnit, C=US"}. The class can be instantiated from a byte representation
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of an object identifier (OID), an ASN.1 DER-encoded version, or a simple
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string holding the distinguished name. The representations must follow either
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * RFC 2253, RFC 1779, or RFC2459.
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class X500Principal implements Serializable, Principal {
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -500463348111345721L;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Defines a constant for the canonical string format of distinguished
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * names.
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
45f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public static final String CANONICAL = "CANONICAL";
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Defines a constant for the RFC 1779 string format of distinguished
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * names.
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
51f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public static final String RFC1779 = "RFC1779";
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Defines a constant for the RFC 2253 string format of distinguished
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * names.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
57f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public static final String RFC2253 = "RFC2253";
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //Distinguished Name
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private transient Name dn;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new X500Principal from a given ASN.1 DER encoding of a
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * distinguished name.
6513970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the ASN.1 DER-encoded distinguished name
6813970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the ASN.1 DER-encoded distinguished name is incorrect
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal(byte[] name) {
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
742313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes            throw new IllegalArgumentException("Name cannot be null");
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // FIXME dn = new Name(name);
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            dn = (Name) Name.ASN1.decode(name);
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
802313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes            throw incorrectInputEncoding(e);
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new X500Principal from a given ASN.1 DER encoding of a
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * distinguished name.
8713970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param in
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            an {@code InputStream} holding the ASN.1 DER-encoded
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            distinguished name
9113970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the ASN.1 DER-encoded distinguished name is incorrect
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal(InputStream in) {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (in == null) {
972313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes            throw new NullPointerException("in == null");
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // FIXME dn = new Name(is);
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            dn = (Name) Name.ASN1.decode(in);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
1032313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes            throw incorrectInputEncoding(e);
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1072313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes    private IllegalArgumentException incorrectInputEncoding(IOException e) {
1082313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes        IllegalArgumentException iae = new IllegalArgumentException("Incorrect input encoding");
1092313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes        iae.initCause(e);
1102313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes        throw iae;
1112313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes    }
1122313047d797e4daece04da8e8ed406d26b589f82Elliott Hughes
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new X500Principal from a string representation of a
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * distinguished name.
11613970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string representation of the distinguished name
11913970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the string representation of the distinguished name is
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             incorrect
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal(String name) {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
12686acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("name == null");
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            dn = new Name(name);
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
1311b3c5388d0fffde4392007eb1b0be011a5dfae82Brian Carlstrom            throw incorrectInputName(e, name);
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    public X500Principal(String name, Map<String,String> keywordMap){
136018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        if (name == null) {
13786acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("name == null");
138018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        }
139018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        try {
140018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            dn = new Name(substituteNameFromMap(name, keywordMap));
141018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        } catch (IOException e) {
1421b3c5388d0fffde4392007eb1b0be011a5dfae82Brian Carlstrom            throw incorrectInputName(e, name);
143018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        }
144018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    }
145018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
1461b3c5388d0fffde4392007eb1b0be011a5dfae82Brian Carlstrom    private IllegalArgumentException incorrectInputName(IOException e, String name) {
1471b3c5388d0fffde4392007eb1b0be011a5dfae82Brian Carlstrom        IllegalArgumentException iae = new IllegalArgumentException("Incorrect input name:" + name);
148018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        iae.initCause(e);
149018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        throw iae;
150018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    }
151018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
1525bd2429e5d62e7885c717bda72e789f2649837beBob Lee    private transient String canonicalName;
1535bd2429e5d62e7885c717bda72e789f2649837beBob Lee    private synchronized String getCanonicalName() {
1545bd2429e5d62e7885c717bda72e789f2649837beBob Lee        if (canonicalName == null) {
1555bd2429e5d62e7885c717bda72e789f2649837beBob Lee            canonicalName = dn.getName(CANONICAL);
1565bd2429e5d62e7885c717bda72e789f2649837beBob Lee        }
1575bd2429e5d62e7885c717bda72e789f2649837beBob Lee        return canonicalName;
1585bd2429e5d62e7885c717bda72e789f2649837beBob Lee    }
1595bd2429e5d62e7885c717bda72e789f2649837beBob Lee
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object o) {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this == o) {
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (o == null || this.getClass() != o.getClass()) {
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        X500Principal principal = (X500Principal) o;
1695bd2429e5d62e7885c717bda72e789f2649837beBob Lee        return getCanonicalName().equals(principal.getCanonicalName());
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an ASN.1 DER-encoded representation of the distinguished name
17413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     * contained in this X.500 principal.
17513970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the ASN.1 DER-encoded representation
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] src = dn.getEncoded();
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] dst = new byte[src.length];
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(src, 0, dst, 0, dst.length);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return dst;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
18613970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     * Returns a human-readable string representation of the distinguished name
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * contained in this X.500 principal.
18813970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string representation
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getName() {
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return dn.getName(RFC2253);
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string representation of the distinguished name contained in
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * this X.500 principal. The format of the representation can be chosen.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Valid arguments are {@link #RFC1779}, {@link #RFC2253}, and
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #CANONICAL}. The representations are specified in RFC 1779 and RFC
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * 2253, respectively. The canonical form is based on RFC 2253, but adds
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * some canonicalizing operations like removing leading and trailing
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * whitespace, lower-casing the whole name, and bringing it into a
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * normalized Unicode representation.
20413970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param format
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the format to use for the representation
20713970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the string representation
20913970a92a67826bfd12464079b9ccc173f9ab5a6Jesse Wilson     *
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the {@code format} argument is not one of the three
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             mentioned above
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getName(String format) {
2155bd2429e5d62e7885c717bda72e789f2649837beBob Lee        if (CANONICAL.equals(format)) {
2165bd2429e5d62e7885c717bda72e789f2649837beBob Lee            return getCanonicalName();
2175bd2429e5d62e7885c717bda72e789f2649837beBob Lee        }
2185bd2429e5d62e7885c717bda72e789f2649837beBob Lee
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return dn.getName(format);
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    public String getName(String format, Map<String, String> oidMap) {
223018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        String rfc1779Name = dn.getName(RFC1779);
224018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        String rfc2253Name = dn.getName(RFC2253);
225018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
22678e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes        if (format.equalsIgnoreCase("RFC1779")) {
227018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            StringBuilder resultName = new StringBuilder(rfc1779Name);
228018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int fromIndex = resultName.length();
229018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int equalIndex = -1;
230018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            while (-1 != (equalIndex = resultName.lastIndexOf("=", fromIndex))) {
231018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                int commaIndex = resultName.lastIndexOf(",", equalIndex);
232018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                String subName = resultName.substring(commaIndex + 1,
233018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        equalIndex).trim();
234018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                if (subName.length() > 4
235018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        && subName.substring(0, 4).equals("OID.")) {
236018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    String subSubName = subName.substring(4);
237018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    if (oidMap.containsKey(subSubName)) {
238018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        String replaceName = oidMap.get(subSubName);
239018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        if(commaIndex > 0) replaceName = " " + replaceName;
240018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        resultName.replace(commaIndex + 1, equalIndex, replaceName);
241018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    }
242018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                }
243018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                fromIndex = commaIndex;
244018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            }
245018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            return resultName.toString();
24678e3320540c8bdcbefba5ae1222ee18f6679ab33Elliott Hughes        } else if (format.equalsIgnoreCase("RFC2253")) {
247018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            StringBuilder resultName = new StringBuilder(rfc2253Name);
248018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            StringBuilder subsidyName = new StringBuilder(rfc1779Name);
249018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
250018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int fromIndex = resultName.length();
251018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int subsidyFromIndex = subsidyName.length();
252018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int equalIndex = -1;
253018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int subsidyEqualIndex = -1;
254018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            while (-1 != (equalIndex = resultName.lastIndexOf("=", fromIndex))) {
255018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                subsidyEqualIndex = subsidyName.lastIndexOf("=",
256018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        subsidyFromIndex);
257018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                int commaIndex = resultName.lastIndexOf(",", equalIndex);
258018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                String subName = resultName.substring(commaIndex + 1,
259018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        equalIndex).trim();
260018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                if (oidMap.containsKey(subName)) {
261018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    int subOrignalEndIndex = resultName
262018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                            .indexOf(",", equalIndex);
263018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    if (subOrignalEndIndex == -1)
264018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        subOrignalEndIndex = resultName.length();
265018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    int subGoalEndIndex = subsidyName.indexOf(",",
266018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                            subsidyEqualIndex);
267018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    if (subGoalEndIndex == -1)
268018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                        subGoalEndIndex = subsidyName.length();
269018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    resultName.replace(equalIndex + 1, subOrignalEndIndex,
270018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                            subsidyName.substring(subsidyEqualIndex + 1,
271018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                                    subGoalEndIndex));
272018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                    resultName.replace(commaIndex + 1, equalIndex, oidMap
273018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                            .get(subName));
274018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                }
275018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                fromIndex = commaIndex;
276018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                subsidyFromIndex = subsidyEqualIndex - 1;
277018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            }
278018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            return resultName.toString();
279018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        } else {
2801b3c5388d0fffde4392007eb1b0be011a5dfae82Brian Carlstrom            throw new IllegalArgumentException("invalid format specified: " + format);
281018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        }
282018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    }
283018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
2865bd2429e5d62e7885c717bda72e789f2649837beBob Lee        return getCanonicalName().hashCode();
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return dn.getName(RFC1779);
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void writeObject(ObjectOutputStream out) throws IOException {
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        out.writeObject(dn.getEncoded());
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        dn = (Name) Name.ASN1.decode((byte[]) in.readObject());
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
301018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson
302018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    private String substituteNameFromMap(String name, Map<String, String> keywordMap) {
303018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        StringBuilder sbName = new StringBuilder(name);
304018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        int fromIndex = sbName.length();
305018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        int equalIndex;
306018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        while (-1 != (equalIndex = sbName.lastIndexOf("=", fromIndex))) {
307018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            int commaIndex = sbName.lastIndexOf(",", equalIndex);
308018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            String subName = sbName.substring(commaIndex + 1, equalIndex).trim();
309018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            if (keywordMap.containsKey(subName)) {
310018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson                sbName.replace(commaIndex + 1, equalIndex, keywordMap.get(subName));
311018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            }
312018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson            fromIndex = commaIndex;
313018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        }
314018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson        return sbName.toString();
315018b67accb28954d35f3cd697be3428e9b45b7d8Jesse Wilson    }
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
317