1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Alexander V. Esin, Stepan M. Mishura 19 * @version $Revision$ 20 */ 21 22 package org.apache.harmony.security.utils; 23 24 import java.util.Arrays; 25 26 /** 27 * Instance of this class represents ObjectIdentifier (OID). 28 * 29 * OID is represented as a sequence of subidentifier. 30 * Each subidentifier is represented as non negative integer value. 31 * There are at least 2 subidentifiers in the sequence. 32 * 33 * Valid values for first subidentifier are 0, 1 and 2. 34 * If the first subidentifier has 0 or 1 value the second 35 * subidentifier MUST be less then 40. 36 * 37 * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a> 38 */ 39 40 public final class ObjectIdentifier { 41 42 //OID as array of integers 43 private final int[] oid; 44 45 //hash code 46 private int hash = -1; 47 48 //OID as string 49 private String soid; 50 51 // stores the following: "OID." + soid 52 private String sOID; 53 54 // OID alias name 55 private String name; 56 57 // OID's group 58 private Object group; 59 60 /** 61 * Creates ObjectIdentifier(OID) from array of integers. 62 * 63 * @param oid - array of integers 64 * @return - OID object 65 * @throws NullPointerException - if oid is null 66 * @throws IllegalArgumentException - if oid is invalid 67 */ 68 public ObjectIdentifier(int[] oid) { 69 70 validateOid(oid); 71 72 this.oid = oid; 73 } 74 75 /** 76 * Creates ObjectIdentifier(OID) from array of integers. 77 * 78 * @param oid - array of integers 79 * @param name - name of OID 80 * @param oidGroup - OID's group. Is used to separate different OID's 81 * @return - OID object 82 * @throws NullPointerException - if oid is null 83 * @throws IllegalArgumentException - if oid is invalid 84 */ 85 public ObjectIdentifier(int[] oid, String name, Object oidGroup) { 86 this(oid); 87 88 if (oidGroup == null) { 89 throw new NullPointerException("oidGroup == null"); 90 } 91 this.group = oidGroup; 92 93 this.name = name; 94 toOIDString(); // init soid & sOID 95 } 96 97 /** 98 * Gets OID. 99 * 100 * @return oid 101 */ 102 public int[] getOid() { 103 return oid; 104 } 105 106 /** 107 * Gets OID's name. 108 * 109 * @return name 110 */ 111 public String getName() { 112 return name; 113 } 114 115 /** 116 * Gets OID's group. 117 * 118 * @return group 119 */ 120 public Object getGroup() { 121 return group; 122 } 123 124 /** 125 * Compares object with OID for equality. 126 * 127 * @return true if object is ObjectIdentifier and it has the same 128 * representation as array of integers, otherwise false 129 */ 130 public boolean equals(Object o) { 131 if (this == o) { 132 return true; 133 } 134 if (o == null || this.getClass() != o.getClass()) { 135 return false; 136 } 137 return Arrays.equals(oid, ((ObjectIdentifier) o).oid); 138 } 139 140 /** 141 * Add "OID." to the beginning of string representation. 142 * 143 * @return oid as string 144 */ 145 public String toOIDString() { 146 if (sOID == null) { 147 sOID = "OID." + toString(); 148 } 149 return sOID; 150 } 151 152 /** 153 * Overrides Object.toString() 154 * 155 * @return oid as string 156 */ 157 public String toString() { 158 if (soid == null) { 159 StringBuilder sb = new StringBuilder(4 * oid.length); 160 161 for (int i = 0; i < oid.length - 1; ++i) { 162 sb.append(oid[i]); 163 sb.append('.'); 164 } 165 sb.append(oid[oid.length - 1]); 166 soid = sb.toString(); 167 } 168 return soid; 169 } 170 171 /** 172 * @see java.lang.Object#hashCode() 173 */ 174 public int hashCode() { 175 if (hash == -1) { 176 hash = hashIntArray(oid); 177 } 178 return hash; 179 } 180 181 /** 182 * Validates ObjectIdentifier (OID). 183 * 184 * @param oid - oid as array of integers 185 * @throws NullPointerException - if oid is null 186 * @throws IllegalArgumentException - if oid is invalid 187 */ 188 public static void validateOid(int[] oid) { 189 190 if (oid == null) { 191 throw new NullPointerException("oid == null"); 192 } 193 194 if (oid.length < 2) { 195 throw new IllegalArgumentException("OID MUST have at least 2 subidentifiers"); 196 } 197 198 if (oid[0] > 2) { 199 throw new IllegalArgumentException("Valid values for first subidentifier are 0, 1 and 2"); 200 } else if (oid[0] != 2 && oid[1] > 39) { 201 throw new IllegalArgumentException("If the first subidentifier has 0 or 1 value the second subidentifier value MUST be less than 40"); 202 } 203 } 204 205 /** 206 * Returns hash code for array of integers 207 * 208 * @param oid - array of integers 209 */ 210 public static int hashIntArray(int[] array) { 211 int intHash = 0; 212 for (int i = 0; i < array.length && i < 4; i++) { 213 intHash += array[i] << (8 * i); //TODO what about to find better one? 214 } 215 return intHash & 0x7FFFFFFF; // only positive 216 } 217 } 218