1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Vladimir N. Molotkov, Alexander Y. Kleymenov 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$ 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/ 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.security.x509; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 266ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilsonimport java.net.InetAddress; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URI; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URISyntaxException; 296ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilsonimport java.net.UnknownHostException; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays; 3228d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Rootimport java.util.Collection; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 35fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstromimport java.util.Locale; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Choice; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Implicit; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1OctetString; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Oid; 4128d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Rootimport org.apache.harmony.security.asn1.ASN1SequenceOf; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1StringType; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1Type; 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.BerInputStream; 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ObjectIdentifier; 464b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughesimport org.apache.harmony.security.utils.Array; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x501.Name; 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 50f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * The class encapsulates the ASN.1 DER encoding/decoding work 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the GeneralName structure which is a part of X.509 certificate 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (as specified in RFC 3280 - 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Internet X.509 Public Key Infrastructure. 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Certificate and Certificate Revocation List (CRL) Profile. 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.ietf.org/rfc/rfc3280.txt): 56f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 58f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * GeneralName::= CHOICE { 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherName [0] OtherName, 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * rfc822Name [1] IA5String, 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dNSName [2] IA5String, 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * x400Address [3] ORAddress, 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directoryName [4] Name, 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ediPartyName [5] EDIPartyName, 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * uniformResourceIdentifier [6] IA5String, 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * iPAddress [7] OCTET STRING, 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * registeredID [8] OBJECT IDENTIFIER 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 70f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OtherName::= SEQUENCE { 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * type-id OBJECT IDENTIFIER, 73f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * value [0] EXPLICIT ANY DEFINED BY type-id 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 75f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * EDIPartyName::= SEQUENCE { 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * nameAssigner [0] DirectoryString OPTIONAL, 78f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * partyName [1] DirectoryString 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * DirectoryString::= CHOICE { 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * teletexString TeletexString (SIZE (1..MAX)), 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * printableString PrintableString (SIZE (1..MAX)), 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * universalString UniversalString (SIZE (1..MAX)), 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * utf8String UTF8String (SIZE (1..MAX)), 86f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * bmpString BMPString (SIZE (1..MAX)) 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 88f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 90f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 916ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * <p>This class doesn't support masked addresses like "10.9.8.0/255.255.255.0". 926ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * These are only necessary for NameConstraints, which are not exposed in the 936ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * Java certificate API. 946ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.NameConstraints 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see org.apache.harmony.security.x509.GeneralSubtree 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 985c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilsonpublic final class GeneralName { 99f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The values of the tags of fields 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int OTHER_NAME = 0; 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int RFC822_NAME = 1; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DNS_NAME = 2; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int X400_ADDR = 3; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DIR_NAME = 4; 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int EDIP_NAME = 5; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int UR_ID = 6; 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int IP_ADDR = 7; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int REG_ID = 8; 112f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ASN1 encoders/decoders for name choices 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static ASN1Type[] nameASN1 = new ASN1Type[9]; 115f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[OTHER_NAME] = OtherName.ASN1; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[RFC822_NAME] = ASN1StringType.IA5STRING; 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[DNS_NAME] = ASN1StringType.IA5STRING; 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[UR_ID] = ASN1StringType.IA5STRING; 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[X400_ADDR] = ORAddress.ASN1; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[DIR_NAME] = Name.ASN1; 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[EDIP_NAME] = EDIPartyName.ASN1; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[IP_ADDR] = ASN1OctetString.getInstance(); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nameASN1[REG_ID] = ASN1Oid.getInstance(); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 1285c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** the tag of the name type */ 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int tag; 1305c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** the name value (can be String or byte array) */ 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object name; 1325c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** the ASN.1 encoded form of GeneralName */ 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] encoding; 1345c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** the ASN.1 encoded form of GeneralName's field */ 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] name_encoding; 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Makes the GeneralName object from the tag type and corresponding 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * well established string representation of the name value. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The String representation of [7] iPAddress is such as: 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For IP v4, as specified in RFC 791, the address must 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contain exactly 4 byte component. For IP v6, as specified in 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * RFC 1883, the address must contain exactly 16 byte component. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If GeneralName structure is used as a part of Name Constraints 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * extension, to represent an address range the number of address 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * component is doubled (to 8 and 32 bytes respectively). 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that the names: 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [0] otherName, [3] x400Address, [5] ediPartyName 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * have no the string representation, so exception will be thrown. 150f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * To make the GeneralName object with such names use another constructor. 151f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @param tag is an integer which value corresponds to the name type. 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name is a name value corresponding to the tag. 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(int tag, String name) throws IOException { 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 156897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("name == null"); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = tag; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tag) { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME : 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR : 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME : 163897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Unknown string representation for type [" + tag + "]"); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME : 165f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // according to RFC 3280 p.34 the DNS name should be 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // checked against the 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // RFC 1034 p.10 (3.5. Preferred name syntax): 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkDNS(name); 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID : 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the uniformResourceIdentifier for correctness 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // according to RFC 3280 p.34 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkURI(name); 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME : 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = oidStrToInts(name); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DIR_NAME : 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = new Name(name); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case IP_ADDR : 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = ipStrToBytes(name); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 190897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Unknown type: [" + tag + "]"); 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(OtherName name) { 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = OTHER_NAME; 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(ORAddress name) { 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = X400_ADDR; 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(Name name) { 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = DIR_NAME; 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(EDIPartyName name) { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = EDIP_NAME; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = name; 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 214f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * Constructor for type [7] iPAddress. 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name is an array of bytes such as: 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For IP v4, as specified in RFC 791, the address must 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contain exactly 4 byte component. For IP v6, as specified in 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * RFC 1883, the address must contain exactly 16 byte component. 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If GeneralName structure is used as a part of Name Constraints 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * extension, to represent an address range the number of address 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * component is doubled (to 8 and 32 bytes respectively). 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public GeneralName(byte[] name) throws IllegalArgumentException { 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = IP_ADDR; 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = new byte[name.length]; 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(name, 0, this.name, 0, name.length); 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs an object representing the value of GeneralName. 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tag is an integer which value corresponds 232f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * to the name type (0-8), 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name is a DER encoded for of the name value 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 235897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes public GeneralName(int tag, byte[] name) throws IOException { 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 237897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new NullPointerException("name == null"); 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((tag < 0) || (tag > 8)) { 240897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("GeneralName: unknown tag: " + tag); 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tag = tag; 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name_encoding = new byte[name.length]; 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(name, 0, this.name_encoding, 0, name.length); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.name = nameASN1[tag].decode(this.name_encoding); 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 247f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the tag of the name in the structure 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getTag() { 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return tag; 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 256f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @return the value of the name. 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The class of name object depends on the tag as follows: 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [0] otherName - OtherName object, 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [1] rfc822Name - String object, 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [2] dNSName - String object, 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [3] x400Address - ORAddress object, 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [4] directoryName - instance of Name object, 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [5] ediPartyName - EDIPartyName object, 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [6] uniformResourceIdentifier - String object, 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [7] iPAddress - array of bytes such as: 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For IP v4, as specified in RFC 791, the address must 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contain exactly 4 byte component. For IP v6, as specified in 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * RFC 1883, the address must contain exactly 16 byte component. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If GeneralName structure is used as a part of Name Constraints 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * extension, to represent an address range the number of address 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * component is doubled (to 8 and 32 bytes respectively). 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * [8] registeredID - String. 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object getName() { 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name; 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 277f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 2785c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson public boolean equals(Object other) { 2795c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson if (!(other instanceof GeneralName)) { 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2825c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson GeneralName gname = (GeneralName) other; 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (this.tag != gname.tag) { 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch(tag) { 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME: 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME: 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID: 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((String) name).equalsIgnoreCase( 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (String) gname.getName()); 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Arrays.equals((int[]) name, (int[]) gname.name); 294f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case IP_ADDR: 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // iPAddress [7], check by using ranges. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Arrays.equals((byte[]) name, (byte[]) gname.name); 297f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case DIR_NAME: 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR: 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME: 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME: 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Arrays.equals(getEncoded(), gname.getEncoded()); 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // should never happen 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 307f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 3089efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes public int hashCode() { 3099efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes switch (tag) { 3109efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case RFC822_NAME: 3119efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case DNS_NAME: 3129efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case UR_ID: 3139efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case REG_ID: 3149efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case IP_ADDR: 3159efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes return name.hashCode(); 3169efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case DIR_NAME: 3179efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case X400_ADDR: 3189efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case OTHER_NAME: 3199efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes case EDIP_NAME: 320196f44e24830d0e7fd17eba627704a162eba779eElliott Hughes return Arrays.hashCode(getEncoded()); 3219efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes default: 3229efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes return super.hashCode(); 3239efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes } 3249efa300c26865520498c0ed132ff9ebe499e7d84Elliott Hughes } 325f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks if the other general name is acceptable by this object. 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The name is acceptable if it has the same type name and its 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name value is equal to name value of this object. Also the name 330f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * is acceptable if this general name object is a part of name 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constraints and the specified name is satisfied the restriction 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provided by this object (for more detail see section 4.2.1.11 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of rfc 3280). 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Note that for X400Address [3] check procedure is unclear so method 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * just checks the equality of encoded forms. 336f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * For otherName [0], ediPartyName [5], and registeredID [8] 337f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * the check procedure if not defined by rfc 3280 and for names of 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * these types this method also checks only for equality of encoded forms. 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isAcceptable(GeneralName gname) { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (this.tag != gname.getTag()) { 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (this.tag) { 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME: 346f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // Mail address [1]: 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // a@b.c - particular address is acceptable by the same address, 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // or by b.c - host name. 349fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom return ((String) gname.getName()).toLowerCase(Locale.US) 350fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom .endsWith(((String) name).toLowerCase(Locale.US)); 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME: 352f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // DNS name [2] that can be constructed by simply adding 353f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // to the left hand side of the name satisfies the name 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // constraint: aaa.aa.aa satisfies to aaa.aa.aa, aa.aa, .. 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String dns = (String) name; 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String _dns = (String) gname.getName(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (dns.equalsIgnoreCase(_dns)) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 360fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom return _dns.toLowerCase(Locale.US).endsWith("." + dns.toLowerCase(Locale.US)); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID: 363f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // For URIs the constraint ".xyz.com" is satisfied by both 364f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // abc.xyz.com and abc.def.xyz.com. However, the constraint 365f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // ".xyz.com" is not satisfied by "xyz.com". 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // When the constraint does not begin with a period, it 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // specifies a host. 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Extract the host from URI: 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String uri = (String) name; 370f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes int begin = uri.indexOf("://")+3; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int end = uri.indexOf('/', begin); 372f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String host = (end == -1) 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? uri.substring(begin) 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : uri.substring(begin, end); 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project uri = (String) gname.getName(); 376f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes begin = uri.indexOf("://")+3; 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project end = uri.indexOf('/', begin); 378f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String _host = (end == -1) 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? uri.substring(begin) 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : uri.substring(begin, end); 381f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (host.startsWith(".")) { 382fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom return _host.toLowerCase(Locale.US).endsWith(host.toLowerCase(Locale.US)); 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return host.equalsIgnoreCase(_host); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case IP_ADDR: 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // iPAddress [7], check by using ranges. 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] address = (byte[]) name; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] _address = (byte[]) gname.getName(); 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int length = address.length; 3913b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root 3923b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root /* 3933b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * For IP v4, as specified in RFC 791, the address must contain 3943b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * exactly 4 byte component. For IP v6, as specified in RFC 3953b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * 1883, the address must contain exactly 16 byte component. If 3963b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * GeneralName structure is used as a part of Name Constraints 3973b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * extension, to represent an address range the number of 3983b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * address component is doubled (to 8 and 32 bytes 3993b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * respectively). 4003b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root */ 4013b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root if (length != 4 && length != 8 && length != 16 && length != 32) { 4023b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root return false; 4033b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root } 4043b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int _length = _address.length; 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (length == _length) { 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Arrays.equals(address, _address); 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (length == 2*_length) { 409fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom for (int i = 0; i < _address.length; i++) { 4106ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson // TODO: should the 2nd IP address be treated as a range or as a mask? 4116ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson int octet = _address[i] & 0xff; 4126ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson int min = address[i] & 0xff; 4136ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson int max = address[i + _length] & 0xff; 4146ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson if ((octet < min) || (octet > max)) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case DIR_NAME: 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME: false: 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // directoryName according to 4.1.2.4 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // comparing the encoded forms of the names 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //TODO: 427f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes //Legacy implementations exist where an RFC 822 name 428f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes //is embedded in the subject distinguished name in an 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //attribute of type EmailAddress 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR: 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME: 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME: 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Arrays.equals(getEncoded(), gname.getEncoded()); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // should never happen 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list representation of this GeneralName object. 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The first entry of the list is an Integer object representing 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the type of mane (0-8), and the second entry is a value of the name: 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * string or ASN.1 DER encoded form depending on the type as follows: 446f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * rfc822Name, dNSName, uniformResourceIdentifier names are returned 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as Strings, using the string formats for those types (rfc 3280) 448f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * IP v4 address names are returned using dotted quad notation. 449f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * IP v6 address names are returned in the form "p1:p2:...:p8", 450f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * where p1-p8 are hexadecimal values representing the eight 16-bit 451f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * pieces of the address. registeredID name are returned as Strings 452f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * represented as a series of nonnegative integers separated by periods. 453f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * And directory names (distinguished names) are returned in 454f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * RFC 2253 string format. 455f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * otherName, X400Address, ediPartyName returned as byte arrays 456f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * containing the ASN.1 DER encoded form of the name. 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4585c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson public List<Object> getAsList() { 4595c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson ArrayList<Object> result = new ArrayList<Object>(); 460fb0ec0e650bf8be35acb0d47da0311a7c446aa33Elliott Hughes result.add(tag); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tag) { 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME: 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(((OtherName) name).getEncoded()); 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME: 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME: 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID: 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(name); // String 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(ObjectIdentifier.toString((int[]) name)); 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR: 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(((ORAddress) name).getEncoded()); 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DIR_NAME: // directoryName is returned as a String 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(((Name) name).getName(X500Principal.RFC2253)); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME: 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(((EDIPartyName) name).getEncoded()); 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case IP_ADDR: //iPAddress is returned as a String, not as a byte array 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(ipBytesToStr((byte[]) name)); 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // should never happen 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Collections.unmodifiableList(result); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 492f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes String result = ""; 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (tag) { 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME: 495f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "otherName[0]: " 4964b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes + Array.getBytesAsString(getEncoded()); 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME: 499f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "rfc822Name[1]: " + name; 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME: 502f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "dNSName[2]: " + name; 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID: 505f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "uniformResourceIdentifier[6]: " + name; 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: 508f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "registeredID[8]: " + ObjectIdentifier.toString((int[]) name); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR: 511f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "x400Address[3]: " 5124b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes + Array.getBytesAsString(getEncoded()); 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 514f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case DIR_NAME: 515f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "directoryName[4]: " 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + ((Name) name).getName(X500Principal.RFC2253); 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME: 519f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "ediPartyName[5]: " 5204b25199bc0b7a64a6feaa60e7d5d6b0474341234Elliott Hughes + Array.getBytesAsString(getEncoded()); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 522f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes case IP_ADDR: 523f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = "iPAddress[7]: " + ipBytesToStr((byte[]) name); 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // should never happen 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 530f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns ASN.1 encoded form of this X.509 GeneralName value. 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getEncoded() { 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (encoding == null) { 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project encoding = ASN1.encode(this); 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return encoding; 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 542f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @return the encoded value of the name without the tag associated 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the name in the GeneralName structure 544f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws IOException 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getEncodedName() { 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name_encoding == null) { 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name_encoding = nameASN1[tag].encode(name); 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name_encoding; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 5548626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * Checks the correctness of the string representation of DNS name as 5558626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * specified in RFC 1034 p. 10 and RFC 1123 section 2.1. 5568626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * 5578626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * <p>This permits a wildcard character '*' anywhere in the name; it is up 5588626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * to the application to check which wildcards are permitted. See RFC 6125 5598626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson * for recommended wildcard matching rules. 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static void checkDNS(String dns) throws IOException { 562fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom String string = dns.toLowerCase(Locale.US); 563fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom int length = string.length(); 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if it is a first letter of the label 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean first_letter = true; 566fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom for (int i = 0; i < length; i++) { 567fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom char ch = string.charAt(i); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (first_letter) { 5698626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson if ((ch > 'z' || ch < 'a') && (ch < '0' || ch > '9') && (ch != '*')) { 570897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("DNS name must start with a letter: " + dns); 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project first_letter = false; 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') 5768626012f833cada8b06c3d82860d2dbe4107ce7aJesse Wilson || (ch == '-') || (ch == '.') || (ch == '*'))) { 577897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Incorrect DNS name: " + dns); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ch == '.') { 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the end of the previous label, it should not 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // be '-' sign 582fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom if (string.charAt(i-1) == '-') { 583897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Incorrect DNS name: label ends with '-': " + dns); 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project first_letter = true; 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks the correctness of the string representation of URI name. 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The correctness is checked as pointed out in RFC 3280 p. 34. 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static void checkURI(String uri) throws IOException { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project URI ur = new URI(uri); 597897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes if (ur.getScheme() == null || ur.getRawSchemeSpecificPart().isEmpty()) { 598897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("No scheme or scheme-specific-part in uniformResourceIdentifier: " + uri); 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!ur.isAbsolute()) { 601897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Relative uniformResourceIdentifier: " + uri); 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (URISyntaxException e) { 604897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw (IOException) new IOException("Bad representation of uniformResourceIdentifier: " + uri).initCause(e); 605f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 610fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom * Converts OID into array of ints. 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static int[] oidStrToInts(String oid) throws IOException { 613fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom int length = oid.length(); 614fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom if (oid.charAt(length-1) == '.') { 615897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Bad OID: " + oid); 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 617fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom int[] result = new int[length/2+1]; // best case: a.b.c.d.e 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int number = 0; // the number of OID's components 619fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom for (int i = 0; i < length; i++) { 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int value = 0; 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos = i; 622fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom for (; i < length; i++) { 623fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom char ch = oid.charAt(i); 624fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom if ((ch < '0') || (ch > '9')) { 625fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom break; 626fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom } 627fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom value = 10 * value + (ch - '0'); 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == pos) { 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // the number was not read 631897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Bad OID: " + oid); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result[number++] = value; 634fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom if (i == length) { 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 637fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom char ch = oid.charAt(i); 638fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom if (ch != '.') { 639897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("Bad OID: " + oid); 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (number < 2) { 643897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("OID should consist of no less than 2 components: " + oid); 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 645fe921473907c2388cf13d014dd3bcf32d2b6d04aBrian Carlstrom return Arrays.copyOfRange(result, 0, number); 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 6496ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson * Returns the bytes of the given IP address or masked IP address. 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static byte[] ipStrToBytes(String ip) throws IOException { 6526ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson if (!InetAddress.isNumeric(ip)) { 6536ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson throw new IOException("Not an IP address: " + ip); 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6556ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson return InetAddress.getByName(ip).getAddress(); 656897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes } 657f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 6593b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * Returns the string form of the given IP address. If the address is not 4 6603b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * octets for IPv4 or 16 octets for IPv6, an IllegalArgumentException will 6613b14c4bd5c7ce28ed3485bd24285c58424c074afKenny Root * be thrown. 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static String ipBytesToStr(byte[] ip) { 6646ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson try { 6656ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson return InetAddress.getByAddress(null, ip).getHostAddress(); 6666ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson } catch (UnknownHostException e) { 6676ed93fa8be996378e766d3fd2586b51c6fe656b1Jesse Wilson throw new IllegalArgumentException("Unexpected IP address: " + Arrays.toString(ip)); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 670f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 67128d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root /** 67228d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root * The "Name" is actually a CHOICE of one entry, so we need to pretend it's 67328d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root * a SEQUENCE OF and just grab the first entry. 67428d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root */ 67528d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root private static final ASN1SequenceOf NAME_ASN1 = new ASN1SequenceOf(Name.ASN1) { 67628d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root @Override 67728d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root public Object decode(BerInputStream in) throws IOException { 67828d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root return ((List<?>) super.decode(in)).get(0); 67928d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root } 68028d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root }; 68128d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final ASN1Choice ASN1 = new ASN1Choice(new ASN1Type[] { 683f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes new ASN1Implicit(0, OtherName.ASN1), 684f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes new ASN1Implicit(1, ASN1StringType.IA5STRING), 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(2, ASN1StringType.IA5STRING), 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(3, ORAddress.ASN1), 68728d504c4188a5d25a7209e4d1c131e0afffa1fcfKenny Root new ASN1Implicit(4, NAME_ASN1), 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(5, EDIPartyName.ASN1), 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(6, ASN1StringType.IA5STRING), 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(7, ASN1OctetString.getInstance()), 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new ASN1Implicit(8, ASN1Oid.getInstance()) }) { 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object getObjectToEncode(Object value) { 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((GeneralName) value).name; 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 696f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getIndex(java.lang.Object object) { 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return ((GeneralName) object).tag; 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7015c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson @Override public Object getDecodedObject(BerInputStream in) throws IOException { 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project GeneralName result; 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (in.choiceIndex) { 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case OTHER_NAME: // OtherName 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName((OtherName) in.content); 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case RFC822_NAME: // rfc822Name 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DNS_NAME: // dNSName 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName(in.choiceIndex, (String) in.content); 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case X400_ADDR: 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName((ORAddress) in.content); 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case DIR_NAME: // directoryName (X.500 Name) 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName((Name) in.content); 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case EDIP_NAME: // ediPartyName 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName((EDIPartyName) in.content); 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case UR_ID: // uniformResourceIdentifier 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String uri = (String) in.content; 722f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (uri.indexOf(":") == -1) { 723897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("GeneralName: scheme is missing in URI: " + uri); 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName(in.choiceIndex, uri); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case IP_ADDR: // iPAddress 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = new GeneralName((byte[]) in.content); 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case REG_ID: // registeredID 731f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result = new GeneralName(in.choiceIndex, 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectIdentifier.toString((int[]) in.content)); 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 735897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IOException("GeneralName: unknown tag: " + in.choiceIndex); 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.encoding = in.getEncoded(); 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 742