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

📄 comp_get.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
			return( status );

		*certInfoLength = textOidLength;
		if( certInfo == NULL )
			return( CRYPT_OK );
		return( attributeCopyParams( certInfo, certInfoMaxLength, 
									 certInfoLength, textOID, 
									 textOidLength ) );
		}

	/* If it's a basic data value, copy it over as an integer */
	if( attributeListPtr->valueLength <= 0 )
		{
		*( ( int * ) certInfo ) = ( int ) attributeListPtr->intValue;
		return( CRYPT_OK );
		}
	ENSURES( certInfoLength != NULL );

	/* It's a more complex data type, copy it across */
	return( attributeCopyParams( certInfo, certInfoMaxLength, certInfoLength, 
								 attributeListPtr->value, 
								 attributeListPtr->valueLength ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getCertAttributeComponent( const CERT_INFO *certInfoPtr,
				IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
				OUT_BUFFER_OPT( certInfoMaxLength, certInfoLength ) void *certInfo, 
				IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
				OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	ATTRIBUTE_LIST *attributeListPtr;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( certInfoType > CRYPT_ATTRIBUTE_NONE && \
			  certInfoType < CRYPT_ATTRIBUTE_LAST );
	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* Try and find this attribute in the attribute list */
	if( isRevocationEntryComponent( certInfoType ) )
		{
		/* If it's an RTCS per-entry attribute get the attribute from the
		   currently selected entry */
		if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
			{
			CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;

			if( certValInfo->currentValidity == NULL )
				return( CRYPT_ERROR_NOTFOUND );
			attributeListPtr = findAttributeFieldEx( \
					certValInfo->currentValidity->attributes, certInfoType );
			}
		else
			{
			CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

			/* It's a CRL or OCSP per-entry attribute get the attribute 
			   from the currently selected entry */
			if( certRevInfo->currentRevocation == NULL )
				return( CRYPT_ERROR_NOTFOUND );
			attributeListPtr = findAttributeFieldEx( \
				certRevInfo->currentRevocation->attributes, certInfoType );
			if( attributeListPtr == NULL && \
				certInfoType == CRYPT_CERTINFO_CRLREASON )
				{
				/* Revocation reason codes are actually a single range of 
				   values spread across two different extensions so if we 
				   don't find the value as a straight cRLReason we try again 
				   for a cRLExtReason.  If we've been specifically asked for 
				   a cRLExtReason we don't go the other way because the 
				   caller (presumably) specifically wants the extended 
				   reason code */
				attributeListPtr = findAttributeFieldEx( \
								certRevInfo->currentRevocation->attributes,
								CRYPT_CERTINFO_CRLEXTREASON );
				}
			}
		}
	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 ) )
		{
		const int value = getDefaultFieldValue( certInfoType );
		if( cryptStatusError( value ) )
			return( value );

		*( ( int * ) certInfo ) = value;
		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,
										   certInfoMaxLength,
										   certInfoLength ) );
	}

/* Get the hash of a certificate */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getCertHash( INOUT CERT_INFO *certInfoPtr,
						IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType, 
						OUT_BUFFER_OPT( certInfoMaxLength, \
										certInfoLength ) void *certInfo, 
						IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	const CRYPT_ALGO_TYPE cryptAlgo = \
				( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 ) ? \
				CRYPT_ALGO_MD5 : CRYPT_ALGO_SHA1;
	HASHFUNCTION_ATOMIC hashFunctionAtomic;
	BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
	int hashSize;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( certInfoType == CRYPT_CERTINFO_FINGERPRINT_MD5 || \
			  certInfoType == CRYPT_CERTINFO_FINGERPRINT_SHA );
	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	/* Get the hash algorithm information */
	getHashAtomicParameters( cryptAlgo, &hashFunctionAtomic, &hashSize );
	*certInfoLength = hashSize;
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( hashSize > certInfoMaxLength )
		return( CRYPT_ERROR_OVERFLOW );
	ENSURES( certInfoPtr->certificate != NULL );

	/* Write the hash (fingerprint) to the output */
	if( cryptAlgo == CRYPT_ALGO_SHA1 && certInfoPtr->certHashSet )
		{
		/* If we've got a cached hash present return that instead of re-
		   hashing the certificate */
		memcpy( certInfo, certInfoPtr->certHash, KEYID_SIZE );
		return( CRYPT_OK );
		}
	hashFunctionAtomic( hash, CRYPT_MAX_HASHSIZE, certInfoPtr->certificate,
						certInfoPtr->certificateSize );
	memcpy( certInfo, hash, hashSize );
	if( cryptAlgo == CRYPT_ALGO_SHA1 )
		{
		/* Remember the hash/fingerprint/oobCertID/certHash/thumbprint/
		   whatever for later since this is reused frequently */
		memcpy( certInfoPtr->certHash, hash, hashSize );
		certInfoPtr->certHashSet = TRUE;
		}
	return( CRYPT_OK );
	}

/* Get a single CRL entry */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getCrlEntry( INOUT CERT_INFO *certInfoPtr, 
						OUT_BUFFER_OPT( certInfoMaxLength, \
										certInfoLength ) void *certInfo, 
						IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
						OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
	STREAM stream;
	WRITECERT_FUNCTION writeCertFunction;
	int crlEntrySize = DUMMY_INIT, status;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
	REQUIRES( certInfoPtr->type == CRYPT_CERTTYPE_CRL );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	if( certRevInfo->currentRevocation == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* Determine how big the encoded CRL entry will be.  Doing it directly
	   in this manner is somewhat ugly but the only other way to do it would 
	   be to pseudo-sign the certificate object in order to write the data, 
	   which doesn't work for CRL entries where we could end up pseudo-
	   signing it multiple times */
	writeCertFunction = getCertWriteFunction( certInfoPtr->type );
	ENSURES( writeCertFunction != NULL );
	sMemNullOpen( &stream );
	status = writeCertFunction( &stream, certInfoPtr, NULL, CRYPT_UNUSED );
	if( cryptStatusOK( status ) )
		crlEntrySize = stell( &stream );
	sMemClose( &stream );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the encoded single CRL entry */
	*certInfoLength = crlEntrySize;
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( crlEntrySize > certInfoMaxLength )
		return( CRYPT_ERROR_OVERFLOW );
	sMemOpen( &stream, certInfo, crlEntrySize );
	status = writeCertFunction( &stream, certInfoPtr, NULL,  CRYPT_UNUSED );
	sMemDisconnect( &stream );

	return( status );
	}

/* Get the issuerAndSerialNumber for a certificate */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getIAndS( const CERT_INFO *certInfoPtr, 
					 OUT_BUFFER_OPT( certInfoMaxLength, \
									 certInfoLength ) void *certInfo, 
					 IN_LENGTH_SHORT_Z const int certInfoMaxLength, 
					 OUT_LENGTH_SHORT_Z int *certInfoLength )
	{
	STREAM stream;
	void *serialNumber;
	int serialNumberLength, status;

	assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
	assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			( isWritePtr( certInfo, certInfoMaxLength ) ) );
	assert( isWritePtr( certInfoLength, sizeof( int ) ) );

	REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
			  ( certInfo != NULL && \
				certInfoMaxLength > 0 && \
			    certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );

	/* Clear return values */
	if( certInfo != NULL )
		memset( certInfo, 0, min( 16, certInfoMaxLength ) );
	*certInfoLength = 0;

	if( certInfoPtr->type == CRYPT_CERTTYPE_CRL )
		{
		REVOCATION_INFO *crlInfoPtr = certInfoPtr->cCertRev->currentRevocation;

		/* If it's a CRL, use the serial number of the currently selected 
		   CRL entry */
		REQUIRES( crlInfoPtr != NULL );

		serialNumber = crlInfoPtr->idPtr;
		serialNumberLength = crlInfoPtr->idLength;
		}
	else
		{
		serialNumber = certInfoPtr->cCertCert->serialNumber;
		serialNumberLength = certInfoPtr->cCertCert->serialNumberLength;
		}
	ENSURES( serialNumber != NULL );
	*certInfoLength = ( int ) \
		sizeofObject( certInfoPtr->issuerDNsize + \
					  sizeofInteger( serialNumber, serialNumberLength ) );
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( *certInfoLength > certInfoMaxLength )
		return( CRYPT_ERROR_OVERFLOW );
	sMemOpen( &stream, certInfo, *certInfoLength );
	writeSequence( &stream, certInfoPtr->issuerDNsize + \
				   sizeofInteger( serialNumber, serialNumberLength ) );
	swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
	status = writeInteger( &stream, serialNumber, serialNumberLength,
						   DEFAULT_TAG );
	sMemDisconnect( &stream );

	return( status );
	}

/* Get the certificate holder's name, usually the commonName but if that's
   not present some commonName-equivalent */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
static int extractDnComponent( IN_BUFFER( encodedDnLength ) \
									const char *encodedDn, 
							   IN_LENGTH_SHORT const int encodedDnLength, 
							   IN_BUFFER( componentNameLength ) \
									const char *componentName, 
							   IN_LENGTH_SHORT const int componentNameLength,
							   OUT_LENGTH_SHORT_Z int *startOffset,
							   OUT_LENGTH_SHORT_Z int *length )
	{
	int startPos, endPos;

	assert( isReadPtr( encodedDn, encodedDnLength ) );
	assert( isReadPtr( componentName, componentNameLength ) );
	assert( isWritePtr( startOffset, sizeof( int ) ) );
	assert( isWritePtr( length, sizeof( int ) ) );

	REQUIRES( encodedDnLength > 0 && \
			  encodedDnLength < MAX_INTLENGTH_SHORT );
	REQUIRES( componentNameLength > 0 && \
			  componentNameLength < MAX_INTLENGTH_SHORT );

	/* Clear return value */
	*startOffset = *length = 0;
	
	/* Try and find the component name in the encoded DN string */
	startPos = strFindStr( encodedDn, encodedDnLength, 
						   componentName, componentNameLength );
	if( startPos < 0 )
		return( -1 );
	startPos += componentNameLength;	/* Skip type indicator */
	
	/* Extract the component value */
	for( endPos = startPos; endPos < encodedDnLength && \
							encodedDn[ endPos ] != ',' && \
							encodedDn[ endPos ] != '+'; endPos++ );
	if( encodedDn[ endPos ] == '+' && \
		encodedDn[ endPos - 1 ] == ' ' )
		endPos--;	/* Strip trailing space */
	
	*startOffset = startPos;
	*length = endPos - startPos;

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 4 ) ) \
static int getNameFromDN( OUT_BUFFER_OPT( nameMaxLength, *nameLength ) void *name, 
						  IN_LENGTH_SHORT_Z const int nameMaxLength, 
						  OUT_LENGTH_SHORT_Z int *nameLength, 
						  IN_BUFFER( encodedDnLength ) const char *encodedDn, 
						  IN_LENGTH_SHORT const int encodedDnLength )
	{
	int startPos, length, status;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -