📄 sign_int.c
字号:
/* Make sure that the requested signature format is available */
if( writeSigFunction == NULL )
return( CRYPT_ERROR_NOTAVAIL );
/* Extract general information */
status = krnlSendMessage( iSignContext, IMESSAGE_GETATTRIBUTE, &signAlgo,
CRYPT_CTXINFO_ALGO );
if( cryptStatusError( status ) )
return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM1 : status );
status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE,
&hashAlgo, CRYPT_CTXINFO_ALGO );
if( cryptStatusError( status ) )
return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM2 : status );
/* DLP and ECC signatures are handled somewhat specially */
if( isDlpAlgo( signAlgo ) || isEccAlgo( signAlgo ) )
{
status = createDlpSignature( bufPtr, bufSize, &length, iSignContext,
iHashContext, signatureType );
}
else
{
MECHANISM_SIGN_INFO mechanismInfo;
/* It's a standard signature, process it as normal */
setMechanismSignInfo( &mechanismInfo, bufPtr, bufSize, iHashContext,
iHashContext2, iSignContext );
status = krnlSendMessage( iSignContext, IMESSAGE_DEV_SIGN, &mechanismInfo,
( signatureType == SIGNATURE_SSL ) ? \
MECHANISM_SIG_SSL : MECHANISM_SIG_PKCS1 );
if( cryptStatusOK( status ) )
length = mechanismInfo.signatureLength;
clearMechanismInfo( &mechanismInfo );
}
if( cryptStatusError( status ) )
{
/* The mechanism messages place the acted-on object (in this case the
hash context) first while the higher-level functions place the
signature context next to the signature data, in other words
before the hash context. Because of this we have to reverse
parameter error values when translating from the mechanism to the
signature function level */
if( bufPtr != NULL )
zeroise( bufPtr, CRYPT_MAX_PKCSIZE );
return( ( status == CRYPT_ARGERROR_NUM1 ) ? \
CRYPT_ARGERROR_NUM2 : \
( status == CRYPT_ARGERROR_NUM2 ) ? \
CRYPT_ARGERROR_NUM1 : status );
}
/* If we're perfoming a dummy sign for a length check, set up a dummy
value to write */
if( signature == NULL )
memset( buffer, 0x01, length );
/* Write the signature record to the output */
sMemOpenOpt( &stream, signature, sigMaxLength );
status = writeSigFunction( &stream, iSignContext, hashAlgo, signAlgo,
buffer, length );
if( cryptStatusOK( status ) )
*signatureLength = stell( &stream );
sMemDisconnect( &stream );
/* Clean up */
zeroise( buffer, CRYPT_MAX_PKCSIZE );
return( status );
}
/****************************************************************************
* *
* Check a Signature *
* *
****************************************************************************/
/* Common signature-checking routine, used by other sign_xxx.c modules */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int checkSignature( IN_BUFFER( signatureLength ) const void *signature,
IN_LENGTH_SHORT const int signatureLength,
IN_HANDLE const CRYPT_CONTEXT iSigCheckContext,
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;
MECHANISM_SIGN_INFO mechanismInfo;
const READSIG_FUNCTION readSigFunction = getReadSigFunction( signatureType );
QUERY_INFO queryInfo;
STREAM stream;
void *signatureData;
int signatureDataLength, status;
assert( isReadPtr( signature, signatureLength ) );
REQUIRES( signatureLength > 40 && \
signatureLength < MAX_INTLENGTH_SHORT );
REQUIRES( isHandleRangeValid( iSigCheckContext ) );
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 ) );
/* Make sure that the requested signature format is available */
if( readSigFunction == NULL )
return( CRYPT_ERROR_NOTAVAIL );
/* Extract general information */
status = krnlSendMessage( iSigCheckContext, IMESSAGE_GETATTRIBUTE,
&signAlgo, CRYPT_CTXINFO_ALGO );
if( cryptStatusError( status ) )
return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM1 : status );
status = krnlSendMessage( iHashContext, IMESSAGE_GETATTRIBUTE,
&hashAlgo, CRYPT_CTXINFO_ALGO );
if( cryptStatusError( status ) )
return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM2 : status );
/* Read and check the signature record */
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 );
}
/* Make sure that we've been given the correct algorithms. Raw
signatures specify the algorithm information elsewhere so the check
is done at a higher level when we process the signature data */
if( signatureType != SIGNATURE_RAW && signatureType != SIGNATURE_SSL )
{
if( signAlgo != queryInfo.cryptAlgo )
status = CRYPT_ERROR_SIGNATURE;
if( signatureType != SIGNATURE_SSH && \
hashAlgo != queryInfo.hashAlgo )
status = CRYPT_ERROR_SIGNATURE;
if( cryptStatusError( status ) )
{
zeroise( &queryInfo, sizeof( QUERY_INFO ) );
return( status );
}
}
/* Make sure that we've been given the correct key if the signature
format supports this type of check. SIGNATURE_CMS supports a check
with MESSAGE_COMPARE_ISSUERANDSERIALNUMBER but this has already been
done while procesing the other CMS data before we were called so we
don't need to do it again */
if( signatureType == SIGNATURE_CRYPTLIB || \
signatureType == SIGNATURE_PGP )
{
MESSAGE_DATA msgData;
setMessageData( &msgData, queryInfo.keyID, queryInfo.keyIDlength );
status = krnlSendMessage( iSigCheckContext, IMESSAGE_COMPARE,
&msgData,
( signatureType == SIGNATURE_CRYPTLIB ) ? \
MESSAGE_COMPARE_KEYID : \
( queryInfo.version == PGP_VERSION_2 ) ? \
MESSAGE_COMPARE_KEYID_PGP : \
MESSAGE_COMPARE_KEYID_OPENPGP );
if( cryptStatusError( status ) )
{
/* A failed comparison is reported as a generic CRYPT_ERROR,
convert it into a wrong-key error if necessary */
zeroise( &queryInfo, sizeof( QUERY_INFO ) );
return( ( status == CRYPT_ERROR ) ? \
CRYPT_ERROR_WRONGKEY : status );
}
}
REQUIRES( rangeCheck( queryInfo.dataStart, queryInfo.dataLength,
signatureLength ) );
signatureData = ( BYTE * ) signature + queryInfo.dataStart;
signatureDataLength = queryInfo.dataLength;
zeroise( &queryInfo, sizeof( QUERY_INFO ) );
/* DLP and ECC signatures are handled somewhat specially */
if( isDlpAlgo( signAlgo ) || isEccAlgo( signAlgo ) )
{
return( checkDlpSignature( signatureData, signatureDataLength,
iSigCheckContext, iHashContext,
signatureType ) );
}
/* It's a standard signature, process it as normal */
setMechanismSignInfo( &mechanismInfo, signatureData, signatureDataLength,
iHashContext, iHashContext2, iSigCheckContext );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_SIGCHECK,
&mechanismInfo,
( signatureType == SIGNATURE_SSL ) ? \
MECHANISM_SIG_SSL : MECHANISM_SIG_PKCS1 );
clearMechanismInfo( &mechanismInfo );
if( cryptStatusError( status ) )
{
/* The mechanism messages place the acted-on object (in this case the
hash context) first while the higher-level functions place the
signature context next to the signature data, in other words
before the hash context. Because of this we have to reverse
parameter error values when translating from the mechanism to the
signature function level */
return( ( status == CRYPT_ARGERROR_NUM1 ) ? \
CRYPT_ARGERROR_NUM2 : \
( status == CRYPT_ARGERROR_NUM2 ) ? \
CRYPT_ARGERROR_NUM1 : status );
}
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -