151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1997, 2004, 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 sun.security.x509;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URI;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URISyntaxException;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.*;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class implements the URIName as required by the GeneralNames
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ASN.1 object.
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * [RFC3280] When the subjectAltName extension contains a URI, the name MUST be
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * stored in the uniformResourceIdentifier (an IA5String). The name MUST
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be a non-relative URL, and MUST follow the URL syntax and encoding
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rules specified in [RFC 1738].  The name must include both a scheme
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (e.g., "http" or "ftp") and a scheme-specific-part.  The scheme-
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specific-part must include a fully qualified domain name or IP
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * address as the host.
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * As specified in [RFC 1738], the scheme name is not case-sensitive
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (e.g., "http" is equivalent to "HTTP").  The host part is also not
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * case-sensitive, but other components of the scheme-specific-part may
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be case-sensitive. When comparing URIs, conforming implementations
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MUST compare the scheme and host without regard to case, but assume
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the remainder of the scheme-specific-part is case sensitive.
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * [RFC1738] In general, URLs are written as follows:
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre>
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <scheme>:<scheme-specific-part>
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre>
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A URL contains the name of the scheme being used (<scheme>) followed
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by a colon and then a string (the <scheme-specific-part>) whose
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interpretation depends on the scheme.
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * While the syntax for the rest of the URL may vary depending on the
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular scheme selected, URL schemes that involve the direct use
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of an IP-based protocol to a specified host on the Internet use a
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * common syntax for the scheme-specific data:
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre>
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * //<user>:<password>@<host>:<port>/<url-path>
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre>
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * [RFC2732] specifies that an IPv6 address contained inside a URL
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * must be enclosed in square brackets (to allow distinguishing the
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * colons that separate IPv6 components from the colons that separate
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * scheme-specific data.
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Amit Kapoor
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Hemma Prafullchandra
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Sean Mullan
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Steve Hanna
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see GeneralName
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see GeneralNames
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see GeneralNameInterface
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class URIName implements GeneralNameInterface {
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // private attributes
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private URI uri;
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private String host;
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private DNSName hostDNS;
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private IPAddressName hostIP;
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create the URIName object from the passed encoded Der value.
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param derValue the encoded DER URIName.
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException on error.
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public URIName(DerValue derValue) throws IOException {
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(derValue.getIA5String());
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create the URIName object with the specified name.
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param name the URIName.
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IOException if name is not a proper URIName
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public URIName(String name) throws IOException {
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            uri = new URI(name);
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (URISyntaxException use) {
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw (IOException) new IOException
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("invalid URI name:" + name).initCause(use);
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (uri.getScheme() == null) {
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IOException("URI name must include scheme:" + name);
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        host = uri.getHost();
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // RFC 3280 says that the host should be non-null, but we allow it to
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // be null because some widely deployed certificates contain CDP
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // extensions with URIs that have no hostname (see bugs 4802236 and
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // 5107944).
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (host != null) {
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (host.charAt(0) == '[') {
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Verify host is a valid IPv6 address name
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                String ipV6Host = host.substring(1, host.length()-1);
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hostIP = new IPAddressName(ipV6Host);
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException ioe) {
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new IOException("invalid URI name (host " +
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        "portion is not a valid IPv6 address):" + name);
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hostDNS = new DNSName(host);
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException ioe) {
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Not a valid DNS Name; see if it is a valid IPv4
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // IPAddressName
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        hostIP = new IPAddressName(host);
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (Exception ioe2) {
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new IOException("invalid URI name (host " +
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            "portion is not a valid DNS name, IPv4 address," +
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            " or IPv6 address):" + name);
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create the URIName object with the specified name constraint. URI
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * name constraints syntax is different than SubjectAltNames, etc. See
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * 4.2.1.11 of RFC 3280.
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param value the URI name constraint
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws IOException if name is not a proper URI name constraint
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static URIName nameConstraint(DerValue value) throws IOException {
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        URI uri;
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String name = value.getIA5String();
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            uri = new URI(name);
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (URISyntaxException use) {
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw (IOException) new IOException
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("invalid URI name constraint:" + name).initCause(use);
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (uri.getScheme() == null) {
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String host = uri.getSchemeSpecificPart();
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                DNSName hostDNS;
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (host.charAt(0) == '.') {
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hostDNS = new DNSName(host.substring(1));
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    hostDNS = new DNSName(host);
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return new URIName(uri, host, hostDNS);
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (IOException ioe) {
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw (IOException) new IOException
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ("invalid URI name constraint:" + name).initCause(ioe);
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IOException("invalid URI name constraint (should not " +
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                "include scheme):" + name);
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    URIName(URI uri, String host, DNSName hostDNS) {
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.uri = uri;
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.host = host;
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.hostDNS = hostDNS;
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the type of the GeneralName.
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getType() {
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return GeneralNameInterface.NAME_URI;
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Encode the URI name into the DerOutputStream.
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param out the DER stream to encode the URIName to.
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException on encoding errors.
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void encode(DerOutputStream out) throws IOException {
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        out.putIA5String(uri.toASCIIString());
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Convert the name into user readable string.
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return "URIName: " + uri.toString();
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compares this name with another, for equality.
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true iff the names are equivalent according to RFC2459.
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(Object obj) {
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (this == obj) {
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return true;
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(obj instanceof URIName)) {
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        URIName other = (URIName) obj;
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return uri.equals(other.getURI());
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the URIName as a java.net.URI object
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public URI getURI() {
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return uri;
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns this URI name.
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getName() {
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return uri.toString();
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the scheme name portion of a URIName
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @returns scheme portion of full name
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getScheme() {
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return uri.getScheme();
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the host name or IP address portion of the URIName
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @returns host name or IP address portion of full name
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getHost() {
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return host;
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the host object type; if host name is a
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DNSName, then this host object does not include any
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * initial "." on the name.
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @returns host name as DNSName or IPAddressName
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Object getHostObject() {
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (hostIP != null) {
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return hostIP;
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return hostDNS;
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the hash code value for this object.
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a hash code value for this object.
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int hashCode() {
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return uri.hashCode();
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return type of constraint inputName places on this name:<ul>
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li>NAME_DIFF_TYPE = -1: input name is different type from name
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       (i.e. does not constrain).
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li>NAME_MATCH = 0: input name matches name.
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       subtree)
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li>NAME_WIDENS = 2: input name widens name (is higher in the naming
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       subtree)
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       is same type.
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </ul>.
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * These results are used in checking NameConstraints during
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * certification path verification.
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * RFC3280: For URIs, the constraint applies to the host part of the name.
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The constraint may specify a host or a domain.  Examples would be
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * "foo.bar.com";  and ".xyz.com".  When the the constraint begins with
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a period, it may be expanded with one or more subdomains.  That is,
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the constraint ".xyz.com" is satisfied by both abc.xyz.com and
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * abc.def.xyz.com.  However, the constraint ".xyz.com" is not satisfied
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by "xyz.com".  When the constraint does not begin with a period, it
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * specifies a host.
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param inputName to be checked for being constrained
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @returns constraint type above
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws UnsupportedOperationException if name is not exact match, but
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  narrowing and widening are not supported for this name type.
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int constrains(GeneralNameInterface inputName)
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws UnsupportedOperationException {
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int constraintType;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (inputName == null) {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            constraintType = NAME_DIFF_TYPE;
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (inputName.getType() != NAME_URI) {
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            constraintType = NAME_DIFF_TYPE;
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Assuming from here on that one or both of these is
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // actually a URI name constraint (not a URI), so we
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // only need to compare the host portion of the name
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            String otherHost = ((URIName)inputName).getHost();
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Quick check for equality
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (otherHost.equalsIgnoreCase(host)) {
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                constraintType = NAME_MATCH;
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Object otherHostObject = ((URIName)inputName).getHostObject();
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if ((hostDNS == null) ||
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    !(otherHostObject instanceof DNSName)) {
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // If one (or both) is an IP address, only same type
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    constraintType = NAME_SAME_TYPE;
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Both host portions are DNS names. Are they domains?
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    boolean thisDomain = (host.charAt(0) == '.');
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    boolean otherDomain = (otherHost.charAt(0) == '.');
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    DNSName otherDNS = (DNSName) otherHostObject;
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Run DNSName.constrains.
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    constraintType = hostDNS.constrains(otherDNS);
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // If neither one is a domain, then they can't
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // widen or narrow. That's just SAME_TYPE.
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((!thisDomain && !otherDomain) &&
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ((constraintType == NAME_WIDENS) ||
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         (constraintType == NAME_NARROWS))) {
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        constraintType = NAME_SAME_TYPE;
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // If one is a domain and the other isn't,
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // then they can't match. The one that's a
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // domain doesn't include the one that's
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // not a domain.
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((thisDomain != otherDomain) &&
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (constraintType == NAME_MATCH)) {
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (thisDomain) {
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            constraintType = NAME_WIDENS;
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else {
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            constraintType = NAME_NARROWS;
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return constraintType;
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return subtree depth of this name for purposes of determining
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * NameConstraints minimum and maximum bounds and for calculating
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * path lengths in name subtrees.
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @returns distance of name from root
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws UnsupportedOperationException if not supported for this name type
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int subtreeDepth() throws UnsupportedOperationException {
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DNSName dnsName = null;
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dnsName = new DNSName(host);
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException ioe) {
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException(ioe.getMessage());
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return dnsName.subtreeDepth();
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
396