📄 sign_int.c
字号:
/****************************************************************************
* *
* Internal Signature Routines *
* Copyright Peter Gutmann 1993-2007 *
* *
****************************************************************************/
#if defined( INC_ALL )
#include "crypt.h"
#include "mech.h"
#include "asn1.h"
#include "pgp.h"
#else
#include "crypt.h"
#include "mechs/mech.h"
#include "misc/asn1.h"
#include "misc/pgp.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* DLP Signature Handling *
* *
****************************************************************************/
/* Create a DLP signature */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
int createDlpSignature( OUT_BUFFER_OPT( sigMaxLength, *signatureLength ) \
void *buffer,
IN_RANGE( 0, CRYPT_MAX_PKCSIZE ) const int bufSize,
OUT_LENGTH_Z int *length,
IN_HANDLE const CRYPT_CONTEXT iSignContext,
IN_HANDLE const CRYPT_CONTEXT iHashContext,
IN_ENUM( SIGNATURE ) const SIGNATURE_TYPE signatureType )
{
DLP_PARAMS dlpParams;
MESSAGE_DATA msgData;
BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
int hashSize, status;
assert( ( buffer == NULL && bufSize == 0 ) || \
isWritePtr( buffer, bufSize ) );
assert( isWritePtr( length, sizeof( int ) ) );
REQUIRES( ( buffer == NULL && bufSize == 0 ) || \
( buffer != NULL && \
bufSize > MIN_CRYPT_OBJECTSIZE && \
bufSize <= CRYPT_MAX_PKCSIZE ) );
REQUIRES( isHandleRangeValid( iSignContext ) );
REQUIRES( isHandleRangeValid( iHashContext ) );
REQUIRES( signatureType > SIGNATURE_NONE && \
signatureType < SIGNATURE_LAST );
/* Clear return value */
*length = 0;
/* Extract the hash value from the context. If we're doing a length
check there's no hash value present yet, so we just fill in the hash
length value from the blocksize attribute */
if( buffer == NULL )
{
memset( hash, 0, CRYPT_MAX_HASHSIZE ); /* Keep mem.checkers happy */
status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE,
&msgData.length,
CRYPT_CTXINFO_BLOCKSIZE );
}
else
{
setMessageData( &msgData, hash, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_HASHVALUE );
}
if( cryptStatusError( status ) )
return( status );
hashSize = msgData.length;
/* Standard DSA is only defined for hash algorithms with a block size of
160 bits, FIPS 186-3 extends this to allow use with larger hashes so
all we do is require at least 160 bits, which also works for ECC
algorithms */
if( hashSize < 20 )
{
/* The error reporting here is a bit complex, see the comment in
createSignature() for how this works */
return( CRYPT_ARGERROR_NUM1 );
}
/* If we're doing a length check and the signature is being written in
cryptlib format the length is just an estimate since it can change by
up to two bytes depending on whether the signature values have the
high bit set or not, which requires zero-padding of the ASN.1-encoded
integers (we use a worst-case estimate here and assume that both
integers will be of the maximum size and need padding). This is
rather nasty because it means that we can't tell how large a
signature will be without actually creating it */
if( buffer == NULL )
{
*length = ( signatureType == SIGNATURE_PGP ) ? \
2 * ( 2 + hashSize ) : \
sizeofObject( ( 2 * sizeofObject( hashSize + 1 ) ) );
return( CRYPT_OK );
}
/* Sign the data */
setDLPParams( &dlpParams, hash, hashSize, buffer, bufSize );
if( signatureType == SIGNATURE_PGP )
dlpParams.formatType = CRYPT_FORMAT_PGP;
if( signatureType == SIGNATURE_SSH )
dlpParams.formatType = CRYPT_IFORMAT_SSH;
status = krnlSendMessage( iSignContext, IMESSAGE_CTX_SIGN,
&dlpParams, sizeof( DLP_PARAMS ) );
if( cryptStatusOK( status ) )
*length = dlpParams.outLen;
return( status );
}
/* Check a DLP signature */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int checkDlpSignature( IN_BUFFER( signatureDataLength ) const void *signatureData,
IN_LENGTH_SHORT const int signatureDataLength,
IN_HANDLE const CRYPT_CONTEXT iSigCheckContext,
IN_HANDLE const CRYPT_CONTEXT iHashContext,
IN_ENUM( SIGNATURE ) const SIGNATURE_TYPE signatureType )
{
DLP_PARAMS dlpParams;
MESSAGE_DATA msgData;
BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
int hashSize, status;
REQUIRES( signatureDataLength > 40 && \
signatureDataLength < MAX_INTLENGTH_SHORT );
REQUIRES( isHandleRangeValid( iSigCheckContext ) );
REQUIRES( isHandleRangeValid( iHashContext ) );
REQUIRES( signatureType > SIGNATURE_NONE && \
signatureType < SIGNATURE_LAST );
/* Extract the hash value from the context */
setMessageData( &msgData, hash, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_HASHVALUE );
if( cryptStatusError( status ) )
return( status );
hashSize = msgData.length;
/* Standard DSA is only defined for hash algorithms with a block size of
160 bits, FIPS 186-3 extends this to allow use with larger hashes so
all we do is require at least 160 bits, which also works for ECC
algorithms */
if( hashSize < 20 )
{
/* The error reporting here is a bit complex, see the comment in
createSignature() for how this works */
return( CRYPT_ARGERROR_NUM1 );
}
/* Check the signature validity using the encoded signature data and
hash */
setDLPParams( &dlpParams, hash, hashSize, NULL, 0 );
dlpParams.inParam2 = signatureData;
dlpParams.inLen2 = signatureDataLength;
if( signatureType == SIGNATURE_PGP )
dlpParams.formatType = CRYPT_FORMAT_PGP;
if( signatureType == SIGNATURE_SSH )
dlpParams.formatType = CRYPT_IFORMAT_SSH;
return( krnlSendMessage( iSigCheckContext, IMESSAGE_CTX_SIGCHECK,
&dlpParams, sizeof( DLP_PARAMS ) ) );
}
/****************************************************************************
* *
* Create a Signature *
* *
****************************************************************************/
/* Common signature-creation routine, used by other sign_xxx.c modules */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
int createSignature( OUT_BUFFER_OPT( sigMaxLength, *signatureLength ) \
void *signature,
IN_LENGTH_Z const int sigMaxLength,
OUT_LENGTH_Z int *signatureLength,
IN_HANDLE const CRYPT_CONTEXT iSignContext,
IN_HANDLE const CRYPT_CONTEXT iHashContext,
IN_HANDLE_OPT const CRYPT_CONTEXT iHashContext2,
IN_ENUM( SIGNATURE ) const SIGNATURE_TYPE signatureType )
{
CRYPT_ALGO_TYPE signAlgo, hashAlgo;
STREAM stream;
const WRITESIG_FUNCTION writeSigFunction = getWriteSigFunction( signatureType );
BYTE buffer[ CRYPT_MAX_PKCSIZE + 8 ];
BYTE *bufPtr = ( signature == NULL ) ? NULL : buffer;
const int bufSize = ( signature == NULL ) ? 0 : CRYPT_MAX_PKCSIZE;
int length = DUMMY_INIT, status;
assert( ( signature == NULL && sigMaxLength == 0 ) || \
isWritePtr( signature, sigMaxLength ) );
assert( isWritePtr( signatureLength, sizeof( int ) ) );
REQUIRES( ( signature == NULL && sigMaxLength == 0 ) || \
( signature != NULL && \
sigMaxLength > MIN_CRYPT_OBJECTSIZE && \
sigMaxLength < MAX_INTLENGTH ) );
REQUIRES( isHandleRangeValid( iSignContext ) );
REQUIRES( isHandleRangeValid( iHashContext ) );
REQUIRES( ( signatureType == SIGNATURE_SSL && \
isHandleRangeValid( iHashContext2 ) ) || \
( ( signatureType == SIGNATURE_CMS || \
signatureType == SIGNATURE_CRYPTLIB || \
signatureType == SIGNATURE_PGP || \
signatureType == SIGNATURE_RAW || \
signatureType == SIGNATURE_SSH || \
signatureType == SIGNATURE_X509 ) && \
iHashContext2 == CRYPT_UNUSED ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -