dbxpk15.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,715 行 · 第 1/5 页
C
1,715 行
if( cryptStatusError( objectLength ) )
status = objectLength;
else
if( objectLength < 8 || objectLength > 8192 )
status = CRYPT_ERROR_BADDATA;
if( cryptStatusOK( status ) )
{
objectLength += ( int ) stell( stream ) - startPos;
if( ( objectData = malloc( objectLength ) ) == NULL )
status = CRYPT_ERROR_MEMORY;
}
if( cryptStatusError( status ) )
break;
sseek( stream, startPos );
status = sread( stream, objectData, objectLength );
if( cryptStatusOK( status ) )
{
STREAM objectStream;
sMemConnect( &objectStream, objectData, objectLength );
status = readObjectAttributes( &objectStream,
&pkcs15objectInfo, type );
sMemDisconnect( &objectStream );
}
if( cryptStatusError( status ) )
{
free( objectData );
break;
}
/* Find out where to add the object data */
pkcs15infoPtr = findEntry( pkcs15info, CRYPT_IKEYID_ID,
pkcs15objectInfo.iD,
pkcs15objectInfo.iDlength,
KEYMGMT_FLAG_NONE );
if( pkcs15infoPtr == NULL )
{
int i;
/* This personality isn't present yet, find out where we can
add the object data and copy the fixed information
over */
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].type == PKCS15_SUBTYPE_NONE )
break;
if( i == MAX_PKCS15_OBJECTS )
{
free( objectData );
status = CRYPT_ERROR_OVERFLOW;
break;
}
pkcs15info[ i ] = pkcs15objectInfo;
pkcs15infoPtr = &pkcs15info[ i ];
pkcs15infoPtr->index = i;
}
/* If any new ID information has become available, copy it over.
The keyID defaults to the iD, so we only copy the newly-read
keyID over if it's something other than the existing iD */
if( pkcs15infoPtr->iDlength != pkcs15objectInfo.keyIDlength || \
memcmp( pkcs15infoPtr->iD, pkcs15objectInfo.keyID,
pkcs15objectInfo.keyIDlength ) )
{
memcpy( pkcs15infoPtr->keyID, pkcs15objectInfo.keyID,
pkcs15objectInfo.keyIDlength );
pkcs15infoPtr->keyIDlength = pkcs15objectInfo.keyIDlength;
}
if( pkcs15objectInfo.iAndSIDlength )
{
memcpy( pkcs15infoPtr->iAndSID, pkcs15objectInfo.iAndSID,
pkcs15objectInfo.iAndSIDlength );
pkcs15infoPtr->iAndSIDlength = pkcs15objectInfo.iAndSIDlength;
}
if( pkcs15objectInfo.subjectNameIDlength )
{
memcpy( pkcs15infoPtr->subjectNameID,
pkcs15objectInfo.subjectNameID,
pkcs15objectInfo.subjectNameIDlength );
pkcs15infoPtr->subjectNameIDlength = \
pkcs15objectInfo.subjectNameIDlength;
}
if( pkcs15objectInfo.issuerNameIDlength )
{
memcpy( pkcs15infoPtr->issuerNameID,
pkcs15objectInfo.issuerNameID,
pkcs15objectInfo.issuerNameIDlength );
pkcs15infoPtr->issuerNameIDlength = \
pkcs15objectInfo.issuerNameIDlength;
}
if( pkcs15objectInfo.pgp2KeyIDlength )
{
memcpy( pkcs15infoPtr->pgp2KeyID,
pkcs15objectInfo.pgp2KeyID,
pkcs15objectInfo.pgp2KeyIDlength );
pkcs15infoPtr->pgp2KeyIDlength = \
pkcs15objectInfo.pgp2KeyIDlength;
}
if( pkcs15objectInfo.openPGPKeyIDlength )
{
memcpy( pkcs15infoPtr->openPGPKeyID,
pkcs15objectInfo.openPGPKeyID,
pkcs15objectInfo.openPGPKeyIDlength );
pkcs15infoPtr->openPGPKeyIDlength = \
pkcs15objectInfo.openPGPKeyIDlength;
}
/* Copy the payload over */
switch( type )
{
case PKCS15_OBJECT_PUBKEY:
pkcs15infoPtr->type = PKCS15_SUBTYPE_NORMAL;
pkcs15infoPtr->pubKeyData = objectData;
pkcs15infoPtr->pubKeyDataSize = objectLength;
pkcs15infoPtr->pubKeyOffset = pkcs15objectInfo.pubKeyOffset;
pkcs15infoPtr->pubKeyUsage = pkcs15objectInfo.pubKeyUsage;
break;
case PKCS15_OBJECT_PRIVKEY:
pkcs15infoPtr->type = PKCS15_SUBTYPE_NORMAL;
pkcs15infoPtr->privKeyData = objectData;
pkcs15infoPtr->privKeyDataSize = objectLength;
pkcs15infoPtr->privKeyOffset = pkcs15objectInfo.privKeyOffset;
pkcs15infoPtr->privKeyUsage = pkcs15objectInfo.privKeyUsage;
break;
case PKCS15_OBJECT_CERT:
case PKCS15_OBJECT_TRUSTEDCERT:
case PKCS15_OBJECT_USEFULCERT:
if( pkcs15infoPtr->type == PKCS15_SUBTYPE_NONE )
pkcs15infoPtr->type = PKCS15_SUBTYPE_CERT;
pkcs15infoPtr->certData = objectData;
pkcs15infoPtr->certDataSize = objectLength;
pkcs15infoPtr->certOffset = pkcs15objectInfo.certOffset;
break;
case PKCS15_OBJECT_SECRETKEY:
assert( NOTREACHED );
case PKCS15_OBJECT_DATA:
pkcs15infoPtr->type = PKCS15_SUBTYPE_DATA;
pkcs15infoPtr->dataType = pkcs15objectInfo.dataType;
pkcs15infoPtr->dataData = objectData;
pkcs15infoPtr->dataDataSize = objectLength;
pkcs15infoPtr->dataOffset = pkcs15objectInfo.dataOffset;
break;
}
}
}
if( cryptStatusError( status ) )
{
zeroise( keysetInfo->keyData, keysetInfo->keyDataSize );
free( keysetInfo->keyData );
keysetInfo->keyDataSize = 0;
}
return( status );
}
/* Shut down the PKCS #15 state, flushing information to disk if necessary */
static void shutdownFunction( KEYSET_INFO *keysetInfo )
{
/* If the contents have been changed, commit the changes to disk */
if( keysetInfo->isDirty )
{
int status;
sseek( &keysetInfo->keysetFile.stream, 0 );
status = pkcs15Flush( &keysetInfo->keysetFile.stream,
keysetInfo->keyData );
if( status == OK_SPECIAL )
keysetInfo->isEmpty = TRUE;
}
/* Free the PKCS #15 object info */
if( keysetInfo->keyData != NULL )
{
pkcs15Free( keysetInfo->keyData );
zeroise( keysetInfo->keyData, keysetInfo->keyDataSize );
free( keysetInfo->keyData );
}
}
/****************************************************************************
* *
* Read a Key *
* *
****************************************************************************/
/* Read the decryption information for the encrypted private key and use it
to import the encrypted private components into an existing PKC context */
static int readEncryptedKey( STREAM *stream,
const CRYPT_CONTEXT iPrivateKey,
const char *password, const int passwordLength )
{
CRYPT_CONTEXT iSessionKey;
MESSAGE_CREATEOBJECT_INFO createInfo;
MECHANISM_WRAP_INFO mechanismInfo;
RESOURCE_DATA msgData;
QUERY_INFO queryInfo, contentQueryInfo;
void *encryptedKey;
int status;
/* Skip the version number and header for the SET OF EncryptionInfo and
query the exported key information to determine the parameters
required to reconstruct the decryption key */
readShortInteger( stream, NULL );
readSet( stream, NULL );
status = queryObject( stream, &queryInfo );
if( cryptStatusError( status ) )
return( status );
if( queryInfo.type != CRYPT_OBJECT_ENCRYPTED_KEY )
return( CRYPT_ERROR_BADDATA );
encryptedKey = sMemBufPtr( stream );
readUniversal( stream ); /* Skip the exported key */
/* Read the session key information into a context */
status = readCMSencrHeader( stream, dataOIDselection, &iSessionKey,
&contentQueryInfo );
if( cryptStatusError( status ) )
return( status );
/* Create an encryption context and derive the user password into it
using the given parameters, and import the session key. If there's
an error in the parameters stored with the exported key we'll get an
arg or attribute error when we try to set the attribute so we
translate it into an error code which is appropriate for the
situation */
setMessageCreateObjectInfo( &createInfo, queryInfo.cryptAlgo );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
&createInfo, OBJECT_TYPE_CONTEXT );
if( cryptStatusOK( status ) )
{
status = krnlSendMessage( createInfo.cryptHandle,
RESOURCE_IMESSAGE_SETATTRIBUTE,
&queryInfo.cryptMode, CRYPT_CTXINFO_MODE );
if( cryptStatusOK( status ) )
status = krnlSendMessage( createInfo.cryptHandle,
RESOURCE_IMESSAGE_SETATTRIBUTE,
&queryInfo.keySetupAlgo,
CRYPT_CTXINFO_KEYING_ALGO );
if( cryptStatusOK( status ) )
status = krnlSendMessage( createInfo.cryptHandle,
RESOURCE_IMESSAGE_SETATTRIBUTE,
&queryInfo.keySetupIterations,
CRYPT_CTXINFO_KEYING_ITERATIONS );
if( cryptStatusOK( status ) )
{
setResourceData( &msgData, queryInfo.salt, queryInfo.saltLength );
status = krnlSendMessage( createInfo.cryptHandle,
RESOURCE_IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_KEYING_SALT );
}
if( cryptStatusOK( status ) )
{
setResourceData( &msgData, ( void * ) password, passwordLength );
status = krnlSendMessage( createInfo.cryptHandle,
RESOURCE_IMESSAGE_SETATTRIBUTE_S,
&msgData, CRYPT_CTXINFO_KEYING_VALUE );
}
if( cryptStatusOK( status ) )
status = iCryptImportKeyEx( encryptedKey, queryInfo.size,
createInfo.cryptHandle, iSessionKey );
krnlSendNotifier( createInfo.cryptHandle,
RESOURCE_IMESSAGE_DECREFCOUNT );
}
memset( &queryInfo, 0, sizeof( QUERY_INFO ) );
if( cryptStatusError( status ) )
{
krnlSendNotifier( iSessionKey, RESOURCE_IMESSAGE_DECREFCOUNT );
return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
}
/* Import the encrypted key into the PKC context */
setMechanismWrapInfo( &mechanismInfo, sMemBufPtr( stream ),
contentQueryInfo.size, NULL, 0, iPrivateKey,
iSessionKey, CRYPT_UNUSED );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
RESOURCE_IMESSAGE_DEV_IMPORT, &mechanismInfo,
MECHANISM_PRIVATEKEYWRAP );
clearMechanismInfo( &mechanismInfo );
krnlSendNotifier( iSessionKey, RESOURCE_IMESSAGE_DECREFCOUNT );
return( status );
}
/* Return an encoded configuration item */
static int getConfigItem( KEYSET_INFO *keysetInfo,
const CRYPT_ATTRIBUTE_TYPE dataType,
void *data, int *dataLength )
{
const PKCS15_INFO *pkcs15infoPtr = keysetInfo->keyData;
static int trustedCertIndex;
assert( dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
dataType == CRYPT_IATTRIBUTE_USERINDEX || \
dataType == CRYPT_IATTRIBUTE_USERINFO || \
dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT || \
dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT_NEXT );
/* If we're being asked for pre-encoded data, return it to the caller */
if( dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
dataType == CRYPT_IATTRIBUTE_USERINDEX || \
dataType == CRYPT_IATTRIBUTE_USERINFO )
{
int i;
/* Find the particular data type we're looking for */
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( ( pkcs15infoPtr[ i ].type == PKCS15_SUBTYPE_DATA && \
pkcs15infoPtr[ i ].dataType == dataType ) )
break;
if( i == MAX_PKCS15_OBJECTS )
return( CRYPT_ERROR_NOTFOUND );
pkcs15infoPtr = &pkcs15infoPtr[ i ];
/* Return it to the caller */
return( attributePtrCopy( data, dataLength,
( BYTE * ) pkcs15infoPtr->dataData + \
pkcs15infoPtr->dataOffset,
pkcs15infoPtr->dataDataSize - pkcs15infoPtr->dataOffset ) );
}
/* If this is the first cert, reset the index value. This is pretty
awful since this sort of value should be stored with the caller,
however there's no way to pass this back and forth in a RESOURCE_DATA
without resorting to an even uglier hack and it's safe since this
attribute is only ever read for the config keyset */
if( dataType == CRYPT_IATTRIBUTE_TRUSTEDCERT )
trustedCertIndex = 0;
/* If we're being asked for a trusted cert, find the first or next one */
while( trustedCertIndex < MAX_PKCS15_OBJECTS )
{
if( pkcs15infoPtr[ trustedCertIndex ].implicitTrust )
{
int status;
status = attributePtrCopy( data, dataLength,
( BYTE * ) pkcs15infoPtr[ trustedCertIndex ].certData + \
pkcs15infoPtr[ trustedCertIndex ].ce
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?