📄 pkcs15.c
字号:
return( CRYPT_ERROR_BADDATA );
if( peekTag( stream ) == MAKE_CTAG( 0 ) )
readUniversal( stream );
status = readLongSequence( stream, NULL );
if( cryptStatusError( status ) )
return( status );
}
/* Allocate the PKCS #15 object info */
if( ( pkcs15info = clAlloc( "initFunction", \
sizeof( PKCS15_INFO ) * \
MAX_PKCS15_OBJECTS ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS );
keysetInfo->keyData = pkcs15info;
keysetInfo->keyDataSize = sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS;
/* If this is a newly-created keyset, there's nothing left to do */
if( options == CRYPT_KEYOPT_CREATE )
return( CRYPT_OK );
/* Read all of the keys in the keyset */
status = readKeyset( &keysetInfo->keysetFile->stream, pkcs15info,
endPos );
if( cryptStatusError( status ) )
{
pkcs15Free( pkcs15info );
clFree( "initFunction", keysetInfo->keyData );
keysetInfo->keyData = NULL;
keysetInfo->keyDataSize = 0;
}
return( status );
}
/****************************************************************************
* *
* PKCS #15 Shutdown Functions *
* *
****************************************************************************/
/* Write the wrapping needed for individual objects */
static void writeObjectWrapper( STREAM *stream, const int length,
const int tag )
{
writeConstructed( stream, ( int ) sizeofObject( length ), tag );
writeConstructed( stream, length, CTAG_OV_DIRECT );
assert( sStatusOK( stream ) );
}
/* Write a data item */
static int sizeofDataItem( const PKCS15_INFO *pkcs15infoPtr )
{
const int dataSize = \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
pkcs15infoPtr->dataDataSize : \
( int ) sizeofObject( pkcs15infoPtr->dataDataSize );
const int labelSize = \
( pkcs15infoPtr->labelLength ) ? \
( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
return( ( int ) \
sizeofObject( \
sizeofObject( labelSize ) + \
sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
sizeofObject( \
sizeofObject( \
sizeofOID( OID_CRYPTLIB_CONFIGDATA ) + dataSize ) ) ) );
}
static void writeDataItem( STREAM *stream, const PKCS15_INFO *pkcs15infoPtr )
{
const BYTE *oid = \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA ) ? \
OID_CRYPTLIB_CONFIGDATA : \
( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX ) ? \
OID_CRYPTLIB_USERINDEX : OID_CRYPTLIB_USERINFO;
const int labelSize = \
( pkcs15infoPtr->labelLength ) ? \
( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
const int contentSize = sizeofOID( oid ) + \
( ( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
pkcs15infoPtr->dataDataSize : \
( int ) sizeofObject( pkcs15infoPtr->dataDataSize ) );
assert( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX || \
pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO );
writeConstructed( stream, \
( int ) sizeofObject( labelSize ) + \
( int ) sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
( int ) sizeofObject( sizeofObject( contentSize ) ),
CTAG_DO_OIDDO );
writeSequence( stream, labelSize );
if( labelSize )
writeCharacterString( stream, ( BYTE * ) pkcs15infoPtr->label,
pkcs15infoPtr->labelLength, BER_STRING_UTF8 );
writeSequence( stream, sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) );
writeOID( stream, OID_CRYPTLIB_CONTENTTYPE );
writeConstructed( stream, ( int ) sizeofObject( contentSize ),
CTAG_OB_TYPEATTR );
writeSequence( stream, contentSize );
writeOID( stream, oid );
if( pkcs15infoPtr->dataType != CRYPT_IATTRIBUTE_USERINFO )
/* UserInfo is a straight object, the others are SEQUENCEs of
objects */
writeSequence( stream, pkcs15infoPtr->dataDataSize );
swrite( stream, pkcs15infoPtr->dataData, pkcs15infoPtr->dataDataSize );
assert( sStatusOK( stream ) );
}
/* Flush a PKCS #15 collection to a stream */
static int pkcs15Flush( STREAM *stream, const PKCS15_INFO *pkcs15info )
{
int pubKeySize = 0, privKeySize = 0, certSize = 0, dataSize = 0;
int objectsSize = 0, i;
/* Determine the overall size of the objects */
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
switch( pkcs15info[ i ].type )
{
case PKCS15_SUBTYPE_NONE:
break;
case PKCS15_SUBTYPE_NORMAL:
pubKeySize += pkcs15info[ i ].pubKeyDataSize;
privKeySize += pkcs15info[ i ].privKeyDataSize;
/* Drop through */
case PKCS15_SUBTYPE_CERT:
certSize += pkcs15info[ i ].certDataSize;
break;
case PKCS15_SUBTYPE_SECRETKEY:
assert( NOTREACHED );
break;
case PKCS15_SUBTYPE_DATA:
dataSize += sizeofDataItem( &pkcs15info[ i ] );
break;
default:
assert( NOTREACHED );
}
/* Determine how much data there is to write. If there's no data
present, let the caller know that the keyset is empty */
objectsSize = \
( pubKeySize > 0 ? \
( int ) sizeofObject( sizeofObject( pubKeySize ) ) : 0 ) +
( privKeySize > 0 ? \
( int ) sizeofObject( sizeofObject( privKeySize ) ) : 0 ) +
( certSize > 0 ? \
( int ) sizeofObject( sizeofObject( certSize ) ) : 0 ) +
( dataSize > 0 ? \
( int ) sizeofObject( sizeofObject( dataSize ) ) : 0 );
if( objectsSize <= 0 )
return( OK_SPECIAL );
/* Write the header information and each public key, private key, and
cert */
writeCMSheader( stream, OID_PKCS15_CONTENTTYPE,
sizeofShortInteger( 0 ) + sizeofObject( objectsSize ),
FALSE );
writeShortInteger( stream, 0, DEFAULT_TAG );
writeSequence( stream, objectsSize );
if( privKeySize > 0 )
{
writeObjectWrapper( stream, privKeySize, PKCS15_OBJECT_PRIVKEY );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].privKeyDataSize > 0 )
swrite( stream, pkcs15info[ i ].privKeyData,
pkcs15info[ i ].privKeyDataSize );
}
if( pubKeySize > 0 )
{
writeObjectWrapper( stream, pubKeySize, PKCS15_OBJECT_PUBKEY );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].pubKeyDataSize > 0 )
swrite( stream, pkcs15info[ i ].pubKeyData,
pkcs15info[ i ].pubKeyDataSize );
}
if( certSize > 0 )
{
writeObjectWrapper( stream, certSize, PKCS15_OBJECT_CERT );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( ( pkcs15info[ i ].type == PKCS15_SUBTYPE_NORMAL && \
pkcs15info[ i ].certDataSize > 0 ) || \
( pkcs15info[ i ].type == PKCS15_SUBTYPE_CERT ) )
swrite( stream, pkcs15info[ i ].certData,
pkcs15info[ i ].certDataSize );
}
if( dataSize > 0 )
{
writeObjectWrapper( stream, dataSize, PKCS15_OBJECT_DATA );
for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
if( pkcs15info[ i ].dataDataSize > 0 )
writeDataItem( stream, &pkcs15info[ i ] );
}
assert( sStatusOK( stream ) );
return( sflush( stream ) );
}
/* 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->flags & KEYSET_DIRTY )
{
BYTE buffer[ STREAM_BUFSIZE ];
int status;
sseek( &keysetInfo->keysetFile->stream, 0 );
sioctl( &keysetInfo->keysetFile->stream,
STREAM_IOCTL_IOBUFFER, buffer, STREAM_BUFSIZE );
status = pkcs15Flush( &keysetInfo->keysetFile->stream,
keysetInfo->keyData );
sioctl( &keysetInfo->keysetFile->stream,
STREAM_IOCTL_IOBUFFER, NULL, 0 );
if( status == OK_SPECIAL )
keysetInfo->flags |= KEYSET_EMPTY;
}
/* Free the PKCS #15 object info */
if( keysetInfo->keyData != NULL )
{
pkcs15Free( keysetInfo->keyData );
zeroise( keysetInfo->keyData, keysetInfo->keyDataSize );
clFree( "shutdownFunction", keysetInfo->keyData );
}
}
/****************************************************************************
* *
* Delete a Key *
* *
****************************************************************************/
static int deleteItemFunction( KEYSET_INFO *keysetInfo,
const KEYMGMT_ITEM_TYPE itemType,
const CRYPT_KEYID_TYPE keyIDtype,
const void *keyID, const int keyIDlength )
{
PKCS15_INFO *pkcs15infoPtr;
assert( keyIDtype == CRYPT_KEYID_NAME || \
keyIDtype == CRYPT_KEYID_URI || \
keyIDtype == CRYPT_IKEYID_KEYID || \
keyIDtype == CRYPT_IKEYID_ISSUERID );
assert( keyID != NULL ); assert( keyIDlength >= 1 );
/* Locate the appropriate object in the PKCS #15 collection */
pkcs15infoPtr = findEntry( keysetInfo->keyData, keyIDtype, keyID,
keyIDlength, KEYMGMT_FLAG_NONE );
if( pkcs15infoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* Clear this entry */
pkcs15freeEntry( pkcs15infoPtr );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Keyset Access Routines *
* *
****************************************************************************/
int setAccessMethodPKCS15( KEYSET_INFO *keysetInfo )
{
/* Set the access method pointers */
keysetInfo->initFunction = initFunction;
keysetInfo->shutdownFunction = shutdownFunction;
keysetInfo->deleteItemFunction = deleteItemFunction;
initPKCS15read( keysetInfo );
initPKCS15write( keysetInfo );
return( CRYPT_OK );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -