History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/jgss/GSSHeader.java (1 of 18352 files). Show all

Unified · Split

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