📄 ext.c
字号:
ATTRIBUTE_LIST *findAttributeField( IN_OPT const ATTRIBUTE_LIST *attributeListPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE fieldID,
IN_ATTRIBUTE_OPT \
const CRYPT_ATTRIBUTE_TYPE subFieldID )
{
assert( attributeListPtr == NULL || \
isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
REQUIRES_N( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
fieldID <= CRYPT_CERTINFO_LAST );
REQUIRES_N( subFieldID == CRYPT_ATTRIBUTE_NONE || \
( subFieldID >= CRYPT_CERTINFO_FIRST_NAME && \
subFieldID <= CRYPT_CERTINFO_LAST_GENERALNAME ) );
return( attributeFind( attributeListPtr, getAttrFunction,
fieldID, subFieldID ) );
}
CHECK_RETVAL_PTR \
ATTRIBUTE_LIST *findAttributeFieldEx( IN_OPT const ATTRIBUTE_LIST *attributeListPtr,
IN_ATTRIBUTE \
const CRYPT_ATTRIBUTE_TYPE fieldID )
{
static const ATTRIBUTE_LIST defaultField = DEFAULTFIELD_VALUE;
static const ATTRIBUTE_LIST completeAttribute = COMPLETEATTRIBUTE_VALUE;
const ATTRIBUTE_LIST *attributeListCursor;
const ATTRIBUTE_INFO *attributeInfoPtr;
const ATTRIBUTE_TYPE attributeType = \
( fieldID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE;
CRYPT_ATTRIBUTE_TYPE attributeID;
int iterationCount;
assert( attributeListPtr == NULL || \
isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
REQUIRES_N( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
fieldID <= CRYPT_CERTINFO_LAST );
if( attributeListPtr == NULL )
return( NULL );
/* Find the position of this component in the list */
attributeListCursor = attributeFind( attributeListPtr,
getAttrFunction, fieldID,
CRYPT_ATTRIBUTE_NONE );
if( attributeListCursor != NULL )
return( ( ATTRIBUTE_LIST * ) attributeListCursor );
/* The field isn't present in the list of attributes, check whether
the attribute itself is present and whether this field has a default
value */
attributeInfoPtr = fieldIDToAttribute( attributeType, fieldID,
CRYPT_ATTRIBUTE_NONE, &attributeID );
if( attributeInfoPtr == NULL )
{
/* There's no attribute containing this field, exit */
return( NULL );
}
/* Check whether any part of the attribute that contains the given
field is present in the list of attribute fields */
for( attributeListCursor = attributeListPtr, iterationCount = 0;
attributeListCursor != NULL && \
isValidAttributeField( attributeListCursor ) && \
attributeListCursor->attributeID != attributeID && \
iterationCount < FAILSAFE_ITERATIONS_MAX;
attributeListCursor = attributeListCursor->next, iterationCount++ );
ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
if( attributeListCursor == NULL || \
!isValidAttributeField( attributeListCursor ) )
return( NULL );
/* Some other part of the attribute containing the given field is
present in the list. If this field wasn't found it could either be a
default value (in which case we return an entry that denotes that
this field is absent but has a default setting) or a field that
denotes an entire constructed attribute (in which case we return an
entry that denotes this) */
if( attributeInfoPtr->flags & FL_DEFAULT )
return( ( ATTRIBUTE_LIST * ) &defaultField );
if( attributeInfoPtr->fieldType == BER_SEQUENCE )
return( ( ATTRIBUTE_LIST * ) &completeAttribute );
return( NULL );
}
/* Find the next instance of an attribute field in an attribute. This is
used to step through multiple instances of a field, for example where the
attribute is defined as containing a SEQUENCE OF <field> */
CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \
ATTRIBUTE_LIST *findNextFieldInstance( const ATTRIBUTE_LIST *attributeListPtr )
{
assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
return( attributeFindNextInstance( attributeListPtr,
getAttrFunction ) );
}
/* Find an overall attribute in a list of attributes. This is almost always
used as a check for the presence of an overall attribute so we provide a
separate function to make this explicit */
CHECK_RETVAL_PTR \
ATTRIBUTE_LIST *findAttribute( IN_OPT const ATTRIBUTE_LIST *attributeListPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID,
const BOOLEAN isFieldID )
{
CRYPT_ATTRIBUTE_TYPE localAttributeID = attributeID;
int iterationCount;
assert( attributeListPtr == NULL || \
isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
REQUIRES_N( attributeID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
attributeID <= CRYPT_CERTINFO_LAST );
if( attributeListPtr == NULL )
return( NULL );
/* If this is a (potential) fieldID rather than an attributeID, find the
attributeID for the attribute containing this field */
if( isFieldID )
{
if( fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
attributeID, CRYPT_ATTRIBUTE_NONE,
&localAttributeID ) == NULL )
{
/* There's no attribute containing this field, exit */
return( NULL );
}
}
else
{
/* Make sure that we're searching on an attribute ID rather than a
field ID */
ENSURES_N( \
fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
attributeID, CRYPT_ATTRIBUTE_NONE,
&localAttributeID ) != NULL && \
attributeID == localAttributeID );
}
/* Check whether this attribute is present in the list of attribute
fields */
for( iterationCount = 0;
attributeListPtr != NULL && \
isValidAttributeField( attributeListPtr ) && \
iterationCount < FAILSAFE_ITERATIONS_MAX;
attributeListPtr = attributeListPtr->next, iterationCount++ )
{
if( attributeListPtr->attributeID == localAttributeID )
return( ( ATTRIBUTE_LIST * ) attributeListPtr );
}
ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MAX );
return( NULL );
}
CHECK_RETVAL_BOOL \
BOOLEAN checkAttributePresent( IN_OPT const ATTRIBUTE_LIST *attributeListPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE fieldID )
{
REQUIRES_B( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
fieldID <= CRYPT_CERTINFO_LAST );
return( findAttribute( attributeListPtr, fieldID, FALSE ) != NULL ? \
TRUE : FALSE );
}
/* Move the attribute cursor relative to the current cursor position */
CHECK_RETVAL_PTR \
ATTRIBUTE_LIST *certMoveAttributeCursor( IN_OPT const ATTRIBUTE_LIST *currentCursor,
IN_ATTRIBUTE \
const CRYPT_ATTRIBUTE_TYPE certInfoType,
IN_RANGE( CRYPT_CURSOR_FIRST, \
CRYPT_CURSOR_LAST ) \
const int position )
{
assert( currentCursor == NULL || \
isReadPtr( currentCursor, sizeof( ATTRIBUTE_LIST ) ) );
REQUIRES_N( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
certInfoType == CRYPT_ATTRIBUTE_CURRENT || \
certInfoType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );
REQUIRES_N( position <= CRYPT_CURSOR_FIRST && \
position >= CRYPT_CURSOR_LAST );
return( ( ATTRIBUTE_LIST * ) \
attributeMoveCursor( currentCursor, getAttrFunction,
certInfoType, position ) );
}
/****************************************************************************
* *
* Miscellaneous Attribute Routines *
* *
****************************************************************************/
/* Get the default value for an optional field of an attribute */
CHECK_RETVAL \
int getDefaultFieldValue( IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE fieldID )
{
const ATTRIBUTE_INFO *attributeInfoPtr;
REQUIRES( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
fieldID <= CRYPT_CERTINFO_LAST );
attributeInfoPtr = \
fieldIDToAttribute( ( fieldID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, fieldID,
CRYPT_ATTRIBUTE_NONE, NULL );
ENSURES( attributeInfoPtr != NULL );
return( ( int ) attributeInfoPtr->defaultValue );
}
/* Fix up certificate attributes, mapping from incorrect values to standards-
compliant ones */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int fixAttributes( INOUT CERT_INFO *certInfoPtr )
{
int complianceLevel, status;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* Try and locate email addresses wherever they might be stashed and move
them to the certificate altNames */
status = convertEmail( certInfoPtr, &certInfoPtr->subjectName,
CRYPT_CERTINFO_SUBJECTALTNAME );
if( cryptStatusOK( status ) )
status = convertEmail( certInfoPtr, &certInfoPtr->issuerName,
CRYPT_CERTINFO_ISSUERALTNAME );
if( cryptStatusError( status ) )
return( status );
/* If we're running at a compliance level of
CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL or above don't try and compensate
for dubious attributes */
status = krnlSendMessage( certInfoPtr->ownerHandle,
IMESSAGE_GETATTRIBUTE, &complianceLevel,
CRYPT_OPTION_CERT_COMPLIANCELEVEL );
if( cryptStatusError( status ) )
return( status );
if( complianceLevel >= CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL )
return( CRYPT_OK );
/* If the only key usage info present is the Netscape one, convert it
into the X.509 equivalent */
if( !checkAttributePresent( certInfoPtr->attributes,
CRYPT_CERTINFO_KEYUSAGE ) && \
findAttributeField( certInfoPtr->attributes,
CRYPT_CERTINFO_NS_CERTTYPE,
CRYPT_ATTRIBUTE_NONE ) != NULL )
{
int keyUsage;
status = getKeyUsageFromExtKeyUsage( certInfoPtr, &keyUsage,
&certInfoPtr->errorLocus,
&certInfoPtr->errorType );
if( cryptStatusOK( status ) )
{
status = addAttributeField( &certInfoPtr->attributes,
CRYPT_CERTINFO_KEYUSAGE, CRYPT_ATTRIBUTE_NONE,
&keyUsage, CRYPT_UNUSED, ATTR_FLAG_NONE,
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
}
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -