static int readCertAttributes( INOUT STREAM *stream, INOUT PKCS15_INFO *pkcs15infoPtr, IN_LENGTH const int endPos ) { int length, status = CRYPT_OK; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) ); REQUIRES( endPos > 0 && endPos > stell( stream ) && \ endPos < MAX_INTLENGTH ); if( peekTag( stream ) == BER_BOOLEAN ) /* Authority flag */ status = readUniversal( stream ); if( canContinue( stream, status, endPos ) && /* Identifier */ peekTag( stream ) == BER_SEQUENCE ) status = readUniversal( stream ); if( canContinue( stream, status, endPos ) && /* Thumbprint */ peekTag( stream ) == MAKE_CTAG( CTAG_CA_DUMMY ) ) status = readUniversal( stream ); if( canContinue( stream, status, endPos ) && /* Trusted usage */ peekTag( stream ) == MAKE_CTAG( CTAG_CA_TRUSTED_USAGE ) ) { readConstructed( stream, NULL, CTAG_CA_TRUSTED_USAGE ); status = readBitString( stream, &pkcs15infoPtr->trustedUsage ); } if( canContinue( stream, status, endPos ) && /* Identifiers */ peekTag( stream ) == MAKE_CTAG( CTAG_CA_IDENTIFIERS ) ) { status = readConstructed( stream, &length, CTAG_CA_IDENTIFIERS ); if( cryptStatusOK( status ) ) status = readKeyIdentifiers( stream, pkcs15infoPtr, stell( stream ) + length ); } if( canContinue( stream, status, endPos ) && /* Implicitly trusted */ peekTag( stream ) == MAKE_CTAG_PRIMITIVE( CTAG_CA_TRUSTED_IMPLICIT ) ) status = readBooleanTag( stream, &pkcs15infoPtr->implicitTrust, 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 ); }
static int readRsaPrivateKey( INOUT STREAM *stream, INOUT CONTEXT_INFO *contextInfoPtr ) { PKC_INFO *rsaKey = contextInfoPtr->ctxPKC; int status; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) ); REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \ contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA ); /* Read the header */ status = readSequence( stream, NULL ); if( cryptStatusOK( status ) && \ peekTag( stream ) == MAKE_CTAG( 0 ) ) { /* Erroneously written in older code */ status = readConstructed( stream, NULL, 0 ); } if( cryptStatusError( status ) ) return( status ); /* Read the key components */ if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 0 ) ) { /* The public components may already have been read when we read a corresponding public key or certificate so we only read them if they're not already present */ if( BN_is_zero( &rsaKey->rsaParam_n ) && \ BN_is_zero( &rsaKey->rsaParam_e ) ) { status = readBignumTag( stream, &rsaKey->rsaParam_n, RSAPARAM_MIN_N, RSAPARAM_MAX_N, NULL, 0 ); if( cryptStatusOK( status ) ) { status = readBignumTag( stream, &rsaKey->rsaParam_e, RSAPARAM_MIN_E, RSAPARAM_MAX_E, &rsaKey->rsaParam_n, 1 ); } } else { /* The key components are already present, skip them */ REQUIRES( !BN_is_zero( &rsaKey->rsaParam_n ) && \ !BN_is_zero( &rsaKey->rsaParam_e ) ); readUniversal( stream ); status = readUniversal( stream ); } if( cryptStatusError( status ) ) return( status ); } if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 2 ) ) { /* d isn't used so we skip it */ status = readUniversal( stream ); if( cryptStatusError( status ) ) return( status ); } status = readBignumTag( stream, &rsaKey->rsaParam_p, RSAPARAM_MIN_P, RSAPARAM_MAX_P, &rsaKey->rsaParam_n, 3 ); if( cryptStatusOK( status ) ) status = readBignumTag( stream, &rsaKey->rsaParam_q, RSAPARAM_MIN_Q, RSAPARAM_MAX_Q, &rsaKey->rsaParam_n, 4 ); if( cryptStatusError( status ) ) return( status ); if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 5 ) ) { status = readBignumTag( stream, &rsaKey->rsaParam_exponent1, RSAPARAM_MIN_EXP1, RSAPARAM_MAX_EXP1, &rsaKey->rsaParam_n, 5 ); if( cryptStatusOK( status ) ) status = readBignumTag( stream, &rsaKey->rsaParam_exponent2, RSAPARAM_MIN_EXP2, RSAPARAM_MAX_EXP2, &rsaKey->rsaParam_n, 6 ); if( cryptStatusOK( status ) ) status = readBignumTag( stream, &rsaKey->rsaParam_u, RSAPARAM_MIN_U, RSAPARAM_MAX_U, &rsaKey->rsaParam_n, 7 ); } return( status ); }