cryptcrt.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 960 行 · 第 1/3 页
C
960 行
return( CRYPT_OK );
}
if( message == RESOURCE_MESSAGE_UNLOCK )
{
/* Restore the volatile state from before the object was locked */
restoreSelectionState( certInfoPtr->selectionState, certInfoPtr );
/* "Wenn drei Leute in ein Zimmer reingehen und fuenf kommen raus,
dann muessen erst mal zwei wieder reingehen bis das Zimmer leer
ist" */
unlockResource( certInfoPtr ); /* Undo RESOURCE_MESSAGE_LOCK lock */
unlockResourceExit( certInfoPtr, CRYPT_OK );
}
/* Process object-specific messages */
if( message == RESOURCE_MESSAGE_CRT_SIGN )
{
int status;
assert( certInfoPtr->certificate == NULL );
/* Make sure the signing object can actually be used for signing, the
sole exception is a CRMF request which can be created with an
encryption-only key if the private key POP is performed via an
out-of-band mechanism */
status = krnlSendMessage( messageValue, RESOURCE_IMESSAGE_CHECK, NULL,
RESOURCE_MESSAGE_CHECK_PKC_SIGN );
if( cryptStatusError( status ) && \
certInfoPtr->type != CRYPT_CERTTYPE_REQUEST_CERT )
unlockResourceExit( certInfoPtr, CRYPT_ARGERROR_VALUE );
/* We're changing data in a certificate, clear the error
information */
clearErrorInfo( certInfoPtr );
status = signCert( certInfoPtr, messageValue );
unlockResourceExit( certInfoPtr, status );
}
if( message == RESOURCE_MESSAGE_CRT_SIGCHECK )
{
int status;
assert( certInfoPtr->certificate != NULL || \
certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );
/* We're checking data in a certificate, clear the error
information */
clearErrorInfo( certInfoPtr );
status = checkCertValidity( certInfoPtr, messageValue );
unlockResourceExit( certInfoPtr, status );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/* Create a certificate object, returning a pointer to the locked cert info
ready for further initialisation */
int createCertificateInfo( CERT_INFO **certInfoPtrPtr,
const CRYPT_USER cryptOwner,
const CRYPT_CERTTYPE_TYPE certType )
{
CRYPT_CERTIFICATE iCertificate;
CERT_INFO *certInfoPtr;
const int subType = \
/* Standard types */
( certType == CRYPT_CERTTYPE_CERTIFICATE ) ? SUBTYPE_CERT_CERT : \
( certType == CRYPT_CERTTYPE_ATTRIBUTE_CERT ) ? SUBTYPE_CERT_ATTRCERT : \
( certType == CRYPT_CERTTYPE_CERTCHAIN ) ? SUBTYPE_CERT_CERTCHAIN : \
( certType == CRYPT_CERTTYPE_CERTREQUEST ) ? SUBTYPE_CERT_CERTREQ : \
( certType == CRYPT_CERTTYPE_REQUEST_CERT ) ? SUBTYPE_CERT_REQ_CERT : \
( certType == CRYPT_CERTTYPE_REQUEST_REVOCATION ) ? SUBTYPE_CERT_REQ_REV : \
( certType == CRYPT_CERTTYPE_CRL ) ? SUBTYPE_CERT_CRL : \
( certType == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? SUBTYPE_CERT_CMSATTR : \
( certType == CRYPT_CERTTYPE_OCSP_REQUEST ) ? SUBTYPE_CERT_OCSP_REQ : \
( certType == CRYPT_CERTTYPE_OCSP_RESPONSE ) ? SUBTYPE_CERT_OCSP_RESP : \
( certType == CRYPT_CERTTYPE_PKIUSER ) ? SUBTYPE_CERT_PKIUSER : 0;
assert( certInfoPtrPtr != NULL );
assert( subType != 0 );
*certInfoPtrPtr = NULL;
/* Create the certificate object */
iCertificate = krnlCreateObject( ( void ** ) &certInfoPtr, cryptOwner,
OBJECT_TYPE_CERTIFICATE, subType,
sizeof( CERT_INFO ), 0, 0,
certificateMessageFunction );
if( cryptStatusError( iCertificate ) )
return( iCertificate );
initResourceLock( certInfoPtr );
lockResource( certInfoPtr );
certInfoPtr->objectHandle = iCertificate;
certInfoPtr->ownerHandle = cryptOwner;
certInfoPtr->type = certType;
/* Set up any internal objects to contain invalid handles */
certInfoPtr->iCryptContext = CRYPT_ERROR;
/* Set the state information to its initial state */
certInfoPtr->certChainPos = CRYPT_ERROR;
certInfoPtr->trustedUsage = CRYPT_ERROR;
/* Return the locked cert info pointer */
*certInfoPtrPtr = certInfoPtr;
return( iCertificate );
}
/* Create a certificate */
int createCertificate( MESSAGE_CREATEOBJECT_INFO *createInfo,
const void *auxDataPtr, const int auxValue )
{
CRYPT_CERTIFICATE iCertificate;
CERT_INFO *certInfoPtr;
int status;
assert( auxDataPtr == NULL );
assert( auxValue == 0 );
assert( createInfo->arg2 == 0 );
assert( createInfo->strArg1 == NULL );
assert( createInfo->strArgLen1 == 0 );
/* Perform basic error checking */
if( createInfo->arg1 <= CRYPT_CERTTYPE_NONE || \
createInfo->arg1 >= CRYPT_CERTTYPE_LAST )
return( CRYPT_ARGERROR_NUM1 );
status = createCertificateInfo( &certInfoPtr, createInfo->cryptOwner,
createInfo->arg1 );
if( cryptStatusError( status ) )
return( status );
iCertificate = status;
/* We've finished setting up the object-type-specific info, tell the
kernel the object is ready for use */
unlockResource( certInfoPtr );
status = krnlSendMessage( iCertificate, RESOURCE_IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
if( cryptStatusOK( status ) )
createInfo->cryptHandle = iCertificate;
return( status );
}
/* Create a certificate by instantiating it from its encoded form */
int createCertificateIndirect( MESSAGE_CREATEOBJECT_INFO *createInfo,
const void *auxDataPtr, const int auxValue )
{
CRYPT_CERTIFICATE iCertificate;
int status;
assert( auxDataPtr == NULL );
assert( auxValue == 0 );
assert( createInfo->arg1 >= CERTFORMAT_NORMAL && \
createInfo->arg1 < CERTFORMAT_LAST );
assert( createInfo->strArg1 != NULL );
assert( createInfo->strArgLen1 > 16 ); /* May be CMS attr.*/
assert( ( createInfo->arg2 == 0 && createInfo->strArg2 == NULL && \
createInfo->strArgLen2 == 0 ) || \
( ( createInfo->arg2 == CRYPT_IKEYID_KEYID || \
createInfo->arg2 == CRYPT_IKEYID_ISSUERANDSERIALNUMBER ) && \
createInfo->strArg2 != NULL && createInfo->strArgLen2 > 2 ) );
/* Pass the call through to the low-level import function. This returns
a length value so we convert it to a proper status for the caller */
status = importCert( createInfo->strArg1, createInfo->strArgLen1,
&iCertificate, createInfo->cryptOwner,
createInfo->arg2, createInfo->strArg2,
createInfo->strArgLen2, createInfo->arg1 );
if( !cryptStatusError( status ) )
{
createInfo->cryptHandle = iCertificate;
return( CRYPT_OK );
}
return( status );
}
/* Get/add/delete certificate attributes */
C_RET cryptGetCertExtension( C_IN CRYPT_HANDLE cryptHandle,
C_IN char C_PTR oid,
C_OUT int C_PTR criticalFlag,
C_OUT void C_PTR extension,
C_OUT int C_PTR extensionLength )
{
CRYPT_CERTIFICATE certificate;
CERT_INFO *certInfoPtr;
ATTRIBUTE_LIST *attributeListPtr;
BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
BOOLEAN returnData = ( extension != NULL ) ? TRUE : FALSE;
int status;
/* Perform basic error checking */
status = krnlSendMessage( cryptHandle, RESOURCE_MESSAGE_GETDEPENDENT,
&certificate, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
CRYPT_ERROR_PARAM1 : status );
getCheckInternalResource( certificate, certInfoPtr,
OBJECT_TYPE_CERTIFICATE );
if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
if( checkBadPtrWrite( criticalFlag, sizeof( int ) ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
*criticalFlag = CRYPT_ERROR;
if( extension != NULL )
*( ( BYTE * ) extension ) = 0;
if( checkBadPtrWrite( extensionLength, sizeof( int ) ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM5 );
*extensionLength = CRYPT_ERROR;
/* Lock the currently selected cert in a cert chain if necessary */
if( certInfoPtr->certChainPos != CRYPT_ERROR )
{
CERT_INFO *certChainInfoPtr;
getCheckInternalResource( certInfoPtr->certChain[ certInfoPtr->certChainPos ],
certChainInfoPtr, OBJECT_TYPE_CERTIFICATE );
unlockResource( certInfoPtr );
certInfoPtr = certChainInfoPtr;
}
/* Convert the OID to its binary form and try and locate the attribute
identified by the OID */
if( !textToOID( oid, strlen( oid ), binaryOID ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
attributeListPtr = findAttributeByOID( certInfoPtr->attributes, binaryOID );
if( attributeListPtr == NULL )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_NOTFOUND );
*criticalFlag = ( attributeListPtr->flags & ATTR_FLAG_CRITICAL ) ? \
TRUE : FALSE;
*extensionLength = attributeListPtr->dataLength;
if( returnData )
{
const void *dataPtr = \
( attributeListPtr->dataLength <= CRYPT_MAX_TEXTSIZE ) ? \
attributeListPtr->smallData : attributeListPtr->data;
if( checkBadPtrWrite( extension, attributeListPtr->dataLength ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
memcpy( extension, dataPtr, attributeListPtr->dataLength );
}
unlockResourceExit( certInfoPtr, CRYPT_OK );
}
C_RET cryptAddCertExtension( C_IN CRYPT_CERTIFICATE certificate,
C_IN char C_PTR oid, C_IN int criticalFlag,
C_IN void C_PTR extension,
C_IN int extensionLength )
{
CERT_INFO *certInfoPtr;
BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
int status;
/* Perform basic error checking */
getCheckResource( certificate, certInfoPtr, OBJECT_TYPE_CERTIFICATE,
CRYPT_ERROR_PARAM1 );
if( certInfoPtr->certificate != NULL || \
certInfoPtr->certChainPos != CRYPT_ERROR )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PERMISSION );
if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
if( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES && \
criticalFlag != CRYPT_UNUSED )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
if( extensionLength <= 3 || extensionLength > MAX_ATTRIBUTE_SIZE )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM5 );
if( checkBadPtrRead( extension, extensionLength ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM4 );
status = checkObjectEncoding( extension, extensionLength );
if( cryptStatusError( status ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM4 );
/* Convert the OID to its binary form, copy the data to an internal
buffer, and add the attribute to the certificate */
if( !textToOID( oid, strlen( oid ), binaryOID ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
status = addAttribute( ( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, &certInfoPtr->attributes,
binaryOID, ( BOOLEAN ) /* Fix for VC++ */
( ( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? FALSE : \
criticalFlag ), extension, extensionLength );
if( status == CRYPT_ERROR_INITED )
/* If the attribute is already present, set error information for it.
We can't set an error locus since it's an unknown blob */
setErrorInfo( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
CRYPT_ERRTYPE_ATTR_PRESENT );
unlockResourceExit( certInfoPtr, status );
}
C_RET cryptDeleteCertExtension( C_IN CRYPT_CERTIFICATE certificate,
C_IN char C_PTR oid )
{
CERT_INFO *certInfoPtr;
ATTRIBUTE_LIST *attributeListPtr;
BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
/* Perform basic error checking */
getCheckResource( certificate, certInfoPtr, OBJECT_TYPE_CERTIFICATE,
CRYPT_ERROR_PARAM1 );
if( certInfoPtr->certificate != NULL || \
certInfoPtr->certChainPos != CRYPT_ERROR )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PERMISSION );
if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
/* Convert the OID to its binary form, find the attribute identified by
this OID, and delete it */
if( !textToOID( oid, strlen( oid ), binaryOID ) )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
attributeListPtr = findAttributeByOID( certInfoPtr->attributes, binaryOID );
if( attributeListPtr == NULL )
unlockResourceExit( certInfoPtr, CRYPT_ERROR_NOTFOUND );
deleteAttribute( &certInfoPtr->attributes, NULL, attributeListPtr );
unlockResourceExit( certInfoPtr, CRYPT_OK );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?