📄 certcomp.c
字号:
certInfoType, CRYPT_ATTRIBUTE_NONE, certInfo, certInfoLength,
ATTR_FLAG_NONE, &certInfoPtr->errorLocus, &certInfoPtr->errorType ) );
}
return( addAttributeField( &certInfoPtr->attributes,
certInfoType, CRYPT_ATTRIBUTE_NONE, certInfo, certInfoLength,
ATTR_FLAG_NONE, &certInfoPtr->errorLocus, &certInfoPtr->errorType ) );
}
/* Everything else isn't available */
assert( NOTREACHED );
return( CRYPT_ARGERROR_VALUE );
}
/****************************************************************************
* *
* Get a Component *
* *
****************************************************************************/
/* Get a certificate component */
static int getCertAttributeComponentData( const ATTRIBUTE_LIST *attributeListPtr,
void *certInfo, int *certInfoLength )
{
const int maxLength = ( certInfoLength != NULL ) ? *certInfoLength : 0;
/* If the data type is an OID, we have to convert it to a human-readable
form before we return it */
if( attributeListPtr->fieldType == BER_OBJECT_IDENTIFIER )
{
char textOID[ CRYPT_MAX_TEXTSIZE * 2 ];
int length;
length = oidToText( attributeListPtr->smallData, textOID );
*certInfoLength = length;
if( certInfo != NULL )
{
if( length > maxLength )
return( CRYPT_ERROR_OVERFLOW );
if( checkBadPtrWrite( certInfo, strlen( textOID ) ) )
return( CRYPT_ARGERROR_STR1 );
memcpy( certInfo, textOID, length );
}
return( CRYPT_OK );
}
/* If it's a basic data value, copy it over as an integer */
if( !attributeListPtr->dataLength )
*( ( int * ) certInfo ) = ( int ) attributeListPtr->value;
else
{
/* It's a more complex data type, copy it across either from the
small buffer in the attribute list entry or from an external
buffer */
*certInfoLength = attributeListPtr->dataLength;
if( certInfo != NULL )
{
if( attributeListPtr->dataLength > maxLength )
return( CRYPT_ERROR_OVERFLOW );
if( checkBadPtrWrite( certInfo, attributeListPtr->dataLength ) )
return( CRYPT_ARGERROR_STR1 );
memcpy( certInfo, ( attributeListPtr->data != NULL ) ? \
attributeListPtr->data : attributeListPtr->smallData,
attributeListPtr->dataLength );
}
}
return( CRYPT_OK );
}
static int getCertAttributeComponent( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
void *certInfo, int *certInfoLength )
{
ATTRIBUTE_LIST *attributeListPtr;
assert( ( certInfo == NULL && *certInfoLength == 0 ) || \
( certInfoLength == NULL ) || \
( *certInfoLength > 1 && *certInfoLength <= 32768 ) );
/* Try and find this attribute in the attribute list */
if( isRevocationEntryComponent( certInfoType ) )
{
/* It's a CRL or OCSP per-entry attribute, get the attribute from the
currently selected entry */
if( certInfoPtr->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
attributeListPtr = findAttributeFieldEx( \
certInfoPtr->currentRevocation->attributes, certInfoType );
}
else
attributeListPtr = findAttributeFieldEx( certInfoPtr->attributes,
certInfoType );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* If this is a non-present field in a present attribute with a default
value for the field, return that */
if( isDefaultFieldValue( attributeListPtr ) )
{
*( ( int * ) certInfo ) = getDefaultFieldValue( certInfoType );
return( CRYPT_OK );
}
/* If this is a non-present field in a present attribute which denotes
an entire (constructed) attribute, return a boolean indicating its
presence */
if( isCompleteAttribute( attributeListPtr ) )
{
*( ( int * ) certInfo ) = TRUE;
return( CRYPT_OK );
}
return( getCertAttributeComponentData( attributeListPtr, certInfo,
certInfoLength ) );
}
/* Get a certificate component */
int getCertComponent( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
void *certInfo, int *certInfoLength )
{
const BOOLEAN returnData = ( certInfo != NULL ) ? TRUE : FALSE;
const int maxLength = ( certInfoLength != NULL ) ? *certInfoLength : 0;
void *data;
int *valuePtr = ( int * ) certInfo;
int dataLength = CRYPT_ERROR;
assert( ( certInfo == NULL && *certInfoLength == 0 ) || \
( certInfoLength == NULL ) || \
( *certInfoLength > 1 && *certInfoLength <= 32768 ) );
/* If it's a certificate pseudo-component, return information on it */
if( certInfoType >= CRYPT_FIRST_PSEUDOINFO && \
certInfoType <= CRYPT_LAST_PSEUDOINFO )
{
/* The fingerprints are string components unlike all the others */
if( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 || \
certInfoType == CRYPT_CERTINFO_FINGERPRINT_SHA )
{
const CRYPT_ALGO cryptAlgo = \
( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 ) ? \
CRYPT_ALGO_MD5 : CRYPT_ALGO_SHA;
HASHFUNCTION hashFunction;
BYTE hash[ CRYPT_MAX_HASHSIZE ];
int hashSize, status;
/* Get the hash algorithm information */
getHashParameters( cryptAlgo, &hashFunction, &hashSize );
*certInfoLength = hashSize;
if( !returnData )
return( CRYPT_OK );
if( hashSize > maxLength )
return( CRYPT_ERROR_OVERFLOW );
/* Write the hash (fingerprint) to the output */
if( checkBadPtrWrite( certInfo, hashSize ) )
return( CRYPT_ARGERROR_STR1 );
if( certInfoPtr->type == CRYPT_CERTTYPE_CRL )
{
STREAM stream;
BYTE crlEntry[ 1024 ], *crlEntryPtr = crlEntry;
int crlEntrySize;
if( certInfoPtr->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* Write the CRL entry to a memory buffer and hash it */
crlEntrySize = sizeofCRLentry( certInfoPtr->currentRevocation );
if( crlEntrySize > 1024 && \
( crlEntryPtr = malloc( crlEntrySize ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
sMemOpen( &stream, crlEntryPtr, crlEntrySize );
status = writeCRLentry( &stream, certInfoPtr->currentRevocation );
sMemDisconnect( &stream );
hashFunction( NULL, certInfo, crlEntryPtr, crlEntrySize,
HASH_ALL );
if( crlEntryPtr != crlEntry )
free( crlEntryPtr );
return( status );
}
assert( certInfoPtr->certificate != NULL );
if( cryptAlgo == CRYPT_ALGO_SHA && certInfoPtr->certHashSet )
{
/* If we've got a cached hash present, return that instead of
re-hashing the cert */
memcpy( certInfo, certInfoPtr->certHash, KEYID_SIZE );
return( CRYPT_OK );
}
hashFunction( NULL, hash, certInfoPtr->certificate,
certInfoPtr->certificateSize, HASH_ALL );
memcpy( certInfo, hash, hashSize );
if( cryptAlgo == CRYPT_ALGO_SHA )
{
/* Remember the hash/fingerprint/oobCertID/thumbprint/
whatever for later, since this is reused frequently */
memcpy( certInfoPtr->certHash, hash, hashSize );
certInfoPtr->certHashSet = TRUE;
}
return( CRYPT_OK );
}
if( certInfoType == CRYPT_CERTINFO_SELFSIGNED )
*valuePtr = ( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) ? \
TRUE : FALSE;
if( certInfoType == CRYPT_CERTINFO_IMMUTABLE )
*valuePtr = ( certInfoPtr->certificate != NULL ) ? TRUE: FALSE;
if( certInfoType == CRYPT_CERTINFO_CERTTYPE )
*valuePtr = certInfoPtr->type;
if( isCursorComponent( certInfoType ) )
{
/* The current component and field are essentially the same thing
since a component is one of a set of entries in a multivalued
field, thus we only distinguish between extensions and
everything else */
if( certInfoPtr->attributeCursor == NULL )
return( CRYPT_ERROR_NOTINITED );
*valuePtr = ( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION ) ? \
certInfoPtr->attributeCursor->attributeID :
certInfoPtr->attributeCursor->fieldID;
}
if( certInfoType == CRYPT_CERTINFO_TRUSTED_USAGE )
{
if( certInfoPtr->trustedUsage == CRYPT_ERROR )
return( CRYPT_ERROR_NOTFOUND );
*valuePtr = certInfoPtr->trustedUsage;
}
if( certInfoType == CRYPT_CERTINFO_TRUSTED_IMPLICIT )
*valuePtr = checkCertTrusted( certInfoPtr );
if( certInfoType == CRYPT_CERTINFO_XYZZY )
{
BYTE policyOID[ MAX_OID_SIZE ];
int policyOIDLength = MAX_OID_SIZE;
/* Check for the presence of the XYZZY policy OID */
if( cryptStatusOK( \
getCertAttributeComponent( certInfoPtr,
CRYPT_CERTINFO_CERTPOLICYID,
policyOID, &policyOIDLength ) ) && \
policyOIDLength == sizeofOID( OID_CRYPTLIB_XYZZYCERT ) && \
!memcmp( policyOID, OID_CRYPTLIB_XYZZYCERT, policyOIDLength ) )
*valuePtr = TRUE;
else
*valuePtr = FALSE;
}
return( CRYPT_OK );
}
/* Return general integer information */
if( certInfoType == CRYPT_CERTINFO_REVOCATIONSTATUS )
{
const REVOCATION_INFO *revInfoPtr = \
( certInfoPtr->currentRevocation != NULL ) ? \
certInfoPtr->currentRevocation : certInfoPtr->revocations;
if( revInfoPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
*valuePtr = revInfoPtr->status;
return( CRYPT_OK );
}
/* Return general string information */
switch( certInfoType )
{
case CRYPT_CERTINFO_SERIALNUMBER:
if( certInfoPtr->type == CRYPT_CERTTYPE_CRL )
{
const REVOCATION_INFO *revInfoPtr = \
( certInfoPtr->currentRevocation != NULL ) ? \
certInfoPtr->currentRevocation : certInfoPtr->revocations;
data = ( revInfoPtr != NULL ) ? revInfoPtr->dataPtr : NULL;
dataLength = ( data != NULL ) ? revInfoPtr->dataLength : 0;
}
else
{
data = certInfoPtr->serialNumber;
dataLength = certInfoPtr->serialNumberLength;
}
break;
case CRYPT_CERTINFO_VALIDFROM:
case CRYPT_CERTINFO_THISUPDATE:
data = &certInfoPtr->startTime;
dataLength = sizeof( time_t );
break;
case CRYPT_CERTINFO_VALIDTO:
case CRYPT_CERTINFO_NEXTUPDATE:
data = certInfoPtr->endTime ? &certInfoPtr->endTime : NULL;
dataLength = ( data != NULL ) ? sizeof( time_t ) : 0;
break;
case CRYPT_CERTINFO_REVOCATIONDATE:
/* If there's a specific revocation entry selected, get its
revocation time, otherwise if there are revoked certs
present get the first cert's revocation time, otherwise get
the default revocation time */
data = ( certInfoPtr->currentRevocation != NULL ) ? \
&certInfoPtr->currentRevocation->revocationTime : \
( certInfoPtr->revocations != NULL ) ? \
&certInfoPtr->revocations->revocationTime : \
( certInfoPtr->revocationTime ) ? \
&certInfoPtr->revocationTime : NULL;
dataLength = ( data != NULL ) ? sizeof( time_t ) : 0;
break;
case CRYPT_CERTINFO_ISSUERUNIQUEID:
data = certInfoPtr->issuerUniqueID;
dataLength = certInfoPtr->issuerUniqueIDlength;
break;
case CRYPT_CERTINFO_SUBJECTUNIQUEID:
data = certInfoPtr->subjectUniqueID;
dataLength = certInfoPtr->subjectUniqueIDlength;
break;
case CRYPT_IATTRIBUTE_SUBJECT:
/* Normally these attributes are only present for signed objects
(ie ones which are in the high state), however CRMF requests
acting as CMP revocation requests aren't signed so we have to
set the ACLs to allow the attribute to be read in the low state
as well. Since this only represents a programming error rather
than a real access violation, we catch it here with an
assertion */
assert( ( certInfoPtr->type == CRYPT_CERTTYPE_REQUEST_REVOCATION && \
certInfoPtr->certificate == NULL ) || \
( certInfoPtr->type != CRYPT_CERTTYPE_REQUEST_REVOCATION && \
certInfoPtr->certificate != NULL ) );
data = certInfoPtr->subjectDNptr;
dataLength = certInfoPtr->subjectDNsize;
break;
case CRYPT_IATTRIBUTE_ISSUER:
data = certInfoPtr->issuerDNptr;
dataLength = certInfoPtr->issuerDNsize;
break;
case CRYPT_IATTRIBUTE_SPKI:
data = certInfoPtr->publicKeyInfo;
dataLength = getObjectLength( certInfoPtr->publicKeyInfo, 16 );
break;
case CRYPT_IATTRIBUTE_OCSPSERVER:
/* An OCSP URL may be present if it was copied over from a cert
which is being checked, however if there wasn't any
authorityInfoAccess information present the URL won't have
been initialised.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -