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