151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
2b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage javax.security.auth.x500;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.Principal;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Collections;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Map;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.x509.X500Name;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.*;
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
36b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * <p> This class represents an X.500 {@code Principal}.
37b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * {@code X500Principal}s are represented by distinguished names such as
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US".
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> This class can be instantiated by using a string representation
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the distinguished name, or by using the ASN.1 DER encoded byte
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * representation of the distinguished name.  The current specification
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for the string representation of a distinguished name is defined in
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253: Lightweight
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Directory Access Protocol (v3): UTF-8 String Representation of
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Distinguished Names</a>. This class, however, accepts string formats from
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * both RFC 2253 and <a href="http://www.ietf.org/rfc/rfc1779.txt">RFC 1779:
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A String Representation of Distinguished Names</a>, and also recognizes
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * attribute type keywords whose OIDs (Object Identifiers) are defined in
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Public Key Infrastructure Certificate and CRL Profile</a>.
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
53b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * <p> The string representation for this {@code X500Principal}
54b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * can be obtained by calling the {@code getName} methods.
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
56b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * <p> Note that the {@code getSubjectX500Principal} and
57b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * {@code getIssuerX500Principal} methods of
58b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro * {@code X509Certificate} return X500Principals representing the
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * issuer and subject fields of the certificate.
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.security.cert.X509Certificate
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic final class X500Principal implements Principal, java.io.Serializable {
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final long serialVersionUID = -500463348111345721L;
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 1779 String format of Distinguished Names.
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final String RFC1779 = "RFC1779";
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 2253 String format of Distinguished Names.
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final String RFC2253 = "RFC2253";
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Canonical String format of Distinguished Names.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final String CANONICAL = "CANONICAL";
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The X500Name representing this principal.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * NOTE: this field is reflectively accessed from within X500Name.
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private transient X500Name thisX500Name;
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates an X500Principal by wrapping an X500Name.
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * NOTE: The constructor is package private. It is intended to be accessed
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using privileged reflection from classes in sun.security.*.
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Currently referenced from sun.security.x509.X500Name.asX500Principal().
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    X500Principal(X500Name x500Name) {
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        thisX500Name = x500Name;
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
100b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Creates an {@code X500Principal} from a string representation of
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an X.500 distinguished name (ex:
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The distinguished name must be specified using the grammar defined in
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 1779 or RFC 2253 (either format is acceptable).
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>This constructor recognizes the attribute type keywords
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * defined in RFC 1779 and RFC 2253
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * (and listed in {@link #getName(String format) getName(String format)}),
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
110b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
111b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Identifiers (OIDs) are defined in RFC 3280 and its successor.
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Any other attribute type must be specified as an OID.
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
114b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <p>This implementation enforces a more restrictive OID syntax than
115b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * defined in RFC 1779 and 2253. It uses the more correct syntax defined in
116b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
117b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * specifies that OIDs contain at least 2 digits:
118b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *
119b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <p>{@code numericoid = number 1*( DOT number ) }
120b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
122b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @exception NullPointerException if the {@code name}
123b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *                  is {@code null}
124b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @exception IllegalArgumentException if the {@code name}
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  is improperly specified
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X500Principal(String name) {
128b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro        this(name, Collections.<String, String>emptyMap());
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
132b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Creates an {@code X500Principal} from a string representation of
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an X.500 distinguished name (ex:
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US").
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The distinguished name must be specified using the grammar defined in
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 1779 or RFC 2253 (either format is acceptable).
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This constructor recognizes the attribute type keywords specified
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in {@link #X500Principal(String)} and also recognizes additional
140b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * keywords that have entries in the {@code keywordMap} parameter.
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Keyword entries in the keywordMap take precedence over the default
142b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * keywords recognized by {@code X500Principal(String)}. Keywords
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * MUST be specified in all upper-case, otherwise they will be ignored.
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Improperly specified keywords are ignored; however if a keyword in the
145b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * name maps to an improperly specified Object Identifier (OID), an
146b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code IllegalArgumentException} is thrown. It is permissible to
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * have 2 different keywords that map to the same OID.
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
149b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <p>This implementation enforces a more restrictive OID syntax than
150b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * defined in RFC 1779 and 2253. It uses the more correct syntax defined in
151b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <a href="http://www.ietf.org/rfc/rfc4512.txt">RFC 4512</a>, which
152b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * specifies that OIDs contain at least 2 digits:
153b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *
154b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <p>{@code numericoid = number 1*( DOT number ) }
155b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param keywordMap an attribute type keyword map, where each key is a
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   keyword String that maps to a corresponding object identifier in String
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   form (a sequence of nonnegative integers separated by periods). The map
160b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *   may be empty but never {@code null}.
161b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @exception NullPointerException if {@code name} or
162b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *   {@code keywordMap} is {@code null}
163b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @exception IllegalArgumentException if the {@code name} is
164b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *   improperly specified or a keyword in the {@code name} maps to an
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   OID that is not in the correct form
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.6
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X500Principal(String name, Map<String, String> keywordMap) {
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (name == null) {
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (sun.security.util.ResourcesMgr.getString
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("provided.null.name"));
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (keywordMap == null) {
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (sun.security.util.ResourcesMgr.getString
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("provided.null.keyword.map"));
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            thisX500Name = new X500Name(name, keywordMap);
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            IllegalArgumentException iae = new IllegalArgumentException
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("improperly specified input name: " + name);
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            iae.initCause(e);
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw iae;
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
191b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Creates an {@code X500Principal} from a distinguished name in
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ASN.1 DER encoded form. The ASN.1 notation for this structure is as
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * follows.
194b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <pre>{@code
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Name ::= CHOICE {
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   RDNSequence }
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RelativeDistinguishedName ::=
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AttributeTypeAndValue ::= SEQUENCE {
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   type     AttributeType,
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   value    AttributeValue }
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AttributeType ::= OBJECT IDENTIFIER
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * AttributeValue ::= ANY DEFINED BY AttributeType
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * ....
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DirectoryString ::= CHOICE {
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       teletexString           TeletexString (SIZE (1..MAX)),
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       printableString         PrintableString (SIZE (1..MAX)),
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       universalString         UniversalString (SIZE (1..MAX)),
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       utf8String              UTF8String (SIZE (1.. MAX)),
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       bmpString               BMPString (SIZE (1..MAX)) }
217b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * }</pre>
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name a byte array containing the distinguished name in ASN.1
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DER encoded form
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException if an encoding error occurs
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          (incorrect form for DN)
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X500Principal(byte[] name) {
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            thisX500Name = new X500Name(name);
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            IllegalArgumentException iae = new IllegalArgumentException
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("improperly specified input name");
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            iae.initCause(e);
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw iae;
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
236b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Creates an {@code X500Principal} from an {@code InputStream}
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * containing the distinguished name in ASN.1 DER encoded form.
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The ASN.1 notation for this structure is supplied in the
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * documentation for
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> The read position of the input stream is positioned
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to the next available byte after the encoded distinguished name.
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
245b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @param is an {@code InputStream} containing the distinguished
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          name in ASN.1 DER encoded form
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
248b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @exception NullPointerException if the {@code InputStream}
249b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          is {@code null}
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if an encoding error occurs
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          (incorrect form for DN)
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public X500Principal(InputStream is) {
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (is == null) {
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException("provided null input stream");
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (is.markSupported())
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                is.mark(is.available() + 1);
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DerValue der = new DerValue(is);
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            thisX500Name = new X500Name(der.data);
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (is.markSupported()) {
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    is.reset();
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException ioe) {
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    IllegalArgumentException iae = new IllegalArgumentException
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("improperly specified input stream " +
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("and unable to reset input stream"));
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    iae.initCause(e);
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw iae;
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            IllegalArgumentException iae = new IllegalArgumentException
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("improperly specified input stream");
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            iae.initCause(e);
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw iae;
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a string representation of the X.500 distinguished name using
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the format defined in RFC 2253.
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>This method is equivalent to calling
287b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code getName(X500Principal.RFC2253)}.
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
289b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return the distinguished name of this {@code X500Principal}
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getName() {
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getName(X500Principal.RFC2253);
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a string representation of the X.500 distinguished name
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using the specified format. Valid values for the format are
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * "RFC1779", "RFC2253", and "CANONICAL" (case insensitive).
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If "RFC1779" is specified as the format,
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method emits the attribute type keywords defined in
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 1779 (CN, L, ST, O, OU, C, STREET).
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Any other attribute type is emitted as an OID.
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If "RFC2253" is specified as the format,
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method emits the attribute type keywords defined in
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC 2253 (CN, L, ST, O, OU, C, STREET, DC, UID).
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Any other attribute type is emitted as an OID.
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Under a strict reading, RFC 2253 only specifies a UTF-8 string
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * representation. The String returned by this method is the
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Unicode string achieved by decoding this UTF-8 representation.
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> If "CANONICAL" is specified as the format,
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method returns an RFC 2253 conformant string representation
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the following additional canonicalizations:
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
317b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <ol>
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> Leading zeros are removed from attribute types
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          that are encoded as dotted decimal OIDs
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> DirectoryString attribute values of type
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          PrintableString and UTF8String are not
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          output in hexadecimal format
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> DirectoryString attribute values of types
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          other than PrintableString and UTF8String
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          are output in hexadecimal format
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> Leading and trailing white space characters
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          are removed from non-hexadecimal attribute values
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          (unless the value consists entirely of white space characters)
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> Internal substrings of one or more white space characters are
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          converted to a single space in non-hexadecimal
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          attribute values
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> Relative Distinguished Names containing more than one
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          Attribute Value Assertion (AVA) are output in the
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          following order: an alphabetical ordering of AVAs
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          containing standard keywords, followed by a numeric
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          ordering of AVAs containing OID keywords.
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> The only characters in attribute values that are escaped are
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          those which section 2.4 of RFC 2253 states must be escaped
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          (they are escaped using a preceding backslash character)
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> The entire name is converted to upper case
341b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          using {@code String.toUpperCase(Locale.US)}
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> The entire name is converted to lower case
343b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          using {@code String.toLowerCase(Locale.US)}
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li> The name is finally normalized using normalization form KD,
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          as described in the Unicode Standard and UAX #15
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </ol>
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Additional standard formats may be introduced in the future.
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param format the format to use
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
352b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return a string representation of this {@code X500Principal}
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          using the specified format
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException if the specified format is invalid
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          or null
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getName(String format) {
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (format != null) {
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (format.equalsIgnoreCase(RFC1779)) {
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return thisX500Name.getRFC1779Name();
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (format.equalsIgnoreCase(RFC2253)) {
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return thisX500Name.getRFC2253Name();
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (format.equalsIgnoreCase(CANONICAL)) {
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return thisX500Name.getRFC2253CanonicalName();
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throw new IllegalArgumentException("invalid format specified");
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a string representation of the X.500 distinguished name
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using the specified format. Valid values for the format are
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * "RFC1779" and "RFC2253" (case insensitive). "CANONICAL" is not
374b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * permitted and an {@code IllegalArgumentException} will be thrown.
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>This method returns Strings in the format as specified in
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #getName(String)} and also emits additional attribute type
378b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * keywords for OIDs that have entries in the {@code oidMap}
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * parameter. OID entries in the oidMap take precedence over the default
380b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * OIDs recognized by {@code getName(String)}.
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Improperly specified OIDs are ignored; however if an OID
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the name maps to an improperly specified keyword, an
383b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code IllegalArgumentException} is thrown.
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Additional standard formats may be introduced in the future.
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Warning: additional attribute type keywords may not be recognized
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by other implementations; therefore do not use this method if
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * you are unsure if these keywords will be recognized by other
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * implementations.
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param format the format to use
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param oidMap an OID map, where each key is an object identifier in
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  String form (a sequence of nonnegative integers separated by periods)
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  that maps to a corresponding attribute type keyword String.
396b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *  The map may be empty but never {@code null}.
397b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return a string representation of this {@code X500Principal}
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          using the specified format
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IllegalArgumentException if the specified format is invalid,
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  null, or an OID in the name maps to an improperly specified keyword
401b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @throws NullPointerException if {@code oidMap} is {@code null}
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.6
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getName(String format, Map<String, String> oidMap) {
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oidMap == null) {
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (sun.security.util.ResourcesMgr.getString
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("provided.null.OID.map"));
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (format != null) {
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (format.equalsIgnoreCase(RFC1779)) {
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return thisX500Name.getRFC1779Name(oidMap);
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (format.equalsIgnoreCase(RFC2253)) {
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return thisX500Name.getRFC2253Name(oidMap);
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throw new IllegalArgumentException("invalid format specified");
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the distinguished name in ASN.1 DER encoded form. The ASN.1
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * notation for this structure is supplied in the documentation for
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #X500Principal(byte[] name) X500Principal(byte[] name)}.
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>Note that the byte array returned is cloned to protect against
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * subsequent modifications.
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a byte array containing the distinguished name in ASN.1 DER
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * encoded form
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public byte[] getEncoded() {
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return thisX500Name.getEncoded();
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException e) {
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new RuntimeException("unable to get encoding", e);
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return a user-friendly string representation of this
441b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code X500Principal}.
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
443b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return a string representation of this {@code X500Principal}
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return thisX500Name.toString();
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
450b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Compares the specified {@code Object} with this
451b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code X500Principal} for equality.
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
453b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * <p> Specifically, this method returns {@code true} if
454b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * the {@code Object} <i>o</i> is an {@code X500Principal}
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and if the respective canonical string representations
456b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * (obtained via the {@code getName(X500Principal.CANONICAL)} method)
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of this object and <i>o</i> are equal.
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This implementation is compliant with the requirements of RFC 3280.
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param o Object to be compared for equality with this
462b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          {@code X500Principal}
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
464b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return {@code true} if the specified {@code Object} is equal
465b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          to this {@code X500Principal}, {@code false} otherwise
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(Object o) {
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (this == o) {
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return true;
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o instanceof X500Principal == false) {
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        X500Principal other = (X500Principal)o;
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.thisX500Name.equals(other.thisX500Name);
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
479b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * Return a hash code for this {@code X500Principal}.
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> The hash code is calculated via:
482b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * {@code getName(X500Principal.CANONICAL).hashCode()}
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
484b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @return a hash code for this {@code X500Principal}
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int hashCode() {
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return thisX500Name.hashCode();
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Save the X500Principal object to a stream.
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
493b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     * @serialData this {@code X500Principal} is serialized
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          by writing out its DER-encoded form
495b2bb47be12d2f58ab0b5e7003f2efef515542d82Sergio Giro     *          (the value of {@code getEncoded} is serialized).
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void writeObject(java.io.ObjectOutputStream s)
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        s.writeObject(thisX500Name.getEncodedInternal());
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads this object from a stream (i.e., deserializes it).
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void readObject(java.io.ObjectInputStream s)
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws java.io.IOException,
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               java.io.NotActiveException,
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               ClassNotFoundException {
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // re-create thisX500Name
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        thisX500Name = new X500Name((byte[])s.readObject());
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
514