jdk/src/share/classes/sun/security/util/ObjectIdentifier.java
author xuelei
Fri, 20 Feb 2009 12:50:02 +0800
changeset 2060 75e464ce81af
parent 2 90ce3da70b43
child 2584 a89e7cabf6fd
permissions -rw-r--r--
4918870: Examine session cache implementation (sun.misc.Cache) Summary: replace sun.misc.Cache with sun.security.util.Cache Reviewed-by: weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.util;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * Represent an ISO Object Identifier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * <P>Object Identifiers are arbitrary length hierarchical identifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * The individual components are numbers, and they define paths from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * root of an ISO-managed identifier space.  You will sometimes see a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * string name used instead of (or in addition to) the numerical id.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * These are synonyms for the numerical IDs, but are not widely used
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * since most sites do not know all the requisite strings, while all
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * sites can parse the numeric forms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * <P>So for example, JavaSoft has the sole authority to assign the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * meaning to identifiers below the 1.3.6.1.4.1.42.2.17 node in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * hierarchy, and other organizations can easily acquire the ability
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * to assign such unique identifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @author David Brownell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @author Amit Kapoor
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @author Hemma Prafullchandra
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
final public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
class ObjectIdentifier implements Serializable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    /** use serialVersionUID from JDK 1.1. for interoperability */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private static final long serialVersionUID = 8697030238860181294L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static final int maxFirstComponent = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    private static final int maxSecondComponent = 39;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * Constructs an object identifier from a string.  This string
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * should be of the form 1.23.34.45.56 etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    public ObjectIdentifier (String oid) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        int ch = '.';
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        int     start = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        int end = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        // Calculate length of oid
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        componentLen = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        while ((end = oid.indexOf(ch,start)) != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            start = end + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            componentLen += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        componentLen += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        components = new int[componentLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        start = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        int i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        String comp = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            while ((end = oid.indexOf(ch,start)) != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
                comp = oid.substring(start,end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
                components[i++] = Integer.valueOf(comp).intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
                start = end + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            comp = oid.substring(start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            components[i] = Integer.valueOf(comp).intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            throw new IOException("ObjectIdentifier() -- Invalid format: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
                    + e.toString(), e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        checkValidOid(components, componentLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        this.stringForm = oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * Check if the values make a legal OID. There must be at least 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * components and they must be all non-negative. The first component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * should be 0,1 or 2. When the first component is 0 or 1, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * second component should be less than or equal to 39
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * @param values the components that will make the OID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * @param len the number of components to check. Note that the allocation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     *        size of <code>values</code> may be longer than <code>len</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     *        In this case, only the first <code>len</code> items are checked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * @exception IOException if this is not a legal OID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    private void checkValidOid(int[] values, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        if (values == null || len < 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            throw new IOException("ObjectIdentifier() -- " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                    "Must be at least two oid components ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        for (int i=0; i<len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            if (values[i] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                throw new IOException("ObjectIdentifier() -- " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                        "oid component #" + (i+1) + " must be non-negative ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        if (values[0] > maxFirstComponent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            throw new IOException("ObjectIdentifier() -- " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                    "First oid component is invalid ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        if (values[0] < 2 && values[1] > maxSecondComponent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            throw new IOException("ObjectIdentifier() -- " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                    "Second oid component is invalid ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * Constructs an object ID from an array of integers.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * is used to construct constant object IDs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public ObjectIdentifier (int values []) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        checkValidOid(values, values.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        components = values.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        componentLen = values.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * Constructs an object ID from an ASN.1 encoded input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * The encoding of the ID in the stream uses "DER", a BER/1 subset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * In this case, that means a triple { typeId, length, data }.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * <P><STRONG>NOTE:</STRONG>  When an exception is thrown, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * input stream has not been returned to its "initial" state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * @param in DER-encoded data holding an object ID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * @exception IOException indicates a decoding error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    public ObjectIdentifier (DerInputStream in)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        byte    type_id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        int     bufferEnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
         * Object IDs are a "universal" type, and their tag needs only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
         * one byte of encoding.  Verify that the tag of this datum
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
         * is that of an object ID.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
         * Then get and check the length of the ID's encoding.  We set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
         * up so that we can use in.available() to check for the end of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
         * this value in the data stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        type_id = (byte) in.getByte ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        if (type_id != DerValue.tag_ObjectId)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            throw new IOException (
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                "ObjectIdentifier() -- data isn't an object ID"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                + " (tag = " +  type_id + ")"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        bufferEnd = in.available () - in.getLength () - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        if (bufferEnd < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            throw new IOException (
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                "ObjectIdentifier() -- not enough data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        initFromEncoding (in, bufferEnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * Build the OID from the rest of a DER input buffer; the tag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * and length have been removed/verified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    ObjectIdentifier (DerInputBuffer buf) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        initFromEncoding (new DerInputStream (buf), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * Private constructor for use by newInternal(). Dummy argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * to avoid clash with the public constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private ObjectIdentifier(int[] components, boolean dummy) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        this.components = components;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        this.componentLen = components.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * Create a new ObjectIdentifier for internal use. The values are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * neither checked nor cloned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    public static ObjectIdentifier newInternal(int[] values) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        return new ObjectIdentifier(values, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * Helper function -- get the OID from a stream, after tag and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * length are verified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    private void initFromEncoding (DerInputStream in, int bufferEnd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
         * Now get the components ("sub IDs") one at a time.  We fill a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
         * temporary buffer, resizing it as needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        int             component;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        boolean         first_subid = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        for (components = new int [allocationQuantum], componentLen = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                in.available () > bufferEnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            component = getComponent (in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            if (component < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                throw new IOException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    "ObjectIdentifier() -- " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                    "component values must be nonnegative");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            if (first_subid) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                int     X, Y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                 * NOTE:  the allocation quantum is large enough that we know
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                 * we don't have to reallocate here!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                if (component < 40)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                    X = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                else if (component < 80)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                    X = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                    X = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                Y = component - ( X * 40);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                components [0] = X;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                components [1] = Y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                componentLen = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                first_subid = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                 * Other components are encoded less exotically.  The only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                 * potential trouble is the need to grow the array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                if (componentLen >= components.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                    int         tmp_components [];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                    tmp_components = new int [components.length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                                        + allocationQuantum];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                    System.arraycopy (components, 0, tmp_components, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                            components.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                    components = tmp_components;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                components [componentLen++] = component;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        checkValidOid(components, componentLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         * Final sanity check -- if we didn't use exactly the number of bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         * specified, something's quite wrong.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        if (in.available () != bufferEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            throw new IOException (
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                    "ObjectIdentifier() -- malformed input data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * n.b. the only public interface is DerOutputStream.putOID()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    void encode (DerOutputStream out) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        DerOutputStream bytes = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        // According to ISO X.660, when the 1st component is 0 or 1, the 2nd
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        // component is restricted to be less than or equal to 39, thus make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        // it small enough to be encoded into one single byte.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        if (components[0] < 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            bytes.write ((components [0] * 40) + components [1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            putComponent(bytes, (components [0] * 40) + components [1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        for (i = 2; i < componentLen; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            putComponent (bytes, components [i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
         * Now that we've constructed the component, encode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
         * it in the stream we were given.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        out.write (DerValue.tag_ObjectId, bytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * Tricky OID component parsing technique ... note that one bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * per octet is lost, this returns at most 28 bits of component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * Also, notice this parses in big-endian format.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    private static int getComponent (DerInputStream in)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        int retval, i, tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        for (i = 0, retval = 0; i < 4; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            retval <<= 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            tmp = in.getByte ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            retval |= (tmp & 0x07f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            if ((tmp & 0x080) == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        throw new IOException ("ObjectIdentifier() -- component value too big");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * Reverse of the above routine.  Notice it needs to emit in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     * big-endian form, so it buffers the output until it's ready.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * (Minimum length encoding is a DER requirement.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    private static void putComponent (DerOutputStream out, int val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        int     i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        // TODO: val must be <128*128*128*128 here, otherwise, 4 bytes is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        // enough to hold it. Will address this later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        byte    buf [] = new byte [4] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        for (i = 0; i < 4; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            buf [i] = (byte) (val & 0x07f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            val >>>= 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            if (val == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        for ( ; i > 0; --i)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            out.write (buf [i] | 0x080);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        out.write (buf [0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    // XXX this API should probably facilitate the JDK sort utility
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * Compares this identifier with another, for sorting purposes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * An identifier does not precede itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * @param other identifer that may precede this one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * @return true iff <em>other</em> precedes this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     *          in a particular sorting order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    public boolean precedes (ObjectIdentifier other)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        int             i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        // shorter IDs go first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (other == this || componentLen < other.componentLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        if (other.componentLen < componentLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        // for each component, the lesser component goes first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        for (i = 0; i < componentLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            if (other.components [i] < components [i])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        // identical IDs don't precede each other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * @deprecated Use equals((Object)oid)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    @Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    public boolean equals(ObjectIdentifier other) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        return equals((Object)other);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * Compares this identifier with another, for equality.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * @return true iff the names are identical.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    public boolean equals(Object obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        if (this == obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        if (obj instanceof ObjectIdentifier == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        ObjectIdentifier other = (ObjectIdentifier)obj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        if (componentLen != other.componentLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        for (int i = 0; i < componentLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            if (components[i] != other.components[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        int h = componentLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        for (int i = 0; i < componentLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            h += components[i] * 37;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        return h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * Returns a string form of the object ID.  The format is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * conventional "dot" notation for such IDs, without any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * user-friendly descriptive strings, since those strings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * will not be understood everywhere.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        String s = stringForm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        if (s == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            StringBuffer sb = new StringBuffer(componentLen * 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            for (int i = 0; i < componentLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                if (i != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                    sb.append('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                sb.append(components[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            s = sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
            stringForm = s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * To simplify, we assume no individual component of an object ID is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * larger than 32 bits.  Then we represent the path from the root as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * an array that's (usually) only filled at the beginning.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    private int         components [];                  // path from root
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    private int         componentLen;                   // how much is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    private transient volatile String stringForm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    private static final int allocationQuantum = 5;     // >= 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
}