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

📄 sign_pgp.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
		{
		status = writePgpSigPacketHeader( NULL, 0, &extraDataLength, 
										  iSignContext, iHashContext, 
										  iAndSlength );
		if( cryptStatusError( status ) )
			return( status );
		status = createSignature( NULL, 0, &signatureDataLength, 
								  iSignContext, iHashContext, CRYPT_UNUSED, 
								  SIGNATURE_PGP );
		if( cryptStatusError( status ) )
			return( status );
		*signatureLength = 1 + pgpSizeofLength( extraDataLength + 2 + \
												signatureDataLength ) + \
						   extraDataLength + 2 + signatureDataLength;

		return( CRYPT_OK );
		}

	/* If there's an issuerAndSerialNumber present, allocate a larger buffer 
	   for it if necessary (this virtually never occurs, the iAndS would need
	   to be over 1kB long.  Note that we can't use a dynBuf for this 
	   because we're allocating a buffer larger than the attribute, not the 
	   same size as the attribute */
	if( iAndSlength > extraDataLength - 128 )
		{
		extraDataLength = 128 + iAndSlength;
		if( ( extraDataPtr = clDynAlloc( "createSignaturePGP", \
										 extraDataLength ) ) == NULL )
			return( CRYPT_ERROR_MEMORY );
		}

	/* Complete the hashing and create the signature.  In theory this could
	   get ugly because there could be multiple one-pass signature packets
	   present, however PGP handles multiple signatures by nesting them so
	   this isn't a problem.

	   PGP processes the authenticated attributes in an odd way, first
	   hashing part of the packet from the version number to the end of the
	   authenticated attributes, then hashing some more (out-of-band) stuff, 
	   and finally signing the result of the overall hashing.  Because of 
	   this complex way of handling things we can't write the signature 
	   packet in one go but instead have to write the part that we can 
	   create now, hash the portion that's hashed (all but the last 16 bits, 
	   the length of the unathenticated attributes), and then go back and 
	   assemble the whole thing including the length and signature later on 
	   from the pre-hashed data and the length, hash check, and signature */
	status = writePgpSigPacketHeader( extraData, extraDataLength, 
									  &extraDataLength, iSignContext,
									  iHashContext, iAndSlength );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
								  extraData, extraDataLength - UINT16_SIZE );
		if( status == CRYPT_ERROR_COMPLETE )
			{
			/* Unlike standard signatures PGP requires that the hashing not 
			   be wrapped up before the signature is generated because it 
			   needs to hash in further data before it can generate the 
			   signature.  Since completing the hashing is likely to be a 
			   common error we specifically check for this and return an
			   appropriate error code */
			status = CRYPT_ARGERROR_NUM2;
			}
		}
	if( cryptStatusError( status ) )
		{
		zeroise( extraDataPtr, extraDataLength );
		if( extraDataPtr != extraData )
			clFree( "createSignaturePGP", extraDataPtr );
		return( status );
		}

	/* Hash in even more stuff at the end.  This is a complex jumble of 
	   items constituting a version number, an 0xFF, and another length.  
	   This was motivated by a concern that something that meant one thing 
	   in a version n sig could mean something different when interpreted as 
	   a version n+1 sig.  For this reason a hash-convention version (v4) 
	   was added, along with a disambiguator 0xFF that will never be found 
	   at that position in older (v3) hash-convention sigs (the 0x04 is in 
	   fact redundant but may be needed at some point if the hash 
	   convention moves to a v5 format).  The length has something to do 
	   with parsing the packet from the end, so that out-of-band data 
	   doesn't run into payload data, but no-one can quite remember why 
	   it's actually there */
	sMemOpen( &stream, extraTrailer, 8 );
	sputc( &stream, 0x04 );
	sputc( &stream, 0xFF );
	status = writeUint32( &stream, extraDataLength - UINT16_SIZE );
	if( cryptStatusOK( status ) )
		extraTrailerLength = stell( &stream );
	sMemDisconnect( &stream );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, 
								  extraTrailer, extraTrailerLength );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, hash, CRYPT_MAX_HASHSIZE );
		status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CTXINFO_HASHVALUE );
		}
	if( cryptStatusError( status ) )
		{
		zeroise( extraDataPtr, extraDataLength );
		if( extraDataPtr != extraData )
			clFree( "createSignaturePGP", extraDataPtr );
		return( status );
		}

	/* We've finally finished with all the hashing, create the signature */
	status = createSignature( signatureData, CRYPT_MAX_PKCSIZE + 128, 
							  &signatureDataLength, iSignContext, 
							  iHashContext, CRYPT_UNUSED, SIGNATURE_PGP );
	if( cryptStatusOK( status ) )
		{
		totalLength = 1 + \
					  pgpSizeofLength( extraDataLength + 2 + \
									   signatureDataLength ) + \
					  extraDataLength + 2 + signatureDataLength;
		if( totalLength + 64 > sigMaxLength )
			status = CRYPT_ERROR_OVERFLOW;
		}
	if( cryptStatusError( status ) )
		{
		zeroise( extraDataPtr, extraDataLength );
		if( extraDataPtr != extraData )
			clFree( "createSignaturePGP", extraDataPtr );
		return( status );
		}

	/* Write the signature packet:

	  [	signature packet header ]
		byte[2]	hash check
		mpi		signature

	  Since we've already had to write half the packet earlier on in order
	  to hash it we copy this pre-encoded information across and add the 
	  header and trailer around it */
	sMemOpen( &stream, signature, totalLength + 64 );
	pgpWritePacketHeader( &stream, PGP_PACKET_SIGNATURE,
						  extraDataLength + 2 + signatureDataLength );
	swrite( &stream, extraData, extraDataLength );
	swrite( &stream, hash, 2 );			/* Hash check */
	status = swrite( &stream, signatureData, signatureDataLength );
	if( cryptStatusOK( status ) )
		*signatureLength = stell( &stream );
	sMemDisconnect( &stream );
	zeroise( extraDataPtr, extraDataLength );
	zeroise( signatureData, CRYPT_MAX_PKCSIZE + 128 );
	if( extraDataPtr != extraData )
		clFree( "createSignaturePGP", extraDataPtr );

	return( status );
	}

/* Check a PGP signature */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int checkSignaturePGP( IN_BUFFER( signatureLength ) const void *signature, 
					   IN_LENGTH_SHORT const int signatureLength,
					   IN_HANDLE const CRYPT_CONTEXT sigCheckContext,
					   IN_HANDLE const CRYPT_CONTEXT iHashContext )
	{
	const READSIG_FUNCTION readSigFunction = getReadSigFunction( SIGNATURE_PGP );
	QUERY_INFO queryInfo;
	STREAM stream;
	int status;

	assert( isReadPtr( signature, signatureLength ) );
	
	REQUIRES( signatureLength > 40 && signatureLength < MAX_INTLENGTH );
	REQUIRES( isHandleRangeValid( sigCheckContext ) );
	REQUIRES( isHandleRangeValid( iHashContext ) );

	/* Make sure that the requested signature format is available */
	if( readSigFunction == NULL )
		return( CRYPT_ERROR_NOTAVAIL );

	/* Determine whether there are any authenticated attributes attached to
	   the signature */
	memset( &queryInfo, 0, sizeof( QUERY_INFO ) );
	sMemConnect( &stream, signature, signatureLength );
	status = readSigFunction( &stream, &queryInfo );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		{
		zeroise( &queryInfo, sizeof( QUERY_INFO ) );
		return( status );
		}

	/* After hashing the content, PGP also hashes in extra authenticated
	   attributes, see the earlier comment in createSignaturePGP() */
	REQUIRES( rangeCheck( queryInfo.attributeStart, 
						  queryInfo.attributeLength, queryInfo.size ) );
	status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
							  ( BYTE * ) signature + queryInfo.attributeStart,
							  queryInfo.attributeLength );
	if( cryptStatusOK( status ) && queryInfo.attributeLength != 5 )
		{
		BYTE buffer[ 8 + 8 ];
		int length = DUMMY_INIT;

		/* In addition to the standard authenticated attributes OpenPGP
		   hashes in even more stuff at the end (see the comments for 
		   createSignaturePGP() for more on this) */
		sMemOpen( &stream, buffer, 8 );
		sputc( &stream, 0x04 );
		sputc( &stream, 0xFF );
		status = writeUint32( &stream, queryInfo.attributeLength );
		if( cryptStatusOK( status ) )
			length = stell( &stream );
		sMemDisconnect( &stream );
		if( cryptStatusOK( status ) )
			{
			status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH,
									  buffer, length );
			}
		}
	zeroise( &queryInfo, sizeof( QUERY_INFO ) );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 );
	if( cryptStatusError( status ) )
		return( status );

	/* Check the signature */
	return( checkSignature( signature, signatureLength, sigCheckContext,
							iHashContext, CRYPT_UNUSED, SIGNATURE_PGP ) );
	}
#endif /* USE_PGP */

⌨️ 快捷键说明

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