AC_DEFINE(HAVE_GSSAPI, 1, [GSSAPI support])
fi
- AC_CACHE_CHECK([for spnego support], squid_cv_have_spnego, [
- AC_RUN_IFELSE([AC_LANG_SOURCE([[
-#ifdef HAVE_HEIMDAL_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#else
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#endif
-#include <string.h>
-int main(int argc, char *argv[]) {
- OM_uint32 major_status,minor_status;
- gss_OID_set gss_mech_set;
- int i;
-
-static gss_OID_desc _gss_mech_spnego = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
-gss_OID gss_mech_spnego = &_gss_mech_spnego;
-
- major_status = gss_indicate_mechs( &minor_status, &gss_mech_set);
-
- for (i=0;i<gss_mech_set->count;i++) {
- if (!memcmp(gss_mech_set->elements[i].elements,gss_mech_spnego->elements,gss_mech_set->elements[i].length)) {
- return 0;
- }
- }
-
- return 1;
-}
-]])], [ squid_cv_have_spnego=yes ], [ squid_cv_have_spnego=no ])])
-
- if test "$squid_cv_have_spnego" = "yes" ; then
- AC_DEFINE(HAVE_SPNEGO,1, [Define to 1 if you have SPNEGO support])
- fi
AC_CACHE_CHECK([for working krb5], squid_cv_working_krb5, [
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#ifdef HAVE_KRB5_H
AC_SUBST(KRB5INCS)
AC_SUBST(KRB5LIBS)
fi
-AM_CONDITIONAL(HAVE_SPNEGO, test x"$squid_cv_have_spnego" = x"yes" )
dnl Enable "NTLM fail open"
AC_ARG_ENABLE(ntlm-fail-open,
SOURCE = negotiate_kerberos_auth.cc base64.cc base64.h
SOURCE_test = negotiate_kerberos_auth_test.cc base64.cc base64.h
-SPNEGO = \
- spnegohelp/derparse.cc spnegohelp/derparse.h \
- spnegohelp/spnego.cc spnegohelp/spnego.h \
- spnegohelp/spnegohelp.cc spnegohelp/spnegohelp.h \
- spnegohelp/spnegoparse.cc spnegohelp/spnegoparse.h
-if HAVE_SPNEGO
negotiate_kerberos_auth_SOURCES = $(SOURCE)
AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)
-else
-negotiate_kerberos_auth_SOURCES = $(SOURCE) $(SPNEGO)
-AM_CPPFLAGS = $(INCLUDES) -I$(srcdir)/spnegohelp -I$(srcdir)
-endif
negotiate_kerberos_auth_test_SOURCES = $(SOURCE_test)
#include "base64.h"
#include "getaddrinfo.h"
#include "getnameinfo.h"
-#if !HAVE_SPNEGO
-#include "spnegohelp.h"
-#endif
#if HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
int length = 0;
static int err = 0;
int opt, debug = 0, log = 0, norealm = 0;
-#if !HAVE_SPNEGO
- int rc;
-#endif
OM_uint32 ret_flags = 0, spnego_flag = 0;
char *service_name = (char *) "HTTP", *host_name = NULL;
char *token = NULL;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
const unsigned char *kerberosToken = NULL;
-#if !HAVE_SPNEGO
- size_t kerberosTokenLength = 0;
-#endif
const unsigned char *spnegoToken = NULL;
size_t spnegoTokenLength = 0;
ska_base64_decode((char*)input_token.value, buf + 3, input_token.length);
-#if !HAVE_SPNEGO
- if ((rc = parseNegTokenInit((const unsigned char*)input_token.value,
- input_token.length,
- &kerberosToken, &kerberosTokenLength)) != 0) {
- if (debug)
- fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n",
- LogTime(), PROGRAM, rc);
-
- /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
- if (rc < 100 || rc > 199) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n",
- LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid GSS-SPNEGO query\n");
- goto cleanup;
- }
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp(input_token.value, ntlmProtocol,
- sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n",
- LogTime(), PROGRAM,
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- fprintf(stdout, "BH received type %d NTLM token\n",
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- goto cleanup;
- }
- if (debug)
- fprintf(stderr, "%s| %s: Token is possibly a GSSAPI token\n",
- LogTime(), PROGRAM);
- spnego_flag = 0;
- } else {
- gss_release_buffer(&minor_status, &input_token);
- input_token.length = kerberosTokenLength;
- input_token.value = (void *) kerberosToken;
- spnego_flag = 1;
- }
-#else
if ((input_token.length >= sizeof ntlmProtocol + 1) &&
(!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
if (debug)
sizeof ntlmProtocol));
goto cleanup;
}
-#endif
if (service_principal) {
if (strcasecmp(service_principal, "GSS_C_NO_NAME")) {
if (output_token.length) {
-#if !HAVE_SPNEGO
- if (spnego_flag) {
- if ((rc = makeNegTokenTarg((const unsigned char*)output_token.value,
- output_token.length,
- &spnegoToken, &spnegoTokenLength)) != 0) {
- if (debug)
- fprintf(stderr,
- "%s| %s: makeNegTokenTarg failed with rc=%d\n",
- LogTime(), PROGRAM, rc);
- fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",
- rc);
- goto cleanup;
- }
- } else {
- spnegoToken = (const unsigned char*)output_token.value;
- spnegoTokenLength = output_token.length;
- }
-#else
spnegoToken = (const unsigned char*)output_token.value;
spnegoTokenLength = output_token.length;
-#endif
token = (char*)xmalloc(ska_base64_encode_len(spnegoTokenLength));
if (token == NULL) {
if (debug)
return buf;
}
-#ifdef HAVE_SPNEGO
#ifndef gss_mech_spnego
static gss_OID_desc _gss_mech_spnego = { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
gss_OID gss_mech_spnego = &_gss_mech_spnego;
#endif
-#endif
int
check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
major_status = gss_init_sec_context(&minor_status,
GSS_C_NO_CREDENTIAL, &gss_context, server_name,
-#ifdef HAVE_SPNEGO
gss_mech_spnego,
-#else
- 0,
-#endif
0,
0,
GSS_C_NO_CHANNEL_BINDINGS,
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-
-/////////////////////////////////////////////////////////////
-//
-// DERPARSE.C
-//
-// SPNEGO Token Handler Source File
-//
-// Contains implementation of ASN.1 DER read/write functions
-// as defined in DERPARSE.H.
-//
-/////////////////////////////////////////////////////////////
-
-#include "config.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include "spnego.h"
-#include "derparse.h"
-
-//
-// The GSS Mechanism OID enumeration values (SPNEGO_MECH_OID) control which offset in
-// the array below, that a mechanism can be found.
-//
-MECH_OID g_stcMechOIDList[] = {
- {(unsigned char *) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy}, // 1.2.840.48018.1.2.2
- {(unsigned char *) "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5}, // 1.2.840.113554.1.2.2
- {(unsigned char *) "\x06\x06\x2b\x06\x01\x05\x05\x02", 8, 6, spnego_mech_oid_Spnego}, // 1.3.6.1.1.5.5.2
- {(unsigned char *) "", 0, 0, spnego_mech_oid_NotUsed} // Placeholder
-};
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerGetLength
-//
-// Parameters:
-// [in] pbLengthData - DER Length Data
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnLength - Filled out with length value
-// [out] pnNumLengthBytes - Filled out with number of bytes
-// consumed by DER length.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Interprets the data at pbLengthData as a DER length. The length must
-// fit within the bounds of nBoundary length. We do not currently
-// process lengths that take more than 4 bytes.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
- long *pnLength, long *pnNumLengthBytes)
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- int nNumLengthBytes = 0;
-
- // First check if the extended length bit is set
-
- if (*pbLengthData & LEN_XTND) {
- // Lower 7 bits contain the number of trailing bytes that describe the length
- nNumLengthBytes = *pbLengthData & LEN_MASK;
-
- // Check that the number of bytes we are about to read is within our boundary
- // constraints
-
- if (nNumLengthBytes <= nBoundaryLength - 1) {
-
- // For now, our handler won't deal with lengths greater than 4 bytes
- if (nNumLengthBytes >= 1 && nNumLengthBytes <= 4) {
- // 0 out the initial length
- *pnLength = 0L;
-
- // Bump by 1 byte
- pbLengthData++;
-
-#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
-
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch (nNumLengthBytes) {
- case 1: {
- *(((unsigned char *) pnLength)) = *pbLengthData;
- break;
- }
-
- case 2: {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 1) = *(pbLengthData);
-
- break;
- }
-
- case 3: {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 2);
- *(((unsigned char *) pnLength) + 2) =
- *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
- break;
- }
-
- case 4: {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 3);
- *(((unsigned char *) pnLength) + 1) =
- *(pbLengthData + 2);
- *(((unsigned char *) pnLength) + 2) =
- *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
-
-#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
-
- memcpy(((unsigned char *) pnLength) + (4 - nNumLengthBytes),
- pbLengthData, nNumLengthBytes);
-#endif
-
- // Account for the initial length byte
- *pnNumLengthBytes = nNumLengthBytes + 1;
- nReturn = SPNEGO_E_SUCCESS;
-
- } // IF Valid Length
-
- } // IF num bytes to read is within the boundary length
-
- } // IF xtended length
- else {
-
- // Extended bit is not set, so the length is in the value and the one
- // byte describes the length
- *pnLength = *pbLengthData & LEN_MASK;
- *pnNumLengthBytes = 1;
- nReturn = SPNEGO_E_SUCCESS;
-
- }
- LOG(("ASNDerGetLength returned %d\n", nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCheckToken
-//
-// Parameters:
-// [in] pbTokenData - Token Data
-// [in] nToken - Token identifier to check for
-// [in] nLengthWithToken - Expected token length (with data)
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnLength - Filled out with data length
-// [out] pnTokenLength - Filled out with number of bytes
-// consumed by token identifier and length.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data pointed to by pbTokenData for the specified token
-// identifier and the length that immediately follows. If
-// nLengthWithToken is > 0, the calculated length must match. The
-// length must also not exceed the specified boundary length .
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
- long nLengthWithToken, long nBoundaryLength,
- long *pnLength, long *pnTokenLength)
-{
-
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- long nNumLengthBytes = 0L;
-
- // Make sure that we've at least got 2 bytes of room to work with
-
- if (nBoundaryLength >= 2) {
- // The first byte of the token data MUST match the specified token
- if (*pbTokenData == nToken) {
- // Next byte indicates the length
- pbTokenData++;
-
- // Get the length described by the token
- if ((nReturn =
- ASNDerGetLength(pbTokenData, nBoundaryLength, pnLength,
- &nNumLengthBytes)) == SPNEGO_E_SUCCESS) {
- // Verify that the length is LESS THAN the boundary length
- // (this should prevent us walking out of our buffer)
- if ((nBoundaryLength - (nNumLengthBytes + 1) < *pnLength)) {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
- // If we were passed a length to check, do so now
- if (nLengthWithToken > 0L) {
-
- // Check that the expected length matches
- if ((nLengthWithToken - (nNumLengthBytes + 1)) != *pnLength) {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
-
- } // IF need to validate length
-
- if (SPNEGO_E_SUCCESS == nReturn) {
- *pnTokenLength = nNumLengthBytes + 1;
- }
-
- } // IF ASNDerGetLength
-
- } // IF token matches
- else {
- nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
- }
-
- } // IF Boundary Length is at least 2 bytes
-
- LOG(("ASNDerCheckToken returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCheckOID
-//
-// Parameters:
-// [in] pbTokenData - Token Data
-// [in] nMechOID - OID we are looking for
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnTokenLength - Filled out with number of bytes
-// consumed by token and data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data pointed to by pbTokenData for the specified OID.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
- long nBoundaryLength, long *pnTokenLength)
-{
- int nReturn = 0L;
- long nLength = 0L;
-
- // Verify that we have an OID token
- if ((nReturn = ASNDerCheckToken(pbTokenData, OID, 0L, nBoundaryLength,
- &nLength, pnTokenLength)) == SPNEGO_E_SUCCESS) {
- // Add the data length to the Token Length
- *pnTokenLength += nLength;
-
- // Token Lengths plus the actual length must match the length in our OID list element.
- // If it doesn't, we're done
- if (*pnTokenLength == g_stcMechOIDList[nMechOID].iLen) {
- // Memcompare the token and the expected field
- if (memcmp(pbTokenData, g_stcMechOIDList[nMechOID].ucOid,
- *pnTokenLength) != 0) {
- LOG(("ASNDerCheckOID memcmp failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
- } else {
- LOG(("ASNDerCheckOID token length failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
-
- } // IF OID Token CHecks
-
- LOG(("ASNDerCheckOID returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcNumLengthBytes
-//
-// Parameters:
-// [in] nLength - Length to calculate length bytes for.
-//
-// Returns:
-// int Number of bytes necessary to represent length
-//
-// Comments :
-// Helper function to calculate the number of length bytes necessary to
-// represent a length value. For our purposes, a 32-bit value should be
-// enough to describea length.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerCalcNumLengthBytes(long nLength)
-{
- if (nLength <= 0x7F) {
- // A single byte will be sufficient for describing this length.
- // The byte will simply contain the length
- return 1;
- } else if (nLength <= 0xFF) {
- // Two bytes are necessary, one to say how many following bytes
- // describe the length, and one to give the length
- return 2;
- } else if (nLength <= 0xFFFF) {
- // Three bytes are necessary, one to say how many following bytes
- // describe the length, and two to give the length
- return 3;
- } else if (nLength <= 0xFFFFFF) {
- // Four bytes are necessary, one to say how many following bytes
- // describe the length, and three to give the length
- return 4;
- } else {
- // Five bytes are necessary, one to say how many following bytes
- // describe the length, and four to give the length
- return 5;
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcTokenLength
-//
-// Parameters:
-// [in] nLength - Length to calculate length bytes for.
-// [in] nDataLength - Actual Data length value.
-//
-// Returns:
-// long Number of bytes necessary to represent a token, length and data
-//
-// Comments :
-// Helper function to calculate a token and value size, based on a
-// supplied length value, and any binary data that will need to be
-// written out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long
-ASNDerCalcTokenLength(long nLength, long nDataLength)
-{
- // Add a byte to the length size to account for a single byte to
- // hold the token type.
- long nTotalLength = ASNDerCalcNumLengthBytes(nLength) + 1;
-
- return nTotalLength + nDataLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcElementLength
-//
-// Parameters:
-// [in] nDataLength - Length of data.
-// [out] pnInternalLength - Filled out with length of element
-// without sequence info.
-//
-// Returns:
-// long Number of bytes necessary to represent an element
-//
-// Comments :
-// Helper function to calculate an element length. An element consists
-// of a sequence token, a type token and then the data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long
-ASNDerCalcElementLength(long nDataLength, long *pnInternalLength)
-{
- // First the type token and the actual data
- long nTotalLength = ASNDerCalcTokenLength(nDataLength, nDataLength);
-
- // Internal length is the length without the element sequence token
- if (NULL != pnInternalLength) {
- *pnInternalLength = nTotalLength;
- }
- // Next add in the element's sequence token (remember that its
- // length is the total length of the type token and data)
- nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- return nTotalLength;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcMechListLength
-//
-// Parameters:
-// [in] mechoid - Mech OID to put in list.
-// [out] pnInternalLength - Filled out with length of element
-// without the primary sequence token.
-//
-// Returns:
-// long Number of bytes necessary to represent a mechList
-//
-// Comments :
-// Helper function to calculate a MechList length. A mechlist consists
-// of a NegTokenInit sequence token, a sequence token for the MechList
-// and finally a list of OIDs. In our case, we only really have one
-// OID.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long
-ASNDerCalcMechListLength(SPNEGO_MECH_OID mechoid, long *pnInternalLength)
-{
- // First the OID
- long nTotalLength = g_stcMechOIDList[mechoid].iLen;
-
- // Next add in a sequence token
- nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Internal length is the length without the element sequence token
- if (NULL != pnInternalLength) {
- *pnInternalLength = nTotalLength;
- }
- // Finally add in the element's sequence token
- nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- return nTotalLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteLength
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] nLength - Length to write out.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a length value following DER rules .
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerWriteLength(unsigned char *pbData, long nLength)
-{
- int nNumBytesRequired = ASNDerCalcNumLengthBytes(nLength);
- int nNumLengthBytes = nNumBytesRequired - 1;
-
-
- if (nNumBytesRequired > 1) {
-
- // Write out the number of bytes following which will be used
- *pbData = (unsigned char) (LEN_XTND | nNumLengthBytes);
-
- // Point to where we'll actually write the length
- pbData++;
-
-#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
-
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch (nNumLengthBytes) {
- case 1: {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- break;
- }
-
- case 2: {
- *pbData = *(((unsigned char *) &nLength) + 1);
- *(pbData + 1) = *(((unsigned char *) &nLength));
- break;
- }
-
- case 3: {
- *pbData = *(((unsigned char *) &nLength) + 3);
- *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
- *(pbData + 2) = *(((unsigned char *) &nLength));
- break;
- }
-
- case 4: {
- *pbData = *(((unsigned char *) &nLength) + 3);
- *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
- *(pbData + 2) = *(((unsigned char *) &nLength) + 1);
- *(pbData + 3) = *(((unsigned char *) &nLength));
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
-
-#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
-
- memcpy(pbData,
- ((unsigned char *) &nLength) + (4 - nNumLengthBytes),
- nNumLengthBytes);
-#endif
-
- } // IF > 1 byte for length
- else {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- }
-
- return nNumBytesRequired;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteToken
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] ucType - Token Type
-// [in] pbTokenValue - Actual Value
-// [in] nLength - Length of Data.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a token and any associated data. If
-// pbTokenValue is non-NULL, then it is written out in addition to the
-// token identifier and the length bytes.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength)
-{
- int nTotalBytesWrittenOut = 0L;
- int nNumLengthBytesWritten = 0L;
-
- // Write out the type
- *pbData = ucType;
-
- // Wrote 1 byte, and move data pointer
- nTotalBytesWrittenOut++;
- pbData++;
-
- // Now write out the length and adjust the number of bytes written out
- nNumLengthBytesWritten = ASNDerWriteLength(pbData, nLength);
-
- nTotalBytesWrittenOut += nNumLengthBytesWritten;
- pbData += nNumLengthBytesWritten;
-
- // Write out the token value if we got one. The assumption is that the
- // nLength value indicates how many bytes are in pbTokenValue.
-
- if (NULL != pbTokenValue) {
- memcpy(pbData, pbTokenValue, nLength);
- nTotalBytesWrittenOut += nLength;
- }
-
- return nTotalBytesWrittenOut;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteOID
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] eMechOID - OID to write out.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out an OID. For these we have the raw bytes
-// listed in a global structure. The caller simply indicates which OID
-// should be written and we will splat out the data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerWriteOID(unsigned char *pbData, SPNEGO_MECH_OID eMechOID)
-{
-
- memcpy(pbData, g_stcMechOIDList[eMechOID].ucOid,
- g_stcMechOIDList[eMechOID].iLen);
-
- return g_stcMechOIDList[eMechOID].iLen;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteMechList
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] eMechOID - OID to put in MechList.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a MechList. A MechList consists of the
-// Init Token Sequence, a sequence token and then the list of OIDs. In
-// our case the OID is from a global array of known OIDs.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long
-ASNDerWriteMechList(unsigned char *pbData, SPNEGO_MECH_OID mechoid)
-{
- // First get the length
- long nInternalLength = 0L;
- long nMechListLength = ASNDerCalcMechListLength(mechoid, &nInternalLength);
- long nTempLength = 0L;
-
- nTempLength = ASNDerWriteToken(pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
- NULL, nInternalLength);
-
- // Adjust the data pointer
- pbData += nTempLength;
-
- // Now write the Sequence token and the OID (the OID is a BLOB in the global
- // structure.
-
- nTempLength = ASNDerWriteToken(pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
- g_stcMechOIDList[mechoid].ucOid, g_stcMechOIDList[mechoid].iLen);
-
- return nMechListLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteElement
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] ucElementSequence - Sequence Token
-// [in] ucType - Token Type
-// [in] pbTokenValue - Actual Value
-// [in] nLength - Length of Data.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a SPNEGO Token element. An element
-// consists of a sequence token, a type token and the associated data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ASNDerWriteElement(unsigned char *pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char *pbTokenValue, long nLength)
-{
- // First get the length
- long nInternalLength = 0L;
- long nElementLength = ASNDerCalcElementLength(nLength, &nInternalLength);
- long nTempLength = 0L;
-
- // Write out the sequence byte and the length of the type and data
- nTempLength =
- ASNDerWriteToken(pbData, ucElementSequence, NULL, nInternalLength);
-
- // Adjust the data pointer
- pbData += nTempLength;
-
- // Now write the type and the data.
- nTempLength = ASNDerWriteToken(pbData, ucType, pbTokenValue, nLength);
-
- return nElementLength;
-}
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-/////////////////////////////////////////////////////////////
-//
-// DERPARSE.H
-//
-// SPNEGO Token Handler Header File
-//
-// Contains the definitions required to properly parse the
-// SPNEGO DER encoding.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __DERPARSE_H__
-#define __DERPARSE_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
- /* Identifier Types */
-#define IDENTIFIER_MASK 0xC0 // Bits 7 and 8
-#define IDENTIFIER_UNIVERSAL 0x00 // 00 = universal
-#define IDENTIFIER_APPLICATION 0x40 // 01 = application
-#define IDENTIFIER_CONTEXT_SPECIFIC 0x80 // 10 = context specific
-#define IDENTIFIER_PRIVATE 0xC0 // 11 = Private
-
- /* Encoding type */
-
-#define FORM_MASK 0x20 /* Bit 6 */
-#define PRIMITIVE 0x00 /* 0 = primitive */
-#define CONSTRUCTED 0x20 /* 1 = constructed */
-
- /* Universal tags */
-
-#define TAG_MASK 0x1F /* Bits 5 - 1 */
-#define BOOLEAN 0x01 /* 1: TRUE or FALSE */
-#define INTEGER 0x02 /* 2: Arbitrary precision integer */
-#define BITSTRING 0x03 /* 2: Sequence of bits */
-#define OCTETSTRING 0x04 /* 4: Sequence of bytes */
-#define NULLTAG 0x05 /* 5: NULL */
-#define OID 0x06 /* 6: Object Identifier (numeric sequence) */
-#define OBJDESCRIPTOR 0x07 /* 7: Object Descriptor (human readable) */
-#define EXTERNAL 0x08 /* 8: External / Instance Of */
-#define REAL 0x09 /* 9: Real (Mantissa * Base^Exponent) */
-#define ENUMERATED 0x0A /* 10: Enumerated */
-#define EMBEDDED_PDV 0x0B /* 11: Embedded Presentation Data Value */
-#define SEQUENCE 0x10 /* 16: Constructed Sequence / Sequence Of */
-#define SET 0x11 /* 17: Constructed Set / Set Of */
-#define NUMERICSTR 0x12 /* 18: Numeric String (digits only) */
-#define PRINTABLESTR 0x13 /* 19: Printable String */
-#define T61STR 0x14 /* 20: T61 String (Teletex) */
-#define VIDEOTEXSTR 0x15 /* 21: Videotex String */
-#define IA5STR 0x16 /* 22: IA5 String */
-#define UTCTIME 0x17 /* 23: UTC Time */
-#define GENERALIZEDTIME 0x18 /* 24: Generalized Time */
-#define GRAPHICSTR 0x19 /* 25: Graphic String */
-#define VISIBLESTR 0x1A /* 26: Visible String (ISO 646) */
-#define GENERALSTR 0x1B /* 27: General String */
-#define UNIVERSALSTR 0x1C /* 28: Universal String */
-#define BMPSTR 0x1E /* 30: Basic Multilingual Plane String */
-
- /* Length encoding */
-
-#define LEN_XTND 0x80 /* Indefinite or long form */
-#define LEN_MASK 0x7f /* Bits 7 - 1 */
-
-//
-// SPNEGO Token Parsing Constants
-//
-
-
-// Fixed Length of NegTokenInit ReqFlags field
-#define SPNEGO_NEGINIT_MAXLEN_REQFLAGS 2
-
-// Difference in bits for ReqFlags token
-#define SPNEGO_NEGINIT_REQFLAGS_BITDIFF 1
-
-// Fixed Length of NegTokenTarg NegResult field
-#define SPNEGO_NEGTARG_MAXLEN_NEGRESULT 1
-
-// Application Specific Construct - Always at the start of a NegTokenInit
-#define SPNEGO_NEGINIT_APP_CONSTRUCT ( IDENTIFIER_APPLICATION | CONSTRUCTED ) // 0x60
-
-// Constructed Sequence token - after the actual token identifier token
-#define SPNEGO_CONSTRUCTED_SEQUENCE ( SEQUENCE | CONSTRUCTED )
-
-// MechList Type Identifier
-#define SPNEGO_MECHLIST_TYPE ( SEQUENCE | CONSTRUCTED | OID )
-
-//
-// NegTokenInit - Token Identifier and Elements
-//
-
-// NegTokenInit - 0xa0
-#define SPNEGO_NEGINIT_TOKEN_IDENTIFIER ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_TOKEN_INIT )
-
-// Structure elements for NegTokenInit
-#define SPNEGO_NEGINIT_MECHTYPES 0x0 // MechTypes is element 0
-#define SPNEGO_NEGINIT_REQFLAGS 0x1 // ReqFlags is element 1
-#define SPNEGO_NEGINIT_MECHTOKEN 0x2 // MechToken is element 2
-#define SPNEGO_NEGINIT_MECHLISTMIC 0x3 // MechListMIC is element 3
-
-// MechTypes element is 0xa0
-#define SPNEGO_NEGINIT_ELEMENT_MECHTYPES ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHTYPES )
-
-// ReqFlags element is 0xa1
-#define SPNEGO_NEGINIT_ELEMENT_REQFLAGS ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_REQFLAGS )
-
-// MechToken element is 0xa2
-#define SPNEGO_NEGINIT_ELEMENT_MECHTOKEN ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHTOKEN )
-
-// MechListMIC element is 0xa3
-#define SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHLISTMIC )
-
-//
-// NegTokenTarg - Token Identifier and Elements
-//
-
-// NegTokenTarg - 0xa1
-#define SPNEGO_NEGTARG_TOKEN_IDENTIFIER ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_TOKEN_TARG )
-
-// Structure elements for NegTokenTarg
-#define SPNEGO_NEGTARG_NEGRESULT 0x0 // NegResult is element 0
-#define SPNEGO_NEGTARG_SUPPORTEDMECH 0x1 // SupportedMech is element 1
-#define SPNEGO_NEGTARG_RESPONSETOKEN 0x2 // ResponseToken is element 2
-#define SPNEGO_NEGTARG_MECHLISTMIC 0x3 // MechListMIC is element 3
-
-// NegResult element is 0xa0
-#define SPNEGO_NEGTARG_ELEMENT_NEGRESULT ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_NEGRESULT )
-
-// SupportedMech element is 0xa1
-#define SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_SUPPORTEDMECH )
-
-// ResponseToken element is 0xa2
-#define SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_RESPONSETOKEN )
-
-// MechListMIC element is 0xa3
-#define SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_MECHLISTMIC )
-
-//
-// Defines a GSS Mechanism OID. We keep a single static array
-// of these which we'll use for validation/searches/parsing.
-//
-
- typedef struct _mechOID {
- unsigned char *ucOid; // Byte representation of OID
- int iLen; // Length of the OID, length and identifier
- int iActualDataLen; // Length of the actual OID
- SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
- } MECH_OID;
-
-
-//
-// ASN Der functions
-//
-
- int ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
- long *pnLength, long *pnNumLengthBytes);
- int ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
- long nCheckLength, long nBoundaryLength, long *pnLength,
- long *pnTokenLength);
- int ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
- long nBoundaryLength, long *pnTokenLength);
- int ASNDerCalcNumLengthBytes(long nLength);
- long ASNDerCalcTokenLength(long nLength, long nDataLength);
- long ASNDerCalcElementLength(long nDataLength, long *pnInternalLength);
- long ASNDerCalcMechListLength(SPNEGO_MECH_OID mechoid,
- long *pnInternalLength);
- int ASNDerWriteLength(unsigned char *pbData, long nLength);
- int ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength);
- int ASNDerWriteOID(unsigned char *pbData, SPNEGO_MECH_OID eMechOID);
- long ASNDerWriteMechList(unsigned char *pbData, SPNEGO_MECH_OID mechoid);
- int ASNDerWriteElement(unsigned char *pbData,
- unsigned char ucElementSequence, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength);
-
-
- // C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGO.C
-//
-// SPNEGO Token Handler Source File
-//
-// Contains implementation of SPNEGO Token Handling API
-// as defined in SPNEGO.H.
-//
-/////////////////////////////////////////////////////////////
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include "spnego.h"
-#include "derparse.h"
-#include "spnegoparse.h"
-
-//
-// Defined in DERPARSE.C
-//
-
-extern MECH_OID g_stcMechOIDList[];
-
-
-/**********************************************************************/
-/** **/
-/** **/
-/** **/
-/** **/
-/** SPNEGO Token Handler API implementation **/
-/** **/
-/** **/
-/** **/
-/** **/
-/**********************************************************************/
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoInitFromBinary
-//
-// Parameters:
-// [in] pbTokenData - Binary Token Data
-// [in] ulLength - Length of binary Token Data
-// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Initializes a SPNEGO_TOKEN_HANDLE from the supplied
-// binary data. Data is copied locally. Returned data structure
-// must be freed by calling spnegoFreeData().
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN_HANDLE * phSpnegoToken)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
-
- // Pass off to a handler function that allows tighter control over how the token structure
- // is handled. In this case, we want the token data copied and we want the associated buffer
- // freed.
- nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYDATA,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
- ulLength, ppSpnegoToken);
-
- LOG(("spnegoInitFromBinary returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoCreateNegTokenInit
-//
-// Parameters:
-// [in] MechType - MechType to specify in MechTypeList element
-// [in] ucContextFlags - Context Flags element value
-// [in] pbMechToken - Pointer to binary MechToken Data
-// [in] ulMechTokenLen - Length of MechToken Data
-// [in] pbMechListMIC - Pointer to binary MechListMIC Data
-// [in] ulMechListMICLen - Length of MechListMIC Data
-// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type
-// from the supplied parameters. ucContextFlags may be 0 or must be
-// a valid flag combination. MechToken data can be NULL - if not, it
-// must correspond to the MechType. MechListMIC can also be NULL.
-// Returned data structure must be freed by calling spnegoFreeData().
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long nInternalTokenLength = 0L;
- unsigned char *pbTokenData = NULL;
- SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
-
- if (NULL != ppSpnegoToken &&
- IsValidMechOid(MechType) && IsValidContextFlags(ucContextFlags)) {
- // Get the actual token size
-
- if ((nReturn =
- CalculateMinSpnegoInitTokenSize(ulMechTokenLen,
- ulMechListMICLen, MechType, (ucContextFlags != 0L),
- &nTokenLength, &nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Allocate a buffer to hold the data.
- pbTokenData = static_cast<unsigned char*>(calloc(1, nTokenLength));
-
- if (NULL != pbTokenData) {
-
- // Now write the token
- if ((nReturn = CreateSpnegoInitToken(MechType,
- ucContextFlags, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken);
-
- }
- // Cleanup on failure
- if (SPNEGO_E_SUCCESS != nReturn) {
- free(pbTokenData);
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
-
- } // IF Valid Parameters
-
- LOG(("spnegoCreateNegTokenInit returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoCreateNegTokenTarg
-//
-// Parameters:
-// [in] MechType - MechType to specify in supported MechType element
-// [in] spnegoNegResult - NegResult value
-// [in] pbMechToken - Pointer to response MechToken Data
-// [in] ulMechTokenLen - Length of MechToken Data
-// [in] pbMechListMIC - Pointer to binary MechListMIC Data
-// [in] ulMechListMICLen - Length of MechListMIC Data
-// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenTarg type
-// from the supplied parameters. MechToken data can be NULL - if not,
-// it must correspond to the MechType. MechListMIC can also be NULL.
-// Returned data structure must be freed by calling spnegoFreeData().
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long nInternalTokenLength = 0L;
- unsigned char *pbTokenData = NULL;
- SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
-
- //
- // spnego_mech_oid_NotUsed and spnego_negresult_NotUsed
- // are okay here, however a valid MechOid is required
- // if spnego_negresult_success or spnego_negresult_incomplete
- // is specified.
- //
-
- if (NULL != ppSpnegoToken &&
- (IsValidMechOid(MechType) ||
- spnego_mech_oid_NotUsed == MechType) &&
- (IsValidNegResult(spnegoNegResult) ||
- spnego_negresult_NotUsed == spnegoNegResult) &&
- !(!IsValidMechOid(MechType) &&
- (spnego_negresult_success == spnegoNegResult ||
- spnego_negresult_incomplete == spnegoNegResult))) {
-
- // Get the actual token size
-
- if ((nReturn =
- CalculateMinSpnegoTargTokenSize(MechType, spnegoNegResult,
- ulMechTokenLen, ulMechListMICLen, &nTokenLength,
- &nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Allocate a buffer to hold the data.
- pbTokenData = static_cast<unsigned char*>(calloc(1, nTokenLength));
-
- if (NULL != pbTokenData) {
-
- // Now write the token
- if ((nReturn = CreateSpnegoTargToken(MechType,
- spnegoNegResult, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken);
-
- }
- // Cleanup on failure
- if (SPNEGO_E_SUCCESS != nReturn) {
- free(pbTokenData);
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
-
- } // IF Valid Parameters
-
- LOG(("spnegoCreateNegTokenTarg returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoTokenGetBinary
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pbTokenData - Buffer to copy token into
-// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
-// with actual size used upon function return.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Copies binary SPNEGO token data from hSpnegoToken into the user
-// supplied buffer. If pbTokenData is NULL, or the value in pulDataLen
-// is too small, the function will return SPNEGO_E_BUFFER_TOO_SMALL and
-// fill out pulDataLen with the minimum required buffer size.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters - pbTokenData is optional
- if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
-
- // Check for Buffer too small conditions
- if (NULL == pbTokenData || pSpnegoToken->ulBinaryDataLen > *pulDataLen) {
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- memcpy(pbTokenData, pSpnegoToken->pbBinaryData,
- pSpnegoToken->ulBinaryDataLen);
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoTokenGetBinary returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoFreeData
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-//
-// Returns:
-// void
-//
-// Comments :
-// Frees up resources consumed by hSpnegoToken. The supplied data
-// pointer is invalidated by this function.
-//
-////////////////////////////////////////////////////////////////////////////
-
-void
-spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken)
-{
- FreeSpnegoToken((SPNEGO_TOKEN *) hSpnegoToken);
- return;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoGetTokenType
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] piTokenType - Filled out with token type value.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// The function will analyze hSpnegoToken and return the appropriate
-// type in piTokenType.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) && NULL != piTokenType && pSpnegoToken) {
-
- // Check that the type in the structure makes sense
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
- *piTokenType = pSpnegoToken->ucTokenType;
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetTokenType returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoIsMechTypeAvailable
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [in] MechOID - MechOID to search MechTypeList for
-// [out] piMechTypeIndex - Filled out with index in MechTypeList
-// element if MechOID is found.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken must reference a token of type NegTokenInit. The
-// function will search the MechTypeList element for an OID corresponding
-// to the specified MechOID. If one is found, the index (0 based) will
-// be passed into the piMechTypeIndex parameter.
-//
-////////////////////////////////////////////////////////////////////////////
-
-// Returns the Initial Mech Type in the MechList element in the NegInitToken.
-int
-spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != piMechTypeIndex &&
- IsValidMechOid(MechOID) &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Check if MechList is available
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // Locate the MechOID in the list element
- nReturn =
- FindMechOIDInMechList(&pSpnegoToken->
- aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], MechOID,
- piMechTypeIndex);
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoIsMechTypeAvailable returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoGetContextFlags
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pucContextFlags - Filled out with ContextFlags value.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken must reference a token of type NegTokenInit. The
-// function will copy data from the ContextFlags element into the
-// location pucContextFlags points to. Note that the function will
-// fail if the actual ContextFlags data appears invalid.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pucContextFlags)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pucContextFlags &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Check if ContextFlags is available
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // The length should be two, the value should show a 1 bit difference in the difference byte, and
- // the value must be valid
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS
- && pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF
- && IsValidContextFlags(pSpnegoToken->
- aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1])) {
- *pucContextFlags =
- pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- pbData[1];
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
-
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetContextFlags returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoGetNegotiationResult
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pnegResult - Filled out with NegResult value.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken must reference a token of type NegTokenTarg. The
-// function will copy data from the NegResult element into the
-// location pointed to by pnegResult. Note that the function will
-// fail if the actual NegResult data appears invalid.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_NEGRESULT * pnegResult)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pnegResult && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
-
- // Check if NegResult is available
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // Must be 1 byte long and a valid value
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT
- && IsValidNegResult(static_cast<SPNEGO_NEGRESULT>(*pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData))) {
- *pnegResult = static_cast<SPNEGO_NEGRESULT>(*pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData);
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetNegotiationResult returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoGetSupportedMechType
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pMechOID - Filled out with Supported MechType value.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken must reference a token of type NegTokenTarg. The
-// function will check the Supported MechType element, and if it
-// corresponds to a supported MechType ( spnego_mech_oid_Kerberos_V5_Legacy
-// or spnego_mech_oid_Kerberos_V5 ), will set the location pointed
-// to by pMechOID equal to the appropriate value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID * pMechOID)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- int nCtr = 0L;
- long nLength = 0L;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pMechOID && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
-
- // Check if MechList is available
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
-
- for (nCtr = 0;
- nReturn != SPNEGO_E_SUCCESS &&
- g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
- nCtr++) {
-
- if ((nReturn =
- ASNDerCheckOID(pSpnegoToken->
- aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
- static_cast<SPNEGO_MECH_OID>(nCtr),
- pSpnegoToken->
- aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
- nDatalength, &nLength)) == SPNEGO_E_SUCCESS) {
- *pMechOID = static_cast<SPNEGO_MECH_OID>(nCtr);
- }
-
- } // For enum MechOIDs
-
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetSupportedMechType returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoTokenGetMechToken
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pbTokenData - Buffer to copy MechToken into
-// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
-// with actual size used upon function return.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token.
-// The function will copy the MechToken (the initial MechToken if
-// NegTokenInit, the response MechToken if NegTokenTarg) from the
-// underlying token into the buffer pointed to by pbTokenData. If
-// pbTokenData is NULL, or the value in pulDataLen is too small, the
-// function will return SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen
-// with the minimum required buffer size. The token can then be passed
-// to a GSS-API function for processing.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbTokenData,
- unsigned long *pulDataLen)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
- SPNEGO_ELEMENT *pSpnegoElement = NULL;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
-
- // Point at the proper Element
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
- } else {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
- }
-
- // Check if MechType is available
- if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
- // Check for Buffer too small conditions
- if (NULL == pbTokenData ||
- pSpnegoElement->nDatalength > *pulDataLen) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy(pbTokenData, pSpnegoElement->pbData,
- pSpnegoElement->nDatalength);
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetMechToken returned %d\n", nReturn));
- return nReturn;;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// spnegoTokenGetMechListMIC
-//
-// Parameters:
-// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
-// [out] pbTokenData - Buffer to copy MechListMIC data into
-// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
-// with actual size used upon function return.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token.
-// The function will copy the MechListMIC data from the underlying token
-// into the buffer pointed to by pbTokenData. If pbTokenData is NULL,
-// or the value in pulDataLen is too small, the function will return
-// SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen with the minimum
-// required buffer size.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbMICData,
- unsigned long *pulDataLen)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
- SPNEGO_ELEMENT *pSpnegoElement = NULL;
-
- // Check parameters
- if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
-
- // Point at the proper Element
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
- } else {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
- }
-
- // Check if MechType is available
- if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
- // Check for Buffer too small conditions
- if (NULL == pbMICData || pSpnegoElement->nDatalength > *pulDataLen) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy(pbMICData, pSpnegoElement->pbData,
- pSpnegoElement->nDatalength);
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
-
- } // IF parameters OK
-
- LOG(("spnegoGetMechListMIC returned %d\n", nReturn));
- return nReturn;;
-}
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGO.H
-//
-// SPNEGO Token Handler Header File
-//
-// Contains the definitions required to interpret and create
-// SPNEGO tokens so that Kerberos GSS tokens can be
-// Unpackaged/packaged.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __SPNEGO_H__
-#define __SPNEGO_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-// Type Definitions
-
-//
-// Users of SPNEGO Token Handler API will request
-// these as well as free them,
-//
- typedef void *SPNEGO_TOKEN_HANDLE;
-
-//
-// Defines the element types that are found
-// in each of the tokens.
-//
-
- typedef enum spnego_element_type
- {
- spnego_element_min, // Lower bound
-
- // Init token elements
- spnego_init_mechtypes,
- spnego_init_reqFlags,
- spnego_init_mechToken,
- spnego_init_mechListMIC,
-
- // Targ token elements
- spnego_targ_negResult,
- spnego_targ_supportedMech,
- spnego_targ_responseToken,
- spnego_targ_mechListMIC,
-
- spnego_element_max // Upper bound
- } SPNEGO_ELEMENT_TYPE;
-
-//
-// Token Element Availability. Elements in both
-// token types are optional. Since there are only
-// 4 elements in each Token, we will allocate space
-// to hold the information, but we need a way to
-// indicate whether or not an element is available
-//
-
-#define SPNEGO_TOKEN_ELEMENT_UNAVAILABLE 0
-#define SPNEGO_TOKEN_ELEMENT_AVAILABLE 1
-
-//
-// Token type values. SPNEGO has 2 token types:
-// NegTokenInit and NegTokenTarg
-//
-
-#define SPNEGO_TOKEN_INIT 0
-#define SPNEGO_TOKEN_TARG 1
-
-//
-// GSS Mechanism OID enumeration. We only really handle
-// 3 different OIDs. These are stored in an array structure
-// defined in the parsing code.
-//
-
- typedef enum spnego_mech_oid
- {
- // Init token elements
- spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
- spnego_mech_oid_Kerberos_V5,
- spnego_mech_oid_Spnego,
- spnego_mech_oid_NotUsed = -1
- } SPNEGO_MECH_OID;
-
-//
-// Defines the negResult values.
-//
-
- typedef enum spnego_negResult
- {
- spnego_negresult_success,
- spnego_negresult_incomplete,
- spnego_negresult_rejected,
- spnego_negresult_NotUsed = -1
- } SPNEGO_NEGRESULT;
-
-//
-// Context Flags in NegTokenInit
-//
-
-//
-// ContextFlags values MUST be zero or a combination
-// of the below
-//
-
-#define SPNEGO_NEGINIT_CONTEXT_DELEG_FLAG 0x80
-#define SPNEGO_NEGINIT_CONTEXT_MUTUAL_FLAG 0x40
-#define SPNEGO_NEGINIT_CONTEXT_REPLAY_FLAG 0x20
-#define SPNEGO_NEGINIT_CONTEXT_SEQUENCE_FLAG 0x10
-#define SPNEGO_NEGINIT_CONTEXT_ANON_FLAG 0x8
-#define SPNEGO_NEGINIT_CONTEXT_CONF_FLAG 0x4
-#define SPNEGO_NEGINIT_CONTEXT_INTEG_FLAG 0x2
-
-//
-// Mask to retrieve valid values.
-//
-
-#define SPNEGO_NEGINIT_CONTEXT_MASK 0xFE // Logical combination of above flags
-
-//
-// SPNEGO API return codes.
-//
-
-// API function was successful
-#define SPNEGO_E_SUCCESS 0
-
-// The supplied Token was invalid
-#define SPNEGO_E_INVALID_TOKEN -1
-
-// An invalid length was encountered
-#define SPNEGO_E_INVALID_LENGTH -2
-
-// The Token Parse failed
-#define SPNEGO_E_PARSE_FAILED -3
-
-// The requested value was not found
-#define SPNEGO_E_NOT_FOUND -4
-
-// The requested element is not available
-#define SPNEGO_E_ELEMENT_UNAVAILABLE -5
-
-// Out of Memory
-#define SPNEGO_E_OUT_OF_MEMORY -6
-
-// Not Implemented
-#define SPNEGO_E_NOT_IMPLEMENTED -7
-
-// Invalid Parameter
-#define SPNEGO_E_INVALID_PARAMETER -8
-
-// Token Handler encountered an unexpected OID
-#define SPNEGO_E_UNEXPECTED_OID -9
-
-// The requested token was not found
-#define SPNEGO_E_TOKEN_NOT_FOUND -10
-
-// An unexpected type was encountered in the encoding
-#define SPNEGO_E_UNEXPECTED_TYPE -11
-
-// The buffer was too small
-#define SPNEGO_E_BUFFER_TOO_SMALL -12
-
-// A Token Element was invalid (e.g. improper length or value)
-#define SPNEGO_E_INVALID_ELEMENT -13
-
- /* Miscelaneous API Functions */
-
-// Frees opaque data
- void spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken);
-
-// Initializes SPNEGO_TOKEN structure from DER encoded binary data
- int spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN_HANDLE * phSpnegoToken);
-
-// Initializes SPNEGO_TOKEN structure for a NegTokenInit type using the
-// supplied parameters
- int spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechTokenMIC,
- unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
-
-// Initializes SPNEGO_TOKEN structure for a NegTokenTarg type using the
-// supplied parameters
- int spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
-
-// Copies binary representation of SPNEGO Data into user supplied buffer
- int spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen);
-
-// Returns SPNEGO Token Type
- int spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType);
-
- /* Reading an Init Token */
-
-// Returns the Initial Mech Type in the MechList element in the NegInitToken.
- int spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
-
-// Returns the value from the context flags element in the NegInitToken as an unsigned long
- int spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pucContextFlags);
-
- /* Reading a Response Token */
-
-// Returns the value from the negResult element (Status code of GSS call - 0,1,2)
- int spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_NEGRESULT * pnegResult);
-
-// Returns the Supported Mech Type from the NegTokenTarg.
- int spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID * pMechOID);
-
- /* Reading either Token Type */
-
-// Returns the actual Mechanism data from the token (this is what is passed into GSS-API functions
- int spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen);
-
-// Returns the Message Integrity BLOB in the token
- int spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbMICData, unsigned long *pulDataLen);
-
-// C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-#ifdef DEBUG
-#include <stdio.h>
-#define PRERR(...) fprintf(stderr, __VA_ARGS__)
-#define LOG(x) PRERR x
-#else
-#define LOG(x)
-#endif
-#endif
+++ /dev/null
-/* -----------------------------------------------------------------------------
- * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003 All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * -----------------------------------------------------------------------------
- */
-
-#include "spnegohelp.h"
-#include "spnego.h"
-
-#include <stdlib.h>
-
-int
-makeNegTokenTarg(const unsigned char *kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char **negTokenTarg, size_t * negTokenTargLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
-
- /* Check arguments. */
-
- if (!kerberosToken || !negTokenTarg || !negTokenTargLength)
- return 10;
-
- /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
-
- /* Does IIS always reply with accept_completed? */
-
- /* IIS does not include a MIC. */
-
- rc2 = spnegoCreateNegTokenTarg(spnego_mech_oid_Kerberos_V5_Legacy,
- spnego_negresult_success,
- (unsigned char *) kerberosToken,
- kerberosTokenLength, NULL, 0, &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 100;
- goto cleanup;
- }
-
- /* Get NegTokenTarg length. */
-
- rc2 = spnegoTokenGetBinary(hSpnegoToken,
- NULL, (unsigned long *) negTokenTargLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2) + 200;
- goto cleanup;
- }
-
- *negTokenTarg = static_cast<const unsigned char *>(malloc(*negTokenTargLength));
-
- if (!*negTokenTarg) {
- rc1 = abs(rc2) + 300;
- goto cleanup;
- }
-
- /* Get NegTokenTarg data. */
-
- rc2 = spnegoTokenGetBinary(hSpnegoToken,
- (unsigned char *) *negTokenTarg, (unsigned long *) negTokenTargLength);
-
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 400;
- goto error;
- }
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*negTokenTarg) {
- free((unsigned char *) *negTokenTarg);
- *negTokenTarg = NULL;
- *negTokenTargLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData(hSpnegoToken);
-
- LOG(("makeNegTokenTarg returned %d\n", rc1));
- return rc1;
-}
-
-int
-parseNegTokenInit(const unsigned char *negTokenInit,
- size_t negTokenInitLength,
- const unsigned char **kerberosToken, size_t * kerberosTokenLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int pindex = -1;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
- unsigned char reqFlags = 0;
- int tokenType = 0;
-
- /* Check arguments. */
-
- if (!negTokenInit || !kerberosToken || !kerberosTokenLength)
- return 10;
-
- /* Decode SPNEGO token. */
-
- rc2 = spnegoInitFromBinary((unsigned char *) negTokenInit,
- negTokenInitLength, &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 100;
- goto cleanup;
- }
-
- /* Check for negTokenInit choice. */
-
- rc2 = spnegoGetTokenType(hSpnegoToken, &tokenType);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 200;
- goto cleanup;
- }
-
- if (tokenType != SPNEGO_TOKEN_INIT) {
- rc1 = abs(rc2) + 300;
- goto cleanup;
- }
-
- /*
- * Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
- */
-
- /*
- * IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
- */
-
- rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
- spnego_mech_oid_Kerberos_V5_Legacy, &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
- rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
- spnego_mech_oid_Kerberos_V5, &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
- rc1 = abs(rc2) + 400;
- goto cleanup;
- }
- }
-
- /* Check for no reqFlags. */
-
- /* Does IE ever send reqFlags? */
-
- rc2 = spnegoGetContextFlags(hSpnegoToken, &reqFlags);
-
- if (rc2 == SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 500;
- goto cleanup;
- }
-
- /* Get mechanism token length. */
-
- rc2 = spnegoGetMechToken(hSpnegoToken,
- NULL, (unsigned long *) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2) + 600;
- goto cleanup;
- }
-
- *kerberosToken = static_cast<const unsigned char *>(malloc(*kerberosTokenLength));
-
- if (!*kerberosToken) {
- rc1 = abs(rc2) + 700;
- goto cleanup;
- }
-
- /* Get mechanism token data. */
-
- rc2 = spnegoGetMechToken(hSpnegoToken,
- (unsigned char *) *kerberosToken,
- (unsigned long *) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 800;
- goto error;
- }
-
- /* According to Microsoft, IE does not send a MIC. */
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*kerberosToken) {
- free((unsigned char *) *kerberosToken);
- *kerberosToken = NULL;
- *kerberosTokenLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData(hSpnegoToken);
-
- LOG(("parseNegTokenInit returned %d\n", rc1));
- return rc1;
-}
+++ /dev/null
-/* -----------------------------------------------------------------------------
- * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003. All rights reserved.
- * -----------------------------------------------------------------------------
- */
-
-#ifndef SPNEGOHELP_H
-#define SPNEGOHELP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
- /* -----------------------------------------------------------------------------
- * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
- * RFC 1964 Kerberos GSS-API token.
- *
- * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
- * memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
- int makeNegTokenTarg(const unsigned char *kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char **negTokenTarg, size_t * negTokenTargLength);
-
- /* -----------------------------------------------------------------------------
- * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
- * an RFC 1964 Kerberos GSS-API token.
- *
- * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
- * returns an error.
- *
- * If parseNegTokenInit is successful, call free (*kerberosToken) to
- * free the memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
- int parseNegTokenInit(const unsigned char *negTokenInit,
- size_t negTokenInitLength,
- const unsigned char **kerberosToken, size_t * kerberosTokenLength);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SPNEGOHELP_H */
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGOPARSE.C
-//
-// SPNEGO Token Handler Source File
-//
-// Contains implementation of SPNEGO Token parsing functions.
-//
-/////////////////////////////////////////////////////////////
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include "spnego.h"
-#include "derparse.h"
-#include "spnegoparse.h"
-
-//
-// Defined in DERPARSE.C
-//
-
-extern MECH_OID g_stcMechOIDList[];
-
-/**********************************************************************/
-/** **/
-/** **/
-/** **/
-/** **/
-/** Local SPNEGO Helper definitions **/
-/** **/
-/** **/
-/** **/
-/** **/
-/**********************************************************************/
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateMinSpnegoInitTokenSize
-//
-// Parameters:
-// [in] nMechTokenLength - Length of the MechToken Element
-// [in] nMechListMICLength - Length of the MechListMIC Element
-// [in] mechOID - OID for MechList
-// [in] nReqFlagsAvailable - Is ContextFlags element available
-// [out] pnTokenSize - Filled out with total size of token
-// [out] pnInternalTokenLength - Filled out with length minus length
-// for initial token.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Calculates the required length for a SPNEGO NegTokenInit token based
-// on the supplied variable length values and which elements are present.
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long *pnTokenSize, long *pnInternalTokenLength)
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTotalLength = 0;
- long nTempLength = 0L;
-
- // We will calculate this by walking the token backwards
-
- // Start with MIC Element
- if (nMechListMICLength > 0L) {
- nTempLength = ASNDerCalcElementLength(nMechListMICLength, NULL);
-
- // Check for rollover error
- if (nTempLength < nMechListMICLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength += nTempLength;
- }
- // Next is the MechToken
- if (nMechTokenLength > 0L) {
- nTempLength += ASNDerCalcElementLength(nMechTokenLength, NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
- }
- // Next is the ReqFlags
- if (nReqFlagsAvailable) {
- nTempLength +=
- ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
- }
- // Next is the MechList - This is REQUIRED
- nTempLength += ASNDerCalcMechListLength(mechOid, NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // Following four fields are the basic header tokens
-
- // Sequence Token
- nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // SPNEGO OID Token
- nTempLength += g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // App Constructed Token
- nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
- // The internal length doesn't include the number of bytes
- // for the initial token
- *pnInternalTokenLength = nTotalLength;
- nTotalLength = nTempLength;
-
- // We're done
- *pnTokenSize = nTotalLength;
- nReturn = SPNEGO_E_SUCCESS;
-
-xEndTokenInitLength:
-
- LOG(("CalculateMinSpnegoInitTokenSize returned %d\n", nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CreateSpnegoInitToken
-//
-// Parameters:
-// [in] MechType - OID in MechList
-// [in] ucContextFlags - ContextFlags value
-// [in] pbMechToken - Mech Token Binary Data
-// [in] ulMechTokenLen - Length of Mech Token
-// [in] pbMechListMIC - MechListMIC Binary Data
-// [in] ulMechListMICn - Length of MechListMIC
-// [out] pbTokenData - Buffer to write token into.
-// [in] nTokenLength - Length of pbTokenData buffer
-// [in] nInternalTokenLength - Length of full token without leading
-// token bytes.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Uses DER to fill out pbTokenData with a SPNEGO NegTokenInit Token
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength)
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTempLength = 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
-
- unsigned char *pbWriteTokenData = pbTokenData + nTokenLength;
-
- // Temporary buffer to hold the REQ Flags as BIT String Data
- unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS];
-
-
- // We will write the token out backwards to properly handle the cases
- // where the length bytes become adjustable
-
- // Start with MIC Element
- if (ulMechListMICLen > 0L) {
- nTempLength =
- ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
- ulMechListMICLen);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechListMIC is present
-
- // Next is the MechToken
- if (ulMechTokenLen > 0L) {
- nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, OCTETSTRING, pbMechToken,
- ulMechTokenLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechToken Length is present
-
- // Next is the ReqFlags
- if (ucContextFlags > 0L) {
-
- nTempLength =
- ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS,
- &nInternalLength);
-
- // We need a byte that indicates how many bits difference between the number
- // of bits used in final octet (we only have one) and the max (8)
-
- abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
- abTempReqFlags[1] = ucContextFlags;
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_REQFLAGS, BITSTRING, abTempReqFlags,
- SPNEGO_NEGINIT_MAXLEN_REQFLAGS);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF ContextFlags
-
- // Next is the MechList - This is REQUIRED
- nTempLength = ASNDerCalcMechListLength(MechType, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteMechList(pbWriteTokenData, MechType);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
- // The next tokens we're writing out reflect the total number of bytes
- // we have actually written out.
-
- // Sequence Token
- nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
- nTotalBytesWritten);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
- // Neg Init Token Identifier Token
- nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
- // SPNEGO OID Token
- nTempLength = g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteOID(pbWriteTokenData, spnego_mech_oid_Spnego);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
- // App Constructed Token
- nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, NULL,
- nTotalBytesWritten);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
-
- // Don't adjust the internal token length here, it doesn't account
- // the initial bytes written out (we really don't need to keep
- // a running count here, but for debugging, it helps to be able
- // to see the total number of bytes written out as well as the
- // number of bytes left to write).
-
- if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData) {
- nReturn = SPNEGO_E_SUCCESS;
- }
-
-xEndWriteNegTokenInit:
-
- LOG(("CreateSpnegoInitToken returned %d\n", nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateMinSpnegoTargTokenSize
-//
-// Parameters:
-// [in] MechType - Supported MechType
-// [in] spnegoNegResult - Neg Result
-// [in] nMechTokenLength - Length of the MechToken Element
-// [in] nMechListMICLength - Length of the MechListMIC Element
-// [out] pnTokenSize - Filled out with total size of token
-// [out] pnInternalTokenLength - Filled out with length minus length
-// for initial token.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Calculates the required length for a SPNEGO NegTokenTarg token based
-// on the supplied variable length values and which elements are present.
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechListMICLen, long *pnTokenSize, long *pnInternalTokenLength)
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTotalLength = 0;
- long nTempLength = 0L;
-
- // We will calculate this by walking the token backwards
-
- // Start with MIC Element
- if (nMechListMICLen > 0L) {
- nTempLength = ASNDerCalcElementLength(nMechListMICLen, NULL);
-
- // Check for rollover error
- if (nTempLength < nMechListMICLen) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength += nTempLength;
- }
- // Next is the MechToken
- if (nMechTokenLen > 0L) {
- nTempLength += ASNDerCalcElementLength(nMechTokenLen, NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
- }
- // Supported MechType
- if (spnego_mech_oid_NotUsed != MechType) {
- // Supported MechOID element - we use the token function since
- // we already know the size of the OID token and value
- nTempLength +=
- ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
- NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF MechType is available
-
- // NegResult Element
- if (spnego_negresult_NotUsed != spnegoNegResult) {
- nTempLength +=
- ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF negResult is available
-
- // Following two fields are the basic header tokens
-
- // Sequence Token
- nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- // Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength(nTotalLength, 0L);
-
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
- // The internal length doesn't include the number of bytes
- // for the initial token
- *pnInternalTokenLength = nTotalLength;
- nTotalLength = nTempLength;
-
- // We're done
- *pnTokenSize = nTotalLength;
- nReturn = SPNEGO_E_SUCCESS;
-
-xEndTokenTargLength:
-
- LOG(("CalculateMinSpnegoTargTokenSize returned %d\n", nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CreateSpnegoTargToken
-//
-// Parameters:
-// [in] MechType - Supported MechType
-// [in] eNegResult - NegResult value
-// [in] pbMechToken - Mech Token Binary Data
-// [in] ulMechTokenLen - Length of Mech Token
-// [in] pbMechListMIC - MechListMIC Binary Data
-// [in] ulMechListMICn - Length of MechListMIC
-// [out] pbTokenData - Buffer to write token into.
-// [in] nTokenLength - Length of pbTokenData buffer
-// [in] nInternalTokenLength - Length of full token without leading
-// token bytes.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Uses DER to fill out pbTokenData with a SPNEGO NegTokenTarg Token
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength)
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTempLength = 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
-
- unsigned char ucTemp = 0;
-
- // We will write the token out backwards to properly handle the cases
- // where the length bytes become adjustable, so the write location
- // is initialized to point *just* past the end of the buffer.
-
- unsigned char *pbWriteTokenData = pbTokenData + nTokenLength;
-
-
- // Start with MIC Element
- if (ulMechListMICLen > 0L) {
- nTempLength =
- ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
- ulMechListMICLen);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechListMIC is present
-
- // Next is the MechToken
- if (ulMechTokenLen > 0L) {
- nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, OCTETSTRING, pbMechToken,
- ulMechTokenLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechToken Length is present
-
- // Supported Mech Type
- if (spnego_mech_oid_NotUsed != MechType) {
-
- nTempLength =
- ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
- &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- g_stcMechOIDList[MechType].ucOid, g_stcMechOIDList[MechType].iLen);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechType is present
-
- // Neg Result
- // NegResult Element
- if (spnego_negresult_NotUsed != eNegResult) {
- ucTemp = (unsigned char) eNegResult;
-
- nTempLength =
- ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT,
- &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_NEGRESULT, ENUMERATED, &ucTemp,
- SPNEGO_NEGTARG_MAXLEN_NEGRESULT);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
-
- } // If eNegResult is available
-
- // The next tokens we're writing out reflect the total number of bytes
- // we have actually written out.
-
- // Sequence Token
- nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
- nTotalBytesWritten);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
- // Neg Targ Token Identifier Token
- nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten);
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
-
- // Don't adjust the internal token length here, it doesn't account
- // the initial bytes written out (we really don't need to keep
- // a running count here, but for debugging, it helps to be able
- // to see the total number of bytes written out as well as the
- // number of bytes left to write).
-
- if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData) {
- nReturn = SPNEGO_E_SUCCESS;
- }
-
-
-xEndWriteNegTokenTarg:
-
- LOG(("CreateSpnegoTargToken returned %d\n", nReturn));
- return nReturn;
-
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// AllocEmptySpnegoToken
-//
-// Parameters:
-// [in] ucCopyData - Flag to copy data or pointer.
-// [in] ulFlags - Flags for SPNEGO_TOKEN data member.
-// [in] pbTokenData - Binary token data.
-// [in] ulTokenSize - Size of pbTokenData.
-//
-// Returns:
-// SPNEGO_TOKEN* Success - Pointer to initialized SPNEGO_TOKEN struct
-// Failure - NULL
-//
-// Comments :
-// Allocates a SPNEGO_TOKEN data structure and initializes it. Based on
-// the value of ucCopyData, if non-zero, we copy the data into a buffer
-// we allocate in this function, otherwise, we copy the data pointer
-// direcly.
-//
-////////////////////////////////////////////////////////////////////////////
-
-SPNEGO_TOKEN *
-AllocEmptySpnegoToken(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulTokenSize)
-{
- SPNEGO_TOKEN *pSpnegoToken =
- (SPNEGO_TOKEN *) calloc(1, sizeof(SPNEGO_TOKEN));
-
- if (NULL != pSpnegoToken) {
- // Set the token size
- pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
-
- // Initialize the element array
- InitSpnegoTokenElementArray(pSpnegoToken);
-
- // Assign the flags value
- pSpnegoToken->ulFlags = ulFlags;
-
- //
- // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
- // Otherwise, we will just copy the pointer and the length. This is so we
- // can cut out additional allocations for performance reasons
- //
-
- if (SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData) {
- // Alloc the internal buffer. Cleanup on failure.
- pSpnegoToken->pbBinaryData =
- (unsigned char *) calloc(ulTokenSize, sizeof(unsigned char));
-
- if (NULL != pSpnegoToken->pbBinaryData) {
- // We must ALWAYS free this buffer
- pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
-
- // Copy the data locally
- memcpy(pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize);
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- } else {
- free(pSpnegoToken);
- pSpnegoToken = NULL;
- }
-
- } // IF ucCopyData
- else {
- // Copy the pointer and the length directly - ulFlags will control whether or not
- // we are allowed to free the value
-
- pSpnegoToken->pbBinaryData = pbTokenData;
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- }
-
- }
-
- return pSpnegoToken;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// FreeSpnegoToken
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN to free.
-//
-// Returns:
-// void
-//
-// Comments :
-// If non-NULL, interprets pSpnegoToken, freeing any internal allocations
-// and finally the actual structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-void
-FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken)
-{
- if (NULL != pSpnegoToken) {
-
- // Cleanup internal allocation per the flags
- if (pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
- NULL != pSpnegoToken->pbBinaryData) {
- free(pSpnegoToken->pbBinaryData);
- pSpnegoToken->pbBinaryData = NULL;
- }
-
- free(pSpnegoToken);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementArray
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
-//
-// Returns:
-// void
-//
-// Comments :
-// Initializes the element array data member of a SPNEGO_TOKEN data
-// structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-void
-InitSpnegoTokenElementArray(SPNEGO_TOKEN * pSpnegoToken)
-{
- int nCtr;
-
- // Set the number of elemnts
- pSpnegoToken->nNumElements = MAX_NUM_TOKEN_ELEMENTS;
-
- //
- // Initially, all elements are unavailable
- //
-
- for (nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++) {
- // Set the element size as well
- pSpnegoToken->aElementArray[nCtr].nStructSize = SPNEGO_ELEMENT_SIZE;
- pSpnegoToken->aElementArray[nCtr].iElementPresent =
- SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenType
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
-// [out] pnTokenLength - Filled out with total token length
-// [out] pnRemainingTokenLength - Filled out with remaining length
-// after header is parsed
-// [out] ppbFirstElement - Filled out with pointer to first
-// element after header info.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Walks the underlying binary data for a SPNEGO_TOKEN data structure
-// and determines the type of the underlying token based on token header
-// information.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
- long *pnRemainingTokenLength, unsigned char **ppbFirstElement)
-{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nActualTokenLength = 0L;
- long nBoundaryLength = pSpnegoToken->ulBinaryDataLen;
- unsigned char *pbTokenData = pSpnegoToken->pbBinaryData;
-
- //
- // First byte MUST be either an APP_CONSTRUCT or the NEGTARG_TOKEN_TARG
- //
-
- if (SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData) {
- // Validate the above token - this will tell us the actual length of the token
- // per the encoding (minus the actual token bytes)
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L,
- nBoundaryLength, pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should be an OID
- if ((nReturn =
- ASNDerCheckOID(pbTokenData, spnego_mech_oid_Spnego,
- nBoundaryLength,
- &nActualTokenLength)) == SPNEGO_E_SUCCESS) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the NegTokenInit
- if ((nReturn =
- ASNDerCheckToken(pbTokenData,
- SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength,
- pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ((nReturn =
- ASNDerCheckToken(pbTokenData,
- SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength,
- pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
-
- } // IF Check for SPNEGO OID
-
-
- } // IF check app construct token
-
- } else if (SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData) {
-
- // The next token should specify the NegTokenInit
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
- } // ELSE IF it's a NegTokenTarg
-
- LOG(("InitSpnegoTokenType returned %d\n", nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// GetSpnegoInitTokenMechList
-//
-// Parameters:
-// [in] pbTokenData - Points to binary MechList element
-// in NegTokenInit.
-// [in] nMechListLength - Length of the MechList
-// [out] pSpnegoElement - Filled out with MechList Element
-// data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks that pbTokenData is pointing at something that at least
-// *looks* like a MechList and then fills out the supplied
-// SPNEGO_ELEMENT structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-GetSpnegoInitTokenMechList(unsigned char *pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT * pSpnegoElement)
-{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // Actual MechList is prepended by a Constructed Sequence Token
- if ((nReturn = ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- nMechListLength, nMechListLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Adjust for this token
- nMechListLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Perform simple validation of the actual MechList (i.e. ensure that
- // the OIDs in the MechList are reasonable).
-
- if ((nReturn =
- ValidateMechList(pbTokenData, nLength)) == SPNEGO_E_SUCCESS) {
- // Initialize the element now
- pSpnegoElement->eElementType = spnego_init_mechtypes;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF Check Token
-
- LOG(("GetSpnegoInitTokenMechList returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementFromBasicType
-//
-// Parameters:
-// [in] pbTokenData - Points to binary element data in
-// a SPNEGO token.
-// [in] nElementLength - Length of the element
-// [in] ucExpectedType - Expected DER type.
-// [in] spnegoElementType - Which element is this?
-// [out] pSpnegoElement - Filled out with element data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks that pbTokenData is pointing at the specified DER type. If so,
-// then we verify that lengths are proper and then fill out the
-// SPNEGO_ELEMENT data structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
- int nElementLength, unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
-{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // The type BYTE must match our token data or something is badly wrong
- if (*pbTokenData == ucExpectedType) {
-
- // Check that we are pointing at the specified type
- if ((nReturn = ASNDerCheckToken(pbTokenData, ucExpectedType,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Adjust for this token
- nElementLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = ucExpectedType;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n", nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementFromOID
-//
-// Parameters:
-// [in] pbTokenData - Points to binary element data in
-// a SPNEGO token.
-// [in] nElementLength - Length of the element
-// [in] spnegoElementType - Which element is this?
-// [out] pSpnegoElement - Filled out with element data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Initializes a SpnegoElement from an OID - normally, this would have
-// used the Basic Type function above, but since we do binary compares
-// on the OIDs against the DER information as well as the OID, we need
-// to account for that.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-InitSpnegoTokenElementFromOID(unsigned char *pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
-{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // The type BYTE must match our token data or something is badly wrong
- if (*pbTokenData == OID) {
-
- // Check that we are pointing at an OID type
- if ((nReturn = ASNDerCheckToken(pbTokenData, OID,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Don't adjust any values for this function
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = OID;
- pSpnegoElement->nDatalength = nElementLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n", nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElements
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN struct
-// [in] pbTokenData - Points to initial binary element
-// data in a SPNEGO token.
-// [in] nRemainingTokenLength - Length remaining past header
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Interprets the data at pbTokenData based on the TokenType in
-// pSpnegoToken. Since some elements are optional (technically all are
-// but the token becomes quite useless if this is so), we check if
-// an element exists before filling out the element in the array.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken, unsigned char *pbTokenData,
- long nRemainingTokenLength)
-{
- //
- // The following arrays contain the token identifiers for the elements
- // comprising the actual token. All values are optional, and there are
- // no defaults.
- //
-
- static unsigned char abNegTokenInitElements[] = { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC
- };
-
- static unsigned char abNegTokenTargElements[] = { SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
- SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC
- };
-
- int nReturn = SPNEGO_E_SUCCESS;
- int nCtr = 0L;
- long nElementLength = 0L;
- long nActualTokenLength = 0L;
- unsigned char *pbElements = NULL;
-
- // Point to the correct array
- switch (pSpnegoToken->ucTokenType) {
- case SPNEGO_TOKEN_INIT: {
- pbElements = abNegTokenInitElements;
- }
- break;
-
- case SPNEGO_TOKEN_TARG: {
- pbElements = abNegTokenTargElements;
- }
- break;
-
- } // SWITCH tokentype
-
- //
- // Enumerate the element arrays and look for the tokens at our current location
- //
-
- for (nCtr = 0L;
- SPNEGO_E_SUCCESS == nReturn &&
- nCtr < MAX_NUM_TOKEN_ELEMENTS && nRemainingTokenLength > 0L; nCtr++) {
-
- // Check if the token exists
- if ((nReturn = ASNDerCheckToken(pbTokenData, pbElements[nCtr],
- 0L, nRemainingTokenLength,
- &nElementLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // Token data should skip over the sequence token and then
- // call the appropriate function to initialize the element
- pbTokenData += nActualTokenLength;
-
- // Lengths in the elements should NOT go beyond the element
- // length
-
- // Different tokens mean different elements
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Handle each element as appropriate
- switch (pbElements[nCtr]) {
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTYPES: {
- //
- // This is a Mech List that specifies which OIDs the
- // originator of the Init Token supports.
- //
-
- nReturn =
- GetSpnegoInitTokenMechList(pbTokenData,
- nElementLength, &pSpnegoToken->aElementArray[nCtr]);
-
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_REQFLAGS: {
- //
- // This is a BITSTRING which specifies the flags that the receiver
- // pass to the gss_accept_sec_context() function.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, BITSTRING, spnego_init_reqFlags,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN: {
- //
- // This is an OCTETSTRING which contains a GSSAPI token corresponding
- // to the first OID in the MechList.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING, spnego_init_mechToken,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC: {
- //
- // This is an OCTETSTRING which contains a message integrity BLOB.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_init_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- } // SWITCH Element
- } else {
-
- switch (pbElements[nCtr]) {
-
- case SPNEGO_NEGTARG_ELEMENT_NEGRESULT: {
- //
- // This is an ENUMERATION which specifies result of the last GSS
- // token negotiation call.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, ENUMERATED, spnego_targ_negResult,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH: {
- //
- // This is an OID which specifies a supported mechanism.
- //
-
- nReturn =
- InitSpnegoTokenElementFromOID(pbTokenData,
- nElementLength, spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN: {
- //
- // This is an OCTETSTRING which specifies results of the last GSS
- // token negotiation call.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_targ_responseToken,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC: {
- //
- // This is an OCTETSTRING which specifies a message integrity BLOB.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- } // SWITCH Element
-
- } // ELSE !NegTokenInit
-
- // Account for the entire token and following data
- nRemainingTokenLength -= (nActualTokenLength + nElementLength);
-
- // Token data should skip past the element length now
- pbTokenData += nElementLength;
-
- } // IF Token found
- else if (SPNEGO_E_TOKEN_NOT_FOUND == nReturn) {
- // For now, this is a benign error (remember, all elements are optional, so
- // if we don't find one, it's okay).
-
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // FOR enum elements
-
- //
- // We should always run down to 0 remaining bytes in the token. If not, we've got
- // a bad token.
- //
-
- if (SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L) {
- nReturn = SPNEGO_E_INVALID_TOKEN;
- }
-
- LOG(("InitSpnegoTokenElements returned %d\n", nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// FindMechOIDInMechList
-//
-// Parameters:
-// [in] pSpnegoElement - SPNEGO_ELEMENT for MechList
-// [in] MechOID - OID we're looking for.
-// [out] piMechTypeIndex - Index in the list where OID was
-// found
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Walks the MechList for MechOID. When it is found, the index in the
-// list is written to piMechTypeIndex.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int *piMechTypeIndex)
-{
- int nReturn = SPNEGO_E_NOT_FOUND;
- int nCtr = 0;
- long nLength = 0L;
- long nBoundaryLength = pSpnegoElement->nDatalength;
- unsigned char *pbMechListData = pSpnegoElement->pbData;
-
- while (SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L) {
-
- // Use the helper function to check the OID
- if ((nReturn =
- ASNDerCheckOID(pbMechListData, MechOID, nBoundaryLength,
- &nLength))
- == SPNEGO_E_SUCCESS) {
- *piMechTypeIndex = nCtr;
- }
- // Adjust for the current OID
- pbMechListData += nLength;
- nBoundaryLength -= nLength;
- nCtr++;
-
- } // WHILE enuming OIDs
-
- LOG(("FindMechOIDInMechList returned %d\n", nReturn));
- return nReturn;
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ValidateMechList
-//
-// Parameters:
-// [in] pbMechListData - Pointer to binary MechList data
-// [in] nBoundaryLength - Length we must not exceed
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data at pbMechListData to see if it looks like a MechList.
-// As part of this, we walk the list and ensure that none of the OIDs
-// have a length that takes us outside of nBoundaryLength.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-ValidateMechList(unsigned char *pbMechListData, long nBoundaryLength)
-{
- int nReturn = SPNEGO_E_SUCCESS;
- long nLength = 0L;
- long nTokenLength = 0L;
-
- while (SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L) {
- // Verify that we have something that at least *looks* like an OID - in other
- // words it has an OID identifier and specifies a length that doesn't go beyond
- // the size of the list.
- nReturn = ASNDerCheckToken(pbMechListData, OID, 0L, nBoundaryLength,
- &nLength, &nTokenLength);
-
- // Adjust for the current OID
- pbMechListData += (nLength + nTokenLength);
- nBoundaryLength -= (nLength + nTokenLength);
-
- } // WHILE enuming OIDs
-
- LOG(("ValidateMechList returned %d\n", nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidMechOid
-//
-// Parameters:
-// [in] mechOid - mechOID id enumeration
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid mechOid value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-IsValidMechOid(SPNEGO_MECH_OID mechOid)
-{
- LOG(("IsValidMechOid returned %d\n",
- mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
- && mechOid <= spnego_mech_oid_Spnego));
- return (mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
- && mechOid <= spnego_mech_oid_Spnego);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidContextFlags
-//
-// Parameters:
-// [in] ucContextFlags - ContextFlags value
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid ContextFlags value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-IsValidContextFlags(unsigned char ucContextFlags)
-{
- // Mask out our valid bits. If there is anything leftover, this
- // is not a valid value for Context Flags
- LOG(("IsValidContextFlags returned %d\n",
- ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0)));
- return ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidNegResult
-//
-// Parameters:
-// [in] negResult - NegResult value
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid NegResult value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-IsValidNegResult(SPNEGO_NEGRESULT negResult)
-{
- LOG(("IsValidNegResult returned %d\n", negResult >= spnego_negresult_success
- && negResult <= spnego_negresult_rejected));
- return (negResult >= spnego_negresult_success
- && negResult <= spnego_negresult_rejected);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidSpnegoToken
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Performs simple heuristic on location pointed to by pSpnegoToken.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-IsValidSpnegoToken(SPNEGO_TOKEN * pSpnegoToken)
-{
- int nReturn = 0;
-
- // Parameter should be non-NULL
- if (NULL != pSpnegoToken) {
- // Length should be at least the size defined in the header
- if (pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE) {
- // Number of elements should be >= our maximum - if it's greater, that's
- // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
- if (pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS) {
- // Check for proper token type
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
- nReturn = 1;
- }
- }
-
- } // IF struct size makes sense
-
- } // IF non-NULL spnego Token
-
- LOG(("IsValidSpnegoToken returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidSpnegoElement
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-// [in] spnegoElement - spnegoElement Type from enumeration
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks that spnegoElement has a valid value and is appropriate for
-// the SPNEGO token encapsulated by pSpnegoToken.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement)
-{
- int nReturn = 0;
-
- // Check boundaries
- if (spnegoElement > spnego_element_min &&
- spnegoElement < spnego_element_max) {
-
- // Check for appropriateness to token type
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- nReturn = (spnegoElement >= spnego_init_mechtypes &&
- spnegoElement <= spnego_init_mechListMIC);
- } else {
- nReturn = (spnegoElement >= spnego_targ_negResult &&
- spnegoElement <= spnego_targ_mechListMIC);
- }
-
- } // IF boundary conditions are met
-
- LOG(("IsValidSpnegoElement returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateElementArrayIndex
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-// [in] spnegoElement - spnegoElement Type from enumeration
-//
-// Returns:
-// int index in the SPNEGO_TOKEN element array that the element can
-// can be found
-//
-// Comments :
-// Based on the Token Type, calculates the index in the element array
-// at which the specified element can be found.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int
-CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement)
-{
- int nReturn = 0;
-
- // Offset is difference between value and initial element identifier
- // (these differ based on ucTokenType)
-
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- nReturn = spnegoElement - spnego_init_mechtypes;
- } else {
- nReturn = spnegoElement - spnego_targ_negResult;
- }
-
- LOG(("CalculateElementArrayIndex returned %d\n", nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitTokenFromBinary
-//
-// Parameters:
-// [in] ucCopyData - Flag indicating if data should be copied
-// [in] ulFlags - Flags value for structure
-// [in] pnTokenData - Binary Token Data
-// [in] ulLength - Length of the data
-// [out] ppSpnegoToken - Pointer to call allocated SPNEGO Token
-// data structure
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Allocates a SPNEGO_TOKEN data structure and fills it out as
-// appropriate based in the flags passed into the function.
-//
-////////////////////////////////////////////////////////////////////////////
-
-
-// Initializes SPNEGO_TOKEN structure from DER encoded binary data
-int
-InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN ** ppSpnegoToken)
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN *pSpnegoToken = NULL;
- unsigned char *pbFirstElement = NULL;
- long nTokenLength = 0L;
- long nRemainingTokenLength = 0L;
-
- // Basic Parameter Validation
-
- if (NULL != pbTokenData && NULL != ppSpnegoToken && 0L != ulLength) {
-
- //
- // Allocate the empty token, then initialize the data structure.
- //
-
- pSpnegoToken =
- AllocEmptySpnegoToken(ucCopyData, ulFlags, pbTokenData, ulLength);
-
- if (NULL != pSpnegoToken) {
-
- // Copy the binary data locally
-
-
- // Initialize the token type
- if ((nReturn = InitSpnegoTokenType(pSpnegoToken, &nTokenLength,
- &nRemainingTokenLength, &pbFirstElement))
- == SPNEGO_E_SUCCESS) {
-
- // Initialize the element array
- if ((nReturn =
- InitSpnegoTokenElements(pSpnegoToken, pbFirstElement,
- nRemainingTokenLength))
- == SPNEGO_E_SUCCESS) {
- *ppSpnegoToken = pSpnegoToken;
- }
-
- } // IF Init Token Type
-
- // Cleanup on error condition
- if (SPNEGO_E_SUCCESS != nReturn) {
- spnegoFreeData(pSpnegoToken);
- }
-
- } else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // IF Valid parameters
-
-
- LOG(("InitTokenFromBinary returned %d\n", nReturn));
- return nReturn;
-}
+++ /dev/null
-// Copyright (C) 2002 Microsoft Corporation
-// All rights reserved.
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
-// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-// OR IMPLIED, INCLUDING BUT NOT LIMITED
-// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
-// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Date - 10/08/2002
-// Author - Sanj Surati
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGOPARSE.H
-//
-// SPNEGO Token Parser Header File
-//
-// Contains the definitions required to properly parse a
-// SPNEGO token using ASN.1 DER helpers.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __SPNEGOPARSE_H__
-#define __SPNEGOPARSE_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-// Indicates if we copy data when creating a SPNEGO_TOKEN structure or not
-#define SPNEGO_TOKEN_INTERNAL_COPYPTR 0
-#define SPNEGO_TOKEN_INTERNAL_COPYDATA 0x1
-
-// Internal flag dictates whether or not we will free the binary data when
-// the SPNEG_TOKEN structure is destroyed
-#define SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA 0x1
-
- //
-// Each SPNEGO Token Type can be broken down into a
-// maximum of 4 separate elements.
-//
-
-#define MAX_NUM_TOKEN_ELEMENTS 4
-
-//
-// Element offsets in the array
-//
-
-// INIT elements
-#define SPNEGO_INIT_MECHTYPES_ELEMENT 0
-#define SPNEGO_INIT_REQFLAGS_ELEMENT 1
-#define SPNEGO_INIT_MECHTOKEN_ELEMENT 2
-#define SPNEGO_INIT_MECHLISTMIC_ELEMENT 3
-
-// Response elements
-#define SPNEGO_TARG_NEGRESULT_ELEMENT 0
-#define SPNEGO_TARG_SUPPMECH_ELEMENT 1
-#define SPNEGO_TARG_RESPTOKEN_ELEMENT 2
-#define SPNEGO_TARG_MECHLISTMIC_ELEMENT 3
-
-//
-// Defines an individual SPNEGO Token Element.
-//
-
- typedef struct SpnegoElement {
- size_t nStructSize; // Size of the element structure
- int iElementPresent; // Is the field present? Must be either
- // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
- // SPNEGO_TOKEN_ELEMENT_AVAILABLE
-
- SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
-
- unsigned char type; // Data Type
-
- unsigned char *pbData; // Points to actual Data
-
- unsigned long nDatalength; // Actual Data Length
-
- } SPNEGO_ELEMENT;
-
-// Structure size in case we later choose to extend the structure
-#define SPNEGO_ELEMENT_SIZE sizeof(SPNEGO_ELEMENT)
-
-//
-// Packages a SPNEGO Token Encoding. There are two types of
-// encodings: NegTokenInit and NegTokenTarg. Each encoding can
-// contain up to four distinct, optional elements.
-//
-
- typedef struct SpnegoToken {
- size_t nStructSize; // Size of the Token structure
- unsigned long ulFlags; // Internal Structure Flags - Reserved!
- int ucTokenType; // Token Type - Must be
- // SPNEGO_TOKEN_INIT or
- // SPNEGO_TOKEN_TARG
-
- unsigned char *pbBinaryData; // Points to binary token data
-
- unsigned long ulBinaryDataLen; // Length of the actual binary data
- int nNumElements; // Number of elements
- SPNEGO_ELEMENT aElementArray[MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
- } SPNEGO_TOKEN;
-
-// Structure size in case we later choose to extend the structure
-#define SPNEGO_TOKEN_SIZE sizeof(SPNEGO_TOKEN)
-
-//
-// Function definitions
-//
-
- SPNEGO_TOKEN *AllocEmptySpnegoToken(unsigned char ucCopyData,
- unsigned long ulFlags, unsigned char *pbTokenData,
- unsigned long ulTokenSize);
- void FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
- void InitSpnegoTokenElementArray(SPNEGO_TOKEN * pSpnegoToken);
- int InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
- long *pnRemainingTokenLength, unsigned char **ppbFirstElement);
- int InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken,
- unsigned char *pbTokenData, long nRemainingTokenLength);
- int GetSpnegoInitTokenMechList(unsigned char *pbTokenData,
- int nMechListLength, SPNEGO_ELEMENT * pSpnegoElement);
- int InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
- int nElementLength, unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement);
- int InitSpnegoTokenElementFromOID(unsigned char *pbTokenData,
- int nElementLength, SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT * pSpnegoElement);
- int FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
- int ValidateMechList(unsigned char *pbMechListData, long nBoundaryLength);
- int CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long *plTokenSize, long *plInternalLength);
- int CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechTokenMIC, long *pnTokenSize, long *pnInternalTokenLength);
- int CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength);
- int CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength);
- int IsValidMechOid(SPNEGO_MECH_OID mechOid);
- int IsValidContextFlags(unsigned char ucContextFlags);
- int IsValidNegResult(SPNEGO_NEGRESULT negResult);
- int IsValidSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
- int IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement);
- int CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement);
- int InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN ** ppSpnegoToken);
-
- // C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-
-#endif