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

📄 comp_get.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 4 页
字号:
	if( !certInfoPtr->certHashSet )
		{
		hashFunction( NULL, certInfoPtr->certHash, certInfoPtr->certificate,
					  certInfoPtr->certificateSize, HASH_ALL );
		certInfoPtr->certHashSet = TRUE;
		}
	assert( certInfoPtr->cCertCert->serialNumber != NULL );

	/* Write the ESSCertID:

		ESSCertID ::= SEQUENCE {
			certHash		OCTET STRING SIZE(20),
			issuerSerial	SEQUENCE {
				issuer		SEQUENCE { [4] EXPLICIT Name },
				serial		INTEGER
				}
			} */
	issuerSerialDataSize = ( int ) \
			sizeofObject( sizeofObject( certInfoPtr->issuerDNsize ) ) + \
			sizeofInteger( certInfoPtr->cCertCert->serialNumber,
						   certInfoPtr->cCertCert->serialNumberLength );
	*certInfoLength = ( int ) \
			sizeofObject( sizeofObject( hashSize ) + \
						  sizeofObject( issuerSerialDataSize ) );
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( *certInfoLength > maxLength )
		return( CRYPT_ERROR_OVERFLOW );
	sMemOpen( &stream, certInfo, *certInfoLength );
	writeSequence( &stream, sizeofObject( hashSize ) + \
							sizeofObject( issuerSerialDataSize ) );
	writeOctetString( &stream, certInfoPtr->certHash, hashSize, DEFAULT_TAG );
	writeSequence( &stream, issuerSerialDataSize );
	writeSequence( &stream, sizeofObject( certInfoPtr->issuerDNsize ) );
	writeConstructed( &stream, certInfoPtr->issuerDNsize, 4 );
	swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
	status = writeInteger( &stream, certInfoPtr->cCertCert->serialNumber,
						   certInfoPtr->cCertCert->serialNumberLength, 
						   DEFAULT_TAG );
	sMemDisconnect( &stream );
	assert( cryptStatusOK( status ) );

	return( status );
	}

/* Encode PKI user information into the external format and return it */

static int getPkiUserInfo( CERT_INFO *certInfoPtr, 
						   const CRYPT_ATTRIBUTE_TYPE certInfoType, 
						   void *certInfo, int *certInfoLength )
	{
	CERT_PKIUSER_INFO *certUserInfo = certInfoPtr->cCertUser;
	char encUserInfo[ 128 ];
	BYTE userInfo[ 128 ], *userInfoPtr = userInfo;
	const int maxLength = *certInfoLength;
	int userInfoLength = 128, status;

	if( certInfoType == CRYPT_CERTINFO_PKIUSER_ID )
		{
		status = getCertAttributeComponent( certInfoPtr,
											CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
											userInfo, &userInfoLength );
		assert( cryptStatusOK( status ) );
		if( cryptStatusError( status ) )
			return( status );	/* Should never happen */
		}
	else
		userInfoPtr = ( certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD ) ? \
					  certUserInfo->pkiIssuePW : certUserInfo->pkiRevPW;
	*certInfoLength = encodePKIUserValue( encUserInfo, userInfoPtr,
				( certInfoType == CRYPT_CERTINFO_PKIUSER_ID ) ? 3 : 4 );
	zeroise( userInfo, 128 );
	if( certInfo == NULL )
		return( CRYPT_OK );
	if( *certInfoLength > maxLength )
		return( CRYPT_ERROR_OVERFLOW );
	memcpy( certInfo, encUserInfo, *certInfoLength );
	zeroise( encUserInfo, 128 );
	return( CRYPT_OK );
	}

/* Get a pointer to the currently selected revocation/validity time */

