1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.util.asn1;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24
25 public class DERObjectIdentifier
26 extends DERObject
27 {
28 String identifier;
29
30 /**
31 * return an OID from the passed in object
32 *
33 * @exception IllegalArgumentException if the object cannot be converted.
34 */
35 public static DERObjectIdentifier getInstance(
36 Object obj)
37 {
38 if (obj == null || obj instanceof DERObjectIdentifier)
39 {
40 return (DERObjectIdentifier)obj;
41 }
42
43 if (obj instanceof ASN1OctetString)
44 {
45 return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets());
46 }
47
48 if (obj instanceof ASN1TaggedObject)
49 {
50 return getInstance(((ASN1TaggedObject)obj).getObject());
51 }
52
53 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
54 }
55
56 /**
57 * return an Object Identifier from a tagged object.
58 *
59 * @param obj the tagged object holding the object we want
60 * @param explicit true if the object is meant to be explicitly
61 * tagged false otherwise.
62 * @exception IllegalArgumentException if the tagged object cannot
63 * be converted.
64 */
65 public static DERObjectIdentifier getInstance(
66 ASN1TaggedObject obj,
67 boolean explicit)
68 {
69 return getInstance(obj.getObject());
70 }
71
72
73 DERObjectIdentifier(
74 byte[] bytes)
75 {
76 StringBuffer objId = new StringBuffer();
77 long value = 0;
78 boolean first = true;
79
80 for (int i = 0; i != bytes.length; i++)
81 {
82 int b = bytes[i] & 0xff;
83
84 value = value * 128 + (b & 0x7f);
85 if ((b & 0x80) == 0)
86 {
87 if (first)
88 {
89 switch ((int)value / 40)
90 {
91 case 0:
92 objId.append('0');
93 break;
94 case 1:
95 objId.append('1');
96 value -= 40;
97 break;
98 default:
99 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 }