📄 cryptkey.c
字号:
case CRYPT_ATTRIBUTE_INT_ERRORCODE:
switch( keysetInfoPtr->type )
{
case KEYSET_HTTP:
*valuePtr = keysetInfoPtr->keysetHTTP->errorCode;
break;
case KEYSET_LDAP:
*valuePtr = keysetInfoPtr->keysetLDAP->errorCode;
break;
case KEYSET_DBMS:
*valuePtr = keysetInfoPtr->keysetDBMS->errorCode;
break;
default:
*valuePtr = CRYPT_OK;
}
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processGetAttributeS( KEYSET_INFO *keysetInfoPtr,
void *messageDataPtr, const int messageValue )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
switch( messageValue )
{
case CRYPT_ATTRIBUTE_INT_ERRORMESSAGE:
{
const char *errorMessagePtr;
switch( keysetInfoPtr->type )
{
case KEYSET_HTTP:
errorMessagePtr = keysetInfoPtr->keysetHTTP->errorMessage;
break;
case KEYSET_LDAP:
errorMessagePtr = keysetInfoPtr->keysetLDAP->errorMessage;
break;
case KEYSET_DBMS:
errorMessagePtr = keysetInfoPtr->keysetDBMS->errorMessage;
break;
default:
errorMessagePtr = "";
}
if( !*errorMessagePtr )
return( exitErrorNotFound( keysetInfoPtr,
CRYPT_ATTRIBUTE_INT_ERRORMESSAGE ) );
return( attributeCopy( msgData, errorMessagePtr,
strlen( errorMessagePtr ) ) );
}
case CRYPT_IATTRIBUTE_CONFIGDATA:
case CRYPT_IATTRIBUTE_USERINDEX:
case CRYPT_IATTRIBUTE_USERINFO:
case CRYPT_IATTRIBUTE_TRUSTEDCERT:
case CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT:
/* It's encoded cryptlib-specific data, fetch it from to the
keyset */
assert( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
return( keysetInfoPtr->getItemFunction( keysetInfoPtr, NULL,
KEYMGMT_ITEM_DATA, CRYPT_KEYID_NONE,
NULL, 0, msgData->data, &msgData->length,
messageValue ) );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttribute( KEYSET_INFO *keysetInfoPtr,
void *messageDataPtr, const int messageValue )
{
switch( messageValue )
{
case MESSAGE_SETATTRIBUTE:
/* It's an initialisation message, there's nothing to do */
assert( *( int * ) messageDataPtr == CRYPT_IATTRIBUTE_INITIALISED );
return( CRYPT_OK );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
static int processSetAttributeS( KEYSET_INFO *keysetInfoPtr,
void *messageDataPtr, const int messageValue )
{
RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
int status;
switch( messageValue )
{
case CRYPT_KEYINFO_QUERY:
case CRYPT_KEYINFO_QUERY_REQUESTS:
assert( keysetInfoPtr->getFirstItemFunction != NULL );
assert( keysetInfoPtr->isBusyFunction != NULL );
/* If we're in the middle of an existing query the user needs to
cancel it before starting another one */
if( keysetInfoPtr->isBusyFunction( keysetInfoPtr ) && \
( msgData->length != 6 || \
strCompare( msgData->data, "cancel", msgData->length ) ) )
return( exitErrorIncomplete( keysetInfoPtr, messageValue ) );
/* Send the query to the data source */
return( keysetInfoPtr->getFirstItemFunction( keysetInfoPtr, NULL,
NULL, CRYPT_KEYID_NAME, msgData->data, msgData->length,
( messageValue == CRYPT_KEYINFO_QUERY_REQUESTS ) ? \
KEYMGMT_ITEM_REQUEST : KEYMGMT_ITEM_PUBLICKEY,
KEYMGMT_FLAG_NONE ) );
case CRYPT_IATTRIBUTE_CONFIGDATA:
case CRYPT_IATTRIBUTE_USERINDEX:
case CRYPT_IATTRIBUTE_USERID:
case CRYPT_IATTRIBUTE_USERINFO:
/* It's encoded cryptlib-specific data, pass it through to the
keyset */
assert( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
assert( keysetInfoPtr->setItemFunction != NULL );
status = keysetInfoPtr->setItemFunction( keysetInfoPtr,
CRYPT_UNUSED, KEYMGMT_ITEM_DATA,
msgData->data, msgData->length, messageValue );
if( cryptStatusOK( status ) && \
messageValue != CRYPT_IATTRIBUTE_USERID )
{
/* The update succeeded, remember that the data in the keyset
has changed, unless it's a userID that just modifies
existing data */
keysetInfoPtr->flags |= KEYSET_DIRTY;
keysetInfoPtr->flags &= ~KEYSET_EMPTY;
}
return( status );
}
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/****************************************************************************
* *
* Keyset Message Handler *
* *
****************************************************************************/
/* Handle a message sent to a keyset object */
static int keysetMessageFunction( const void *objectInfoPtr,
const MESSAGE_TYPE message,
void *messageDataPtr,
const int messageValue )
{
KEYSET_INFO *keysetInfoPtr = ( KEYSET_INFO * ) objectInfoPtr;
/* Process the destroy object message */
if( message == MESSAGE_DESTROY )
{
/* If the keyset is active, perform any required cleanup functions */
if( keysetInfoPtr->flags & KEYSET_OPEN )
{
/* Shut down the keyset if required */
if( keysetInfoPtr->shutdownFunction != NULL )
keysetInfoPtr->shutdownFunction( keysetInfoPtr );
/* If the keyset is implemented as a file, close it (the keyset-
specific handler sees only an I/O stream and doesn't perform
any file-level functions). Because we cache all information
in a PKCS #12/#15 keyset and close the stream immediately
afterwards if we've opened it in read-only mode, we only
close the underlying stream for a PKCS #12/#15 keyset if it's
still active. Note the distinction between the keyset being
active and the stream being active, for PKCS #12/#15 the
keyset can be active without being associated with an open
stream */
if( keysetInfoPtr->flags & KEYSET_STREAM_OPEN )
{
/* Since the update may have changed the overall size, we
need to clear any leftover data from the previous
version of the keyset before we close the file */
if( keysetInfoPtr->flags & KEYSET_DIRTY )
fileClearToEOF( &keysetInfoPtr->keysetFile->stream );
sFileClose( &keysetInfoPtr->keysetFile->stream );
/* If it's a newly-created empty keyset file or one in which
all the keys have been deleted, remove it. This situation
can occur if there's some sort of error on writing and no
keys are ever written to the keyset */
if( keysetInfoPtr->flags & KEYSET_EMPTY )
fileErase( keysetInfoPtr->keysetFile->fileName );
}
}
return( CRYPT_OK );
}
/* Process attribute get/set/delete messages */
if( isAttributeMessage( message ) )
{
assert( message == MESSAGE_GETATTRIBUTE || \
message == MESSAGE_GETATTRIBUTE_S || \
message == MESSAGE_SETATTRIBUTE || \
message == MESSAGE_SETATTRIBUTE_S );
/* If it's a keyset-specific attribute, forward it directly to
the low-level code */
if( messageValue >= CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS && \
messageValue <= CRYPT_OPTION_KEYS_LDAP_EMAILNAME )
{
int status;
if( message == MESSAGE_SETATTRIBUTE || \
message == MESSAGE_SETATTRIBUTE_S )
{
assert( keysetInfoPtr->setAttributeFunction != NULL );
status = keysetInfoPtr->setAttributeFunction( keysetInfoPtr,
messageDataPtr, messageValue );
if( status == CRYPT_ERROR_INITED )
return( exitError( keysetInfoPtr, messageValue,
CRYPT_ERRTYPE_ATTR_PRESENT,
CRYPT_ERROR_INITED ) );
}
else
{
assert( message == MESSAGE_GETATTRIBUTE || \
message == MESSAGE_GETATTRIBUTE_S );
assert( keysetInfoPtr->getAttributeFunction != NULL );
status = keysetInfoPtr->getAttributeFunction( keysetInfoPtr,
messageDataPtr, messageValue );
if( status == CRYPT_ERROR_NOTFOUND )
return( exitErrorNotFound( keysetInfoPtr,
messageValue ) );
}
return( status );
}
if( message == MESSAGE_GETATTRIBUTE )
return( processGetAttribute( keysetInfoPtr, messageDataPtr,
messageValue ) );
if( message == MESSAGE_GETATTRIBUTE_S )
return( processGetAttributeS( keysetInfoPtr, messageDataPtr,
messageValue ) );
if( message == MESSAGE_SETATTRIBUTE )
return( processSetAttribute( keysetInfoPtr, messageDataPtr,
messageValue ) );
if( message == MESSAGE_SETATTRIBUTE_S )
return( processSetAttributeS( keysetInfoPtr, messageDataPtr,
messageValue ) );
assert( NOTREACHED );
return( CRYPT_ERROR ); /* Get rid of compiler warning */
}
/* Process messages that check a keyset */
if( message == MESSAGE_CHECK )
{
/* The check for whether this keyset type can contain an object that
can perform the requested operation has already been performed by
the kernel, so there's nothing further to do here */
assert( ( messageValue != MESSAGE_CHECK_PKC_PRIVATE && \
messageValue != MESSAGE_CHECK_PKC_DECRYPT && \
messageValue != MESSAGE_CHECK_PKC_DECRYPT_AVAIL && \
messageValue != MESSAGE_CHECK_PKC_SIGN && \
messageValue != MESSAGE_CHECK_PKC_SIGN_AVAIL ) ||
( keysetInfoPtr->type != KEYSET_DBMS && \
keysetInfoPtr->type != KEYSET_LDAP && \
keysetInfoPtr->type != KEYSET_HTTP ) );
return( CRYPT_OK );
}
/* Process object-specific messages */
if( message == MESSAGE_KEY_GETKEY )
{
MESSAGE_KEYMGMT_INFO *getkeyInfo = \
( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
getkeyInfo->keyIDtype, getkeyInfo->keyID, \
getkeyInfo->keyIDlength );
BYTE keyIDbuffer[ KEYID_SIZE ];
int status;
CONST_SET_STRUCT( keyIDinfo.keyIDtype = getkeyInfo->keyIDtype; \
keyIDinfo.keyID = getkeyInfo->keyID; \
keyIDinfo.keyIDlength = getkeyInfo->keyIDlength );
assert( keysetInfoPtr->getItemFunction != NULL );
assert( keyIDinfo.keyIDtype != CRYPT_KEYID_NONE && \
keyIDinfo.keyID != NULL && keyIDinfo.keyIDlength > 0 );
assert( messageValue != KEYMGMT_ITEM_PRIVATEKEY || \
keysetInfoPtr->type == KEYSET_FILE );
assert( ( messageValue != KEYMGMT_ITEM_SECRETKEY && \
messageValue != KEYMGMT_ITEM_DATA ) || \
( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 ) );
assert( ( messageValue != KEYMGMT_ITEM_REQUEST && \
messageValue != KEYMGMT_ITEM_REVOCATIONINFO && \
messageValue != KEYMGMT_ITEM_PKIUSER ) || \
keysetInfoPtr->type == KEYSET_DBMS );
/* Get the key */
resetErrorInfo( keysetInfoPtr );
status = initKeysetUpdate( keysetInfoPtr, &keyIDinfo, keyIDbuffer,
TRUE );
if( cryptStatusOK( status ) )
status = keysetInfoPtr->getItemFunction( keysetInfoPtr,
&getkeyInfo->cryptHandle, messageValue,
keyIDinfo.keyIDtype, keyIDinfo.keyID,
keyIDinfo.keyIDlength, getkeyInfo->auxInfo,
&getkeyInfo->auxInfoLength,
getkeyInfo->flags );
return( status );
}
if( message == MESSAGE_KEY_SETKEY )
{
MESSAGE_KEYMGMT_INFO *setkeyInfo = \
( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
int status;
assert( keysetInfoPtr->setItemFunction != NULL );
assert( messageValue != KEYMGMT_ITEM_PRIVATEKEY || \
( keysetInfoPtr->type == KEYSET_FILE && \
( keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 || \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS12 ) ) );
assert( ( messageValue != KEYMGMT_ITEM_SECRETKEY && \
messageValue != KEYMGMT_ITEM_DATA ) || \
( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 ) );
assert( ( messageValue != KEYMGMT_ITEM_REQUEST && \
messageValue != KEYMGMT_ITEM_REVOCATIONINFO && \
messageValue != KEYMGMT_ITEM_PKIUSER ) || \
( keysetInfoPtr->type == KEYSET_DBMS ) );
/* Set the key. This is currently the only way to associate a cert
with a context (that is, it's not possible to add a cert to an
existing context directly). At first glance this should be
possible since the required access checks are performed by the
kernel: The object is of the correct type (a certificate), in the
high state (it's been signed), and the cert owner and context
owner are the same. However, the process of attaching the cert to
the context is quite tricky. The cert will have a public-key
context already attached to it from when the cert was created or
imported. In order to attach this to the other context, we need
to first destroy the context associated with the cert and then
replace it with the other context. This procedure is both messy
and non-atomic. There are also complications surrounding use
with devices, where contexts are really cryptlib objects but just
dummy values that point back to the object for handling of
operations. Going via a keyset/device bypasses these issues, but
doing it directly shows up all of these problems */
resetErrorInfo( keysetInfoPtr );
status = initKeysetUpdate( keysetInfoPtr, NULL, NULL, FALSE );
if( cryptStatusOK( status ) )
status = keysetInfoPtr->setItemFunction( keysetInfoPtr,
setkeyInfo->cryptHandle, messageValue,
setkeyInfo->auxInfo, setkeyInfo->auxInfoLength,
setkeyInfo->flags );
if( cryptStatusOK( status ) )
{
/* The update succeeded, remember that the data in the keyset has
changed */
keysetInfoPtr->flags |= KEYSET_DIRTY;
keysetInfoPtr->flags &= ~KEYSET_EMPTY;
}
return( status );
}
if( message == MESSAGE_KEY_DELETEKEY )
{
MESSAGE_KEYMGMT_INFO *deletekeyInfo = \
( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
deletekeyInfo->keyIDtype, deletekeyInfo->keyID, \
deletekeyInfo->keyIDlength );
BYTE keyIDbuffer[ KEYID_SIZE ];
int status;
CONST_SET_STRUCT( keyIDinfo.keyIDtype = deletekeyInfo->keyIDtype; \
keyIDinfo.keyID = deletekeyInfo->keyID; \
keyIDinfo.keyIDlength = deletekeyInfo->keyIDlength );
assert( keysetInfoPtr->deleteItemFunction != NULL );
assert( keyIDinfo.keyIDtype != CRYPT_KEYID_NONE && \
keyIDinfo.keyID != NULL && keyIDinfo.keyIDlength > 0 );
/* Delete the key */
resetErrorInfo( keysetInfoPtr );
status = initKeysetUpdate( keysetInfoPtr, &keyIDinfo, keyIDbuffer,
FALSE );
if( cryptStatusOK( status ) )
status = keysetInfoPtr->deleteItemFunction( keysetInfoPtr,
messageValue, keyIDinfo.keyIDtype,
keyIDinfo.keyID, keyIDinfo.keyIDlength );
if( cryptStatusOK( status ) )
/* The update succeeded, remember that the data in the keyset has
changed */
keysetInfoPtr->flags |= KEYSET_DIRTY;
return( status );
}
if( message == MESSAGE_KEY_GETFIRSTCERT )
{
MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
CONST_INIT_STRUCT_3( KEYID_INFO keyIDinfo, \
getnextcertInfo->keyIDtype, getnextcertInfo->keyID, \
getnextcertInfo->keyIDlength );
BYTE keyIDbuffer[ KEYID_SIZE ];
int status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -