⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certcomp.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
				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 + -