📄 certval.c
字号:
/****************************************************************************
* *
* Certificate Validity Routines *
* Copyright Peter Gutmann 1996-2007 *
* *
****************************************************************************/
#if defined( INC_ALL )
#include "cert.h"
#include "asn1.h"
#include "asn1_ext.h"
#else
#include "cert/cert.h"
#include "misc/asn1.h"
#include "misc/asn1_ext.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* Add/Delete/Check Validity Information *
* *
****************************************************************************/
/* Find an entry in a validity info list */
CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1, 2 ) ) \
static VALIDITY_INFO *findValidityEntry( const VALIDITY_INFO *listPtr,
IN_BUFFER( valueLength ) const void *value,
IN_LENGTH_SHORT const int valueLength )
{
const int vCheck = checksumData( value, valueLength );
int iterationCount;
assert( isReadPtr( listPtr, sizeof( VALIDITY_INFO ) ) );
assert( isReadPtr( value, valueLength ) );
REQUIRES_N( valueLength > 0 && valueLength < MAX_INTLENGTH_SHORT );
/* Check whether this entry is present in the list */
for( iterationCount = 0;
listPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_LARGE;
iterationCount++ )
{
if( listPtr->dCheck == vCheck && \
!memcmp( listPtr->data, value, valueLength ) )
return( CRYPT_OK );
listPtr = listPtr->next;
}
ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_LARGE );
return( NULL );
}
#if 0 /* 30/6/08 Doesn't seem to be used by anything */
/* Check whether a certificate is valid */
static int checkValidity( const CERT_INFO *certInfoPtr,
CERT_INFO *validityInfoPtr )
{
CERT_VAL_INFO *certValInfo = validityInfoPtr->cCertVal;
VALIDITY_INFO *validityEntry;
BYTE certHash[ CRYPT_MAX_HASHSIZE + 8 ];
int certHashLength, status;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( validityInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( validityInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE );
/* If there's no validity information present we can't say anything
about the certificate */
if( certValInfo->validityInfo == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* Get the certificate hash and use it to check whether there's an entry
for this certificate in the list. We read the certificate hash
indirectly since it's computed on demand and may not have been
evaluated yet */
status = getCertComponent( ( CERT_INFO * ) certInfoPtr,
CRYPT_CERTINFO_FINGERPRINT_SHA,
certHash, CRYPT_MAX_HASHSIZE,
&certHashLength );
if( cryptStatusError( status ) )
return( status );
validityEntry = findValidityEntry( certValInfo->validityInfo,
certHash, certHashLength );
if( validityEntry == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* Select the entry that contains the validity info and return the
certificate's status */
certValInfo->currentValidity = validityEntry;
return( ( validityEntry->status == TRUE ) ? \
CRYPT_OK : CRYPT_ERROR_INVALID );
}
#endif /* 0 */
/* Add an entry to a validation list */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
int addValidityEntry( INOUT_PTR VALIDITY_INFO **listHeadPtrPtr,
OUT_OPT_PTR VALIDITY_INFO **newEntryPosition,
IN_BUFFER( valueLength ) const void *value,
IN_LENGTH_SHORT const int valueLength )
{
VALIDITY_INFO *newElement;
assert( isWritePtr( listHeadPtrPtr, sizeof( VALIDITY_INFO * ) ) );
assert( newEntryPosition == NULL || \
isWritePtr( newEntryPosition, sizeof( VALIDITY_INFO * ) ) );
assert( isReadPtr( value, valueLength ) );
REQUIRES( valueLength > 0 && valueLength < MAX_INTLENGTH_SHORT );
/* Clear return value */
if( newEntryPosition != NULL )
*newEntryPosition = NULL;
/* Make sure that this entry isn't already present */
if( *listHeadPtrPtr != NULL && \
findValidityEntry( *listHeadPtrPtr, value, valueLength ) != NULL )
{
/* If we found an entry that matches the one being added, we can't
add it again */
return( CRYPT_ERROR_DUPLICATE );
}
/* Allocate memory for the new element and copy the information across */
if( ( newElement = ( VALIDITY_INFO * ) \
clAlloc( "addValidityEntry", sizeof( VALIDITY_INFO ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memset( newElement, 0, sizeof( VALIDITY_INFO ) );
memcpy( newElement->data, value, valueLength );
newElement->dCheck = checksumData( value, valueLength );
/* Insert the new element into the list */
insertSingleListElement( listHeadPtrPtr, *listHeadPtrPtr, newElement );
if( newEntryPosition != NULL )
*newEntryPosition = newElement;
return( CRYPT_OK );
}
/* Delete a validity info list */
STDC_NONNULL_ARG( ( 1 ) ) \
void deleteValidityEntries( INOUT_PTR VALIDITY_INFO **listHeadPtrPtr )
{
VALIDITY_INFO *entryListPtr = *listHeadPtrPtr;
int iterationCount;
assert( isWritePtr( listHeadPtrPtr, sizeof( VALIDITY_INFO * ) ) );
*listHeadPtrPtr = NULL;
/* Destroy any remaining list items */
for( iterationCount = 0;
entryListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_LARGE;
iterationCount++ )
{
VALIDITY_INFO *itemToFree = entryListPtr;
entryListPtr = entryListPtr->next;
if( itemToFree->attributes != NULL )
deleteAttributes( &itemToFree->attributes );
zeroise( itemToFree, sizeof( VALIDITY_INFO ) );
clFree( "deleteValidityEntries", itemToFree );
}
ENSURES_V( iterationCount < FAILSAFE_ITERATIONS_LARGE );
}
/* Copy a validity info list */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int copyValidityEntries( INOUT_PTR VALIDITY_INFO **destListHeadPtrPtr,
const VALIDITY_INFO *srcListPtr )
{
const VALIDITY_INFO *srcListCursor;
VALIDITY_INFO *destListCursor = DUMMY_INIT_PTR;
int iterationCount;
assert( isWritePtr( destListHeadPtrPtr, sizeof( VALIDITY_INFO * ) ) );
assert( *destListHeadPtrPtr == NULL ); /* Dest.should be empty */
assert( isReadPtr( srcListPtr, sizeof( VALIDITY_INFO ) ) );
/* Sanity check to make sure that the destination list doesn't already
exist, which would cause the copy loop below to fail */
REQUIRES( *destListHeadPtrPtr == NULL );
/* Copy all validation entries from source to destination */
for( srcListCursor = srcListPtr, iterationCount = 0;
srcListCursor != NULL && iterationCount < FAILSAFE_ITERATIONS_LARGE;
srcListCursor = srcListCursor->next, iterationCount++ )
{
VALIDITY_INFO *newElement;
/* Allocate the new entry and copy the data from the existing one
across. We don't copy the attributes because there aren't any
that should be carried from request to response */
if( ( newElement = ( VALIDITY_INFO * ) \
clAlloc( "copyValidityEntries", \
sizeof( VALIDITY_INFO ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
memcpy( newElement, srcListCursor, sizeof( VALIDITY_INFO ) );
newElement->attributes = NULL;
newElement->next = NULL;
/* Set the status to invalid/unknown by default, this means that any
entries that we can't do anything with automatically get the
correct status associated with them */
newElement->status = FALSE;
newElement->extStatus = CRYPT_CERTSTATUS_UNKNOWN;
/* Link the new element into the list */
if( *destListHeadPtrPtr == NULL )
*destListHeadPtrPtr = destListCursor = newElement;
else
{
destListCursor->next = newElement;
destListCursor = newElement;
}
}
ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
return( CRYPT_OK );
}
/* Prepare the entries in a certificate validity list prior to encoding
them */
CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3, 4 ) ) \
int prepareValidityEntries( INOUT_OPT VALIDITY_INFO *listPtr,
OUT_PTR VALIDITY_INFO **errorEntry,
OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
CRYPT_ATTRIBUTE_TYPE *errorLocus,
OUT_ENUM_OPT( CRYPT_ERRTYPE ) \
CRYPT_ERRTYPE_TYPE *errorType )
{
VALIDITY_INFO *validityEntry;
int iterationCount;
assert( listPtr == NULL || \
isReadPtr( listPtr, sizeof( VALIDITY_INFO ) ) );
assert( isWritePtr( errorEntry, sizeof( VALIDITY_INFO * ) ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -