📄 comp_set.c
字号:
/* It's an absolute attribute positioning code, reset the
attribute cursor to the start of the list before we try to
move it */
if( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP )
certInfoPtr->attributeCursor = certInfoPtr->attributes;
else
/* It's a field or component positioning code, initialise the
attribute cursor if necessary */
if( certInfoPtr->attributeCursor == NULL )
certInfoPtr->attributeCursor = certInfoPtr->attributes;
/* If there are no attributes present, return the appropriate
error code */
if( certInfoPtr->attributeCursor == NULL )
return( ( value == CRYPT_CURSOR_FIRST || \
value == CRYPT_CURSOR_LAST ) ? \
CRYPT_ERROR_NOTFOUND : CRYPT_ERROR_NOTINITED );
}
else
/* It's a relative positioning code, return a not-inited error
rather than a not-found error if the cursor isn't set since
there may be attributes present but the cursor hasn't been
initialised yet by selecting the first or last absolute
attribute */
if( certInfoPtr->attributeCursor == NULL )
return( CRYPT_ERROR_NOTINITED );
/* Move the attribute cursor */
attributeCursor = moveAttributeCursor( certInfoPtr->attributeCursor,
certInfoType, value );
if( attributeCursor == NULL )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->attributeCursor = attributeCursor;
syncSelection( certInfoPtr );
return( CRYPT_OK );
}
/* It's a field in an extension, try and move to the start of the
extension that contains this field */
if( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP )
{
ATTRIBUTE_LIST *attributeListPtr;
attributeListPtr = findAttribute( certInfoPtr->attributes, value,
TRUE );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->attributeCursor = attributeListPtr;
syncSelection( certInfoPtr );
return( CRYPT_OK );
}
assert( certInfoType == CRYPT_ATTRIBUTE_CURRENT || \
certInfoType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );
assert( value >= CRYPT_CERTINFO_FIRST_EXTENSION && \
value <= CRYPT_CERTINFO_LAST_EXTENSION );
/* If it's a GeneralName selection component, locate the attribute field
that it corresponds to */
if( isGeneralNameSelectionComponent( value ) )
return( selectGeneralName( certInfoPtr, value, MAY_BE_ABSENT ) );
/* It's a standard attribute field, try and locate it */
return( moveCursorToField( certInfoPtr, value ) );
}
/****************************************************************************
* *
* Add a Component *
* *
****************************************************************************/
/* Add a certificate component */
int addCertComponent( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
const void *certInfo, const int certInfoLength )
{
CRYPT_CERTIFICATE addedCert;
CERT_INFO *addedCertInfoPtr;
int status;
/* If we're adding data to a certificate, clear the error information */
if( !isPseudoInformation( certInfoType ) )
clearErrorInfo( certInfoPtr );
/* If it's a GeneralName or DN component, add it. These are special-
case attribute values, so they have to come before the attribute-
handling code */
if( isGeneralNameSelectionComponent( certInfoType ) )
{
status = selectGeneralName( certInfoPtr, certInfoType,
MAY_BE_ABSENT );
if( cryptStatusError( status ) )
return( status );
return( selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT ) );
}
if( isGeneralNameComponent( certInfoType ) )
{
status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
CREATE_IF_ABSENT );
if( cryptStatusOK( status ) )
status = addAttributeField( &certInfoPtr->attributes,
( certInfoPtr->attributeCursor != NULL ) ? \
certInfoPtr->attributeCursor->fieldID : \
certInfoPtr->currentSelection.generalName,
certInfoType, certInfo, certInfoLength, ATTR_FLAG_NONE,
&certInfoPtr->errorLocus, &certInfoPtr->errorType );
if( cryptStatusOK( status ) && \
certInfoPtr->currentSelection.updateCursor )
/* If we couldn't update the cursor earlier on because the
attribute field in question hadn't been created yet, do it
now */
selectGeneralName( certInfoPtr,
certInfoPtr->currentSelection.generalName,
MAY_BE_ABSENT );
return( status );
}
if( isDNComponent( certInfoType ) )
{
/* Add the string component to the DN */
status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
CREATE_IF_ABSENT );
if( cryptStatusOK( status ) )
status = insertDNComponent( certInfoPtr->currentSelection.dnPtr,
certInfoType, certInfo, certInfoLength,
&certInfoPtr->errorType );
if( cryptStatusOK( status ) && \
certInfoPtr->currentSelection.updateCursor )
/* If we couldn't update the cursor earlier on because the
attribute field in question hadn't been created yet, do it
now */
selectGeneralName( certInfoPtr,
certInfoPtr->currentSelection.generalName,
MAY_BE_ABSENT );
if( cryptStatusError( status ) && status != CRYPT_ERROR_MEMORY )
certInfoPtr->errorLocus = certInfoType;
return( status );
}
/* If it's standard cert or CMS attribute, add it to the certificate */
if( ( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
certInfoType <= CRYPT_CERTINFO_LAST_EXTENSION ) || \
( certInfoType >= CRYPT_CERTINFO_FIRST_CMS && \
certInfoType <= CRYPT_CERTINFO_LAST_CMS ) )
{
int localCertInfoType = certInfoType;
/* Revocation reason codes are actually a single range of values
spread across two different extensions, so we adjust the
(internal) type based on the reason code value */
if( certInfoType == CRYPT_CERTINFO_CRLREASON || \
certInfoType == CRYPT_CERTINFO_CRLEXTREASON )
localCertInfoType = \
( *( ( int * ) certInfo ) < CRYPT_CRLREASON_LAST ) ? \
CRYPT_CERTINFO_CRLREASON : CRYPT_CERTINFO_CRLEXTREASON;
/* If it's a CRL, RTCS, or OCSP per-entry attribute, add the
attribute to the currently selected entry unless it's a
revocation request, in which case it goes in with the main
attributes */
if( isRevocationEntryComponent( localCertInfoType ) && \
certInfoPtr->type != CRYPT_CERTTYPE_REQUEST_REVOCATION )
{
if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
{
if( certInfoPtr->cCertVal->currentValidity == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( addAttributeField( \
&certInfoPtr->cCertVal->currentValidity->attributes,
localCertInfoType, CRYPT_ATTRIBUTE_NONE,
certInfo, certInfoLength, ATTR_FLAG_NONE,
&certInfoPtr->errorLocus, &certInfoPtr->errorType ) );
}
assert( certInfoPtr->type == CRYPT_CERTTYPE_CRL || \
certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );
if( certInfoPtr->cCertRev->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( addAttributeField( \
&certInfoPtr->cCertRev->currentRevocation->attributes,
localCertInfoType, CRYPT_ATTRIBUTE_NONE,
certInfo, certInfoLength, ATTR_FLAG_NONE,
&certInfoPtr->errorLocus, &certInfoPtr->errorType ) );
}
return( addAttributeField( &certInfoPtr->attributes,
localCertInfoType, CRYPT_ATTRIBUTE_NONE, certInfo, certInfoLength,
ATTR_FLAG_NONE, &certInfoPtr->errorLocus, &certInfoPtr->errorType ) );
}
/* If it's anything else, handle it specially */
switch( certInfoType )
{
case CRYPT_CERTINFO_SELFSIGNED:
if( *( ( int * ) certInfo ) )
certInfoPtr->flags |= CERT_FLAG_SELFSIGNED;
else
certInfoPtr->flags &= ~CERT_FLAG_SELFSIGNED;
return( CRYPT_OK );
case CRYPT_CERTINFO_XYZZY:
return( setXyzzyInfo( certInfoPtr ) );
case CRYPT_CERTINFO_CURRENT_CERTIFICATE:
return( setCertCursorInfo( certInfoPtr,
*( ( int * ) certInfo ) ) );
case CRYPT_ATTRIBUTE_CURRENT_GROUP:
case CRYPT_ATTRIBUTE_CURRENT:
case CRYPT_ATTRIBUTE_CURRENT_INSTANCE:
return( setCursorInfo( certInfoPtr, certInfoType,
*( ( int * ) certInfo ) ) );
case CRYPT_CERTINFO_TRUSTED_USAGE:
certInfoPtr->cCertCert->trustedUsage = *( ( int * ) certInfo );
return( CRYPT_OK );
case CRYPT_CERTINFO_TRUSTED_IMPLICIT:
return( krnlSendMessage( certInfoPtr->ownerHandle,
IMESSAGE_SETATTRIBUTE,
&certInfoPtr->objectHandle,
*( ( int * ) certInfo ) ? \
CRYPT_IATTRIBUTE_CERT_TRUSTED : \
CRYPT_IATTRIBUTE_CERT_UNTRUSTED ) );
case CRYPT_CERTINFO_SIGNATURELEVEL:
certInfoPtr->cCertRev->signatureLevel = *( ( int * ) certInfo );
return( CRYPT_OK );
case CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO:
return( copyPublicKeyInfo( certInfoPtr,
*( ( CRYPT_HANDLE * ) certInfo ),
NULL ) );
case CRYPT_CERTINFO_CERTIFICATE:
/* If it's a certificate, copy across various components or
store the entire cert where required */
status = krnlSendMessage( *( ( CRYPT_HANDLE * ) certInfo ),
IMESSAGE_GETDEPENDENT, &addedCert,
OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
/* If it's a cert chain, we're adding the complete cert, just
store it and exit */
if( certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN )
{
int i;
if( certInfoPtr->cCertCert->chainEnd >= MAX_CHAINLENGTH - 1 )
return( CRYPT_ERROR_OVERFLOW );
/* Perform a simple check to make sure that it hasn't been
added already */
for( i = 0; i < certInfoPtr->cCertCert->chainEnd; i++ )
if( cryptStatusOK( \
krnlSendMessage( addedCert, IMESSAGE_COMPARE,
&certInfoPtr->cCertCert->chain[ i ],
MESSAGE_COMPARE_CERTOBJ ) ) )
{
setErrorInfo( certInfoPtr,
CRYPT_CERTINFO_CERTIFICATE,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
/* Add the user cert and increment its reference count */
krnlSendNotifier( addedCert, IMESSAGE_INCREFCOUNT );
certInfoPtr->cCertCert->chain[ certInfoPtr->cCertCert->chainEnd++ ] = addedCert;
return( CRYPT_OK );
}
/* For remaining operations we need access to the user cert
internals */
status = krnlAcquireObject( addedCert, OBJECT_TYPE_CERTIFICATE,
( void ** ) &addedCertInfoPtr,
CRYPT_ARGERROR_NUM1 );
if( cryptStatusError( status ) )
return( status );
status = copyUserCertInfo( certInfoPtr, addedCertInfoPtr,
*( ( CRYPT_HANDLE * ) certInfo ) );
krnlReleaseObject( addedCertInfoPtr->objectHandle );
return( status );
case CRYPT_CERTINFO_CACERTIFICATE:
/* We can't add another CA cert if there's already one present,
in theory this is valid but it's more likely to be an
implementation problem than an attempt to query multiple CAs
through a single responder */
if( certInfoPtr->certHashSet )
{
setErrorInfo( certInfoPtr, CRYPT_CERTINFO_CACERTIFICATE,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
assert( certInfoPtr->version == 1 );
/* Get the cert handle and make sure that it really is a CA
cert */
status = krnlSendMessage( *( ( CRYPT_HANDLE * ) certInfo ),
IMESSAGE_GETDEPENDENT, &addedCert,
OBJECT_TYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
if( cryptStatusError( \
krnlSendMessage( addedCert, IMESSAGE_CHECK, NULL,
MESSAGE_CHECK_CA ) ) )
return( CRYPT_ARGERROR_NUM1 );
status = krnlAcquireObject( addedCert, OBJECT_TYPE_CERTIFICATE,
( void ** ) &addedCertInfoPtr,
CRYPT_ARGERROR_NUM1 );
if( cryptStatusError( status ) )
return( status );
status = copyCaCertInfo( certInfoPtr, addedCertInfoPtr );
krnlReleaseObject( addedCertInfoPtr->objectHandle );
return( status );
case CRYPT_CERTINFO_SERIALNUMBER:
assert( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE );
if( certInfoPtr->cCertCert->serialNumber != NULL )
{
setErrorInfo( certInfoPtr, CRYPT_CERTINFO_SERIALNUMBER,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
return( setSerialNumber( certInfoPtr, certInfo,
certInfoLength ) );
case CRYPT_CERTINFO_SUBJECTNAME:
case CRYPT_CERTINFO_ISSUERNAME:
if( *( ( int * ) certInfo ) != CRYPT_UNUSED )
return( CRYPT_ARGERROR_NUM1 );
return( selectDN( certInfoPtr, certInfoType, MAY_BE_ABSENT ) );
case CRYPT_CERTINFO_VALIDFROM:
case CRYPT_CERTINFO_THISUPDATE:
{
time_t certTime = *( ( time_t * ) certInfo );
if( certInfoPtr->startTime )
{
setErrorInfo( c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -