GeneralName.java revision 196f44e24830d0e7fd17eba627704a162eba779e
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 Project/**
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Vladimir N. Molotkov, Alexander Y. Kleymenov
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.security.x509;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
266ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilsonimport java.net.InetAddress;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URI;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URISyntaxException;
296ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilsonimport java.net.UnknownHostException;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
34fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstromimport java.util.Locale;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Choice;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Implicit;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1OctetString;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Oid;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1StringType;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ObjectIdentifier;
444b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughesimport org.apache.harmony.security.utils.Array;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x501.Name;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
48f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * The class encapsulates the ASN.1 DER encoding/decoding work
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the GeneralName structure which is a part of X.509 certificate
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (as specified in RFC 3280 -
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Internet X.509 Public Key Infrastructure.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Certificate and Certificate Revocation List (CRL) Profile.
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  http://www.ietf.org/rfc/rfc3280.txt):
54f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre>
56f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   GeneralName::= CHOICE {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        otherName                       [0]     OtherName,
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        rfc822Name                      [1]     IA5String,
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        dNSName                         [2]     IA5String,
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        x400Address                     [3]     ORAddress,
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        directoryName                   [4]     Name,
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        ediPartyName                    [5]     EDIPartyName,
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        uniformResourceIdentifier       [6]     IA5String,
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        iPAddress                       [7]     OCTET STRING,
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        registeredID                    [8]     OBJECT IDENTIFIER
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
68f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   OtherName::= SEQUENCE {
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        type-id    OBJECT IDENTIFIER,
71f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *        value      [0] EXPLICIT ANY DEFINED BY type-id
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
73f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   EDIPartyName::= SEQUENCE {
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        nameAssigner            [0]     DirectoryString OPTIONAL,
76f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *        partyName               [1]     DirectoryString
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
78f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   DirectoryString::= CHOICE {
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        teletexString             TeletexString   (SIZE (1..MAX)),
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        printableString           PrintableString (SIZE (1..MAX)),
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        universalString           UniversalString (SIZE (1..MAX)),
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        utf8String              UTF8String      (SIZE (1..MAX)),
84f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *        bmpString               BMPString       (SIZE (1..MAX))
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
86f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre>
88f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
896ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * <p>This class doesn't support masked addresses like "10.9.8.0/255.255.255.0".
906ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * These are only necessary for NameConstraints, which are not exposed in the
916ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * Java certificate API.
926ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson *
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.NameConstraints
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.GeneralSubtree
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
965c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilsonpublic final class GeneralName {
97f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The values of the tags of fields
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int OTHER_NAME = 0;
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int RFC822_NAME = 1;
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DNS_NAME = 2;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int X400_ADDR = 3;
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DIR_NAME = 4;
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int EDIP_NAME = 5;
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int UR_ID = 6;
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int IP_ADDR = 7;
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int REG_ID = 8;
110f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // ASN1 encoders/decoders for name choices
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static ASN1Type[] nameASN1 = new ASN1Type[9];
113f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[OTHER_NAME] = OtherName.ASN1;
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[RFC822_NAME] = ASN1StringType.IA5STRING;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[DNS_NAME] = ASN1StringType.IA5STRING;
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[UR_ID] = ASN1StringType.IA5STRING;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[X400_ADDR] = ORAddress.ASN1;
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[DIR_NAME] = Name.ASN1;
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[EDIP_NAME] = EDIPartyName.ASN1;
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[IP_ADDR] = ASN1OctetString.getInstance();
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[REG_ID] = ASN1Oid.getInstance();
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
125f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
1265c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the tag of the name type */
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int tag;
1285c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the name value (can be String or byte array) */
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object name;
1305c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the ASN.1 encoded form of GeneralName */
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] encoding;
1325c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    /** the ASN.1 encoded form of GeneralName's field */
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] name_encoding;
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Makes the GeneralName object from the tag type and corresponding
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * well established string representation of the name value.
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The String representation of [7] iPAddress is such as:
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that the names:
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [0] otherName, [3] x400Address, [5] ediPartyName
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *   have no the string representation, so exception will be thrown.
148f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * To make the GeneralName object with such names use another constructor.
149f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @param tag is an integer which value corresponds to the name type.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name is a name value corresponding to the tag.
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(int tag, String name) throws IOException {
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
154897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IOException("name == null");
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = tag;
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tag) {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME :
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR :
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME :
161897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Unknown string representation for type [" + tag + "]");
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME :
163f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // according to RFC 3280 p.34 the DNS name should be
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checked against the
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // RFC 1034 p.10 (3.5. Preferred name syntax):
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                checkDNS(name);
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID :
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the uniformResourceIdentifier for correctness
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // according to RFC 3280 p.34
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                checkURI(name);
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME :
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = oidStrToInts(name);
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DIR_NAME :
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = new Name(name);
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR :
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = ipStrToBytes(name);
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
188897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Unknown type: [" + tag + "]");
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(OtherName name) {
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = OTHER_NAME;
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(ORAddress name) {
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = X400_ADDR;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(Name name) {
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = DIR_NAME;
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(EDIPartyName name) {
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = EDIP_NAME;
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
212f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * Constructor for type [7] iPAddress.
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name is an array of bytes such as:
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(byte[] name) throws IllegalArgumentException {
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int length = name.length;
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length != 4 && length != 8 && length != 16 && length != 32) {
224897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException("name.length invalid");
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = IP_ADDR;
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = new byte[name.length];
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(name, 0, this.name, 0, name.length);
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs an object representing the value of GeneralName.
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tag is an integer which value corresponds
234f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * to the name type (0-8),
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name is a DER encoded for of the name value
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
237897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes    public GeneralName(int tag, byte[] name) throws IOException {
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
239897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException("name == null");
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((tag < 0) || (tag > 8)) {
242897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IOException("GeneralName: unknown tag: " + tag);
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = tag;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name_encoding = new byte[name.length];
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(name, 0, this.name_encoding, 0, name.length);
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = nameASN1[tag].decode(this.name_encoding);
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
249f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the tag of the name in the structure
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTag() {
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return tag;
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
258f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @return the value of the name.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The class of name object depends on the tag as follows:
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [0] otherName - OtherName object,
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [1] rfc822Name - String object,
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [2] dNSName - String object,
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [3] x400Address - ORAddress object,
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [4] directoryName - instance of Name object,
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [5] ediPartyName - EDIPartyName object,
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [6] uniformResourceIdentifier - String object,
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [7] iPAddress - array of bytes such as:
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [8] registeredID - String.
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object getName() {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return name;
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
279f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
2805c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public boolean equals(Object other) {
2815c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        if (!(other instanceof GeneralName)) {
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2845c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        GeneralName gname = (GeneralName) other;
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.tag != gname.tag) {
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch(tag) {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return ((String) name).equalsIgnoreCase(
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (String) gname.getName());
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals((int[]) name, (int[]) gname.name);
296f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case IP_ADDR:
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // iPAddress [7], check by using ranges.
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals((byte[]) name, (byte[]) gname.name);
299f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case DIR_NAME:
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals(getEncoded(), gname.getEncoded());
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
309f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
3109efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes    public int hashCode() {
3119efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        switch (tag) {
3129efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case RFC822_NAME:
3139efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case DNS_NAME:
3149efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case UR_ID:
3159efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case REG_ID:
3169efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case IP_ADDR:
3179efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes            return name.hashCode();
3189efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case DIR_NAME:
3199efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case X400_ADDR:
3209efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case OTHER_NAME:
3219efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        case EDIP_NAME:
322196f44e24830d0e7fd17eba627704a162eba779eElliott Hughes            return Arrays.hashCode(getEncoded());
3239efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        default:
3249efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes            return super.hashCode();
3259efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes        }
3269efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes    }
327f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks if the other general name is acceptable by this object.
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The name is acceptable if it has the same type name and its
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name value is equal to name value of this object. Also the name
332f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * is acceptable if this general name object is a part of name
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * constraints and the specified name is satisfied the restriction
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * provided by this object (for more detail see section 4.2.1.11
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of rfc 3280).
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that for X400Address [3] check procedure is unclear so method
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * just checks the equality of encoded forms.
338f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * For otherName [0], ediPartyName [5], and registeredID [8]
339f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * the check procedure if not defined by rfc 3280 and for names of
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these types this method also checks only for equality of encoded forms.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isAcceptable(GeneralName gname) {
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.tag != gname.getTag()) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (this.tag) {
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
348f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // Mail address [1]:
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // a@b.c - particular address is acceptable by the same address,
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // or by b.c - host name.
351fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                return ((String) gname.getName()).toLowerCase(Locale.US)
352fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                    .endsWith(((String) name).toLowerCase(Locale.US));
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
354f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // DNS name [2] that can be constructed by simply adding
355f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // to the left hand side of the name satisfies the name
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // constraint: aaa.aa.aa satisfies to aaa.aa.aa, aa.aa, ..
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String dns = (String) name;
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String _dns = (String) gname.getName();
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (dns.equalsIgnoreCase(_dns)) {
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
362fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                    return _dns.toLowerCase(Locale.US).endsWith("." + dns.toLowerCase(Locale.US));
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
365f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // For URIs the constraint ".xyz.com" is satisfied by both
366f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // abc.xyz.com and abc.def.xyz.com.  However, the constraint
367f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                // ".xyz.com" is not satisfied by "xyz.com".
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // When the constraint does not begin with a period, it
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // specifies a host.
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Extract the host from URI:
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String uri = (String) name;
372f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                int begin = uri.indexOf("://")+3;
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int end = uri.indexOf('/', begin);
374f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                String host = (end == -1)
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? uri.substring(begin)
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : uri.substring(begin, end);
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                uri = (String) gname.getName();
378f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                begin = uri.indexOf("://")+3;
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                end = uri.indexOf('/', begin);
380f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                String _host = (end == -1)
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? uri.substring(begin)
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : uri.substring(begin, end);
383f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                if (host.startsWith(".")) {
384fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                    return _host.toLowerCase(Locale.US).endsWith(host.toLowerCase(Locale.US));
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return host.equalsIgnoreCase(_host);
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
388f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case IP_ADDR:
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // iPAddress [7], check by using ranges.
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] address = (byte[]) name;
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] _address = (byte[]) gname.getName();
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int length = address.length;
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int _length = _address.length;
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (length == _length) {
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return Arrays.equals(address, _address);
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (length == 2*_length) {
397fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                    for (int i = 0; i < _address.length; i++) {
3986ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson                        // TODO: should the 2nd IP address be treated as a range or as a mask?
3996ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson                        int octet = _address[i] & 0xff;
4006ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson                        int min = address[i] & 0xff;
4016ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson                        int max = address[i + _length] & 0xff;
4026ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson                        if ((octet < min) || (octet > max)) {
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return false;
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
410f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case DIR_NAME:
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // FIXME: false:
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // directoryName according to 4.1.2.4
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // comparing the encoded forms of the names
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                //TODO:
415f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                //Legacy implementations exist where an RFC 822 name
416f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                //is embedded in the subject distinguished name in an
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                //attribute of type EmailAddress
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals(getEncoded(), gname.getEncoded());
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
428f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets a list representation of this GeneralName object.
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The first entry of the list is an Integer object representing
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the type of mane (0-8), and the second entry is a value of the name:
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * string or ASN.1 DER encoded form depending on the type as follows:
434f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * rfc822Name, dNSName, uniformResourceIdentifier names are returned
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as Strings, using the string formats for those types (rfc 3280)
436f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * IP v4 address names are returned using dotted quad notation.
437f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * IP v6 address names are returned in the form "p1:p2:...:p8",
438f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * where p1-p8 are hexadecimal values representing the eight 16-bit
439f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * pieces of the address. registeredID name are returned as Strings
440f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * represented as a series of nonnegative integers separated by periods.
441f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * And directory names (distinguished names) are returned in
442f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * RFC 2253 string format.
443f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * otherName, X400Address, ediPartyName returned as byte arrays
444f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * containing the ASN.1 DER encoded form of the name.
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4465c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson    public List<Object> getAsList() {
4475c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        ArrayList<Object> result = new ArrayList<Object>();
448fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes        result.add(tag);
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tag) {
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(((OtherName) name).getEncoded());
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(name); // String
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(ObjectIdentifier.toString((int[]) name));
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(((ORAddress) name).getEncoded());
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DIR_NAME: // directoryName is returned as a String
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(((Name) name).getName(X500Principal.RFC2253));
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(((EDIPartyName) name).getEncoded());
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR: //iPAddress is returned as a String, not as a byte array
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.add(ipBytesToStr((byte[]) name));
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return Collections.unmodifiableList(result);
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
480f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        String result = "";
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tag) {
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
483f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "otherName[0]: "
4844b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes                         + Array.getBytesAsString(getEncoded());
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
487f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "rfc822Name[1]: " + name;
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
490f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "dNSName[2]: " + name;
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
493f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "uniformResourceIdentifier[6]: " + name;
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
496f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "registeredID[8]: " + ObjectIdentifier.toString((int[]) name);
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
499f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "x400Address[3]: "
5004b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes                         + Array.getBytesAsString(getEncoded());
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
502f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case DIR_NAME:
503f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "directoryName[4]: "
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         + ((Name) name).getName(X500Principal.RFC2253);
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
507f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "ediPartyName[5]: "
5084b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes                         + Array.getBytesAsString(getEncoded());
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
510f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            case IP_ADDR:
511f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                result = "iPAddress[7]: " + ipBytesToStr((byte[]) name);
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
518f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns ASN.1 encoded form of this X.509 GeneralName value.
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding == null) {
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding = ASN1.encode(this);
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return encoding;
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
530f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @return the encoded value of the name without the tag associated
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         with the name in the GeneralName structure
532f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @throws  IOException
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncodedName() {
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name_encoding == null) {
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            name_encoding = nameASN1[tag].encode(name);
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return name_encoding;
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks the correctness of the string representation of DNS name.
5432f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * The correctness is checked as specified in RFC 1034 p. 10, and modified
5442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * by RFC 1123 (section 2.1).
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void checkDNS(String dns) throws IOException {
547fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        String string = dns.toLowerCase(Locale.US);
548fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        int length = string.length();
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // indicates if it is a first letter of the label
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean first_letter = true;
551fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        for (int i = 0; i < length; i++) {
552fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom            char ch = string.charAt(i);
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (first_letter) {
554fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                if ((length > 2) && (ch == '*') && (string.charAt(1) == '.')) {
5552f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    first_letter = false;
5562f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    continue;
5572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                }
5582f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                if ((ch > 'z' || ch < 'a') && (ch < '0' || ch > '9')) {
559897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                    throw new IOException("DNS name must start with a letter: " + dns);
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                first_letter = false;
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || (ch == '-') || (ch == '.'))) {
566897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Incorrect DNS name: " + dns);
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ch == '.') {
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the end of the previous label, it should not
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // be '-' sign
571fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                if (string.charAt(i-1) == '-') {
572897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                    throw new IOException("Incorrect DNS name: label ends with '-': " + dns);
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                first_letter = true;
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks the correctness of the string representation of URI name.
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The correctness is checked as pointed out in RFC 3280 p. 34.
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void checkURI(String uri) throws IOException {
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            URI ur = new URI(uri);
586897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            if (ur.getScheme() == null || ur.getRawSchemeSpecificPart().isEmpty()) {
587897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("No scheme or scheme-specific-part in uniformResourceIdentifier: " + uri);
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!ur.isAbsolute()) {
590897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Relative uniformResourceIdentifier: " + uri);
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (URISyntaxException e) {
593897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw (IOException) new IOException("Bad representation of uniformResourceIdentifier: " + uri).initCause(e);
594f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
599fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom     * Converts OID into array of ints.
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static int[] oidStrToInts(String oid) throws IOException {
602fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        int length = oid.length();
603fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        if (oid.charAt(length-1) == '.') {
604897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IOException("Bad OID: " + oid);
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
606fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        int[] result = new int[length/2+1]; // best case: a.b.c.d.e
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int number = 0; // the number of OID's components
608fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        for (int i = 0; i < length; i++) {
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int value = 0;
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int pos = i;
611fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom            for (; i < length; i++) {
612fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                char ch = oid.charAt(i);
613fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                if ((ch < '0') || (ch > '9')) {
614fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                    break;
615fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                }
616fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom                value = 10 * value + (ch - '0');
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (i == pos) {
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // the number was not read
620897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Bad OID: " + oid);
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result[number++] = value;
623fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom            if (i == length) {
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
626fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom            char ch = oid.charAt(i);
627fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom            if (ch != '.') {
628897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                throw new IOException("Bad OID: " + oid);
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (number < 2) {
632897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IOException("OID should consist of no less than 2 components: " + oid);
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
634fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom        return Arrays.copyOfRange(result, 0, number);
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
6386ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson     * Returns the bytes of the given IP address or masked IP address.
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static byte[] ipStrToBytes(String ip) throws IOException {
6416ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson        if (!InetAddress.isNumeric(ip)) {
6426ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson            throw new IOException("Not an IP address: " + ip);
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
6446ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson        return InetAddress.getByName(ip).getAddress();
645897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes    }
646f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
6486ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson     * Returns the string form of the given IP address. Addresses of length 2x
6496ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson     * the canonical length are treated as a route/mask pair.
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String ipBytesToStr(byte[] ip) {
6526ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson        try {
6536ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson            return InetAddress.getByAddress(null, ip).getHostAddress();
6546ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson        } catch (UnknownHostException e) {
6556ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson            throw new IllegalArgumentException("Unexpected IP address: " + Arrays.toString(ip));
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
658f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final ASN1Choice ASN1 = new ASN1Choice(new ASN1Type[] {
660f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes           new ASN1Implicit(0, OtherName.ASN1),
661f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes           new ASN1Implicit(1, ASN1StringType.IA5STRING),
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(2, ASN1StringType.IA5STRING),
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(3, ORAddress.ASN1),
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(4, Name.ASN1),
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(5, EDIPartyName.ASN1),
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(6, ASN1StringType.IA5STRING),
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(7, ASN1OctetString.getInstance()),
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(8, ASN1Oid.getInstance()) }) {
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object getObjectToEncode(Object value) {
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ((GeneralName) value).name;
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
673f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int getIndex(java.lang.Object object) {
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return  ((GeneralName) object).tag;
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6785c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson        @Override public Object getDecodedObject(BerInputStream in) throws IOException {
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            GeneralName result;
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (in.choiceIndex) {
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case OTHER_NAME: // OtherName
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((OtherName) in.content);
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case RFC822_NAME: // rfc822Name
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case DNS_NAME: // dNSName
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName(in.choiceIndex, (String) in.content);
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case X400_ADDR:
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((ORAddress) in.content);
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case DIR_NAME: // directoryName (X.500 Name)
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((Name) in.content);
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case EDIP_NAME: // ediPartyName
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((EDIPartyName) in.content);
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case UR_ID: // uniformResourceIdentifier
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String uri = (String) in.content;
699f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    if (uri.indexOf(":") == -1) {
700897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                        throw new IOException("GeneralName: scheme is missing in URI: " + uri);
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName(in.choiceIndex, uri);
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case IP_ADDR: // iPAddress
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((byte[]) in.content);
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case REG_ID: // registeredID
708f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                    result = new GeneralName(in.choiceIndex,
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ObjectIdentifier.toString((int[]) in.content));
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                default:
712897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes                    throw new IOException("GeneralName: unknown tag: " + in.choiceIndex);
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.encoding = in.getEncoded();
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result;
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
719