📄 dbx_wr.c
字号:
/****************************************************************************
* *
* cryptlib DBMS Interface *
* Copyright Peter Gutmann 1996-2007 *
* *
****************************************************************************/
#if defined( INC_ALL )
#include "crypt.h"
#include "keyset.h"
#include "dbms.h"
#else
#include "crypt.h"
#include "keyset/keyset.h"
#include "keyset/dbms.h"
#endif /* Compiler-specific includes */
/* A structure to store ID information extracted from a certificate before
it's added to the certificate store */
typedef struct {
/* User identification data */
BUFFER( CRYPT_MAX_TEXTSIZE, Clength ) \
char C[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, SPlength ) \
char SP[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, Llength ) \
char L[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, Olength ) \
char O[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, OUlength ) \
char OU[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, CNlength ) \
char CN[ CRYPT_MAX_TEXTSIZE + 8 ];
BUFFER( CRYPT_MAX_TEXTSIZE, uriLength ) \
char uri[ CRYPT_MAX_TEXTSIZE + 8 ];
int Clength, SPlength, Llength, Olength, OUlength, CNlength, uriLength;
/* Certificate identification data */
BUFFER( ENCODED_DBXKEYID_SIZE, certIDlength ) \
char certID[ ENCODED_DBXKEYID_SIZE + 8 ];
BUFFER( ENCODED_DBXKEYID_SIZE, nameIDlength ) \
char nameID[ ENCODED_DBXKEYID_SIZE + 8 ];
BUFFER( ENCODED_DBXKEYID_SIZE, issuerIDlength ) \
char issuerID[ ENCODED_DBXKEYID_SIZE + 8 ];
BUFFER( ENCODED_DBXKEYID_SIZE, keyIDlength ) \
char keyID[ ENCODED_DBXKEYID_SIZE + 8 ];
int certIDlength, nameIDlength, issuerIDlength, keyIDlength;
} CERT_ID_DATA;
#ifdef USE_DBMS
/****************************************************************************
* *
* Utility Routines *
* *
****************************************************************************/
/* Get the SQL string to delete data from a given table */
CHECK_RETVAL_PTR \
static char *getDeleteString( IN_ENUM( KEYMGMT_ITEM ) \
const KEYMGMT_ITEM_TYPE itemType )
{
REQUIRES_N( itemType == KEYMGMT_ITEM_PKIUSER || \
itemType == KEYMGMT_ITEM_PUBLICKEY );
switch( itemType )
{
case KEYMGMT_ITEM_PKIUSER:
return( "DELETE FROM pkiUsers WHERE " );
case KEYMGMT_ITEM_PUBLICKEY:
return( "DELETE FROM certificates WHERE " );
}
retIntError_Null();
}
/****************************************************************************
* *
* Extract ID Information *
* *
****************************************************************************/
/* Extract user identification data from a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
static int extractCertNameData( IN_HANDLE const CRYPT_CERTIFICATE iCryptHandle,
IN_ENUM( CRYPT_CERTTYPE ) \
const CRYPT_CERTTYPE_TYPE certType,
OUT CERT_ID_DATA *certIdData )
{
static const int value = CRYPT_CERTINFO_SUBJECTALTNAME;
MESSAGE_DATA msgData;
int status;
assert( isWritePtr( certIdData, sizeof( CERT_ID_DATA ) ) );
REQUIRES( isHandleRangeValid( iCryptHandle ) );
REQUIRES( certType == CRYPT_CERTTYPE_CERTIFICATE || \
certType == CRYPT_CERTTYPE_REQUEST_CERT || \
certType == CRYPT_CERTTYPE_PKIUSER );
/* Clear return value */
memset( certIdData, 0, sizeof( CERT_ID_DATA ) );
/* Extract the DN and altName (URI) components. This changes the
currently selected DN components but this is OK because we've got the
certificate locked and the prior state will be restored when we
unlock it */
status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_UNUSED,
CRYPT_CERTINFO_SUBJECTNAME );
if( cryptStatusError( status ) )
return( status );
setMessageData( &msgData, certIdData->C, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_COUNTRYNAME );
if( cryptStatusOK( status ) )
certIdData->Clength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
setMessageData( &msgData, certIdData->SP, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_STATEORPROVINCENAME );
if( cryptStatusOK( status ) )
certIdData->SPlength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
setMessageData( &msgData, certIdData->L, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_LOCALITYNAME );
if( cryptStatusOK( status ) )
certIdData->Llength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
setMessageData( &msgData, certIdData->O, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_ORGANIZATIONNAME );
if( cryptStatusOK( status ) )
certIdData->Olength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
setMessageData( &msgData, certIdData->OU, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_ORGANIZATIONALUNITNAME );
if( cryptStatusOK( status ) )
certIdData->OUlength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
/* The CommonName component is the generic "name" associated with the
certificate, to make sure that there's always at least something
useful present to identify it we fetch the certificate holder name
rather than the specific common name */
setMessageData( &msgData, certIdData->CN, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_HOLDERNAME );
if( cryptStatusOK( status ) )
certIdData->CNlength = msgData.length;
else
{
if( status != CRYPT_ERROR_NOTFOUND )
return( status );
}
/* PKI user objects don't have URI information so if we're processing
one of these we're done */
if( certType == CRYPT_CERTTYPE_PKIUSER )
return( CRYPT_OK );
/* Get the URI for this certificate, in order of likelihood of
occurrence */
setMessageData( &msgData, certIdData->uri, CRYPT_MAX_TEXTSIZE );
krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
( void * ) &value, CRYPT_ATTRIBUTE_CURRENT );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_RFC822NAME );
if( status == CRYPT_ERROR_NOTFOUND )
{
setMessageData( &msgData, certIdData->uri, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData,
CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
}
if( status == CRYPT_ERROR_NOTFOUND )
{
setMessageData( &msgData, certIdData->uri, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_DNSNAME );
}
if( cryptStatusOK( status ) )
{
int i;
/* Force the URI (as stored) to lowercase to make case-insensitive
matching easier. In most cases we could ask the back-end to do
this but this complicates indexing and there's no reason why we
can't do it here */
for( i = 0; i < msgData.length; i++ )
certIdData->uri[ i ] = toLower( certIdData->uri[ i ] );
certIdData->uriLength = msgData.length;
}
return( status );
}
/* Extract certificate identification data from a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
static int extractCertIdData( IN_HANDLE const CRYPT_CERTIFICATE iCryptHandle,
IN_ENUM( CRYPT_CERTTYPE ) \
const CRYPT_CERTTYPE_TYPE certType,
INOUT CERT_ID_DATA *certIdData )
{
MESSAGE_DATA msgData;
int status;
assert( isWritePtr( certIdData, sizeof( CERT_ID_DATA ) ) );
REQUIRES( isHandleRangeValid( iCryptHandle ) );
REQUIRES( certType == CRYPT_CERTTYPE_CERTIFICATE || \
certType == CRYPT_CERTTYPE_REQUEST_CERT || \
certType == CRYPT_CERTTYPE_PKIUSER );
/* Get general ID information */
status = getKeyID( certIdData->certID, ENCODED_DBXKEYID_SIZE,
&certIdData->certIDlength, iCryptHandle,
CRYPT_CERTINFO_FINGERPRINT_SHA );
if( cryptStatusError( status ) )
return( status );
/* Get object-specific ID information */
if( certType == CRYPT_CERTTYPE_CERTIFICATE )
{
status = getKeyID( certIdData->nameID, ENCODED_DBXKEYID_SIZE,
&certIdData->nameIDlength, iCryptHandle,
CRYPT_IATTRIBUTE_SUBJECT );
if( cryptStatusOK( status ) )
status = getKeyID( certIdData->issuerID, ENCODED_DBXKEYID_SIZE,
&certIdData->issuerIDlength, iCryptHandle,
CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
if( cryptStatusOK( status ) )
status = getCertKeyID( certIdData->keyID, ENCODED_DBXKEYID_SIZE,
&certIdData->keyIDlength, iCryptHandle );
return( status );
}
if( certType == CRYPT_CERTTYPE_PKIUSER )
{
BYTE binaryKeyID[ 64 + 8 ];
char encKeyID[ CRYPT_MAX_TEXTSIZE + 8 ];
int binaryKeyIDlength;
/* Get the PKI user ID. We can't read this directly since it's
returned in text form for use by end users so we have to read the
encoded form, decode it, and then turn the decoded binary value
into a key ID. We identify the result as a keyID,
(== subjectKeyIdentifier, which it isn't really) but we need to
use this to ensure that it's hashed/expanded out to the correct
size */
setMessageData( &msgData, encKeyID, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( iCryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_PKIUSER_ID );
if( cryptStatusError( status ) )
return( status );
status = decodePKIUserValue( binaryKeyID, 64, &binaryKeyIDlength,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -