📄 dbx_wr.c
字号:
if( cryptStatusError( status ) )
{
/* Convert any low-level certificate-specific error into something
generic that makes a bit more sense to the caller */
retExtArg( CRYPT_ARGERROR_NUM1,
( CRYPT_ARGERROR_NUM1, errorInfo,
"Couldn't extract CRL data from CRL" ) );
}
/* Set up the certificate object data to be written and send it to the
database. Certificate stores contain extra inforomation that's
needed to build a CRL so we have to vary the SQL string depending on
the keyset type */
initBoundData( boundDataPtr );
if( isCertStore( dbmsInfo ) )
{
setBoundDataDate( boundDataPtr, 0, &expiryDate );
setBoundData( boundDataPtr, 1, crlIdData.nameID,
crlIdData.nameIDlength );
setBoundData( boundDataPtr, 2, crlIdData.issuerID,
crlIdData.issuerIDlength );
setBoundData( boundDataPtr, 3, crlIdData.certID,
crlIdData.certIDlength );
boundDataIndex = 4;
sqlString = "INSERT INTO CRLs VALUES (?, ?, ?, ?, ?)";
}
else
{
setBoundData( boundDataPtr, 0, crlIdData.issuerID,
crlIdData.issuerIDlength );
boundDataIndex = 1;
sqlString = "INSERT INTO CRLs VALUES (?, ?)";
}
if( hasBinaryBlobs( dbmsInfo ) )
{
setBoundDataBlob( boundDataPtr, boundDataIndex, certData,
certDataLength );
}
else
{
int encodedCertDataLength;
status = base64encode( encodedCertData, MAX_ENCODED_CERT_SIZE,
&encodedCertDataLength, certData,
certDataLength, CRYPT_CERTTYPE_NONE );
if( cryptStatusError( status ) )
{
assert( DEBUG_WARN );
retIntError();
}
setBoundData( boundDataPtr, boundDataIndex, encodedCertData,
encodedCertDataLength );
}
status = dbmsUpdate( sqlString, boundDataPtr, updateType );
if( cryptStatusError( status ) )
{
retExtErr( status,
( status, errorInfo, getDbmsErrorInfo( dbmsInfo ),
"CRL add operation failed: " ) );
}
return( CRYPT_OK );
}
/* Add an item to the certificate store */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int setItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
IN_HANDLE const CRYPT_HANDLE iCryptHandle,
IN_ENUM( KEYMGMT_ITEM ) \
const KEYMGMT_ITEM_TYPE itemType,
STDC_UNUSED const char *password,
STDC_UNUSED const int passwordLength,
IN_FLAGS( KEYMGMT ) const int flags )
{
DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
BOOLEAN seenNonDuplicate = FALSE;
int type, iterationCount = 0, status;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
REQUIRES( isHandleRangeValid( iCryptHandle ) );
REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
itemType == KEYMGMT_ITEM_REVOCATIONINFO || \
itemType == KEYMGMT_ITEM_REQUEST || \
itemType == KEYMGMT_ITEM_PKIUSER );
REQUIRES( password == NULL && passwordLength == 0 );
REQUIRES( flags >= KEYMGMT_FLAG_NONE && flags < KEYMGMT_FLAG_MAX );
/* Make sure that we've been given a certificate, certificate chain, or
CRL (or a PKI user if it's a CA certificate store). We can't do any
more specific checking against the itemType because if it's coming
from outside cryptlib it'll just be passed in as a generic
certificate object with no distinction between object subtypes */
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE,
&type, CRYPT_CERTINFO_CERTTYPE );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_NUM1 );
if( isCertStore( dbmsInfo ) )
{
/* The only item that can be inserted directly into a CA certificate
store is a CA request or PKI user information */
if( type != CRYPT_CERTTYPE_CERTREQUEST && \
type != CRYPT_CERTTYPE_REQUEST_CERT && \
type != CRYPT_CERTTYPE_REQUEST_REVOCATION && \
type != CRYPT_CERTTYPE_PKIUSER )
{
retExtArg( CRYPT_ARGERROR_NUM1,
( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO,
"Invalid item type for CA certificate store" ) );
}
if( itemType == KEYMGMT_ITEM_PKIUSER )
return( caAddPKIUser( dbmsInfo, iCryptHandle, KEYSET_ERRINFO ) );
/* It's a certificate request being added to a CA certificate
store */
REQUIRES( itemType == KEYMGMT_ITEM_REQUEST );
return( caAddCertRequest( dbmsInfo, iCryptHandle, type,
( flags & KEYMGMT_FLAG_UPDATE ) ? \
TRUE : FALSE, KEYSET_ERRINFO ) );
}
if( type != CRYPT_CERTTYPE_CERTIFICATE && \
type != CRYPT_CERTTYPE_CERTCHAIN && \
type != CRYPT_CERTTYPE_CRL )
{
retExtArg( CRYPT_ARGERROR_NUM1,
( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO,
"Item being added must be a CRL or certificate" ) );
}
REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
itemType == KEYMGMT_ITEM_REVOCATIONINFO );
/* Lock the certificate or CRL for our exclusive use and select the
first sub-item (certificate in a certificate chain, entry in a CRL),
update the keyset with the certificate(s)/CRL entries, and unlock it
to allow others access */
status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusOK( status ) )
status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_CURSORFIRST,
CRYPT_CERTINFO_CURRENT_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
do
{
/* Add the certificate or CRL */
if( type == CRYPT_CERTTYPE_CRL )
status = addCRL( dbmsInfo, iCryptHandle, CRYPT_UNUSED,
DBMS_UPDATE_NORMAL, KEYSET_ERRINFO );
else
status = addCert( dbmsInfo, iCryptHandle,
CRYPT_CERTTYPE_CERTIFICATE, CERTADD_NORMAL,
DBMS_UPDATE_NORMAL, KEYSET_ERRINFO );
/* An item being added may already be present but we can't fail
immediately because what's being added may be a chain containing
further certificates or a CRL containing further entries so we
keep track of whether we've successfully added at least one item
and clear data duplicate errors */
if( status == CRYPT_OK )
seenNonDuplicate = TRUE;
else
{
if( status == CRYPT_ERROR_DUPLICATE )
status = CRYPT_OK;
}
}
while( cryptStatusOK( status ) && \
krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_CURSORNEXT,
CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK && \
iterationCount++ < FAILSAFE_ITERATIONS_MED );
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
( void ) krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusOK( status ) && !seenNonDuplicate )
{
/* We reached the end of the certificate chain/CRL without finding
anything that we could add, return a data duplicate error */
retExt( CRYPT_ERROR_DUPLICATE,
( CRYPT_ERROR_DUPLICATE, KEYSET_ERRINFO,
"No new %s were found to add to the certificate store",
( type == CRYPT_CERTTYPE_CRL ) ? \
"CRL entries" : "certificates" ) );
}
return( status );
}
/* Delete an item from the certificate store */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int deleteItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
IN_ENUM( KEYMGMT_ITEM ) \
const KEYMGMT_ITEM_TYPE itemType,
IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
IN_BUFFER( keyIDlength ) const void *keyID,
IN_LENGTH_KEYID const int keyIDlength )
{
DBMS_INFO *dbmsInfo = keysetInfoPtr->keysetDBMS;
BOUND_DATA boundData[ BOUND_DATA_MAXITEMS ], *boundDataPtr = boundData;
char sqlBuffer[ MAX_SQL_QUERY_SIZE + 8 ];
char encodedKeyID[ ( CRYPT_MAX_TEXTSIZE * 2 ) + 8 ];
const char *keyName = getKeyName( keyIDtype );
const char *deleteString = getDeleteString( itemType );
int encodedKeyIDlength, status;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
assert( isReadPtr( keyID, keyIDlength ) );
REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
itemType == KEYMGMT_ITEM_PKIUSER );
REQUIRES( ( !isCertStore( dbmsInfo ) && \
itemType == KEYMGMT_ITEM_PUBLICKEY ) || \
( isCertStore( dbmsInfo ) && \
itemType == KEYMGMT_ITEM_PKIUSER ) );
REQUIRES( keyIDtype > CRYPT_KEYID_NONE && \
keyIDtype < CRYPT_KEYID_LAST );
REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
keyIDlength < MAX_ATTRIBUTE_SIZE );
/* Delete the item from the certificate store */
status = makeKeyID( encodedKeyID, CRYPT_MAX_TEXTSIZE * 2,
&encodedKeyIDlength, keyIDtype, keyID, keyIDlength );
if( cryptStatusError( status ) )
return( CRYPT_ARGERROR_STR1 );
if( isCertStore( dbmsInfo ) )
{
/* The only item that can be deleted from a CA certificate store is
PKI user information */
if( itemType != KEYMGMT_ITEM_PKIUSER )
{
retExtArg( CRYPT_ARGERROR_NUM1,
( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO,
"Invalid operation for CA certificate store" ) );
}
return( caDeletePKIUser( dbmsInfo, keyIDtype, keyID, keyIDlength,
KEYSET_ERRINFO ) );
}
ENSURES( keyName != NULL && deleteString != NULL );
strlcpy_s( sqlBuffer, MAX_SQL_QUERY_SIZE, deleteString );
strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, keyName );
strlcat_s( sqlBuffer, MAX_SQL_QUERY_SIZE, " = ?" );
initBoundData( boundDataPtr );
setBoundData( boundDataPtr, 0, encodedKeyID, encodedKeyIDlength );
status = dbmsUpdate( sqlBuffer, boundDataPtr, DBMS_UPDATE_NORMAL );
if( cryptStatusError( status ) )
{
retExtErr( status,
( status, KEYSET_ERRINFO, getDbmsErrorInfo( dbmsInfo ),
"Certificate delete operation failed: " ) );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Database Access Routines *
* *
****************************************************************************/
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initDBMSwrite( INOUT KEYSET_INFO *keysetInfoPtr )
{
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_DBMS );
keysetInfoPtr->setItemFunction = setItemFunction;
keysetInfoPtr->deleteItemFunction = deleteItemFunction;
return( CRYPT_OK );
}
#endif /* USE_DBMS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -