2N/A * // Copyright (C) 2002 Microsoft Corporation 2N/A * // All rights reserved. 2N/A * // THIS CODE AND INFORMATION IS PROVIDED "AS IS" 2N/A * // WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 2N/A * // OR IMPLIED, INCLUDING BUT NOT LIMITED 2N/A * // TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY 2N/A * // AND/OR FITNESS FOR A PARTICULAR PURPOSE. 2N/A * // Date - 10/08/2002 2N/A * // Author - Sanj Surati 2N/A * SPNEGO Token Handler Source File 2N/A * as defined in DERPARSE.H. 2N/A * The GSS Mechanism OID enumeration values (SPNEGO_MECH_OID) control which 2N/A * offset in the array below, that a mechanism can be found. 2N/A {
"\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02",
11,
9,
2N/A {
"\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02",
11,
9,
2N/A {
"\x06\x06\x2b\x06\x01\x05\x05\x02",
8,
6,
2N/A {
"\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a",
12,
10,
2N/A * [in] pbLengthData - DER Length Data 2N/A * [in] nBoundaryLength - Length that value must not exceed. 2N/A * [out] pnLength - Filled out with length value 2N/A * [out] pnNumLengthBytes - Filled out with number of bytes 2N/A * consumed by DER length. 2N/A * int Success - SPNEGO_E_SUCCESS 2N/A * Failure - SPNEGO API Error code 2N/A * Interprets the data at pbLengthData as a DER length. The length must 2N/A * fit within the bounds of nBoundary length. We do not currently 2N/A * process lengths that take more than 4 bytes. 2N/A /* First check if the extended length bit is set */ 2N/A * Lower 7 bits contain number of trailing bytes that describe 2N/A * Check that the number of bytes we are about to read is within 2N/A * our boundary constraints 2N/A /* We won't deal with lengths greater than 4 bytes */ 2N/A /* 0 out the initial length */ 2N/A /* Bump by 1 byte */ 2N/A }
/* SWITCH ( nNumLengthBytes ) */ 2N/A * We are Big-Endian, so the length can be 2N/A * copied in from the source as is. Ensure that 2N/A * we adjust for the number of bytes we actually 2N/A /* Account for the initial length byte */ 2N/A }
/* IF Valid Length */ 2N/A }
/* IF num bytes to read is within the boundary length */ 2N/A * Extended bit is not set, so the length is in the value and 2N/A * the one byte describes the length. 2N/A * smbfs_ASNDerCheckToken 2N/A * [in] pbTokenData - Token Data 2N/A * [in] nToken - Token identifier to check for 2N/A * [in] nLengthWithToken - Expected token length (with data) 2N/A * [in] nBoundaryLength - Length that value must not exceed. 2N/A * [out] pnLength - Filled out with data length 2N/A * [out] pnTokenLength - Filled out with number of bytes 2N/A * consumed by token identifier and length. 2N/A * int Success - SPNEGO_E_SUCCESS 2N/A * Failure - SPNEGO API Error code 2N/A * Checks the data pointed to by pbTokenData for the specified token 2N/A * identifier and the length that immediately follows. If 2N/A * nLengthWithToken is > 0, the calculated length must match. The 2N/A * length must also not exceed the specified boundary length . 2N/A /* Make sure that we've at least got 2 bytes of room to work with */ 2N/A /* The 1st byte of token data MUST match the specified token */ 2N/A /* Next byte indicates the length */ 2N/A /* Get the length described by the token */ 2N/A * Verify that the length is LESS THAN the 2N/A * boundary length (this should prevent us 2N/A * walking out of our buffer) 2N/A /* Check that expected length matches */ 2N/A }
/* IF need to validate length */ 2N/A }
/* IF ASNDerGetLength */ 2N/A }
/* IF Boundary Length is at least 2 bytes */ 2N/A * smbfs_ASNDerCheckOID 2N/A * [in] pbTokenData - Token Data 2N/A * [in] nMechOID - OID we are looking for 2N/A * [in] nBoundaryLength - Length that value must not exceed. 2N/A * [out] pnTokenLength - Filled out with number of bytes 2N/A * consumed by token and data. 2N/A * int Success - SPNEGO_E_SUCCESS 2N/A * Failure - SPNEGO API Error code 2N/A * Checks the data pointed to by pbTokenData for the specified OID. 2N/A /* Verify that we have an OID token */ 2N/A /* Add the data length to the Token Length */ 2N/A * Token Lengths plus the actual length must match the length in 2N/A * our OID list element. If it doesn't, we're done. 2N/A /* Memcompare the token and the expected field */ 2N/A }
/* IF OID Token CHecks */ 2N/A * smbfs_ASNDerCalcNumLengthBytes 2N/A * [in] nLength - Length to calculate length bytes for. 2N/A * int Number of bytes necessary to represent length 2N/A * Helper function to calculate the number of length bytes necessary to 2N/A * represent a length value. For our purposes, a 32-bit value should be 2N/A * enough to describea length. 2N/A * A single byte will be sufficient for describing this length. 2N/A * The byte will simply contain the length 2N/A * Two bytes are necessary, one to say how many following bytes 2N/A * describe the length, and one to give the length 2N/A * Three bytes are necessary, one to say how many following 2N/A * bytes describe the length, and two to give the length. 2N/A * Four bytes are necessary, one to say how many following bytes 2N/A * describe the length, and three to give the length 2N/A * Five bytes are necessary, one to say how many following bytes 2N/A * describe the length, and four to give the length 2N/A * smbfs_ASNDerCalcTokenLength 2N/A * [in] nLength - Length to calculate length bytes for. 2N/A * [in] nDataLength - Actual Data length value. 2N/A * long Number of bytes necessary to represent a token, length and data 2N/A * Helper function to calculate a token and value size, based on a 2N/A * supplied length value, and any binary data that will need to be 2N/A * Add a byte to the length size to account for a single byte to 2N/A * hold the token type. 2N/A * smbfs_ASNDerCalcElementLength 2N/A * [in] nDataLength - Length of data. 2N/A * [out] pnInternalLength - Filled out with length of element 2N/A * without sequence info. 2N/A * long Number of bytes necessary to represent an element 2N/A * Helper function to calculate an element length. An element consists 2N/A * of a sequence token, a type token and then the data. 2N/A /* First the type token and the actual data */ 2N/A /* Internal length is the length without the element sequence token */ 2N/A * Next add in the element's sequence token (remember that its 2N/A * length is the total length of the type token and data) 2N/A * smbfs_ASNDerCalcMechListLength 2N/A * [in] mechoid - Mech OID to put in list. 2N/A * [out] pnInternalLength - Filled out with length of element 2N/A * without the primary sequence token. 2N/A * long Number of bytes necessary to represent a mechList 2N/A * Helper function to calculate a MechList length. A mechlist consists 2N/A * of a NegTokenInit sequence token, a sequence token for the MechList 2N/A * and finally a list of OIDs. In our case, we only really have one 2N/A /* Next add in a sequence token */ 2N/A /* Internal length is the length without the element sequence token */ 2N/A /* Finally add in the element's sequence token */ 2N/A * smbfs_ASNDerWriteLength 2N/A * [out] pbData - Buffer to write into. 2N/A * [in] nLength - Length to write out. 2N/A * int Number of bytes written out 2N/A * Helper function to write out a length value following DER rules . 2N/A /* Write out the number of bytes following which will be used */ 2N/A /* Point to where we'll actually write the length */ 2N/A * Cast the length to a single byte, since we 2N/A * know that it is 0x7F or less (or we wouldn't 2N/A * only need a single byte). 2N/A }
/* SWITCH ( nNumLengthBytes ) */ 2N/A * We are Big-Endian, so the length can be copied in from the 2N/A * source as is. Ensure that we adjust for the number of bytes 2N/A * Cast the length to a single byte, since we know that it 2N/A * is 0x7F or less (or we wouldn't only need a single byte). 2N/A * smbfs_ASNDerWriteToken 2N/A * [out] pbData - Buffer to write into. 2N/A * [in] ucType - Token Type 2N/A * [in] pbTokenValue - Actual Value 2N/A * [in] nLength - Length of Data. 2N/A * int Number of bytes written out 2N/A * Helper function to write out a token and any associated data. If 2N/A * pbTokenValue is non-NULL, then it is written out in addition to the 2N/A * token identifier and the length bytes. 2N/A /* Write out the type */ 2N/A /* Wrote 1 byte, and move data pointer */ 2N/A /* Write out the length and adjust the number of bytes written out */ 2N/A * Write out the token value if we got one. The assumption is that the 2N/A * nLength value indicates how many bytes are in pbTokenValue. 2N/A * smbfs_ASNDerWriteOID 2N/A * [out] pbData - Buffer to write into. 2N/A * [in] eMechOID - OID to write out. 2N/A * int Number of bytes written out 2N/A * Helper function to write out an OID. For these we have the raw bytes 2N/A * listed in a global structure. The caller simply indicates which OID 2N/A * should be written and we will splat out the data. 2N/A * smbfs_ASNDerWriteMechList 2N/A * [out] pbData - Buffer to write into. 2N/A * [in] eMechOID - OID to put in MechList. 2N/A * int Number of bytes written out 2N/A * Helper function to write out a MechList. A MechList consists of the 2N/A * Init Token Sequence, a sequence token and then the list of OIDs. In 2N/A * our case the OID is from a global array of known OIDs. 2N/A /* First get the length */ 2N/A /* Adjust the data pointer */ 2N/A * Now write the Sequence token and the OID (the OID is a BLOB in the 2N/A * smbfs_ASNDerWriteElement 2N/A * [out] pbData - Buffer to write into. 2N/A * [in] ucElementSequence - Sequence Token 2N/A * [in] ucType - Token Type 2N/A * [in] pbTokenValue - Actual Value 2N/A * [in] nLength - Length of Data. 2N/A * int Number of bytes written out 2N/A * Helper function to write out a SPNEGO Token element. An element 2N/A * consists of a sequence token, a type token and the associated data. 2N/A /* First get the length */ 2N/A /* Write out the sequence byte and the length of the type and data */ 2N/A /* Adjust the data pointer */ 2N/A /* Now write the type and the data. */