📄 comp_get.c
字号:
const CRYPT_ATTRIBUTE_TYPE fieldID = certInfoPtr->attributeCursor->fieldID;
ATTRIBUTE_LIST *attributeListPtr;
int iterationCount;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* We're inside a GeneralName, clear any possible saved selection */
certInfoPtr->currentSelection.generalName = CRYPT_ATTRIBUTE_NONE;
REQUIRES( selectionInfoConsistent( certInfoPtr ) );
/* Search for a DN in the current GeneralName */
for( attributeListPtr = certInfoPtr->attributeCursor,
iterationCount = 0;
attributeListPtr != NULL && \
attributeListPtr->attributeID == attributeID && \
attributeListPtr->fieldID == fieldID && \
iterationCount < FAILSAFE_ITERATIONS_MAX;
attributeListPtr = attributeListPtr->next, iterationCount++ )
{
if( attributeListPtr->fieldType == FIELDTYPE_DN )
{
/* We found a DN, select it */
certInfoPtr->currentSelection.dnPtr = &attributeListPtr->value;
if( updateCursor )
certInfoPtr->attributeCursor = attributeListPtr;
certInfoPtr->currentSelection.dnInExtension = TRUE;
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
return( CRYPT_ERROR_NOTFOUND );
}
/* Find a GeneralName field in a GeneralName */
#if 0
/* Currently handled with:
attributeListPtr = findAttributeField( certInfoPtr->attributeCursor,
certInfoPtr->attributeCursor->fieldID,
certInfoType ); */
static const ATTRIBUTE_LIST *findGeneralNameField( const ATTRIBUTE_LIST *attributeListPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType )
{
const CRYPT_ATTRIBUTE_TYPE attributeID = attributeListPtr->attributeID;
const CRYPT_ATTRIBUTE_TYPE fieldID = attributeListPtr->fieldID;
int iterationCount;
REQUIRES( isGeneralNameSelectionComponent( attributeListPtr->fieldID ) );
/* Search for the GeneralName component in the current GeneralName */
for( iterationCount = 0;
attributeListPtr != NULL && \
attributeListPtr->attributeID == attributeID && \
attributeListPtr->fieldID == fieldID && \
iterationCount < FAILSAFE_ITERATIONS_LARGE;
attributeListPtr = attributeListPtr->next, iterationCount++ )
{
if( attributeListPtr->subFieldID == certInfoType )
return( attributeListPtr );
}
ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_LARGE );
return( NULL );
}
#endif /* 0 */
/* Move the extension cursor to the given extension field */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int moveCursorToField( INOUT CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType )
{
const ATTRIBUTE_LIST *attributeListPtr;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( selectionInfoConsistent( certInfoPtr ) );
REQUIRES( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
certInfoType <= CRYPT_CERTINFO_LAST );
/* Try and locate the given field in the extension */
attributeListPtr = findAttributeField( certInfoPtr->attributes,
certInfoType,
CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* We found the given field, update the cursor and select the DN within
it if it's present */
certInfoPtr->currentSelection.updateCursor = FALSE;
certInfoPtr->attributeCursor = ( ATTRIBUTE_LIST * ) attributeListPtr;
if( isGeneralNameSelectionComponent( certInfoType ) )
{
/* If this is a GeneralName, select the DN within it if there's one
present. Since this is peripheral to the main operation of
moving the cursor, we ignore the return status */
( void ) findDnInExtension( certInfoPtr, FALSE );
}
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
/* Synchronise DN/GeneralName selection information after moving the
extension cursor */
STDC_NONNULL_ARG( ( 1 ) ) \
void syncSelection( INOUT CERT_INFO *certInfoPtr )
{
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* We've moved the cursor, clear any saved GeneralName selection */
certInfoPtr->currentSelection.generalName = CRYPT_ATTRIBUTE_NONE;
/* I've we've moved the cursor off the GeneralName or there's no DN in
the GeneralName, deselect the DN */
if( !isGeneralNameSelected( certInfoPtr ) || \
cryptStatusError( findDnInExtension( certInfoPtr, FALSE ) ) )
{
certInfoPtr->currentSelection.dnPtr = NULL;
certInfoPtr->currentSelection.dnInExtension = FALSE;
}
}
/* Handle selection of a GeneralName in a certificate extension */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int selectGeneralName( INOUT CERT_INFO *certInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
IN_ENUM( SELECTION_OPTION ) const SELECTION_OPTION option )
{
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
#ifndef __WINCE__ /* String too long for compiler */
REQUIRES( ( option == MAY_BE_ABSENT && \
isGeneralNameSelectionComponent( certInfoType ) ) || \
( ( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT ) && \
certInfoType == CRYPT_ATTRIBUTE_NONE ) );
#endif /* !__WINCE__ */
REQUIRES( selectionInfoConsistent( certInfoPtr ) );
certInfoPtr->currentSelection.updateCursor = FALSE;
if( option == MAY_BE_ABSENT )
{
/* If the selection is present, update the extension cursor and
exit */
if( cryptStatusOK( moveCursorToField( certInfoPtr, certInfoType ) ) )
return( CRYPT_OK );
/* If the certificate is in the high state then the MAY is treated
as a MUST since we can't be selecting something in order to
create it later as we can for a certificate in the low state */
if( certInfoPtr->certificate != NULL )
return( CRYPT_ERROR_NOTFOUND );
/* The selection isn't present, remember it for later without
changing any other selection info */
certInfoPtr->currentSelection.generalName = certInfoType;
certInfoPtr->attributeCursor = NULL;
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
ENSURES( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT );
/* If there's no saved GeneralName selection present, the extension
cursor must be pointing to a GeneralName */
if( certInfoPtr->currentSelection.generalName == CRYPT_ATTRIBUTE_NONE )
{
return( isGeneralNameSelected( certInfoPtr ) ? \
CRYPT_OK : CRYPT_ERROR_NOTFOUND );
}
/* Try and move the cursor to the saved GeneralName selection */
if( cryptStatusOK( \
moveCursorToField( certInfoPtr,
certInfoPtr->currentSelection.generalName ) ) )
return( CRYPT_OK );
if( option == MUST_BE_PRESENT )
return( CRYPT_ERROR_NOTFOUND );
/* We're creating the GeneralName extension, deselect the current DN and
remember that we have to update the extension cursor when we've done
it */
certInfoPtr->currentSelection.dnPtr = NULL;
certInfoPtr->currentSelection.dnInExtension = FALSE;
certInfoPtr->currentSelection.updateCursor = TRUE;
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
/* Handle selection of DNs */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int selectDN( INOUT CERT_INFO *certInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
IN_ENUM( SELECTION_OPTION ) const SELECTION_OPTION option )
{
CRYPT_ATTRIBUTE_TYPE generalName = \
certInfoPtr->currentSelection.generalName;
static const int value = CRYPT_UNUSED;
int status;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( ( option == MAY_BE_ABSENT && \
isDNSelectionComponent( certInfoType ) ) || \
( ( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT ) && \
certInfoType == CRYPT_ATTRIBUTE_NONE ) );
REQUIRES( selectionInfoConsistent( certInfoPtr ) );
if( option == MAY_BE_ABSENT )
{
/* Try and select a DN based on the supplied attribute ID */
switch( certInfoType )
{
case CRYPT_CERTINFO_SUBJECTNAME:
certInfoPtr->currentSelection.dnPtr = &certInfoPtr->subjectName;
break;
case CRYPT_CERTINFO_ISSUERNAME:
certInfoPtr->currentSelection.dnPtr = &certInfoPtr->issuerName;
/* If it's a self-signed certificate and the issuer name
isn't explicitly present then it must be implicitly
present as the subject name */
if( certInfoPtr->issuerName == NULL && \
( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) )
certInfoPtr->currentSelection.dnPtr = &certInfoPtr->subjectName;
break;
default:
retIntError();
}
/* We've selected a built-in DN, remember that this isn't one in an
(optional) extension */
certInfoPtr->currentSelection.dnInExtension = FALSE;
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
/* If there's a DN already selected, we're done */
if( certInfoPtr->currentSelection.dnPtr != NULL )
return( CRYPT_OK );
ENSURES( option == MUST_BE_PRESENT || option == CREATE_IF_ABSENT );
/* To select a DN in a GeneralName we first need to have a GeneralName
selected */
status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE, option );
if( cryptStatusError( status ) )
return( status );
/* If we've now got a GeneralName selected, try and find a DN in it */
if( isGeneralNameSelected( certInfoPtr ) )
{
/* If there's a DN currently selected, we're done */
if( certInfoPtr->attributeCursor->fieldType == FIELDTYPE_DN )
{
certInfoPtr->currentSelection.dnPtr = \
&certInfoPtr->attributeCursor->value;
certInfoPtr->currentSelection.dnInExtension = TRUE;
ENSURES( selectionInfoConsistent( certInfoPtr ) );
return( CRYPT_OK );
}
/* There's no DN selected, see if there's one present somewhere in
the extension */
if( cryptStatusOK( findDnInExtension( certInfoPtr, TRUE ) ) )
return( CRYPT_OK );
/* If there's no DN present and we're not about to create one,
exit */
if( option == MUST_BE_PRESENT )
return( CRYPT_ERROR_NOTFOUND );
/* Create the DN in the currently selected GeneralName */
generalName = certInfoPtr->attributeCursor->fieldID;
}
/* We're being asked to instantiate the DN, create the attribute field
that contains it */
status = addAttributeField( &certInfoPtr->attributes, generalName,
CRYPT_CERTINFO_DIRECTORYNAME, &value, CRYPT_UNUSED,
ATTR_FLAG_NONE, &certInfoPtr->errorLocus,
&certInfoPtr->errorType );
if( cryptStatusError( status ) )
return( status );
/* Find the field that we just created. This is a newly-created
attribute so it's the only one present (i.e we don't have to worry
about finding one added at the end of the sequence of identical
attributes) and we also know that it must be present since we've
just created it */
return( selectGeneralName( certInfoPtr, generalName, MAY_BE_ABSENT ) );
}
/****************************************************************************
* *
* Get Certificate Info *
* *
****************************************************************************/
/* Copy integer-value data from a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int copyCertInfoValue( OUT TYPECAST( int * ) void *certInfo,
const int value )
{
assert( isWritePtr( certInfo, sizeof( int ) ) );
if( certInfo != NULL )
*( ( int * ) certInfo ) = value;
return( CRYPT_OK );
}
/* Get a certificate component */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getCertAttributeComponentData( const ATTRIBUTE_LIST *attributeListPtr,
OUT_BUFFER_OPT( certInfoMaxLength, certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength < MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* If the data type is an OID we have to convert it to a human-readable
form before we return it */
if( attributeListPtr->fieldType == BER_OBJECT_IDENTIFIER )
{
char textOID[ ( CRYPT_MAX_TEXTSIZE * 2 ) + 8 ];
int textOidLength, status;
ENSURES( certInfoLength != NULL );
status = oidToText( attributeListPtr->value,
attributeListPtr->valueLength,
textOID, CRYPT_MAX_TEXTSIZE * 2,
&textOidLength );
if( cryptStatusError( status ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -