mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
1714 lines
53 KiB
C
1714 lines
53 KiB
C
/*
|
|
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
#include "sun_security_jgss_wrapper_GSSLibStub.h"
|
|
#include "NativeUtil.h"
|
|
#include "NativeFunc.h"
|
|
#include "jlong.h"
|
|
#include <jni.h>
|
|
|
|
/* Constants for indicating what type of info is needed for inquiries */
|
|
const int TYPE_CRED_NAME = 10;
|
|
const int TYPE_CRED_TIME = 11;
|
|
const int TYPE_CRED_USAGE = 12;
|
|
|
|
static jclass tlsCBCl = NULL;
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: init
|
|
* Signature: (Ljava/lang/String;Z)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_init(JNIEnv *env,
|
|
jclass jcls,
|
|
jstring jlibName,
|
|
jboolean jDebug) {
|
|
const char *libName;
|
|
int failed;
|
|
|
|
if (!jDebug) {
|
|
JGSS_DEBUG = 0;
|
|
} else {
|
|
JGSS_DEBUG = 1;
|
|
}
|
|
|
|
if (jlibName == NULL) {
|
|
TRACE0("[GSSLibStub_init] GSS lib name is NULL");
|
|
return JNI_FALSE;
|
|
}
|
|
|
|
libName = (*env)->GetStringUTFChars(env, jlibName, NULL);
|
|
if (libName == NULL) {
|
|
return JNI_FALSE;
|
|
}
|
|
TRACE1("[GSSLibStub_init] libName=%s", libName);
|
|
|
|
/* initialize global function table */
|
|
failed = loadNative(libName);
|
|
(*env)->ReleaseStringUTFChars(env, jlibName, libName);
|
|
|
|
if (tlsCBCl == NULL) {
|
|
|
|
/* initialize TLS Channel Binding class wrapper */
|
|
jclass cl = (*env)->FindClass(env,
|
|
"sun/security/jgss/krb5/internal/TlsChannelBindingImpl");
|
|
if (cl == NULL) { /* exception thrown */
|
|
return JNI_FALSE;
|
|
}
|
|
tlsCBCl = (*env)->NewGlobalRef(env, cl);
|
|
}
|
|
|
|
if (!failed) {
|
|
return JNI_TRUE;
|
|
} else {
|
|
if (JGSS_DEBUG) {
|
|
#ifdef WIN32
|
|
#define MAX_MSG_SIZE 256
|
|
static CHAR szMsgBuf[MAX_MSG_SIZE];
|
|
DWORD dwRes;
|
|
DWORD dwError = GetLastError();
|
|
dwRes = FormatMessage (
|
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
dwError,
|
|
0,
|
|
szMsgBuf,
|
|
MAX_MSG_SIZE,
|
|
NULL);
|
|
if (0 == dwRes) {
|
|
TRACE1("GSS-API: Unknown failure %d", dwError);
|
|
} else {
|
|
TRACE1("GSS-API: %s",szMsgBuf);
|
|
}
|
|
#else
|
|
char* error = dlerror();
|
|
if (error) {
|
|
TRACE0(error);
|
|
}
|
|
#endif
|
|
}
|
|
return JNI_FALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getMechPtr
|
|
* Signature: ([B)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getMechPtr(JNIEnv *env,
|
|
jclass jcls,
|
|
jbyteArray jbytes) {
|
|
gss_OID cOid;
|
|
unsigned int i, len;
|
|
jbyte* bytes;
|
|
int found;
|
|
|
|
if (jbytes != NULL) {
|
|
found = 0;
|
|
len = (unsigned int)((*env)->GetArrayLength(env, jbytes) - 2);
|
|
bytes = (*env)->GetByteArrayElements(env, jbytes, NULL);
|
|
if (bytes == NULL) {
|
|
return ptr_to_jlong(NULL);
|
|
}
|
|
for (i = 0; i < ftab->mechs->count; i++) {
|
|
cOid = &(ftab->mechs->elements[i]);
|
|
if (len == cOid->length &&
|
|
(memcmp(cOid->elements, (bytes + 2), len) == 0)) {
|
|
// Found a match
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
(*env)->ReleaseByteArrayElements(env, jbytes, bytes, 0);
|
|
|
|
if (found != 1) {
|
|
checkStatus(env, NULL, GSS_S_BAD_MECH, 0, "[GSSLibStub_getMechPtr]");
|
|
return ptr_to_jlong(NULL);
|
|
} else {
|
|
return ptr_to_jlong(cOid);
|
|
}
|
|
} else {
|
|
return ptr_to_jlong(GSS_C_NO_OID);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Utility routine which releases the specified gss_channel_bindings_t
|
|
* structure.
|
|
*/
|
|
void deleteGSSCB(gss_channel_bindings_t cb) {
|
|
|
|
if (cb == GSS_C_NO_CHANNEL_BINDINGS) return;
|
|
|
|
/* release initiator address */
|
|
if (cb->initiator_addrtype != GSS_C_AF_NULLADDR &&
|
|
cb->initiator_addrtype != GSS_C_AF_UNSPEC) {
|
|
resetGSSBuffer(&(cb->initiator_address));
|
|
}
|
|
/* release acceptor address */
|
|
if (cb->acceptor_addrtype != GSS_C_AF_NULLADDR &&
|
|
cb->acceptor_addrtype != GSS_C_AF_UNSPEC) {
|
|
resetGSSBuffer(&(cb->acceptor_address));
|
|
}
|
|
/* release application data */
|
|
if (cb->application_data.length != 0) {
|
|
resetGSSBuffer(&(cb->application_data));
|
|
}
|
|
free(cb);
|
|
}
|
|
|
|
/*
|
|
* Utility routine which creates a gss_channel_bindings_t structure
|
|
* using the specified org.ietf.jgss.ChannelBinding object.
|
|
* NOTE: must call deleteGSSCB() to free up the resources.
|
|
*/
|
|
gss_channel_bindings_t newGSSCB(JNIEnv *env, jobject jcb) {
|
|
gss_channel_bindings_t cb;
|
|
jobject jinetAddr;
|
|
jbyteArray value;
|
|
|
|
if (jcb == NULL) {
|
|
return GSS_C_NO_CHANNEL_BINDINGS;
|
|
}
|
|
|
|
// initialize cb as zeroes to avoid uninitialized pointer being
|
|
// freed when deleteGSSCB is called at cleanup.
|
|
cb = calloc(1, sizeof(struct gss_channel_bindings_struct));
|
|
|
|
if (cb == NULL) {
|
|
gssThrowOutOfMemoryError(env, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
// initialize addrtype in CB first
|
|
// LDAP TLS Channel Binding requires GSS_C_AF_UNSPEC address type
|
|
// for unspecified initiator and acceptor addresses.
|
|
// GSS_C_AF_NULLADDR value should be used for unspecified address
|
|
// in all other cases.
|
|
|
|
if ((*env)->IsInstanceOf(env, jcb, tlsCBCl)) {
|
|
// TLS Channel Binding requires unspecified addrtype=0
|
|
cb->initiator_addrtype = GSS_C_AF_UNSPEC;
|
|
cb->acceptor_addrtype = GSS_C_AF_UNSPEC;
|
|
} else {
|
|
cb->initiator_addrtype = GSS_C_AF_NULLADDR;
|
|
cb->acceptor_addrtype = GSS_C_AF_NULLADDR;
|
|
}
|
|
|
|
/* set up initiator address */
|
|
jinetAddr = (*env)->CallObjectMethod(env, jcb,
|
|
MID_ChannelBinding_getInitiatorAddr);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
if (jinetAddr != NULL) {
|
|
value = (*env)->CallObjectMethod(env, jinetAddr,
|
|
MID_InetAddress_getAddr);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
cb->initiator_addrtype = GSS_C_AF_INET;
|
|
initGSSBuffer(env, value, &(cb->initiator_address));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
}
|
|
/* set up acceptor address */
|
|
jinetAddr = (*env)->CallObjectMethod(env, jcb,
|
|
MID_ChannelBinding_getAcceptorAddr);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
if (jinetAddr != NULL) {
|
|
value = (*env)->CallObjectMethod(env, jinetAddr,
|
|
MID_InetAddress_getAddr);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
cb->acceptor_addrtype = GSS_C_AF_INET;
|
|
initGSSBuffer(env, value, &(cb->acceptor_address));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
}
|
|
/* set up application data */
|
|
value = (*env)->CallObjectMethod(env, jcb,
|
|
MID_ChannelBinding_getAppData);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
initGSSBuffer(env, value, &(cb->application_data));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto cleanup;
|
|
}
|
|
return cb;
|
|
cleanup:
|
|
deleteGSSCB(cb);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Utility routine for storing the supplementary information
|
|
* into the specified org.ietf.jgss.MessageProp object.
|
|
*/
|
|
void setSupplementaryInfo(JNIEnv *env, jobject jstub, jobject jprop,
|
|
int suppInfo, int minor) {
|
|
jboolean isDuplicate, isOld, isUnseq, hasGap;
|
|
jstring minorMsg;
|
|
|
|
if (suppInfo != GSS_S_COMPLETE) {
|
|
isDuplicate = ((suppInfo & GSS_S_DUPLICATE_TOKEN) != 0);
|
|
isOld = ((suppInfo & GSS_S_OLD_TOKEN) != 0);
|
|
isUnseq = ((suppInfo & GSS_S_UNSEQ_TOKEN) != 0);
|
|
hasGap = ((suppInfo & GSS_S_GAP_TOKEN) != 0);
|
|
minorMsg = getMinorMessage(env, jstub, minor);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return;
|
|
}
|
|
(*env)->CallVoidMethod(env, jprop, MID_MessageProp_setSupplementaryStates,
|
|
isDuplicate, isOld, isUnseq, hasGap, minor,
|
|
minorMsg);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: indicateMechs
|
|
* Signature: ()[Lorg/ietf/jgss/Oid;
|
|
*/
|
|
JNIEXPORT jobjectArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_indicateMechs(JNIEnv *env,
|
|
jclass jcls)
|
|
{
|
|
if (ftab->mechs != NULL && ftab->mechs != GSS_C_NO_OID_SET) {
|
|
return getJavaOIDArray(env, ftab->mechs);
|
|
} else return NULL;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: inquireNamesForMech
|
|
* Signature: ()[Lorg/ietf/jgss/Oid;
|
|
*/
|
|
JNIEXPORT jobjectArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_inquireNamesForMech(JNIEnv *env,
|
|
jobject jobj)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_OID mech;
|
|
gss_OID_set nameTypes;
|
|
jobjectArray result;
|
|
|
|
if (ftab->inquireNamesForMech != NULL) {
|
|
mech = (gss_OID)jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
|
|
nameTypes = GSS_C_NO_OID_SET;
|
|
|
|
/* gss_inquire_names_for_mech(...) => N/A */
|
|
major = (*ftab->inquireNamesForMech)(&minor, mech, &nameTypes);
|
|
|
|
/* release intermediate buffers before checking status */
|
|
result = getJavaOIDArray(env, nameTypes);
|
|
deleteGSSOIDSet(nameTypes);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireNamesForMech]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
return result;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: releaseName
|
|
* Signature: (J)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_releaseName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl;
|
|
|
|
nameHdl = (gss_name_t) jlong_to_ptr(pName);
|
|
|
|
TRACE1("[GSSLibStub_releaseName] %ld", (long) pName);
|
|
|
|
if (nameHdl != GSS_C_NO_NAME) {
|
|
/* gss_release_name(...) => GSS_S_BAD_NAME */
|
|
major = (*ftab->releaseName)(&minor, &nameHdl);
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseName]");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: importName
|
|
* Signature: ([BLorg/ietf/jgss/Oid;)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv *env,
|
|
jobject jobj,
|
|
jbyteArray jnameVal,
|
|
jobject jnameType)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_buffer_desc nameVal;
|
|
gss_OID nameType;
|
|
gss_name_t nameHdl;
|
|
nameHdl = GSS_C_NO_NAME;
|
|
|
|
TRACE0("[GSSLibStub_importName]");
|
|
|
|
initGSSBuffer(env, jnameVal, &nameVal);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
|
|
nameType = newGSSOID(env, jnameType);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
resetGSSBuffer(&nameVal);
|
|
return jlong_zero;
|
|
}
|
|
|
|
/* gss_import_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME,
|
|
GSS_S_BAD_MECH */
|
|
major = (*ftab->importName)(&minor, &nameVal, nameType, &nameHdl);
|
|
|
|
TRACE1("[GSSLibStub_importName] %" PRIuPTR "", (uintptr_t) nameHdl);
|
|
|
|
/* release intermediate buffers */
|
|
deleteGSSOID(nameType);
|
|
resetGSSBuffer(&nameVal);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_importName]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
return ptr_to_jlong(nameHdl);
|
|
}
|
|
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: compareName
|
|
* Signature: (JJ)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_compareName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName1,
|
|
jlong pName2)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl1, nameHdl2;
|
|
int isEqual;
|
|
|
|
isEqual = 0;
|
|
nameHdl1 = (gss_name_t) jlong_to_ptr(pName1);
|
|
nameHdl2 = (gss_name_t) jlong_to_ptr(pName2);
|
|
|
|
TRACE2("[GSSLibStub_compareName] %ld %ld", (long)pName1, (long)pName2);
|
|
|
|
if ((nameHdl1 != GSS_C_NO_NAME) && (nameHdl2 != GSS_C_NO_NAME)) {
|
|
|
|
/* gss_compare_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!) */
|
|
major = (*ftab->compareName)(&minor, nameHdl1, nameHdl2, &isEqual);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_compareName]");
|
|
}
|
|
return (isEqual != 0);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: canonicalizeName
|
|
* Signature: (J)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl, mnNameHdl;
|
|
gss_OID mech;
|
|
|
|
nameHdl = (gss_name_t) jlong_to_ptr(pName);
|
|
|
|
TRACE1("[GSSLibStub_canonicalizeName] %ld", (long) pName);
|
|
|
|
if (nameHdl != GSS_C_NO_NAME) {
|
|
mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
|
|
mnNameHdl = GSS_C_NO_NAME;
|
|
|
|
/* gss_canonicalize_name(...) may return GSS_S_BAD_NAMETYPE,
|
|
GSS_S_BAD_NAME, GSS_S_BAD_MECH */
|
|
major = (*ftab->canonicalizeName)(&minor, nameHdl, mech, &mnNameHdl);
|
|
|
|
TRACE1("[GSSLibStub_canonicalizeName] MN=%" PRIuPTR "", (uintptr_t)mnNameHdl);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_canonicalizeName]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return ptr_to_jlong(GSS_C_NO_NAME);
|
|
}
|
|
return ptr_to_jlong(mnNameHdl);
|
|
}
|
|
return ptr_to_jlong(GSS_C_NO_NAME);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: exportName
|
|
* Signature: (J)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_exportName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName) {
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl, mNameHdl;
|
|
gss_buffer_desc outBuf;
|
|
jbyteArray jresult;
|
|
|
|
nameHdl = (gss_name_t) jlong_to_ptr(pName);
|
|
|
|
TRACE1("[GSSLibStub_exportName] %ld", (long) pName);
|
|
|
|
/* gss_export_name(...) => GSS_S_NAME_NOT_MN, GSS_S_BAD_NAMETYPE,
|
|
GSS_S_BAD_NAME */
|
|
major = (*ftab->exportName)(&minor, nameHdl, &outBuf);
|
|
|
|
/* canonicalize the internal name to MN and retry */
|
|
if (major == GSS_S_NAME_NOT_MN) {
|
|
/* release intermediate buffers before retrying */
|
|
(*ftab->releaseBuffer)(&minor, &outBuf);
|
|
|
|
TRACE0("[GSSLibStub_exportName] canonicalize and re-try");
|
|
|
|
mNameHdl = (gss_name_t)jlong_to_ptr(
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_canonicalizeName
|
|
(env, jobj, pName));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
major = (*ftab->exportName)(&minor, mNameHdl, &outBuf);
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_releaseName
|
|
(env, jobj, ptr_to_jlong(mNameHdl));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
/* release intermediate buffers */
|
|
(*ftab->releaseBuffer)(&minor, &outBuf);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/* release intermediate buffers before checking status */
|
|
jresult = getJavaBuffer(env, &outBuf);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_exportName]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: displayName
|
|
* Signature: (J)[Ljava/lang/Object;
|
|
*/
|
|
JNIEXPORT jobjectArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_displayName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName) {
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl;
|
|
gss_buffer_desc outNameBuf;
|
|
gss_OID outNameType;
|
|
jstring jname;
|
|
jobject jtype;
|
|
jobjectArray jresult;
|
|
|
|
nameHdl = (gss_name_t) jlong_to_ptr(pName);
|
|
|
|
TRACE1("[GSSLibStub_displayName] %ld", (long) pName);
|
|
|
|
if (nameHdl == GSS_C_NO_NAME) {
|
|
checkStatus(env, jobj, GSS_S_BAD_NAME, 0, "[GSSLibStub_displayName]");
|
|
return NULL;
|
|
}
|
|
|
|
/* gss_display_name(...) => GSS_S_BAD_NAME */
|
|
major = (*ftab->displayName)(&minor, nameHdl, &outNameBuf, &outNameType);
|
|
|
|
/* release intermediate buffers before checking status */
|
|
jname = getJavaString(env, &outNameBuf);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_displayName]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
jtype = getJavaOID(env, outNameType);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
jresult = (*env)->NewObjectArray(env, 2, CLS_Object, NULL);
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
(*env)->SetObjectArrayElement(env, jresult, 0, jname);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
(*env)->SetObjectArrayElement(env, jresult, 1, jtype);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: acquireCred
|
|
* Signature: (JII)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pName,
|
|
jint reqTime,
|
|
jint usage)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_OID mech;
|
|
gss_OID_set mechs;
|
|
gss_cred_usage_t credUsage;
|
|
gss_name_t nameHdl;
|
|
gss_cred_id_t credHdl;
|
|
credHdl = GSS_C_NO_CREDENTIAL;
|
|
|
|
TRACE0("[GSSLibStub_acquireCred]");
|
|
|
|
mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
|
|
mechs = newGSSOIDSet(mech);
|
|
credUsage = (gss_cred_usage_t) usage;
|
|
nameHdl = (gss_name_t) jlong_to_ptr(pName);
|
|
|
|
TRACE2("[GSSLibStub_acquireCred] pName=%ld, usage=%d", (long)pName, usage);
|
|
|
|
/* gss_acquire_cred(...) => GSS_S_BAD_MECH, GSS_S_BAD_NAMETYPE,
|
|
GSS_S_BAD_NAME, GSS_S_CREDENTIALS_EXPIRED, GSS_S_NO_CRED */
|
|
major =
|
|
(*ftab->acquireCred)(&minor, nameHdl, reqTime, mechs,
|
|
credUsage, &credHdl, NULL, NULL);
|
|
/* release intermediate buffers */
|
|
deleteGSSOIDSet(mechs);
|
|
|
|
TRACE1("[GSSLibStub_acquireCred] pCred=%" PRIuPTR "", (uintptr_t) credHdl);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_acquireCred]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
return ptr_to_jlong(credHdl);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: releaseCred
|
|
* Signature: (J)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_releaseCred(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_cred_id_t credHdl;
|
|
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
|
|
TRACE1("[GSSLibStub_releaseCred] %ld", (long int)pCred);
|
|
|
|
if (credHdl != GSS_C_NO_CREDENTIAL) {
|
|
/* gss_release_cred(...) => GSS_S_NO_CRED(!) */
|
|
major = (*ftab->releaseCred)(&minor, &credHdl);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_releaseCred]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
}
|
|
return ptr_to_jlong(credHdl);
|
|
}
|
|
|
|
/*
|
|
* Utility routine for obtaining info about a credential.
|
|
*/
|
|
void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred,
|
|
jint type, void *result) {
|
|
OM_uint32 minor=0, major=0;
|
|
OM_uint32 routineErr;
|
|
gss_cred_id_t credHdl;
|
|
|
|
credHdl = pCred;
|
|
|
|
TRACE1("[gss_inquire_cred] %" PRIuPTR "", (uintptr_t) pCred);
|
|
|
|
/* gss_inquire_cred(...) => GSS_S_DEFECTIVE_CREDENTIAL(!),
|
|
GSS_S_CREDENTIALS_EXPIRED(!), GSS_S_NO_CRED(!) */
|
|
if (type == TYPE_CRED_NAME) {
|
|
major = (*ftab->inquireCred)(&minor, credHdl, result, NULL, NULL, NULL);
|
|
} else if (type == TYPE_CRED_TIME) {
|
|
major = (*ftab->inquireCred)(&minor, credHdl, NULL, result, NULL, NULL);
|
|
} else if (type == TYPE_CRED_USAGE) {
|
|
major = (*ftab->inquireCred)(&minor, credHdl, NULL, NULL, result, NULL);
|
|
}
|
|
|
|
routineErr = GSS_ROUTINE_ERROR(major);
|
|
if (routineErr == GSS_S_CREDENTIALS_EXPIRED) {
|
|
/* ignore GSS_S_CREDENTIALS_EXPIRED for query */
|
|
major = GSS_CALLING_ERROR(major) |
|
|
GSS_SUPPLEMENTARY_INFO(major);
|
|
} else if (routineErr == GSS_S_NO_CRED) {
|
|
/* twik since Java API throws BAD_MECH instead of NO_CRED */
|
|
major = GSS_CALLING_ERROR(major) |
|
|
GSS_S_BAD_MECH | GSS_SUPPLEMENTARY_INFO(major);
|
|
}
|
|
checkStatus(env, jobj, major, minor, "[gss_inquire_cred]");
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getCredName
|
|
* Signature: (J)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred)
|
|
{
|
|
gss_name_t nameHdl;
|
|
gss_cred_id_t credHdl;
|
|
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
|
|
TRACE1("[GSSLibStub_getCredName] %ld", (long int)pCred);
|
|
|
|
nameHdl = GSS_C_NO_NAME;
|
|
inquireCred(env, jobj, credHdl, TYPE_CRED_NAME, &nameHdl);
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
|
|
TRACE1("[GSSLibStub_getCredName] pName=%" PRIuPTR "", (uintptr_t) nameHdl);
|
|
return ptr_to_jlong(nameHdl);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getCredTime
|
|
* Signature: (J)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getCredTime(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred)
|
|
{
|
|
gss_cred_id_t credHdl;
|
|
OM_uint32 lifetime;
|
|
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
|
|
TRACE1("[GSSLibStub_getCredTime] %ld", (long int)pCred);
|
|
|
|
lifetime = 0;
|
|
inquireCred(env, jobj, credHdl, TYPE_CRED_TIME, &lifetime);
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return 0;
|
|
}
|
|
return getJavaTime(lifetime);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getCredUsage
|
|
* Signature: (J)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getCredUsage(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred)
|
|
{
|
|
gss_cred_usage_t usage;
|
|
gss_cred_id_t credHdl;
|
|
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
|
|
TRACE1("[GSSLibStub_getCredUsage] %ld", (long int)pCred);
|
|
|
|
inquireCred(env, jobj, credHdl, TYPE_CRED_USAGE, &usage);
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return -1;
|
|
}
|
|
return (jint) usage;
|
|
}
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: importContext
|
|
* Signature: ([B)Lsun/security/jgss/wrapper/NativeGSSContext;
|
|
*/
|
|
JNIEXPORT jobject JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_importContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jbyteArray jctxtToken)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_buffer_desc ctxtToken;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_OID mech, mech2;
|
|
|
|
TRACE0("[GSSLibStub_importContext]");
|
|
|
|
contextHdl = GSS_C_NO_CONTEXT;
|
|
initGSSBuffer(env, jctxtToken, &ctxtToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* gss_import_sec_context(...) => GSS_S_NO_CONTEXT, GSS_S_DEFECTIVE_TOKEN,
|
|
GSS_S_UNAVAILABLE, GSS_S_UNAUTHORIZED */
|
|
major = (*ftab->importSecContext)(&minor, &ctxtToken, &contextHdl);
|
|
|
|
TRACE1("[GSSLibStub_importContext] pContext=%" PRIuPTR "", (uintptr_t) contextHdl);
|
|
|
|
/* release intermediate buffers */
|
|
resetGSSBuffer(&ctxtToken);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext]");
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* now that the context has been imported, proceed to find out
|
|
its mech */
|
|
major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL,
|
|
NULL, &mech, NULL, NULL, NULL);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_importContext] getMech");
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
mech2 = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj,
|
|
FID_GSSLibStub_pMech));
|
|
|
|
if (sameMech(mech, mech2) == JNI_TRUE) {
|
|
/* mech match - return the context object */
|
|
return (*env)->NewObject(env, CLS_NativeGSSContext,
|
|
MID_NativeGSSContext_ctor,
|
|
ptr_to_jlong(contextHdl), jobj);
|
|
} else {
|
|
/* mech mismatch - clean up then return null */
|
|
major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
|
|
checkStatus(env, jobj, major, minor,
|
|
"[GSSLibStub_importContext] cleanup");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: initContext
|
|
* Signature: (JJLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred,
|
|
jlong pName,
|
|
jobject jcb,
|
|
jbyteArray jinToken,
|
|
jobject jcontextSpi)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_cred_id_t credHdl ;
|
|
gss_ctx_id_t contextHdl, contextHdlSave;
|
|
gss_name_t targetName;
|
|
gss_OID mech;
|
|
OM_uint32 flags, aFlags;
|
|
OM_uint32 time, aTime;
|
|
gss_channel_bindings_t cb;
|
|
gss_buffer_desc inToken;
|
|
gss_buffer_desc outToken;
|
|
jbyteArray jresult;
|
|
/* UNCOMMENT after SEAM bug#6287358 is backported to S10
|
|
gss_OID aMech;
|
|
jobject jMech;
|
|
*/
|
|
|
|
TRACE0("[GSSLibStub_initContext]");
|
|
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
contextHdl = contextHdlSave = (gss_ctx_id_t) jlong_to_ptr(
|
|
(*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
|
|
targetName = (gss_name_t) jlong_to_ptr(pName);
|
|
mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
|
|
flags = (OM_uint32) (*env)->GetIntField(env, jcontextSpi,
|
|
FID_NativeGSSContext_flags);
|
|
time = getGSSTime((*env)->GetIntField(env, jcontextSpi,
|
|
FID_NativeGSSContext_lifetime));
|
|
cb = newGSSCB(env, jcb);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
initGSSBuffer(env, jinToken, &inToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
deleteGSSCB(cb);
|
|
return NULL;
|
|
}
|
|
|
|
TRACE2( "[GSSLibStub_initContext] before: pCred=%" PRIuPTR ", pContext=%" PRIuPTR "",
|
|
(uintptr_t)credHdl, (uintptr_t)contextHdl);
|
|
|
|
/* gss_init_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
|
|
GSS_S_DEFECTIVE_TOKEN, GSS_S_NO_CRED, GSS_S_DEFECTIVE_CREDENTIAL(!),
|
|
GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS, GSS_S_BAD_MIC,
|
|
GSS_S_OLD_TOKEN, GSS_S_DUPLICATE_TOKEN, GSS_S_NO_CONTEXT(!),
|
|
GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME(!), GSS_S_BAD_MECH */
|
|
major = (*ftab->initSecContext)(&minor, credHdl,
|
|
&contextHdl, targetName, mech,
|
|
flags, time, cb, &inToken, NULL /*aMech*/,
|
|
&outToken, &aFlags, &aTime);
|
|
|
|
TRACE2("[GSSLibStub_initContext] after: pContext=%" PRIuPTR ", outToken len=%ld",
|
|
(uintptr_t)contextHdl, (long)outToken.length);
|
|
|
|
// update context handle with the latest value if changed
|
|
// this is to work with both MIT and Solaris. Former deletes half-built
|
|
// context if error occurs
|
|
if (contextHdl != contextHdlSave) {
|
|
(*env)->CallVoidMethod(env, jcontextSpi, MID_NativeGSSContext_setContext,
|
|
ptr_to_jlong(contextHdl));
|
|
TRACE1("[GSSLibStub_initContext] set pContext=%" PRIuPTR "", (uintptr_t)contextHdl);
|
|
}
|
|
|
|
if (GSS_ERROR(major) == GSS_S_COMPLETE) {
|
|
/* update member values if needed */
|
|
(*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
|
|
TRACE1("[GSSLibStub_initContext] set flags=0x%x", aFlags);
|
|
|
|
if (major == GSS_S_COMPLETE) {
|
|
(*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
|
|
getJavaTime(aTime));
|
|
TRACE0("[GSSLibStub_initContext] context established");
|
|
|
|
(*env)->SetBooleanField(env, jcontextSpi,
|
|
FID_NativeGSSContext_isEstablished,
|
|
JNI_TRUE);
|
|
|
|
/* UNCOMMENT after SEAM bug#6287358 is backported to S10
|
|
jMech = getJavaOID(env, aMech);
|
|
(*env)->SetObjectField(env, jcontextSpi,
|
|
FID_NativeGSSContext_actualMech, jMech);
|
|
*/
|
|
} else if (major & GSS_S_CONTINUE_NEEDED) {
|
|
TRACE0("[GSSLibStub_initContext] context not established");
|
|
major -= GSS_S_CONTINUE_NEEDED;
|
|
}
|
|
}
|
|
|
|
/* release intermediate buffers before checking status */
|
|
deleteGSSCB(cb);
|
|
resetGSSBuffer(&inToken);
|
|
jresult = getJavaBuffer(env, &outToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_initContext]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: acceptContext
|
|
* Signature: (JLorg/ietf/jgss/ChannelBinding;[BLsun/security/jgss/wrapper/NativeGSSContext;)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pCred,
|
|
jobject jcb,
|
|
jbyteArray jinToken,
|
|
jobject jcontextSpi)
|
|
{
|
|
OM_uint32 minor, major;
|
|
OM_uint32 minor2, major2;
|
|
gss_ctx_id_t contextHdl, contextHdlSave;
|
|
gss_cred_id_t credHdl;
|
|
gss_buffer_desc inToken;
|
|
gss_channel_bindings_t cb;
|
|
gss_name_t srcName;
|
|
gss_buffer_desc outToken;
|
|
gss_OID aMech;
|
|
OM_uint32 aFlags;
|
|
OM_uint32 aTime;
|
|
gss_cred_id_t delCred;
|
|
jobject jsrcName = NULL;
|
|
jobject jdelCred;
|
|
jobject jMech;
|
|
jboolean setTarget;
|
|
gss_name_t targetName;
|
|
jobject jtargetName;
|
|
|
|
TRACE0("[GSSLibStub_acceptContext]");
|
|
|
|
contextHdl = contextHdlSave = (gss_ctx_id_t)jlong_to_ptr(
|
|
(*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
|
|
credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
|
|
initGSSBuffer(env, jinToken, &inToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
cb = newGSSCB(env, jcb);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
resetGSSBuffer(&inToken);
|
|
return NULL;
|
|
}
|
|
srcName = targetName = GSS_C_NO_NAME;
|
|
delCred = GSS_C_NO_CREDENTIAL;
|
|
setTarget = (credHdl == GSS_C_NO_CREDENTIAL);
|
|
aFlags = 0;
|
|
|
|
TRACE2( "[GSSLibStub_acceptContext] before: pCred=%" PRIuPTR ", pContext=%" PRIuPTR "",
|
|
(uintptr_t) credHdl, (uintptr_t) contextHdl);
|
|
|
|
/* gss_accept_sec_context(...) => GSS_S_CONTINUE_NEEDED(!),
|
|
GSS_S_DEFECTIVE_TOKEN, GSS_S_DEFECTIVE_CREDENTIAL(!),
|
|
GSS_S_NO_CRED, GSS_S_CREDENTIALS_EXPIRED, GSS_S_BAD_BINDINGS,
|
|
GSS_S_NO_CONTEXT(!), GSS_S_BAD_MIC, GSS_S_OLD_TOKEN,
|
|
GSS_S_DUPLICATE_TOKEN, GSS_S_BAD_MECH */
|
|
major =
|
|
(*ftab->acceptSecContext)(&minor, &contextHdl, credHdl,
|
|
&inToken, cb, &srcName, &aMech, &outToken,
|
|
&aFlags, &aTime, &delCred);
|
|
/* release intermediate buffers before checking status */
|
|
|
|
deleteGSSCB(cb);
|
|
resetGSSBuffer(&inToken);
|
|
|
|
TRACE3("[GSSLibStub_acceptContext] after: pCred=%" PRIuPTR ", pContext=%" PRIuPTR ", pDelegCred=%" PRIuPTR "",
|
|
(uintptr_t)credHdl, (uintptr_t)contextHdl, (uintptr_t) delCred);
|
|
|
|
// update context handle with the latest value if changed
|
|
// this is to work with both MIT and Solaris. Former deletes half-built
|
|
// context if error occurs
|
|
if (contextHdl != contextHdlSave) {
|
|
(*env)->CallVoidMethod(env, jcontextSpi, MID_NativeGSSContext_setContext,
|
|
ptr_to_jlong(contextHdl));
|
|
TRACE1("[GSSLibStub_acceptContext] set pContext=%" PRIuPTR "", (uintptr_t)contextHdl);
|
|
}
|
|
|
|
if (GSS_ERROR(major) == GSS_S_COMPLETE) {
|
|
/* update member values if needed */
|
|
// WORKAROUND for a Heimdal bug
|
|
if (delCred == GSS_C_NO_CREDENTIAL) {
|
|
aFlags &= 0xfffffffe;
|
|
}
|
|
(*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
|
|
TRACE1("[GSSLibStub_acceptContext] set flags=0x%x", aFlags);
|
|
|
|
if (setTarget) {
|
|
major2 = (*ftab->inquireContext)(&minor2, contextHdl, NULL,
|
|
&targetName, NULL, NULL, NULL,
|
|
NULL, NULL);
|
|
checkStatus(env, jobj, major2, minor2,
|
|
"[GSSLibStub_acceptContext] inquire");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
|
|
jtargetName = (*env)->NewObject(env, CLS_GSSNameElement,
|
|
MID_GSSNameElement_ctor,
|
|
ptr_to_jlong(targetName), jobj);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
|
|
TRACE1("[GSSLibStub_acceptContext] set targetName=%" PRIuPTR "",
|
|
(uintptr_t)targetName);
|
|
|
|
(*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_targetName,
|
|
jtargetName);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
}
|
|
if (srcName != GSS_C_NO_NAME) {
|
|
jsrcName = (*env)->NewObject(env, CLS_GSSNameElement,
|
|
MID_GSSNameElement_ctor,
|
|
ptr_to_jlong(srcName), jobj);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
|
|
TRACE1("[GSSLibStub_acceptContext] set srcName=%" PRIuPTR "", (uintptr_t)srcName);
|
|
|
|
(*env)->SetObjectField(env, jcontextSpi, FID_NativeGSSContext_srcName,
|
|
jsrcName);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
}
|
|
if (major == GSS_S_COMPLETE) {
|
|
TRACE0("[GSSLibStub_acceptContext] context established");
|
|
|
|
(*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
|
|
getJavaTime(aTime));
|
|
(*env)->SetBooleanField(env, jcontextSpi,
|
|
FID_NativeGSSContext_isEstablished,
|
|
JNI_TRUE);
|
|
jMech = getJavaOID(env, aMech);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
(*env)->SetObjectField(env, jcontextSpi,
|
|
FID_NativeGSSContext_actualMech, jMech);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
if (delCred != GSS_C_NO_CREDENTIAL) {
|
|
jdelCred = (*env)->NewObject(env, CLS_GSSCredElement,
|
|
MID_GSSCredElement_ctor,
|
|
ptr_to_jlong(delCred), jsrcName, jMech);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
(*env)->SetObjectField(env, jcontextSpi,
|
|
FID_NativeGSSContext_delegatedCred,
|
|
jdelCred);
|
|
TRACE1("[GSSLibStub_acceptContext] set delegatedCred=%" PRIuPTR "",
|
|
(uintptr_t) delCred);
|
|
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
goto error;
|
|
}
|
|
}
|
|
} else if (major & GSS_S_CONTINUE_NEEDED) {
|
|
TRACE0("[GSSLibStub_acceptContext] context not established");
|
|
|
|
if (aFlags & GSS_C_PROT_READY_FLAG) {
|
|
(*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime,
|
|
getJavaTime(aTime));
|
|
}
|
|
major -= GSS_S_CONTINUE_NEEDED;
|
|
}
|
|
}
|
|
return getJavaBuffer(env, &outToken);
|
|
|
|
error:
|
|
(*ftab->releaseBuffer)(&minor, &outToken);
|
|
if (srcName != GSS_C_NO_NAME) {
|
|
(*ftab->releaseName)(&minor, &srcName);
|
|
}
|
|
if (targetName != GSS_C_NO_NAME) {
|
|
(*ftab->releaseName)(&minor, &targetName);
|
|
}
|
|
if (delCred != GSS_C_NO_CREDENTIAL) {
|
|
(*ftab->releaseCred) (&minor, &delCred);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: inquireContext
|
|
* Signature: (J)[J
|
|
*/
|
|
JNIEXPORT jlongArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_inquireContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_name_t srcName, targetName;
|
|
OM_uint32 time;
|
|
OM_uint32 flags;
|
|
int isInitiator, isEstablished;
|
|
#if defined (_WIN32) && defined (_MSC_VER)
|
|
_Alignas(8)
|
|
#endif
|
|
jlong result[6];
|
|
jlongArray jresult;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_inquireContext] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
srcName = targetName = GSS_C_NO_NAME;
|
|
time = 0;
|
|
flags = isInitiator = isEstablished = 0;
|
|
|
|
/* gss_inquire_context(...) => GSS_S_NO_CONTEXT(!) */
|
|
major = (*ftab->inquireContext)(&minor, contextHdl, &srcName,
|
|
&targetName, &time, NULL, &flags,
|
|
&isInitiator, &isEstablished);
|
|
/* update member values if needed */
|
|
TRACE2("[GSSLibStub_inquireContext] srcName %" PRIuPTR ", targetName %" PRIuPTR "",
|
|
(uintptr_t)srcName, (uintptr_t)targetName);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContext]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
result[0] = ptr_to_jlong(srcName);
|
|
result[1] = ptr_to_jlong(targetName);
|
|
result[2] = (jlong) isInitiator;
|
|
result[3] = (jlong) isEstablished;
|
|
result[4] = (jlong) flags;
|
|
result[5] = (jlong) getJavaTime(time);
|
|
|
|
jresult = (*env)->NewLongArray(env, 6);
|
|
if (jresult == NULL) {
|
|
return NULL;
|
|
}
|
|
(*env)->SetLongArrayRegion(env, jresult, 0, 6, result);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getContextMech
|
|
* Signature: (J)Lorg/ietf/jgss/Oid;
|
|
*/
|
|
JNIEXPORT jobject JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getContextMech(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_OID mech;
|
|
gss_ctx_id_t contextHdl;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_getContextMech] %ld", (long int)pContext);
|
|
|
|
major = (*ftab->inquireContext)(&minor, contextHdl, NULL, NULL,
|
|
NULL, &mech, NULL, NULL, NULL);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextMech]");
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
return getJavaOID(env, mech);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getContextName
|
|
* Signature: (JZ)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv *env,
|
|
jobject jobj, jlong pContext, jboolean isSrc)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_name_t nameHdl;
|
|
gss_ctx_id_t contextHdl;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE2("[GSSLibStub_getContextName] %" PRIuPTR ", isSrc=%d",
|
|
(uintptr_t)contextHdl, isSrc);
|
|
|
|
nameHdl = GSS_C_NO_NAME;
|
|
if (isSrc == JNI_TRUE) {
|
|
major = (*ftab->inquireContext)(&minor, contextHdl, &nameHdl, NULL,
|
|
NULL, NULL, NULL, NULL, NULL);
|
|
} else {
|
|
major = (*ftab->inquireContext)(&minor, contextHdl, NULL, &nameHdl,
|
|
NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContextAll]");
|
|
/* return immediately if an exception has occurred */
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
|
|
TRACE1("[GSSLibStub_getContextName] pName=%" PRIuPTR "", (uintptr_t) nameHdl);
|
|
|
|
return ptr_to_jlong(nameHdl);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getContextTime
|
|
* Signature: (J)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getContextTime(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext) {
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
OM_uint32 time;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_getContextTime] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) return 0;
|
|
|
|
/* gss_context_time(...) => GSS_S_CONTEXT_EXPIRED(!),
|
|
GSS_S_NO_CONTEXT(!) */
|
|
major = (*ftab->contextTime)(&minor, contextHdl, &time);
|
|
if (GSS_ROUTINE_ERROR(major) == GSS_S_CONTEXT_EXPIRED) {
|
|
major = GSS_CALLING_ERROR(major) | GSS_SUPPLEMENTARY_INFO(major);
|
|
}
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_getContextTime]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return 0;
|
|
}
|
|
return getJavaTime(time);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: deleteContext
|
|
* Signature: (J)J
|
|
*/
|
|
JNIEXPORT jlong JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_deleteContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_deleteContext] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) return ptr_to_jlong(GSS_C_NO_CONTEXT);
|
|
|
|
/* gss_delete_sec_context(...) => GSS_S_NO_CONTEXT(!) */
|
|
major = (*ftab->deleteSecContext)(&minor, &contextHdl, GSS_C_NO_BUFFER);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_deleteContext]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return jlong_zero;
|
|
}
|
|
return (jlong) ptr_to_jlong(contextHdl);
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: wrapSizeLimit
|
|
* Signature: (JIII)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_wrapSizeLimit(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext,
|
|
jint reqFlag,
|
|
jint jqop,
|
|
jint joutSize)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
OM_uint32 outSize, maxInSize;
|
|
gss_qop_t qop;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_wrapSizeLimit] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0,
|
|
"[GSSLibStub_wrapSizeLimit]");
|
|
return 0;
|
|
}
|
|
|
|
qop = (gss_qop_t) jqop;
|
|
outSize = (OM_uint32) joutSize;
|
|
/* gss_wrap_size_limit(...) => GSS_S_NO_CONTEXT(!), GSS_S_CONTEXT_EXPIRED,
|
|
GSS_S_BAD_QOP */
|
|
major = (*ftab->wrapSizeLimit)(&minor, contextHdl, reqFlag,
|
|
qop, outSize, &maxInSize);
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_wrapSizeLimit]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return 0;
|
|
}
|
|
return (jint) maxInSize;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: exportContext
|
|
* Signature: (J)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_exportContext(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_buffer_desc interProcToken;
|
|
jbyteArray jresult;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_exportContext] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_NO_CONTEXT, 0, "[GSSLibStub_exportContext]");
|
|
return NULL;
|
|
}
|
|
/* gss_export_sec_context(...) => GSS_S_CONTEXT_EXPIRED,
|
|
GSS_S_NO_CONTEXT, GSS_S_UNAVAILABLE */
|
|
major =
|
|
(*ftab->exportSecContext)(&minor, &contextHdl, &interProcToken);
|
|
|
|
/* release intermediate buffers */
|
|
jresult = getJavaBuffer(env, &interProcToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_exportContext]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: getMic
|
|
* Signature: (JI[B)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_getMic(JNIEnv *env, jobject jobj,
|
|
jlong pContext, jint jqop,
|
|
jbyteArray jmsg)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_qop_t qop;
|
|
gss_buffer_desc msg;
|
|
gss_buffer_desc msgToken;
|
|
jbyteArray jresult;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_getMic] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]");
|
|
return NULL;
|
|
}
|
|
qop = (gss_qop_t) jqop;
|
|
initGSSBuffer(env, jmsg, &msg);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* gss_get_mic(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
|
|
GSS_S_BAD_QOP */
|
|
major =
|
|
(*ftab->getMic)(&minor, contextHdl, qop, &msg, &msgToken);
|
|
|
|
/* release intermediate buffers */
|
|
resetGSSBuffer(&msg);
|
|
jresult = getJavaBuffer(env, &msgToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_getMic]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: verifyMic
|
|
* Signature: (J[B[BLorg/ietf/jgss/MessageProp;)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_verifyMic(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext,
|
|
jbyteArray jmsgToken,
|
|
jbyteArray jmsg,
|
|
jobject jprop)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_buffer_desc msg;
|
|
gss_buffer_desc msgToken;
|
|
gss_qop_t qop;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_verifyMic] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0,
|
|
"[GSSLibStub_verifyMic]");
|
|
return;
|
|
}
|
|
|
|
qop = (gss_qop_t) (*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
|
|
if ((*env)->ExceptionCheck(env)) { return; }
|
|
|
|
initGSSBuffer(env, jmsg, &msg);
|
|
if ((*env)->ExceptionCheck(env)) { return; }
|
|
|
|
initGSSBuffer(env, jmsgToken, &msgToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
resetGSSBuffer(&msg);
|
|
return;
|
|
}
|
|
|
|
/* gss_verify_mic(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
|
|
GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
|
|
GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
|
|
major =
|
|
(*ftab->verifyMic)(&minor, contextHdl, &msg, &msgToken, &qop);
|
|
|
|
/* release intermediate buffers */
|
|
resetGSSBuffer(&msg);
|
|
resetGSSBuffer(&msgToken);
|
|
|
|
checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_verifyMic]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return;
|
|
}
|
|
|
|
(*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return;
|
|
}
|
|
|
|
setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
|
|
minor);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: wrap
|
|
* Signature: (J[BLorg/ietf/jgss/MessageProp;)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_wrap(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext,
|
|
jbyteArray jmsg,
|
|
jobject jprop)
|
|
{
|
|
OM_uint32 minor, major;
|
|
jboolean confFlag;
|
|
gss_qop_t qop;
|
|
gss_buffer_desc msg;
|
|
gss_buffer_desc msgToken;
|
|
int confState;
|
|
gss_ctx_id_t contextHdl;
|
|
jbyteArray jresult;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_wrap] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_wrap]");
|
|
return NULL;
|
|
}
|
|
|
|
confFlag =
|
|
(*env)->CallBooleanMethod(env, jprop, MID_MessageProp_getPrivacy);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
qop = (gss_qop_t)
|
|
(*env)->CallIntMethod(env, jprop, MID_MessageProp_getQOP);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
initGSSBuffer(env, jmsg, &msg);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* gss_wrap(...) => GSS_S_CONTEXT_EXPIRED, GSS_S_NO_CONTEXT(!),
|
|
GSS_S_BAD_QOP */
|
|
major = (*ftab->wrap)(&minor, contextHdl, confFlag, qop, &msg, &confState,
|
|
&msgToken);
|
|
|
|
/* release intermediate buffers */
|
|
resetGSSBuffer(&msg);
|
|
jresult = getJavaBuffer(env, &msgToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, major, minor, "[GSSLibStub_wrap]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
(*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
|
|
(confState? JNI_TRUE:JNI_FALSE));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
return jresult;
|
|
}
|
|
|
|
/*
|
|
* Class: sun_security_jgss_wrapper_GSSLibStub
|
|
* Method: unwrap
|
|
* Signature: (J[BLorg/ietf/jgss/MessageProp;)[B
|
|
*/
|
|
JNIEXPORT jbyteArray JNICALL
|
|
Java_sun_security_jgss_wrapper_GSSLibStub_unwrap(JNIEnv *env,
|
|
jobject jobj,
|
|
jlong pContext,
|
|
jbyteArray jmsgToken,
|
|
jobject jprop)
|
|
{
|
|
OM_uint32 minor, major;
|
|
gss_ctx_id_t contextHdl;
|
|
gss_buffer_desc msgToken;
|
|
gss_buffer_desc msg;
|
|
int confState;
|
|
gss_qop_t qop;
|
|
jbyteArray jresult;
|
|
|
|
contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
|
|
|
|
TRACE1("[GSSLibStub_unwrap] %" PRIuPTR "", (uintptr_t)contextHdl);
|
|
|
|
if (contextHdl == GSS_C_NO_CONTEXT) {
|
|
// Twik per javadoc
|
|
checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_unwrap]");
|
|
return NULL;
|
|
}
|
|
|
|
initGSSBuffer(env, jmsgToken, &msgToken);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
confState = 0;
|
|
qop = GSS_C_QOP_DEFAULT;
|
|
/* gss_unwrap(...) => GSS_S_DEFECTIVE_TOKEN, GSS_S_BAD_MIC,
|
|
GSS_S_CONTEXT_EXPIRED, GSS_S_DUPLICATE_TOKEN(!), GSS_S_OLD_TOKEN(!),
|
|
GSS_S_UNSEQ_TOKEN(!), GSS_S_GAP_TOKEN(!), GSS_S_NO_CONTEXT(!) */
|
|
major =
|
|
(*ftab->unwrap)(&minor, contextHdl, &msgToken, &msg, &confState, &qop);
|
|
|
|
/* release intermediate buffers */
|
|
resetGSSBuffer(&msgToken);
|
|
jresult = getJavaBuffer(env, &msg);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
checkStatus(env, jobj, GSS_ERROR(major), minor, "[GSSLibStub_unwrap]");
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
/* update the message prop with relevant info */
|
|
(*env)->CallVoidMethod(env, jprop, MID_MessageProp_setPrivacy,
|
|
(confState != 0));
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
(*env)->CallVoidMethod(env, jprop, MID_MessageProp_setQOP, qop);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
setSupplementaryInfo(env, jobj, jprop, GSS_SUPPLEMENTARY_INFO(major),
|
|
minor);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
return NULL;
|
|
}
|
|
|
|
return jresult;
|
|
}
|