📄 pkcs15.c
字号:
if( pkcs15info->pubKeyData != NULL )
{
zeroise( pkcs15info->pubKeyData, pkcs15info->pubKeyDataSize );
clFree( "pkcs15freeEntry", pkcs15info->pubKeyData );
}
if( pkcs15info->privKeyData != NULL )
{
zeroise( pkcs15info->privKeyData, pkcs15info->privKeyDataSize );
clFree( "pkcs15freeEntry", pkcs15info->privKeyData );
}
if( pkcs15info->certData != NULL )
{
zeroise( pkcs15info->certData, pkcs15info->certDataSize );
clFree( "pkcs15freeEntry", pkcs15info->certData );
}
if( pkcs15info->dataData != NULL )
{
zeroise( pkcs15info->dataData, pkcs15info->dataDataSize );
clFree( "pkcs15freeEntry", pkcs15info->dataData );
}
zeroise( pkcs15info, sizeof( PKCS15_INFO ) );
}
STDC_NONNULL_ARG( ( 1 ) ) \
static void pkcs15Free( INOUT_ARRAY( noPkcs15objects ) PKCS15_INFO *pkcs15info,
IN_LENGTH_SHORT const int noPkcs15objects )
{
int i;
assert( isWritePtr( pkcs15info, \
sizeof( PKCS15_INFO ) * noPkcs15objects ) );
REQUIRES_V( noPkcs15objects >= 1 && \
noPkcs15objects < MAX_INTLENGTH_SHORT );
for( i = 0; i < noPkcs15objects && i < FAILSAFE_ITERATIONS_MED; i++ )
pkcs15freeEntry( &pkcs15info[ i ] );
ENSURES_V( i < FAILSAFE_ITERATIONS_MED );
zeroise( pkcs15info, sizeof( PKCS15_INFO ) * noPkcs15objects );
}
/* Get the PKCS #15 validity information from a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int getValidityInfo( INOUT PKCS15_INFO *pkcs15info,
IN_HANDLE const CRYPT_HANDLE cryptHandle )
{
MESSAGE_DATA msgData;
time_t validFrom, validTo;
int status;
assert( isWritePtr( pkcs15info, sizeof( PKCS15_INFO ) ) );
REQUIRES( isHandleRangeValid( cryptHandle ) );
/* Remember the validity information for later. We always update the
validity (even if it's already set) since we may be replacing an
older certificate with a newer one */
setMessageData( &msgData, &validFrom, sizeof( time_t ) );
status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_VALIDFROM );
if( cryptStatusError( status ) )
return( status );
setMessageData( &msgData, &validTo, sizeof( time_t ) );
status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_CERTINFO_VALIDTO );
if( cryptStatusError( status ) )
return( status );
if( pkcs15info->validTo > validTo )
{
/* There's an existing, newer certificate already present, make sure
that we don't try and add the new one */
return( CRYPT_ERROR_DUPLICATE );
}
pkcs15info->validFrom = validFrom;
pkcs15info->validTo = validTo;
return( CRYPT_OK );
}
/* Read the header of a PKCS #15 keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readPkcs15header( INOUT STREAM *stream,
OUT_INT_Z long *endPosPtr )
{
long endPos, dataEndPos;
int value, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( endPosPtr, sizeof( long ) ) );
/* Clear return value */
*endPosPtr = 0;
/* Read the outer header and make sure that the length information is
valid */
status = readCMSheader( stream, keyFileOIDinfo,
FAILSAFE_ARRAYSIZE( keyFileOIDinfo, OID_INFO ),
&dataEndPos, FALSE );
if( cryptStatusError( status ) )
return( status );
/* If it's indefinite-length data, don't try and go any further (the
general length check below will also catch this, but we make the
check explicit here) */
if( dataEndPos == CRYPT_UNUSED )
return( CRYPT_ERROR_BADDATA );
/* Make sure that the length information is sensible. readCMSheader()
reads the version number field at the start of the content so we have
to adjust the stream position for this when we calculate the data end
position */
endPos = ( stell( stream ) - sizeofShortInteger( 0 ) ) + dataEndPos;
if( dataEndPos < MIN_OBJECT_SIZE || dataEndPos >= MAX_INTLENGTH || \
endPos < 16 + MIN_OBJECT_SIZE || endPos >= MAX_INTLENGTH )
return( CRYPT_ERROR_BADDATA );
*endPosPtr = endPos;
/* Skip the key management information if there is any and read the
inner wrapper */
status = value = peekTag( stream );
if( cryptStatusError( status ) )
return( status );
if( value == MAKE_CTAG( 0 ) )
readUniversal( stream );
return( readLongSequence( stream, NULL ) );
}
/****************************************************************************
* *
* Init/Shutdown Functions *
* *
****************************************************************************/
/* A PKCS #15 keyset can contain multiple keys and whatnot, so when we open
it we parse the contents into memory for later use */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int initFunction( INOUT KEYSET_INFO *keysetInfoPtr,
STDC_UNUSED const char *name,
STDC_UNUSED const int nameLength,
IN_ENUM( CRYPT_KEYOPT ) const CRYPT_KEYOPT_TYPE options )
{
PKCS15_INFO *pkcs15info;
STREAM *stream = &keysetInfoPtr->keysetFile->stream;
long endPos = DUMMY_INIT;
int status;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
REQUIRES( name == NULL && nameLength == 0 );
REQUIRES( options >= CRYPT_KEYOPT_NONE && options < CRYPT_KEYOPT_LAST );
/* If we're opening an existing keyset skip the outer header, optional
keyManagementInfo, and inner header. We do this before we perform any
setup operations to weed out potential problem files */
if( options != CRYPT_KEYOPT_CREATE )
{
status = readPkcs15header( stream, &endPos );
if( cryptStatusError( status ) )
retExt( status,
( status, KEYSET_ERRINFO,
"Invalid PKCS #15 keyset header" ) );
}
/* Allocate the PKCS #15 object information */
if( ( pkcs15info = clAlloc( "initFunction", \
sizeof( PKCS15_INFO ) * \
MAX_PKCS15_OBJECTS ) ) == NULL )
{
if( options != CRYPT_KEYOPT_CREATE )
{
/* Reset the stream position to account for the header
information that we've already read */
sseek( stream, 0 ) ;
}
return( CRYPT_ERROR_MEMORY );
}
memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS );
keysetInfoPtr->keyData = pkcs15info;
keysetInfoPtr->keyDataSize = sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS;
keysetInfoPtr->keyDataNoObjects = 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( &keysetInfoPtr->keysetFile->stream, pkcs15info,
MAX_PKCS15_OBJECTS, endPos, KEYSET_ERRINFO );
if( cryptStatusError( status ) )
{
pkcs15Free( pkcs15info, MAX_PKCS15_OBJECTS );
clFree( "initFunction", keysetInfoPtr->keyData );
keysetInfoPtr->keyData = NULL;
keysetInfoPtr->keyDataSize = 0;
if( options != CRYPT_KEYOPT_CREATE )
{
/* Reset the stream position to account for the header
information that we've already read */
sseek( stream, 0 ) ;
}
return( status );
}
return( CRYPT_OK );
}
/* Shut down the PKCS #15 state, flushing information to disk if necessary */
RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int shutdownFunction( INOUT KEYSET_INFO *keysetInfoPtr )
{
int status = CRYPT_OK;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
/* If the contents have been changed, allocate a working I/O buffer for
the duration of the flush and commit the changes to disk */
if( keysetInfoPtr->flags & KEYSET_DIRTY )
{
STREAM *stream = &keysetInfoPtr->keysetFile->stream;
BYTE buffer[ STREAM_BUFSIZE + 8 ];
sseek( stream, 0 );
sioctl( stream, STREAM_IOCTL_IOBUFFER, buffer, STREAM_BUFSIZE );
status = pkcs15Flush( stream, keysetInfoPtr->keyData,
keysetInfoPtr->keyDataNoObjects );
sioctl( stream, STREAM_IOCTL_IOBUFFER, NULL, 0 );
if( status == OK_SPECIAL )
{
keysetInfoPtr->flags |= KEYSET_EMPTY;
status = CRYPT_OK;
}
}
/* Free the PKCS #15 object information */
if( keysetInfoPtr->keyData != NULL )
{
pkcs15Free( keysetInfoPtr->keyData, keysetInfoPtr->keyDataNoObjects );
zeroise( keysetInfoPtr->keyData, keysetInfoPtr->keyDataSize );
clFree( "shutdownFunction", keysetInfoPtr->keyData );
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, KEYSET_ERRINFO,
"Couldn't send PKCS #15 data to persistent storage" ) );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Keyset Access Routines *
* *
****************************************************************************/
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setAccessMethodPKCS15( INOUT KEYSET_INFO *keysetInfoPtr )
{
int status;
assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
keysetInfoPtr->subType == KEYSET_SUBTYPE_PKCS15 );
/* Set the access method pointers */
keysetInfoPtr->initFunction = initFunction;
keysetInfoPtr->shutdownFunction = shutdownFunction;
status = initPKCS15get( keysetInfoPtr );
if( cryptStatusOK( status ) )
status = initPKCS15set( keysetInfoPtr );
return( status );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -