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 package org.apache.geronimo.crypto.asn1; 19 20 import java.io.ByteArrayOutputStream; 21 import java.io.IOException; 22 import java.io.OutputStream; 23 24 public class DERObjectIdentifier 25 extends DERObject 26 { 27 String identifier; 28 29 /** 30 * return an OID from the passed in object 31 * 32 * @exception IllegalArgumentException if the object cannot be converted. 33 */ 34 public static DERObjectIdentifier getInstance( 35 Object obj) 36 { 37 if (obj == null || obj instanceof DERObjectIdentifier) 38 { 39 return (DERObjectIdentifier)obj; 40 } 41 42 if (obj instanceof ASN1OctetString) 43 { 44 return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets()); 45 } 46 47 if (obj instanceof ASN1TaggedObject) 48 { 49 return getInstance(((ASN1TaggedObject)obj).getObject()); 50 } 51 52 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 53 } 54 55 /** 56 * return an Object Identifier from a tagged object. 57 * 58 * @param obj the tagged object holding the object we want 59 * @param explicit true if the object is meant to be explicitly 60 * tagged false otherwise. 61 * @exception IllegalArgumentException if the tagged object cannot 62 * be converted. 63 */ 64 public static DERObjectIdentifier getInstance( 65 ASN1TaggedObject obj, 66 boolean explicit) 67 { 68 return getInstance(obj.getObject()); 69 } 70 71 72 DERObjectIdentifier( 73 byte[] bytes) 74 { 75 StringBuffer objId = new StringBuffer(); 76 long value = 0; 77 boolean first = true; 78 79 for (int i = 0; i != bytes.length; i++) 80 { 81 int b = bytes[i] & 0xff; 82 83 value = value * 128 + (b & 0x7f); 84 if ((b & 0x80) == 0) // end of number reached 85 { 86 if (first) 87 { 88 switch ((int)value / 40) 89 { 90 case 0: 91 objId.append('0'); 92 break; 93 case 1: 94 objId.append('1'); 95 value -= 40; 96 break; 97 default: 98 objId.append('2'); 99 value -= 80; 100 } 101 first = false; 102 } 103 104 objId.append('.'); 105 objId.append(Long.toString(value)); 106 value = 0; 107 } 108 } 109 110 this.identifier = objId.toString(); 111 } 112 113 public DERObjectIdentifier( 114 String identifier) 115 { 116 for (int i = identifier.length() - 1; i >= 0; i--) 117 { 118 char ch = identifier.charAt(i); 119 120 if ('0' <= ch && ch <= '9') 121 { 122 continue; 123 } 124 125 if (ch == '.') 126 { 127 continue; 128 } 129 130 throw new IllegalArgumentException("string " + identifier + " not an OID"); 131 } 132 133 this.identifier = identifier; 134 } 135 136 public String getId() 137 { 138 return identifier; 139 } 140 141 private void writeField( 142 OutputStream out, 143 long fieldValue) 144 throws IOException 145 { 146 if (fieldValue >= (1 << 7)) 147 { 148 if (fieldValue >= (1 << 14)) 149 { 150 if (fieldValue >= (1 << 21)) 151 { 152 if (fieldValue >= (1 << 28)) 153 { 154 if (fieldValue >= (1 << 35)) 155 { 156 if (fieldValue >= (1 << 42)) 157 { 158 if (fieldValue >= (1 << 49)) 159 { 160 if (fieldValue >= (1 << 56)) 161 { 162 out.write((int)(fieldValue >> 56) | 0x80); 163 } 164 out.write((int)(fieldValue >> 49) | 0x80); 165 } 166 out.write((int)(fieldValue >> 42) | 0x80); 167 } 168 out.write((int)(fieldValue >> 35) | 0x80); 169 } 170 out.write((int)(fieldValue >> 28) | 0x80); 171 } 172 out.write((int)(fieldValue >> 21) | 0x80); 173 } 174 out.write((int)(fieldValue >> 14) | 0x80); 175 } 176 out.write((int)(fieldValue >> 7) | 0x80); 177 } 178 out.write((int)fieldValue & 0x7f); 179 } 180 181 void encode( 182 DEROutputStream out) 183 throws IOException 184 { 185 OIDTokenizer tok = new OIDTokenizer(identifier); 186 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 187 DEROutputStream dOut = new DEROutputStream(bOut); 188 189 writeField(bOut, 190 Integer.parseInt(tok.nextToken()) * 40 191 + Integer.parseInt(tok.nextToken())); 192 193 while (tok.hasMoreTokens()) 194 { 195 writeField(bOut, Long.parseLong(tok.nextToken())); 196 } 197 198 dOut.close(); 199 200 byte[] bytes = bOut.toByteArray(); 201 202 out.writeEncoded(OBJECT_IDENTIFIER, bytes); 203 } 204 205 public int hashCode() 206 { 207 return identifier.hashCode(); 208 } 209 210 public boolean equals( 211 Object o) 212 { 213 if ((o == null) || !(o instanceof DERObjectIdentifier)) 214 { 215 return false; 216 } 217 218 return identifier.equals(((DERObjectIdentifier)o).identifier); 219 } 220 221 public String toString() 222 { 223 return getId(); 224 } 225 }