📄 pkcs15_atrd.c
字号:
CTAG_CA_TRUSTED_IMPLICIT );
if( canContinue( stream, status, endPos ) && /* Validity */
peekTag( stream ) == MAKE_CTAG( CTAG_CA_VALIDTO ) )
{
/* Due to miscommunication between PKCS #15 and 7816-15 there are
two ways to encode the validity information for certificates, one
based on the format used elsewhere in PKCS #15 (for PKCS #15) and
the other based on the format used in certificates (for 7816-15).
Luckily they can be distinguished by the tagging type */
readConstructed( stream, NULL, CTAG_CA_VALIDTO );
readUTCTime( stream, &pkcs15infoPtr->validFrom );
status = readUTCTime( stream, &pkcs15infoPtr->validTo );
}
else
{
if( canContinue( stream, status, endPos ) && /* Start date */
peekTag( stream ) == BER_TIME_GENERALIZED )
status = readGeneralizedTime( stream, &pkcs15infoPtr->validFrom );
if( canContinue( stream, status, endPos ) && /* End date */
peekTag( stream ) == MAKE_CTAG_PRIMITIVE( CTAG_CA_VALIDTO ) )
status = readGeneralizedTimeTag( stream, &pkcs15infoPtr->validTo,
CTAG_CA_VALIDTO );
}
return( status );
}
/* Read an object's attributes */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
int readObjectAttributes( INOUT STREAM *stream,
INOUT PKCS15_INFO *pkcs15infoPtr,
IN_ENUM( PKCS15_OBJECT ) const PKCS15_OBJECT_TYPE type,
INOUT ERROR_INFO *errorInfo )
{
const ALLOWED_ATTRIBUTE_TYPES *allowedTypeInfo;
BOOLEAN skipDataRead = TRUE, isCryptlibData = FALSE;
int length, endPos, value, tag, i, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );
REQUIRES( type > PKCS15_OBJECT_NONE && type < PKCS15_OBJECT_LAST );
REQUIRES( errorInfo != NULL );
/* Clear the return value */
memset( pkcs15infoPtr, 0, sizeof( PKCS15_INFO ) );
/* Find the allowed-subtype information for this object type */
for( i = 0; \
allowedTypesTbl[ i ].type != type && \
i < FAILSAFE_ARRAYSIZE( allowedTypesTbl, ALLOWED_ATTRIBUTE_TYPES );
i++ );
ENSURES( i < FAILSAFE_ARRAYSIZE( allowedTypesTbl, ALLOWED_ATTRIBUTE_TYPES ) );
allowedTypeInfo = &allowedTypesTbl[ i ];
/* Make sure that this is a subtype that we can handle */
tag = peekTag( stream );
if( cryptStatusError( tag ) )
return( tag );
status = readGenericHole( stream, NULL, MIN_OBJECT_SIZE, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( status );
for( i = 0; allowedTypeInfo->subTypes[ i ] != CRYPT_ERROR && \
i < FAILSAFE_ITERATIONS_SMALL; i++ )
{
/* If this is a recognised subtype, process the attribute data */
if( allowedTypeInfo->subTypes[ i ] == tag )
{
skipDataRead = FALSE;
break;
}
}
ENSURES( i < FAILSAFE_ITERATIONS_SMALL );
/* Process the PKCS15CommonObjectAttributes */
status = readSequence( stream, &length );
if( cryptStatusOK( status ) && length > 0 )
{
endPos = stell( stream ) + length;
/* Read the label if it's present and skip anything else */
if( peekTag( stream ) == BER_STRING_UTF8 )
{
status = readCharacterString( stream,
pkcs15infoPtr->label, CRYPT_MAX_TEXTSIZE,
&pkcs15infoPtr->labelLength, BER_STRING_UTF8 );
}
if( canContinue( stream, status, endPos ) )
status = sseek( stream, endPos );
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 common object attributes" ) );
}
/* Process the PKCS15CommonXXXAttributes */
status = readSequence( stream, &length );
if( cryptStatusError( status ) )
return( status );
endPos = stell( stream ) + length;
switch( type )
{
case PKCS15_OBJECT_DATA:
/* If it's a data object then all of the attributes are
optional. If it's specifically a cryptlib data object then
it'll be identified via the cryptlib OID */
if( length <= 0 )
break;
if( peekTag( stream ) == BER_STRING_UTF8 )
status = readUniversal( stream ); /* Skip application name */
if( canContinue( stream, status, endPos ) && \
peekTag( stream ) == BER_OBJECT_IDENTIFIER )
{
status = readOID( stream, dataObjectOIDinfo,
FAILSAFE_ARRAYSIZE( dataObjectOIDinfo, \
OID_INFO ), &value );
if( cryptStatusOK( status ) && value == TRUE )
isCryptlibData = TRUE;
}
break;
case PKCS15_OBJECT_PUBKEY:
case PKCS15_OBJECT_PRIVKEY:
/* It's a key object, read the ID and assorted flags */
status = readOctetString( stream, pkcs15infoPtr->iD,
&pkcs15infoPtr->iDlength,
1, CRYPT_MAX_HASHSIZE );
if( cryptStatusOK( status ) && \
canContinue( stream, status, endPos ) )
{
status = readPubkeyAttributes( stream, pkcs15infoPtr,
endPos,
( type == PKCS15_OBJECT_PUBKEY ) ? \
TRUE : FALSE );
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 public/private-key "
"attributes" ) );
}
break;
case PKCS15_OBJECT_CERT:
/* It's a certificate object, read the ID and assorted flags */
status = readOctetString( stream, pkcs15infoPtr->iD,
&pkcs15infoPtr->iDlength,
1, CRYPT_MAX_HASHSIZE );
if( cryptStatusOK( status ) && \
canContinue( stream, status, endPos ) )
{
status = readCertAttributes( stream, pkcs15infoPtr,
endPos );
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 certificate attributes" ) );
}
break;
default:
retIntError();
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 common type attributes" ) );
}
/* Skip any additional attribute information that may be present */
if( stell( stream ) < endPos )
{
status = sseek( stream, endPos );
if( cryptStatusError( status ) )
return( status );
}
/* For now we use the iD as the keyID, this may be overridden later if
there's a real keyID present */
if( pkcs15infoPtr->iDlength > 0 )
{
memcpy( pkcs15infoPtr->keyID, pkcs15infoPtr->iD,
pkcs15infoPtr->iDlength );
pkcs15infoPtr->keyIDlength = pkcs15infoPtr->iDlength;
}
/* Skip the subclass attributes if present */
if( peekTag( stream ) == MAKE_CTAG( CTAG_OB_SUBCLASSATTR ) )
{
status = readUniversal( stream );
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 subclass attributes" ) );
}
}
/* Process the type attributes, which just consists of remembering where
the payload starts */
readConstructed( stream, NULL, CTAG_OB_TYPEATTR );
status = readSequence( stream, &length );
if( cryptStatusError( status ) )
return( status );
endPos = stell( stream ) + length;
if( skipDataRead )
{
/* It's a non-recognised object subtype, skip it */
return( ( stell( stream ) < endPos ) ? \
sseek( stream, endPos ) : CRYPT_OK );
}
switch( type )
{
case PKCS15_OBJECT_PUBKEY:
status = readConstructed( stream, NULL, CTAG_OV_DIRECT );
if( cryptStatusOK( status ) )
pkcs15infoPtr->pubKeyOffset = stell( stream );
break;
case PKCS15_OBJECT_PRIVKEY:
pkcs15infoPtr->privKeyOffset = stell( stream );
break;
case PKCS15_OBJECT_CERT:
pkcs15infoPtr->certOffset = stell( stream );
break;
case PKCS15_OBJECT_DATA:
/* If it's not cryptlib data, we can't do much with it */
if( !isCryptlibData )
break;
/* It's a cryptlib data object, extract the contents */
status = readOID( stream, cryptlibDataOIDinfo,
FAILSAFE_ARRAYSIZE( cryptlibDataOIDinfo, \
OID_INFO ),
&value );
if( cryptStatusOK( status ) && \
( value == CRYPT_IATTRIBUTE_CONFIGDATA || \
value == CRYPT_IATTRIBUTE_USERINDEX ) )
{
/* The configuration data and user index are SEQUENCEs of
objects */
status = readSequence( stream, NULL );
}
if( cryptStatusError( status ) )
break;
if( value == CRYPT_ATTRIBUTE_NONE )
{
/* It's a non-recognised cryptlib data subtype, skip it */
break;
}
pkcs15infoPtr->dataOffset = stell( stream );
pkcs15infoPtr->dataType = value;
break;
default:
retIntError();
}
if( cryptStatusError( status ) )
{
retExt( status,
( status, errorInfo,
"Invalid PKCS #15 type attributes" ) );
}
/* Skip the object data and any additional attribute information that
may be present */
if( stell( stream ) < endPos )
return( sseek( stream, endPos ) );
return( CRYPT_OK );
}
#endif /* USE_PKCS15 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -