certext.c
来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,330 行 · 第 1/4 页
C
1,330 行
/* Copy the complete attribute across */
status = copyAttribute( destListHeadPtr, srcListPtr, FALSE );
if( cryptStatusError( status ) )
return( status );
/* Move on to the next attribute */
while( srcListPtr != NULL && srcListPtr->attributeID == attributeID )
srcListPtr = srcListPtr->next;
}
/* If there are blob-type attributes left at the end of the list, copy
them across last */
if( srcListPtr != NULL )
{
ATTRIBUTE_LIST *insertPoint;
/* Find the end of the destination list */
for( insertPoint = *destListHeadPtr;
insertPoint != NULL && insertPoint->next != NULL;
insertPoint = insertPoint->next );
/* Copy all remaining attributes across */
while( srcListPtr != NULL )
{
ATTRIBUTE_LIST *newAttribute;
int status;
status = copyAttributeField( &newAttribute, srcListPtr );
if( cryptStatusError( status ) )
return( status );
insertListElements( destListHeadPtr, insertPoint, newAttribute,
newAttribute );
srcListPtr = srcListPtr->next;
}
}
return( CRYPT_OK );
}
/* Copy attributes which are propagated down cert chains from an issuer to a
subject cert, changing the field types from subject to issuer at the same
time if required */
int copyIssuerAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr,
CRYPT_ATTRIBUTE_TYPE *errorLocus,
CRYPT_ERRTYPE_TYPE *errorType,
const CRYPT_CERTTYPE_TYPE type )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );
/* If the destination is a CA cert and the source has name constraints,
copy them over to the destination */
attributeListPtr = findAttribute( *destListHeadPtr, CRYPT_CERTINFO_CA );
if( attributeListPtr != NULL && attributeListPtr->value )
{
ATTRIBUTE_LIST *srcPermittedSubtrees, *srcExcludedSubtrees;
srcPermittedSubtrees = findAttributeField( srcListPtr,
CRYPT_CERTINFO_PERMITTEDSUBTREES, CRYPT_ATTRIBUTE_NONE );
srcExcludedSubtrees = findAttributeField( srcListPtr,
CRYPT_CERTINFO_EXCLUDEDSUBTREES, CRYPT_ATTRIBUTE_NONE );
/* If we're copying permitted or excluded subtrees, they can't
already be present */
if( srcPermittedSubtrees != NULL && \
findAttributeField( *destListHeadPtr, \
CRYPT_CERTINFO_PERMITTEDSUBTREES, CRYPT_ATTRIBUTE_NONE ) != NULL )
{
*errorLocus = CRYPT_CERTINFO_PERMITTEDSUBTREES;
*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
return( CRYPT_ERROR_DUPLICATE );
}
if( srcExcludedSubtrees != NULL && \
findAttributeField( *destListHeadPtr,
CRYPT_CERTINFO_EXCLUDEDSUBTREES, CRYPT_ATTRIBUTE_NONE ) != NULL )
{
*errorLocus = CRYPT_CERTINFO_EXCLUDEDSUBTREES;
*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
return( CRYPT_ERROR_DUPLICATE );
}
/* Copy the fields across */
if( srcPermittedSubtrees != NULL )
status = copyAttribute( destListHeadPtr, srcPermittedSubtrees, FALSE );
if( cryptStatusOK( status ) && srcExcludedSubtrees != NULL )
status = copyAttribute( destListHeadPtr, srcExcludedSubtrees, FALSE );
if( cryptStatusError( status ) )
return( status );
}
/* If it's an attribute certificate, that's all we can copy */
if( type == CRYPT_CERTTYPE_ATTRIBUTE_CERT )
return( CRYPT_OK );
/* Copy the altName and keyIdentifier if these are present. We don't
have to check for their presence in the destination cert since they're
read-only fields and can't be added by the user */
attributeListPtr = findAttributeField( srcListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttributeField( srcListPtr,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
if( cryptStatusError( status ) )
return( status );
}
/* Copy the authorityInfoAccess if it's present. This one is a bit
tricky both because it's a multi-valued attribute and some values
may already be present in the destination cert and because it's not
certain that the issuer cert's AIA should be the same as the subject
cert's AIA. At the moment with monolithic CAs (ie ones which control
all the certs down to the EE) this is always the case, and if it isn't
it's assumed the CA will set the EE's AIA to the appropriate value
before trying to sign the cert. Because of this we copy the issuer
AIA if there's no subject AIA present, otherwise we assume the CA has
set the subject AIA to its own choice of value and don't try and copy
anything */
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_AUTHORITYINFOACCESS );
if( attributeListPtr != NULL && \
findAttribute( *destListHeadPtr,
CRYPT_CERTINFO_AUTHORITYINFOACCESS ) == NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
/* Copy attributes which are propagated from an OCSP request to a response */
int copyRequestAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr,
CRYPT_ATTRIBUTE_TYPE *errorLocus,
CRYPT_ERRTYPE_TYPE *errorType )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );
/* If the nonce attribute is already present in the destination, delete
it */
attributeListPtr = findAttributeField( *destListHeadPtr,
CRYPT_CERTINFO_OCSP_NONCE, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
deleteAttributeField( destListHeadPtr, NULL, attributeListPtr );
/* Copy the nonce attribute from the source to the destination. We don't
copy anything else (ie default to deny-all) to prevent the requester
from being able to insert arbitrary attributes into the response */
attributeListPtr = findAttributeField( srcListPtr,
CRYPT_CERTINFO_OCSP_NONCE, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
return( status );
}
/* Copy attributes which are propagated from a revocation request to a CRL */
int copyRevocationAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr,
CRYPT_ATTRIBUTE_TYPE *errorLocus,
CRYPT_ERRTYPE_TYPE *errorType )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, ATTRIBUTE_LIST * ) );
assert( isReadPtr( srcListPtr, ATTRIBUTE_LIST ) );
/* Copy the CRL reason and invalidity date attributes from the source to
the destination. We don't copy anything else (ie default to deny-all)
to prevent the requester from being able to insert arbitrary
attributes into the CRL */
attributeListPtr = findAttributeField( srcListPtr,
CRYPT_CERTINFO_CRLREASON, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttributeField( srcListPtr,
CRYPT_CERTINFO_INVALIDITYDATE, CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL )
status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
return( status );
}
/* Delete an attribute/attribute field from a list of attributes, updating
the list cursor at the same time. This is a somewhat ugly kludge, it's
not really possible to do this cleanly since deleting attributes affects
the attribute cursor */
void deleteAttributeField( ATTRIBUTE_LIST **attributeListPtr,
ATTRIBUTE_LIST **listCursorPtr,
ATTRIBUTE_LIST *listItem )
{
ATTRIBUTE_LIST *listPrevPtr = listItem->prev;
ATTRIBUTE_LIST *listNextPtr = listItem->next;
assert( isWritePtr( attributeListPtr, ATTRIBUTE_LIST * ) );
assert( isWritePtr( *attributeListPtr, ATTRIBUTE_LIST ) );
assert( isWritePtr( listItem, ATTRIBUTE_LIST ) );
/* If we're about to delete the field which is pointed to by the
attribute cursor, advance the cursor to the next field. If there's no
next field, move it to the previous field. This behaviour is the most
logically consistent, it means we can do things like deleting an
entire attribute list by repeatedly deleting a field */
if( listCursorPtr != NULL && *listCursorPtr == listItem )
*listCursorPtr = ( listNextPtr != NULL ) ? listNextPtr : listPrevPtr;
/* Remove the item from the list */
if( listItem == *attributeListPtr )
{
/* Special case for first item */
*attributeListPtr = listNextPtr;
if( listNextPtr != NULL )
listNextPtr->prev = NULL;
}
else
{
/* Delete from the middle or the end of the chain */
listPrevPtr->next = listNextPtr;
if( listNextPtr != NULL )
listNextPtr->prev = listPrevPtr;
}
/* Clear all data in the item and free the memory */
if( listItem->fieldType == FIELDTYPE_DN )
deleteDN( ( void ** ) &listItem->data );
else
if( listItem->dataLength > CRYPT_MAX_TEXTSIZE )
{
assert( !checkBadPtrWrite( listItem->data,
listItem->dataLength ) );
zeroise( listItem->data, listItem->dataLength );
free( listItem->data );
}
zeroise( listItem, sizeof( ATTRIBUTE_LIST ) );
free( listItem );
}
void deleteAttribute( ATTRIBUTE_LIST **attributeListPtr,
ATTRIBUTE_LIST **listCursorPtr,
ATTRIBUTE_LIST *listItem )
{
CRYPT_ATTRIBUTE_TYPE attributeID;
ATTRIBUTE_LIST *attributeListCursor;
assert( isWritePtr( attributeListPtr, ATTRIBUTE_LIST * ) );
assert( isWritePtr( *attributeListPtr, ATTRIBUTE_LIST ) );
assert( isWritePtr( listItem, ATTRIBUTE_LIST ) );
/* If it's a blob-type attribute, everything is contained in this one
list item so we only need to destroy that */
if( isBlobAttribute( listItem ) )
{
deleteAttributeField( attributeListPtr, listCursorPtr, listItem );
return;
}
/* If it's a field which denotes an entire (constructed) attribute, it
won't have an entry in the list, so we find the first field of the
constructed attribute which is present in the list and start deleting
from that point */
if( isCompleteAttribute( listItem ) )
{
for( attributeListCursor = *attributeListPtr;
attributeListCursor != NULL && \
attributeListCursor->attributeID != listItem->value;
attributeListCursor = attributeListCursor->next );
}
else
/* The list item is a field in the attribute, find the start of the
fields in this attribute */
attributeListCursor = findAttributeStart( listItem );
assert( isWritePtr( attributeListCursor, ATTRIBUTE_LIST ) );
attributeID = attributeListCursor->attributeID;
/* It's an item with multiple fields, destroy each field separately */
while( attributeListCursor != NULL && \
attributeListCursor->attributeID == attributeID )
{
ATTRIBUTE_LIST *itemToFree = attributeListCursor;
attributeListCursor = attributeListCursor->next;
deleteAttributeField( attributeListPtr, listCursorPtr, itemToFree );
}
}
/* Delete a complete set of attributes */
void deleteAttributes( ATTRIBUTE_LIST **attributeListPtr )
{
ATTRIBUTE_LIST *attributeListCursor = *attributeListPtr;
/* If the list was empty, return now */
if( attributeListCursor == NULL )
return;
/* Destroy any remaining list items */
while( attributeListCursor != NULL )
{
ATTRIBUTE_LIST *itemToFree = attributeListCursor;
attributeListCursor = attributeListCursor->next;
deleteAttributeField( attributeListPtr, NULL, itemToFree );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?