OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [security/] [OID.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* OID.java -- numeric representation of an object identifier
2
   Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.security;
40
 
41
import gnu.java.security.der.DEREncodingException;
42
 
43
import java.io.ByteArrayOutputStream;
44
import java.io.IOException;
45
import java.io.InputStream;
46
import java.util.StringTokenizer;
47
 
48
/**
49
 * This immutable class represents an object identifier, or OID.
50
 *
51
 * <p>OIDs are represented as a series of hierarchical tokens, each of
52
 * which is usually represented as a single, unsigned integer. The
53
 * hierarchy works so that later tokens are considered within the group
54
 * of earlier tokens. Thus, the OID for the Serpent block cipher,
55
 * 1.3.6.1.4.1.11591.13.2, is maintained by the GNU project, whose OID
56
 * is 1.3.6.1.4.1.11591 (which is, in turn, part of bigger, more general
57
 * bodies; the topmost, 1, stands for the OIDs assigned by the
58
 * International Standards Organization, ISO).
59
 *
60
 * <p>OIDs can be represented in a variety of ways, including the
61
 * dotted-decimal form we use here.
62
 *
63
 * <p>OIDs may be relative, in which case the first two elements of the
64
 * OID are omitted.
65
 *
66
 * @author Casey Marshall (csm@gnu.org)
67
 */
68
public class OID implements Cloneable, Comparable, java.io.Serializable
69
{
70
 
71
  // Fields.
72
  // ------------------------------------------------------------------------
73
 
74
  /**
75
   * The numeric ID structure.
76
   */
77
  private int[] components;
78
 
79
  /**
80
   * The string representation of this OID, in dotted-decimal format.
81
   */
82
  private transient String strRep;
83
 
84
  /**
85
   * The DER encoding of this OID.
86
   */
87
  private transient byte[] der;
88
 
89
  /**
90
   * Whether or not this OID is relative.
91
   */
92
  private boolean relative;
93
 
94
  // Constructors.
95
  // ------------------------------------------------------------------------
96
 
97
  /**
98
   * Create a new OID from the given byte array. The argument (which can
99
   * neither be null nor zero-length) is copied to prevent subsequent
100
   * modification.
101
   *
102
   * @param components The numeric IDs.
103
   * @throws IllegalArgumentException If <i>components</i> is null or empty.
104
   */
105
  public OID(int[] components)
106
  {
107
    this(components, false);
108
  }
109
 
110
  /**
111
   * Create a new OID from the given byte array. The argument (which can
112
   * neither be null nor zero-length) is copied to prevent subsequent
113
   * modification.
114
   *
115
   * @param components The numeric IDs.
116
   * @param relative The relative flag.
117
   * @throws IllegalArgumentException If <i>components</i> is null or empty.
118
   */
119
  public OID(int[] components, boolean relative)
120
  {
121
    if (components == null || components.length == 0)
122
      throw new IllegalArgumentException();
123
    this.components = (int[]) components.clone();
124
    this.relative = relative;
125
  }
126
 
127
  /**
128
   * Create a new OID from the given dotted-decimal representation.
129
   *
130
   * @param strRep The string representation of the OID.
131
   * @throws IllegalArgumentException If the string does not contain at
132
   * least one integer.
133
   * @throws NumberFormatException If the string does not contain only
134
   * numbers and periods ('.').
135
   */
136
  public OID(String strRep)
137
  {
138
    this(strRep, false);
139
  }
140
 
141
  /**
142
   * Create a new OID from the given dotted-decimal representation.
143
   *
144
   * @param strRep The string representation of the OID.
145
   * @param relative The relative flag.
146
   * @throws IllegalArgumentException If the string does not contain at
147
   * least one integer.
148
   * @throws NumberFormatException If the string does not contain only
149
   * numbers and periods ('.').
150
   */
151
  public OID(String strRep, boolean relative)
152
  {
153
    this.relative = relative;
154
    this.strRep = strRep;
155
    components = fromString(strRep);
156
  }
157
 
158
  /**
159
   * Construct a new OID from the DER bytes in an input stream. This method
160
   * does not read the tag or the length field from the input stream, so
161
   * the caller must supply the number of octets in this OID's encoded
162
   * form.
163
   *
164
   * @param derIn The DER input stream.
165
   * @param len   The number of bytes in the encoded form.
166
   * @throws IOException If an error occurs reading the OID.
167
   */
168
  public OID(InputStream derIn, int len) throws IOException
169
  {
170
    this(derIn, len, false);
171
  }
172
 
173
  /**
174
   * Construct a new OID from the DER bytes in an input stream. This method
175
   * does not read the tag or the length field from the input stream, so
176
   * the caller must supply the number of octets in this OID's encoded
177
   * form.
178
   *
179
   * @param derIn The DER input stream.
180
   * @param len   The number of bytes in the encoded form.
181
   * @param relative The relative flag.
182
   * @throws IOException If an error occurs reading the OID.
183
   */
184
  public OID(InputStream derIn, int len, boolean relative) throws IOException
185
  {
186
    der = new byte[len];
187
    derIn.read(der);
188
    this.relative = relative;
189
    try
190
      {
191
        components = fromDER(der, relative);
192
      }
193
    catch (ArrayIndexOutOfBoundsException aioobe)
194
      {
195
        aioobe.printStackTrace();
196
        throw aioobe;
197
      }
198
  }
199
 
200
  /**
201
   * Construct a new OID from the given DER bytes.
202
   *
203
   * @param encoded The DER encoded OID.
204
   * @throws IOException If an error occurs reading the OID.
205
   */
206
  public OID(byte[] encoded) throws IOException
207
  {
208
    this(encoded, false);
209
  }
210
 
211
  /**
212
   * Construct a new OID from the given DER bytes.
213
   *
214
   * @param root The root OID.
215
   * @param encoded The encoded relative OID.
216
   * @param relative The relative flag.
217
   */
218
  public OID(byte[] encoded, boolean relative) throws IOException
219
  {
220
    der = (byte[]) encoded.clone();
221
    this.relative = relative;
222
    try
223
      {
224
        components = fromDER(der, relative);
225
      }
226
    catch (ArrayIndexOutOfBoundsException aioobe)
227
      {
228
        aioobe.printStackTrace();
229
        throw aioobe;
230
      }
231
  }
232
 
233
  /**
234
   * Our private constructor.
235
   */
236
  private OID()
237
  {
238
  }
239
 
240
  // Instance methods.
241
  // ------------------------------------------------------------------------
242
 
243
  /**
244
   * Return the numeric IDs of this OID. The value returned is copied to
245
   * prevent modification.
246
   *
247
   * @return The IDs in a new integer array.
248
   */
249
  public int[] getIDs()
250
  {
251
    return (int[]) components.clone();
252
  }
253
 
254
  /**
255
   * Get the DER encoding of this OID, minus the tag and length fields.
256
   *
257
   * @return The DER bytes.
258
   */
259
  public byte[] getDER()
260
  {
261
    if (der == null)
262
      {
263
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
264
        int i = 0;
265
        if (!relative)
266
          {
267
            int b = components[i++] * 40 + (components.length > 1
268
              ? components[i++] : 0);
269
            encodeSubID(bout, b);
270
          }
271
        for ( ; i < components.length; i++)
272
          encodeSubID(bout, components[i]);
273
        der = bout.toByteArray();
274
      }
275
    return (byte[]) der.clone();
276
  }
277
 
278
  /**
279
   * Get the parent OID of this OID. That is, if this OID is "1.2.3.4",
280
   * then the parent OID will be "1.2.3". If this OID is a top-level
281
   * OID, this method returns null.
282
   *
283
   * @return The parent OID, or null.
284
   */
285
  public OID getParent()
286
  {
287
    if (components.length == 1)
288
      return null;
289
    int[] parent = new int[components.length - 1];
290
    System.arraycopy(components, 0, parent, 0, parent.length);
291
    return new OID(parent);
292
  }
293
 
294
  public OID getChild(int id)
295
  {
296
    int[] child = new int[components.length + 1];
297
    System.arraycopy(components, 0, child, 0, components.length);
298
    child[child.length - 1] = id;
299
    return new OID(child);
300
  }
301
 
302
  /**
303
   * Get the root OID of this OID. That is, the first two components.
304
   *
305
   * @return The root OID.
306
   */
307
  public OID getRoot()
308
  {
309
    if (components.length <= 2)
310
      return this;
311
    int[] root = new int[2];
312
    root[0] = components[0];
313
    root[1] = components[1];
314
    return new OID(root);
315
  }
316
 
317
  public boolean isRelative()
318
  {
319
    return relative;
320
  }
321
 
322
  /**
323
   * Returns a copy of this OID.
324
   *
325
   * @return The copy.
326
   */
327
  public Object clone()
328
  {
329
    OID oid = new OID();
330
    oid.components = this.components;
331
    oid.strRep = this.strRep;
332
    return oid;
333
  }
334
 
335
  /* Nice idea, but possibly too expensive for whatever benefit it
336
   * provides.
337
 
338
  public String getShortName()
339
  {
340
    return OIDTable.getShortName(this);
341
  }
342
 
343
  public String getLongName()
344
  {
345
    return OIDTable.getLongName(this);
346
  }
347
 
348
  */
349
 
350
  /**
351
   * Returns the value of this OID in dotted-decimal format.
352
   *
353
   * @return The string representation.
354
   */
355
  public String toString()
356
  {
357
    if (strRep != null)
358
      return strRep;
359
    else
360
      {
361
        StringBuffer buf = new StringBuffer();
362
        for (int i = 0; i < components.length; i++)
363
          {
364
            buf.append((long) components[i] & 0xFFFFFFFFL);
365
            if (i < components.length - 1)
366
              buf.append('.');
367
          }
368
        return (strRep = buf.toString());
369
      }
370
  }
371
 
372
  /**
373
   * Computes a hash code for this OID.
374
   *
375
   * @return The hash code.
376
   */
377
  public int hashCode()
378
  {
379
    int ret = 0;
380
    for (int i = 0; i < components.length; i++)
381
      ret += components[i] << (i & 31);
382
    return ret;
383
  }
384
 
385
  /**
386
   * Tests whether or not this OID equals another.
387
   *
388
   * @return Whether or not this OID equals the other.
389
   */
390
  public boolean equals(Object o)
391
  {
392
    if (!(o instanceof OID))
393
      return false;
394
    return java.util.Arrays.equals(components, ((OID) o).components);
395
  }
396
 
397
  /**
398
   * Compares this OID to another. The comparison is essentially
399
   * lexicographic, where the two OIDs are compared until their
400
   * first difference, then that difference is returned. If one OID is
401
   * shorter, but all elements equal between the two for the shorter
402
   * length, then the shorter OID is lesser than the longer.
403
   *
404
   * @param o The object to compare.
405
   * @return An integer less than, equal to, or greater than zero if
406
   *         this object is less than, equal to, or greater than the
407
   *         argument.
408
   * @throws ClassCastException If <i>o</i> is not an OID.
409
   */
410
  public int compareTo(Object o)
411
  {
412
    if (equals(o))
413
      return 0;
414
    int[] components2 = ((OID) o).components;
415
    int len = Math.min(components.length, components2.length);
416
    for (int i = 0; i < len; i++)
417
      {
418
        if (components[i] != components2[i])
419
          return (components[i] < components2[i]) ? -1 : 1;
420
      }
421
    if (components.length == components2.length)
422
      return 0;
423
    return (components.length < components2.length) ? -1 : 1;
424
  }
425
 
426
  // Own methods.
427
  // ------------------------------------------------------------------------
428
 
429
  private static int[] fromDER(byte[] der, boolean relative)
430
    throws DEREncodingException
431
  {
432
    // cannot be longer than this.
433
    int[] components = new int[der.length + 1];
434
    int count = 0;
435
    int i = 0;
436
    if (!relative && i < der.length)
437
      {
438
        // Non-relative OIDs have the first two arcs coded as:
439
        //
440
        //   i = first_arc * 40 + second_arc;
441
        //
442
        int j = (der[i] & 0xFF);
443
        components[count++] = j / 40;
444
        components[count++] = j % 40;
445
        i++;
446
      }
447
    while (i < der.length)
448
      {
449
        int j = 0;
450
        do
451
          {
452
            j = der[i++] & 0xFF;
453
            components[count] <<= 7;
454
            components[count]  |= j & 0x7F;
455
            if (i >= der.length && (j & 0x80) != 0)
456
              throw new DEREncodingException("malformed OID");
457
          }
458
        while ((j & 0x80) != 0);
459
        count++;
460
      }
461
    if (count == components.length)
462
      return components;
463
    int[] ret = new int[count];
464
    System.arraycopy(components, 0, ret, 0, count);
465
    return ret;
466
  }
467
 
468
  private static int[] fromString(String strRep) throws NumberFormatException
469
  {
470
    if (strRep.startsWith("OID.") || strRep.startsWith("oid."))
471
      strRep = strRep.substring(4);
472
    StringTokenizer tok = new StringTokenizer(strRep, ".");
473
    if (tok.countTokens() == 0)
474
      throw new IllegalArgumentException();
475
    int[] components = new int[tok.countTokens()];
476
    int i = 0;
477
    while (tok.hasMoreTokens())
478
      {
479
        components[i++] = Integer.parseInt(tok.nextToken());
480
      }
481
    return components;
482
  }
483
 
484
  private static void encodeSubID(ByteArrayOutputStream out, int id)
485
  {
486
    if (id < 128)
487
      {
488
        out.write(id);
489
      }
490
    else if (id < 16384)
491
      {
492
        out.write((id >>> 7) | 0x80);
493
        out.write(id & 0x7F);
494
      }
495
    else if (id < 2097152)
496
      {
497
        out.write((id >>> 14) | 0x80);
498
        out.write(((id >>> 7) | 0x80) & 0xFF);
499
        out.write(id & 0x7F);
500
      }
501
    else if (id < 268435456)
502
      {
503
        out.write( (id >>> 21) | 0x80);
504
        out.write(((id >>> 14) | 0x80) & 0xFF);
505
        out.write(((id >>>  7) | 0x80) & 0xFF);
506
        out.write(id & 0x7F);
507
      }
508
  }
509
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.