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/GSSContextImpl.java
38830 views
1
/*
2
* Copyright (c) 2000, 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;
27
28
import org.ietf.jgss.*;
29
import sun.security.jgss.spi.*;
30
import sun.security.util.ObjectIdentifier;
31
import java.io.InputStream;
32
import java.io.OutputStream;
33
import java.io.ByteArrayInputStream;
34
import java.io.ByteArrayOutputStream;
35
import java.io.IOException;
36
import com.sun.security.jgss.*;
37
38
/**
39
* This class represents the JGSS security context and its associated
40
* operations. JGSS security contexts are established between
41
* peers using locally established credentials. Multiple contexts
42
* may exist simultaneously between a pair of peers, using the same
43
* or different set of credentials. The JGSS is independent of
44
* the underlying transport protocols and depends on its callers to
45
* transport the tokens between peers.
46
* <p>
47
* The context object can be thought of as having 3 implicit states:
48
* before it is established, during its context establishment, and
49
* after a fully established context exists.
50
* <p>
51
* Before the context establishment phase is initiated, the context
52
* initiator may request specific characteristics desired of the
53
* established context. These can be set using the set methods. After the
54
* context is established, the caller can check the actual characteristic
55
* and services offered by the context using the query methods.
56
* <p>
57
* The context establishment phase begins with the first call to the
58
* initSecContext method by the context initiator. During this phase the
59
* initSecContext and acceptSecContext methods will produce GSS-API
60
* authentication tokens which the calling application needs to send to its
61
* peer. The initSecContext and acceptSecContext methods may
62
* return a CONTINUE_NEEDED code which indicates that a token is needed
63
* from its peer in order to continue the context establishment phase. A
64
* return code of COMPLETE signals that the local end of the context is
65
* established. This may still require that a token be sent to the peer,
66
* depending if one is produced by GSS-API. The isEstablished method can
67
* also be used to determine if the local end of the context has been
68
* fully established. During the context establishment phase, the
69
* isProtReady method may be called to determine if the context can be
70
* used for the per-message operations. This allows implementation to
71
* use per-message operations on contexts which aren't fully established.
72
* <p>
73
* After the context has been established or the isProtReady method
74
* returns "true", the query routines can be invoked to determine the actual
75
* characteristics and services of the established context. The
76
* application can also start using the per-message methods of wrap and
77
* getMIC to obtain cryptographic operations on application supplied data.
78
* <p>
79
* When the context is no longer needed, the application should call
80
* dispose to release any system resources the context may be using.
81
* <DL><DT><B>RFC 2078</b>
82
* <DD>This class corresponds to the context level calls together with
83
* the per message calls of RFC 2078. The gss_init_sec_context and
84
* gss_accept_sec_context calls have been made simpler by only taking
85
* required parameters. The context can have its properties set before
86
* the first call to initSecContext. The supplementary status codes for the
87
* per-message operations are returned in an instance of the MessageProp
88
* class, which is used as an argument in these calls.</dl>
89
*/
90
class GSSContextImpl implements ExtendedGSSContext {
91
92
private final GSSManagerImpl gssManager;
93
private final boolean initiator;
94
95
// private flags for the context state
96
private static final int PRE_INIT = 1;
97
private static final int IN_PROGRESS = 2;
98
private static final int READY = 3;
99
private static final int DELETED = 4;
100
101
// instance variables
102
private int currentState = PRE_INIT;
103
104
private GSSContextSpi mechCtxt = null;
105
private Oid mechOid = null;
106
private ObjectIdentifier objId = null;
107
108
private GSSCredentialImpl myCred = null;
109
110
private GSSNameImpl srcName = null;
111
private GSSNameImpl targName = null;
112
113
private int reqLifetime = INDEFINITE_LIFETIME;
114
private ChannelBinding channelBindings = null;
115
116
private boolean reqConfState = true;
117
private boolean reqIntegState = true;
118
private boolean reqMutualAuthState = true;
119
private boolean reqReplayDetState = true;
120
private boolean reqSequenceDetState = true;
121
private boolean reqCredDelegState = false;
122
private boolean reqAnonState = false;
123
private boolean reqDelegPolicyState = false;
124
125
/**
126
* Creates a GSSContextImp on the context initiator's side.
127
*/
128
public GSSContextImpl(GSSManagerImpl gssManager, GSSName peer, Oid mech,
129
GSSCredential myCred, int lifetime)
130
throws GSSException {
131
if ((peer == null) || !(peer instanceof GSSNameImpl)) {
132
throw new GSSException(GSSException.BAD_NAME);
133
}
134
if (mech == null) mech = ProviderList.DEFAULT_MECH_OID;
135
136
this.gssManager = gssManager;
137
this.myCred = (GSSCredentialImpl) myCred; // XXX Check first
138
reqLifetime = lifetime;
139
targName = (GSSNameImpl)peer;
140
this.mechOid = mech;
141
initiator = true;
142
}
143
144
/**
145
* Creates a GSSContextImpl on the context acceptor's side.
146
*/
147
public GSSContextImpl(GSSManagerImpl gssManager, GSSCredential myCred)
148
throws GSSException {
149
this.gssManager = gssManager;
150
this.myCred = (GSSCredentialImpl) myCred; // XXX Check first
151
initiator = false;
152
}
153
154
/**
155
* Creates a GSSContextImpl out of a previously exported
156
* GSSContext.
157
*
158
* @see #isTransferable
159
*/
160
public GSSContextImpl(GSSManagerImpl gssManager, byte[] interProcessToken)
161
throws GSSException {
162
this.gssManager = gssManager;
163
mechCtxt = gssManager.getMechanismContext(interProcessToken);
164
initiator = mechCtxt.isInitiator();
165
this.mechOid = mechCtxt.getMech();
166
}
167
168
public byte[] initSecContext(byte inputBuf[], int offset, int len)
169
throws GSSException {
170
/*
171
* Size of ByteArrayOutputStream will double each time that extra
172
* bytes are to be written. Usually, without delegation, a GSS
173
* initial token containing the Kerberos AP-REQ is between 400 and
174
* 600 bytes.
175
*/
176
ByteArrayOutputStream bos = new ByteArrayOutputStream(600);
177
ByteArrayInputStream bin =
178
new ByteArrayInputStream(inputBuf, offset, len);
179
int size = initSecContext(bin, bos);
180
return (size == 0? null : bos.toByteArray());
181
}
182
183
public int initSecContext(InputStream inStream,
184
OutputStream outStream) throws GSSException {
185
186
if (mechCtxt != null && currentState != IN_PROGRESS) {
187
throw new GSSExceptionImpl(GSSException.FAILURE,
188
"Illegal call to initSecContext");
189
}
190
191
GSSHeader gssHeader = null;
192
int inTokenLen = -1;
193
GSSCredentialSpi credElement = null;
194
boolean firstToken = false;
195
196
try {
197
if (mechCtxt == null) {
198
if (myCred != null) {
199
try {
200
credElement = myCred.getElement(mechOid, true);
201
} catch (GSSException ge) {
202
if (GSSUtil.isSpNegoMech(mechOid) &&
203
ge.getMajor() == GSSException.NO_CRED) {
204
credElement = myCred.getElement
205
(myCred.getMechs()[0], true);
206
} else {
207
throw ge;
208
}
209
}
210
}
211
GSSNameSpi nameElement = targName.getElement(mechOid);
212
mechCtxt = gssManager.getMechanismContext(nameElement,
213
credElement,
214
reqLifetime,
215
mechOid);
216
mechCtxt.requestConf(reqConfState);
217
mechCtxt.requestInteg(reqIntegState);
218
mechCtxt.requestCredDeleg(reqCredDelegState);
219
mechCtxt.requestMutualAuth(reqMutualAuthState);
220
mechCtxt.requestReplayDet(reqReplayDetState);
221
mechCtxt.requestSequenceDet(reqSequenceDetState);
222
mechCtxt.requestAnonymity(reqAnonState);
223
mechCtxt.setChannelBinding(channelBindings);
224
mechCtxt.requestDelegPolicy(reqDelegPolicyState);
225
226
objId = new ObjectIdentifier(mechOid.toString());
227
228
currentState = IN_PROGRESS;
229
firstToken = true;
230
} else {
231
if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
232
GSSUtil.isSpNegoMech(mechOid)) {
233
// do not parse GSS header for native provider or SPNEGO
234
// mech
235
} else {
236
// parse GSS header
237
gssHeader = new GSSHeader(inStream);
238
if (!gssHeader.getOid().equals((Object) objId))
239
throw new GSSExceptionImpl
240
(GSSException.DEFECTIVE_TOKEN,
241
"Mechanism not equal to " +
242
mechOid.toString() +
243
" in initSecContext token");
244
inTokenLen = gssHeader.getMechTokenLength();
245
}
246
}
247
248
byte[] obuf = mechCtxt.initSecContext(inStream, inTokenLen);
249
250
int retVal = 0;
251
252
if (obuf != null) {
253
retVal = obuf.length;
254
if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
255
(!firstToken && GSSUtil.isSpNegoMech(mechOid))) {
256
// do not add GSS header for native provider or SPNEGO
257
// except for the first SPNEGO token
258
} else {
259
// add GSS header
260
gssHeader = new GSSHeader(objId, obuf.length);
261
retVal += gssHeader.encode(outStream);
262
}
263
outStream.write(obuf);
264
}
265
266
if (mechCtxt.isEstablished())
267
currentState = READY;
268
269
return retVal;
270
271
} catch (IOException e) {
272
throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN,
273
e.getMessage());
274
}
275
}
276
277
public byte[] acceptSecContext(byte inTok[], int offset, int len)
278
throws GSSException {
279
280
/*
281
* Usually initial GSS token containing a Kerberos AP-REP is less
282
* than 100 bytes.
283
*/
284
ByteArrayOutputStream bos = new ByteArrayOutputStream(100);
285
acceptSecContext(new ByteArrayInputStream(inTok, offset, len),
286
bos);
287
byte[] out = bos.toByteArray();
288
return (out.length == 0) ? null : out;
289
}
290
291
public void acceptSecContext(InputStream inStream,
292
OutputStream outStream) throws GSSException {
293
294
if (mechCtxt != null && currentState != IN_PROGRESS) {
295
throw new GSSExceptionImpl(GSSException.FAILURE,
296
"Illegal call to acceptSecContext");
297
}
298
299
GSSHeader gssHeader = null;
300
int inTokenLen = -1;
301
GSSCredentialSpi credElement = null;
302
303
try {
304
if (mechCtxt == null) {
305
// mechOid will be null for an acceptor's context
306
gssHeader = new GSSHeader(inStream);
307
inTokenLen = gssHeader.getMechTokenLength();
308
309
/*
310
* Convert ObjectIdentifier to Oid
311
*/
312
objId = gssHeader.getOid();
313
mechOid = new Oid(objId.toString());
314
// System.out.println("Entered GSSContextImpl.acceptSecContext"
315
// + " with mechanism = " + mechOid);
316
if (myCred != null) {
317
credElement = myCred.getElement(mechOid, false);
318
}
319
320
mechCtxt = gssManager.getMechanismContext(credElement,
321
mechOid);
322
mechCtxt.setChannelBinding(channelBindings);
323
324
currentState = IN_PROGRESS;
325
} else {
326
if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
327
(GSSUtil.isSpNegoMech(mechOid))) {
328
// do not parse GSS header for native provider and SPNEGO
329
} else {
330
// parse GSS Header
331
gssHeader = new GSSHeader(inStream);
332
if (!gssHeader.getOid().equals((Object) objId))
333
throw new GSSExceptionImpl
334
(GSSException.DEFECTIVE_TOKEN,
335
"Mechanism not equal to " +
336
mechOid.toString() +
337
" in acceptSecContext token");
338
inTokenLen = gssHeader.getMechTokenLength();
339
}
340
}
341
342
byte[] obuf = mechCtxt.acceptSecContext(inStream, inTokenLen);
343
344
if (obuf != null) {
345
int retVal = obuf.length;
346
if (mechCtxt.getProvider().getName().equals("SunNativeGSS") ||
347
(GSSUtil.isSpNegoMech(mechOid))) {
348
// do not add GSS header for native provider and SPNEGO
349
} else {
350
// add GSS header
351
gssHeader = new GSSHeader(objId, obuf.length);
352
retVal += gssHeader.encode(outStream);
353
}
354
outStream.write(obuf);
355
}
356
357
if (mechCtxt.isEstablished()) {
358
currentState = READY;
359
}
360
} catch (IOException e) {
361
throw new GSSExceptionImpl(GSSException.DEFECTIVE_TOKEN,
362
e.getMessage());
363
}
364
}
365
366
public boolean isEstablished() {
367
if (mechCtxt == null)
368
return false;
369
else
370
return (currentState == READY);
371
}
372
373
public int getWrapSizeLimit(int qop, boolean confReq,
374
int maxTokenSize) throws GSSException {
375
if (mechCtxt != null)
376
return mechCtxt.getWrapSizeLimit(qop, confReq, maxTokenSize);
377
else
378
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
379
"No mechanism context yet!");
380
}
381
382
public byte[] wrap(byte inBuf[], int offset, int len,
383
MessageProp msgProp) throws GSSException {
384
if (mechCtxt != null)
385
return mechCtxt.wrap(inBuf, offset, len, msgProp);
386
else
387
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
388
"No mechanism context yet!");
389
}
390
391
public void wrap(InputStream inStream, OutputStream outStream,
392
MessageProp msgProp) throws GSSException {
393
if (mechCtxt != null)
394
mechCtxt.wrap(inStream, outStream, msgProp);
395
else
396
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
397
"No mechanism context yet!");
398
}
399
400
public byte [] unwrap(byte[] inBuf, int offset, int len,
401
MessageProp msgProp) throws GSSException {
402
if (mechCtxt != null)
403
return mechCtxt.unwrap(inBuf, offset, len, msgProp);
404
else
405
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
406
"No mechanism context yet!");
407
}
408
409
public void unwrap(InputStream inStream, OutputStream outStream,
410
MessageProp msgProp) throws GSSException {
411
if (mechCtxt != null)
412
mechCtxt.unwrap(inStream, outStream, msgProp);
413
else
414
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
415
"No mechanism context yet!");
416
}
417
418
public byte[] getMIC(byte []inMsg, int offset, int len,
419
MessageProp msgProp) throws GSSException {
420
if (mechCtxt != null)
421
return mechCtxt.getMIC(inMsg, offset, len, msgProp);
422
else
423
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
424
"No mechanism context yet!");
425
}
426
427
public void getMIC(InputStream inStream, OutputStream outStream,
428
MessageProp msgProp) throws GSSException {
429
if (mechCtxt != null)
430
mechCtxt.getMIC(inStream, outStream, msgProp);
431
else
432
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
433
"No mechanism context yet!");
434
}
435
436
public void verifyMIC(byte[] inTok, int tokOffset, int tokLen,
437
byte[] inMsg, int msgOffset, int msgLen,
438
MessageProp msgProp) throws GSSException {
439
if (mechCtxt != null)
440
mechCtxt.verifyMIC(inTok, tokOffset, tokLen,
441
inMsg, msgOffset, msgLen, msgProp);
442
else
443
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
444
"No mechanism context yet!");
445
}
446
447
public void verifyMIC(InputStream tokStream, InputStream msgStream,
448
MessageProp msgProp) throws GSSException {
449
if (mechCtxt != null)
450
mechCtxt.verifyMIC(tokStream, msgStream, msgProp);
451
else
452
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
453
"No mechanism context yet!");
454
}
455
456
public byte[] export() throws GSSException {
457
// Defaults to null to match old behavior
458
byte[] result = null;
459
// Only allow context export from native provider since JGSS
460
// still has not defined its own interprocess token format
461
if (mechCtxt.isTransferable() &&
462
mechCtxt.getProvider().getName().equals("SunNativeGSS")) {
463
result = mechCtxt.export();
464
}
465
return result;
466
}
467
468
public void requestMutualAuth(boolean state) throws GSSException {
469
if (mechCtxt == null && initiator)
470
reqMutualAuthState = state;
471
}
472
473
public void requestReplayDet(boolean state) throws GSSException {
474
if (mechCtxt == null && initiator)
475
reqReplayDetState = state;
476
}
477
478
public void requestSequenceDet(boolean state) throws GSSException {
479
if (mechCtxt == null && initiator)
480
reqSequenceDetState = state;
481
}
482
483
public void requestCredDeleg(boolean state) throws GSSException {
484
if (mechCtxt == null && initiator)
485
reqCredDelegState = state;
486
}
487
488
public void requestAnonymity(boolean state) throws GSSException {
489
if (mechCtxt == null && initiator)
490
reqAnonState = state;
491
}
492
493
public void requestConf(boolean state) throws GSSException {
494
if (mechCtxt == null && initiator)
495
reqConfState = state;
496
}
497
498
public void requestInteg(boolean state) throws GSSException {
499
if (mechCtxt == null && initiator)
500
reqIntegState = state;
501
}
502
503
public void requestLifetime(int lifetime) throws GSSException {
504
if (mechCtxt == null && initiator)
505
reqLifetime = lifetime;
506
}
507
508
public void setChannelBinding(ChannelBinding channelBindings)
509
throws GSSException {
510
511
if (mechCtxt == null)
512
this.channelBindings = channelBindings;
513
514
}
515
516
public boolean getCredDelegState() {
517
if (mechCtxt != null)
518
return mechCtxt.getCredDelegState();
519
else
520
return reqCredDelegState;
521
}
522
523
public boolean getMutualAuthState() {
524
if (mechCtxt != null)
525
return mechCtxt.getMutualAuthState();
526
else
527
return reqMutualAuthState;
528
}
529
530
public boolean getReplayDetState() {
531
if (mechCtxt != null)
532
return mechCtxt.getReplayDetState();
533
else
534
return reqReplayDetState;
535
}
536
537
public boolean getSequenceDetState() {
538
if (mechCtxt != null)
539
return mechCtxt.getSequenceDetState();
540
else
541
return reqSequenceDetState;
542
}
543
544
public boolean getAnonymityState() {
545
if (mechCtxt != null)
546
return mechCtxt.getAnonymityState();
547
else
548
return reqAnonState;
549
}
550
551
public boolean isTransferable() throws GSSException {
552
if (mechCtxt != null)
553
return mechCtxt.isTransferable();
554
else
555
return false;
556
}
557
558
public boolean isProtReady() {
559
if (mechCtxt != null)
560
return mechCtxt.isProtReady();
561
else
562
return false;
563
}
564
565
public boolean getConfState() {
566
if (mechCtxt != null)
567
return mechCtxt.getConfState();
568
else
569
return reqConfState;
570
}
571
572
public boolean getIntegState() {
573
if (mechCtxt != null)
574
return mechCtxt.getIntegState();
575
else
576
return reqIntegState;
577
}
578
579
public int getLifetime() {
580
if (mechCtxt != null)
581
return mechCtxt.getLifetime();
582
else
583
return reqLifetime;
584
}
585
586
public GSSName getSrcName() throws GSSException {
587
if (srcName == null) {
588
srcName = GSSNameImpl.wrapElement
589
(gssManager, mechCtxt.getSrcName());
590
}
591
return srcName;
592
}
593
594
public GSSName getTargName() throws GSSException {
595
if (targName == null) {
596
targName = GSSNameImpl.wrapElement
597
(gssManager, mechCtxt.getTargName());
598
}
599
return targName;
600
}
601
602
public Oid getMech() throws GSSException {
603
if (mechCtxt != null) {
604
return mechCtxt.getMech();
605
}
606
return mechOid;
607
}
608
609
public GSSCredential getDelegCred() throws GSSException {
610
611
if (mechCtxt == null)
612
throw new GSSExceptionImpl(GSSException.NO_CONTEXT,
613
"No mechanism context yet!");
614
GSSCredentialSpi delCredElement = mechCtxt.getDelegCred();
615
return (delCredElement == null ?
616
null : new GSSCredentialImpl(gssManager, delCredElement));
617
}
618
619
public boolean isInitiator() throws GSSException {
620
return initiator;
621
}
622
623
public void dispose() throws GSSException {
624
currentState = DELETED;
625
if (mechCtxt != null) {
626
mechCtxt.dispose();
627
mechCtxt = null;
628
}
629
myCred = null;
630
srcName = null;
631
targName = null;
632
}
633
634
// ExtendedGSSContext methods:
635
636
@Override
637
public Object inquireSecContext(InquireType type) throws GSSException {
638
SecurityManager security = System.getSecurityManager();
639
if (security != null) {
640
security.checkPermission(new InquireSecContextPermission(type.toString()));
641
}
642
if (mechCtxt == null) {
643
throw new GSSException(GSSException.NO_CONTEXT);
644
}
645
return mechCtxt.inquireSecContext(type);
646
}
647
648
@Override
649
public void requestDelegPolicy(boolean state) throws GSSException {
650
if (mechCtxt == null && initiator)
651
reqDelegPolicyState = state;
652
}
653
654
@Override
655
public boolean getDelegPolicyState() {
656
if (mechCtxt != null)
657
return mechCtxt.getDelegPolicyState();
658
else
659
return reqDelegPolicyState;
660
}
661
}
662
663