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

📄 crypt.h

📁 cryptlib安全工具包
💻 H
📖 第 1 页 / 共 3 页
字号:
   of getting an "out of stack" exception, it's turned into a no-op.  The 
   second time the last guard page is hit, the application is terminated by 
   the system, since it's passed its first-chance exception.

   A variation of this is that the calling app could be deliberately passing
   a pointer to a guard page and catching the guard page exception in order
   to dynamically generate the data that would fill the page (this can 
   happen for example when simulating a large address space with pointer 
   swizzling), but this is a pretty weird programming technique that's 
   unlikely to be used with a crypto library.

   A lesser problem is that there's a race condition in the checking, since
   the memory can be unmapped between the IsBadXxxPtr() check and the actual
   access, but you'd pretty much have to be trying to actively subvert the
   checks to do something like this.

   For these reasons we use these functions mostly for debugging, wrapping
   them up in assert()s.  Under Windows Vista, they've actually been turned
   into no-ops because of the above problems, although it's probable that
   they'll be replaced by a code to check for NULL pointers, since
   Microsoft's docs indicate that this much checking will still be done.  If
   necessary we could also replace the no-op'd out versions with the 
   equivalent code:

	inline BOOL IsBadReadPtr( const VOID *lp, UINT_PTR ucb )
		{
		__try { memcmp( p, p, cb ); }
		__except( EXCEPTION_EXECUTE_HANDLER ) { return( FALSE ); }
		return( TRUE );
		}

	inline BOOL IsBadWritePtr( LPVOID lp, UINT_PTR ucb )
		{
		__try { memset( p, 0, cb ); }
		__except( EXCEPTION_EXECUTE_HANDLER ) { return( FALSE ); }
		return( TRUE );
		} */

#if ( defined( __WIN32__ ) || defined( __WINCE__ ) ) && 1
  #define isReadPtr( ptr, size )	( ( ptr ) != NULL && ( size ) > 0 && \
									  !IsBadReadPtr( ( ptr ), ( size ) ) )
  #define isWritePtr( ptr, size )	( ( ptr ) != NULL && ( size ) > 0 && \
									  !IsBadWritePtr( ( ptr ), ( size ) ) )
#else
  #define isReadPtr( ptr, size )	( ( ptr ) != NULL && ( size ) > 0 )
  #define isWritePtr( ptr, size )	( ( ptr ) != NULL && ( size ) > 0 )
#endif /* Pointer check macros */

/* Clear/set object error information */

#define clearErrorInfo( objectInfoPtr ) \
	{ \
	( objectInfoPtr )->errorLocus = CRYPT_ATTRIBUTE_NONE; \
	( objectInfoPtr )->errorType = CRYPT_OK; \
	}

#define setErrorInfo( objectInfoPtr, locus, type ) \
	{ \
	( objectInfoPtr )->errorLocus = locus; \
	( objectInfoPtr )->errorType = type; \
	}

/****************************************************************************
*																			*
*								Internal API Functions						*
*																			*
****************************************************************************/

/* Pull in the internal API function definitions and prototypes */

#if defined( INC_ALL )
  #include "int_api.h"
#else
  #include "misc/int_api.h"
#endif /* Compiler-specific includes */

/****************************************************************************
*																			*
*								Debugging Functions							*
*																			*
****************************************************************************/

/* When we encounter an internal consistency check failure, we usually want
   to display some sort of message telling the user that something has gone
   catastrophically wrong, however people probably don't want klaxons going
   off when there's a problem in production code so we only enable it in
   debug versions.  The command-line makefile by default builds release
   versions, so in practice the warn-the-user action is only taken under
   Windows unless the user explicitly enables the use of assertions */

#if defined( __WINCE__ ) && _WIN32_WCE < 400
#if 0
  /* Older WinCE environments don't support assert() because there's no
     console and no other support for it in the runtime (the documentation
	 claims there's at least an _ASSERT available, but this isn't present
	 in many systems such as PocketPC), so we use it if it's available and
	 otherwise kludge it using NKDbgPrintfW() */
  #ifndef _ASSERTE
	#ifdef NDEBUG
	  #define _ASSERTE( x )
	#else
	  #define _ASSERTE( expr )	( void )( ( expr ) || ( NKDbgPrintfW( #expr ) ) )
	#endif /* Debug vs. non-debug builds */
  #endif /* _ASSERTE available */
  #define assert( expr )	_ASSERTE( expr )
#else
  /* Older WinCE environments don't support assert() because there's no
     console and no other support for it in the runtime (the documentation
	 claims there's at least an _ASSERT available, but this isn't present
	 in many systems such as PocketPC), so we build our own assert() from
	 DEBUGMSG().  Note that (in theory) the version check isn't reliable
	 since we should be checking for the development environment version
	 rather than the target OS version, however in practice compiler/SDK
	 version == OS version unless you seriously enjoy pain, and in any case
	 it's not really possible to differentiate between eVC++ 3.0 and 4.0 -
	 the SHx, MIPS, and ARM compilers at least report 120{1|2} for 3.0 and
	 1200 for 3.0, but the x86 compiler reports 1200 for both 3.0 and 4.0
	 even though it's a different build, 0.8168 vs. 0.8807 */
  #ifdef NDEBUG
	#define assert( x )
  #else
	#define assert( x )		\
			DEBUGMSG( !( x ), ( TEXT( "Assert failed in %s line %d: %s" ), TEXT( __FILE__ ), __LINE__, TEXT( #x ) ) )
  #endif /* Debug vs. non-debug builds */
#endif /* 0 */
#else
  #include <assert.h>
#endif /* Systems without assert() */
#define DEBUG_WARN	0	/* Force an assertion failure via assert( DEBUG_WARN ) */

/* Output an I-am-here to stdout, useful when tracing errors in code without 
   debug symbols available */

#if defined( __GNUC__ ) || ( defined( _MSC_VER ) && VC_GE_2005( _MSC_VER ) )
  /* Older version of gcc don't support the current syntax */
  #if defined( __GNUC__ ) && ( __STDC_VERSION__ < 199901L )
	#if __GNUC__ >= 2
	  #define __FUNCTION__	__func__ 
	#else
	  #define __FUNCTION__	"<unknown>"
	#endif /* gcc 2.x or newer */
  #endif /* gcc without __func__ support */

  #define DEBUG_ENTER()	printf( "Enter %s %s %d.\n", __FILE__, __FUNCTION__, __LINE__ )
  #define DEBUG_IN()	printf( "In    %s %s %d.\n", __FILE__, __FUNCTION__, __LINE__ )
  #define DEBUG_EXIT()	printf( "Exit  %s %s %d, status %d.\n", __FILE__, __FUNCTION__, __LINE__, status )
#else
  #define DEBUG_ENTER()	printf( "Enter %s %d.\n", __FILE__, __LINE__ )
  #define DEBUG_IN()	printf( "In    %s %d.\n", __FILE__, __LINE__ )
  #define DEBUG_EXIT()	printf( "Exit  %s %d, status %d.\n", __FILE__, __LINE__, status )
#endif /* Compiler-specific diagnotics */

/* Dump a PDU to disk and create a hex dump of the first n bytes of a buffer 
   along with the length and a checksum of the entire buffer.  As a safeguard 
   these only work in the Win32 debug version to prevent them from being 
   accidentally enabled in any release version */

#if defined( __WIN32__ ) && !defined( NDEBUG )
  #ifdef __STDC_LIB_EXT1__
	#define OPEN_FILE( filePtr, fileName ) \
			if( fopen_s( &filePtr, fileName, "wb" ) != 0 ) \
				filePtr = NULL
  #else
	#define OPEN_FILE( filePtr, fileName ) \
			filePtr = fopen( fileName, "wb" )
  #endif /* __STDC_LIB_EXT1__ */

  #define DEBUG_DUMP( name, data, length ) \
	{ \
	FILE *filePtr; \
	char fileName[ 1024 ]; \
	\
	GetTempPath( 512, fileName ); \
	strlcat_s( fileName, 1024, name ); \
	strlcat_s( fileName, 1024, ".der" ); \
	\
	OPEN_FILE( filePtr, fileName ); \
	if( filePtr != NULL ) \
		{ \
		if( length > 0 ) \
			fwrite( data, 1, length, filePtr ); \
		fclose( filePtr ); \
		} \
	}

  #define DEBUG_DUMP_CERT( name, cert ) \
	{ \
	RESOURCE_DATA msgData; \
	FILE *filePtr; \
	char fileName[ 1024 ]; \
	BYTE certData[ 2048 ]; \
	\
	GetTempPath( 512, fileName ); \
	strlcat_s( fileName, 1024, name ); \
	strlcat_s( fileName, 1024, ".der" ); \
	\
	OPEN_FILE( filePtr, fileName ); \
	if( filePtr != NULL ) \
		{ \
		setMessageData( &msgData, certData, 2048 ); \
		status = krnlSendMessage( cert, IMESSAGE_CRT_EXPORT, &msgData, \
								  CRYPT_CERTFORMAT_CERTIFICATE ); \
		if( cryptStatusOK( status ) ) \
			fwrite( msgData.data, 1, msgData.length, filePtr ); \
		fclose( filePtr ); \
		} \
	}

  /* The use of a memory buffer is to allow the hex dump to be performed 
     from multiple threads without them fighting over stdout */
  #define DEBUG_DUMPHEX( dumpPrefix, dumpBuf, dumpLen ) \
	{ \
	char dumpBuffer[ 128 ]; \
	int offset, i, j; \
	\
	offset = sprintf( dumpBuffer, "%4s %4d %04X ", dumpPrefix, dumpLen, \
					  checksumData( dumpBuf, dumpLen ) ); \
	for( i = 0; i < dumpLen; i += 16 ) \
		{ \
		const int innerLen = min( dumpLen - i, 16 ); \
		\
		if( i > 0 ) \
			offset = sprintf( dumpBuffer, "%4s           ", \
							  dumpPrefix ); \
		for( j = 0; j < innerLen; j++ ) \
			offset += sprintf( dumpBuffer + offset, "%02X ", \
							   ( ( BYTE * ) dumpBuf )[ i + j ] ); \
		for( ; j < 16; j++ ) \
			offset += sprintf( dumpBuffer + offset, "   " ); \
		for( j = 0; j < innerLen; j++ ) \
			{ \
			const BYTE ch = ( ( BYTE * ) dumpBuf )[ i + j ]; \
			\
			offset += sprintf( dumpBuffer + offset, "%c", \
							   isprint( ch ) ? ch : '.' ); \
			} \
		puts( dumpBuffer ); \
		} \
	fflush( stdout ); \
	}
#else
  #define DEBUG_DUMP( name, data, length )
  #define DEBUG_DUMP_CERT( name, data, length )
  #define DEBUG_DUMPHEX( dumpPrefix, dumpBuf, dumpLen )
#endif /* Win32 debug */

/* Dump a trace of a double-linked list */

#define DEBUG_DUMP_LIST( label, listHead, listTail, listType ) \
		{ \
		listType *listPtr; \
		\
		printf( "%s: Walking list beginning at %lX.\n", \
				label, ( listHead ) ); \
		for( listPtr = ( listHead ); \
			 listPtr != NULL; listPtr = listPtr->next ) \
			{ \
			printf( "  Ptr = %lX, prev = %lX, next = %lX.\n", \
					listPtr, listPtr->prev, listPtr->next ); \
			} \
		if( ( listHead ) != NULL ) \
			printf( "  List tail = %lX.\n", ( listTail ) ); \
		printf( "Finished walking list beginning at %lX.\n", ( listHead ) ); \
		}

/* In order to debug memory usage, we can define CONFIG_DEBUG_MALLOC to dump
   memory usage diagnostics to stdout (this would usually be done in the
   makefile).  Without this, the debug malloc just becomes a standard malloc.
   Note that crypt/osconfig.h contains its own debug-malloc() handling for
   the OpenSSL-derived code enabled via USE_BN_DEBUG_MALLOC in osconfig.h,
   and zlib also has its own allocation code (which isn't instrumented for
   diagnostic purposes).

   In addition in order to control on-demand allocation of buffers for
   larger-than-normal data items, we can define CONFIG_NO_DYNALLOC to
   disable this allocation.  This is useful in memory-constrained
   environments where we can't afford to grab chunks of memory at random */

#ifdef CONFIG_DEBUG_MALLOC
  #undef clAlloc
  #undef clFree
  #define clAlloc( string, size ) \
		  clAllocFn( __FILE__, ( string ), __LINE__, ( size ) )
  #define clFree( string, memblock ) \
		  clFreeFn( __FILE__, ( string ), __LINE__, ( memblock ) )
  void *clAllocFn( const char *fileName, const char *fnName,
				   const int lineNo, size_t size );
  void clFreeFn( const char *fileName, const char *fnName,
				 const int lineNo, void *memblock );
#else
  #define clAlloc( string, size )		malloc( size )
  #define clFree( string, memblock )	free( memblock )
#endif /* !CONFIG_DEBUG_MALLOC */
#ifdef CONFIG_NO_DYNALLOC
  #define clDynAlloc( string, size )	NULL
#else
  #define clDynAlloc( string, size )	clAlloc( string, size )
#endif /* CONFIG_NO_DYNALLOC */

#endif /* _CRYPT_DEFINED */

⌨️ 快捷键说明

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