1 /*
2 * Copyright (c) 2005, 2019, 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 #include "sun_security_jgss_wrapper_GSSLibStub.h"
27 #include "NativeUtil.h"
28 #include "NativeFunc.h"
29 #include "jlong.h"
30 #include <jni.h>
31
32 /* Constants for indicating what type of info is needed for inquiries */
33 const int TYPE_CRED_NAME = 10;
34 const int TYPE_CRED_TIME = 11;
35 const int TYPE_CRED_USAGE = 12;
36
37 static jclass tlsCBCl = NULL;
38
39 /*
40 * Class: sun_security_jgss_wrapper_GSSLibStub
41 * Method: init
42 * Signature: (Ljava/lang/String;Z)Z
43 */
44 JNIEXPORT jboolean JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv * env,jclass jcls,jstring jlibName,jboolean jDebug)45 Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv *env,
46 jclass jcls,
47 jstring jlibName,
48 jboolean jDebug) {
49 const char *libName;
50 int failed;
51 char *error = NULL;
52
53 if (!jDebug) {
54 JGSS_DEBUG = 0;
55 } else {
56 JGSS_DEBUG = 1;
57 }
58
59 if (jlibName == NULL) {
60 TRACE0("[GSSLibStub_init] GSS lib name is NULL");
61 return JNI_FALSE;
62 }
63
64 libName = (*env)->GetStringUTFChars(env, jlibName, NULL);
65 if (libName == NULL) {
66 return JNI_FALSE;
67 }
68 TRACE1("[GSSLibStub_init] libName=%s", libName);
69
70 /* initialize global function table */
71 failed = loadNative(libName);
72 (*env)->ReleaseStringUTFChars(env, jlibName, libName);
73
74 if (tlsCBCl == NULL) {
75
76 /* initialize TLS Channel Binding class wrapper */
77 jclass cl = (*env)->FindClass(env,
78 "sun/security/jgss/krb5/internal/TlsChannelBindingImpl");
79 if (cl == NULL) { /* exception thrown */
80 return JNI_FALSE;
81 }
82 tlsCBCl = (*env)->NewGlobalRef(env, cl);
83 }
84
85 if (!failed) {
86 return JNI_TRUE;
87 } else {
88 if (JGSS_DEBUG) {
89 #ifdef WIN32
90 #define MAX_MSG_SIZE 256
91 static CHAR szMsgBuf[MAX_MSG_SIZE];
92 DWORD dwRes;
93 DWORD dwError = GetLastError();
94 dwRes = FormatMessage (
95 FORMAT_MESSAGE_FROM_SYSTEM,
96 NULL,
97 dwError,
98 0,
99 szMsgBuf,
100 MAX_MSG_SIZE,
101 NULL);
102 if (0 == dwRes) {
103 printf("GSS-API: Unknown failure %d\n", dwError);
104 } else {
105 printf("GSS-API: %s\n",szMsgBuf);
106 }
107 #else
108 char* error = dlerror();
109 if (error) {
110 TRACE0(error);
111 }
112 #endif
113 }
114 return JNI_FALSE;
115 }
116 }
117
118 /*
119 * Class: sun_security_jgss_wrapper_GSSLibStub
120 * Method: getMechPtr
121 * Signature: ([B)J
122 */
123 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getMechPtr(JNIEnv * env,jclass jcls,jbyteArray jbytes)124 Java_sun_security_jgss_wrapper_GSSLibStub_getMechPtr(JNIEnv *env,
125 jclass jcls,
126 jbyteArray jbytes) {
127 gss_OID cOid;
128 unsigned int i, len;
129 jbyte* bytes;
130 int found;
131
132 if (jbytes != NULL) {
133 found = 0;
134 len = (unsigned int)((*env)->GetArrayLength(env, jbytes) - 2);
135 bytes = (*env)->GetByteArrayElements(env, jbytes, NULL);
136 if (bytes == NULL) {
137 return ptr_to_jlong(NULL);
138 }
139 for (i = 0; i < ftab->mechs->count; i++) {
140 cOid = &(ftab->mechs->elements[i]);
141 if (len == cOid->length &&
142 (memcmp(cOid->elements, (bytes + 2), len) == 0)) {
143 // Found a match
144 found = 1;
145 break;
146 }
147 }
148 (*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
149
150 if (found != 1) {
151 checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]");
152 return ptr_to_jlong(NULL);
153 } else {
154 return ptr_to_jlong(cOid);
155 }
156 } else {
157 return ptr_to_jlong(GSS_C_NO_OID);
158 }
159 }
160
161 /*
162 * Utility routine which releases the specified gss_channel_bindings_t
163 * structure.
164 */
deleteGSSCB(gss_channel_bindings_t cb)165 void deleteGSSCB(gss_channel_bindings_t cb) {
166
167 if (cb == GSS_C_NO_CHANNEL_BINDINGS) return;
168
169 /* release initiator address */
170 if (cb->initiator_addrtype != GSS_C_AF_NULLADDR &&
171 cb->initiator_addrtype != GSS_C_AF_UNSPEC) {
172 resetGSSBuffer(&(cb->initiator_address));
173 }
174 /* release acceptor address */
175 if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR &&
176 cb->acceptor_addrtype != GSS_C_AF_UNSPEC) {
177 resetGSSBuffer(&(cb->acceptor_address));
178 }
179 /* release application data */
180 if (cb->application_data.length != 0) {
181 resetGSSBuffer(&(cb->application_data));
182 }
183 free(cb);
184 }
185
186 /*
187 * Utility routine which creates a gss_channel_bindings_t structure
188 * using the specified org.ietf.jgss.ChannelBinding object.
189 * NOTE: must call deleteGSSCB() to free up the resources.
190 */
newGSSCB(JNIEnv * env,jobject jcb)191 gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) {
192 gss_channel_bindings_t cb;
193 jobject jinetAddr;
194 jbyteArray value;
195
196 if (jcb == NULL) {
197 return GSS_C_NO_CHANNEL_BINDINGS;
198 }
199
200 cb = malloc(sizeof(struct gss_channel_bindings_struct));
201 if (cb == NULL) {
202 throwOutOfMemoryError(env,NULL);
203 return NULL;
204 }
205
206 // initialize addrtype in CB first
207 // LDAP TLS Channel Binding requires GSS_C_AF_UNSPEC address type
208 // for unspecified initiator and acceptor addresses.
209 // GSS_C_AF_NULLADDR value should be used for unspecified address
210 // in all other cases.
211
212 if ((*env)->IsInstanceOf(env, jcb, tlsCBCl)) {
213 // TLS Channel Binding requires unspecified addrtype=0
214 cb->initiator_addrtype = GSS_C_AF_UNSPEC;
215 cb->acceptor_addrtype = GSS_C_AF_UNSPEC;
216 } else {
217 cb->initiator_addrtype = GSS_C_AF_NULLADDR;
218 cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
219 }
220 // addresses needs to be initialized to empty
221 memset(&cb->initiator_address, 0, sizeof(cb->initiator_address));
222 memset(&cb->acceptor_address, 0, sizeof(cb->acceptor_address));
223
224 /* set up initiator address */
225 jinetAddr = (*env)->CallObjectMethod(env, jcb,
226 MID_ChannelBinding_getInitiatorAddr);
227 if ((*env)->ExceptionCheck(env)) {
228 goto cleanup;
229 }
230 if (jinetAddr != NULL) {
231 value = (*env)->CallObjectMethod(env, jinetAddr,
232 MID_InetAddress_getAddr);
233 if ((*env)->ExceptionCheck(env)) {
234 goto cleanup;
235 }
236 cb->initiator_addrtype = GSS_C_AF_INET;
237 initGSSBuffer(env, value, &(cb->initiator_address));
238 if ((*env)->ExceptionCheck(env)) {
239 goto cleanup;
240 }
241 }
242 /* set up acceptor address */
243 jinetAddr = (*env)->CallObjectMethod(env, jcb,
244 MID_ChannelBinding_getAcceptorAddr);
245 if ((*env)->ExceptionCheck(env)) {
246 goto cleanup;
247 }
248 if (jinetAddr != NULL) {
249 value = (*env)->CallObjectMethod(env, jinetAddr,
250 MID_InetAddress_getAddr);
251 if ((*env)->ExceptionCheck(env)) {
252 goto cleanup;
253 }
254 cb->acceptor_addrtype = GSS_C_AF_INET;
255 initGSSBuffer(env, value, &(cb->acceptor_address));
256 if ((*env)->ExceptionCheck(env)) {
257 goto cleanup;
258 }
259 }
260 /* set up application data */
261 value = (*env)->CallObjectMethod(env, jcb,
262 MID_ChannelBinding_getAppData);
263 if ((*env)->ExceptionCheck(env)) {
264 goto cleanup;
265 }
266 initGSSBuffer(env, value, &(cb->application_data));
267 if ((*env)->ExceptionCheck(env)) {
268 goto cleanup;
269 }
270 return cb;
271 cleanup:
272 deleteGSSCB(cb);
273 return NULL;
274 }
275
276 /*
277 * Utility routine for storing the supplementary information
278 * into the specified org.ietf.jgss.MessageProp object.
279 */
setSupplementaryInfo(JNIEnv * env,jobject jstub,jobject jprop,int suppInfo,int minor)280 void setSupplementaryInfo(JNIEnv *env, jobject jstub, jobject jprop,
281 int suppInfo, int minor) {
282 jboolean isDuplicate, isOld, isUnseq, hasGap;
283 jstring minorMsg;
284
285 if (suppInfo != GSS_S_COMPLETE) {
286 isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0);
287 isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0);
288 isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0);
289 hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0);
290 minorMsg = getMinorMessage(env, jstub, minor);
291 if ((*env)->ExceptionCheck(env)) {
292 return;
293 }
294 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates,
295 isDuplicate, isOld, isUnseq, hasGap, minor,
296 minorMsg);
297 }
298 }
299
300 /*
301 * Class: sun_security_jgss_wrapper_GSSLibStub
302 * Method: indicateMechs
303 * Signature: ()[Lorg/ietf/jgss/Oid;
304 */
305 JNIEXPORT jobjectArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_indicateMechs(JNIEnv * env,jclass jcls)306 Java_sun_security_jgss_wrapper_GSSLibStub_indicateMechs(JNIEnv *env,
307 jclass jcls)
308 {
309 if (ftab->mechs != NULL && ftab->mechs != GSS_C_NO_OID_SET) {
310 return getJavaOIDArray(env, ftab->mechs);
311 } else return NULL;
312 }
313
314 /*
315 * Class: sun_security_jgss_wrapper_GSSLibStub
316 * Method: inquireNamesForMech
317 * Signature: ()[Lorg/ietf/jgss/Oid;
318 */
319 JNIEXPORT jobjectArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_inquireNamesForMech(JNIEnv * env,jobject jobj)320 Java_sun_security_jgss_wrapper_GSSLibStub_inquireNamesForMech(JNIEnv *env,
321 jobject jobj)
322 {
323 OM_uint32 minor, major;
324 gss_OID mech;
325 gss_OID_set nameTypes;
326 jobjectArray result;
327
328 if (ftab->inquireNamesForMech != NULL) {
329 mech = (gss_OID)jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
330 nameTypes = GSS_C_NO_OID_SET;
331
332 /* gss_inquire_names_for_mech(...) => N/A */
333 major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes);
334
335 /* release intermediate buffers before checking status */
336 result = getJavaOIDArray(env, nameTypes);
337 deleteGSSOIDSet(nameTypes);
338 if ((*env)->ExceptionCheck(env)) {
339 return NULL;
340 }
341
342 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
343 if ((*env)->ExceptionCheck(env)) {
344 return NULL;
345 }
346 return result;
347 }
348 return NULL;
349 }
350
351 /*
352 * Class: sun_security_jgss_wrapper_GSSLibStub
353 * Method: releaseName
354 * Signature: (J)V
355 */
356 JNIEXPORT void JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_releaseName(JNIEnv * env,jobject jobj,jlong pName)357 Java_sun_security_jgss_wrapper_GSSLibStub_releaseName(JNIEnv *env,
358 jobject jobj,
359 jlong pName)
360 {
361 OM_uint32 minor, major;
362 gss_name_t nameHdl;
363
364 nameHdl = (gss_name_t) jlong_to_ptr(pName);
365
366 TRACE1("[GSSLibStub_releaseName] %ld", (long) pName);
367
368 if (nameHdl != GSS_C_NO_NAME) {
369 /* gss_release_name(...) => GSS_S_BAD_NAME */
370 major = (*ftab->releaseName)(&minor, &nameHdl);
371 checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseName]");
372 }
373 }
374
375 /*
376 * Class: sun_security_jgss_wrapper_GSSLibStub
377 * Method: importName
378 * Signature: ([BLorg/ietf/jgss/Oid;)J
379 */
380 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv * env,jobject jobj,jbyteArray jnameVal,jobject jnameType)381 Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv *env,
382 jobject jobj,
383 jbyteArray jnameVal,
384 jobject jnameType)
385 {
386 OM_uint32 minor, major;
387 gss_buffer_desc nameVal;
388 gss_OID nameType;
389 gss_name_t nameHdl;
390 nameHdl = GSS_C_NO_NAME;
391
392 TRACE0("[GSSLibStub_importName]");
393
394 initGSSBuffer(env, jnameVal, &nameVal);
395 if ((*env)->ExceptionCheck(env)) {
396 return jlong_zero;
397 }
398
399 nameType = newGSSOID(env, jnameType);
400 if ((*env)->ExceptionCheck(env)) {
401 resetGSSBuffer(&nameVal);
402 return jlong_zero;
403 }
404
405 /* gss_import_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME,
406 GSS_S_BAD_MECH */
407 major = (*ftab->importName)(&minor, &nameVal, nameType, &nameHdl);
408
409 TRACE1("[GSSLibStub_importName] %" PRIuPTR "", (uintptr_t) nameHdl);
410
411 /* release intermediate buffers */
412 deleteGSSOID(nameType);
413 resetGSSBuffer(&nameVal);
414
415 checkStatus(env, jobj, major, minor, "[GSSLibStub_importName]");
416 if ((*env)->ExceptionCheck(env)) {
417 return jlong_zero;
418 }
419 return ptr_to_jlong(nameHdl);
420 }
421
422
423 /*
424 * Class: sun_security_jgss_wrapper_GSSLibStub
425 * Method: compareName
426 * Signature: (JJ)Z
427 */
428 JNIEXPORT jboolean JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_compareName(JNIEnv * env,jobject jobj,jlong pName1,jlong pName2)429 Java_sun_security_jgss_wrapper_GSSLibStub_compareName(JNIEnv *env,
430 jobject jobj,
431 jlong pName1,
432 jlong pName2)
433 {
434 OM_uint32 minor, major;
435 gss_name_t nameHdl1, nameHdl2;
436 int isEqual;
437
438 isEqual = 0;
439 nameHdl1 = (gss_name_t) jlong_to_ptr(pName1);
440 nameHdl2 = (gss_name_t) jlong_to_ptr(pName2);
441
442 TRACE2("[GSSLibStub_compareName] %ld %ld", (long)pName1, (long)pName2);
443
444 if ((nameHdl1 != GSS_C_NO_NAME) && (nameHdl2 != GSS_C_NO_NAME)) {
445
446 /* gss_compare_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!) */
447 major = (*ftab->compareName)(&minor, nameHdl1, nameHdl2, &isEqual);
448
449 checkStatus(env, jobj, major, minor, "[GSSLibStub_compareName]");
450 }
451 return (isEqual != 0);
452 }
453
454 /*
455 * Class: sun_security_jgss_wrapper_GSSLibStub
456 * Method: canonicalizeName
457 * Signature: (J)J
458 */
459 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName(JNIEnv * env,jobject jobj,jlong pName)460 Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName(JNIEnv *env,
461 jobject jobj,
462 jlong pName)
463 {
464 OM_uint32 minor, major;
465 gss_name_t nameHdl, mnNameHdl;
466 gss_OID mech;
467
468 nameHdl = (gss_name_t) jlong_to_ptr(pName);
469
470 TRACE1("[GSSLibStub_canonicalizeName] %ld", (long) pName);
471
472 if (nameHdl != GSS_C_NO_NAME) {
473 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
474 mnNameHdl = GSS_C_NO_NAME;
475
476 /* gss_canonicalize_name(...) may return GSS_S_BAD_NAMETYPE,
477 GSS_S_BAD_NAME, GSS_S_BAD_MECH */
478 major = (*ftab->canonicalizeName)(&minor, nameHdl, mech, &mnNameHdl);
479
480 TRACE1("[GSSLibStub_canonicalizeName] MN=%" PRIuPTR "", (uintptr_t)mnNameHdl);
481
482 checkStatus(env, jobj, major, minor, "[GSSLibStub_canonicalizeName]");
483 if ((*env)->ExceptionCheck(env)) {
484 return ptr_to_jlong(GSS_C_NO_NAME);
485 }
486 return ptr_to_jlong(mnNameHdl);
487 }
488 return ptr_to_jlong(GSS_C_NO_NAME);
489 }
490
491 /*
492 * Class: sun_security_jgss_wrapper_GSSLibStub
493 * Method: exportName
494 * Signature: (J)[B
495 */
496 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_exportName(JNIEnv * env,jobject jobj,jlong pName)497 Java_sun_security_jgss_wrapper_GSSLibStub_exportName(JNIEnv *env,
498 jobject jobj,
499 jlong pName) {
500 OM_uint32 minor, major;
501 gss_name_t nameHdl, mNameHdl;
502 gss_buffer_desc outBuf;
503 jbyteArray jresult;
504
505 nameHdl = (gss_name_t) jlong_to_ptr(pName);
506
507 TRACE1("[GSSLibStub_exportName] %ld", (long) pName);
508
509 /* gss_export_name(...) => GSS_S_NAME_NOT_MN, GSS_S_BAD_NAMETYPE,
510 GSS_S_BAD_NAME */
511 major = (*ftab->exportName)(&minor, nameHdl, &outBuf);
512
513 /* canonicalize the internal name to MN and retry */
514 if (major == GSS_S_NAME_NOT_MN) {
515 /* release intermediate buffers before retrying */
516 (*ftab->releaseBuffer)(&minor, &outBuf);
517
518 TRACE0("[GSSLibStub_exportName] canonicalize and re-try");
519
520 mNameHdl = (gss_name_t)jlong_to_ptr(
521 Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName
522 (env, jobj, pName));
523 if ((*env)->ExceptionCheck(env)) {
524 return NULL;
525 }
526
527 major = (*ftab->exportName)(&minor, mNameHdl, &outBuf);
528 Java_sun_security_jgss_wrapper_GSSLibStub_releaseName
529 (env, jobj, ptr_to_jlong(mNameHdl));
530 if ((*env)->ExceptionCheck(env)) {
531 /* release intermediate buffers */
532 (*ftab->releaseBuffer)(&minor, &outBuf);
533 return NULL;
534 }
535 }
536
537 /* release intermediate buffers before checking status */
538 jresult = getJavaBuffer(env, &outBuf);
539 if ((*env)->ExceptionCheck(env)) {
540 return NULL;
541 }
542
543 checkStatus(env, jobj, major, minor, "[GSSLibStub_exportName]");
544 if ((*env)->ExceptionCheck(env)) {
545 return NULL;
546 }
547 return jresult;
548 }
549
550 /*
551 * Class: sun_security_jgss_wrapper_GSSLibStub
552 * Method: displayName
553 * Signature: (J)[Ljava/lang/Object;
554 */
555 JNIEXPORT jobjectArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_displayName(JNIEnv * env,jobject jobj,jlong pName)556 Java_sun_security_jgss_wrapper_GSSLibStub_displayName(JNIEnv *env,
557 jobject jobj,
558 jlong pName) {
559 OM_uint32 minor, major;
560 gss_name_t nameHdl;
561 gss_buffer_desc outNameBuf;
562 gss_OID outNameType;
563 jstring jname;
564 jobject jtype;
565 jobjectArray jresult;
566
567 nameHdl = (gss_name_t) jlong_to_ptr(pName);
568
569 TRACE1("[GSSLibStub_displayName] %ld", (long) pName);
570
571 if (nameHdl == GSS_C_NO_NAME) {
572 checkStatus(env, jobj, GSS_S_BAD_NAME, 0, "[GSSLibStub_displayName]");
573 return NULL;
574 }
575
576 /* gss_display_name(...) => GSS_S_BAD_NAME */
577 major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType);
578
579 /* release intermediate buffers before checking status */
580 jname = getJavaString(env, &outNameBuf);
581 if ((*env)->ExceptionCheck(env)) {
582 return NULL;
583 }
584
585 checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]");
586 if ((*env)->ExceptionCheck(env)) {
587 return NULL;
588 }
589
590 jtype = getJavaOID(env, outNameType);
591 if ((*env)->ExceptionCheck(env)) {
592 return NULL;
593 }
594
595 jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL);
596 /* return immediately if an exception has occurred */
597 if ((*env)->ExceptionCheck(env)) {
598 return NULL;
599 }
600
601 (*env)->SetObjectArrayElement(env, jresult, 0, jname);
602 if ((*env)->ExceptionCheck(env)) {
603 return NULL;
604 }
605 (*env)->SetObjectArrayElement(env, jresult, 1, jtype);
606 if ((*env)->ExceptionCheck(env)) {
607 return NULL;
608 }
609
610 return jresult;
611 }
612
613 /*
614 * Class: sun_security_jgss_wrapper_GSSLibStub
615 * Method: acquireCred
616 * Signature: (JII)J
617 */
618 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv * env,jobject jobj,jlong pName,jint reqTime,jint usage)619 Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv *env,
620 jobject jobj,
621 jlong pName,
622 jint reqTime,
623 jint usage)
624 {
625 OM_uint32 minor, major;
626 gss_OID mech;
627 gss_OID_set mechs;
628 gss_cred_usage_t credUsage;
629 gss_name_t nameHdl;
630 gss_cred_id_t credHdl;
631 credHdl = GSS_C_NO_CREDENTIAL;
632
633 TRACE0("[GSSLibStub_acquireCred]");
634
635 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
636 mechs = newGSSOIDSet(mech);
637 credUsage = (gss_cred_usage_t) usage;
638 nameHdl = (gss_name_t) jlong_to_ptr(pName);
639
640 TRACE2("[GSSLibStub_acquireCred] pName=%ld, usage=%d", (long)pName, usage);
641
642 /* gss_acquire_cred(...) => GSS_S_BAD_MECH, GSS_S_BAD_NAMETYPE,
643 GSS_S_BAD_NAME, GSS_S_CREDENTIALS_EXPIRED, GSS_S_NO_CRED */
644 major =
645 (*ftab->acquireCred)(&minor, nameHdl, reqTime, mechs,
646 credUsage, &credHdl, NULL, NULL);
647 /* release intermediate buffers */
648 deleteGSSOIDSet(mechs);
649
650 TRACE1("[GSSLibStub_acquireCred] pCred=%" PRIuPTR "", (uintptr_t) credHdl);
651
652 checkStatus(env, jobj, major, minor, "[GSSLibStub_acquireCred]");
653 if ((*env)->ExceptionCheck(env)) {
654 return jlong_zero;
655 }
656 return ptr_to_jlong(credHdl);
657 }
658
659 /*
660 * Class: sun_security_jgss_wrapper_GSSLibStub
661 * Method: releaseCred
662 * Signature: (J)J
663 */
664 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_releaseCred(JNIEnv * env,jobject jobj,jlong pCred)665 Java_sun_security_jgss_wrapper_GSSLibStub_releaseCred(JNIEnv *env,
666 jobject jobj,
667 jlong pCred)
668 {
669 OM_uint32 minor, major;
670 gss_cred_id_t credHdl;
671
672 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
673
674 TRACE1("[GSSLibStub_releaseCred] %ld", (long int)pCred);
675
676 if (credHdl != GSS_C_NO_CREDENTIAL) {
677 /* gss_release_cred(...) => GSS_S_NO_CRED(!) */
678 major = (*ftab->releaseCred)(&minor, &credHdl);
679
680 checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseCred]");
681 if ((*env)->ExceptionCheck(env)) {
682 return jlong_zero;
683 }
684 }
685 return ptr_to_jlong(credHdl);
686 }
687
688 /*
689 * Utility routine for obtaining info about a credential.
690 */
inquireCred(JNIEnv * env,jobject jobj,gss_cred_id_t pCred,jint type,void * result)691 void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred,
692 jint type, void *result) {
693 OM_uint32 minor=0, major=0;
694 OM_uint32 routineErr;
695 gss_cred_id_t credHdl;
696
697 credHdl = pCred;
698
699 TRACE1("[gss_inquire_cred] %" PRIuPTR "", (uintptr_t) pCred);
700
701 /* gss_inquire_cred(...) => GSS_S_DEFECTIVE_CREDENTIAL(!),
702 GSS_S_CREDENTIALS_EXPIRED(!), GSS_S_NO_CRED(!) */
703 if (type == TYPE_CRED_NAME) {
704 major = (*ftab->inquireCred)(&minor, credHdl, result, NULL, NULL, NULL);
705 } else if (type == TYPE_CRED_TIME) {
706 major = (*ftab->inquireCred)(&minor, credHdl, NULL, result, NULL, NULL);
707 } else if (type == TYPE_CRED_USAGE) {
708 major = (*ftab->inquireCred)(&minor, credHdl, NULL, NULL, result, NULL);
709 }
710
711 routineErr = GSS_ROUTINE_ERROR(major);
712 if (routineErr == GSS_S_CREDENTIALS_EXPIRED) {
713 /* ignore GSS_S_CREDENTIALS_EXPIRED for query */
714 major = GSS_CALLING_ERROR(major) |
715 GSS_SUPPLEMENTARY_INFO(major);
716 } else if (routineErr == GSS_S_NO_CRED) {
717 /* twik since Java API throws BAD_MECH instead of NO_CRED */
718 major = GSS_CALLING_ERROR(major) |
719 GSS_S_BAD_MECH | GSS_SUPPLEMENTARY_INFO(major);
720 }
721 checkStatus(env, jobj, major, minor, "[gss_inquire_cred]");
722 }
723
724 /*
725 * Class: sun_security_jgss_wrapper_GSSLibStub
726 * Method: getCredName
727 * Signature: (J)J
728 */
729 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv * env,jobject jobj,jlong pCred)730 Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv *env,
731 jobject jobj,
732 jlong pCred)
733 {
734 gss_name_t nameHdl;
735 gss_cred_id_t credHdl;
736
737 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
738
739 TRACE1("[GSSLibStub_getCredName] %ld", (long int)pCred);
740
741 nameHdl = GSS_C_NO_NAME;
742 inquireCred(env, jobj, credHdl, TYPE_CRED_NAME, &nameHdl);
743 /* return immediately if an exception has occurred */
744 if ((*env)->ExceptionCheck(env)) {
745 return jlong_zero;
746 }
747
748 TRACE1("[GSSLibStub_getCredName] pName=%" PRIuPTR "", (uintptr_t) nameHdl);
749 return ptr_to_jlong(nameHdl);
750 }
751
752 /*
753 * Class: sun_security_jgss_wrapper_GSSLibStub
754 * Method: getCredTime
755 * Signature: (J)I
756 */
757 JNIEXPORT jint JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getCredTime(JNIEnv * env,jobject jobj,jlong pCred)758 Java_sun_security_jgss_wrapper_GSSLibStub_getCredTime(JNIEnv *env,
759 jobject jobj,
760 jlong pCred)
761 {
762 gss_cred_id_t credHdl;
763 OM_uint32 lifetime;
764
765 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
766
767 TRACE1("[GSSLibStub_getCredTime] %ld", (long int)pCred);
768
769 lifetime = 0;
770 inquireCred(env, jobj, credHdl, TYPE_CRED_TIME, &lifetime);
771 /* return immediately if an exception has occurred */
772 if ((*env)->ExceptionCheck(env)) {
773 return 0;
774 }
775 return getJavaTime(lifetime);
776 }
777
778 /*
779 * Class: sun_security_jgss_wrapper_GSSLibStub
780 * Method: getCredUsage
781 * Signature: (J)I
782 */
783 JNIEXPORT jint JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getCredUsage(JNIEnv * env,jobject jobj,jlong pCred)784 Java_sun_security_jgss_wrapper_GSSLibStub_getCredUsage(JNIEnv *env,
785 jobject jobj,
786 jlong pCred)
787 {
788 gss_cred_usage_t usage;
789 gss_cred_id_t credHdl;
790
791 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
792
793 TRACE1("[GSSLibStub_getCredUsage] %ld", (long int)pCred);
794
795 inquireCred(env, jobj, credHdl, TYPE_CRED_USAGE, &usage);
796 /* return immediately if an exception has occurred */
797 if ((*env)->ExceptionCheck(env)) {
798 return -1;
799 }
800 return (jint) usage;
801 }
802 /*
803 * Class: sun_security_jgss_wrapper_GSSLibStub
804 * Method: importContext
805 * Signature: ([B)Lsun/security/jgss/wrapper/NativeGSSContext;
806 */
807 JNIEXPORT jobject JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_importContext(JNIEnv * env,jobject jobj,jbyteArray jctxtToken)808 Java_sun_security_jgss_wrapper_GSSLibStub_importContext(JNIEnv *env,
809 jobject jobj,
810 jbyteArray jctxtToken)
811 {
812 OM_uint32 minor, major;
813 gss_buffer_desc ctxtToken;
814 gss_ctx_id_t contextHdl;
815 gss_OID mech, mech2;
816
817 TRACE0("[GSSLibStub_importContext]");
818
819 contextHdl = GSS_C_NO_CONTEXT;
820 initGSSBuffer(env, jctxtToken, &ctxtToken);
821 if ((*env)->ExceptionCheck(env)) {
822 return NULL;
823 }
824
825 /* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN,
826 GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */
827 major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl);
828
829 TRACE1("[GSSLibStub_importContext] pContext=%" PRIuPTR "", (uintptr_t) contextHdl);
830
831 /* release intermediate buffers */
832 resetGSSBuffer(&ctxtToken);
833
834 checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext]");
835 /* return immediately if an exception has occurred */
836 if ((*env)->ExceptionCheck(env)) {
837 return NULL;
838 }
839
840 /* now that the context has been imported, proceed to find out
841 its mech */
842 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL,
843 NULL, &mech, NULL, NULL, NULL);
844
845 checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext] getMech");
846 /* return immediately if an exception has occurred */
847 if ((*env)->ExceptionCheck(env)) {
848 return NULL;
849 }
850
851 mech2 = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj,
852 FID_GSSLibStub_pMech));
853
854 if (sameMech(mech, mech2) == JNI_TRUE) {
855 /* mech match - return the context object */
856 return (*env)->NewObject(env, CLS_NativeGSSContext,
857 MID_NativeGSSContext_ctor,
858 ptr_to_jlong(contextHdl), jobj);
859 } else {
860 /* mech mismatch - clean up then return null */
861 major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
862 checkStatus(env, jobj, major, minor,
863 "[GSSLibStub_importContext] cleanup");
864 return NULL;
865 }
866 }
867
868 /*
869 * Class: sun_security_jgss_wrapper_GSSLibStub
870 * Method: initContext
871 * Signature: (JJLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B
872 */
873 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv * env,jobject jobj,jlong pCred,jlong pName,jobject jcb,jbyteArray jinToken,jobject jcontextSpi)874 Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv *env,
875 jobject jobj,
876 jlong pCred,
877 jlong pName,
878 jobject jcb,
879 jbyteArray jinToken,
880 jobject jcontextSpi)
881 {
882 OM_uint32 minor, major;
883 gss_cred_id_t credHdl ;
884 gss_ctx_id_t contextHdl, contextHdlSave;
885 gss_name_t targetName;
886 gss_OID mech;
887 OM_uint32 flags, aFlags;
888 OM_uint32 time, aTime;
889 gss_channel_bindings_t cb;
890 gss_buffer_desc inToken;
891 gss_buffer_desc outToken;
892 jbyteArray jresult;
893 /* UNCOMMENT after SEAM bug#6287358 is backported to S10
894 gss_OID aMech;
895 jobject jMech;
896 */
897
898 TRACE0("[GSSLibStub_initContext]");
899
900 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
901 contextHdl = contextHdlSave = (gss_ctx_id_t) jlong_to_ptr(
902 (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
903 targetName = (gss_name_t) jlong_to_ptr(pName);
904 mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
905 flags = (OM_uint32) (*env)->GetIntField(env, jcontextSpi,
906 FID_NativeGSSContext_flags);
907 time = getGSSTime((*env)->GetIntField(env, jcontextSpi,
908 FID_NativeGSSContext_lifetime));
909 cb = newGSSCB(env, jcb);
910 if ((*env)->ExceptionCheck(env)) {
911 return NULL;
912 }
913
914 initGSSBuffer(env, jinToken, &inToken);
915 if ((*env)->ExceptionCheck(env)) {
916 deleteGSSCB(cb);
917 return NULL;
918 }
919
920 TRACE2( "[GSSLibStub_initContext] before: pCred=%" PRIuPTR ", pContext=%" PRIuPTR "",
921 (uintptr_t)credHdl, (uintptr_t)contextHdl);
922
923 /* gss_init_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
924 GSS_S_DEFECTIVE_TOKEN, GSS_S_NO_CRED, GSS_S_DEFECTIVE_CREDENTIAL(!),
925 GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, GSS_S_BAD_MIC,
926 GSS_S_OLD_TOKEN, GSS_S_DUPLICATE_TOKEN, GSS_S_NO_CONTEXT(!),
927 GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!), GSS_S_BAD_MECH */
928 major = (*ftab->initSecContext)(&minor, credHdl,
929 &contextHdl, targetName, mech,
930 flags, time, cb, &inToken, NULL /*aMech*/,
931 &outToken, &aFlags, &aTime);
932
933 TRACE2("[GSSLibStub_initContext] after: pContext=%" PRIuPTR ", outToken len=%ld",
934 (uintptr_t)contextHdl, (long)outToken.length);
935
936 // update context handle with the latest value if changed
937 // this is to work with both MIT and Solaris. Former deletes half-built
938 // context if error occurs
939 if (contextHdl != contextHdlSave) {
940 (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
941 ptr_to_jlong(contextHdl));
942 TRACE1("[GSSLibStub_initContext] set pContext=%" PRIuPTR "", (uintptr_t)contextHdl);
943 }
944
945 if (GSS_ERROR(major) == GSS_S_COMPLETE) {
946 /* update member values if needed */
947 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
948 TRACE1("[GSSLibStub_initContext] set flags=0x%x", aFlags);
949
950 if (major == GSS_S_COMPLETE) {
951 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
952 getJavaTime(aTime));
953 TRACE0("[GSSLibStub_initContext] context established");
954
955 (*env)->SetBooleanField(env, jcontextSpi,
956 FID_NativeGSSContext_isEstablished,
957 JNI_TRUE);
958
959 /* UNCOMMENT after SEAM bug#6287358 is backported to S10
960 jMech = getJavaOID(env, aMech);
961 (*env)->SetObjectField(env, jcontextSpi,
962 FID_NativeGSSContext_actualMech, jMech);
963 */
964 } else if (major & GSS_S_CONTINUE_NEEDED) {
965 TRACE0("[GSSLibStub_initContext] context not established");
966 major -= GSS_S_CONTINUE_NEEDED;
967 }
968 }
969
970 /* release intermediate buffers before checking status */
971 deleteGSSCB(cb);
972 resetGSSBuffer(&inToken);
973 jresult = getJavaBuffer(env, &outToken);
974 if ((*env)->ExceptionCheck(env)) {
975 return NULL;
976 }
977
978 checkStatus(env, jobj, major, minor, "[GSSLibStub_initContext]");
979 if ((*env)->ExceptionCheck(env)) {
980 return NULL;
981 }
982 return jresult;
983 }
984
985 /*
986 * Class: sun_security_jgss_wrapper_GSSLibStub
987 * Method: acceptContext
988 * Signature: (JLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B
989 */
990 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv * env,jobject jobj,jlong pCred,jobject jcb,jbyteArray jinToken,jobject jcontextSpi)991 Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv *env,
992 jobject jobj,
993 jlong pCred,
994 jobject jcb,
995 jbyteArray jinToken,
996 jobject jcontextSpi)
997 {
998 OM_uint32 minor, major;
999 OM_uint32 minor2, major2;
1000 gss_ctx_id_t contextHdl, contextHdlSave;
1001 gss_cred_id_t credHdl;
1002 gss_buffer_desc inToken;
1003 gss_channel_bindings_t cb;
1004 gss_name_t srcName;
1005 gss_buffer_desc outToken;
1006 gss_OID aMech;
1007 OM_uint32 aFlags;
1008 OM_uint32 aTime;
1009 gss_cred_id_t delCred;
1010 jobject jsrcName = NULL;
1011 jobject jdelCred;
1012 jobject jMech;
1013 jboolean setTarget;
1014 gss_name_t targetName;
1015 jobject jtargetName;
1016
1017 TRACE0("[GSSLibStub_acceptContext]");
1018
1019 contextHdl = contextHdlSave = (gss_ctx_id_t)jlong_to_ptr(
1020 (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
1021 credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
1022 initGSSBuffer(env, jinToken, &inToken);
1023 if ((*env)->ExceptionCheck(env)) {
1024 return NULL;
1025 }
1026 cb = newGSSCB(env, jcb);
1027 if ((*env)->ExceptionCheck(env)) {
1028 resetGSSBuffer(&inToken);
1029 return NULL;
1030 }
1031 srcName = targetName = GSS_C_NO_NAME;
1032 delCred = GSS_C_NO_CREDENTIAL;
1033 setTarget = (credHdl == GSS_C_NO_CREDENTIAL);
1034 aFlags = 0;
1035
1036 TRACE2( "[GSSLibStub_acceptContext] before: pCred=%" PRIuPTR ", pContext=%" PRIuPTR "",
1037 (uintptr_t) credHdl, (uintptr_t) contextHdl);
1038
1039 /* gss_accept_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
1040 GSS_S_DEFECTIVE_TOKEN, GSS_S_DEFECTIVE_CREDENTIAL(!),
1041 GSS_S_NO_CRED, GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS,
1042 GSS_S_NO_CONTEXT(!), GSS_S_BAD_MIC, GSS_S_OLD_TOKEN,
1043 GSS_S_DUPLICATE_TOKEN, GSS_S_BAD_MECH */
1044 major =
1045 (*ftab->acceptSecContext)(&minor, &contextHdl, credHdl,
1046 &inToken, cb, &srcName, &aMech, &outToken,
1047 &aFlags, &aTime, &delCred);
1048 /* release intermediate buffers before checking status */
1049
1050 deleteGSSCB(cb);
1051 resetGSSBuffer(&inToken);
1052
1053 TRACE3("[GSSLibStub_acceptContext] after: pCred=%" PRIuPTR ", pContext=%" PRIuPTR ", pDelegCred=%" PRIuPTR "",
1054 (uintptr_t)credHdl, (uintptr_t)contextHdl, (uintptr_t) delCred);
1055
1056 // update context handle with the latest value if changed
1057 // this is to work with both MIT and Solaris. Former deletes half-built
1058 // context if error occurs
1059 if (contextHdl != contextHdlSave) {
1060 (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
1061 ptr_to_jlong(contextHdl));
1062 TRACE1("[GSSLibStub_acceptContext] set pContext=%" PRIuPTR "", (uintptr_t)contextHdl);
1063 }
1064
1065 if (GSS_ERROR(major) == GSS_S_COMPLETE) {
1066 /* update member values if needed */
1067 // WORKAROUND for a Heimdal bug
1068 if (delCred == GSS_C_NO_CREDENTIAL) {
1069 aFlags &= 0xfffffffe;
1070 }
1071 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
1072 TRACE1("[GSSLibStub_acceptContext] set flags=0x%x", aFlags);
1073
1074 if (setTarget) {
1075 major2 = (*ftab->inquireContext)(&minor2, contextHdl, NULL,
1076 &targetName, NULL, NULL, NULL,
1077 NULL, NULL);
1078 checkStatus(env, jobj, major2, minor2,
1079 "[GSSLibStub_acceptContext] inquire");
1080 if ((*env)->ExceptionCheck(env)) {
1081 goto error;
1082 }
1083
1084 jtargetName = (*env)->NewObject(env, CLS_GSSNameElement,
1085 MID_GSSNameElement_ctor,
1086 ptr_to_jlong(targetName), jobj);
1087 if ((*env)->ExceptionCheck(env)) {
1088 goto error;
1089 }
1090
1091 TRACE1("[GSSLibStub_acceptContext] set targetName=%" PRIuPTR "",
1092 (uintptr_t)targetName);
1093
1094 (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_targetName,
1095 jtargetName);
1096 if ((*env)->ExceptionCheck(env)) {
1097 goto error;
1098 }
1099 }
1100 if (srcName != GSS_C_NO_NAME) {
1101 jsrcName = (*env)->NewObject(env, CLS_GSSNameElement,
1102 MID_GSSNameElement_ctor,
1103 ptr_to_jlong(srcName), jobj);
1104 if ((*env)->ExceptionCheck(env)) {
1105 goto error;
1106 }
1107
1108 TRACE1("[GSSLibStub_acceptContext] set srcName=%" PRIuPTR "", (uintptr_t)srcName);
1109
1110 (*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_srcName,
1111 jsrcName);
1112 if ((*env)->ExceptionCheck(env)) {
1113 goto error;
1114 }
1115 }
1116 if (major == GSS_S_COMPLETE) {
1117 TRACE0("[GSSLibStub_acceptContext] context established");
1118
1119 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
1120 getJavaTime(aTime));
1121 (*env)->SetBooleanField(env, jcontextSpi,
1122 FID_NativeGSSContext_isEstablished,
1123 JNI_TRUE);
1124 jMech = getJavaOID(env, aMech);
1125 if ((*env)->ExceptionCheck(env)) {
1126 goto error;
1127 }
1128 (*env)->SetObjectField(env, jcontextSpi,
1129 FID_NativeGSSContext_actualMech, jMech);
1130 if ((*env)->ExceptionCheck(env)) {
1131 goto error;
1132 }
1133 if (delCred != GSS_C_NO_CREDENTIAL) {
1134 jdelCred = (*env)->NewObject(env, CLS_GSSCredElement,
1135 MID_GSSCredElement_ctor,
1136 ptr_to_jlong(delCred), jsrcName, jMech);
1137 if ((*env)->ExceptionCheck(env)) {
1138 goto error;
1139 }
1140 (*env)->SetObjectField(env, jcontextSpi,
1141 FID_NativeGSSContext_delegatedCred,
1142 jdelCred);
1143 TRACE1("[GSSLibStub_acceptContext] set delegatedCred=%" PRIuPTR "",
1144 (uintptr_t) delCred);
1145
1146 if ((*env)->ExceptionCheck(env)) {
1147 goto error;
1148 }
1149 }
1150 } else if (major & GSS_S_CONTINUE_NEEDED) {
1151 TRACE0("[GSSLibStub_acceptContext] context not established");
1152
1153 if (aFlags & GSS_C_PROT_READY_FLAG) {
1154 (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
1155 getJavaTime(aTime));
1156 }
1157 major -= GSS_S_CONTINUE_NEEDED;
1158 }
1159 }
1160 return getJavaBuffer(env, &outToken);
1161
1162 error:
1163 (*ftab->releaseBuffer)(&minor, &outToken);
1164 if (srcName != GSS_C_NO_NAME) {
1165 (*ftab->releaseName)(&minor, &srcName);
1166 }
1167 if (targetName != GSS_C_NO_NAME) {
1168 (*ftab->releaseName)(&minor, &targetName);
1169 }
1170 if (delCred != GSS_C_NO_CREDENTIAL) {
1171 (*ftab->releaseCred) (&minor, &delCred);
1172 }
1173 return NULL;
1174 }
1175
1176 /*
1177 * Class: sun_security_jgss_wrapper_GSSLibStub
1178 * Method: inquireContext
1179 * Signature: (J)[J
1180 */
1181 JNIEXPORT jlongArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_inquireContext(JNIEnv * env,jobject jobj,jlong pContext)1182 Java_sun_security_jgss_wrapper_GSSLibStub_inquireContext(JNIEnv *env,
1183 jobject jobj,
1184 jlong pContext)
1185 {
1186 OM_uint32 minor, major;
1187 gss_ctx_id_t contextHdl;
1188 gss_name_t srcName, targetName;
1189 OM_uint32 time;
1190 OM_uint32 flags;
1191 int isInitiator, isEstablished;
1192 #if defined (_WIN32) && defined (_MSC_VER)
1193 __declspec(align(8))
1194 #endif
1195 jlong result[6];
1196 jlongArray jresult;
1197
1198 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1199
1200 TRACE1("[GSSLibStub_inquireContext] %" PRIuPTR "", (uintptr_t)contextHdl);
1201
1202 srcName = targetName = GSS_C_NO_NAME;
1203 time = 0;
1204 flags = isInitiator = isEstablished = 0;
1205
1206 /* gss_inquire_context(...) => GSS_S_NO_CONTEXT(!) */
1207 major = (*ftab->inquireContext)(&minor, contextHdl, &srcName,
1208 &targetName, &time, NULL, &flags,
1209 &isInitiator, &isEstablished);
1210 /* update member values if needed */
1211 TRACE2("[GSSLibStub_inquireContext] srcName %" PRIuPTR ", targetName %" PRIuPTR "",
1212 (uintptr_t)srcName, (uintptr_t)targetName);
1213
1214 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
1215 if ((*env)->ExceptionCheck(env)) {
1216 return NULL;
1217 }
1218 result[0] = ptr_to_jlong(srcName);
1219 result[1] = ptr_to_jlong(targetName);
1220 result[2] = (jlong) isInitiator;
1221 result[3] = (jlong) isEstablished;
1222 result[4] = (jlong) flags;
1223 result[5] = (jlong) getJavaTime(time);
1224
1225 jresult = (*env)->NewLongArray(env, 6);
1226 if (jresult == NULL) {
1227 return NULL;
1228 }
1229 (*env)->SetLongArrayRegion(env, jresult, 0, 6, result);
1230 if ((*env)->ExceptionCheck(env)) {
1231 return NULL;
1232 }
1233 return jresult;
1234 }
1235
1236 /*
1237 * Class: sun_security_jgss_wrapper_GSSLibStub
1238 * Method: getContextMech
1239 * Signature: (J)Lorg/ietf/jgss/Oid;
1240 */
1241 JNIEXPORT jobject JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getContextMech(JNIEnv * env,jobject jobj,jlong pContext)1242 Java_sun_security_jgss_wrapper_GSSLibStub_getContextMech(JNIEnv *env,
1243 jobject jobj,
1244 jlong pContext)
1245 {
1246 OM_uint32 minor, major;
1247 gss_OID mech;
1248 gss_ctx_id_t contextHdl;
1249
1250 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1251
1252 TRACE1("[GSSLibStub_getContextMech] %ld", (long int)pContext);
1253
1254 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL,
1255 NULL, &mech, NULL, NULL, NULL);
1256
1257 checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextMech]");
1258 /* return immediately if an exception has occurred */
1259 if ((*env)->ExceptionCheck(env)) {
1260 return NULL;
1261 }
1262
1263 return getJavaOID(env, mech);
1264 }
1265
1266 /*
1267 * Class: sun_security_jgss_wrapper_GSSLibStub
1268 * Method: getContextName
1269 * Signature: (JZ)J
1270 */
1271 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv * env,jobject jobj,jlong pContext,jboolean isSrc)1272 Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv *env,
1273 jobject jobj, jlong pContext, jboolean isSrc)
1274 {
1275 OM_uint32 minor, major;
1276 gss_name_t nameHdl;
1277 gss_ctx_id_t contextHdl;
1278
1279 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1280
1281 TRACE2("[GSSLibStub_getContextName] %" PRIuPTR ", isSrc=%d",
1282 (uintptr_t)contextHdl, isSrc);
1283
1284 nameHdl = GSS_C_NO_NAME;
1285 if (isSrc == JNI_TRUE) {
1286 major = (*ftab->inquireContext)(&minor, contextHdl, &nameHdl, NULL,
1287 NULL, NULL, NULL, NULL, NULL);
1288 } else {
1289 major = (*ftab->inquireContext)(&minor, contextHdl, NULL, &nameHdl,
1290 NULL, NULL, NULL, NULL, NULL);
1291 }
1292
1293 checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContextAll]");
1294 /* return immediately if an exception has occurred */
1295 if ((*env)->ExceptionCheck(env)) {
1296 return jlong_zero;
1297 }
1298
1299 TRACE1("[GSSLibStub_getContextName] pName=%" PRIuPTR "", (uintptr_t) nameHdl);
1300
1301 return ptr_to_jlong(nameHdl);
1302 }
1303
1304 /*
1305 * Class: sun_security_jgss_wrapper_GSSLibStub
1306 * Method: getContextTime
1307 * Signature: (J)I
1308 */
1309 JNIEXPORT jint JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getContextTime(JNIEnv * env,jobject jobj,jlong pContext)1310 Java_sun_security_jgss_wrapper_GSSLibStub_getContextTime(JNIEnv *env,
1311 jobject jobj,
1312 jlong pContext) {
1313 OM_uint32 minor, major;
1314 gss_ctx_id_t contextHdl;
1315 OM_uint32 time;
1316
1317 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1318
1319 TRACE1("[GSSLibStub_getContextTime] %" PRIuPTR "", (uintptr_t)contextHdl);
1320
1321 if (contextHdl == GSS_C_NO_CONTEXT) return 0;
1322
1323 /* gss_context_time(...) => GSS_S_CONTEXT_EXPIRED(!),
1324 GSS_S_NO_CONTEXT(!) */
1325 major = (*ftab->contextTime)(&minor, contextHdl, &time);
1326 if (GSS_ROUTINE_ERROR(major) == GSS_S_CONTEXT_EXPIRED) {
1327 major = GSS_CALLING_ERROR(major) | GSS_SUPPLEMENTARY_INFO(major);
1328 }
1329 checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextTime]");
1330 if ((*env)->ExceptionCheck(env)) {
1331 return 0;
1332 }
1333 return getJavaTime(time);
1334 }
1335
1336 /*
1337 * Class: sun_security_jgss_wrapper_GSSLibStub
1338 * Method: deleteContext
1339 * Signature: (J)J
1340 */
1341 JNIEXPORT jlong JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_deleteContext(JNIEnv * env,jobject jobj,jlong pContext)1342 Java_sun_security_jgss_wrapper_GSSLibStub_deleteContext(JNIEnv *env,
1343 jobject jobj,
1344 jlong pContext)
1345 {
1346 OM_uint32 minor, major;
1347 gss_ctx_id_t contextHdl;
1348
1349 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1350
1351 TRACE1("[GSSLibStub_deleteContext] %" PRIuPTR "", (uintptr_t)contextHdl);
1352
1353 if (contextHdl == GSS_C_NO_CONTEXT) return ptr_to_jlong(GSS_C_NO_CONTEXT);
1354
1355 /* gss_delete_sec_context(...) => GSS_S_NO_CONTEXT(!) */
1356 major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
1357
1358 checkStatus(env, jobj, major, minor, "[GSSLibStub_deleteContext]");
1359 if ((*env)->ExceptionCheck(env)) {
1360 return jlong_zero;
1361 }
1362 return (jlong) ptr_to_jlong(contextHdl);
1363 }
1364
1365 /*
1366 * Class: sun_security_jgss_wrapper_GSSLibStub
1367 * Method: wrapSizeLimit
1368 * Signature: (JIII)I
1369 */
1370 JNIEXPORT jint JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_wrapSizeLimit(JNIEnv * env,jobject jobj,jlong pContext,jint reqFlag,jint jqop,jint joutSize)1371 Java_sun_security_jgss_wrapper_GSSLibStub_wrapSizeLimit(JNIEnv *env,
1372 jobject jobj,
1373 jlong pContext,
1374 jint reqFlag,
1375 jint jqop,
1376 jint joutSize)
1377 {
1378 OM_uint32 minor, major;
1379 gss_ctx_id_t contextHdl;
1380 OM_uint32 outSize, maxInSize;
1381 gss_qop_t qop;
1382
1383 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1384
1385 TRACE1("[GSSLibStub_wrapSizeLimit] %" PRIuPTR "", (uintptr_t)contextHdl);
1386
1387 if (contextHdl == GSS_C_NO_CONTEXT) {
1388 // Twik per javadoc
1389 checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0,
1390 "[GSSLibStub_wrapSizeLimit]");
1391 return 0;
1392 }
1393
1394 qop = (gss_qop_t) jqop;
1395 outSize = (OM_uint32) joutSize;
1396 /* gss_wrap_size_limit(...) => GSS_S_NO_CONTEXT(!), GSS_S_CONTEXT_EXPIRED,
1397 GSS_S_BAD_QOP */
1398 major = (*ftab->wrapSizeLimit)(&minor, contextHdl, reqFlag,
1399 qop, outSize, &maxInSize);
1400
1401 checkStatus(env, jobj, major, minor, "[GSSLibStub_wrapSizeLimit]");
1402 if ((*env)->ExceptionCheck(env)) {
1403 return 0;
1404 }
1405 return (jint) maxInSize;
1406 }
1407
1408 /*
1409 * Class: sun_security_jgss_wrapper_GSSLibStub
1410 * Method: exportContext
1411 * Signature: (J)[B
1412 */
1413 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_exportContext(JNIEnv * env,jobject jobj,jlong pContext)1414 Java_sun_security_jgss_wrapper_GSSLibStub_exportContext(JNIEnv *env,
1415 jobject jobj,
1416 jlong pContext)
1417 {
1418 OM_uint32 minor, major;
1419 gss_ctx_id_t contextHdl;
1420 gss_buffer_desc interProcToken;
1421 jbyteArray jresult;
1422
1423 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1424
1425 TRACE1("[GSSLibStub_exportContext] %" PRIuPTR "", (uintptr_t)contextHdl);
1426
1427 if (contextHdl == GSS_C_NO_CONTEXT) {
1428 // Twik per javadoc
1429 checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0, "[GSSLibStub_exportContext]");
1430 return NULL;
1431 }
1432 /* gss_export_sec_context(...) => GSS_S_CONTEXT_EXPIRED,
1433 GSS_S_NO_CONTEXT, GSS_S_UNAVAILABLE */
1434 major =
1435 (*ftab->exportSecContext)(&minor, &contextHdl, &interProcToken);
1436
1437 /* release intermediate buffers */
1438 jresult = getJavaBuffer(env, &interProcToken);
1439 if ((*env)->ExceptionCheck(env)) {
1440 return NULL;
1441 }
1442 checkStatus(env, jobj, major, minor, "[GSSLibStub_exportContext]");
1443 if ((*env)->ExceptionCheck(env)) {
1444 return NULL;
1445 }
1446
1447 return jresult;
1448 }
1449
1450 /*
1451 * Class: sun_security_jgss_wrapper_GSSLibStub
1452 * Method: getMic
1453 * Signature: (JI[B)[B
1454 */
1455 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_getMic(JNIEnv * env,jobject jobj,jlong pContext,jint jqop,jbyteArray jmsg)1456 Java_sun_security_jgss_wrapper_GSSLibStub_getMic(JNIEnv *env, jobject jobj,
1457 jlong pContext, jint jqop,
1458 jbyteArray jmsg)
1459 {
1460 OM_uint32 minor, major;
1461 gss_ctx_id_t contextHdl;
1462 gss_qop_t qop;
1463 gss_buffer_desc msg;
1464 gss_buffer_desc msgToken;
1465 jbyteArray jresult;
1466
1467 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1468
1469 TRACE1("[GSSLibStub_getMic] %" PRIuPTR "", (uintptr_t)contextHdl);
1470
1471 if (contextHdl == GSS_C_NO_CONTEXT) {
1472 // Twik per javadoc
1473 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]");
1474 return NULL;
1475 }
1476 qop = (gss_qop_t) jqop;
1477 initGSSBuffer(env, jmsg, &msg);
1478 if ((*env)->ExceptionCheck(env)) {
1479 return NULL;
1480 }
1481
1482 /* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
1483 GSS_S_BAD_QOP */
1484 major =
1485 (*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken);
1486
1487 /* release intermediate buffers */
1488 resetGSSBuffer(&msg);
1489 jresult = getJavaBuffer(env, &msgToken);
1490 if ((*env)->ExceptionCheck(env)) {
1491 return NULL;
1492 }
1493 checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]");
1494 if ((*env)->ExceptionCheck(env)) {
1495 return NULL;
1496 }
1497
1498 return jresult;
1499 }
1500
1501 /*
1502 * Class: sun_security_jgss_wrapper_GSSLibStub
1503 * Method: verifyMic
1504 * Signature: (J[B[BLorg/ietf/jgss/MessageProp;)V
1505 */
1506 JNIEXPORT void JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_verifyMic(JNIEnv * env,jobject jobj,jlong pContext,jbyteArray jmsgToken,jbyteArray jmsg,jobject jprop)1507 Java_sun_security_jgss_wrapper_GSSLibStub_verifyMic(JNIEnv *env,
1508 jobject jobj,
1509 jlong pContext,
1510 jbyteArray jmsgToken,
1511 jbyteArray jmsg,
1512 jobject jprop)
1513 {
1514 OM_uint32 minor, major;
1515 gss_ctx_id_t contextHdl;
1516 gss_buffer_desc msg;
1517 gss_buffer_desc msgToken;
1518 gss_qop_t qop;
1519
1520 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1521
1522 TRACE1("[GSSLibStub_verifyMic] %" PRIuPTR "", (uintptr_t)contextHdl);
1523
1524 if (contextHdl == GSS_C_NO_CONTEXT) {
1525 // Twik per javadoc
1526 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0,
1527 "[GSSLibStub_verifyMic]");
1528 return;
1529 }
1530
1531 qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
1532 if ((*env)->ExceptionCheck(env)) { return; }
1533
1534 initGSSBuffer(env, jmsg, &msg);
1535 if ((*env)->ExceptionCheck(env)) { return; }
1536
1537 initGSSBuffer(env, jmsgToken, &msgToken);
1538 if ((*env)->ExceptionCheck(env)) {
1539 resetGSSBuffer(&msg);
1540 return;
1541 }
1542
1543 /* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
1544 GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
1545 GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
1546 major =
1547 (*ftab->verifyMic)(&minor, contextHdl, &msg, &msgToken, &qop);
1548
1549 /* release intermediate buffers */
1550 resetGSSBuffer(&msg);
1551 resetGSSBuffer(&msgToken);
1552
1553 checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]");
1554 if ((*env)->ExceptionCheck(env)) {
1555 return;
1556 }
1557
1558 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
1559 if ((*env)->ExceptionCheck(env)) {
1560 return;
1561 }
1562
1563 setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
1564 minor);
1565 if ((*env)->ExceptionCheck(env)) {
1566 return;
1567 }
1568 }
1569
1570 /*
1571 * Class: sun_security_jgss_wrapper_GSSLibStub
1572 * Method: wrap
1573 * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B
1574 */
1575 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_wrap(JNIEnv * env,jobject jobj,jlong pContext,jbyteArray jmsg,jobject jprop)1576 Java_sun_security_jgss_wrapper_GSSLibStub_wrap(JNIEnv *env,
1577 jobject jobj,
1578 jlong pContext,
1579 jbyteArray jmsg,
1580 jobject jprop)
1581 {
1582 OM_uint32 minor, major;
1583 jboolean confFlag;
1584 gss_qop_t qop;
1585 gss_buffer_desc msg;
1586 gss_buffer_desc msgToken;
1587 int confState;
1588 gss_ctx_id_t contextHdl;
1589 jbyteArray jresult;
1590
1591 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1592
1593 TRACE1("[GSSLibStub_wrap] %" PRIuPTR "", (uintptr_t)contextHdl);
1594
1595 if (contextHdl == GSS_C_NO_CONTEXT) {
1596 // Twik per javadoc
1597 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_wrap]");
1598 return NULL;
1599 }
1600
1601 confFlag =
1602 (*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy);
1603 if ((*env)->ExceptionCheck(env)) {
1604 return NULL;
1605 }
1606
1607 qop = (gss_qop_t)
1608 (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
1609 if ((*env)->ExceptionCheck(env)) {
1610 return NULL;
1611 }
1612
1613 initGSSBuffer(env, jmsg, &msg);
1614 if ((*env)->ExceptionCheck(env)) {
1615 return NULL;
1616 }
1617
1618 /* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
1619 GSS_S_BAD_QOP */
1620 major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState,
1621 &msgToken);
1622
1623 /* release intermediate buffers */
1624 resetGSSBuffer(&msg);
1625 jresult = getJavaBuffer(env, &msgToken);
1626 if ((*env)->ExceptionCheck(env)) {
1627 return NULL;
1628 }
1629
1630 checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]");
1631 if ((*env)->ExceptionCheck(env)) {
1632 return NULL;
1633 }
1634
1635 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
1636 (confState? JNI_TRUE:JNI_FALSE));
1637 if ((*env)->ExceptionCheck(env)) {
1638 return NULL;
1639 }
1640 return jresult;
1641 }
1642
1643 /*
1644 * Class: sun_security_jgss_wrapper_GSSLibStub
1645 * Method: unwrap
1646 * Signature: (J[BLorg/ietf/jgss/MessageProp;)[B
1647 */
1648 JNIEXPORT jbyteArray JNICALL
Java_sun_security_jgss_wrapper_GSSLibStub_unwrap(JNIEnv * env,jobject jobj,jlong pContext,jbyteArray jmsgToken,jobject jprop)1649 Java_sun_security_jgss_wrapper_GSSLibStub_unwrap(JNIEnv *env,
1650 jobject jobj,
1651 jlong pContext,
1652 jbyteArray jmsgToken,
1653 jobject jprop)
1654 {
1655 OM_uint32 minor, major;
1656 gss_ctx_id_t contextHdl;
1657 gss_buffer_desc msgToken;
1658 gss_buffer_desc msg;
1659 int confState;
1660 gss_qop_t qop;
1661 jbyteArray jresult;
1662
1663 contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
1664
1665 TRACE1("[GSSLibStub_unwrap] %" PRIuPTR "", (uintptr_t)contextHdl);
1666
1667 if (contextHdl == GSS_C_NO_CONTEXT) {
1668 // Twik per javadoc
1669 checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]");
1670 return NULL;
1671 }
1672
1673 initGSSBuffer(env, jmsgToken, &msgToken);
1674 if ((*env)->ExceptionCheck(env)) {
1675 return NULL;
1676 }
1677
1678 confState = 0;
1679 qop = GSS_C_QOP_DEFAULT;
1680 /* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
1681 GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
1682 GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
1683 major =
1684 (*ftab->unwrap)(&minor, contextHdl, &msgToken, &msg, &confState, &qop);
1685
1686 /* release intermediate buffers */
1687 resetGSSBuffer(&msgToken);
1688 jresult = getJavaBuffer(env, &msg);
1689 if ((*env)->ExceptionCheck(env)) {
1690 return NULL;
1691 }
1692
1693 checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]");
1694 if ((*env)->ExceptionCheck(env)) {
1695 return NULL;
1696 }
1697
1698 /* update the message prop with relevant info */
1699 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
1700 (confState != 0));
1701 if ((*env)->ExceptionCheck(env)) {
1702 return NULL;
1703 }
1704 (*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
1705 if ((*env)->ExceptionCheck(env)) {
1706 return NULL;
1707 }
1708 setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
1709 minor);
1710 if ((*env)->ExceptionCheck(env)) {
1711 return NULL;
1712 }
1713
1714 return jresult;
1715 }
1716