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

📄 dumpasn1.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* __UNIX__ */
	if( strlen( path ) < FILENAME_MAX - 13 && namePos != NULL )
		{
		strcpy( buffer, path );
		strcpy( buffer + ( int ) ( namePos - ( char * ) path ), CONFIG_NAME );
		if( testConfigPath( buffer ) )
			return( readConfig( buffer, TRUE ) );
		}

	/* Now try each of the possible absolute locations for the config file */
	for( i = 0; configPaths[ i ] != NULL; i++ )
		{
		buildConfigPath( buffer, configPaths[ i ] );
		if( testConfigPath( buffer ) )
			return( readConfig( buffer, TRUE ) );
		}

#ifdef __UNIX__
	/* On Unix systems we can also search for the config file on $PATH */
	if( ( envPath = getenv( "PATH" ) ) != NULL )
		{
		char *pathPtr = strtok( envPath, ":" );

		do
			{
			sprintf( buffer, "%s/%s", pathPtr, CONFIG_NAME );
			if( testConfigPath( buffer ) )
				return( readConfig( buffer, TRUE ) );
			pathPtr = strtok( NULL, ":" );
			}
		while( pathPtr != NULL );
		}
#endif /* __UNIX__ */

	/* Default to just the config name (which should fail as it was the
	   first entry in configPaths[]).  readConfig() will display the
	   appropriate warning */
	return( readConfig( CONFIG_NAME, TRUE ) );
	}

/****************************************************************************
*																			*
*							Output/Formatting Routines						*
*																			*
****************************************************************************/

#ifdef __OS390__

static int asciiToEbcdic( const int ch )
	{
	char convBuffer[ 2 ];

	convBuffer[ 0 ] = ch;
	convBuffer[ 1 ] = '\0';
	__atoe( convBuffer ); /* Convert ASCII to EBCDIC for 390 */
	return( convBuffer[ 0 ] );
	}
#endif /* __OS390__ */

/* Indent a string by the appropriate amount */

static void doIndent( const int level )
	{
	int i;

	for( i = 0; i < level; i++ )
		fprintf( output, printDots ? ". " : \
						 shallowIndent ? " " : "  " );
	}

/* Complain about an error in the ASN.1 object */

static void complain( const char *message, const int level )
	{
	if( !doPure )
		fprintf( output, INDENT_STRING );
	doIndent( level + 1 );
	fprintf( output, "Error: %s.\n", message );
	noErrors++;
	}

/* Dump data as a string of hex digits up to a maximum of 128 bytes */

static void dumpHex( FILE *inFile, long length, int level, int isInteger )
	{
	const int lineLength = ( dumpText ) ? 8 : 16;
	char printable[ 9 ];
	long noBytes = length;
	int zeroPadded = FALSE, warnPadding = FALSE, warnNegative = isInteger;
	int singleLine = FALSE;
	int maxLevel = ( doPure ) ? 15 : 8, prevCh = -1, i;

	/* Check if LHS status info + indent + "OCTET STRING" string + data will
	   wrap */
	if( ( ( doPure ) ? 0 : INDENT_SIZE ) + ( level * 2 ) + 12 + \
		( length * 3 ) < outputWidth )
		singleLine = TRUE;

	if( noBytes > 128 && !printAllData )
		noBytes = 128;	/* Only output a maximum of 128 bytes */
	if( level > maxLevel )
		level = maxLevel;	/* Make sure that we don't go off edge of screen */
	printable[ 8 ] = printable[ 0 ] = '\0';
	for( i = 0; i < noBytes; i++ )
		{
		int ch;

		if( !( i % lineLength ) )
			{
			if( singleLine )
				fputc( ' ', output );
			else
				{
				if( dumpText )
					{
					/* If we're dumping text alongside the hex data, print
					   the accumulated text string */
					fputs( "    ", output );
					fputs( printable, output );
					}
				fputc( '\n', output );
				if( !doPure )
					fprintf( output, INDENT_STRING );
				doIndent( level + 1 );
				}
			}
		ch = getc( inFile );
		fprintf( output, "%s%02X", i % lineLength ? " " : "", ch );
		printable[ i % 8 ] = ( ch >= ' ' && ch < 127 ) ? ch : '.';
		fPos++;

		/* If we need to check for negative values and zero padding, check
		   this now */
		if( i == 0 )
			{
			prevCh = ch;
			if( !ch )
				zeroPadded = TRUE;
			if( !( ch & 0x80 ) )
				warnNegative = FALSE;
			}
		if( i == 1 )
			{
			/* Check for the first 9 bits being identical */
			if( ( prevCh == 0x00 ) && ( ( ch & 0x80 ) == 0x00 ) )
				warnPadding = TRUE;
			if( ( prevCh == 0xFF ) && ( ( ch & 0x80 ) == 0x80 ) )
				warnPadding = TRUE;
			}
		}
	if( dumpText )
		{
		/* Print any remaining text */
		i %= lineLength;
		printable[ i ] = '\0';
		while( i < lineLength )
			{
			fprintf( output, "   " );
			i++;
			}
		fputs( "    ", output );
		fputs( printable, output );
		}
	if( length > 128 && !printAllData )
		{
		length -= 128;
		fputc( '\n', output );
		if( !doPure )
			fprintf( output, INDENT_STRING );
		doIndent( level + 5 );
		fprintf( output, "[ Another %ld bytes skipped ]", length );
		fPos += length;
		if( useStdin )
			{
			while( length-- )
				getc( inFile );
			}
		else
			fseek( inFile, length, SEEK_CUR );
		}
	fputs( "\n", output );

	if( isInteger )
		{
		if( warnPadding )
			complain( "Integer has non-DER encoding", level );
		if( warnNegative )
			complain( "Integer has a negative value", level );
		}
	}

/* Dump a bitstring, reversing the bits into the standard order in the
   process */

static void dumpBitString( FILE *inFile, const int length, const int unused,
						   const int level )
	{
	unsigned int bitString = 0, currentBitMask = 0x80, remainderMask = 0xFF;
	int bitFlag, value = 0, noBits, bitNo = -1, i;
	char *errorStr = NULL;

	if( unused < 0 || unused > 7 )
		complain( "Invalid number of unused bits", level );
	noBits = ( length * 8 ) - unused;

	/* ASN.1 bitstrings start at bit 0, so we need to reverse the order of
	   the bits if necessary */
	if( length )
		{
		bitString = fgetc( inFile );
		fPos++;
		}
	for( i = noBits - 8; i > 0; i -= 8 )
		{
		bitString = ( bitString << 8 ) | fgetc( inFile );
		currentBitMask <<= 8;
		remainderMask = ( remainderMask << 8 ) | 0xFF;
		fPos++;
		}
	if( reverseBitString )
		{
		for( i = 0, bitFlag = 1; i < noBits; i++ )
			{
			if( bitString & currentBitMask )
				value |= bitFlag;
			if( !( bitString & remainderMask ) )
				{
				/* The last valid bit should be a one bit */
				errorStr = "Spurious zero bits in bitstring";
				}
			bitFlag <<= 1;
			bitString <<= 1;
			}
		if( noBits < sizeof( int ) && \
			( ( remainderMask << noBits ) & value ) )
			{
			/* There shouldn't be any bits set after the last valid one.  We
			   have to do the noBits check to avoid a fencepost error when
			   there's exactly 32 bits */
			errorStr = "Spurious one bits in bitstring";
			}
		}
	else
		value = bitString;

	/* Now that it's in the right order, dump it.  If there's only one bit
	   set (which is often the case for bit flags) we also print the bit
	   number to save users having to count the zeroes to figure out which
	   flag is set */
	fputc( '\n', output );
	if( !doPure )
		fprintf( output, INDENT_STRING );
	doIndent( level + 1 );
	fputc( '\'', output );
	if( reverseBitString )
		currentBitMask = 1 << ( noBits - 1 );
	for( i = 0; i < noBits; i++ )
		{
		if( value & currentBitMask )
			{
			bitNo = ( bitNo == -1 ) ? ( noBits - 1 ) - i : -2;
			fputc( '1', output );
			}
		else
			fputc( '0', output );
		currentBitMask >>= 1;
		}
	if( bitNo >= 0 )
		fprintf( output, "'B (bit %d)\n", bitNo );
	else
		fputs( "'B\n", output );

	if( errorStr != NULL )
		complain( errorStr, level );
	}

/* Display data as a text string up to a maximum of 240 characters (8 lines
   of 48 chars to match the hex limit of 8 lines of 16 bytes) with special
   treatement for control characters and other odd things that can turn up
   in BMPString and UniversalString types.

   If the string is less than 40 chars in length, we try to print it on the
   same line as the rest of the text (even if it wraps), otherwise we break
   it up into 48-char chunks in a somewhat less nice text-dump format */

static void displayString( FILE *inFile, long length, int level,
						   STR_OPTION strOption )
	{
	char timeStr[ 64 ];
#ifdef __OS390__
	char convBuffer[ 2 ];
#endif /* __OS390__ */
	long noBytes = length;
	int lineLength = 48, maxLevel = ( doPure ) ? 15 : 8, i;
	int firstTime = TRUE, doTimeStr = FALSE, warnIA5 = FALSE;
	int warnPrintable = FALSE, warnTime = FALSE, warnBMP = FALSE;

	if( noBytes > 384 && !printAllData )
		noBytes = 384;	/* Only output a maximum of 384 bytes */
	if( strOption == STR_UTCTIME || strOption == STR_GENERALIZED )
		{
		if( ( strOption == STR_UTCTIME && length != 13 ) || \
			( strOption == STR_GENERALIZED && length != 15 ) )
			warnTime = TRUE;
		else
			doTimeStr = rawTimeString ? FALSE : TRUE;
		}
	if( !doTimeStr && length <= 40 )
		fprintf( output, " '" );		/* Print string on same line */
	if( level > maxLevel )
		level = maxLevel;	/* Make sure that we don't go off edge of screen */
	for( i = 0; i < noBytes; i++ )
		{
		int ch;

		/* If the string is longer than 40 chars, break it up into multiple
		   sections */
		if( length > 40 && !( i % lineLength ) )
			{
			if( !firstTime )
				fputc( '\'', output );
			fputc( '\n', output );
			if( !doPure )
				fprintf( output, INDENT_STRING );
			doIndent( level + 1 );
			fputc( '\'', output );
			firstTime = FALSE;
			}
		ch = getc( inFile );
#if defined( __WIN32__ ) || defined( __UNIX__ ) || defined( __OS390__ )
		if( strOption == STR_BMP )
			{
			if( i == noBytes - 1 && ( noBytes & 1 ) )
				/* Odd-length BMP string, complain */
				warnBMP = TRUE;
			else
				{
				const wchar_t wCh = ( ch << 8 ) | getc( inFile );
				char outBuf[ 8 ];
#ifdef __OS390__
				char *p;
#endif /* OS-specific charset handling */
				int outLen;

				/* Attempting to display Unicode characters is pretty hit and
				   miss, and if it fails nothing is displayed.  To try and
				   detect this we use wcstombs() to see if anything can be
				   displayed, if it can't we drop back to trying to display
				   the data as non-Unicode.  There's one exception to this
				   case, which is for a wrong-endianness Unicode string, for
				   which the first character looks like a single ASCII char */
				outLen = wcstombs( outBuf, &wCh, 1 );
				if( outLen < 1 )
					{
					/* Can't be displayed as Unicode, fall back to
					   displaying it as normal text */
					ungetc( wCh & 0xFF, inFile );
					}
				else
					{
					lineLength++;
					i++;	/* We've read two characters for a wchar_t */
#if defined( __WIN32__ )
					fputwc( wCh, output );
#elif defined( __UNIX__ ) && !( defined( __MACH__ ) || defined( __OpenBSD__ ) )
					/* Some Unix environments differentiate between char
					   and wide-oriented stdout (!!!), so it's necessary to
					   manually switch the orientation of stdout to make it
					   wide-oriented before calling a widechar output
					   function or nothing will be output (exactly what
					   level of braindamage it takes to have an
					   implementation function like this is a mystery).  In
					   order to safely display widechars, we therefore have
					   to use the fwide() kludge function to change stdout
					   modes around the display of the widechar */
					if( fwide( output, 1 ) > 0 )
						{
						fputwc( wCh, output );
						fwide( output, -1 );
						}
					else
						fputc( wCh, output );
#else
  #ifdef __OS390__
					/* This could use some improvement */
					for( p = outBuf; *p != '\0'; p++ )
						*p = asciiToEbcdic( *p );
  #endif /* IBM ASCII -> EBCDIC conversion */
					fprintf( output, "%s", outBuf );
#endif /* OS-specific charset handling */
					fPos += 2;
					continue;
					}
				}
			}
#endif /* __WIN32__ || __UNIX__ || __OS390__ */
		switch( strOption )
			{
			case STR_PRINTABLE:
			case STR_IA5:
			case STR_LATIN1:
				if( strOption == STR_PRINTABLE && !isPrintable( ch ) )
					warnPrintable = TRUE;
				if( strOption == STR_IA5 && !isIA5( ch ) )
					warnIA5 = TRUE;
				if( strOption == STR_LATIN1 )
					{
					if( !isprint( ch & 0x7F ) )
						ch = '.';	/* Convert non-ASCII to placeholders */
					}
				else
					{
					if( !isprint( ch ) )
						ch = '.';	/* Convert non-ASCII to placeholders */
					}
#ifdef __OS390__
				ch = asciiToEbcdic( ch );
#endif /* __OS390__ */
				break;

			case STR_UTCTIME:
			case STR_GENERALIZED:
				if( !isdigit( ch ) && ch != 'Z' )
					{
					warnTime = TRUE;
					if( !isprint( ch ) )
						ch = '.';	/* Convert non-ASCII to placeholders */
					}
#ifdef __OS390__
				ch = asciiToEbcdic( ch );
#endif /* __OS390__ */
				break;

			case STR_BMP_REVERSED:
				if( i == noBytes - 1 && ( noBytes & 1 ) )
					{
					/* Odd-length BMP string, complain */
					warnBMP = TRUE;

⌨️ 快捷键说明

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