001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.geronimo.util.asn1; 020 021 import java.io.ByteArrayOutputStream; 022 import java.io.IOException; 023 import java.io.OutputStream; 024 025 public class DERObjectIdentifier 026 extends DERObject 027 { 028 String identifier; 029 030 /** 031 * return an OID from the passed in object 032 * 033 * @exception IllegalArgumentException if the object cannot be converted. 034 */ 035 public static DERObjectIdentifier getInstance( 036 Object obj) 037 { 038 if (obj == null || obj instanceof DERObjectIdentifier) 039 { 040 return (DERObjectIdentifier)obj; 041 } 042 043 if (obj instanceof ASN1OctetString) 044 { 045 return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets()); 046 } 047 048 if (obj instanceof ASN1TaggedObject) 049 { 050 return getInstance(((ASN1TaggedObject)obj).getObject()); 051 } 052 053 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 054 } 055 056 /** 057 * return an Object Identifier from a tagged object. 058 * 059 * @param obj the tagged object holding the object we want 060 * @param explicit true if the object is meant to be explicitly 061 * tagged false otherwise. 062 * @exception IllegalArgumentException if the tagged object cannot 063 * be converted. 064 */ 065 public static DERObjectIdentifier getInstance( 066 ASN1TaggedObject obj, 067 boolean explicit) 068 { 069 return getInstance(obj.getObject()); 070 } 071 072 073 DERObjectIdentifier( 074 byte[] bytes) 075 { 076 StringBuffer objId = new StringBuffer(); 077 long value = 0; 078 boolean first = true; 079 080 for (int i = 0; i != bytes.length; i++) 081 { 082 int b = bytes[i] & 0xff; 083 084 value = value * 128 + (b & 0x7f); 085 if ((b & 0x80) == 0) // end of number reached 086 { 087 if (first) 088 { 089 switch ((int)value / 40) 090 { 091 case 0: 092 objId.append('0'); 093 break; 094 case 1: 095 objId.append('1'); 096 value -= 40; 097 break; 098 default: 099 objId.append('2'); 100 value -= 80; 101 } 102 first = false; 103 } 104 105 objId.append('.'); 106 objId.append(Long.toString(value)); 107 value = 0; 108 } 109 } 110 111 this.identifier = objId.toString(); 112 } 113 114 public DERObjectIdentifier( 115 String identifier) 116 { 117 for (int i = identifier.length() - 1; i >= 0; i--) 118 { 119 char ch = identifier.charAt(i); 120 121 if ('0' <= ch && ch <= '9') 122 { 123 continue; 124 } 125 126 if (ch == '.') 127 { 128 continue; 129 } 130 131 throw new IllegalArgumentException("string " + identifier + " not an OID"); 132 } 133 134 this.identifier = identifier; 135 } 136 137 public String getId() 138 { 139 return identifier; 140 } 141 142 private void writeField( 143 OutputStream out, 144 long fieldValue) 145 throws IOException 146 { 147 if (fieldValue >= (1 << 7)) 148 { 149 if (fieldValue >= (1 << 14)) 150 { 151 if (fieldValue >= (1 << 21)) 152 { 153 if (fieldValue >= (1 << 28)) 154 { 155 if (fieldValue >= (1 << 35)) 156 { 157 if (fieldValue >= (1 << 42)) 158 { 159 if (fieldValue >= (1 << 49)) 160 { 161 if (fieldValue >= (1 << 56)) 162 { 163 out.write((int)(fieldValue >> 56) | 0x80); 164 } 165 out.write((int)(fieldValue >> 49) | 0x80); 166 } 167 out.write((int)(fieldValue >> 42) | 0x80); 168 } 169 out.write((int)(fieldValue >> 35) | 0x80); 170 } 171 out.write((int)(fieldValue >> 28) | 0x80); 172 } 173 out.write((int)(fieldValue >> 21) | 0x80); 174 } 175 out.write((int)(fieldValue >> 14) | 0x80); 176 } 177 out.write((int)(fieldValue >> 7) | 0x80); 178 } 179 out.write((int)fieldValue & 0x7f); 180 } 181 182 void encode( 183 DEROutputStream out) 184 throws IOException 185 { 186 OIDTokenizer tok = new OIDTokenizer(identifier); 187 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 188 DEROutputStream dOut = new DEROutputStream(bOut); 189 190 writeField(bOut, 191 Integer.parseInt(tok.nextToken()) * 40 192 + Integer.parseInt(tok.nextToken())); 193 194 while (tok.hasMoreTokens()) 195 { 196 writeField(bOut, Long.parseLong(tok.nextToken())); 197 } 198 199 dOut.close(); 200 201 byte[] bytes = bOut.toByteArray(); 202 203 out.writeEncoded(OBJECT_IDENTIFIER, bytes); 204 } 205 206 public int hashCode() 207 { 208 return identifier.hashCode(); 209 } 210 211 public boolean equals( 212 Object o) 213 { 214 if ((o == null) || !(o instanceof DERObjectIdentifier)) 215 { 216 return false; 217 } 218 219 return identifier.equals(((DERObjectIdentifier)o).identifier); 220 } 221 222 public String toString() 223 { 224 return getId(); 225 } 226 }