/*
 * 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 "NativeUtil.h"
#include "NativeFunc.h"
#include "jlong.h"
#include <jni.h>
#include "jni_util.h"

const int JAVA_DUPLICATE_TOKEN_CODE = 19; /* DUPLICATE_TOKEN */
const int JAVA_OLD_TOKEN_CODE = 20; /* OLD_TOKEN */
const int JAVA_UNSEQ_TOKEN_CODE = 21; /* UNSEQ_TOKEN */
const int JAVA_GAP_TOKEN_CODE = 22; /* GAP_TOKEN */
const int JAVA_ERROR_CODE[] = {
  2,  /* BAD_MECH */
  3,  /* BAD_NAME */
  4,  /* BAD_NAMETYPE */
  1,  /* BAD_BINDINGS */
  5,  /* BAD_STATUS */
  6,  /* BAD_MIC */
  13, /* NO_CRED */
  12, /* NO_CONTEXT */
  10, /* DEFECTIVE_TOKEN */
  9,  /* DEFECTIVE_CREDENTIAL */
  8,  /* CREDENTIAL_EXPIRED */
  7,  /* CONTEXT_EXPIRED */
  11, /* FAILURE */
  14, /* BAD_QOP */
  15, /* UNAUTHORIZED */
  16, /* UNAVAILABLE */
  17, /* DUPLICATE_ELEMENT */
  18, /* NAME_NOT_MN */
};
const char SPNEGO_BYTES[] = {
 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02
};

jclass CLS_Object;
jclass CLS_String;
jclass CLS_Oid;
jclass CLS_GSSException;
jclass CLS_GSSNameElement;
jclass CLS_GSSCredElement;
jclass CLS_NativeGSSContext;
jclass CLS_SunNativeProvider;
jmethodID MID_String_ctor;
jmethodID MID_Oid_ctor1;
jmethodID MID_Oid_getDER;
jmethodID MID_MessageProp_getPrivacy;
jmethodID MID_MessageProp_getQOP;
jmethodID MID_MessageProp_setPrivacy;
jmethodID MID_MessageProp_setQOP;
jmethodID MID_MessageProp_setSupplementaryStates;
jmethodID MID_GSSException_ctor3;
jmethodID MID_ChannelBinding_getInitiatorAddr;
jmethodID MID_ChannelBinding_getAcceptorAddr;
jmethodID MID_ChannelBinding_getAppData;
jmethodID MID_InetAddress_getAddr;
jmethodID MID_GSSNameElement_ctor;
jmethodID MID_GSSCredElement_ctor;
jmethodID MID_NativeGSSContext_ctor;
jmethodID MID_NativeGSSContext_setContext;
jfieldID FID_GSSLibStub_pMech;
jfieldID FID_NativeGSSContext_pContext;
jfieldID FID_NativeGSSContext_srcName;
jfieldID FID_NativeGSSContext_targetName;
jfieldID FID_NativeGSSContext_isInitiator;
jfieldID FID_NativeGSSContext_isEstablished;
jfieldID FID_NativeGSSContext_delegatedCred;
jfieldID FID_NativeGSSContext_flags;
jfieldID FID_NativeGSSContext_lifetime;
jfieldID FID_NativeGSSContext_actualMech;

int JGSS_DEBUG;

JNIEXPORT jint JNICALL
DEF_JNI_OnLoad(JavaVM *jvm, void *reserved) {
  JNIEnv *env;
  jclass cls;

  if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
    return JNI_EVERSION; /* JNI version not supported */
  }
  /* Retrieve and store the classes in global ref */
  cls = (*env)->FindClass(env, "java/lang/Object");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find Object class\n");
    return JNI_ERR;
  }
  CLS_Object = (*env)->NewGlobalRef(env, cls);
  if (CLS_Object == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "java/lang/String");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find String class\n");
    return JNI_ERR;
  }
  CLS_String = (*env)->NewGlobalRef(env, cls);
  if (CLS_String == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "org/ietf/jgss/Oid");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find org.ietf.jgss.Oid class\n");
    return JNI_ERR;
  }
  CLS_Oid = (*env)->NewGlobalRef(env, cls);
  if (CLS_Oid == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "org/ietf/jgss/GSSException");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find org.ietf.jgss.GSSException class\n");
    return JNI_ERR;
  }
  CLS_GSSException = (*env)->NewGlobalRef(env, cls);
  if (CLS_GSSException == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/GSSNameElement");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find sun.security.jgss.wrapper.GSSNameElement class\n");
    return JNI_ERR;
  }
  CLS_GSSNameElement = (*env)->NewGlobalRef(env, cls);
  if (CLS_GSSNameElement == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/GSSCredElement");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find sun.security.jgss.wrapper.GSSCredElement class\n");
    return JNI_ERR;
  }
  CLS_GSSCredElement = (*env)->NewGlobalRef(env, cls);
  if (CLS_GSSCredElement == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/NativeGSSContext");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find sun.security.jgss.wrapper.NativeGSSContext class\n");
    return JNI_ERR;
  }
  CLS_NativeGSSContext = (*env)->NewGlobalRef(env, cls);
  if (CLS_NativeGSSContext == NULL) {
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/SunNativeProvider");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find sun.security.jgss.wrapper.SunNativeProvider class\n");
    return JNI_ERR;
  }
  CLS_SunNativeProvider = (*env)->NewGlobalRef(env, cls);
  if (CLS_SunNativeProvider == NULL) {
    return JNI_ERR;
  }
  /* Compute and cache the method ID */
  MID_String_ctor = (*env)->GetMethodID(env, CLS_String,
                                        "<init>", "([B)V");
  if (MID_String_ctor == NULL) {
    fprintf(stderr, "Couldn't find String(byte[]) constructor\n");
    return JNI_ERR;
  }
  MID_Oid_ctor1 =
    (*env)->GetMethodID(env, CLS_Oid, "<init>", "([B)V");
  if (MID_Oid_ctor1 == NULL) {
    fprintf(stderr, "Couldn't find Oid(byte[]) constructor\n");
    return JNI_ERR;
  }
  MID_Oid_getDER = (*env)->GetMethodID(env, CLS_Oid, "getDER", "()[B");
  if (MID_Oid_getDER == NULL) {
    fprintf(stderr, "Couldn't find Oid.getDER() method\n");
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "org/ietf/jgss/MessageProp");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find org.ietf.jgss.MessageProp class\n");
    return JNI_ERR;
  }
  MID_MessageProp_getPrivacy =
    (*env)->GetMethodID(env, cls, "getPrivacy", "()Z");
  if (MID_MessageProp_getPrivacy == NULL) {
    fprintf(stderr, "Couldn't find MessageProp.getPrivacy() method\n");
    return JNI_ERR;
  }
  MID_MessageProp_getQOP = (*env)->GetMethodID(env, cls, "getQOP", "()I");
  if (MID_MessageProp_getQOP == NULL) {
    fprintf(stderr, "Couldn't find MessageProp.getQOP() method\n");
    return JNI_ERR;
  }
  MID_MessageProp_setPrivacy =
    (*env)->GetMethodID(env, cls, "setPrivacy", "(Z)V");
  if (MID_MessageProp_setPrivacy == NULL) {
    fprintf(stderr, "Couldn't find MessageProp.setPrivacy(boolean) method\n");
    return JNI_ERR;
  }
  MID_MessageProp_setQOP = (*env)->GetMethodID(env, cls, "setQOP", "(I)V");
  if (MID_MessageProp_setQOP == NULL) {
    fprintf(stderr, "Couldn't find MessageProp.setQOP(int) method\n");
    return JNI_ERR;
  }
  MID_MessageProp_setSupplementaryStates =
    (*env)->GetMethodID(env, cls, "setSupplementaryStates",
                        "(ZZZZILjava/lang/String;)V");
  if (MID_MessageProp_setSupplementaryStates == NULL) {
    fprintf(stderr, "Couldn't find MessageProp.setSupplementaryStates(...) method\n");
    return JNI_ERR;
  }
  MID_GSSException_ctor3 = (*env)->GetMethodID
    (env, CLS_GSSException, "<init>", "(IILjava/lang/String;)V");
  if (MID_GSSException_ctor3 == NULL) {
    fprintf(stderr, "Couldn't find GSSException(int, int, String) constructor\n");
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "org/ietf/jgss/ChannelBinding");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find org.ietf.jgss.ChannelBinding class\n");
    return JNI_ERR;
  }
  MID_ChannelBinding_getInitiatorAddr =
    (*env)->GetMethodID(env, cls, "getInitiatorAddress",
                        "()Ljava/net/InetAddress;");
  if (MID_ChannelBinding_getInitiatorAddr == NULL) {
    fprintf(stderr, "Couldn't find ChannelBinding.getInitiatorAddress() method\n");
    return JNI_ERR;
  }
  MID_ChannelBinding_getAcceptorAddr =
    (*env)->GetMethodID(env, cls, "getAcceptorAddress",
                        "()Ljava/net/InetAddress;");
  if (MID_ChannelBinding_getAcceptorAddr == NULL) {
    fprintf(stderr, "Couldn't find ChannelBinding.getAcceptorAddress() method\n");
    return JNI_ERR;
  }
  MID_ChannelBinding_getAppData =
    (*env)->GetMethodID(env, cls, "getApplicationData", "()[B");
  if (MID_ChannelBinding_getAppData == NULL) {
    fprintf(stderr, "Couldn't find ChannelBinding.getApplicationData() method\n");
    return JNI_ERR;
  }
  cls = (*env)->FindClass(env, "java/net/InetAddress");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find java.net.InetAddress class\n");
    return JNI_ERR;
  }
  MID_InetAddress_getAddr = (*env)->GetMethodID(env, cls, "getAddress",
                                                "()[B");
  if (MID_InetAddress_getAddr == NULL) {
    fprintf(stderr, "Couldn't find InetAddress.getAddress() method\n");
    return JNI_ERR;
  }
  MID_GSSNameElement_ctor =
    (*env)->GetMethodID(env, CLS_GSSNameElement,
                        "<init>", "(JLsun/security/jgss/wrapper/GSSLibStub;)V");
  if (MID_GSSNameElement_ctor == NULL) {
    fprintf(stderr, "Couldn't find GSSNameElement(long, GSSLibStub) constructor\n");
    return JNI_ERR;
  }
  MID_GSSCredElement_ctor =
    (*env)->GetMethodID(env, CLS_GSSCredElement, "<init>",
        "(JLsun/security/jgss/wrapper/GSSNameElement;Lorg/ietf/jgss/Oid;)V");
  if (MID_GSSCredElement_ctor == NULL) {
    fprintf(stderr, "Couldn't find GSSCredElement(long, GSSLibStub) constructor\n");
    return JNI_ERR;
  }
  MID_NativeGSSContext_ctor =
    (*env)->GetMethodID(env, CLS_NativeGSSContext, "<init>",
                        "(JLsun/security/jgss/wrapper/GSSLibStub;)V");
  if (MID_NativeGSSContext_ctor == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext(long, GSSLibStub) constructor\n");
    return JNI_ERR;
  }

  MID_NativeGSSContext_setContext =
    (*env)->GetMethodID(env, CLS_NativeGSSContext, "setContext",
                        "(J)V");
  if (MID_NativeGSSContext_setContext == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.setContext(long) method\n");
    return JNI_ERR;
  }

  /* Compute and cache the field ID */
  cls = (*env)->FindClass(env, "sun/security/jgss/wrapper/GSSLibStub");
  if (cls == NULL) {
    fprintf(stderr, "Couldn't find sun.security.jgss.wrapper.GSSLibStub class\n");
    return JNI_ERR;
  }
  FID_GSSLibStub_pMech =
    (*env)->GetFieldID(env, cls, "pMech", "J");
  if (FID_GSSLibStub_pMech == NULL) {
    fprintf(stderr, "Couldn't find GSSLibStub.pMech field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_pContext =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "pContext", "J");
  if (FID_NativeGSSContext_pContext == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.pContext field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_srcName =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "srcName",
                       "Lsun/security/jgss/wrapper/GSSNameElement;");
  if (FID_NativeGSSContext_srcName == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.srcName field\n");
   return JNI_ERR;
  }
  FID_NativeGSSContext_targetName =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "targetName",
                       "Lsun/security/jgss/wrapper/GSSNameElement;");
  if (FID_NativeGSSContext_targetName == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.targetName field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_isInitiator =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "isInitiator", "Z");
  if (FID_NativeGSSContext_isInitiator == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.isInitiator field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_isEstablished =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "isEstablished", "Z");
  if (FID_NativeGSSContext_isEstablished == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.isEstablished field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_delegatedCred =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "delegatedCred",
                       "Lsun/security/jgss/wrapper/GSSCredElement;");
  if (FID_NativeGSSContext_delegatedCred == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.delegatedCred field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_flags =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "flags", "I");
  if (FID_NativeGSSContext_flags == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.flags field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_lifetime =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "lifetime", "I");
  if (FID_NativeGSSContext_lifetime == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.lifetime field\n");
    return JNI_ERR;
  }
  FID_NativeGSSContext_actualMech =
    (*env)->GetFieldID(env, CLS_NativeGSSContext, "actualMech",
                       "Lorg/ietf/jgss/Oid;");
  if (FID_NativeGSSContext_actualMech == NULL) {
    fprintf(stderr, "Couldn't find NativeGSSContext.actualMech field\n");
    return JNI_ERR;
  }
  return JNI_VERSION_1_2;
}

JNIEXPORT void JNICALL
DEF_JNI_OnUnload(JavaVM *jvm, void *reserved) {
  JNIEnv *env;

  if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
    return;
  }
  /* Delete the global refs */
  (*env)->DeleteGlobalRef(env, CLS_Object);
  (*env)->DeleteGlobalRef(env, CLS_String);
  (*env)->DeleteGlobalRef(env, CLS_Oid);
  (*env)->DeleteGlobalRef(env, CLS_GSSException);
  (*env)->DeleteGlobalRef(env, CLS_GSSNameElement);
  (*env)->DeleteGlobalRef(env, CLS_GSSCredElement);
  (*env)->DeleteGlobalRef(env, CLS_SunNativeProvider);
  return;
}

const OM_uint32 JAVA_MAX = GSS_C_INDEFINITE/2;

/*
 * Utility routine for converting the C unsigned integer time
 * to Java signed integer time.
 */
jint getJavaTime(OM_uint32 ctime) {
  jint result;

  /* special handle values equals or more than JAVA_MAX */
  if (ctime == GSS_C_INDEFINITE) {
    result = JAVA_MAX;
  } else if (ctime >= JAVA_MAX) {
    result = JAVA_MAX-1;
  } else {
    result = ctime;
  }
  return result;
}
/*
 * Utility routine for converting the Java signed integer time
 * to C unsigned integer time.
 */
OM_uint32 getGSSTime(jint jtime) {
  OM_uint32 result;

  /* special handle values equal to JAVA_MAX */
  if (jtime == (jint)JAVA_MAX) {
    result = GSS_C_INDEFINITE;
  } else {
    result = jtime;
  }
  return result;
}
/*
 * Utility routine for mapping the C error code to the
 * Java one. The routine errors really should have
 * shared the same values but unfortunately don't.
 */
jint getJavaErrorCode(int cNonCallingErr) {
  int cRoutineErr, cSuppStatus;
  /* map the routine errors */
  cRoutineErr = GSS_ROUTINE_ERROR(cNonCallingErr) >> 16;
  if (cRoutineErr != GSS_S_COMPLETE) {
    return JAVA_ERROR_CODE[cRoutineErr-1];
  }
  /* map the supplementary infos */
  cSuppStatus = GSS_SUPPLEMENTARY_INFO(cNonCallingErr);
  if (cSuppStatus & GSS_S_DUPLICATE_TOKEN) {
    return JAVA_DUPLICATE_TOKEN_CODE;
  } else if (cSuppStatus & GSS_S_OLD_TOKEN) {
    return JAVA_OLD_TOKEN_CODE;
  } else if (cSuppStatus & GSS_S_UNSEQ_TOKEN) {
    return JAVA_UNSEQ_TOKEN_CODE;
  } else if (cSuppStatus & GSS_S_GAP_TOKEN) {
    return JAVA_GAP_TOKEN_CODE;
  }
  return GSS_S_COMPLETE;
}

void gssThrowOutOfMemoryError(JNIEnv *env, const char *message) {
    jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");

    if (cls != NULL) {
        (*env)->ThrowNew(env, cls, message);
    }
}

/*
 * Utility routine for creating a java.lang.String object
 * using the specified gss_buffer_t structure. The specified
 * gss_buffer_t structure is always released.
 */
jstring getJavaString(JNIEnv *env, gss_buffer_t bytes) {
  jstring result = NULL;
  OM_uint32 minor;
  int len;
  jbyteArray jbytes;

  if (bytes != NULL) {
    /* constructs the String object with new String(byte[])
       NOTE: do NOT include the trailing NULL */
    len = (int) bytes->length;
    jbytes = (*env)->NewByteArray(env, len);
    if (jbytes == NULL) {
      goto finish;
    }

    (*env)->SetByteArrayRegion(env, jbytes, 0, len, (jbyte *) bytes->value);
    if ((*env)->ExceptionCheck(env)) {
      goto finish;
    }

    result = (*env)->NewObject(env, CLS_String, MID_String_ctor,
                               jbytes);
  finish:
    (*env)->DeleteLocalRef(env, jbytes);
    (*ftab->releaseBuffer)(&minor, bytes);
    return result;
  } /* else fall through */
  return NULL;
}
/*
 * Utility routine for generate message for the specified minor
 * status code.
 */
jstring getMinorMessage(JNIEnv *env, jobject jstub, OM_uint32 statusValue) {
  OM_uint32 messageContext, minor, major;
  gss_buffer_desc statusString;
  gss_OID mech;

  messageContext = 0;
  if (jstub != NULL) {
    mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jstub, FID_GSSLibStub_pMech));
  } else {
    mech = GSS_C_NO_OID;
  }

  /* gss_display_status(...) => GSS_S_BAD_MECH, GSS_S_BAD_STATUS */
  // TBD: check messageContext value and repeat the call if necessary
  major = (*ftab->displayStatus)(&minor, statusValue, GSS_C_MECH_CODE, mech,
                                 &messageContext, &statusString);

  return getJavaString(env, &statusString);
}

/*
 * Utility routine checking the specified major and minor
 * status codes. GSSExceptions will be thrown if they are
 * not GSS_S_COMPLETE (i.e. 0).
 */
void checkStatus(JNIEnv *env, jobject jstub, OM_uint32 major,
                 OM_uint32 minor, char* methodName) {
  int callingErr, routineErr, supplementaryInfo;
  jint jmajor, jminor;
  char* msg;
  jstring jmsg;
  jthrowable gssEx;

  if (major == GSS_S_COMPLETE) return;

  callingErr = GSS_CALLING_ERROR(major);
  routineErr = GSS_ROUTINE_ERROR(major);
  supplementaryInfo = GSS_SUPPLEMENTARY_INFO(major);

  TRACE3("%s Status major/minor = %x/%d", methodName, major, minor);
  TRACE3("c/r/s = %d/%d/%d ", callingErr>>24, routineErr>>16,
          supplementaryInfo);

  jmajor = getJavaErrorCode(routineErr | supplementaryInfo);
  jminor = minor;
  if (jmajor != GSS_S_COMPLETE) {
    jmsg = NULL;
    if (minor != 0) {
      jmsg = getMinorMessage(env, jstub, minor);
      if ((*env)->ExceptionCheck(env)) {
        return;
      }
    }

    gssEx = (*env)->NewObject(env, CLS_GSSException,
                              MID_GSSException_ctor3,
                              jmajor, jminor, jmsg);
    if (gssEx != NULL) {
      (*env)->Throw(env, gssEx);
    }
  } else {
    /* Error in calling the GSS api */
    if (callingErr == GSS_S_CALL_INACCESSIBLE_READ) {
      msg = "A required input parameter cannot be read";
    } else if (callingErr == GSS_S_CALL_INACCESSIBLE_WRITE) {
      msg = "A required output parameter cannot be write";
    } else {
      msg = "A parameter was malformed";
    }
    jmajor = 13; /* use GSSException.FAILURE for now */
    jmsg = (*env)->NewStringUTF(env, msg);
    if (jmsg == NULL) {
      return;
    }
    gssEx = (*env)->NewObject(env, CLS_GSSException,
                              MID_GSSException_ctor3,
                              jmajor, jminor, jmsg);
    if (gssEx != NULL) {
      (*env)->Throw(env, gssEx);
    }
  }
}

/*
 * Utility routine for initializing gss_buffer_t structure
 * with the byte[] in the specified jbyteArray object.
 * NOTE: must call resetGSSBuffer() to free up the resources
 * inside the gss_buffer_t structure.
 */
void initGSSBuffer(JNIEnv *env, jbyteArray jbytes,
                     gss_buffer_t cbytes) {

  int len;
  void* value;

  if (jbytes != NULL) {
    len = (*env)->GetArrayLength(env, jbytes);
    value = malloc(len);
    if (value == NULL) {
      gssThrowOutOfMemoryError(env, NULL);
      return;
    } else {
      (*env)->GetByteArrayRegion(env, jbytes, 0, len, value);
      if ((*env)->ExceptionCheck(env)) {
        free(value);
        return;
      } else {
        cbytes->length = len;
        cbytes->value = value;
      }
    }
  } else {
    cbytes->length = 0;
    cbytes->value = NULL;
  }
}

/*
 * Utility routine for freeing the bytes malloc'ed
 * in initGSSBuffer() method.
 * NOTE: used in conjunction with initGSSBuffer(...).
 */
void resetGSSBuffer(gss_buffer_t cbytes) {
  if ((cbytes != NULL) && (cbytes != GSS_C_NO_BUFFER)) {
    free(cbytes->value);
    cbytes->length = 0;
    cbytes->value = NULL;
  }
}

/*
 * Utility routine for creating a jbyteArray object using
 * the byte[] value in specified gss_buffer_t structure.
 * NOTE: the specified gss_buffer_t structure is always
 * released.
 */
jbyteArray getJavaBuffer(JNIEnv *env, gss_buffer_t cbytes) {
  jbyteArray result = NULL;
  OM_uint32 minor; // don't care, just so it compiles

  if (cbytes != NULL) {
    if ((cbytes != GSS_C_NO_BUFFER) && (cbytes->length != 0)) {
      result = (*env)->NewByteArray(env, (int) cbytes->length);
      if (result == NULL) {
        goto finish;
      }
      (*env)->SetByteArrayRegion(env, result, 0, (int) cbytes->length,
                                 cbytes->value);
      if ((*env)->ExceptionCheck(env)) {
        result = NULL;
      }
    }
  finish:
    (*ftab->releaseBuffer)(&minor, cbytes);
    return result;
  }
  return NULL;
}

/*
 * Utility routine for creating a non-mech gss_OID using
 * the specified org.ietf.jgss.Oid object.
 * NOTE: must call deleteGSSOID(...) to free up the gss_OID.
 */
gss_OID newGSSOID(JNIEnv *env, jobject jOid) {
  jbyteArray jbytes;
  gss_OID cOid;
  if (jOid != NULL) {
    jbytes = (*env)->CallObjectMethod(env, jOid, MID_Oid_getDER);
    if ((*env)->ExceptionCheck(env)) {
      return GSS_C_NO_OID;
    }
    cOid = malloc(sizeof(struct gss_OID_desc_struct));
    if (cOid == NULL) {
      gssThrowOutOfMemoryError(env,NULL);
      return GSS_C_NO_OID;
    }
    cOid->length = (*env)->GetArrayLength(env, jbytes) - 2;
    cOid->elements = malloc(cOid->length);
    if (cOid->elements == NULL) {
      gssThrowOutOfMemoryError(env,NULL);
      goto cleanup;
    }
    (*env)->GetByteArrayRegion(env, jbytes, 2, cOid->length,
                               cOid->elements);
    if ((*env)->ExceptionCheck(env)) {
      goto cleanup;
    }
    return cOid;
  } else {
    return GSS_C_NO_OID;
  }
  cleanup:
    (*env)->DeleteLocalRef(env, jbytes);
    free(cOid->elements);
    free(cOid);
    return GSS_C_NO_OID;
}

/*
 * Utility routine for releasing the specified gss_OID
 * structure.
 * NOTE: used in conjunction with newGSSOID(...).
 */
void deleteGSSOID(gss_OID oid) {
  if (oid != GSS_C_NO_OID) {
    free(oid->elements);
    free(oid);
  }
}

/*
 * Utility routine for creating a org.ietf.jgss.Oid
 * object using the specified gss_OID structure.
 */
jobject getJavaOID(JNIEnv *env, gss_OID cOid) {
  int cLen;
  char oidHdr[2];
  jbyteArray jbytes;
  jobject result = NULL;

  if ((cOid == NULL) || (cOid == GSS_C_NO_OID)) {
    return NULL;
  }
  cLen = cOid->length;
  oidHdr[0] = 6;
  oidHdr[1] = cLen;
  jbytes = (*env)->NewByteArray(env, cLen+2);
  if (jbytes == NULL) {
    return NULL;
  }
  if (!(*env)->ExceptionCheck(env)) {
    (*env)->SetByteArrayRegion(env, jbytes, 0, 2, (jbyte *) oidHdr);
  }
  if (!(*env)->ExceptionCheck(env)) {
    (*env)->SetByteArrayRegion(env, jbytes, 2, cLen, (jbyte *) cOid->elements);
  }
  if (!(*env)->ExceptionCheck(env)) {
    result = (*env)->NewObject(env, CLS_Oid, MID_Oid_ctor1, jbytes);
  }
  (*env)->DeleteLocalRef(env, jbytes);
  return result;
}
/*
 * Utility routine for creating a gss_OID_set structure
 * using the specified gss_OID.
 * NOTE: need to call deleteGSSOIDSet(...) afterwards
 * to release the created gss_OID_set structure.
 */
gss_OID_set newGSSOIDSet(gss_OID oid) {
  gss_OID_set oidSet;
  OM_uint32 minor; // don't care; just so it compiles

  if (oid->length != 6 ||
      memcmp(oid->elements, SPNEGO_BYTES, 6) != 0) {
      (*ftab->createEmptyOidSet)(&minor, &oidSet);
      (*ftab->addOidSetMember)(&minor, oid, &oidSet);
      return oidSet;
  } else {
      // Use all mechs for SPNEGO in order to work with
      // various native GSS impls
      return (ftab->mechs);
  }
}
/*
 * Utility routine for releasing a gss_OID_set structure.
 * NOTE: used in conjunction with newGSSOIDSet(...).
 */
void deleteGSSOIDSet(gss_OID_set oidSet) {
  OM_uint32 minor; /* don't care; just so it compiles */

  if ((oidSet != ftab->mechs) &&
      (oidSet != NULL) && (oidSet != GSS_C_NO_OID_SET)) {
    (*ftab->releaseOidSet)(&minor, &oidSet);
  }
}
/*
 * Utility routine for creating a org.ietf.jgss.Oid[]
 * using the specified gss_OID_set structure.
 */
jobjectArray getJavaOIDArray(JNIEnv *env, gss_OID_set cOidSet) {
  int numOfOids = 0;
  jobjectArray jOidSet;
  jobject jOid;
  int i;

  if (cOidSet != NULL && cOidSet != GSS_C_NO_OID_SET) {
    numOfOids = (int) cOidSet->count;
    jOidSet = (*env)->NewObjectArray(env, numOfOids, CLS_Oid, NULL);
    if ((*env)->ExceptionCheck(env)) {
      return NULL;
    }
    for (i = 0; i < numOfOids; i++) {
      jOid = getJavaOID(env, &(cOidSet->elements[i]));
      if ((*env)->ExceptionCheck(env)) {
        return NULL;
      }
      (*env)->SetObjectArrayElement(env, jOidSet, i, jOid);
      if ((*env)->ExceptionCheck(env)) {
        return NULL;
      }
      (*env)->DeleteLocalRef(env, jOid);
    }
    return jOidSet;
  }
  return NULL;
}

int sameMech(gss_OID mech, gss_OID mech2) {
  int result = JNI_FALSE; // default to not equal

  if (mech->length == mech2->length) {
    result = (memcmp(mech->elements, mech2->elements, mech->length) == 0);
  }
  return result;
}
