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

📄 certcomp.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Find a field in an attribute.  This returns a pointer to the attribute
   field containing the given GeneralName or GeneralName component, the given
   DN, or the given field */

static ATTRIBUTE_LIST *selectNameOrField( CERT_INFO *certInfoPtr,
										  const CRYPT_ATTRIBUTE_TYPE certInfoType )
	{
	/* If it's a GeneralName selection component or a GeneralName component,
	   locate the attribute field which it corresponds to */
	if( isGeneralNameSelectionComponent( certInfoType ) || \
		isGeneralNameComponent( certInfoType ) )
		return( selectGeneralName( certInfoPtr, certInfoType, SELECT_SELECT ) );

	/* If it's a DN selection component, move to the DirectoryName within the
	   appropriate GeneralName */
	if( isDNSelectionComponent( certInfoType ) )
		return( selectGeneralName( certInfoPtr, certInfoType, SELECT_SELECT ) );

	/* It's a standard attribute field, try and locate it (if it's something
	   else which isn't allowed, we'll get a null pointer returned) */
	return( findAttributeField( certInfoPtr->attributes, certInfoType,
								CRYPT_ATTRIBUTE_NONE ) );
	}

/* Copy various components into a certificate object */

static int copyPublicKey( CERT_INFO *certInfoPtr, 
						  const CRYPT_HANDLE cryptHandle )
	{
	CRYPT_CONTEXT iCryptContext;
	int status;

	/* Make sure we haven't already got a public key present */
	if( certInfoPtr->iCryptContext != CRYPT_ERROR )
		{
		setErrorInfo( certInfoPtr, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
		return( CRYPT_ERROR_INITED );
		}

	/* Get the context handle and make sure the context is of the correct
	   type */
	status = krnlSendMessage( cryptHandle, RESOURCE_IMESSAGE_GETDEPENDENT, 
							  &iCryptContext, OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iCryptContext, RESOURCE_IMESSAGE_CHECK,
								  NULL, RESOURCE_MESSAGE_CHECK_PKC );
	if( cryptStatusError( status ) )
		{
		setErrorInfo( certInfoPtr, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO,
					  CRYPT_ERRTYPE_ATTR_VALUE );
		return( status );
		}

	/* Take a copy of the context for the certificate */
	status = krnlSendMessage( certInfoPtr->objectHandle,
							  RESOURCE_IMESSAGE_SETDEPENDENT,
							  &iCryptContext, SETDEP_OPTION_INCREF );
	certInfoPtr->iCryptContext = iCryptContext;

	return( status );
	}

static int copyIssuerDN( CERT_INFO *destCertInfoPtr, 
						 const CERT_INFO *srcCertInfoPtr )
	{
	void *dnDataPtr;

	if( ( dnDataPtr = malloc( srcCertInfoPtr->issuerDNsize ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memcpy( dnDataPtr, srcCertInfoPtr->issuerDNptr,
			srcCertInfoPtr->issuerDNsize );
	destCertInfoPtr->issuerDNptr = destCertInfoPtr->issuerDNdata = dnDataPtr;
	destCertInfoPtr->issuerDNsize = srcCertInfoPtr->issuerDNsize;

	return( CRYPT_OK );
	}

static int copyRevocationInformation( CERT_INFO *crlInfoPtr,
									  const CERT_INFO *revInfoPtr )
	{
	int status;

	/* If there's an issuer name recorded, make sure it matches the one 
	   in the cert which is being added */
	if( crlInfoPtr->issuerDNptr != NULL )
		{
		if( crlInfoPtr->issuerDNsize != revInfoPtr->issuerDNsize || \
			memcmp( crlInfoPtr->issuerDNptr, revInfoPtr->issuerDNptr,
					crlInfoPtr->issuerDNsize ) )
			{
			setErrorInfo( crlInfoPtr, CRYPT_CERTINFO_ISSUERNAME,
						  CRYPT_ERRTYPE_ATTR_VALUE );
			return( CRYPT_ERROR_INVALID );
			}
		}
	else
		{
		/* There's no issuer name present yet, set the CRL issuer name to
		   the cert's issuer to make sure we can't add certs or sign the 
		   CRL with a different issuer.  We do this here rather than 
		   after setting the revocation list entry because of the 
		   difficulty of undoing the revocation entry addition */
		status = copyIssuerDN( crlInfoPtr, revInfoPtr );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Add the cert information to the revocation list and make it the 
	   currently selected entry */
	status = addRevocationEntry( &crlInfoPtr->revocations,
								 &crlInfoPtr->currentRevocation, 
								 CRYPT_CERTINFO_SERIALNUMBER,
								 revInfoPtr->serialNumber, 
								 revInfoPtr->serialNumberLength );
	if( status == CRYPT_ERROR_DUPLICATE )
		/* If this cert is already present in the list, set the extended
		   error code for it */
		setErrorInfo( crlInfoPtr, CRYPT_CERTINFO_USERCERTIFICATE,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
	return( status );
	}

/****************************************************************************
*																			*
*									Add a Component							*
*																			*
****************************************************************************/

/* Add a certificate component */

int addCertComponent( CERT_INFO *certInfoPtr,
					  const CRYPT_ATTRIBUTE_TYPE certInfoType,
					  const void *certInfo, const int certInfoLength )
	{
	int status = CRYPT_OK;

	/* If it's a certificate pseudo-component, update the certificate info */
	if( certInfoType >= CRYPT_FIRST_PSEUDOINFO && \
		certInfoType <= CRYPT_LAST_PSEUDOINFO )
		{
		ATTRIBUTE_LIST *attributeListPtr;
		const int value = *( ( int * ) certInfo );

		/* General certificate flags */
		if( certInfoType == CRYPT_CERTINFO_SELFSIGNED )
			{
			if( value )
				certInfoPtr->flags |= CERT_FLAG_SELFSIGNED;
			else
				certInfoPtr->flags &= ~CERT_FLAG_SELFSIGNED;
			return( CRYPT_OK );
			}

		/* Trust information */
		if( certInfoType == CRYPT_CERTINFO_TRUSTED_USAGE )
			{
			certInfoPtr->trustedUsage = value;
			return( CRYPT_OK );
			}
		if( certInfoType == CRYPT_CERTINFO_TRUSTED_IMPLICIT )
			{
			if( value )
				return( addTrustInfo( certInfoPtr ) );
			return( deleteTrustInfo( certInfoPtr ) );
			}

		/* Magic "just works" certificate */
		if( certInfoType == CRYPT_CERTINFO_XYZZY )
			{
			const BYTE *policyOID = OID_CRYPTLIB_XYZZYCERT;
			const int keyUsage = CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
								 CRYPT_KEYUSAGE_NONREPUDIATION | \
								 CRYPT_KEYUSAGE_KEYENCIPHERMENT | \
								 CRYPT_KEYUSAGE_KEYCERTSIGN | \
								 CRYPT_KEYUSAGE_CRLSIGN;
			const time_t expiryTime = time( NULL ) + ( 86400 * 365 * 20 );
			RESOURCE_DATA msgData;

			/* Clear any existing attribute values before trying to set new
			   ones */
			krnlSendMessage( certInfoPtr->objectHandle, 
							 RESOURCE_IMESSAGE_DELETEATTRIBUTE,
							 NULL, CRYPT_CERTINFO_VALIDTO );
			krnlSendMessage( certInfoPtr->objectHandle, 
							 RESOURCE_IMESSAGE_DELETEATTRIBUTE,
							 NULL, CRYPT_CERTINFO_KEYUSAGE );
			krnlSendMessage( certInfoPtr->objectHandle, 
							 RESOURCE_IMESSAGE_DELETEATTRIBUTE,
							 NULL, CRYPT_CERTINFO_CERTIFICATEPOLICIES );

			/* Give the cert a 20-year expiry time, make it a self-signed CA 
			   cert with all key usage types enabled, and set the policy OID 
			   to identify it as a XYZZY cert */
			setResourceData( &msgData, ( void * ) &expiryTime, 
							 sizeof( time_t ) );
			status = krnlSendMessage( certInfoPtr->objectHandle, 
									  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
									  &msgData, CRYPT_CERTINFO_VALIDTO );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( certInfoPtr->objectHandle, 
										  RESOURCE_IMESSAGE_SETATTRIBUTE,
										  MESSAGE_VALUE_TRUE, 
										  CRYPT_CERTINFO_SELFSIGNED );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( certInfoPtr->objectHandle, 
										  RESOURCE_IMESSAGE_SETATTRIBUTE,
										  MESSAGE_VALUE_TRUE, 
										  CRYPT_CERTINFO_CA );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( certInfoPtr->objectHandle, 
										  RESOURCE_IMESSAGE_SETATTRIBUTE,
										  ( void * ) &keyUsage, 
										  CRYPT_CERTINFO_KEYUSAGE );
			if( cryptStatusOK( status ) )
				{
				setResourceData( &msgData, OID_CRYPTLIB_XYZZYCERT, 
								 sizeofOID( OID_CRYPTLIB_XYZZYCERT ) );
				status = krnlSendMessage( certInfoPtr->objectHandle, 
										  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
										  &msgData, CRYPT_CERTINFO_CERTPOLICYID );
				}
			return( cryptStatusError( status ) ? CRYPT_ERROR_FAILED : status );
			}

		/* Certificate cursor movement (which selects a cert in a cert
		   chain, an entry in a CRL, or a request/response in an OCSP 
		   object) */
		if( certInfoType == CRYPT_CERTINFO_CURRENT_CERTIFICATE )
			{
			const BOOLEAN isCertChain = \
						( certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN ) ? \
						TRUE : FALSE;

			/* We can only select items in a cert chain, CRL, or OCSP 
			   request/response */
			if( !isCertChain && certInfoPtr->type != CRYPT_CERTTYPE_CRL && \
				certInfoPtr->type != CRYPT_CERTTYPE_OCSP_REQUEST && \
				certInfoPtr->type != CRYPT_CERTTYPE_OCSP_RESPONSE )
				return( CRYPT_ARGERROR_OBJECT );

			switch( value )
				{
				case CRYPT_CURSOR_FIRST:
					if( isCertChain )
						certInfoPtr->certChainPos = CRYPT_ERROR;
					else
						{
						certInfoPtr->currentRevocation = certInfoPtr->revocations;
						if( certInfoPtr->currentRevocation == NULL )
							return( CRYPT_ERROR_NOTFOUND );
						}
					break;

				case CRYPT_CURSOR_PREVIOUS:
					if( isCertChain )
						{
						if( certInfoPtr->certChainPos == CRYPT_ERROR )
							return( CRYPT_ERROR_NOTFOUND );
						certInfoPtr->certChainPos--;
						}
					else
						{
						REVOCATION_INFO *revInfo = certInfoPtr->revocations;

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

						/* Find the previous element in the list */
						if( revInfo != certInfoPtr->currentRevocation )
							while( revInfo->next != certInfoPtr->currentRevocation )
								revInfo = revInfo->next;
						certInfoPtr->currentRevocation = revInfo;
						}
					break;

				case CRYPT_CURSOR_NEXT:
					if( isCertChain )
						{
						if( certInfoPtr->certChainPos >= certInfoPtr->certChainEnd - 1 )
							return( CRYPT_ERROR_NOTFOUND );
						certInfoPtr->certChainPos++;
						}
					else
						{
						if( certInfoPtr->currentRevocation == NULL || \
							certInfoPtr->currentRevocation->next == NULL )
							return( CRYPT_ERROR_NOTFOUND );
						certInfoPtr->currentRevocation = certInfoPtr->currentRevocation->next;
						}
					break;

				case CRYPT_CURSOR_LAST:
					if( isCertChain )
						certInfoPtr->certChainPos = certInfoPtr->certChainEnd - 1;
					else
						{
						REVOCATION_INFO *revInfo = certInfoPtr->revocations;

						/* Go to the end of the list */
						if( revInfo != NULL )
							while( revInfo->next != NULL )
								revInfo = revInfo->next;
						if( revInfo == NULL )
							return( CRYPT_ERROR_NOTFOUND );

						certInfoPtr->currentRevocation = revInfo;
						}
					break;

				default:
					return( CRYPT_ARGERROR_NUM1 );
				}

			return( CRYPT_OK );
			}

		assert( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION || \
				certInfoType == CRYPT_CERTINFO_CURRENT_FIELD || \
				certInfoType == CRYPT_CERTINFO_CURRENT_COMPONENT );

		/* If the new position is specified relative to a previous position,
		   try and move to that position.  Note that the seemingly illogical
		   comparison is used because the cursor positioning codes are
		   negative values */
		if( value <= CRYPT_CURSOR_FIRST && value >= CRYPT_CURSOR_LAST )
			{
			/* If it's an absolute positioning code, pre-set the attribute
			   cursor if required */
			if( value == CRYPT_CURSOR_FIRST || value == CRYPT_CURSOR_LAST )
				{
				/* If it's an absolute attribute positioning code, reset the 
				   attribute cursor to the start of the list before we try to 
				   move it */
				if( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION )
					certInfoPtr->attributeCursor = certInfoPtr->attributes;
				else
					/* It's a field or component positioning code, initialise
					   the attribute cursor if necessary */
					if( certInfoPtr->attributeCursor == NULL )
						certInfoPtr->attributeCursor = certInfoPtr->attributes;
				}

			/* Move the attribute cursor */
			if( certInfoPtr->attributeCursor == NULL )
				{
				status = ( value == CRYPT_CURSOR_FIRST || \
						   value == CRYPT_CURSOR_LAST ) ? \
						 CRYPT_ERROR_NOTFOUND : CRYPT_ERROR_NOTINITED;
				return( status );
				}
			status = moveAttributeCursor( &certInfoPtr->attributeCursor,
										  certInfoType, value );
			return( status );
			}

⌨️ 快捷键说明

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