📄 sign.c
字号:
signing attributes present */
if( extraData != NULL )
return( CRYPT_ERROR_PARAM5 );
break;
case CRYPT_FORMAT_CMS:
case CRYPT_FORMAT_SMIME:
if( extraData != NULL )
{
if( !isWritePtr( extraData, sizeof( int ) ) )
return( CRYPT_ERROR_PARAM6 );
*extraData = CRYPT_ERROR;
}
break;
#ifdef USE_PGP
case CRYPT_FORMAT_PGP:
/* PGP doesn't have signing attributes */
if( extraData != NULL )
return( CRYPT_ERROR_PARAM5 );
break;
#endif /* USE_PGP */
default:
retIntError();
}
/* Call the low-level signature create function to check the signature */
status = iCryptCheckSignature( signature, signatureLength, formatType,
sigCheckKey, hashContext, CRYPT_UNUSED,
( extraData != NULL ) ? &iExtraData : NULL );
if( cryptArgError( status ) )
{
/* Remap the error code to refer to the correct parameter */
status = ( status == CRYPT_ARGERROR_NUM1 ) ? \
CRYPT_ERROR_PARAM3 : CRYPT_ERROR_PARAM4;
}
if( extraData != NULL )
{
/* Make the recovered signing attributes externally visible. Bailing
out if this operation fails may be a bit excessive in that the
signature has already verified so failing the whole operation just
because we can't make auxiliary attributes visible could be seen
as overkill, however since the caller has indicated an interest in
the attributes it can be argued that an inability to return them
is as serious as a general sig.check failure */
status = krnlSendMessage( iExtraData, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_INTERNAL );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iExtraData, IMESSAGE_DECREFCOUNT );
return( status );
}
*extraData = iExtraData;
}
return( status );
}
C_RET cryptCheckSignature( C_IN void C_PTR signature,
C_IN int signatureLength,
C_IN CRYPT_HANDLE sigCheckKey,
C_IN CRYPT_CONTEXT hashContext )
{
return( cryptCheckSignatureEx( signature, signatureLength, sigCheckKey,
hashContext, NULL ) );
}
/****************************************************************************
* *
* Internal Import/Export Functions *
* *
****************************************************************************/
/* Internal versions of the above. These skip a lot of the explicit
checking done by the external versions (e.g. "Is this value really a
handle to a valid PKC context?") since they're only called by cryptlib
internal functions rather than being passed untrusted user data. In
addition the iExtraData value can take an extra value CRYPT_UNUSED
(don't use any signing attributes) */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
int iCryptCreateSignature( OUT_BUFFER_OPT( signatureMaxLength, *signatureLength ) \
void *signature,
IN_LENGTH const int signatureMaxLength,
OUT_LENGTH_Z int *signatureLength,
IN_ENUM( CRYPT_FORMAT ) \
const CRYPT_FORMAT_TYPE formatType,
IN_HANDLE const CRYPT_CONTEXT iSignContext,
IN_HANDLE const CRYPT_CONTEXT iHashContext,
IN_HANDLE_OPT const CRYPT_CERTIFICATE iExtraData,
IN_HANDLE_OPT const CRYPT_SESSION iTspSession )
{
CRYPT_CERTTYPE_TYPE certType;
int status;
assert( signature == NULL || isWritePtr( signature, signatureMaxLength ) );
assert( isWritePtr( signatureLength, sizeof( int ) ) );
REQUIRES( ( signature == NULL && signatureMaxLength == 0 ) || \
( signature != NULL && \
signatureMaxLength > MIN_CRYPT_OBJECTSIZE && \
signatureMaxLength < MAX_INTLENGTH ) );
REQUIRES( formatType > CRYPT_FORMAT_NONE && \
formatType < CRYPT_FORMAT_LAST );
REQUIRES( isHandleRangeValid( iSignContext ) );
REQUIRES( isHandleRangeValid( iHashContext ) );
REQUIRES( ( formatType == CRYPT_IFORMAT_SSL && \
isHandleRangeValid( iExtraData ) ) || \
( ( formatType == CRYPT_FORMAT_CMS || \
formatType == CRYPT_FORMAT_SMIME ) && \
( iExtraData == CRYPT_UNUSED || \
iExtraData == CRYPT_USE_DEFAULT || \
isHandleRangeValid( iExtraData ) ) ) || \
( iExtraData == CRYPT_UNUSED ) );
REQUIRES( ( ( formatType == CRYPT_FORMAT_CMS || \
formatType == CRYPT_FORMAT_SMIME ) && \
( ( iTspSession == CRYPT_UNUSED ) || \
isHandleRangeValid( iTspSession ) ) ) || \
( iTspSession == CRYPT_UNUSED ) );
/* Clear return value */
*signatureLength = 0;
/* If the signing context has a cert chain attached then the currently-
selected cert may not be the leaf cert. To ensure that we use the
correct cert we lock the chain (which both protects us from having
the user select a different cert while we're using it and saves the
selection state for when we later unlock it) and explicitly select
the leaf cert. Certs are used for formats other than the obvious
CRYPT_FORMAT_CMS/CRYPT_FORMAT_SMIME so we perform this operation
unconditionally rather than only for those two formats */
status = krnlSendMessage( iSignContext, MESSAGE_GETATTRIBUTE,
&certType, CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) )
{
/* There's no cert of the required type attached */
certType = CRYPT_CERTTYPE_NONE;
}
else
{
/* If it's a cert chain, lock it and select the leaf cert */
if( certType == CRYPT_CERTTYPE_CERTCHAIN )
{
status = krnlSendMessage( iSignContext, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE,
CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusError( status ) )
return( status );
status = krnlSendMessage( iSignContext, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_CURSORFIRST,
CRYPT_CERTINFO_CURRENT_CERTIFICATE );
if( cryptStatusError( status ) )
{
( void ) krnlSendMessage( iSignContext, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_LOCKED );
return( status );
}
}
}
/* Call the low-level signature create function to create the signature */
switch( formatType )
{
case CRYPT_FORMAT_CRYPTLIB:
status = createSignature( signature, signatureMaxLength,
signatureLength, iSignContext,
iHashContext, CRYPT_UNUSED,
SIGNATURE_CRYPTLIB );
break;
#ifdef USE_PGP
case CRYPT_FORMAT_PGP:
status = createSignaturePGP( signature, signatureMaxLength,
signatureLength, iSignContext,
iHashContext );
break;
#endif /* USE_PGP */
#ifdef USE_SSL
case CRYPT_IFORMAT_SSL:
status = createSignature( signature, signatureMaxLength,
signatureLength, iSignContext,
iHashContext, iExtraData,
SIGNATURE_SSL );
break;
#endif /* USE_SSL */
#ifdef USE_SSH
case CRYPT_IFORMAT_SSH:
status = createSignature( signature, signatureMaxLength,
signatureLength, iSignContext,
iHashContext, CRYPT_UNUSED,
SIGNATURE_SSH );
break;
#endif /* USE_SSH */
case CRYPT_FORMAT_CMS:
case CRYPT_FORMAT_SMIME:
status = createSignatureCMS( signature, signatureMaxLength,
signatureLength, iSignContext,
iHashContext, iExtraData,
iTspSession, formatType );
break;
default:
retIntError();
}
if( cryptArgError( status ) )
{
/* Catch any parameter errors that slip through */
assert( DEBUG_WARN );
status = CRYPT_ERROR_FAILED;
}
if( certType == CRYPT_CERTTYPE_CERTCHAIN )
{
/* We're signing with a cert chain, restore its state and unlock it
to allow others access. If this fails there's not much that we
can do to recover so we don't do anything with the return
value */
( void ) krnlSendMessage( iSignContext, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_LOCKED );
}
return( status );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int iCryptCheckSignature( IN_BUFFER( signatureLength ) const void *signature,
IN_LENGTH_SHORT const int signatureLength,
IN_ENUM( CRYPT_FORMAT ) \
const CRYPT_FORMAT_TYPE formatType,
IN_HANDLE const CRYPT_HANDLE iSigCheckKey,
IN_HANDLE const CRYPT_CONTEXT iHashContext,
IN_HANDLE const CRYPT_CONTEXT iHash2Context,
OUT_OPT_HANDLE_OPT CRYPT_HANDLE *extraData )
{
CRYPT_CONTEXT sigCheckContext;
int status;
assert( isReadPtr( signature, signatureLength ) );
REQUIRES( signatureLength > 40 && \
signatureLength < MAX_INTLENGTH_SHORT );
REQUIRES( formatType > CRYPT_FORMAT_NONE && \
formatType < CRYPT_FORMAT_LAST );
REQUIRES( isHandleRangeValid( iSigCheckKey ) );
REQUIRES( isHandleRangeValid( iHashContext ) );
REQUIRES( ( formatType == CRYPT_IFORMAT_SSL && \
isHandleRangeValid( iHash2Context ) && extraData == NULL ) || \
( ( formatType == CRYPT_FORMAT_CMS || CRYPT_FORMAT_SMIME ) && \
iHash2Context == CRYPT_UNUSED ) || \
( iHash2Context == CRYPT_UNUSED && extraData == NULL ) );
/* Perform basic error checking */
status = krnlSendMessage( iSigCheckKey, IMESSAGE_GETDEPENDENT,
&sigCheckContext, OBJECT_TYPE_CONTEXT );
if( cryptStatusError( status ) )
return( status );
/* Call the low-level signature check function to check the signature */
switch( formatType )
{
case CRYPT_FORMAT_CRYPTLIB:
status = checkSignature( signature, signatureLength,
sigCheckContext, iHashContext,
CRYPT_UNUSED, SIGNATURE_CRYPTLIB );
break;
#ifdef USE_PGP
case CRYPT_FORMAT_PGP:
status = checkSignaturePGP( signature, signatureLength,
sigCheckContext, iHashContext );
break;
#endif /* USE_PGP */
#ifdef USE_SSL
case CRYPT_IFORMAT_SSL:
status = checkSignature( signature, signatureLength,
sigCheckContext, iHashContext,
iHash2Context, SIGNATURE_SSL );
break;
#endif /* USE_SSL */
#ifdef USE_SSH
case CRYPT_IFORMAT_SSH:
status = checkSignature( signature, signatureLength,
sigCheckContext, iHashContext,
CRYPT_UNUSED, SIGNATURE_SSH );
break;
#endif /* USE_SSH */
case CRYPT_FORMAT_CMS:
case CRYPT_FORMAT_SMIME:
if( extraData != NULL )
*extraData = CRYPT_ERROR;
status = checkSignatureCMS( signature, signatureLength,
sigCheckContext, iHashContext,
extraData, iSigCheckKey );
break;
default:
retIntError();
}
if( cryptArgError( status ) )
{
/* Catch any parameter errors that slip through */
assert( DEBUG_WARN );
status = CRYPT_ERROR_SIGNATURE;
}
return( status );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -