📄 ext_copy.c
字号:
{
/* We can't set the locus for blob-type attributes since
it's not a known attribute */
*errorLocus = CRYPT_ATTRIBUTE_NONE;
*errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
return( CRYPT_ERROR_DUPLICATE );
}
attributeListCursor = attributeListCursor->next;
}
}
/* Make a second pass copying everything across */
while( srcListPtr != NULL && !isBlobAttribute( srcListPtr ) )
{
CRYPT_ATTRIBUTE_TYPE attributeID = srcListPtr->attributeID;
const ATTRIBUTE_INFO *attributeInfoPtr = \
( srcListPtr->attributeInfoPtr != NULL ) ? \
srcListPtr->attributeInfoPtr : \
fieldIDToAttribute( ( attributeID >= CRYPT_CERTINFO_FIRST_CMS ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
attributeID, CRYPT_ATTRIBUTE_NONE, NULL );
int status;
assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
/* Copy the complete attribute across unless it's one that we
explicitly don't propagate from source to destination */
if( !( attributeInfoPtr->flags & FL_NOCOPY ) )
{
status = copyAttribute( destListHeadPtr, srcListPtr,
COPY_DIRECT );
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 );
insertDoubleListElement( destListHeadPtr, insertPoint,
newAttribute );
srcListPtr = srcListPtr->next;
}
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Copy Specific Attributes *
* *
****************************************************************************/
/* Copy attributes that are propagated down cert chains from an issuer to a
subject cert, changing the field types from subject to issuer and adjust
constraint values at the same time if required */
int copyIssuerAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr,
const CRYPT_CERTTYPE_TYPE type,
CRYPT_ATTRIBUTE_TYPE *errorLocus,
CRYPT_ERRTYPE_TYPE *errorType )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, sizeof( ATTRIBUTE_LIST * ) ) );
assert( isReadPtr( srcListPtr, sizeof( ATTRIBUTE_LIST ) ) );
assert( isWritePtr( errorLocus, sizeof( CRYPT_ATTRIBUTE_TYPE ) ) );
assert( isWritePtr( errorType, sizeof( CRYPT_ERRTYPE_TYPE ) ) );
/* If the destination is a CA cert and the source has constraint
extensions, copy them over to the destination. The reason why we
copy the constraints even though they're already present in the
source is to ensure that they're still present in a cert chain even
if the parent isn't available. This can occur for example when a
chain-internal cert is marked as implicitly trusted and the chain is
only available up to the implicitly-trusted cert, with the contraint-
imposing parent not present */
attributeListPtr = findAttributeField( *destListHeadPtr,
CRYPT_CERTINFO_CA,
CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL && attributeListPtr->intValue )
{
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. We check the two separately rather than just
checking for the overall presence of name constraints since in
theory it's possible to merge permitted and excluded constraints,
so that permitted constraints in the destination don't clash with
excluded constraints in the source (yet another one of X.509's
semantic holes) */
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,
COPY_SUBJECT_TO_ISSUER );
if( cryptStatusOK( status ) && srcExcludedSubtrees != NULL )
status = copyAttribute( destListHeadPtr, srcExcludedSubtrees,
COPY_SUBJECT_TO_ISSUER );
if( cryptStatusError( status ) )
return( status );
/* The path-length constraints are a bit easier to handle, if
they're already present we just use the smaller of the two */
status = copyLengthConstraint( destListHeadPtr, srcPermittedSubtrees,
CRYPT_CERTINFO_PATHLENCONSTRAINT );
if( cryptStatusOK( status ) )
status = copyLengthConstraint( destListHeadPtr, srcPermittedSubtrees,
CRYPT_CERTINFO_REQUIREEXPLICITPOLICY );
if( cryptStatusOK( status ) )
status = copyLengthConstraint( destListHeadPtr, srcPermittedSubtrees,
CRYPT_CERTINFO_INHIBITPOLICYMAPPING );
if( cryptStatusError( status ) )
return( status );
}
/* If it's an attribute certificate, that's all that 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 = findAttribute( srcListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
COPY_SUBJECT_TO_ISSUER );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
COPY_SUBJECT_TO_ISSUER );
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 (i.e. ones that
control all the certs down to the EE) this is always the case, and if
it isn't it's assumed that 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 that 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, FALSE );
if( attributeListPtr != NULL && \
findAttribute( *destListHeadPtr,
CRYPT_CERTINFO_AUTHORITYINFOACCESS, FALSE ) == NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, TRUE );
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
/* Copy attributes that are propagated from an OCSP request to a response */
int copyOCSPRequestAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, sizeof( ATTRIBUTE_LIST * ) ) );
assert( isReadPtr( srcListPtr, sizeof( 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, NULL );
/* Copy the nonce attribute from the source to the destination. We don't
copy anything else (i.e. we 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 that are propagated from a revocation request to a CRL */
int copyRevocationAttributes( ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
int status = CRYPT_OK;
assert( isWritePtr( destListHeadPtr, sizeof( ATTRIBUTE_LIST * ) ) );
assert( isReadPtr( srcListPtr, sizeof( ATTRIBUTE_LIST ) ) );
/* Copy the CRL reason and invalidity date attributes from the source to
the destination. We don't copy anything else (i.e. we default to
deny-all) to prevent the requester from being able to insert arbitrary
attributes into the CRL */
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_CRLREASON, FALSE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_INVALIDITYDATE, FALSE );
if( attributeListPtr != NULL )
status = copyAttribute( destListHeadPtr, attributeListPtr, FALSE );
return( status );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -