📄 derparse.c
字号:
// 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++;#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: { // 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -