📄 ca_misc.c
字号:
/* Get the next partially-issued cert */
status = getNextPartialCert( dbmsInfo, &iCertificate, prevCertData,
FALSE );
if( status == CRYPT_ERROR_DUPLICATE )
/* We're stuck in a loop fetching the same cert over and over,
exit */
break;
if( cryptStatusOK( status ) )
{
/* We found a cert to revoke, complete the revocation */
status = revokeCertDirect( dbmsInfo, iCertificate,
CRYPT_CERTACTION_CERT_CREATION_REVERSE );
krnlSendNotifier( iCertificate, IMESSAGE_DECREFCOUNT );
}
else
errorCount++;
}
while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );
/* If we ran into a problem, perform a fallback general delete of
entries that caused the problem */
if( status != CRYPT_ERROR_NOTFOUND )
{
updateCertErrorLogMsg( dbmsInfo, status, "Partially-issued "
"certificate cleanup operation failed, "
"performing fallback straight delete" );
status = dbmsStaticUpdate(
"DELETE FROM certificates WHERE keyID LIKE '" KEYID_ESC1 "%'" );
if( cryptStatusError( status ) )
updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
"delete failed" );
}
/* Now process any partially-completed renewals */
memset( prevCertData, 0, 8 );
errorCount = 0;
do
{
CRYPT_CERTIFICATE iCertificate;
/* Get the next partially-completed cert */
status = getNextPartialCert( dbmsInfo, &iCertificate, prevCertData,
TRUE );
if( status == CRYPT_ERROR_DUPLICATE )
/* We're stuck in a loop fetching the same cert over and over,
exit */
break;
if( cryptStatusOK( status ) )
{
/* We found a partially-completed cert, complete the renewal */
status = completeCertRenewal( dbmsInfo, iCertificate );
krnlSendNotifier( iCertificate, IMESSAGE_DECREFCOUNT );
}
else
errorCount++;
}
while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );
/* Finally, process any pending revocations */
memset( prevCertData, 0, 8 );
errorCount = 0;
do
{
CRYPT_CERTIFICATE iCertRequest;
char certID[ MAX_QUERY_RESULT_SIZE ];
int certIDlength, dummy;
/* Find the next revocation request and import it. This is slightly
ugly since we could grab it directly by fetching the data based on
the request type field, but there's no way to easily get to the
low-level import functions from here so we have to first fetch the
cert ID and then pass that down to the lower-level functions to
fetch the actual request */
status = dbmsQuery(
"SELECT certID FROM certRequests WHERE type = "
TEXT_CERTTYPE_REQUEST_REVOCATION,
certID, &certIDlength, NULL, 0, 0,
DBMS_CACHEDQUERY_NONE, DBMS_QUERY_NORMAL );
if( cryptStatusError( status ) || \
certIDlength > MAX_ENCODED_DBXKEYID_SIZE )
{
errorCount++;
continue;
}
if( !memcmp( prevCertData, certID, certIDlength ) )
/* We're stuck in a loop fetching the same value over and over,
make an emergency exit */
break;
memcpy( prevCertData, certID, certIDlength );
status = getItemData( dbmsInfo, &iCertRequest, &dummy,
CRYPT_IKEYID_CERTID, certID, certIDlength,
KEYMGMT_ITEM_REQUEST, KEYMGMT_FLAG_NONE );
if( cryptStatusError( status ) )
{
errorCount++;
continue;
}
/* Complete the revocation */
status = caRevokeCert( dbmsInfo, iCertRequest, CRYPT_UNUSED,
CRYPT_CERTACTION_RESTART_REVOKE_CERT );
if( status == CRYPT_ERROR_NOTFOUND )
{
/* This is an allowable error type since the cert may have
expired or been otherwise removed after the revocation
request was received, just delete the entry */
certID[ certIDlength ] = '\0';
dbmsFormatSQL( sqlBuffer,
"DELETE FROM certRequests WHERE certID = '$'",
certID );
status = dbmsStaticUpdate( sqlBuffer );
updateCertErrorLog( dbmsInfo, status, "Deleted revocation "
"request for non-present certificate",
NULL, NULL, certID, NULL, 0 );
}
krnlSendNotifier( iCertRequest, IMESSAGE_DECREFCOUNT );
}
while( status != CRYPT_ERROR_NOTFOUND && errorCount < 10 );
/* If we ran into a problem, perform a fallback general delete of
entries that caused the problem */
if( status != CRYPT_ERROR_NOTFOUND )
{
updateCertErrorLogMsg( dbmsInfo, status, "Revocation request "
"cleanup operation failed, performing "
"fallback straight delete" );
status = dbmsStaticUpdate(
"DELETE FROM certRequests WHERE type = "
TEXT_CERTTYPE_REQUEST_REVOCATION );
if( cryptStatusError( status ) )
updateCertErrorLogMsg( dbmsInfo, status, "Fallback straight "
"delete failed" );
return( status );
}
return( resetErrorInfo( dbmsInfo ) );
}
/****************************************************************************
* *
* CA Cert Management Interface *
* *
****************************************************************************/
/* Perform a cert management operation */
static int certMgmtFunction( KEYSET_INFO *keysetInfo,
CRYPT_CERTIFICATE *iCertificate,
const CRYPT_CERTIFICATE caKey,
const CRYPT_CERTIFICATE request,
const CRYPT_CERTACTION_TYPE action )
{
DBMS_INFO *dbmsInfo = keysetInfo->keysetDBMS;
char reqCertID[ DBXKEYID_BUFFER_SIZE ];
int length, status;
/* In order for various SQL query strings to use the correct values the
type values have to match their text equivalents defined at the start
of this file. Since we can't check this at compile time we have to
do it here via an assertion */
assert( TEXT_CERTTYPE_REQUEST_CERT[ 0 ] - '0' == \
CRYPT_CERTTYPE_REQUEST_CERT );
assert( TEXT_CERTTYPE_REQUEST_REVOCATION[ 0 ] - '0' == \
CRYPT_CERTTYPE_REQUEST_REVOCATION );
assert( TEXT_CERTACTION_CREATE[ 0 ] - '0' == \
CRYPT_CERTACTION_CREATE );
assert( TEXTCH_CERTACTION_ADDUSER - '0' == \
CRYPT_CERTACTION_ADDUSER );
assert( TEXT_CERTACTION_REQUEST_CERT[ 0 ] - '0' == \
CRYPT_CERTACTION_REQUEST_CERT );
assert( TEXTCH_CERTACTION_REQUEST_CERT - '0' == \
CRYPT_CERTACTION_REQUEST_CERT );
assert( TEXT_CERTACTION_REQUEST_RENEWAL[ 0 ] - '0' == \
CRYPT_CERTACTION_REQUEST_RENEWAL );
assert( TEXTCH_CERTACTION_REQUEST_RENEWAL - '0' == \
CRYPT_CERTACTION_REQUEST_RENEWAL );
assert( TEXT_CERTACTION_CERT_CREATION[ 0 ] - '0' == \
CRYPT_CERTACTION_CERT_CREATION / 10 );
assert( TEXT_CERTACTION_CERT_CREATION[ 1 ] - '0' == \
CRYPT_CERTACTION_CERT_CREATION % 10 );
/* Clear the return value */
if( iCertificate != NULL )
*iCertificate = CRYPT_ERROR;
/* If it's a simple cert expire or cleanup, there are no parameters to
check so we can perform the action immediately */
if( action == CRYPT_CERTACTION_EXPIRE_CERT || \
action == CRYPT_CERTACTION_CLEANUP )
{
assert( caKey == CRYPT_UNUSED );
assert( request == CRYPT_UNUSED );
return( caCleanup( dbmsInfo, action ) );
}
/* If it's the completion of a cert creation, process it */
if( action == CRYPT_CERTACTION_CERT_CREATION_COMPLETE || \
action == CRYPT_CERTACTION_CERT_CREATION_DROP || \
action == CRYPT_CERTACTION_CERT_CREATION_REVERSE )
{
assert( caKey == CRYPT_UNUSED );
return( caIssueCertComplete( dbmsInfo, request, action ) );
}
/* Check that the CA key that we've been passed is in order. These
checks are performed automatically during the issue process by the
kernel when we try and convert the request into a cert, however we
perform them explicitly here so that we can return a more meaningful
error message to the caller */
if( action == CRYPT_CERTACTION_ISSUE_CRL )
{
int value;
/* If we're issuing a CRL, the key must be capable of CRL signing */
status = krnlSendMessage( caKey, IMESSAGE_GETATTRIBUTE, &value,
CRYPT_CERTINFO_KEYUSAGE );
if( cryptStatusError( status ) || \
!( value & CRYPT_KEYUSAGE_CRLSIGN ) )
return( CAMGMT_ARGERROR_CAKEY );
}
else
/* For anything other than a revocation action (which just updates the
cert store without doing anything else), the key must be a CA key */
if( action != CRYPT_CERTACTION_REVOKE_CERT && \
cryptStatusError( \
krnlSendMessage( caKey, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_CA ) ) )
return( CAMGMT_ARGERROR_CAKEY );
/* If it's a CRL issue, it's a read-only operation on the CRL store
for which we only need the CA cert (there's no request involved) */
if( action == CRYPT_CERTACTION_ISSUE_CRL )
{
assert( request == CRYPT_UNUSED );
return( caIssueCRL( dbmsInfo, iCertificate, caKey ) );
}
/* We're processing an action that request an explicit cert request,
perform further checks on the request */
if( !checkRequest( request, action ) )
return( CAMGMT_ARGERROR_REQUEST );
/* Make sure that the request is present in the request table in order
to issue a certificate for it. Again, this will be checked later,
but we can return a more meaningful error here */
status = length = getKeyID( reqCertID, request,
CRYPT_CERTINFO_FINGERPRINT_SHA );
if( cryptStatusError( status ) )
return( CAMGMT_ARGERROR_REQUEST );
status = dbmsQuery(
"SELECT certData FROM certRequests WHERE certID = ?",
NULL, 0, reqCertID, length, 0,
DBMS_CACHEDQUERY_NONE, DBMS_QUERY_CHECK );
if( cryptStatusError( status ) )
return( CRYPT_ERROR_NOTFOUND );
/* If it's a revocation request, process it */
if( action == CRYPT_CERTACTION_REVOKE_CERT )
{
assert( caKey == CRYPT_UNUSED );
return( caRevokeCert( dbmsInfo, request, CRYPT_UNUSED,
CRYPT_CERTACTION_REVOKE_CERT ) );
}
/* It's a cert issue request, issue the certificate */
assert( action == CRYPT_CERTACTION_ISSUE_CERT || \
action == CRYPT_CERTACTION_CERT_CREATION );
assert( isHandleRangeValid( caKey ) );
return( caIssueCert( dbmsInfo, iCertificate, caKey, request, action ) );
}
/* Set up the function pointers to the keyset methods */
int initDBMSCA( KEYSET_INFO *keysetInfo )
{
keysetInfo->keysetDBMS->certMgmtFunction = certMgmtFunction;
return( CRYPT_OK );
}
#endif /* USE_DBMS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -