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