time_t *getRevocationTimePtr( CERT_INFO *certInfoPtr )
	{
	time_t *timePtr;

	/* If there's a specific validity/revocation entry selected, get its 
	   invalidity/revocation time, otherwise if there are invalid/revoked 
	   certs present get the first cert's invalidity/revocation time, 
	   otherwise get the default invalidity/revocation time */
	if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
		{
		CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;

		timePtr = ( certValInfo->currentValidity != NULL ) ? \
					&certValInfo->currentValidity->invalidityTime : \
				  ( certValInfo->validityInfo != NULL ) ? \
					&certValInfo->validityInfo->invalidityTime : NULL;
		}
	else
		{
		CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

		timePtr = ( certRevInfo->currentRevocation != NULL ) ? \
					&certRevInfo->currentRevocation->revocationTime : \
				  ( certRevInfo->revocations != NULL ) ? \
					&certRevInfo->revocations->revocationTime : \
				  ( certRevInfo->revocationTime ) ? \
					&certRevInfo->revocationTime : NULL;
		}

	return( timePtr );
	}

/****************************************************************************
*																			*
*									Get a Component							*
*																			*
****************************************************************************/

/* Get a certificate component */

int getCertComponent( CERT_INFO *certInfoPtr,
					  const CRYPT_ATTRIBUTE_TYPE certInfoType,
					  void *certInfo, int *certInfoLength )
	{
	const int maxLength = ( certInfoLength != NULL ) ? *certInfoLength : 0;
	void *data = NULL;
	int dataLength = 0;

	assert( ( certInfo == NULL && *certInfoLength == 0 ) || \
			( certInfoLength == NULL ) || \
			( *certInfoLength > 0 && *certInfoLength <= 32768 ) );

	/* If it's a GeneralName or DN component, return it.  These are 
	   special-case attribute values, so they have to come before the 
	   general attribute-handling code */
	if( isGeneralNameSelectionComponent( certInfoType ) )
		{
		SELECTION_STATE savedState;
		int status;

		/* Determine whether the given component is present or not.  This
		   has a somewhat odd status return since it returns the found/
		   notfound status in the return code as well as the returned value,
		   which mirrors the behaviour when reading extension-present
		   pseudo-attributes.  Because of this we can't use 
		   copyCertInfoValue() but have to perform the copy manually */
		saveSelectionState( savedState, certInfoPtr );
		status = selectGeneralName( certInfoPtr, certInfoType, 
									MAY_BE_ABSENT );
		if( cryptStatusOK( status ) )
			status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE, 
										MUST_BE_PRESENT );
		restoreSelectionState( savedState, certInfoPtr );

		if( certInfo != NULL )
			*( ( int * ) certInfo ) = cryptStatusOK( status ) ? TRUE : FALSE;
		return( status );
		}
	if( isGeneralNameComponent( certInfoType ) )
		{
		ATTRIBUTE_LIST *attributeListPtr;
		int status;

		/* Find the requested GeneralName component and return it to the
		   caller */
		status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
									MUST_BE_PRESENT );
		if( cryptStatusError( status ) )
			return( status );
		attributeListPtr = findAttributeField( certInfoPtr->attributeCursor,
											   certInfoPtr->attributeCursor->fieldID,
											   certInfoType );
		if( attributeListPtr == NULL )
			return( CRYPT_ERROR_NOTFOUND );
		return( getCertAttributeComponentData( attributeListPtr, certInfo,
											   certInfoLength ) );
		}
	if( isDNComponent( certInfoType ) )
		{
		int status;

		/* Find the requested DN component and return it to the caller */
		status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
						   MUST_BE_PRESENT );
		if( cryptStatusError( status ) )
			return( status );
		return( getDNComponentValue( *certInfoPtr->currentSelection.dnPtr,
									 certInfoType, certInfo, certInfoLength,
									 maxLength ) );
		}

	/* If it's standard cert or CMS attribute, return it */
	if( ( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
		  certInfoType <= CRYPT_CERTINFO_LAST_EXTENSION ) || \
		( certInfoType >= CRYPT_CERTINFO_FIRST_CMS && \
		  certInfoType <= CRYPT_CERTINFO_LAST_CMS ) )
		return( getCertAttributeComponent( certInfoPtr, certInfoType,
										   certInfo, certInfoLength ) );

	/* If it's anything else, handle it specially */
	switch( certInfoType )
		{
		case CRYPT_CERTINFO_SELFSIGNED:
			return( copyCertInfoValue( certInfo, \
						( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) ? \
						TRUE : FALSE ) );

		case CRYPT_CERTINFO_IMMUTABLE:
			return( copyCertInfoValue( certInfo, \
						( certInfoPtr->certificate != NULL ) ? \
						TRUE: FALSE ) );

		case CRYPT_CERTINFO_XYZZY:
			{
			BYTE policyOID[ MAX_OID_SIZE ];
			int policyOIDLength = MAX_OID_SIZE;

			/* Check for the presence of the XYZZY policy OID */
			return( copyCertInfoValue( certInfo, \
						( cryptStatusOK( \
							getCertAttributeComponent( certInfoPtr,
										CRYPT_CERTINFO_CERTPOLICYID,
										policyOID, &policyOIDLength ) ) && \
						  policyOIDLength == sizeofOID( OID_CRYPTLIB_XYZZYCERT ) && \
						  !memcmp( policyOID, OID_CRYPTLIB_XYZZYCERT, policyOIDLength ) ) ? \
						TRUE : FALSE ) );
			}
		case CRYPT_CERTINFO_CERTTYPE:
			return( copyCertInfoValue( certInfo, certInfoPtr->type ) );

		case CRYPT_CERTINFO_FINGERPRINT_MD5:
		case CRYPT_CERTINFO_FINGERPRINT_SHA:
			return( getCertHash( certInfoPtr, certInfoType, certInfo, 
								 certInfoLength ) );

		case CRYPT_CERTINFO_CURRENT_CERTIFICATE:
		case CRYPT_ATTRIBUTE_CURRENT_GROUP:
		case CRYPT_ATTRIBUTE_CURRENT:
		case CRYPT_ATTRIBUTE_CURRENT_INSTANCE:
			/* 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 );
			return( copyCertInfoValue( certInfo, \
						( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP ) ? \
							certInfoPtr->attributeCursor->attributeID :
							certInfoPtr->attributeCursor->fieldID ) );

		case CRYPT_CERTINFO_TRUSTED_USAGE:
			if( certInfoPtr->cCertCert->trustedUsage == CRYPT_ERROR )
				return( CRYPT_ERROR_NOTFOUND );
			return( copyCertInfoValue( certInfo, 
									   certInfoPtr->cCertCert->trustedUsage ) );
 
		case CRYPT_CERTINFO_TRUSTED_IMPLICIT:
			return( copyCertInfoValue( certInfo, \
						cryptStatusOK( \
							krnlSendMessage( certInfoPtr->ownerHandle,
											 IMESSAGE_SETATTRIBUTE,
											 &certInfoPtr->objectHandle,
											 CRYPT_IATTRIBUTE_CERT_CHECKTRUST ) ) ? \
						TRUE : FALSE ) );

		case CRYPT_CERTINFO_SIGNATURELEVEL:
			return( copyCertInfoValue( certInfo, \
									   certInfoPtr->cCertRev->signatureLevel ) );

		case CRYPT_CERTINFO_VERSION:
			return( copyCertInfoValue( certInfo, certInfoPtr->version ) );

		case CRYPT_CERTINFO_SERIALNUMBER:
			switch( certInfoPtr->type )
				{
				case CRYPT_CERTTYPE_CRL:
					{
					const CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;

					const REVOCATION_INFO *revInfoPtr = \
						( certRevInfo->currentRevocation != NULL ) ? \
						certRevInfo->currentRevocation : certRevInfo->revocations;

					if( revInfoPtr != NULL )
						{
						data = revInfoPtr->dataPtr;
						dataLength = revInfoPtr->dataLength;
						}
					break;
					}

				case CRYPT_CERTTYPE_REQUEST_REVOCATION:
					data = certInfoPtr->cCertReq->serialNumber;
					dataLength = certInfoPtr->cCertReq->serialNumberLength;
					break;

				case CRYPT_CERTTYPE_CERTIFICATE:
				case CRYPT_CERTTYPE_ATTRIBUTE_CERT:
				case CRYPT_CERTTYPE_CERTCHAIN:
					data = certInfoPtr->cCertCert->serialNumber;
					dataLength = certInfoPtr->cCertCert->serialNumberLength;
					break;

				default:
					assert( NOTREACHED );
					return( CRYPT_ARGERROR_VALUE );
				}
			return( copyCertInfo( certInfo, certInfoLength, data, 
								  dataLength ) );

		case CRYPT_CERTINFO_ISSUERNAME:
		case CRYPT_CERTINFO_SUBJECTNAME:
			{
			const void *dnPtr = ( certInfoType == CRYPT_CERTINFO_ISSUERNAME ) ? \
								certInfoPtr->issuerName : \
								certInfoPtr->subjectName;

			/* These are further selection components with special-case 
			   handling of returned data like the GeneralName selection 
			   components above */
			if( certInfo != NULL )
				*( ( int * ) certInfo ) = ( dnPtr != NULL ) ? TRUE : FALSE;
			return( ( dnPtr == NULL ) ? CRYPT_ERROR_NOTFOUND : CRYPT_OK );
			}

		case CRYPT_CERTINFO_VALIDFROM:
		case CRYPT_CERTINFO_THISUPDATE:
			if( certInfoPtr->startTime > 0 )
				{
				data = &certInfoPtr->startTime;
				dataLength = sizeof( time_t );
				}
			return( copyCertInfo( certInfo, certInfoLength, data, 
								  dataLength ) );

		case CRYPT_CERTINFO_VALIDTO:
		case CRYPT_CERTINFO_NEXTUPDATE:
			if( certInfoPtr->endTime > 0 )
				{
				data = &certInfoPtr->endTime;
				dataLength = sizeof( time_t );
				}
			return( copyCertInfo( certInfo, certInfoLength, data, 
								  dataLength ) );

		case CRYPT_CERTINFO_ISSUERUNIQUEID:
			return( copyCertInfo( certInfo, certInfoLength, 
								  certInfoPtr->cCertCert->issuerUniqueID, 
								  certInfoPtr->cCertCert->issuerUniqueIDlength ) );

		case CRYPT_CERTINFO_SUBJECTUNIQUEID:
			return( copyCertInfo( certInfo, certInfoLength, 
								  certInfoPtr->cCertCert->subjectUniqueID, 
								  certInfoPtr->cCertCert->subjectUniqueIDlength ) );

		case CRYPT_CERTINFO_REVOCATIONDATE:
			data = getRevocationTimePtr( certInfoPtr );
			if( data != NULL )
				dataLength = sizeof( time_t );
			return( copyCertInfo( certInfo, certInfoLength, data, 
								  dataLength ) );

		case CRYPT_CERTINFO_CERTSTATUS:
			{
			const CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;
			const VALIDITY_INFO *valInfoPtr = \
					( certValInfo->currentValidity != NULL ) ? \
					certValInfo->currentValidity : certValInfo->validityInfo;

			if( valInfoPtr == NULL )
				return( CRYPT_ERROR_NOTFOUND );
			return( copyCertInfoValue( certInfo, valInfoPtr->extStatus ) );
			}

		case CRYPT_CERTINFO_REVOCATIONSTATUS:
			{
			const CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
			const REVOCATION_INFO *revInfoPtr = \
					( certRevInfo->currentRevocation != NULL ) ? \
					certRevInfo->currentRevocation : certRevInfo->revocations;

			if( revInfoPtr == NULL )
				return( CRYPT_ERROR_NOTFOUND );
			return( copyCertInfoValue( certInfo, revInfoPtr->status ) );
			}

		case CRYPT_CERTINFO_DN:
			{
			STREAM stream;
			int status;

			/* Export the entire DN in string form */
			status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
							   MUST_BE_PRESENT );
			if( cryptStatusError( status ) )
				return( status );
			sMemOpen( &stream, certInfo, *certInfoLength );
			status = writeDNstring( &stream, 

⌨️ 快捷键说明

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