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