001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.asn1; 019 020 import java.io.ByteArrayOutputStream; 021 import java.io.IOException; 022 import java.io.OutputStream; 023 024 public class DERObjectIdentifier 025 extends DERObject 026 { 027 String identifier; 028 029 /** 030 * return an OID from the passed in object 031 * 032 * @exception IllegalArgumentException if the object cannot be converted. 033 */ 034 public static DERObjectIdentifier getInstance( 035 Object obj) 036 { 037 if (obj == null || obj instanceof DERObjectIdentifier) 038 { 039 return (DERObjectIdentifier)obj; 040 } 041 042 if (obj instanceof ASN1OctetString) 043 { 044 return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets()); 045 } 046 047 if (obj instanceof ASN1TaggedObject) 048 { 049 return getInstance(((ASN1TaggedObject)obj).getObject()); 050 } 051 052 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 053 } 054 055 /** 056 * return an Object Identifier from a tagged object. 057 * 058 * @param obj the tagged object holding the object we want 059 * @param explicit true if the object is meant to be explicitly 060 * tagged false otherwise. 061 * @exception IllegalArgumentException if the tagged object cannot 062 * be converted. 063 */ 064 public static DERObjectIdentifier getInstance( 065 ASN1TaggedObject obj, 066 boolean explicit) 067 { 068 return getInstance(obj.getObject()); 069 } 070 071 072 DERObjectIdentifier( 073 byte[] bytes) 074 { 075 StringBuffer objId = new StringBuffer(); 076 long value = 0; 077 boolean first = true; 078 079 for (int i = 0; i != bytes.length; i++) 080 { 081 int b = bytes[i] & 0xff; 082 083 value = value * 128 + (b & 0x7f); 084 if ((b & 0x80) == 0) // end of number reached 085 { 086 if (first) 087 { 088 switch ((int)value / 40) 089 { 090 case 0: 091 objId.append('0'); 092 break; 093 case 1: 094 objId.append('1'); 095 value -= 40; 096 break; 097 default: 098 objId.append('2'); 099 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 }