📄 pkcs15_set.c
字号:
/* If the certificate isn't signed then we can't store it in this
state */
status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE,
&value, CRYPT_CERTINFO_IMMUTABLE );
if( cryptStatusError( status ) || !value )
{
retExt( CRYPT_ERROR_NOTINITED,
( CRYPT_ERROR_NOTINITED, KEYSET_ERRINFO,
"Certificate being added is incomplete (unsigned)" ) );
}
/* Get a reference to the certificate that's associated with the
context. We have to do this in order to lock it so that we can
store it since the lock operation is only valid for certificates
and not contexts */
status = krnlSendMessage( cryptHandle, IMESSAGE_GETDEPENDENT,
&iCryptCert, OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
certPresent = TRUE;
}
/* Find out where we can add data and what needs to be added. The
strategy for adding items is:
Existing
New | None | Priv+Pub | Priv+Cert | Cert |
------------+-----------+-----------+-----------+-----------+
Priv + Pub | Add | ---- | ---- | Add |
| | | | |
Priv + Cert | Add | Repl.pubk | Add cert | Add cert |
| | with cert | if newer | if newer |
Cert | If trusted| Add | Add cert | Add cert |
| | | if newer | if newer |
------------+-----------+-----------+-----------+-----------+
We don't check for the addition of a trusted certificate at this
point since it could be buried in the middle of a certificate chain
so we leave the checking to addCertChain() */
pkcs15infoPtr = findEntry( pkcs15info, noPkcs15objects, CRYPT_KEYIDEX_ID,
iD, iDsize, KEYMGMT_FLAG_NONE );
if( pkcs15infoPtr != NULL )
{
/* Determine what actually needs to be added */
if( pkcs15infoPtr->privKeyData != NULL )
pkcs15keyPresent = TRUE;
if( pkcs15infoPtr->certData != NULL )
pkcs15certPresent = TRUE;
/* See what we can add */
status = checkAddInfo( pkcs15infoPtr, cryptHandle, isCertChain,
privkeyPresent, certPresent,
pkcs15keyPresent, pkcs15certPresent,
&isCertUpdate, KEYSET_ERRINFO );
if( cryptStatusError( status ) )
{
/* If it's not an OK_SPECIAL status telling us that we can still
try for an opportunistic certificate chain add, exit */
if( status != OK_SPECIAL )
return( status );
/* In theory we can't add anything, however since we've been
given a certificate chain there may be new certificates
present that we can try and add opportunistically */
status = krnlSendMessage( cryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE,
CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusError( status ) )
return( status );
status = pkcs15AddCertChain( pkcs15infoPtr, noPkcs15objects,
cryptHandle, KEYSET_ERRINFO );
( void ) krnlSendMessage( cryptHandle, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_LOCKED );
return( status );
}
}
else
{
/* This key/certificate isn't already present, make sure that the
label of what we're adding doesn't duplicate the label of an
existing object */
if( privkeyPresent )
{
char label[ CRYPT_MAX_TEXTSIZE + 8 ];
setMessageData( &msgData, label, CRYPT_MAX_TEXTSIZE );
status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_LABEL );
if( cryptStatusError( status ) )
return( status );
if( findEntry( pkcs15info, noPkcs15objects, CRYPT_KEYID_NAME,
msgData.data, msgData.length,
KEYMGMT_FLAG_NONE ) != NULL )
{
retExt( CRYPT_ERROR_DUPLICATE,
( CRYPT_ERROR_DUPLICATE, KEYSET_ERRINFO,
"Item with this label is already present" ) );
}
}
/* Find out where we can add the new key data */
pkcs15infoPtr = findFreeEntry( pkcs15info, noPkcs15objects,
&pkcs15index );
if( pkcs15infoPtr == NULL )
{
retExt( CRYPT_ERROR_OVERFLOW,
( CRYPT_ERROR_OVERFLOW, KEYSET_ERRINFO,
"No more room in keyset to add this item" ) );
}
}
/* We're ready to go, lock the object for our exclusive use */
if( certPresent )
{
status = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_TRUE,
CRYPT_IATTRIBUTE_LOCKED );
if( cryptStatusError( status ) )
return( status );
}
/* Add the key data. This will add the public/private key and any
certificate data associated with the key as required */
status = pkcs15AddKey( pkcs15infoPtr, cryptHandle, password,
passwordLength, keysetInfoPtr->ownerHandle,
privkeyPresent, certPresent,
( isCertUpdate || !pkcs15certPresent ) ? \
TRUE : FALSE,
pkcs15keyPresent, KEYSET_ERRINFO );
if( cryptStatusError( status ) )
{
if( certPresent )
{
( void ) krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_LOCKED );
}
return( status );
}
/* The update was successful, update the type and index information if
this was a newly-created entry */
if( pkcs15index != CRYPT_ERROR )
{
pkcs15infoPtr->type = PKCS15_SUBTYPE_NORMAL;
pkcs15infoPtr->index = pkcs15index;
}
/* If we've been given a certificate chain, try and opportunistically
add any further certificates that may be present in it. Error
handling once we get this far gets a bit tricky, we can still get an
error at this point if the certificate chain update fails even if the
main certificate add succeeded, however it's uncertain whether we
should still report an error when the main intended update (of the
private key and public key or certificate) succeeded. Since the
primary items to be added are the keys and a corresponding
certificate (as handled in addKey()) we don't report an error if
adding one of the coincidental certificates fails, since the primary
items were added successfully */
if( isCertChain )
{
( void ) pkcs15AddCertChain( pkcs15infoPtr, noPkcs15objects,
cryptHandle, KEYSET_ERRINFO );
}
/* Clean up */
if( certPresent )
{
( void ) krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_FALSE,
CRYPT_IATTRIBUTE_LOCKED );
}
return( status );
}
/* Add special data to the PKCS #15 keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int setSpecialItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
IN_ATTRIBUTE \
const CRYPT_ATTRIBUTE_TYPE dataType,
IN_BUFFER( dataLength ) const void *data,
IN_LENGTH_SHORT const int dataLength )
{
PKCS15_INFO *pkcs15info = keysetInfoPtr->keyData;
const int noPkcs15objects = keysetInfoPtr->keyDataNoObjects;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
assert( isWritePtr( pkcs15info, \
sizeof( PKCS15_INFO ) * noPkcs15objects ) );
assert( isReadPtr( data, dataLength ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
REQUIRES( dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
dataType == CRYPT_IATTRIBUTE_USERINDEX || \
dataType == CRYPT_IATTRIBUTE_USERID || \
dataType == CRYPT_IATTRIBUTE_USERINFO );
REQUIRES( dataLength > 0 && dataLength < MAX_INTLENGTH_SHORT );
return( addConfigData( pkcs15info, noPkcs15objects, dataType,
data, dataLength ) );
}
/****************************************************************************
* *
* Delete a Key *
* *
****************************************************************************/
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 )
{
PKCS15_INFO *pkcs15infoPtr;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
assert( isReadPtr( keyID, keyIDlength ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
REQUIRES( itemType > KEYMGMT_ITEM_NONE && \
itemType < KEYMGMT_ITEM_LAST );
REQUIRES( keyIDtype == CRYPT_KEYID_NAME || \
keyIDtype == CRYPT_KEYID_URI || \
keyIDtype == CRYPT_IKEYID_KEYID || \
keyIDtype == CRYPT_IKEYID_ISSUERID );
REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
keyIDlength < MAX_ATTRIBUTE_SIZE );
/* Locate the appropriate object in the PKCS #15 collection */
pkcs15infoPtr = findEntry( keysetInfoPtr->keyData,
keysetInfoPtr->keyDataNoObjects, keyIDtype,
keyID, keyIDlength, KEYMGMT_FLAG_NONE );
if( pkcs15infoPtr == NULL )
{
retExt( CRYPT_ERROR_NOTFOUND,
( CRYPT_ERROR_NOTFOUND, KEYSET_ERRINFO,
"No information present for this ID" ) );
}
/* Clear this entry */
pkcs15freeEntry( pkcs15infoPtr );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Keyset Access Routines *
* *
****************************************************************************/
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initPKCS15set( KEYSET_INFO *keysetInfoPtr )
{
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
/* Set the access method pointers */
keysetInfoPtr->setItemFunction = setItemFunction;
keysetInfoPtr->setSpecialItemFunction = setSpecialItemFunction;
keysetInfoPtr->deleteItemFunction = deleteItemFunction;
return( CRYPT_OK );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -