jdk/src/share/classes/sun/security/jgss/GSSHeader.java
author weijun
Wed, 07 Nov 2012 14:13:01 +0800
changeset 14413 e954df027393
parent 5506 202f599c92aa
child 24969 afa6934dd8e8
permissions -rw-r--r--
6355584: Introduce constrained Kerberos delegation Reviewed-by: valeriep
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
2
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
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
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
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
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.jgss;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import org.ietf.jgss.GSSException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.OutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import sun.security.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * This class represents the mechanism independent part of a GSS-API
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * context establishment token. Some mechanisms may choose to encode
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * all subsequent tokens as well such that they start with an encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * of an instance of this class. e.g., The Kerberos v5 GSS-API Mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * uses this header for all GSS-API tokens.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * The format is specified in RFC 2743 section 3.1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * @author Mayank Upadhyay
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * The RFC states that implementations should explicitly follow the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * encoding scheme descibed in this section rather than use ASN.1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * compilers. However, we should consider removing duplicate ASN.1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * like code from here and depend on sun.security.util if possible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
public class GSSHeader {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    private ObjectIdentifier mechOid = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private byte[] mechOidBytes = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private int mechTokenLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     * The tag defined in the GSS-API mechanism independent token
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * format.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    public static final int TOKEN_ID=0x60;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     * Creates a GSSHeader instance whose encoding can be used as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * prefix for a particular mechanism token.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     * @param mechOid the Oid of the mechanism which generated the token
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     * @param mechTokenLength the length of the subsequent portion that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * the mechanism will be adding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    public GSSHeader(ObjectIdentifier mechOid, int mechTokenLength)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        this.mechOid = mechOid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        DerOutputStream temp = new DerOutputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        temp.putOID(mechOid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        mechOidBytes = temp.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        this.mechTokenLength = mechTokenLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * Reads in a GSSHeader from an InputStream. Typically this would be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * used as part of reading the complete token from an InputStream
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * that is obtained from a socket.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    public GSSHeader(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        throws IOException, GSSException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        //      debug("Parsing GSS token: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        int tag = is.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        //      debug("tag=" + tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        if (tag != TOKEN_ID)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
            throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                                   "GSSHeader did not find the right tag");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        int length = getLength(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        DerValue temp = new DerValue(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        mechOidBytes = temp.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        mechOid = temp.getOID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        //      debug (" oid=" + mechOid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        //      debug (" len starting with oid=" + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        mechTokenLength = length - mechOidBytes.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        //      debug("  mechToken length=" + mechTokenLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Used to obtain the Oid stored in this GSSHeader instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * @return the Oid of the mechanism.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public ObjectIdentifier getOid() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        return mechOid;
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
     * Used to obtain the length of the mechanism specific token that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * will follow the encoding of this GSSHeader instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * @return the length of the mechanism specific token portion that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * will follow this GSSHeader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    public int getMechTokenLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        return mechTokenLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * Used to obtain the length of the encoding of this GSSHeader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * @return the lenght of the encoding of this GSSHeader instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    public int getLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        int lenField = mechOidBytes.length + mechTokenLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        return (1 + getLenFieldSize(lenField) + mechOidBytes.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * Used to determine what the maximum possible mechanism token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * size is if the complete GSSToken returned to the application
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * (including a GSSHeader) is not to exceed some pre-determined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * value in size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * @param mechOid the Oid of the mechanism that will generate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * this GSS-API token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * @param maxTotalSize the pre-determined value that serves as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * maximum size for the complete GSS-API token (including a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * GSSHeader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * @return the maximum size of mechanism token that can be used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * so as to not exceed maxTotalSize with the GSS-API token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    public static int getMaxMechTokenSize(ObjectIdentifier mechOid,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                                          int maxTotalSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        int mechOidBytesSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            DerOutputStream temp = new DerOutputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            temp.putOID(mechOid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            mechOidBytesSize = temp.toByteArray().length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        // Subtract bytes needed for 0x60 tag and mechOidBytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        maxTotalSize -= (1 + mechOidBytesSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        // Subtract maximum len bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        maxTotalSize -= 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        return maxTotalSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         * Len field and mechanism token must fit in remaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         * space. The range of the len field that we allow is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
         * 1 through 5.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
         int mechTokenSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
         for (int lenFieldSize = 1; lenFieldSize <= 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
         lenFieldSize++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         mechTokenSize = maxTotalSize - lenFieldSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         if (getLenFieldSize(mechTokenSize + mechOidBytesSize +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
         lenFieldSize) <= lenFieldSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
         break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
         return mechTokenSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
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
     * Used to determine the number of bytes that will be need to encode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * the length field of the GSSHeader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private int getLenFieldSize(int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        int retVal = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        if (len < 128) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            retVal=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        } else if (len < (1 << 8)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            retVal=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        } else if (len < (1 << 16)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            retVal=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        } else if (len < (1 << 24)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            retVal=4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            retVal=5; // See getMaxMechTokenSize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        return retVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * Encodes this GSSHeader instance onto the provided OutputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * @param os the OutputStream to which the token should be written.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * @return the number of bytes that are output as a result of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    public int encode(OutputStream os) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        int retVal = 1 + mechOidBytes.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        os.write(TOKEN_ID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        int length = mechOidBytes.length + mechTokenLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        retVal += putLength(length, os);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        os.write(mechOidBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        return retVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * Get a length from the input stream, allowing for at most 32 bits of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * encoding to be used. (Not the same as getting a tagged integer!)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * @return the length or -1 if indefinite length found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * @exception IOException on parsing error or unsupported lengths.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    // shameless lifted from sun.security.util.DerInputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    private int getLength(InputStream in) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        return getLength(in.read(), in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * Get a length from the input stream, allowing for at most 32 bits of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * encoding to be used. (Not the same as getting a tagged integer!)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * @return the length or -1 if indefinite length found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * @exception IOException on parsing error or unsupported lengths.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    // shameless lifted from sun.security.util.DerInputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    private int getLength(int lenByte, InputStream in) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        int value, tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        tmp = lenByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        if ((tmp & 0x080) == 0x00) { // short form, 1 byte datum
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            value = tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        } else {                                         // long form or indefinite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            tmp &= 0x07f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
             * NOTE:  tmp == 0 indicates indefinite length encoded data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
             * tmp > 4 indicates more than 4Gb of data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            if (tmp == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            if (tmp < 0 || tmp > 4)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                throw new IOException("DerInputStream.getLength(): lengthTag="
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                                      + tmp + ", "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                                      + ((tmp < 0) ? "incorrect DER encoding." : "too big."));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            for (value = 0; tmp > 0; tmp --) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                value <<= 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                value += 0x0ff & in.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * Put the encoding of the length in the specified stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * @params len the length of the attribute.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * @param out the outputstream to write the length to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * @return the number of bytes written
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * @exception IOException on writing errors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    // Shameless lifted from sun.security.util.DerOutputStream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    private int putLength(int len, OutputStream out) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        int retVal = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        if (len < 128) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            out.write((byte)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            retVal=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        } else if (len < (1 << 8)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            out.write((byte)0x081);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            out.write((byte)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            retVal=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        } else if (len < (1 << 16)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            out.write((byte)0x082);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            out.write((byte)(len >> 8));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            out.write((byte)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            retVal=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        } else if (len < (1 << 24)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            out.write((byte)0x083);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            out.write((byte)(len >> 16));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            out.write((byte)(len >> 8));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            out.write((byte)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            retVal=4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            out.write((byte)0x084);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            out.write((byte)(len >> 24));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            out.write((byte)(len >> 16));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            out.write((byte)(len >> 8));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            out.write((byte)len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            retVal=5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        return retVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    // XXX Call these two in some central class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    private void debug(String str) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        System.err.print(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    private  String getHexBytes(byte[] bytes, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        StringBuffer sb = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        for (int i = 0; i < len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            int b1 = (bytes[i]>>4) & 0x0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            int b2 = bytes[i] & 0x0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            sb.append(Integer.toHexString(b1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            sb.append(Integer.toHexString(b2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            sb.append(' ');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
}