📄 misc_rw.c
字号:
OUT_BUFFER_OPT( maxLength, \
*integerLength ) void *integer,
OUT_LENGTH_PKC_Z int *integerLength,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readInteger( stream, integer, integerLength, minLength,
maxLength, LENGTH_16U_BITS, FALSE ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
int readInteger32( INOUT STREAM *stream,
OUT_BUFFER_OPT( maxLength, \
*integerLength ) void *integer,
OUT_LENGTH_PKC_Z int *integerLength,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readInteger( stream, integer, integerLength, minLength,
maxLength, LENGTH_32, FALSE ) );
}
/* Special-case large integer read routines that explicitly check for a too-
short key and return CRYPT_ERROR_NOSECURE rather than the
CRYPT_ERROR_BADDATA that'd otherwise be returned */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
int readInteger16UChecked( INOUT STREAM *stream,
OUT_BUFFER_OPT( maxLength, *integerLength ) \
void *integer,
OUT_LENGTH_PKC_Z int *integerLength,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readInteger( stream, integer, integerLength, minLength,
maxLength, LENGTH_16U, TRUE ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
int readInteger32Checked( INOUT STREAM *stream,
OUT_BUFFER_OPT( maxLength, *integerLength ) \
void *integer,
OUT_LENGTH_PKC_Z int *integerLength,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readInteger( stream, integer, integerLength, minLength,
maxLength, LENGTH_32, TRUE ) );
}
#ifdef USE_PKC
/* Read integers as bignums in various formats */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readBignumInteger( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength,
IN_OPT TYPECAST( BIGNUM * ) const void *maxRange,
IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType,
const BOOLEAN checkShortKey )
{
BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ];
int length, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( bignum, sizeof( BIGNUM ) ) );
assert( maxRange == NULL || isReadPtr( maxRange, sizeof( BIGNUM ) ) );
REQUIRES_S( minLength > 0 && minLength < maxLength && \
maxLength <= CRYPT_MAX_PKCSIZE );
REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
/* Read the integer data */
status = readInteger( stream, buffer, &length, minLength, maxLength,
lengthType, checkShortKey );
if( cryptStatusError( status ) )
return( status );
/* Convert the value to a bignum. Note that we use the checkShortKey
parameter for both readInteger() and extractBignum(), since the
former merely checks the byte count while the latter actually parses
and processes the bignum */
status = extractBignum( bignum, buffer, length, minLength, maxLength,
maxRange, checkShortKey );
if( cryptStatusError( status ) )
status = sSetError( stream, status );
zeroise( buffer, CRYPT_MAX_PKCSIZE );
return( status );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger16U( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength,
IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
{
return( readBignumInteger( stream, bignum, minLength, maxLength,
maxRange, LENGTH_16U, FALSE ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger16Ubits( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minBits,
IN_LENGTH_PKC const int maxBits,
IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
{
return( readBignumInteger( stream, bignum, bitsToBytes( minBits ),
bitsToBytes( maxBits ), maxRange,
LENGTH_16U_BITS, FALSE ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger32( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength,
IN_OPT TYPECAST( BIGNUM * ) const void *maxRange )
{
return( readBignumInteger( stream, bignum, minLength, maxLength,
maxRange, LENGTH_32, FALSE ) );
}
/* Special-case bignum read routines that explicitly check for a too-short
key and return CRYPT_ERROR_NOSECURE rather than the CRYPT_ERROR_BADDATA
that'd otherwise be returned */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger16UChecked( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readBignumInteger( stream, bignum, minLength, maxLength, NULL,
LENGTH_16U, TRUE ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger16UbitsChecked( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minBits,
IN_LENGTH_PKC const int maxBits )
{
return( readBignumInteger( stream, bignum, bitsToBytes( minBits ),
bitsToBytes( maxBits ), NULL,
LENGTH_16U_BITS, TRUE ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int readBignumInteger32Checked( INOUT STREAM *stream,
INOUT TYPECAST( BIGNUM * ) void *bignum,
IN_LENGTH_PKC const int minLength,
IN_LENGTH_PKC const int maxLength )
{
return( readBignumInteger( stream, bignum, minLength, maxLength,
NULL, LENGTH_32, TRUE ) );
}
#endif /* USE_PKC */
/****************************************************************************
* *
* Data Write Routines *
* *
****************************************************************************/
/* Write 16-, 32- and 64-bit integer values */
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeUint16( INOUT STREAM *stream,
IN_RANGE( 0, 0xFFFF ) const int value )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
REQUIRES_S( value >= 0 && value <= 0xFFFFL );
sputc( stream, ( value >> 8 ) & 0xFF );
return( sputc( stream, value & 0xFF ) );
}
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeUint32( INOUT STREAM *stream, IN_INT_Z const long value )
{
BYTE buffer[ UINT32_SIZE + 8 ];
assert( isWritePtr( stream, sizeof( STREAM ) ) );
REQUIRES_S( value >= 0 && value < MAX_INTLENGTH );
buffer[ 0 ] = ( value >> 24 ) & 0xFF;
buffer[ 1 ] = ( value >> 16 ) & 0xFF;
buffer[ 2 ] = ( value >> 8 ) & 0xFF;
buffer[ 3 ] = value & 0xFF;
return( swrite( stream, buffer, UINT32_SIZE ) );
}
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeUint64( INOUT STREAM *stream, IN_INT_Z const long value )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
REQUIRES_S( value >= 0 && value < MAX_INTLENGTH );
swrite( stream, "\x00\x00\x00\x00", UINT64_SIZE / 2 );
return( writeUint32( stream, value ) );
}
/* Write 32- and 64-bit time values */
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeUint32Time( INOUT STREAM *stream, const time_t timeVal )
{
REQUIRES_S( timeVal >= MIN_TIME_VALUE );
return( writeUint32( stream, ( int ) timeVal ) );
}
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeUint64Time( INOUT STREAM *stream, const time_t timeVal )
{
REQUIRES_S( timeVal >= MIN_TIME_VALUE );
return( writeUint64( stream, ( int ) timeVal ) );
}
/* Write a string preceded by a 32-bit length */
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeString32( INOUT STREAM *stream,
IN_BUFFER( stringLength ) const void *string,
IN_LENGTH_SHORT const int stringLength )
{
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( string, stringLength ) );
REQUIRES_S( stringLength > 0 && stringLength < MAX_INTLENGTH );
writeUint32( stream, stringLength );
return( swrite( stream, string, stringLength ) );
}
/* Write large integers in various formats */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeInteger( INOUT STREAM *stream,
IN_BUFFER( integerLength ) const void *integer,
IN_LENGTH_PKC const int integerLength,
IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType )
{
const BYTE *intPtr = integer;
int length = integerLength;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( integer, integerLength ) );
REQUIRES_S( integerLength > 0 && integerLength <= CRYPT_MAX_PKCSIZE );
REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
/* Integers may be passed to us from higher-level code with leading
zeroes as part of the encoding. Before we write them out we strip
out any superfluous leading zeroes that may be present */
while( length > 0 && *intPtr == 0 )
{
intPtr++;
length--;
}
ENSURES( length > 0 );
switch( lengthType )
{
case LENGTH_16U:
writeUint16( stream, length );
break;
case LENGTH_16U_BITS:
writeUint16( stream, bytesToBits( length ) );
break;
case LENGTH_32:
{
const BOOLEAN leadingOneBit = *intPtr & 0x80;
writeUint32( stream, length + ( leadingOneBit ? 1 : 0 ) );
if( leadingOneBit )
sputc( stream, 0 ); /* MPIs are signed values */
break;
}
default:
retIntError_Stream( stream );
}
return( swrite( stream, intPtr, length ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeInteger16U( INOUT STREAM *stream,
IN_BUFFER( integerLength ) const void *integer,
IN_LENGTH_PKC const int integerLength )
{
return( writeInteger( stream, integer, integerLength, LENGTH_16U ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeInteger16Ubits( INOUT STREAM *stream,
IN_BUFFER( integerLength ) const void *integer,
IN_LENGTH_PKC const int integerLength )
{
return( writeInteger( stream, integer, integerLength, LENGTH_16U_BITS ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeInteger32( INOUT STREAM *stream,
IN_BUFFER( integerLength ) const void *integer,
IN_LENGTH_PKC const int integerLength )
{
return( writeInteger( stream, integer, integerLength, LENGTH_32 ) );
}
#ifdef USE_PKC
/* Write integers from bignums in various formats */
CHECK_RETVAL_RANGE( MAX_ERROR, MAX_INTLENGTH_SHORT ) STDC_NONNULL_ARG( ( 1 ) ) \
int sizeofBignumInteger32( const void *bignum )
{
assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
return( UINT32_SIZE + BN_high_bit( ( BIGNUM * ) bignum ) + \
BN_num_bytes( bignum ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeBignumInteger( INOUT STREAM *stream,
TYPECAST( BIGNUM * ) const void *bignum,
IN_ENUM( LENGTH ) const LENGTH_TYPE lengthType )
{
BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ];
int bnLength, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
REQUIRES_S( lengthType > LENGTH_NONE && lengthType < LENGTH_LAST );
status = getBignumData( bignum, buffer, CRYPT_MAX_PKCSIZE, &bnLength );
ENSURES_S( cryptStatusOK( status ) );
if( lengthType == LENGTH_16U_BITS )
{
/* We can't call down to writeInteger() from here because we need to
write a precise length in bits rather than a value reconstructed
from the byte count. This also means that we can't easily
perform the leading-zero truncation that writeInteger() does
without a lot of low-level fiddling that duplicates code in
writeInteger() */
writeUint16( stream, BN_num_bits( bignum ) );
status = swrite( stream, buffer, bnLength );
}
else
status = writeInteger( stream, buffer, bnLength, lengthType );
zeroise( buffer, CRYPT_MAX_PKCSIZE );
return( status );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeBignumInteger16U( INOUT STREAM *stream,
TYPECAST( BIGNUM * ) const void *bignum )
{
return( writeBignumInteger( stream, bignum, LENGTH_16U ) );
}
RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int writeBignumInteger16Ubits( INOUT STREAM *stream,
TYPECAST( BIGNUM * ) const void *bignum )
{
return( writeBignumInteger( stream, bignum, LENGTH_16U_BITS ) );
}
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int writeBignumInteger32( INOUT STREAM *stream,
TYPECAST( BIGNUM * ) const void *bignum )
{
return( writeBignumInteger( stream, bignum, LENGTH_32 ) );
}
#endif /* USE_PKC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -