⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 derparse.c

📁 代理服务器 squid-2.6.STABLE16
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 <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++;   #ifdef __LITTLE_ENDIAN__            // 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;      }}///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -