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

📄 sign_rw.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		byte[8]	keyID
		byte	1 */

int readOnepassSigPacket( STREAM *stream, QUERY_INFO *queryInfo )
	{
	int status;

	/* Make sure that the packet header is in order and check the packet 
	   version.  This is an OpenPGP-only packet */
	status = getPacketInfo( stream, queryInfo );
	if( cryptStatusError( status ) )
		return( status );
	if( sgetc( stream ) != PGP_VERSION_3 )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->version = PGP_VERSION_OPENPGP;

	/* Skip the sig.type, get the hash algorithm and check the signature 
	   algorithm */
	sgetc( stream );
	if( ( queryInfo->hashAlgo = \
			pgpToCryptlibAlgo( sgetc( stream ),
							   PGP_ALGOCLASS_HASH ) ) == CRYPT_ALGO_NONE )
		return( CRYPT_ERROR_NOTAVAIL );
	if( ( queryInfo->cryptAlgo = \
			pgpToCryptlibAlgo( sgetc( stream ),
							   PGP_ALGOCLASS_SIGN ) ) == CRYPT_ALGO_NONE )
		return( CRYPT_ERROR_NOTAVAIL );
	queryInfo->type = CRYPT_OBJECT_SIGNATURE;

	/* Get the PGP key ID and make sure that this isn't a nested signature */
	status = sread( stream, queryInfo->keyID, PGP_KEYID_SIZE );
	if( cryptStatusError( status ) )
		return( status );
	queryInfo->keyIDlength = PGP_KEYID_SIZE;
	return( ( sgetc( stream ) != 1 ) ? CRYPT_ERROR_BADDATA : CRYPT_OK );
	}

/* Read/write PGP signatures.

		byte	ctb = PGP_PACKET_SIGNATURE
		byte[]	length
	v3:	byte	version = 2, 3		v4: byte	version = 4
		byte	infoLen = 5			byte	sigType
			byte	sigType			byte	sigAlgo
			byte[4]	sig.time		byte	hashAlgo
		byte[8]	keyID				byte[2]	length of auth.attributes
		byte	sigAlgo				byte[]	authenticated attributes
		byte	hashAlgo			byte[2]	length of unauth.attributes
		byte[2]	hash check			byte[]	unauthenticated attributes
		mpi(s)	signature			byte[2]	hash check
									mpi(s)	signature */

static int readPgpSignature( STREAM *stream, QUERY_INFO *queryInfo )
	{
	int value, status;

	/* 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 = getPacketInfo( 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;

	/* If it's not an OpenPGP packet, read it as a PGP 2.x-format
	   signature */
	if( value != PGP_VERSION_OPENPGP )
		{
		/* Read the additional signature information */
		if( sgetc( stream ) != 5 )
			return( CRYPT_ERROR_BADDATA );
		queryInfo->attributeStart = sMemBufPtr( stream );
		queryInfo->attributeLength = 5;
		sSkip( stream, 5 );

		/* Read the signer keyID, signature and hash algorithm */
		status = sread( stream, queryInfo->keyID, PGP_KEYID_SIZE );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->keyIDlength = PGP_KEYID_SIZE;
		if( ( queryInfo->cryptAlgo = \
				pgpToCryptlibAlgo( sgetc( stream ),
								   PGP_ALGOCLASS_SIGN ) ) == CRYPT_ALGO_NONE )
			return( CRYPT_ERROR_NOTAVAIL );
		if( ( queryInfo->hashAlgo = \
				pgpToCryptlibAlgo( sgetc( stream ),
								   PGP_ALGOCLASS_HASH ) ) == CRYPT_ALGO_NONE )
			return( CRYPT_ERROR_NOTAVAIL );
		}
	else
		{
		/* It's an OpenPGP packet, remember the extra data to be hashed (this
		   starts at the version byte, which we've already read, so we add a 
		   -1 offset) and read the signature and hash algorithms */
		queryInfo->attributeStart = sMemBufPtr( stream ) - 1;
		queryInfo->attributeLength = 1 + 1 + 1 + 1 + 2;
		sgetc( stream );	/* Skip signature type */
		if( ( queryInfo->cryptAlgo = \
				pgpToCryptlibAlgo( sgetc( stream ),
								   PGP_ALGOCLASS_SIGN ) ) == CRYPT_ALGO_NONE )
			return( CRYPT_ERROR_NOTAVAIL );
		if( ( queryInfo->hashAlgo = \
				pgpToCryptlibAlgo( sgetc( stream ),
								   PGP_ALGOCLASS_HASH ) ) == CRYPT_ALGO_NONE )
			return( CRYPT_ERROR_NOTAVAIL );

		/* Process the authenticated attributes */
		value = readUint16( stream );
		if( value < 0 || value > 2048 )
			return( CRYPT_ERROR_BADDATA );
		if( sMemDataLeft( stream ) < value )
			return( CRYPT_ERROR_UNDERFLOW );
		queryInfo->attributeLength += value;
		if( value > 0 )
			{
			status = readSignatureSubpackets( stream, queryInfo, value, 
											  TRUE );
			if( cryptStatusError( status ) )
				return( status );
			}

		/* Skip the unauthenticated attributes */
		queryInfo->unauthAttributeStart = sMemBufPtr( stream );
		value = readUint16( stream );
		if( value < 0 || value > 2048 )
			return( CRYPT_ERROR_BADDATA );
		if( sMemDataLeft( stream ) < value )
			return( CRYPT_ERROR_UNDERFLOW );
		queryInfo->unauthAttributeLength = 2 + value;
		if( value > 0 )
			{
			status = readSignatureSubpackets( stream, queryInfo, value, 
											  FALSE );
			if( cryptStatusError( status ) )
				return( status );
			}
		}

	/* Skip the hash check and read the signature, recording the start of the
	   signature data */
	sSkip( stream, 2 );
	if( queryInfo->cryptAlgo == CRYPT_ALGO_DSA )
		{
		queryInfo->dataStart = sMemBufPtr( stream );
		status = pgpReadMPI( stream, NULL );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataLength = bitsToBytes( status ) + 2;
		status = pgpReadMPI( stream, NULL );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataLength += bitsToBytes( status ) + 2;
		if( queryInfo->dataLength < 20 || \
			queryInfo->dataLength > 44 )
			return( CRYPT_ERROR_BADDATA );
		}
	else
		{
		queryInfo->dataStart = sMemBufPtr( stream ) + 2;
		status = pgpReadMPI( stream, NULL );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataLength = bitsToBytes( status );
		if( queryInfo->dataLength < 56 || \
			queryInfo->dataLength > CRYPT_MAX_PKCSIZE + 2 )
			return( CRYPT_ERROR_BADDATA );
		}

	return( CRYPT_OK );
	}

static int writePgpSignature( STREAM *stream, 
							  const CRYPT_CONTEXT iSignContext,
							  const CRYPT_ALGO_TYPE hashAlgo, 
							  const CRYPT_ALGO_TYPE signAlgo, 
							  const BYTE *signature, 
							  const int signatureLength )
	{
	const int bitLength = bytesToBits( signatureLength );

	/* 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 ) )
		return( swrite( stream, signature, signatureLength ) );

	/* Write the signature as PGP MPI */
	sputc( stream, ( bitLength >> 8 ) & 0xFF );
	sputc( stream, bitLength & 0xFF );
	return( swrite( stream, signature, signatureLength ) );
	}
#endif /* USE_PGP */

#ifdef USE_SSH2

/* 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 */

static int readSshSignature( STREAM *stream, QUERY_INFO *queryInfo )
	{
	BYTE buffer[ 64 + 8 ];
	int length, status;

	/* Read the signature record size and algorithm information */
	readUint32( stream );
	status = readString32( stream, buffer, &length, 64 );
	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 != 40 || length > sMemDataLeft( stream ) )
			return( CRYPT_ERROR_BADDATA );
		}
	else
		{
		if( length < 56 || length > CRYPT_MAX_PKCSIZE || \
			length > sMemDataLeft( stream ) )
			return( CRYPT_ERROR_BADDATA );
		}
	queryInfo->dataStart = sMemBufPtr( stream );
	queryInfo->dataLength = length;

	return( CRYPT_OK );
	}

static int writeSshSignature( STREAM *stream, 
							  const CRYPT_CONTEXT iSignContext,
							  const CRYPT_ALGO_TYPE hashAlgo, 
							  const CRYPT_ALGO_TYPE signAlgo, 
							  const BYTE *signature, 
							  const int signatureLength )
	{
	writeUint32( stream, sizeofString32( "ssh-Xsa", 7 ) + \
						 sizeofString32( NULL, signatureLength ) );
	writeString32( stream, ( signAlgo == CRYPT_ALGO_RSA ) ? \
						   "ssh-rsa" : "ssh-dss", 7 );
	return( writeString32( stream, signature, signatureLength ) );
	}
#endif /* USE_SSH2 */

#ifdef USE_SSL

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

static int readSslSignature( STREAM *stream, QUERY_INFO *queryInfo )
	{
	int length;

	/* Read the start of the signature */
	length = readUint16( stream );
	if( length < 56 || length > CRYPT_MAX_PKCSIZE || \
		length > sMemDataLeft( stream ) )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->dataStart = sMemBufPtr( stream );
	queryInfo->dataLength = length;

	return( CRYPT_OK );
	}

static int writeSslSignature( STREAM *stream, 
							  const CRYPT_CONTEXT iSignContext,
							  const CRYPT_ALGO_TYPE hashAlgo, 
							  const CRYPT_ALGO_TYPE signAlgo, 
							  const BYTE *signature, 
							  const int signatureLength )
	{
	writeUint16( stream, signatureLength );
	return( swrite( stream, signature, signatureLength ) );
	}
#endif /* USE_SSL */

/****************************************************************************
*																			*
*				Signature Read/Write Function Access Information			*
*																			*
****************************************************************************/

const READSIG_FUNCTION sigReadTable[] = {
	NULL,					/* SIGNATURE_NONE */
	readRawSignature,		/* SIGNATURE_RAW */
	readX509Signature,		/* SIGNATURE_X509 */
	readCmsSignature,		/* SIGNATURE_CMS */
	readCryptlibSignature,	/* SIGNATURE_CRYPTLIB */
#ifdef USE_PGP
	readPgpSignature,		/* SIGNATURE_PGP */
#else
	NULL,					/* SIGNATURE_PGP */
#endif /* USE_PGP */
#ifdef USE_SSH2
	readSshSignature,		/* SIGNATURE_SSH */
#else
	NULL,					/* SIGNATURE_SSH */
#endif /* USE_SSH */
#ifdef USE_SSL
	readSslSignature,		/* SIGNATURE_SSL */
#else
	NULL,					/* SIGNATURE_SSL */
#endif /* USE_SSL */
	NULL, NULL, NULL
	};

const WRITESIG_FUNCTION sigWriteTable[] = {
	NULL,					/* SIGNATURE_NONE */
	writeRawSignature,		/* SIGNATURE_RAW */
	writeX509Signature,		/* SIGNATURE_X509 */
	writeCmsSignature,		/* SIGNATURE_CMS */
	writeCryptlibSignature,	/* SIGNATURE_CRYPTLIB */
#ifdef USE_PGP
	writePgpSignature,		/* SIGNATURE_PGP */
#else
	NULL,					/* SIGNATURE_PGP */
#endif /* USE_PGP */
#ifdef USE_SSH2
	writeSshSignature,		/* SIGNATURE_SSH */
#else
	NULL,					/* SIGNATURE_SSH */
#endif /* USE_SSH */
#ifdef USE_SSL
	writeSslSignature,		/* SIGNATURE_SSL */
#else
	NULL,					/* SIGNATURE_SSL */
#endif /* USE_SSH */
	NULL, NULL, NULL
	};

⌨️ 快捷键说明

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