📄 pkcs15_get.c
字号:
"Couldn't set PKCS #15 permitted action flags for "
"the key" ) );
}
*iCryptHandle = iCryptContext;
return( CRYPT_OK );
}
REQUIRES( ( pkcs15infoPtr->pubKeyData != NULL || \
pkcs15infoPtr->certData != NULL ) && \
pkcs15infoPtr->privKeyData != NULL );
/* Set the key label and read the private key components. We have to
set the label before we load the key or the key load will be blocked
by the kernel */
if( pkcs15infoPtr->labelLength > 0 )
{ setMessageData( &msgData, ( void * ) pkcs15infoPtr->label,
min( pkcs15infoPtr->labelLength, \
CRYPT_MAX_TEXTSIZE ) ); }
else
{ setMessageData( &msgData, ( void * ) "Dummy label", 11 ); }
status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_LABEL );
if( cryptStatusOK( status ) )
{
status = readPrivateKeyComponents( pkcs15infoPtr, iCryptContext,
auxInfo, *auxInfoLength,
KEYSET_ERRINFO );
}
if( cryptStatusError( status ) )
{
krnlSendNotifier( iCryptContext, IMESSAGE_DECREFCOUNT );
if( iDataCert != CRYPT_ERROR )
krnlSendNotifier( iDataCert, IMESSAGE_DECREFCOUNT );
return( status );
}
/* Connect the data-only certificate object to the context if it exists.
This is an internal object used only by the context so we tell the
kernel to mark it as owned by the context only */
if( iDataCert != CRYPT_ERROR )
{
status = krnlSendMessage( iCryptContext, IMESSAGE_SETDEPENDENT,
&iDataCert, SETDEP_OPTION_NOINCREF );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iCryptContext, IMESSAGE_DECREFCOUNT );
if( iDataCert != CRYPT_ERROR )
krnlSendNotifier( iDataCert, IMESSAGE_DECREFCOUNT );
retExt( status,
( status, KEYSET_ERRINFO,
"Couldn't attach certificate to key" ) );
}
}
/* Set the permitted action flags */
status = setKeyAttributes( iCryptContext, pkcs15infoPtr,
privkeyActionFlags );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iCryptContext, MESSAGE_DECREFCOUNT );
retExt( status,
( status, KEYSET_ERRINFO,
"Couldn't set PKCS #15 permitted action flags for the "
"key" ) );
}
*iCryptHandle = iCryptContext;
return( CRYPT_OK );
}
/* Read special data from a PKCS #15 collection */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getSpecialItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
IN_ATTRIBUTE \
const CRYPT_ATTRIBUTE_TYPE dataType,
OUT_BUFFER_OPT( dataMaxLength, *dataLength ) \
void *data,
IN_LENGTH_SHORT_Z const int dataMaxLength,
OUT_LENGTH_SHORT_Z int *dataLength )
{
assert( ( data == NULL && dataMaxLength == 0 ) || \
isWritePtr( data, dataMaxLength ) );
assert( isWritePtr( dataLength, sizeof( int ) ) );
REQUIRES( dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
dataType == CRYPT_IATTRIBUTE_USERINDEX || \
dataType == CRYPT_IATTRIBUTE_USERINFO || \
dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT || \
dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT );
REQUIRES( ( data == NULL && dataMaxLength == 0 ) || \
( data != NULL && \
dataMaxLength >= 16 && dataMaxLength < MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( data != NULL )
memset( data, 0, min( 16, dataMaxLength ) );
*dataLength = 0;
/* If we're being asked for pre-encoded trusted certificate data, return
it to the caller */
if( dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT || \
dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT )
{
return( getTrustedCert( keysetInfoPtr->keyData,
keysetInfoPtr->keyDataNoObjects,
data, dataMaxLength, dataLength,
( dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT ) ? \
TRUE : FALSE ) );
}
/* Return a configuration data item */
return( getConfigItem( keysetInfoPtr->keyData,
keysetInfoPtr->keyDataNoObjects, dataType,
data, dataMaxLength, dataLength ) );
}
/* Fetch a sequence of certificates. These functions are called indirectly
by the certificate code to fetch the first and subsequent certificates in
a certificate chain. The 'stateInfo' value is handled as an OUT parameter
rather than the more obvious INOUT since the state is managed explicitly
by the caller, who uses it to pass in a next-key-ID reference instead of
a current-key-ID one */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6, 10 ) ) \
static int getItem( INOUT_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
IN_LENGTH_SHORT const int noPkcs15objects,
OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
OUT int *stateInfo,
IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
IN_BUFFER( keyIDlength ) const void *keyID,
IN_LENGTH_KEYID const int keyIDlength,
IN_ENUM( KEYMGMT_ITEM ) const KEYMGMT_ITEM_TYPE itemType,
IN_FLAGS_Z( KEYMGMT ) const int options,
INOUT ERROR_INFO *errorInfo )
{
MESSAGE_CREATEOBJECT_INFO createInfo;
const PKCS15_INFO *pkcs15infoPtr;
BYTE *certDataPtr;
int certStartOffset, certDataTotalSize, tag, status;
assert( isWritePtr( pkcs15info, \
sizeof( PKCS15_INFO ) * noPkcs15objects ) );
assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
assert( isReadPtr( stateInfo, sizeof( int ) ) );
assert( isReadPtr( keyID, keyIDlength ) );
REQUIRES( noPkcs15objects > 0 && noPkcs15objects < MAX_INTLENGTH_SHORT );
REQUIRES( keyIDtype == CRYPT_KEYID_NAME || \
keyIDtype == CRYPT_KEYID_URI || \
keyIDtype == CRYPT_IKEYID_KEYID || \
keyIDtype == CRYPT_IKEYID_PGPKEYID || \
keyIDtype == CRYPT_IKEYID_ISSUERID || \
keyIDtype == CRYPT_KEYIDEX_SUBJECTNAMEID );
REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
keyIDlength < MAX_ATTRIBUTE_SIZE );
REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
REQUIRES( options >= KEYMGMT_FLAG_NONE && \
options < KEYMGMT_FLAG_MAX );
REQUIRES( ( options & KEYMGMT_MASK_USAGEOPTIONS ) != \
KEYMGMT_MASK_USAGEOPTIONS );
REQUIRES( errorInfo != NULL );
/* Clear return values */
*iCertificate = CRYPT_ERROR;
*stateInfo = CRYPT_ERROR;
/* Find the appropriate entry based on the ID */
pkcs15infoPtr = findEntry( pkcs15info, noPkcs15objects, keyIDtype,
keyID, keyIDlength, options );
if( pkcs15infoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
*stateInfo = pkcs15infoPtr->index;
/* Import the certificate. This gets somewhat ugly because early drafts
of PKCS #15 wrote the certificate as is while the final version
wrapped it up in a [0] IMPLICIT tag so we can run into both the
original untagged SEQUENCE form and the newer [0] IMPLICIT SEQUENCE.
To handle this we dynamically replace the tag with the standard
SEQUENCE tag and reinstate the original afterwards, this is easier
than trying to pass the special-case decoding requirement down
through the kernel call */
certDataPtr = ( BYTE * ) pkcs15infoPtr->certData + \
pkcs15infoPtr->certOffset;
certStartOffset = pkcs15infoPtr->certOffset;
certDataTotalSize = pkcs15infoPtr->certDataSize;
tag = *certDataPtr;
*certDataPtr = BER_SEQUENCE;
REQUIRES( rangeCheck( certStartOffset,
certDataTotalSize - certStartOffset,
certDataTotalSize ) );
setMessageCreateObjectIndirectInfo( &createInfo, certDataPtr,
certDataTotalSize - certStartOffset,
( options & KEYMGMT_FLAG_DATAONLY_CERT ) ? \
CRYPT_ICERTTYPE_DATAONLY : \
CRYPT_CERTTYPE_CERTIFICATE );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
*certDataPtr = tag;
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Couldn't create certificate from stored certificate "
"data" ) );
}
*iCertificate = createInfo.cryptHandle;
if( pkcs15infoPtr->validFrom <= MIN_TIME_VALUE )
{
/* Perform an opportunistic update of the validity information if
this hasn't already been set. Since this is a purely
opportunistic update we ignore any return value */
( void ) getValidityInfo( pkcs15info, createInfo.cryptHandle );
}
return( CRYPT_OK );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 6 ) ) \
static int getFirstItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
OUT int *stateInfo,
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,
IN_FLAGS_Z( KEYMGMT ) const int options )
{
PKCS15_INFO *pkcs15info = keysetInfoPtr->keyData;
const int noPkcs15objects = keysetInfoPtr->keyDataNoObjects;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
assert( isWritePtr( pkcs15info, \
sizeof( PKCS15_INFO ) * noPkcs15objects ) );
assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
assert( isReadPtr( stateInfo, sizeof( int ) ) );
assert( isReadPtr( keyID, keyIDlength ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
REQUIRES( keyIDtype == CRYPT_KEYID_NAME || \
keyIDtype == CRYPT_KEYID_URI || \
keyIDtype == CRYPT_IKEYID_KEYID || \
keyIDtype == CRYPT_IKEYID_PGPKEYID || \
keyIDtype == CRYPT_IKEYID_ISSUERID );
REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
keyIDlength < MAX_ATTRIBUTE_SIZE );
REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
REQUIRES( options >= KEYMGMT_FLAG_NONE && \
options < KEYMGMT_FLAG_MAX );
REQUIRES( ( options & KEYMGMT_MASK_USAGEOPTIONS ) != \
KEYMGMT_MASK_USAGEOPTIONS );
/* Clear return values */
*iCertificate = CRYPT_ERROR;
*stateInfo = CRYPT_ERROR;
return( getItem( pkcs15info, noPkcs15objects, iCertificate, stateInfo,
keyIDtype, keyID, keyIDlength, itemType, options,
KEYSET_ERRINFO ) );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
static int getNextItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
INOUT int *stateInfo,
IN_FLAGS_Z( KEYMGMT ) const int options )
{
PKCS15_INFO *pkcs15info = keysetInfoPtr->keyData;
const int noPkcs15objects = keysetInfoPtr->keyDataNoObjects;
const int lastEntry = *stateInfo;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
assert( isWritePtr( stateInfo, sizeof( int ) ) );
assert( isWritePtr( pkcs15info, \
sizeof( PKCS15_INFO ) * noPkcs15objects ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
REQUIRES( options >= KEYMGMT_FLAG_NONE && options < KEYMGMT_FLAG_MAX && \
( options & ~KEYMGMT_MASK_CERTOPTIONS ) == 0 );
REQUIRES( ( lastEntry >= 0 && lastEntry < noPkcs15objects ) || \
lastEntry == CRYPT_ERROR );
/* Clear return values */
*iCertificate = CRYPT_ERROR;
*stateInfo = CRYPT_ERROR;
/* If the previous certificate was the last one, there's nothing left to
fetch */
if( lastEntry == CRYPT_ERROR )
{
retExt( CRYPT_ERROR_NOTFOUND,
( CRYPT_ERROR_NOTFOUND, KEYSET_ERRINFO,
"No more items present" ) );
}
ENSURES( lastEntry >= 0 && lastEntry < noPkcs15objects );
/* If there's no index information present to locate other certificates,
we can't go any further */
if( pkcs15info[ lastEntry ].issuerNameIDlength <= 0 )
{
retExt( CRYPT_ERROR_NOTFOUND,
( CRYPT_ERROR_NOTFOUND, KEYSET_ERRINFO,
"No index information available to locate other "
"certificates" ) );
}
/* Find the certificate for which the subjectNameID matches this
certificate's issuerNameID */
return( getItem( pkcs15info, noPkcs15objects, iCertificate, stateInfo,
CRYPT_KEYIDEX_SUBJECTNAMEID,
pkcs15info[ lastEntry ].issuerNameID,
pkcs15info[ lastEntry ].issuerNameIDlength,
KEYMGMT_ITEM_PUBLICKEY, options, KEYSET_ERRINFO ) );
}
/****************************************************************************
* *
* Keyset Access Routines *
* *
****************************************************************************/
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int initPKCS15get( 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->getItemFunction = getItemFunction;
keysetInfoPtr->getSpecialItemFunction = getSpecialItemFunction;
keysetInfoPtr->getFirstItemFunction = getFirstItemFunction;
keysetInfoPtr->getNextItemFunction = getNextItemFunction;
return( CRYPT_OK );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -