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

📄 sign_rw.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:

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

	/* Make sure that the packet header is in order and check the packet
	   version.  For this packet type a version number of 3 denotes PGP 2.x
	   whereas for key transport it denotes OpenPGP */
	status = getPgpPacketInfo( stream, queryInfo );
	if( cryptStatusError( status ) )
		return( status );
	value = sgetc( stream );
	if( value != PGP_VERSION_2 && value != PGP_VERSION_3 && \
		value != PGP_VERSION_OPENPGP )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->type = CRYPT_OBJECT_SIGNATURE;
	queryInfo->version = ( value == PGP_VERSION_OPENPGP ) ? \
						 PGP_VERSION_OPENPGP : PGP_VERSION_2;

	/* Read the signing attributes and skip the hash check */
	if( value != PGP_VERSION_OPENPGP )
		status = readPgp2SigInfo( stream, queryInfo, startPos );
	else
		status = readOpenPgpSigInfo( stream, queryInfo, startPos );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, 2 );
	if( cryptStatusError( status ) )
		return( status );

	/* Read the signature, recording the position and length of the raw RSA 
	   signature data.  We have to be careful how we handle this because 
	   readInteger16Ubits() returns the canonicalised form of the values 
	   (with leading zeroes truncated) so an stell() before the read doesn't 
	   necessarily represent the start of the payload:

		startPos	dataStart		 stell()
			|			|				|
			v			v <-- length -->v
		+---+-----------+---------------+
		|	|			|///////////////| Stream
		+---+-----------+---------------+ */
	if( queryInfo->cryptAlgo == CRYPT_ALGO_RSA )
		{
		status = readInteger16Ubits( stream, NULL, &queryInfo->dataLength,
									 MIN_PKCSIZE, CRYPT_MAX_PKCSIZE );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataStart = stell( stream ) - queryInfo->dataLength;
		}
	else
		{
		const int dataStartPos = stell( stream );
		int dummy;

		REQUIRES( queryInfo->cryptAlgo == CRYPT_ALGO_DSA );

		/* Read the DSA signature, recording the position and combined 
		   lengths of the MPI pair.  Again, we can't use the length returned 
		   by readInteger16Ubits() to determine the overall size but have to 
		   calculate it from the position in the stream */
		status = readInteger16Ubits( stream, NULL, &dummy, 16, 20 );
		if( cryptStatusOK( status ) )
			status = readInteger16Ubits( stream, NULL, &dummy, 16, 20 );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataStart = dataStartPos - startPos;
		queryInfo->dataLength = stell( stream ) - dataStartPos;
		}

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writePgpSignature( INOUT STREAM *stream,
							  STDC_UNUSED const CRYPT_CONTEXT iSignContext,
							  STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
							  IN_ALGO const CRYPT_ALGO_TYPE signAlgo,
							  IN_BUFFER( signatureLength ) const BYTE *signature,
							  IN_LENGTH_SHORT_MIN( 18 + 18 + 1 ) \
								const int signatureLength )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( signature, signatureLength ) );
			/* Other parameters aren't used for this format */

	REQUIRES( signAlgo >= CRYPT_ALGO_FIRST_PKC && \
			  signAlgo <= CRYPT_ALGO_LAST_PKC );
	REQUIRES( signatureLength > ( 18 + 18 ) && \
			  signatureLength < MAX_INTLENGTH_SHORT );

	/* If it's a DLP algorithm we've already specified the DLP output format 
	   as PGP so there's no need for further processing.  The handling of 
	   PGP signatures is non-orthogonal to readPgpSignature() because 
	   creating a PGP signature involves adding assorted additional data 
	   like key IDs and authenticated attributes, which present too much 
	   information to pass into a basic writeSignature() call */
	if( isDlpAlgo( signAlgo ) || isEccAlgo( signAlgo ) )
		return( swrite( stream, signature, signatureLength ) );

	/* Write the signature as a PGP MPI */
	return( writeInteger16Ubits( stream, signature, signatureLength ) );
	}
#endif /* USE_PGP */

/****************************************************************************
*																			*
*						Miscellaneous Signature Routines					*
*																			*
****************************************************************************/

#ifdef USE_SSH

/* Read/write SSH signatures.  SSH signature data is treated as a blob
   encoded as an SSH string rather than properly-formatted data so we don't
   encode/decode it as SSH MPIs */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readSshSignature( INOUT STREAM *stream, 
							 INOUT QUERY_INFO *queryInfo )
	{
	const int startPos = stell( stream );
	BYTE buffer[ CRYPT_MAX_TEXTSIZE + 8 ];
	int length, status;

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

	/* Read the signature record size and algorithm information */
	readUint32( stream );
	status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
	if( cryptStatusError( status ) )
		return( status );
	if( length != 7 )
		return( CRYPT_ERROR_BADDATA );
	if( !memcmp( buffer, "ssh-rsa", 7 ) )
		queryInfo->cryptAlgo = CRYPT_ALGO_RSA;
	else
		{
		if( !memcmp( buffer, "ssh-dss", 7 ) )
			queryInfo->cryptAlgo = CRYPT_ALGO_DSA;
		else
			return( CRYPT_ERROR_BADDATA );
		}

	/* Read the start of the signature */
	length = readUint32( stream );
	if( cryptStatusError( length ) )
		return( length );
	if( queryInfo->cryptAlgo == CRYPT_ALGO_DSA )
		{
		if( length != ( 20 + 20 ) )
			return( CRYPT_ERROR_BADDATA );
		}
	else
		{
		if( length < MIN_PKCSIZE || length > CRYPT_MAX_PKCSIZE )
			return( CRYPT_ERROR_BADDATA );
		}
	queryInfo->dataStart = stell( stream ) - startPos;
	queryInfo->dataLength = length;

	/* Make sure that the remaining signature data is present */
	return( sSkip( stream, length ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writeSshSignature( INOUT STREAM *stream,
							  STDC_UNUSED const CRYPT_CONTEXT iSignContext,
							  STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
							  IN_ALGO const CRYPT_ALGO_TYPE signAlgo,
							  IN_BUFFER( signatureLength ) const BYTE *signature,
							  IN_LENGTH_SHORT_MIN( 40 ) const int signatureLength )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( signature, signatureLength ) );
			/* Other parameters aren't used for this format */

	REQUIRES( signAlgo == CRYPT_ALGO_RSA || signAlgo == CRYPT_ALGO_DSA );
	REQUIRES( signatureLength >= ( 20 + 20 ) && \
			  signatureLength < MAX_INTLENGTH_SHORT );

	writeUint32( stream, sizeofString32( "ssh-Xsa", 7 ) + \
						 sizeofString32( "", signatureLength ) );
	writeString32( stream, ( signAlgo == CRYPT_ALGO_RSA ) ? \
						   "ssh-rsa" : "ssh-dss", 7 );
	return( writeString32( stream, signature, signatureLength ) );
	}
#endif /* USE_SSH */

#ifdef USE_SSL

/* Read/write SSL signatures.  This is just a raw signature without any
   encapsulation */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readSslSignature( INOUT STREAM *stream, 
							 INOUT QUERY_INFO *queryInfo )
	{
	const int startPos = stell( stream );
	int length;

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

	/* Read the start of the signature */
	length = readUint16( stream );
	if( length < MIN_PKCSIZE || length > CRYPT_MAX_PKCSIZE )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->dataStart = stell( stream ) - startPos;
	queryInfo->dataLength = length;

	/* Make sure that the remaining signature data is present */
	return( sSkip( stream, length ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int writeSslSignature( INOUT STREAM *stream,
							  STDC_UNUSED const CRYPT_CONTEXT iSignContext,
							  STDC_UNUSED const CRYPT_ALGO_TYPE hashAlgo,
							  STDC_UNUSED const CRYPT_ALGO_TYPE signAlgo,
							  IN_BUFFER( signatureLength ) const BYTE *signature,
							  IN_LENGTH_SHORT_MIN( 18 + 18 + 1 ) \
								const int signatureLength )
	{
	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( signature, signatureLength ) );
			/* Other parameters aren't used for this format */

	REQUIRES( signatureLength > ( 18 + 18 ) && \
			  signatureLength < MAX_INTLENGTH_SHORT );

	writeUint16( stream, signatureLength );
	return( swrite( stream, signature, signatureLength ) );
	}
#endif /* USE_SSL */

/****************************************************************************
*																			*
*					Signature Read/Write Access Functions					*
*																			*
****************************************************************************/

typedef struct {
	const SIGNATURE_TYPE type;
	const READSIG_FUNCTION function;
	} SIG_READ_INFO;
static const SIG_READ_INFO sigReadTable[] = {
	{ SIGNATURE_RAW, readRawSignature },
	{ SIGNATURE_X509, readX509Signature },
	{ SIGNATURE_CMS, readCmsSignature },
	{ SIGNATURE_CRYPTLIB, readCryptlibSignature },
#ifdef USE_PGP
	{ SIGNATURE_PGP, readPgpSignature },
#endif /* USE_PGP */
#ifdef USE_SSH
	{ SIGNATURE_SSH, readSshSignature },
#endif /* USE_SSH */
#ifdef USE_SSL
	{ SIGNATURE_SSL, readSslSignature },
#endif /* USE_SSL */
	{ SIGNATURE_NONE, NULL }, { SIGNATURE_NONE, NULL }
	};

typedef struct {
	const SIGNATURE_TYPE type;
	const WRITESIG_FUNCTION function;
	} SIG_WRITE_INFO;
static const SIG_WRITE_INFO sigWriteTable[] = {
	{ SIGNATURE_RAW, writeRawSignature },
	{ SIGNATURE_X509, writeX509Signature },
	{ SIGNATURE_CMS, writeCmsSignature },
	{ SIGNATURE_CRYPTLIB, writeCryptlibSignature },
#ifdef USE_PGP
	{ SIGNATURE_PGP, writePgpSignature },
#endif /* USE_PGP */
#ifdef USE_SSH
	{ SIGNATURE_SSH, writeSshSignature },
#endif /* USE_SSH */
#ifdef USE_SSL
	{ SIGNATURE_SSL, writeSslSignature },
#endif /* USE_SSH */
	{ SIGNATURE_NONE, NULL }, { SIGNATURE_NONE, NULL }
	};

CHECK_RETVAL_PTR \
READSIG_FUNCTION getReadSigFunction( IN_ENUM( SIGNATURE ) \
										const SIGNATURE_TYPE sigType )
	{
	int i;

	REQUIRES_N( sigType > SIGNATURE_NONE && sigType < SIGNATURE_LAST );

	for( i = 0; 
		 sigReadTable[ i ].type != SIGNATURE_NONE && \
			i < FAILSAFE_ARRAYSIZE( sigReadTable, SIG_READ_INFO ); 
		 i++ )
		{
		if( sigReadTable[ i ].type == sigType )
			return( sigReadTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( sigReadTable, SIG_READ_INFO ) );

	return( NULL );
	}
CHECK_RETVAL_PTR \
WRITESIG_FUNCTION getWriteSigFunction( IN_ENUM( SIGNATURE ) \
										const SIGNATURE_TYPE sigType )
	{
	int i;

	REQUIRES_N( sigType > SIGNATURE_NONE && sigType < SIGNATURE_LAST );

	for( i = 0; 
		 sigWriteTable[ i ].type != SIGNATURE_NONE && \
			i < FAILSAFE_ARRAYSIZE( sigWriteTable, SIG_WRITE_INFO ); 
		 i++ )
		{
		if( sigWriteTable[ i ].type == sigType )
			return( sigWriteTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( sigWriteTable, SIG_WRITE_INFO ) );

	return( NULL );
	}

⌨️ 快捷键说明

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