Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java
38923 views
1
/*
2
* Copyright (c) 2005, 2009, 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.wrapper;
27
28
import org.ietf.jgss.*;
29
import java.security.Provider;
30
import sun.security.jgss.GSSHeader;
31
import sun.security.jgss.GSSUtil;
32
import sun.security.jgss.GSSExceptionImpl;
33
import sun.security.jgss.spi.*;
34
import sun.security.util.DerValue;
35
import sun.security.util.ObjectIdentifier;
36
import sun.security.jgss.spnego.NegTokenInit;
37
import sun.security.jgss.spnego.NegTokenTarg;
38
import javax.security.auth.kerberos.DelegationPermission;
39
import com.sun.security.jgss.InquireType;
40
import java.io.*;
41
42
43
/**
44
* This class is essentially a wrapper class for the gss_ctx_id_t
45
* structure of the native GSS library.
46
* @author Valerie Peng
47
* @since 1.6
48
*/
49
class NativeGSSContext implements GSSContextSpi {
50
51
private static final int GSS_C_DELEG_FLAG = 1;
52
private static final int GSS_C_MUTUAL_FLAG = 2;
53
private static final int GSS_C_REPLAY_FLAG = 4;
54
private static final int GSS_C_SEQUENCE_FLAG = 8;
55
private static final int GSS_C_CONF_FLAG = 16;
56
private static final int GSS_C_INTEG_FLAG = 32;
57
private static final int GSS_C_ANON_FLAG = 64;
58
private static final int GSS_C_PROT_READY_FLAG = 128;
59
private static final int GSS_C_TRANS_FLAG = 256;
60
61
private static final int NUM_OF_INQUIRE_VALUES = 6;
62
63
private long pContext = 0; // Pointer to the gss_ctx_id_t structure
64
private GSSNameElement srcName;
65
private GSSNameElement targetName;
66
private GSSCredElement cred;
67
private boolean isInitiator;
68
private boolean isEstablished;
69
private Oid actualMech; // Assigned during context establishment
70
71
private ChannelBinding cb;
72
private GSSCredElement delegatedCred;
73
private int flags;
74
private int lifetime = GSSCredential.DEFAULT_LIFETIME;
75
private final GSSLibStub cStub;
76
77
private boolean skipDelegPermCheck;
78
private boolean skipServicePermCheck;
79
80
// Retrieve the (preferred) mech out of SPNEGO tokens, i.e.
81
// NegTokenInit & NegTokenTarg
82
private static Oid getMechFromSpNegoToken(byte[] token,
83
boolean isInitiator)
84
throws GSSException {
85
Oid mech = null;
86
if (isInitiator) {
87
GSSHeader header = null;
88
try {
89
header = new GSSHeader(new ByteArrayInputStream(token));
90
} catch (IOException ioe) {
91
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
92
}
93
int negTokenLen = header.getMechTokenLength();
94
byte[] negToken = new byte[negTokenLen];
95
System.arraycopy(token, token.length-negTokenLen,
96
negToken, 0, negToken.length);
97
98
NegTokenInit ntok = new NegTokenInit(negToken);
99
if (ntok.getMechToken() != null) {
100
Oid[] mechList = ntok.getMechTypeList();
101
mech = mechList[0];
102
}
103
} else {
104
NegTokenTarg ntok = new NegTokenTarg(token);
105
mech = ntok.getSupportedMech();
106
}
107
return mech;
108
}
109
110
// Perform the Service permission check
111
private void doServicePermCheck() throws GSSException {
112
if (System.getSecurityManager() != null) {
113
String action = (isInitiator? "initiate" : "accept");
114
// Need to check Service permission for accessing
115
// initiator cred for SPNEGO during context establishment
116
if (GSSUtil.isSpNegoMech(cStub.getMech()) && isInitiator
117
&& !isEstablished) {
118
if (srcName == null) {
119
// Check by creating default initiator KRB5 cred
120
GSSCredElement tempCred =
121
new GSSCredElement(null, lifetime,
122
GSSCredential.INITIATE_ONLY,
123
GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID));
124
tempCred.dispose();
125
} else {
126
String tgsName = Krb5Util.getTGSName(srcName);
127
Krb5Util.checkServicePermission(tgsName, action);
128
}
129
}
130
String targetStr = targetName.getKrbName();
131
Krb5Util.checkServicePermission(targetStr, action);
132
skipServicePermCheck = true;
133
}
134
}
135
136
// Perform the Delegation permission check
137
private void doDelegPermCheck() throws GSSException {
138
SecurityManager sm = System.getSecurityManager();
139
if (sm != null) {
140
String targetStr = targetName.getKrbName();
141
String tgsStr = Krb5Util.getTGSName(targetName);
142
StringBuffer buf = new StringBuffer("\"");
143
buf.append(targetStr).append("\" \"");
144
buf.append(tgsStr).append('\"');
145
String krbPrincPair = buf.toString();
146
SunNativeProvider.debug("Checking DelegationPermission (" +
147
krbPrincPair + ")");
148
DelegationPermission perm =
149
new DelegationPermission(krbPrincPair);
150
sm.checkPermission(perm);
151
skipDelegPermCheck = true;
152
}
153
}
154
155
private byte[] retrieveToken(InputStream is, int mechTokenLen)
156
throws GSSException {
157
try {
158
byte[] result = null;
159
if (mechTokenLen != -1) {
160
// Need to add back the GSS header for a complete GSS token
161
SunNativeProvider.debug("Precomputed mechToken length: " +
162
mechTokenLen);
163
GSSHeader gssHeader = new GSSHeader
164
(new ObjectIdentifier(cStub.getMech().toString()),
165
mechTokenLen);
166
ByteArrayOutputStream baos = new ByteArrayOutputStream(600);
167
168
byte[] mechToken = new byte[mechTokenLen];
169
int len = is.read(mechToken);
170
assert(mechTokenLen == len);
171
gssHeader.encode(baos);
172
baos.write(mechToken);
173
result = baos.toByteArray();
174
} else {
175
// Must be unparsed GSS token or SPNEGO's NegTokenTarg token
176
assert(mechTokenLen == -1);
177
DerValue dv = new DerValue(is);
178
result = dv.toByteArray();
179
}
180
SunNativeProvider.debug("Complete Token length: " +
181
result.length);
182
return result;
183
} catch (IOException ioe) {
184
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
185
}
186
}
187
188
// Constructor for context initiator
189
NativeGSSContext(GSSNameElement peer, GSSCredElement myCred,
190
int time, GSSLibStub stub) throws GSSException {
191
if (peer == null) {
192
throw new GSSException(GSSException.FAILURE, 1, "null peer");
193
}
194
cStub = stub;
195
cred = myCred;
196
targetName = peer;
197
isInitiator = true;
198
lifetime = time;
199
200
if (GSSUtil.isKerberosMech(cStub.getMech())) {
201
doServicePermCheck();
202
if (cred == null) {
203
cred = new GSSCredElement(null, lifetime,
204
GSSCredential.INITIATE_ONLY, cStub);
205
}
206
srcName = cred.getName();
207
}
208
}
209
210
// Constructor for context acceptor
211
NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)
212
throws GSSException {
213
cStub = stub;
214
cred = myCred;
215
216
if (cred != null) targetName = cred.getName();
217
218
isInitiator = false;
219
// Defer Service permission check for default acceptor cred
220
// to acceptSecContext()
221
if (GSSUtil.isKerberosMech(cStub.getMech()) && targetName != null) {
222
doServicePermCheck();
223
}
224
225
// srcName and potentially targetName (when myCred is null)
226
// will be set in GSSLibStub.acceptContext(...)
227
}
228
229
// Constructor for imported context
230
NativeGSSContext(long pCtxt, GSSLibStub stub) throws GSSException {
231
assert(pContext != 0);
232
pContext = pCtxt;
233
cStub = stub;
234
235
// Set everything except cred, cb, delegatedCred
236
long[] info = cStub.inquireContext(pContext);
237
if (info.length != NUM_OF_INQUIRE_VALUES) {
238
throw new RuntimeException("Bug w/ GSSLibStub.inquireContext()");
239
}
240
srcName = new GSSNameElement(info[0], cStub);
241
targetName = new GSSNameElement(info[1], cStub);
242
isInitiator = (info[2] != 0);
243
isEstablished = (info[3] != 0);
244
flags = (int) info[4];
245
lifetime = (int) info[5];
246
247
// Do Service Permission check when importing SPNEGO context
248
// just to be safe
249
Oid mech = cStub.getMech();
250
if (GSSUtil.isSpNegoMech(mech) || GSSUtil.isKerberosMech(mech)) {
251
doServicePermCheck();
252
}
253
}
254
255
public Provider getProvider() {
256
return SunNativeProvider.INSTANCE;
257
}
258
259
public byte[] initSecContext(InputStream is, int mechTokenLen)
260
throws GSSException {
261
byte[] outToken = null;
262
if ((!isEstablished) && (isInitiator)) {
263
byte[] inToken = null;
264
// Ignore the specified input stream on the first call
265
if (pContext != 0) {
266
inToken = retrieveToken(is, mechTokenLen);
267
SunNativeProvider.debug("initSecContext=> inToken len=" +
268
inToken.length);
269
}
270
271
if (!getCredDelegState()) skipDelegPermCheck = true;
272
273
if (GSSUtil.isKerberosMech(cStub.getMech()) && !skipDelegPermCheck) {
274
doDelegPermCheck();
275
}
276
277
long pCred = (cred == null? 0 : cred.pCred);
278
outToken = cStub.initContext(pCred, targetName.pName,
279
cb, inToken, this);
280
SunNativeProvider.debug("initSecContext=> outToken len=" +
281
(outToken == null ? 0 : outToken.length));
282
283
// Only inspect the token when the permission check
284
// has not been performed
285
if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) {
286
// WORKAROUND for SEAM bug#6287358
287
actualMech = getMechFromSpNegoToken(outToken, true);
288
289
if (GSSUtil.isKerberosMech(actualMech)) {
290
if (!skipServicePermCheck) doServicePermCheck();
291
if (!skipDelegPermCheck) doDelegPermCheck();
292
}
293
}
294
295
if (isEstablished) {
296
if (srcName == null) {
297
srcName = new GSSNameElement
298
(cStub.getContextName(pContext, true), cStub);
299
}
300
if (cred == null) {
301
cred = new GSSCredElement(srcName, lifetime,
302
GSSCredential.INITIATE_ONLY,
303
cStub);
304
}
305
}
306
}
307
return outToken;
308
}
309
310
public byte[] acceptSecContext(InputStream is, int mechTokenLen)
311
throws GSSException {
312
byte[] outToken = null;
313
if ((!isEstablished) && (!isInitiator)) {
314
byte[] inToken = retrieveToken(is, mechTokenLen);
315
SunNativeProvider.debug("acceptSecContext=> inToken len=" +
316
inToken.length);
317
long pCred = (cred == null? 0 : cred.pCred);
318
outToken = cStub.acceptContext(pCred, cb, inToken, this);
319
SunNativeProvider.debug("acceptSecContext=> outToken len=" +
320
(outToken == null? 0 : outToken.length));
321
322
if (targetName == null) {
323
targetName = new GSSNameElement
324
(cStub.getContextName(pContext, false), cStub);
325
// Replace the current default acceptor cred now that
326
// the context acceptor name is available
327
if (cred != null) cred.dispose();
328
cred = new GSSCredElement(targetName, lifetime,
329
GSSCredential.ACCEPT_ONLY, cStub);
330
}
331
332
// Only inspect token when the permission check has not
333
// been performed
334
if (GSSUtil.isSpNegoMech(cStub.getMech()) &&
335
(outToken != null) && !skipServicePermCheck) {
336
if (GSSUtil.isKerberosMech(getMechFromSpNegoToken
337
(outToken, false))) {
338
doServicePermCheck();
339
}
340
}
341
}
342
return outToken;
343
}
344
345
public boolean isEstablished() {
346
return isEstablished;
347
}
348
349
public void dispose() throws GSSException {
350
srcName = null;
351
targetName = null;
352
cred = null;
353
delegatedCred = null;
354
if (pContext != 0) {
355
pContext = cStub.deleteContext(pContext);
356
pContext = 0;
357
}
358
}
359
360
public int getWrapSizeLimit(int qop, boolean confReq,
361
int maxTokenSize)
362
throws GSSException {
363
return cStub.wrapSizeLimit(pContext, (confReq? 1:0), qop,
364
maxTokenSize);
365
}
366
367
public byte[] wrap(byte[] inBuf, int offset, int len,
368
MessageProp msgProp) throws GSSException {
369
byte[] data = inBuf;
370
if ((offset != 0) || (len != inBuf.length)) {
371
data = new byte[len];
372
System.arraycopy(inBuf, offset, data, 0, len);
373
}
374
return cStub.wrap(pContext, data, msgProp);
375
}
376
public void wrap(byte inBuf[], int offset, int len,
377
OutputStream os, MessageProp msgProp)
378
throws GSSException {
379
try {
380
byte[] result = wrap(inBuf, offset, len, msgProp);
381
os.write(result);
382
} catch (IOException ioe) {
383
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
384
}
385
}
386
public int wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf,
387
int outOffset, MessageProp msgProp)
388
throws GSSException {
389
byte[] result = wrap(inBuf, inOffset, len, msgProp);
390
System.arraycopy(result, 0, outBuf, outOffset, result.length);
391
return result.length;
392
}
393
public void wrap(InputStream inStream, OutputStream outStream,
394
MessageProp msgProp) throws GSSException {
395
try {
396
byte[] data = new byte[inStream.available()];
397
int length = inStream.read(data);
398
byte[] token = wrap(data, 0, length, msgProp);
399
outStream.write(token);
400
} catch (IOException ioe) {
401
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
402
}
403
}
404
405
public byte[] unwrap(byte[] inBuf, int offset, int len,
406
MessageProp msgProp)
407
throws GSSException {
408
if ((offset != 0) || (len != inBuf.length)) {
409
byte[] temp = new byte[len];
410
System.arraycopy(inBuf, offset, temp, 0, len);
411
return cStub.unwrap(pContext, temp, msgProp);
412
} else {
413
return cStub.unwrap(pContext, inBuf, msgProp);
414
}
415
}
416
public int unwrap(byte[] inBuf, int inOffset, int len,
417
byte[] outBuf, int outOffset,
418
MessageProp msgProp) throws GSSException {
419
byte[] result = null;
420
if ((inOffset != 0) || (len != inBuf.length)) {
421
byte[] temp = new byte[len];
422
System.arraycopy(inBuf, inOffset, temp, 0, len);
423
result = cStub.unwrap(pContext, temp, msgProp);
424
} else {
425
result = cStub.unwrap(pContext, inBuf, msgProp);
426
}
427
System.arraycopy(result, 0, outBuf, outOffset, result.length);
428
return result.length;
429
}
430
public void unwrap(InputStream inStream, OutputStream outStream,
431
MessageProp msgProp) throws GSSException {
432
try {
433
byte[] wrapped = new byte[inStream.available()];
434
int wLength = inStream.read(wrapped);
435
byte[] data = unwrap(wrapped, 0, wLength, msgProp);
436
outStream.write(data);
437
outStream.flush();
438
} catch (IOException ioe) {
439
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
440
}
441
}
442
443
public int unwrap(InputStream inStream,
444
byte[] outBuf, int outOffset,
445
MessageProp msgProp) throws GSSException {
446
byte[] wrapped = null;
447
int wLength = 0;
448
try {
449
wrapped = new byte[inStream.available()];
450
wLength = inStream.read(wrapped);
451
byte[] result = unwrap(wrapped, 0, wLength, msgProp);
452
} catch (IOException ioe) {
453
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
454
}
455
byte[] result = unwrap(wrapped, 0, wLength, msgProp);
456
System.arraycopy(result, 0, outBuf, outOffset, result.length);
457
return result.length;
458
}
459
460
public byte[] getMIC(byte[] in, int offset, int len,
461
MessageProp msgProp) throws GSSException {
462
int qop = (msgProp == null? 0:msgProp.getQOP());
463
byte[] inMsg = in;
464
if ((offset != 0) || (len != in.length)) {
465
inMsg = new byte[len];
466
System.arraycopy(in, offset, inMsg, 0, len);
467
}
468
return cStub.getMic(pContext, qop, inMsg);
469
}
470
471
public void getMIC(InputStream inStream, OutputStream outStream,
472
MessageProp msgProp) throws GSSException {
473
try {
474
int length = 0;
475
byte[] msg = new byte[inStream.available()];
476
length = inStream.read(msg);
477
478
byte[] msgToken = getMIC(msg, 0, length, msgProp);
479
if ((msgToken != null) && msgToken.length != 0) {
480
outStream.write(msgToken);
481
}
482
} catch (IOException ioe) {
483
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
484
}
485
}
486
487
public void verifyMIC(byte[] inToken, int tOffset, int tLen,
488
byte[] inMsg, int mOffset, int mLen,
489
MessageProp msgProp) throws GSSException {
490
byte[] token = inToken;
491
byte[] msg = inMsg;
492
if ((tOffset != 0) || (tLen != inToken.length)) {
493
token = new byte[tLen];
494
System.arraycopy(inToken, tOffset, token, 0, tLen);
495
}
496
if ((mOffset != 0) || (mLen != inMsg.length)) {
497
msg = new byte[mLen];
498
System.arraycopy(inMsg, mOffset, msg, 0, mLen);
499
}
500
cStub.verifyMic(pContext, token, msg, msgProp);
501
}
502
503
public void verifyMIC(InputStream tokStream, InputStream msgStream,
504
MessageProp msgProp) throws GSSException {
505
try {
506
byte[] msg = new byte[msgStream.available()];
507
int mLength = msgStream.read(msg);
508
byte[] tok = new byte[tokStream.available()];
509
int tLength = tokStream.read(tok);
510
verifyMIC(tok, 0, tLength, msg, 0, mLength, msgProp);
511
} catch (IOException ioe) {
512
throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
513
}
514
}
515
516
public byte[] export() throws GSSException {
517
byte[] result = cStub.exportContext(pContext);
518
pContext = 0;
519
return result;
520
}
521
522
private void changeFlags(int flagMask, boolean isEnable) {
523
if (isInitiator && pContext == 0) {
524
if (isEnable) {
525
flags |= flagMask;
526
} else {
527
flags &= ~flagMask;
528
}
529
}
530
}
531
public void requestMutualAuth(boolean state) throws GSSException {
532
changeFlags(GSS_C_MUTUAL_FLAG, state);
533
}
534
public void requestReplayDet(boolean state) throws GSSException {
535
changeFlags(GSS_C_REPLAY_FLAG, state);
536
}
537
public void requestSequenceDet(boolean state) throws GSSException {
538
changeFlags(GSS_C_SEQUENCE_FLAG, state);
539
}
540
public void requestCredDeleg(boolean state) throws GSSException {
541
changeFlags(GSS_C_DELEG_FLAG, state);
542
}
543
public void requestAnonymity(boolean state) throws GSSException {
544
changeFlags(GSS_C_ANON_FLAG, state);
545
}
546
public void requestConf(boolean state) throws GSSException {
547
changeFlags(GSS_C_CONF_FLAG, state);
548
}
549
public void requestInteg(boolean state) throws GSSException {
550
changeFlags(GSS_C_INTEG_FLAG, state);
551
}
552
public void requestDelegPolicy(boolean state) throws GSSException {
553
// Not supported, ignore
554
}
555
public void requestLifetime(int lifetime) throws GSSException {
556
if (isInitiator && pContext == 0) {
557
this.lifetime = lifetime;
558
}
559
}
560
public void setChannelBinding(ChannelBinding cb) throws GSSException {
561
if (pContext == 0) {
562
this.cb = cb;
563
}
564
}
565
566
private boolean checkFlags(int flagMask) {
567
return ((flags & flagMask) != 0);
568
}
569
public boolean getCredDelegState() {
570
return checkFlags(GSS_C_DELEG_FLAG);
571
}
572
public boolean getMutualAuthState() {
573
return checkFlags(GSS_C_MUTUAL_FLAG);
574
}
575
public boolean getReplayDetState() {
576
return checkFlags(GSS_C_REPLAY_FLAG);
577
}
578
public boolean getSequenceDetState() {
579
return checkFlags(GSS_C_SEQUENCE_FLAG);
580
}
581
public boolean getAnonymityState() {
582
return checkFlags(GSS_C_ANON_FLAG);
583
}
584
public boolean isTransferable() throws GSSException {
585
return checkFlags(GSS_C_TRANS_FLAG);
586
}
587
public boolean isProtReady() {
588
return checkFlags(GSS_C_PROT_READY_FLAG);
589
}
590
public boolean getConfState() {
591
return checkFlags(GSS_C_CONF_FLAG);
592
}
593
public boolean getIntegState() {
594
return checkFlags(GSS_C_INTEG_FLAG);
595
}
596
public boolean getDelegPolicyState() {
597
return false;
598
}
599
public int getLifetime() {
600
return cStub.getContextTime(pContext);
601
}
602
public GSSNameSpi getSrcName() throws GSSException {
603
return srcName;
604
}
605
public GSSNameSpi getTargName() throws GSSException {
606
return targetName;
607
}
608
public Oid getMech() throws GSSException {
609
if (isEstablished && actualMech != null) {
610
return actualMech;
611
} else {
612
return cStub.getMech();
613
}
614
}
615
public GSSCredentialSpi getDelegCred() throws GSSException {
616
return delegatedCred;
617
}
618
public boolean isInitiator() {
619
return isInitiator;
620
}
621
622
protected void finalize() throws Throwable {
623
dispose();
624
}
625
626
public Object inquireSecContext(InquireType type)
627
throws GSSException {
628
throw new GSSException(GSSException.UNAVAILABLE, -1,
629
"Inquire type not supported.");
630
}
631
}
632
633