📄 ext_copy.c
字号:
iterationCount < FAILSAFE_ITERATIONS_MAX;
iterationCount++ )
{
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 && \
iterationCount++ < FAILSAFE_ITERATIONS_MAX )
srcListPtr = srcListPtr->next;
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
/* 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, iterationCount = 0;
insertPoint != NULL && insertPoint->next != NULL && \
iterationCount < FAILSAFE_ITERATIONS_MAX;
insertPoint = insertPoint->next, iterationCount++ );
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
/* Copy all remaining attributes across */
for( ; srcListPtr != NULL && \
iterationCount < FAILSAFE_ITERATIONS_MAX;
srcListPtr = srcListPtr->next, iterationCount++ )
{
ATTRIBUTE_LIST *newAttribute;
int status;
status = copyAttributeField( &newAttribute, srcListPtr );
if( cryptStatusError( status ) )
return( status );
insertDoubleListElement( destListHeadPtr, insertPoint,
newAttribute );
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Copy Specific Attributes *
* *
****************************************************************************/
/* Copy attributes that are propagated down certificate chains from an
issuer to a subject certificate, changing the field types from subject
to issuer and adjust constraint values at the same time if required */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 5 ) ) \
int copyIssuerAttributes( INOUT ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr,
const CRYPT_CERTTYPE_TYPE type,
OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
CRYPT_ATTRIBUTE_TYPE *errorLocus,
OUT_ENUM_OPT( CRYPT_ERRTYPE ) \
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 ) ) );
REQUIRES( type > CRYPT_CERTTYPE_NONE && type < CRYPT_CERTTYPE_LAST );
/* If the destination is a CA certificate 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 certificate chain
even if the parent isn't available. This can occur for example when
a chain-internal certificate is marked as implicitly trusted and the
chain is only available up to the implicitly-trusted certificate with
the contraint-imposing parent not present */
attributeListPtr = findAttributeField( *destListHeadPtr,
CRYPT_CERTINFO_CA,
CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL && attributeListPtr->intValue > 0 )
{
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( cryptStatusError( status ) )
return( status );
}
if( 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 */
if( srcPermittedSubtrees != NULL )
{
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 certificate since
they're read-only fields and can't be added by the user */
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
TRUE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr,
COPY_SUBJECT_TO_ISSUER );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
TRUE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr,
COPY_SUBJECT_TO_ISSUER );
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 certificate and because
it's not certain that the issuer certificate's AIA should be the same
as the subject certificate's AIA. At the moment with monolithic CAs
(i.e. ones that control all the certificates 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
certificate. 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,
COPY_SUBJECT_TO_ISSUER );
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
/* Copy attributes that are propagated from a CRMF certificate request
template to the issued certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int copyCRMFRequestAttributes( INOUT ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
int status;
assert( isWritePtr( destListHeadPtr, sizeof( ATTRIBUTE_LIST * ) ) );
assert( isReadPtr( srcListPtr, sizeof( ATTRIBUTE_LIST ) ) );
/* Copy the altName across. This is needed because it contains
additional identification information (in fact probably the only
identification information of any value) like the email address and
server URL */
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
TRUE );
if( attributeListPtr != NULL )
{
status = copyAttribute( destListHeadPtr, attributeListPtr,
COPY_DIRECT );
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
/* Copy attributes that are propagated from an OCSP request to a response */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int copyOCSPRequestAttributes( INOUT ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
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 )
{
return( copyAttribute( destListHeadPtr, attributeListPtr,
COPY_DIRECT ) );
}
return( CRYPT_OK );
}
/* Copy attributes that are propagated from a revocation request to a CRL */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int copyRevocationAttributes( INOUT ATTRIBUTE_LIST **destListHeadPtr,
const ATTRIBUTE_LIST *srcListPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
int status;
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,
COPY_DIRECT );
if( cryptStatusError( status ) )
return( status );
}
attributeListPtr = findAttribute( srcListPtr,
CRYPT_CERTINFO_INVALIDITYDATE, FALSE );
if( attributeListPtr != NULL )
{
return( copyAttribute( destListHeadPtr, attributeListPtr,
COPY_DIRECT ) );
}
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -