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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [OID.java] - Blame information for rev 769

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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