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

📄 misc_rw.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*				Miscellaneous (Non-ASN.1) Read/Write Routines				*
*						Copyright Peter Gutmann 1992-2003					*
*																			*
****************************************************************************/

/* Non-ASN.1 formats use their own encoding types for integers, strings,
   and misellaneous other values, the following functions read and write
   these values */

#if defined( INC_ALL )
  #include "crypt.h"
  #include "bn.h"
  #include "misc_rw.h"
#elif defined( INC_CHILD )
  #include "../crypt.h"
  #include "../bn/bn.h"
  #include "misc_rw.h"
#else
  #include "crypt.h"
  #include "bn/bn.h"
  #include "misc/misc_rw.h"
#endif /* Compiler-specific includes */

#if defined( USE_PGP ) || defined( USE_PGPKEYS ) || \
	defined( USE_SSH1 ) || defined( USE_SSH2 )

/****************************************************************************
*																			*
*								Utility Routines							*
*																			*
****************************************************************************/

/* Read a constrained-length data value, used by several routines */

static int readConstrainedData( STREAM *stream, void *buffer,
								int *bufferLength, const int length,
								const int maxLength )
	{
	int dataLength = length, remainder = 0;

	if( bufferLength != NULL )
		*bufferLength = length;

	/* If we don't care about the return value, skip it and exit */
	if( buffer == NULL )
		return( sSkip( stream, dataLength ) );

	/* Read in the object, limiting the size to the maximum buffer size */
	if( dataLength > maxLength )
		{
		remainder = dataLength - maxLength;
		dataLength = maxLength;
		}
	if( dataLength > 0 )
		{
		sread( stream, buffer, dataLength );
		*bufferLength = dataLength;
		}

	/* Skip any remaining data if necessary */
	if( remainder > 0 )
		sSkip( stream, remainder );

	return( sGetStatus( stream ) );
	}

/* Read large integer data */

typedef enum { LENGTH_16BITS_BITS, LENGTH_32BITS, LENGTH_32BITS_BITS } LENGTH_TYPE;

static int readIntegerData( STREAM *stream, void *integer,
							int *integerLength, const int minLength, 
							const int maxLength, 
							const LENGTH_TYPE lengthType )
	{
	BYTE *integerDataPtr = integer;
	int length, i, status;

	/* Clear return values */
	if( integer != NULL )
		*integerDataPtr = '\0';
	if( integerLength != NULL )
		*integerLength = 0;

	/* Read the integer value */
	if( lengthType == LENGTH_16BITS_BITS )
		{
		const int bitLength = ( sgetc( stream ) << 8 ) | sgetc( stream );

		length = bitsToBytes( bitLength );
		if( cryptStatusError( sGetStatus( stream ) ) )
			return( sGetStatus( stream ) );
		}
	else
		{
		length = readUint32( stream );
		if( cryptStatusError( length ) )
			return( length );
		if( lengthType == LENGTH_32BITS_BITS )
			length = bitsToBytes( length );
		}
	if( length < minLength || length > maxLength )
		{
		sSetError( stream, CRYPT_ERROR_BADDATA );
		return( CRYPT_ERROR_BADDATA );
		}
	if( integerLength != NULL )
		*integerLength = length;
	if( integer == NULL )
		return( sSkip( stream, length ) );
	status = sread( stream, integer, length );
	if( cryptStatusError( status ) )
		return( status );

	/* Strip possible leading-zero padding */
	for( i = 0; integerDataPtr[ i ] == 0 && i < length; i++ );
	if( i > 0 )
		{
		if( length - i <= 0 )
			{
			sSetError( stream, CRYPT_ERROR_BADDATA );
			return( CRYPT_ERROR_BADDATA );
			}
		memmove( integerDataPtr, integerDataPtr + i, length - i );
		if( integerLength != NULL )
			*integerLength = length;
		}
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Data Read/Write Routines						*
*																			*
****************************************************************************/

/* Read and write 32-bit integer values */

int readUint32( STREAM *stream )
	{
	BYTE buffer[ UINT32_SIZE ];
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	status = sread( stream, buffer, UINT32_SIZE );
	if( cryptStatusError( status ) )
		return( status );
	if( buffer[ 0 ] & 0x80 )
		{
		sSetError( stream, CRYPT_ERROR_BADDATA );
		return( CRYPT_ERROR_BADDATA );
		}
	return( ( ( unsigned int ) buffer[ 0 ] << 24 ) | \
			( ( unsigned int ) buffer[ 1 ] << 16 ) | \
			( ( unsigned int ) buffer[ 2 ] << 8 ) | \
							   buffer[ 3 ] );
	}

int writeUint32( STREAM *stream, const int value )
	{
	BYTE buffer[ UINT32_SIZE ];

	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	buffer[ 0 ] = value >> 24;
	buffer[ 1 ] = value >> 16;
	buffer[ 2 ] = value >> 8;
	buffer[ 3 ] = value & 0xFF;
	return( swrite( stream, buffer, UINT32_SIZE ) );
	}

/* Read and write 64-bit integer values standard integer values */

int readUint64( STREAM *stream )
	{
	BYTE buffer[ UINT64_SIZE / 2 ];
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	status = sread( stream, buffer, UINT64_SIZE / 2 );
	if( cryptStatusError( status ) )
		return( status );
	if( memcmp( buffer, "\x00\x00\x00\x00", UINT64_SIZE / 2 ) )
		{
		sSetError( stream, CRYPT_ERROR_BADDATA );
		return( CRYPT_ERROR_BADDATA );
		}
	return( readUint32( stream ) );
	}

int writeUint64( STREAM *stream, const int value )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	swrite( stream, "\x00\x00\x00\x00", UINT64_SIZE / 2 );
	return( writeUint32( stream, value ) );
	}

/* Read and write 32- and 64-bit time values.  Note that we can't call down 
   to read/writeUint32 for these since time_t may be unsigned or of a 
   different integral size than int */

int readUint32Time( STREAM *stream, time_t *timeVal )
	{
	BYTE buffer[ UINT32_SIZE ];
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( timeVal, sizeof( time_t ) ) );

	status = sread( stream, buffer, UINT32_SIZE );
	if( cryptStatusError( status ) )
		return( status );
	if( timeVal != NULL )
		*timeVal = ( ( time_t ) buffer[ 0 ] << 24 ) | \
				   ( ( time_t ) buffer[ 1 ] << 16 ) | \
				   ( ( time_t ) buffer[ 2 ] << 8 ) | \
								buffer[ 3 ];
	return( CRYPT_OK );
	}

int writeUint32Time( STREAM *stream, const time_t timeVal )
	{
	BYTE buffer[ UINT32_SIZE ];

	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	buffer[ 0 ] = ( int ) ( timeVal >> 24 );
	buffer[ 1 ] = ( int ) ( timeVal >> 16 );
	buffer[ 2 ] = ( int ) ( timeVal >> 8 );
	buffer[ 3 ] = ( int ) ( timeVal & 0xFF );
	return( swrite( stream, buffer, UINT32_SIZE ) );
	}

int readUint64Time( STREAM *stream, time_t *timeVal )
	{
	BYTE buffer[ UINT64_SIZE ];
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( timeVal, sizeof( time_t ) ) );

	status = sread( stream, buffer, UINT64_SIZE );
	if( cryptStatusError( status ) )
		return( status );
	if( memcmp( buffer, "\x00\x00\x00\x00", UINT64_SIZE / 2 ) )
		{
		sSetError( stream, CRYPT_ERROR_BADDATA );
		return( CRYPT_ERROR_BADDATA );
		}
	return( readUint32Time( stream, timeVal ) );
	}

int writeUint64Time( STREAM *stream, const time_t timeVal )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );

	swrite( stream, "\x00\x00\x00\x00", UINT64_SIZE / 2 );
	return( writeUint32Time( stream, timeVal ) );
	}

/* Read and write strings preceded by 32-bit lengths */

int readString32( STREAM *stream, void *string, int *stringLength,
				  const int maxLength )
	{
	int length;

	/* Clear return values */
	if( string != NULL )
		( ( char * ) string )[ 0 ] = '\0';
	if( stringLength != NULL )
		*stringLength = 0;

	/* Read the string, limiting the size to the maximum buffer size */
	length = readUint32( stream );
	if( length <= 0 )
		return( length );	/* Error or zero length */
	return( readConstrainedData( stream, string, stringLength, length,
								 maxLength ) );
	}

int writeString32( STREAM *stream, const void *string,
				   const int stringLength )
	{
	const int length = ( stringLength ) ? stringLength : strlen( string );

	writeUint32( stream, length );
	return( swrite( stream, string, length ) );
	}

/* Read and write (large) integers preceded by 32-bit lengths */

int readInteger32( STREAM *stream, void *integer, int *integerLength,
				   const int maxLength )
	{
	return( readIntegerData( stream, integer, integerLength, 1, maxLength, 
							 LENGTH_32BITS ) );
	}

int writeInteger32( STREAM *stream, const void *integer,
					const int integerLength )
	{
	const BOOLEAN leadingOneBit = ( ( BYTE * ) integer )[ 0 ] & 0x80;

	writeUint32( stream, integerLength + ( leadingOneBit ? 1 : 0 ) );
	if( leadingOneBit )
		sputc( stream, 0 );	/* MPIs are signed values */
	return( swrite( stream, integer, integerLength ) );
	}

/* Read and write unsigned (large) integers preceded by 16- and 32-bit 
   lengths, lengths in bits */

int readInteger16Ubits( STREAM *stream, void *integer, int *integerLength,

⌨️ 快捷键说明

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