📄 mech_sig.c
字号:
setMessageData( &msgData, hash2, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( mechanismInfo->hashContext2,
IMESSAGE_GETATTRIBUTE_S, &msgData,
CRYPT_CTXINFO_HASHVALUE );
if( cryptStatusError( status ) )
return( status );
hashSize2 = msgData.length;
}
/* Encode the payload as required */
sMemOpen( &stream, mechanismInfo->signature, length );
switch( type )
{
case SIGN_PKCS1:
{
int payloadSize;
/* Encode the payload using the PKCS #1 format:
[ 0 ][ 1 ][ 0xFF padding ][ 0 ][ payload ] */
payloadSize = sizeofMessageDigest( hashAlgo, hashSize );
sputc( &stream, 0 );
sputc( &stream, 1 );
for( i = 0; i < length - ( payloadSize + 3 ); i++ )
sputc( &stream, 0xFF );
sputc( &stream, 0 );
status = writeMessageDigest( &stream, hashAlgo, hash, hashSize );
break;
}
case SIGN_SSL:
REQUIRES( hashAlgo == CRYPT_ALGO_MD5 );
/* Encode the payload using the PKCS #1 SSL format:
[ 0 ][ 1 ][ 0xFF padding ][ 0 ][ MD5 hash ][ SHA1 hash ] */
sputc( &stream, 0 );
sputc( &stream, 1 );
for( i = 0; i < length - ( hashSize + hashSize2 + 3 ); i++ )
sputc( &stream, 0xFF );
sputc( &stream, 0 );
swrite( &stream, hash, hashSize );
status = swrite( &stream, hash2, hashSize2 );
break;
default:
retIntError();
}
ENSURES( cryptStatusError( status ) || stell( &stream ) == length );
sMemDisconnect( &stream );
if( cryptStatusError( status ) )
{
zeroise( mechanismInfo->signature, mechanismInfo->signatureLength );
return( status );
}
/* If we're using side-channel protection remember a copy of the
signature data for later so that we can check it against the
recovered signature data */
if( sideChannelProtectionLevel > 0 )
memcpy( preSigData, mechanismInfo->signature, length );
/* Sign the data */
status = krnlSendMessage( mechanismInfo->signContext,
IMESSAGE_CTX_SIGN, mechanismInfo->signature,
length );
if( cryptStatusError( status ) )
{
zeroise( mechanismInfo->signature, mechanismInfo->signatureLength );
return( status );
}
mechanismInfo->signatureLength = length;
/* If we're using side-channel protection check that the signature
verifies */
if( sideChannelProtectionLevel > 0 )
{
status = checkRecoveredSignature( mechanismInfo->signContext,
preSigData, length,
mechanismInfo->signature, length );
zeroise( preSigData, CRYPT_MAX_PKCSIZE );
if( cryptStatusError( status ) )
{
zeroise( mechanismInfo->signature, length );
mechanismInfo->signatureLength = 0;
return( status );
}
}
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int sigcheck( INOUT MECHANISM_SIGN_INFO *mechanismInfo,
IN_ENUM( SIGN ) const SIGN_TYPE type )
{
CRYPT_ALGO_TYPE contextHashAlgo = DUMMY_INIT;
MESSAGE_DATA msgData;
STREAM stream;
BYTE decryptedSignature[ CRYPT_MAX_PKCSIZE + 8 ];
BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
int length, hashSize = DUMMY_INIT, status;
assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_SIGN_INFO ) ) );
REQUIRES( type > SIGN_NONE && type < SIGN_LAST );
/* Get various algorithm parameters */
status = getPkcAlgoParams( mechanismInfo->signContext, NULL,
&length );
if( cryptStatusOK( status ) )
status = getHashAlgoParams( mechanismInfo->hashContext,
&contextHashAlgo, NULL );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, hash, CRYPT_MAX_HASHSIZE );
status = krnlSendMessage( mechanismInfo->hashContext,
IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_HASHVALUE );
if( cryptStatusOK( status ) )
hashSize = msgData.length;
}
if( cryptStatusError( status ) )
return( status );
/* Format the input data as required for the signatue check to work */
status = adjustPKCS1Data( decryptedSignature, CRYPT_MAX_PKCSIZE,
mechanismInfo->signature, mechanismInfo->signatureLength,
length );
if( cryptStatusError( status ) )
return( status );
/* Recover the signed data */
status = krnlSendMessage( mechanismInfo->signContext,
IMESSAGE_CTX_SIGCHECK, decryptedSignature,
length );
if( cryptStatusError( status ) )
return( status );
/* Decode the payload as required */
sMemConnect( &stream, decryptedSignature, length );
switch( type )
{
case SIGN_PKCS1:
/* The payload is an ASN.1-encoded hash, process it very
carefully */
status = decodePKCS1( &stream, length );
if( cryptStatusError( status ) )
break;
status = compareHashInfo( &stream, contextHashAlgo, hash,
hashSize );
break;
case SIGN_SSL:
{
BYTE hash2[ CRYPT_MAX_HASHSIZE + 8 ];
REQUIRES( contextHashAlgo == CRYPT_ALGO_MD5 );
/* The payload is [ MD5 hash ][ SHA1 hash ] */
status = decodePKCS1( &stream, length );
if( cryptStatusError( status ) )
break;
status = sread( &stream, hash, 16 );
if( cryptStatusOK( status ) )
status = sread( &stream, hash2, 20);
if( cryptStatusError( status ) )
break;
/* Make sure that the two hash values match */
setMessageData( &msgData, hash, 16 );
status = krnlSendMessage( mechanismInfo->hashContext,
IMESSAGE_COMPARE, &msgData,
MESSAGE_COMPARE_HASH );
if( cryptStatusOK( status ) )
{
setMessageData( &msgData, hash2, 20 );
status = krnlSendMessage( mechanismInfo->hashContext2,
IMESSAGE_COMPARE, &msgData,
MESSAGE_COMPARE_HASH );
}
/* Clean up */
zeroise( hash2, CRYPT_MAX_HASHSIZE );
break;
}
default:
retIntError();
}
if( cryptStatusOK( status ) && sMemDataLeft( &stream ) != 0 )
{
/* Make sure that's all that there is. This is already checked
implicitly anderswhere but we make the check explicit here */
status = CRYPT_ERROR_BADDATA;
}
sMemDisconnect( &stream );
/* Clean up */
zeroise( decryptedSignature, CRYPT_MAX_PKCSIZE );
zeroise( hash, CRYPT_MAX_HASHSIZE );
return( cryptStatusError( status ) ? CRYPT_ERROR_SIGNATURE : status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
int signPKCS1( STDC_UNUSED void *dummy,
INOUT MECHANISM_SIGN_INFO *mechanismInfo )
{
UNUSED_ARG( dummy );
assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_SIGN_INFO ) ) );
return( sign( mechanismInfo, SIGN_PKCS1 ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
int sigcheckPKCS1( STDC_UNUSED void *dummy,
INOUT MECHANISM_SIGN_INFO *mechanismInfo )
{
UNUSED_ARG( dummy );
assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_SIGN_INFO ) ) );
return( sigcheck( mechanismInfo, SIGN_PKCS1 ) );
}
#ifdef USE_SSL
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
int signSSL( STDC_UNUSED void *dummy,
INOUT MECHANISM_SIGN_INFO *mechanismInfo )
{
UNUSED_ARG( dummy );
assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_SIGN_INFO ) ) );
return( sign( mechanismInfo, SIGN_SSL ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
int sigcheckSSL( STDC_UNUSED void *dummy,
INOUT MECHANISM_SIGN_INFO *mechanismInfo )
{
UNUSED_ARG( dummy );
assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_SIGN_INFO ) ) );
return( sigcheck( mechanismInfo, SIGN_SSL ) );
}
#endif /* USE_SSL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -