GeneralName.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
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;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URI;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URISyntaxException;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Choice;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Implicit;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1OctetString;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Oid;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1StringType;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ObjectIdentifier;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.internal.nls.Messages;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x501.Name;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The class encapsulates the ASN.1 DER encoding/decoding work
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the GeneralName structure which is a part of X.509 certificate
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (as specified in RFC 3280 -
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Internet X.509 Public Key Infrastructure.
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Certificate and Certificate Revocation List (CRL) Profile.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  http://www.ietf.org/rfc/rfc3280.txt):
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre>
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   GeneralName::= CHOICE {
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        otherName                       [0]     OtherName,
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        rfc822Name                      [1]     IA5String,
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        dNSName                         [2]     IA5String,
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        x400Address                     [3]     ORAddress,
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        directoryName                   [4]     Name,
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        ediPartyName                    [5]     EDIPartyName,
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        uniformResourceIdentifier       [6]     IA5String,
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        iPAddress                       [7]     OCTET STRING,
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        registeredID                    [8]     OBJECT IDENTIFIER
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   OtherName::= SEQUENCE {
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        type-id    OBJECT IDENTIFIER,
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        value      [0] EXPLICIT ANY DEFINED BY type-id
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   EDIPartyName::= SEQUENCE {
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        nameAssigner            [0]     DirectoryString OPTIONAL,
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        partyName               [1]     DirectoryString
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   DirectoryString::= CHOICE {
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        teletexString             TeletexString   (SIZE (1..MAX)),
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        printableString           PrintableString (SIZE (1..MAX)),
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        universalString           UniversalString (SIZE (1..MAX)),
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        utf8String              UTF8String      (SIZE (1..MAX)),
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *        bmpString               BMPString       (SIZE (1..MAX))
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre>
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.NameConstraints
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.GeneralSubtree
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class GeneralName {
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The values of the tags of fields
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int OTHER_NAME = 0;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int RFC822_NAME = 1;
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DNS_NAME = 2;
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int X400_ADDR = 3;
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int DIR_NAME = 4;
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int EDIP_NAME = 5;
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int UR_ID = 6;
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int IP_ADDR = 7;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int REG_ID = 8;
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // ASN1 encoders/decoders for name choices
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static ASN1Type[] nameASN1 = new ASN1Type[9];
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[OTHER_NAME] = OtherName.ASN1;
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[RFC822_NAME] = ASN1StringType.IA5STRING;
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[DNS_NAME] = ASN1StringType.IA5STRING;
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[UR_ID] = ASN1StringType.IA5STRING;
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[X400_ADDR] = ORAddress.ASN1;
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[DIR_NAME] = Name.ASN1;
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[EDIP_NAME] = EDIPartyName.ASN1;
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[IP_ADDR] = ASN1OctetString.getInstance();
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        nameASN1[REG_ID] = ASN1Oid.getInstance();
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // the tag of the name type
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int tag;
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // the name value (can be String or byte array)
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Object name;
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // the ASN.1 encoded form of GeneralName
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] encoding;
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // the ASN.1 encoded form of GeneralName's field
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] name_encoding;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Makes the GeneralName object from the tag type and corresponding
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * well established string representation of the name value.
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The String representation of [7] iPAddress is such as:
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that the names:
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [0] otherName, [3] x400Address, [5] ediPartyName
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *   have no the string representation, so exception will be thrown.
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * To make the GeneralName object with such names use another constructor.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tag is an integer which value corresponds to the name type.
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name is a name value corresponding to the tag.
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <pre>
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(int tag, String name) throws IOException {
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("security.28")); //$NON-NLS-1$
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = tag;
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tag) {
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME :
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR :
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME :
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException( Messages.getString("security.180", tag )); //$NON-NLS-1$ //$NON-NLS-2$
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME :
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // according to RFC 3280 p.34 the DNS name should be
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checked against the
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // RFC 1034 p.10 (3.5. Preferred name syntax):
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                checkDNS(name);
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID :
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the uniformResourceIdentifier for correctness
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // according to RFC 3280 p.34
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                checkURI(name);
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME :
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = name;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = oidStrToInts(name);
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DIR_NAME :
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = new Name(name);
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR :
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.name = ipStrToBytes(name);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.181", tag)); //$NON-NLS-1$ //$NON-NLS-2$
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   name:   OtherName
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    /**
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   name:   ORAddress
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(ORAddress name) {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = X400_ADDR;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   name:   Name
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(Name name) {
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = DIR_NAME;
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   name:   EDIPartyName
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(EDIPartyName name) {
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = EDIP_NAME;
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = name;
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructor for type [7] iPAddress.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name is an array of bytes such as:
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(byte[] name) throws IllegalArgumentException {
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int length = name.length;
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (length != 4 && length != 8 && length != 16 && length != 32) {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException(
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Messages.getString("security.182")); //$NON-NLS-1$
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = IP_ADDR;
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = new byte[name.length];
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(name, 0, this.name, 0, name.length);
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs an object representing the value of GeneralName.
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tag is an integer which value corresponds
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the name type (0-8),
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name is a DER encoded for of the name value
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GeneralName(int tag, byte[] name)
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    throws IOException {
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name == null) {
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException(Messages.getString("security.28")); //$NON-NLS-1$
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((tag < 0) || (tag > 8)) {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("security.183", tag)); //$NON-NLS-1$
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.tag = tag;
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name_encoding = new byte[name.length];
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(name, 0, this.name_encoding, 0, name.length);
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.name = nameASN1[tag].decode(this.name_encoding);
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the tag of the name in the structure
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the tag of the name
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTag() {
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return tag;
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the name.
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The class of name object depends on the tag as follows:
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [0] otherName - OtherName object,
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [1] rfc822Name - String object,
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [2] dNSName - String object,
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [3] x400Address - ORAddress object,
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [4] directoryName - instance of Name object,
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [5] ediPartyName - EDIPartyName object,
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [6] uniformResourceIdentifier - String object,
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [7] iPAddress - array of bytes such as:
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  For IP v4, as specified in RFC 791, the address must
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  contain exactly 4 byte component.  For IP v6, as specified in
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  RFC 1883, the address must contain exactly 16 byte component.
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If GeneralName structure is used as a part of Name Constraints
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  extension, to represent an address range the number of address
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  component is doubled (to 8 and 32 bytes respectively).
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * [8] registeredID - String.
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object getName() {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return name;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   _gname: Object
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object _gname) {
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(_gname instanceof GeneralName)) {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        GeneralName gname = (GeneralName) _gname;
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.tag != gname.tag) {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch(tag) {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return ((String) name).equalsIgnoreCase(
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (String) gname.getName());
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals((int[]) name, (int[]) gname.name);
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR:
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // iPAddress [7], check by using ranges.
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals((byte[]) name, (byte[]) gname.name);
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DIR_NAME:
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return Arrays.equals(getEncoded(), gname.getEncoded());
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //System.out.println(false);
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks if the other general name is acceptable by this object.
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The name is acceptable if it has the same type name and its
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name value is equal to name value of this object. Also the name
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is acceptable if this general name object is a part of name
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * constraints and the specified name is satisfied the restriction
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * provided by this object (for more detail see section 4.2.1.11
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of rfc 3280).
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note that for X400Address [3] check procedure is unclear so method
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * just checks the equality of encoded forms.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For otherName [0], ediPartyName [5], and registeredID [8]
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the check procedure if not defined by rfc 3280 and for names of
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * these types this method also checks only for equality of encoded forms.
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isAcceptable(GeneralName gname) {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.tag != gname.getTag()) {
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (this.tag) {
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Mail address [1]:
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // a@b.c - particular address is acceptable by the same address,
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // or by b.c - host name.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return ((String) gname.getName()).toLowerCase()
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    .endsWith(((String) name).toLowerCase());
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // DNS name [2] that can be constructed by simply adding
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // to the left hand side of the name satisfies the name
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // constraint: aaa.aa.aa satisfies to aaa.aa.aa, aa.aa, ..
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String dns = (String) name;
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String _dns = (String) gname.getName();
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (dns.equalsIgnoreCase(_dns)) {
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return _dns.toLowerCase().endsWith("." + dns.toLowerCase()); //$NON-NLS-1$
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // For URIs the constraint ".xyz.com" is satisfied by both
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // abc.xyz.com and abc.def.xyz.com.  However, the constraint
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // ".xyz.com" is not satisfied by "xyz.com".
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // When the constraint does not begin with a period, it
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // specifies a host.
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Extract the host from URI:
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String uri = (String) name;
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int begin = uri.indexOf("://")+3; //$NON-NLS-1$
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int end = uri.indexOf('/', begin);
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String host = (end == -1)
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? uri.substring(begin)
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : uri.substring(begin, end);
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                uri = (String) gname.getName();
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                begin = uri.indexOf("://")+3; //$NON-NLS-1$
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                end = uri.indexOf('/', begin);
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                String _host = (end == -1)
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? uri.substring(begin)
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : uri.substring(begin, end);
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (host.startsWith(".")) { //$NON-NLS-1$
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return _host.toLowerCase().endsWith(host.toLowerCase());
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return host.equalsIgnoreCase(_host);
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR:
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // iPAddress [7], check by using ranges.
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] address = (byte[]) name;
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] _address = (byte[]) gname.getName();
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int length = address.length;
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int _length = _address.length;
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (length == _length) {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return Arrays.equals(address, _address);
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (length == 2*_length) {
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int i=0; i<_address.length; i++) {
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if ((_address[i] < address[i])
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                || (_address[i] > address[i+_length])) {
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                }
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            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:
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                //Legacy implementations exist where an RFC 822 name
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                //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    }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
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:
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * rfc822Name, dNSName, uniformResourceIdentifier names are returned
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as Strings, using the string formats for those types (rfc 3280)
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IP v4 address names are returned using dotted quad notation.
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IP v6 address names are returned in the form "p1:p2:...:p8",
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * where p1-p8 are hexadecimal values representing the eight 16-bit
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * pieces of the address. registeredID name are returned as Strings
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * represented as a series of nonnegative integers separated by periods.
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * And directory names (distinguished names) are returned in
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * RFC 2253 string format.
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * otherName, X400Address, ediPartyName returned as byte arrays
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * containing the ASN.1 DER encoded form of the name.
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public List getAsList() {
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ArrayList result = new ArrayList();
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.add(new Integer(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    //
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // TODO
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // @param   data:   byte[]
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // @return
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String getBytesAsString(byte[] data) {
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String result = ""; //$NON-NLS-1$
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<data.length; i++) {
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String tail = Integer.toHexString(0x00ff & data[i]);
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (tail.length() == 1) {
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                tail = "0" + tail;  //$NON-NLS-1$
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result += tail + " "; //$NON-NLS-1$
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * TODO
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String result = ""; //$NON-NLS-1$
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (tag) {
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case OTHER_NAME:
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "otherName[0]: "  //$NON-NLS-1$
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         + getBytesAsString(getEncoded());
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case RFC822_NAME:
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "rfc822Name[1]: " + name; //$NON-NLS-1$
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DNS_NAME:
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "dNSName[2]: " + name; //$NON-NLS-1$
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case UR_ID:
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "uniformResourceIdentifier[6]: " + name; //$NON-NLS-1$
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case REG_ID:
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "registeredID[8]: " + ObjectIdentifier.toString((int[]) name); //$NON-NLS-1$
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case X400_ADDR:
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "x400Address[3]: "  //$NON-NLS-1$
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         + getBytesAsString(getEncoded());
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case DIR_NAME:
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "directoryName[4]: "  //$NON-NLS-1$
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         + ((Name) name).getName(X500Principal.RFC2253);
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case EDIP_NAME:
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "ediPartyName[5]: "  //$NON-NLS-1$
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         + getBytesAsString(getEncoded());
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            case IP_ADDR:
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = "iPAddress[7]: " + ipBytesToStr((byte[]) name); //$NON-NLS-1$
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            default:
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // should never happen
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns ASN.1 encoded form of this X.509 GeneralName value.
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a byte array containing ASN.1 encode form.
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (encoding == null) {
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            encoding = ASN1.encode(this);
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return encoding;
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the encoded value of the name without the tag associated
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         with the name in the GeneralName structure
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws  IOException
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncodedName() {
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (name_encoding == null) {
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            name_encoding = nameASN1[tag].encode(name);
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return name_encoding;
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks the correctness of the string representation of DNS name.
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The correctness is checked as specified in RFC 1034 p. 10.
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void checkDNS(String dns) throws IOException {
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] bytes = dns.toLowerCase().getBytes();
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // indicates if it is a first letter of the label
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean first_letter = true;
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<bytes.length; i++) {
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte ch = bytes[i];
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (first_letter) {
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (ch > 'z' || ch < 'a') {
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.184", //$NON-NLS-1$
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            (char)ch, dns));
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                first_letter = false;
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                continue;
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || (ch == '-') || (ch == '.'))) {
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.185", dns)); //$NON-NLS-1$
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ch == '.') {
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the end of the previous label, it should not
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // be '-' sign
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (bytes[i-i] == '-') {
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            Messages.getString("security.186", dns)); //$NON-NLS-1$
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                first_letter = true;
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks the correctness of the string representation of URI name.
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The correctness is checked as pointed out in RFC 3280 p. 34.
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void checkURI(String uri) throws IOException {
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            URI ur = new URI(uri);
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((ur.getScheme() == null)
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    || (ur.getRawSchemeSpecificPart().length() == 0)) {
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.187", uri)); //$NON-NLS-1$
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!ur.isAbsolute()) {
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.188", uri)); //$NON-NLS-1$
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (URISyntaxException e) {
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw (IOException) new IOException(
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Messages.getString("security.189", uri)).initCause(e);//$NON-NLS-1$
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Converts OID into array of bytes.
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static int[] oidStrToInts(String oid) throws IOException {
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] bytes = oid.getBytes();
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (bytes[bytes.length-1] == '.') {
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int[] result = new int[bytes.length/2+1]; // best case: a.b.c.d.e
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int number = 0; // the number of OID's components
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<bytes.length; i++) {
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int value = 0;
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int pos = i;
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while ((i < bytes.length) && (bytes[i] >= '0')
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && (bytes[i] <= '9')) {
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                value = 10 * value + (bytes[i++] - 48);
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (i == pos) {
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // the number was not read
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result[number++] = value;
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (i >= bytes.length) {
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                break;
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bytes[i] != '.') {
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (number < 2) {
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(Messages.getString("security.18A", oid));//$NON-NLS-1$
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int[] res = new int[number];
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<number; i++) {
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            res[i] = result[i];
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return res;
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Helper method. Converts the String representation of IP address
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the array of bytes. IP addresses are expected in two versions:<br>
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IPv4 - in dot-decimal notation<br>
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * IPv6 - in colon hexadecimal notation<br>
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Also method works with the ranges of the addresses represented
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * as 2 addresses separated by '/' character.
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   address :   String representation of IP address
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return  byte representation of IP address
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static byte[] ipStrToBytes(String ip) throws IOException {
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean isIPv4 = (ip.indexOf('.') > 0);
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // number of components (should be 4 or 8)
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int num_components = (isIPv4) ? 4 : 16;
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ip.indexOf('/') > 0) {
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            num_components *= 2; // this is a range of addresses
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // the resulting array
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = new byte[num_components];
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] ip_bytes = ip.getBytes();
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // number of address component to be read
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int component = 0;
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // if it is reading the second bound of a range
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean reading_second_bound = false;
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isIPv4) {
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // IPv4 address is expected in the form of dot-decimal notation:
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            //      1.100.2.200
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // or in the range form:
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            //      1.100.2.200/1.100.3.300
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int i = 0;
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while (i < ip_bytes.length) {
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int digits = 0;
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // the value of the address component
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int value = 0;
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while ((i < ip_bytes.length) && (ip_bytes[i] >= '0')
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && (ip_bytes[i] <= '9')) {
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    digits++;
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (digits > 3) {
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new IOException(Messages.getString("security.18B", ip)); //$NON-NLS-1$
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    value = 10 * value + (ip_bytes[i] - 48);
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    i++;
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (digits == 0) {
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // ip_bytes[i] is not a number
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18C", ip));//$NON-NLS-1$
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result[component] = (byte) value;
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                component++;
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i >= ip_bytes.length) {
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // no more bytes
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the reached delimiter
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((ip_bytes[i] != '.' && ip_bytes[i] != '/')) {
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18C", ip)); //$NON-NLS-1$
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the correctness of the range
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (ip_bytes[i] == '/') {
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (reading_second_bound) {
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // more than 2 bounds in the range
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new IOException(Messages.getString("security.18C", ip)); //$NON-NLS-1$
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (component != 4) {
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    reading_second_bound = true;
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // check the number of the components
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (component > ((reading_second_bound) ? 7 : 3)) {
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                i++;
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // check the number of read components
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (component != num_components) {
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.18D", ip)); //$NON-NLS-1$
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // IPv6 address is expected in the form of
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // colon hexadecimal notation:
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // 010a:020b:3337:1000:FFFA:ABCD:9999:0000
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // or in a range form:
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // 010a:020b:3337:1000:FFFA:ABCD:9999:0000/010a:020b:3337:1000:FFFA:ABCD:9999:1111
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ip_bytes.length != 39 && ip_bytes.length != 79) {
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // incorrect length of the string representation
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int value = 0;
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // indicates the reading of the second half of byte
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean second_hex = false;
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if the delimiter (':' or '/') is expected
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean expect_delimiter = false;
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<ip_bytes.length; i++) {
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte bytik = ip_bytes[i];
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((bytik >= '0') && (bytik <= '9')) {
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    value = (bytik - 48); // '0':0, '1':1, ... , '9':9
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if ((bytik >= 'A') && (bytik <= 'F')) {
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    value = (bytik - 55); // 'A':10, 'B':11, ... , 'F':15
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if ((bytik >= 'a') && (bytik <= 'f')) {
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    value = (bytik - 87); // 'a':10, 'b':11, ... , 'f':15
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (second_hex) {
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // second hex value of a byte is expected but was not read
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // (it is the situation like: ...ABCD:A:ABCD...)
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if ((bytik == ':') || (bytik == '/')) {
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (component % 2 == 1) {
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // second byte of the component is omitted
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // (it is the situation like: ... ABDC:AB:ABCD ...)
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (bytik == '/') {
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (reading_second_bound) {
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // more than 2 bounds in the range
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            throw new IOException(
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    Messages.getString("security.18E", ip)); //$NON-NLS-1$
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (component != 16) {
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            // check the number of read components
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            throw new IOException(Messages.getString("security.18F", ip)); //$NON-NLS-1$
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        reading_second_bound = true;
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    expect_delimiter = false;
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    continue;
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (expect_delimiter) { // delimiter is expected but was not read
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!second_hex) {
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // first half of byte has been read
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result[component] = (byte) (value << 4);
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    second_hex = true;
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else {
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // second half of byte has been read
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result[component] = (byte)
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        ((result[component] & 0xFF) | value);
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // delimiter is expected if 2 bytes were read
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    expect_delimiter = (component % 2 == 1);
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    second_hex = false;
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    component++;
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // check the correctness of the read address:
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (second_hex || (component % 2 == 1)) {
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IOException(Messages.getString("security.18E", ip)); //$NON-NLS-1$
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Helper method. Converts the byte array representation of ip address
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to the String.
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param   ip :   byte array representation of ip address
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If the length of byte array 4 then it represents an IP v4
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  and the output String will be in the dotted quad form.
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If the length is 16 then it represents an IP v6
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  and the output String will be returned in format "p1:p2:...:p8",
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  where p1-p8 are hexadecimal values representing the eight 16-bit
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  pieces of the address.
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  If the length is 8 or 32 then it represents an address range (RFC 1519)
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *  and the output String will contain 2 IP address divided by "/"
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return  String representation of ip address
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static String ipBytesToStr(byte[] ip) {
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String result = ""; //$NON-NLS-1$
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (ip.length < 9) { // IP v4
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<ip.length; i++) {
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result += Integer.toString(ip[i] & 0xff);
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (i != ip.length-1) {
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result += (i == 3) ? "/": "."; //$NON-NLS-1$ //$NON-NLS-2$
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<ip.length; i++) {
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result += Integer.toHexString(0x00ff & ip[i]);
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((i % 2 != 0) && (i != ip.length-1)) {
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result += (i == 15) ? "/": ":"; //$NON-NLS-1$ //$NON-NLS-2$
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final ASN1Choice ASN1 = new ASN1Choice(new ASN1Type[] {
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(0, OtherName.ASN1),
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(1, ASN1StringType.IA5STRING),
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(2, ASN1StringType.IA5STRING),
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(3, ORAddress.ASN1),
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(4, Name.ASN1),
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(5, EDIPartyName.ASN1),
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(6, ASN1StringType.IA5STRING),
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(7, ASN1OctetString.getInstance()),
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project           new ASN1Implicit(8, ASN1Oid.getInstance()) }) {
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object getObjectToEncode(Object value) {
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return ((GeneralName) value).name;
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public int getIndex(java.lang.Object object) {
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return  ((GeneralName) object).tag;
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object getDecodedObject(BerInputStream in) throws IOException {
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            GeneralName result;
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            switch (in.choiceIndex) {
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case OTHER_NAME: // OtherName
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((OtherName) in.content);
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case RFC822_NAME: // rfc822Name
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case DNS_NAME: // dNSName
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName(in.choiceIndex, (String) in.content);
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case X400_ADDR:
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((ORAddress) in.content);
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case DIR_NAME: // directoryName (X.500 Name)
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((Name) in.content);
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case EDIP_NAME: // ediPartyName
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((EDIPartyName) in.content);
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case UR_ID: // uniformResourceIdentifier
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String uri = (String) in.content;
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (uri.indexOf(":") == -1) { //$NON-NLS-1$
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new IOException(
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            Messages.getString("security.190", uri)); //$NON-NLS-1$
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName(in.choiceIndex, uri);
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case IP_ADDR: // iPAddress
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName((byte[]) in.content);
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                case REG_ID: // registeredID
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result = new GeneralName(in.choiceIndex,
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            ObjectIdentifier.toString((int[]) in.content));
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    break;
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                default:
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throw new IOException(Messages.getString("security.191", in.choiceIndex)); //$NON-NLS-1$
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.encoding = in.getEncoded();
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return result;
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    };
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // public static void printAsHex(int perLine,
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         String prefix,
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         String delimiter,
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         byte[] data) {
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     for (int i=0; i<data.length; i++) {
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         String tail = Integer.toHexString(0x000000ff & data[i]);
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         if (tail.length() == 1) {
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //             tail = "0" + tail;
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         }
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         System.out.print(prefix + "0x" + tail + delimiter);
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         if (((i+1)%perLine) == 0) {
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //             System.out.println();
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //         }
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     }
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println();
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // public static void main(String[] args) {
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println(">> "+new BigInteger(new byte[] {(byte)23, (byte)255}).toString(2));
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130}));
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     ipStrToBytes("1.2.3.4");
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     ipStrToBytes("1.2.3.4/4.3.2.1");
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //     printAsHex(8, "", " ", ipStrToBytes("ff17:8082:ff17:8082:ff17:8082:ff17:8082/ff17:8082:ff17:8082:ff17:8082:ff17:8082"));
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // }
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
946