Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.security.jgss/share/classes/sun/security/jgss/GSSHeader.java
41159 views
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
if (value < 0) {
274
throw new IOException("Invalid length bytes");
275
}
276
}
277
return value;
278
}
279
280
/**
281
* Put the encoding of the length in the specified stream.
282
*
283
* @params len the length of the attribute.
284
* @param out the outputstream to write the length to
285
* @return the number of bytes written
286
* @exception IOException on writing errors.
287
*/
288
// Shameless lifted from sun.security.util.DerOutputStream.
289
private int putLength(int len, OutputStream out) throws IOException {
290
int retVal = 0;
291
if (len < 128) {
292
out.write((byte)len);
293
retVal=1;
294
295
} else if (len < (1 << 8)) {
296
out.write((byte)0x081);
297
out.write((byte)len);
298
retVal=2;
299
300
} else if (len < (1 << 16)) {
301
out.write((byte)0x082);
302
out.write((byte)(len >> 8));
303
out.write((byte)len);
304
retVal=3;
305
306
} else if (len < (1 << 24)) {
307
out.write((byte)0x083);
308
out.write((byte)(len >> 16));
309
out.write((byte)(len >> 8));
310
out.write((byte)len);
311
retVal=4;
312
313
} else {
314
out.write((byte)0x084);
315
out.write((byte)(len >> 24));
316
out.write((byte)(len >> 16));
317
out.write((byte)(len >> 8));
318
out.write((byte)len);
319
retVal=5;
320
}
321
322
return retVal;
323
}
324
325
// XXX Call these two in some central class
326
private void debug(String str) {
327
System.err.print(str);
328
}
329
330
private String getHexBytes(byte[] bytes, int len)
331
throws IOException {
332
333
StringBuilder sb = new StringBuilder();
334
for (int i = 0; i < len; i++) {
335
336
int b1 = (bytes[i]>>4) & 0x0f;
337
int b2 = bytes[i] & 0x0f;
338
339
sb.append(Integer.toHexString(b1));
340
sb.append(Integer.toHexString(b2));
341
sb.append(' ');
342
}
343
return sb.toString();
344
}
345
}
346
347