12b65585e720714b31036daaa2b30eb76014048eGordon Ross// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Copyright (C) 2002 Microsoft Corporation
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// OR IMPLIED, INCLUDING BUT NOT LIMITED
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Date - 10/08/2002
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Author - Sanj Surati
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// DERPARSE.C
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// SPNEGO Token Handler Source File
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Contains implementation of ASN.1 DER read/write functions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// as defined in DERPARSE.H.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdlib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdio.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <memory.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/byteorder.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "spnego.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "derparse.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// The GSS Mechanism OID enumeration values (SPNEGO_MECH_OID) control which offset in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// the array below, that a mechanism can be found.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#pragma error_messages (off,E_INITIALIZATION_TYPE_MISMATCH)
4bff34e37def8a90f9194d81bc345c52ba20086athurlowMECH_OID g_stcMechOIDList [] =
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe {(unsigned char *)"\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02",
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe 11, 9, spnego_mech_oid_Kerberos_V5_Legacy}, // 1.2.840.48018.1.2.2
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe {(unsigned char *)"\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02",
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe 11, 9, spnego_mech_oid_Kerberos_V5}, // 1.2.840.113554.1.2.2
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe {(unsigned char *)"\x06\x06\x2b\x06\x01\x05\x05\x02",
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe 8, 6, spnego_mech_oid_Spnego}, // 1.3.6.1.5.5.2
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe {(unsigned char *)"\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a",
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe 12, 10, spnego_mech_oid_NTLMSSP}, // 1.3.6.1.4.1.311.2.2.10
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe {(unsigned char *)"", 0, 0, spnego_mech_oid_NotUsed // Placeholder
228c5c17dd30d7640072462f5334f96835507e11Richard Lowe }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow};
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#pragma error_messages (default,E_INITIALIZATION_TYPE_MISMATCH)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerGetLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbLengthData - DER Length Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nBoundaryLength - Length that value must not exceed.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnLength - Filled out with length value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnNumLengthBytes - Filled out with number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// consumed by DER length.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Interprets the data at pbLengthData as a DER length. The length must
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// fit within the bounds of nBoundary length. We do not currently
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// process lengths that take more than 4 bytes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pnLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnNumLengthBytes )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nNumLengthBytes = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // First check if the extended length bit is set
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( *pbLengthData & LEN_XTND )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Lower 7 bits contain the number of trailing bytes that describe the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nNumLengthBytes = *pbLengthData & LEN_MASK;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check that the number of bytes we are about to read is within our boundary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // constraints
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nNumLengthBytes <= nBoundaryLength - 1 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // For now, our handler won't deal with lengths greater than 4 bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nNumLengthBytes >= 1 && nNumLengthBytes <= 4 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // 0 out the initial length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Bump by 1 byte
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbLengthData++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow #ifdef _LITTLE_ENDIAN
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // There may be a cleaner way to do this, but for now, this seems to be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // an easy way to do the transformation
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch ( nNumLengthBytes )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 1:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) ) = *pbLengthData;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 2:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 3:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 4:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 3);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData + 2);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // SWITCH ( nNumLengthBytes )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow #else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We are Big-Endian, so the length can be copied in from the source
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // as is. Ensure that we adjust for the number of bytes we actually
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // copy.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow memcpy( ( (unsigned char *) pnLength ) + ( 4 - nNumLengthBytes ),
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbLengthData, nNumLengthBytes );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow #endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Account for the initial length byte
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnNumLengthBytes = nNumLengthBytes + 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Valid Length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF num bytes to read is within the boundary length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF xtended length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Extended bit is not set, so the length is in the value and the one
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // byte describes the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnLength = *pbLengthData & LEN_MASK;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnNumLengthBytes = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_SUCCESS;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCheckToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Token Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nToken - Token identifier to check for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLengthWithToken - Expected token length (with data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nBoundaryLength - Length that value must not exceed.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnLength - Filled out with data length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnTokenLength - Filled out with number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// consumed by token identifier and length.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks the data pointed to by pbTokenData for the specified token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// identifier and the length that immediately follows. If
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// nLengthWithToken is > 0, the calculated length must match. The
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// length must also not exceed the specified boundary length .
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLengthWithToken, long nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnLength, long* pnTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nNumLengthBytes = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Make sure that we've at least got 2 bytes of room to work with
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nBoundaryLength >= 2 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The first byte of the token data MUST match the specified token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( *pbTokenData == nToken )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next byte indicates the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbTokenData++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Get the length described by the token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerGetLength( pbTokenData, nBoundaryLength, pnLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nNumLengthBytes ) ) == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Verify that the length is LESS THAN the boundary length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // (this should prevent us walking out of our buffer)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nBoundaryLength - ( nNumLengthBytes + 1 ) < *pnLength ) )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // If we were passed a length to check, do so now
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nLengthWithToken > 0L )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Check that the expected length matches
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nLengthWithToken - ( nNumLengthBytes + 1 ) ) != *pnLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_INVALID_LENGTH;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF need to validate length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( SPNEGO_E_SUCCESS == nReturn )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnTokenLength = nNumLengthBytes + 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF ASNDerGetLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF token matches
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF Boundary Length is at least 2 bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCheckOID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenData - Token Data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nMechOID - OID we are looking for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nBoundaryLength - Length that value must not exceed.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnTokenLength - Filled out with number of bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// consumed by token and data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Success - SPNEGO_E_SUCCESS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Failure - SPNEGO API Error code
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Checks the data pointed to by pbTokenData for the specified OID.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long* pnTokenLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nReturn = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Verify that we have an OID token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID, 0L, nBoundaryLength,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &nLength, pnTokenLength ) ) == SPNEGO_E_SUCCESS )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Add the data length to the Token Length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnTokenLength += nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Token Lengths plus the actual length must match the length in our OID list element.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // If it doesn't, we're done
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( *pnTokenLength == g_stcMechOIDList[nMechOID].iLen )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Memcompare the token and the expected field
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( memcmp( pbTokenData, g_stcMechOIDList[nMechOID].ucOid, *pnTokenLength ) != 0 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_UNEXPECTED_OID;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nReturn = SPNEGO_E_UNEXPECTED_OID;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF OID Token CHecks
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nReturn;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCalcNumLengthBytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLength - Length to calculate length bytes for.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes necessary to represent length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to calculate the number of length bytes necessary to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// represent a length value. For our purposes, a 32-bit value should be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// enough to describea length.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerCalcNumLengthBytes( long nLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nLength <= 0x7F )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // A single byte will be sufficient for describing this length.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // The byte will simply contain the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else if ( nLength <= 0xFF )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Two bytes are necessary, one to say how many following bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // describe the length, and one to give the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else if ( nLength <= 0xFFFF )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Three bytes are necessary, one to say how many following bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // describe the length, and two to give the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return 3;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else if ( nLength <= 0xFFFFFF )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Four bytes are necessary, one to say how many following bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // describe the length, and three to give the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return 4;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Five bytes are necessary, one to say how many following bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // describe the length, and four to give the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return 5;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCalcTokenLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLength - Length to calculate length bytes for.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nDataLength - Actual Data length value.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// long Number of bytes necessary to represent a token, length and data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to calculate a token and value size, based on a
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// supplied length value, and any binary data that will need to be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// written out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowlong ASNDerCalcTokenLength( long nLength, long nDataLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Add a byte to the length size to account for a single byte to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // hold the token type.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalLength = ASNDerCalcNumLengthBytes( nLength ) + 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nTotalLength + nDataLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCalcElementLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nDataLength - Length of data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnInternalLength - Filled out with length of element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// without sequence info.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// long Number of bytes necessary to represent an element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to calculate an element length. An element consists
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// of a sequence token, a type token and then the data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowlong ASNDerCalcElementLength( long nDataLength, long* pnInternalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // First the type token and the actual data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTotalLength = ASNDerCalcTokenLength( nDataLength, nDataLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Internal length is the length without the element sequence token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pnInternalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pnInternalLength = nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Next add in the element's sequence token (remember that its
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // length is the total length of the type token and data)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerCalcMechListLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] mechoid - Mech OID to put in list.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pnInternalLength - Filled out with length of element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// without the primary sequence token.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// long Number of bytes necessary to represent a mechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to calculate a MechList length. A mechlist consists
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// of a NegTokenInit sequence token, a sequence token for the MechList
12b65585e720714b31036daaa2b30eb76014048eGordon Ross// and finally a list of OIDs.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Rosslong ASNDerCalcMechListLength( SPNEGO_MECH_OID *mechOidLst, int mechOidCnt,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long* pnInternalLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // First the OID
12b65585e720714b31036daaa2b30eb76014048eGordon Ross SPNEGO_MECH_OID oid_idx;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long nTotalLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross int i;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTotalLength = 0;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross for (i = 0; i < mechOidCnt; i++) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross oid_idx = mechOidLst[i];
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTotalLength += g_stcMechOIDList[oid_idx].iLen;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Next add in a sequence token
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Internal length is the length without the element sequence token
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if ( NULL != pnInternalLength )
12b65585e720714b31036daaa2b30eb76014048eGordon Ross {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross *pnInternalLength = nTotalLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Finally add in the element's sequence token
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross return nTotalLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerWriteLength
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbData - Buffer to write into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLength - Length to write out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to write out a length value following DER rules .
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerWriteLength( unsigned char* pbData, long nLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nNumBytesRequired = ASNDerCalcNumLengthBytes( nLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nNumLengthBytes = nNumBytesRequired - 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( nNumBytesRequired > 1 )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Write out the number of bytes following which will be used
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = (unsigned char ) ( LEN_XTND | nNumLengthBytes );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Point to where we'll actually write the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbData++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#ifdef _LITTLE_ENDIAN
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // There may be a cleaner way to do this, but for now, this seems to be
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // an easy way to do the transformation
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch ( nNumLengthBytes )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 1:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Cast the length to a single byte, since we know that it
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is 0x7F or less (or we wouldn't only need a single byte).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = (unsigned char) nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 2:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = *( ( (unsigned char*) &nLength ) + 1 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 1) = *( ( (unsigned char*) &nLength ) );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 3:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = *( ( (unsigned char*) &nLength ) + 3 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 2) = *( ( (unsigned char*) &nLength ) );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 4:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = *( ( (unsigned char*) &nLength ) + 3 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 2) = *( ( (unsigned char*) &nLength ) + 1 );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *( pbData + 3) = *( ( (unsigned char*) &nLength ) );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // SWITCH ( nNumLengthBytes )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // We are Big-Endian, so the length can be copied in from the source
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // as is. Ensure that we adjust for the number of bytes we actually
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // copy.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow memcpy( pbData,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ( (unsigned char *) &nLength ) + ( 4 - nNumLengthBytes ), nNumLengthBytes );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } // IF > 1 byte for length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow else
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Cast the length to a single byte, since we know that it
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // is 0x7F or less (or we wouldn't only need a single byte).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = (unsigned char) nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nNumBytesRequired;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerWriteToken
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbData - Buffer to write into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucType - Token Type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenValue - Actual Value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLength - Length of Data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to write out a token and any associated data. If
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// pbTokenValue is non-NULL, then it is written out in addition to the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// token identifier and the length bytes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char* pbTokenValue, long nLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nTotalBytesWrittenOut = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int nNumLengthBytesWritten = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Write out the type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *pbData = ucType;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Wrote 1 byte, and move data pointer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWrittenOut++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbData++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Now write out the length and adjust the number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nNumLengthBytesWritten = ASNDerWriteLength( pbData, nLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWrittenOut += nNumLengthBytesWritten;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbData += nNumLengthBytesWritten;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Write out the token value if we got one. The assumption is that the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // nLength value indicates how many bytes are in pbTokenValue.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ( NULL != pbTokenValue )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow memcpy( pbData, pbTokenValue, nLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTotalBytesWrittenOut += nLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nTotalBytesWrittenOut;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerWriteOID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbData - Buffer to write into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] eMechOID - OID to write out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to write out an OID. For these we have the raw bytes
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// listed in a global structure. The caller simply indicates which OID
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// should be written and we will splat out the data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if (pbData != NULL) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross memcpy( pbData, g_stcMechOIDList[eMechOID].ucOid,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross g_stcMechOIDList[eMechOID].iLen );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross return g_stcMechOIDList[eMechOID].iLen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerWriteMechList
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbData - Buffer to write into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] eMechOID - OID to put in MechList.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to write out a MechList. A MechList consists of the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Init Token Sequence, a sequence token and then the list of OIDs. In
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// our case the OID is from a global array of known OIDs.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Rosslong ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID *mechOidLst, int mechOidCnt )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // First get the length
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long nInternalLength = 0L;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long nMechListLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross long nTempLength = 0L;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross int i;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nMechListLength = ASNDerCalcMechListLength(mechOidLst, mechOidCnt, &nInternalLength);
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength = ASNDerWriteToken( pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow NULL, nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Adjust the data pointer
12b65585e720714b31036daaa2b30eb76014048eGordon Ross pbData += nTempLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nInternalLength -= nTempLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // Now write the Sequence token and the OID (the OID is a BLOB in the global
12b65585e720714b31036daaa2b30eb76014048eGordon Ross // structure.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength = ASNDerWriteToken( pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
12b65585e720714b31036daaa2b30eb76014048eGordon Ross NULL, nInternalLength);
12b65585e720714b31036daaa2b30eb76014048eGordon Ross pbData += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross for (i = 0; i < mechOidCnt; i++) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross nTempLength = ASNDerWriteOID( pbData, mechOidLst[i] );
12b65585e720714b31036daaa2b30eb76014048eGordon Ross pbData += nTempLength;
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
12b65585e720714b31036daaa2b30eb76014048eGordon Ross return nMechListLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Function:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// ASNDerWriteElement
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Parameters:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [out] pbData - Buffer to write into.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucElementSequence - Sequence Token
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] ucType - Token Type
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] pbTokenValue - Actual Value
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// [in] nLength - Length of Data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Returns:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// int Number of bytes written out
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Comments :
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// Helper function to write out a SPNEGO Token element. An element
4bff34e37def8a90f9194d81bc345c52ba20086athurlow// consists of a sequence token, a type token and the associated data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow//
4bff34e37def8a90f9194d81bc345c52ba20086athurlow////////////////////////////////////////////////////////////////////////////
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow unsigned char ucType, unsigned char* pbTokenValue, long nLength )
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // First get the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nInternalLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nElementLength = ASNDerCalcElementLength( nLength, &nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow long nTempLength = 0L;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Write out the sequence byte and the length of the type and data
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbData, ucElementSequence, NULL, nInternalLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Adjust the data pointer
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbData += nTempLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow // Now write the type and the data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow nTempLength = ASNDerWriteToken( pbData, ucType, pbTokenValue, nLength );
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return nElementLength;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}