📄 pkcs15_rd.c
字号:
&mechanismInfo, MECHANISM_PRIVATEKEYWRAP );
clearMechanismInfo( &mechanismInfo );
krnlSendNotifier( iSessionKey, IMESSAGE_DECREFCOUNT );
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo, "Couldn't unwrap private key" ) );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Read a Keyset *
* *
****************************************************************************/
/* Read a single object in a keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4, 6 ) ) \
static int readObject( INOUT STREAM *stream,
INOUT PKCS15_INFO *pkcs15objectInfo,
OUT_BUFFER_ALLOC( *objectLengthPtr ) void **objectPtrPtr,
OUT_LENGTH_SHORT_Z int *objectLengthPtr,
IN_ENUM( PKCS15_OBJECT ) const PKCS15_OBJECT_TYPE type,
INOUT ERROR_INFO *errorInfo )
{
STREAM objectStream;
BYTE buffer[ MIN_OBJECT_SIZE + 8 ];
void *objectData;
int headerSize = DUMMY_INIT, objectLength = DUMMY_INIT, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( pkcs15objectInfo, sizeof( PKCS15_INFO ) ) );
assert( isWritePtr( objectPtrPtr, sizeof( void * ) ) );
assert( isWritePtr( objectLengthPtr, sizeof( int ) ) );
REQUIRES( type > PKCS15_OBJECT_NONE && type < PKCS15_OBJECT_LAST );
REQUIRES( errorInfo != NULL );
/* Clear return values */
memset( pkcs15objectInfo, 0, sizeof( PKCS15_INFO ) );
*objectPtrPtr = NULL;
*objectLengthPtr = 0;
/* Read the current object. We can't use getObjectLength() here because
we're reading from a file rather than a memory stream so we have to
grab the first MIN_OBJECT_SIZE bytes from the file stream and decode
them to see what's next */
status = sread( stream, buffer, MIN_OBJECT_SIZE );
if( cryptStatusOK( status ) )
{
STREAM headerStream;
sMemConnect( &headerStream, buffer, MIN_OBJECT_SIZE );
status = readGenericHole( &headerStream, &objectLength,
MIN_OBJECT_SIZE, DEFAULT_TAG );
if( cryptStatusOK( status ) )
headerSize = stell( &headerStream );
sMemDisconnect( &headerStream );
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Couldn't read PKCS #15 object data" ) );
}
if( objectLength < MIN_OBJECT_SIZE || \
objectLength > MAX_INTLENGTH_SHORT )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 object length %d", objectLength ) );
}
/* Allocate storage for the object and copy the already-read portion to
the start of the storage */
objectLength += headerSize;
if( ( objectData = clAlloc( "readObject", objectLength ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memcpy( objectData, buffer, MIN_OBJECT_SIZE );
/* Read the remainder of the object into the memory buffer and check
that the overall object is valid */
status = sread( stream, ( BYTE * ) objectData + MIN_OBJECT_SIZE,
objectLength - MIN_OBJECT_SIZE );
if( cryptStatusOK( status ) )
status = checkObjectEncoding( objectData, objectLength );
if( cryptStatusError( status ) )
{
clFree( "readObject", objectData );
retExt( status,
( status, errorInfo, "Invalid PKCS #15 object data" ) );
}
/* Read the object attributes from the in-memory object data */
sMemConnect( &objectStream, objectData, objectLength );
status = readObjectAttributes( &objectStream, pkcs15objectInfo, type,
errorInfo );
sMemDisconnect( &objectStream );
if( cryptStatusError( status ) )
{
clFree( "readObject", objectData );
return( status );
}
/* Remember the encoded object data */
*objectPtrPtr = objectData;
*objectLengthPtr = objectLength;
return( CRYPT_OK );
}
/* Read an entire keyset */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
int readKeyset( INOUT STREAM *stream,
OUT_ARRAY( maxNoPkcs15objects ) PKCS15_INFO *pkcs15info,
IN_LENGTH_SHORT const int maxNoPkcs15objects,
IN_LENGTH const long endPos,
INOUT ERROR_INFO *errorInfo )
{
int iterationCount, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( pkcs15info, sizeof( PKCS15_INFO ) ) );
REQUIRES( maxNoPkcs15objects >= 1 && \
maxNoPkcs15objects < MAX_INTLENGTH_SHORT );
REQUIRES( endPos > 0 && endPos > stell( stream ) && \
endPos < MAX_INTLENGTH );
REQUIRES( errorInfo != NULL );
/* Clear return value */
memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * maxNoPkcs15objects );
/* Scan all of the objects in the file */
for( status = CRYPT_OK, iterationCount = 0;
cryptStatusOK( status ) && stell( stream ) < endPos && \
iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ )
{
typedef struct {
int tag;
PKCS15_OBJECT_TYPE type;
} TAGTOTYPE_INFO;
static const TAGTOTYPE_INFO tagToTypeTbl[] = {
{ CTAG_PO_PRIVKEY, PKCS15_OBJECT_PRIVKEY },
{ CTAG_PO_PUBKEY, PKCS15_OBJECT_PUBKEY },
{ CTAG_PO_TRUSTEDPUBKEY, PKCS15_OBJECT_PUBKEY },
{ CTAG_PO_SECRETKEY, PKCS15_OBJECT_SECRETKEY },
{ CTAG_PO_CERT, PKCS15_OBJECT_CERT },
{ CTAG_PO_TRUSTEDCERT, PKCS15_OBJECT_CERT },
{ CTAG_PO_USEFULCERT, PKCS15_OBJECT_CERT },
{ CTAG_PO_DATA, PKCS15_OBJECT_DATA },
{ CTAG_PO_AUTH, PKCS15_OBJECT_NONE },
{ CRYPT_ERROR, PKCS15_OBJECT_NONE },
{ CRYPT_ERROR, PKCS15_OBJECT_NONE }
};
PKCS15_OBJECT_TYPE type = PKCS15_OBJECT_NONE;
int tag, innerEndPos, i, innerIterationCount;
/* Map the object tag to a PKCS #15 object type */
tag = peekTag( stream );
if( cryptStatusError( tag ) )
return( tag );
tag = EXTRACT_CTAG( tag );
for( i = 0; tagToTypeTbl[ i ].tag != CRYPT_ERROR && \
i < FAILSAFE_ARRAYSIZE( tagToTypeTbl, TAGTOTYPE_INFO );
i++ )
{
if( tagToTypeTbl[ i ].tag == tag )
{
type = tagToTypeTbl[ i ].type;
break;
}
}
ENSURES( i < FAILSAFE_ARRAYSIZE( tagToTypeTbl, TAGTOTYPE_INFO ) );
if( type == PKCS15_OBJECT_NONE )
{
retExt( CRYPT_ERROR_BADDATA,
( CRYPT_ERROR_BADDATA, errorInfo,
"Invalid PKCS #15 object type %02X", tag ) );
}
/* Read the [n] [0] wrapper to find out what we're dealing with.
Note that we set the upper limit at MAX_INTLENGTH rather than
MAX_INTLENGTH_SHORT because some keysets with many large objects
may have a combined group-of-objects length larger than
MAX_INTLENGTH_SHORT */
readConstructed( stream, NULL, tag );
status = readConstructed( stream, &innerEndPos, CTAG_OV_DIRECT );
if( cryptStatusError( status ) )
return( status );
if( innerEndPos < MIN_OBJECT_SIZE || innerEndPos >= MAX_INTLENGTH )
{
retExt( CRYPT_ERROR_BADDATA,
( CRYPT_ERROR_BADDATA, errorInfo,
"Invalid PKCS #15 object data size %d",
innerEndPos ) );
}
innerEndPos += stell( stream );
/* Scan all objects of this type */
for( innerIterationCount = 0;
stell( stream ) < innerEndPos && \
innerIterationCount < FAILSAFE_ITERATIONS_LARGE;
innerIterationCount++ )
{
PKCS15_INFO pkcs15objectInfo, *pkcs15infoPtr = NULL;
void *object;
int objectLength;
/* Read the object */
status = readObject( stream, &pkcs15objectInfo, &object,
&objectLength, type, errorInfo );
if( cryptStatusError( status ) )
return( status );
/* If we read an object with associated ID information, find out
where to add the object data */
if( pkcs15objectInfo.iDlength > 0 )
{
pkcs15infoPtr = findEntry( pkcs15info, maxNoPkcs15objects,
CRYPT_KEYIDEX_ID,
pkcs15objectInfo.iD,
pkcs15objectInfo.iDlength,
KEYMGMT_FLAG_NONE );
}
if( pkcs15infoPtr == NULL )
{
int index;
/* This personality isn't present yet, find out where we can
add the object data and copy the fixed object information
over */
pkcs15infoPtr = findFreeEntry( pkcs15info,
maxNoPkcs15objects, &index );
if( pkcs15infoPtr == NULL )
{
clFree( "readKeyset", object );
retExt( CRYPT_ERROR_OVERFLOW,
( CRYPT_ERROR_OVERFLOW, errorInfo,
"No more room in keyset to add further items" ) );
}
pkcs15infoPtr->index = index;
memcpy( pkcs15infoPtr, &pkcs15objectInfo,
sizeof( PKCS15_INFO ) );
}
/* Copy over any ID information */
copyObjectIdInfo( pkcs15infoPtr, &pkcs15objectInfo );
/* Copy over any other new information that may have become
available. The semantics when multiple date ranges are
present (for example one for a key and one for a certificate)
are a bit uncertain, we use the most recent date available on
the assumption that this reflects the newest information */
if( pkcs15objectInfo.validFrom > pkcs15infoPtr->validFrom )
pkcs15infoPtr->validFrom = pkcs15objectInfo.validFrom;
if( pkcs15objectInfo.validTo > pkcs15infoPtr->validTo )
pkcs15infoPtr->validTo = pkcs15objectInfo.validTo;
/* Copy the payload over */
copyObjectPayloadInfo( pkcs15infoPtr, &pkcs15objectInfo,
object, objectLength, type );
}
ENSURES( innerIterationCount < FAILSAFE_ITERATIONS_LARGE );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
return( CRYPT_OK );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -