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

📄 cmp.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
		   that caused the failure earlier on */
		setMessageCertMgmtInfo( &certMgmtInfo, CRYPT_UNUSED,
								sessionInfoPtr->iCertResponse );
		localStatus = krnlSendMessage( sessionInfoPtr->cryptKeyset,
									IMESSAGE_KEY_CERTMGMT, &certMgmtInfo,
									CRYPT_CERTACTION_CERT_CREATION_REVERSE );
		return( cryptStatusOK( status ) ? localStatus : status );
		}
	DEBUG_DUMP_CMP( protocolInfo.operation, 3, sessionInfoPtr );

	/* The client has confirmed the cert creation, finalise it */
	setMessageCertMgmtInfo( &certMgmtInfo, CRYPT_UNUSED,
							sessionInfoPtr->iCertResponse );
	status = krnlSendMessage( sessionInfoPtr->cryptKeyset,
							  IMESSAGE_KEY_CERTMGMT, &certMgmtInfo,
							  CRYPT_CERTACTION_CERT_CREATION_COMPLETE );
	if( cryptStatusError( status ) )
		{
		sendErrorResponse( sessionInfoPtr, &protocolInfo, status );
		destroyProtocolInfo( &protocolInfo );
		retExt( sessionInfoPtr, status, "Cert issue completion failed" );
		}

	/* Send back the final ack and clean up.  We don't bother checking the
	   return status since the message write can never fail (it just encodes
	   a null data value) and there's not much we can do if the final socket
	   write fails.  In addition we remember the authentication context in 
	   case we can reuse it for another transaction */
	writePkiMessage( sessionInfoPtr, &protocolInfo, CMPBODY_ACK );
	DEBUG_DUMP_CMP( protocolInfo.operation, 4, sessionInfoPtr );
	writePkiDatagram( sessionInfoPtr );
	sessionInfoPtr->cmpSavedMacContext = protocolInfo.iMacContext;
	protocolInfo.iMacContext = CRYPT_ERROR;
	destroyProtocolInfo( &protocolInfo );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Control Information Management Functions			*
*																			*
****************************************************************************/

static int getAttributeFunction( SESSION_INFO *sessionInfoPtr,
								 void *data, const CRYPT_ATTRIBUTE_TYPE type )
	{
	CRYPT_CERTIFICATE *cmpResponsePtr = ( CRYPT_CERTIFICATE * ) data;

	assert( type == CRYPT_SESSINFO_CMP_REQUESTTYPE || \
			type == CRYPT_SESSINFO_RESPONSE );

	/* If it's a general protocol-specific attribute read, return the
	   information and exit */
	if( type == CRYPT_SESSINFO_CMP_REQUESTTYPE )
		{
		if( sessionInfoPtr->cmpRequestType == CRYPT_REQUESTTYPE_NONE )
			{
			setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_CMP_REQUESTTYPE,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			return( CRYPT_ERROR_NOTFOUND );
			}
		*( ( int * ) data ) = sessionInfoPtr->cmpRequestType;
		return( CRYPT_OK );
		}

	/* If we didn't get a response there's nothing to return */
	if( sessionInfoPtr->iCertResponse == CRYPT_ERROR )
		return( CRYPT_ERROR_NOTFOUND );

	/* Return the information to the caller */
	krnlSendNotifier( sessionInfoPtr->iCertResponse, IMESSAGE_INCREFCOUNT );
	*cmpResponsePtr = sessionInfoPtr->iCertResponse;
	return( CRYPT_OK );
	}

static int setAttributeFunction( SESSION_INFO *sessionInfoPtr,
								 const void *data,
								 const CRYPT_ATTRIBUTE_TYPE type )
	{
	CRYPT_CERTIFICATE cryptCert = *( ( CRYPT_CERTIFICATE * ) data );
	int value, status;

	assert( type == CRYPT_SESSINFO_CMP_REQUESTTYPE || \
			type == CRYPT_SESSINFO_CMP_PRIVKEYSET || \
			type == CRYPT_SESSINFO_REQUEST || \
			type == CRYPT_SESSINFO_CACERTIFICATE );

	/* Standard CMP (with user-supplied request info) can't be combined with
	   plug-and-play CMP (with automatically-generated request info) */
	if( ( type == CRYPT_SESSINFO_CMP_REQUESTTYPE || \
		  type == CRYPT_SESSINFO_REQUEST ) && \
		sessionInfoPtr->privKeyset != CRYPT_ERROR )
		{
		setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_CMP_PRIVKEYSET,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
		return( CRYPT_ERROR_INITED );
		}
	if( type == CRYPT_SESSINFO_CMP_PRIVKEYSET && \
		( sessionInfoPtr->cmpRequestType != CRYPT_REQUESTTYPE_NONE || \
		  sessionInfoPtr->iCertRequest != CRYPT_ERROR ) )
		{
		setErrorInfo( sessionInfoPtr, 
					  ( sessionInfoPtr->iCertRequest != CRYPT_ERROR ) ? \
						CRYPT_SESSINFO_REQUEST : \
						CRYPT_SESSINFO_CMP_REQUESTTYPE,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
		return( CRYPT_ERROR_INITED );
		}

	/* If it's general protocol-specific information other than a request or 
	   cert, set it */
	if( type == CRYPT_SESSINFO_CMP_REQUESTTYPE )
		{
		/* Make sure that the value hasn't been set yet */
		value = *( ( int * ) data );
		if( sessionInfoPtr->cmpRequestType != CRYPT_REQUESTTYPE_NONE )
			{
			setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_CMP_REQUESTTYPE,
						  CRYPT_ERRTYPE_ATTR_PRESENT );
			return( CRYPT_ERROR_INITED );
			}

		/* If the request object is already present, make sure that it 
		   matches the request type.  We can't do this check unconditionally 
		   because the request type may be set before the request object is 
		   set */
		if( sessionInfoPtr->iCertRequest != CRYPT_ERROR )
			{
			int requestType;

			status = krnlSendMessage( sessionInfoPtr->iCertRequest,
									  IMESSAGE_GETATTRIBUTE, &requestType, 
									  CRYPT_CERTINFO_CERTTYPE );
			if( cryptStatusError( status ) )
				return( status );
			if( requestType == CRYPT_CERTTYPE_REQUEST_CERT )
				{
				if( value != CRYPT_REQUESTTYPE_INITIALISATION && \
					value != CRYPT_REQUESTTYPE_CERTIFICATE && \
					value != CRYPT_REQUESTTYPE_KEYUPDATE )
					status = CRYPT_ERROR_INVALID;
				}
			else
				if( value != CRYPT_REQUESTTYPE_REVOCATION )
					status = CRYPT_ERROR_INVALID;
			if( cryptStatusError( status ) )
				{
				setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_REQUEST,
							  CRYPT_ERRTYPE_CONSTRAINT );
				return( status );
				}
			}

		/* Set the request type and tell the higher-level code that further
		   information needs to be provided before we can activate the
		   session */
		sessionInfoPtr->cmpRequestType = value;
		if( value == CRYPT_REQUESTTYPE_INITIALISATION || \
			value == CRYPT_REQUESTTYPE_PKIBOOT )
			sessionInfoPtr->clientReqAttrFlags = \
									SESSION_NEEDS_USERID | \
									SESSION_NEEDS_PASSWORD;
		else
			if( value == CRYPT_REQUESTTYPE_REVOCATION )
				sessionInfoPtr->clientReqAttrFlags = \
									SESSION_NEEDS_PRIVATEKEY | \
									SESSION_NEEDS_PRIVKEYSIGN | \
									SESSION_NEEDS_PRIVKEYCERT | \
									SESSION_NEEDS_KEYORPASSWORD;
			else
				sessionInfoPtr->clientReqAttrFlags = \
									SESSION_NEEDS_PRIVATEKEY | \
									SESSION_NEEDS_PRIVKEYSIGN | \
									SESSION_NEEDS_PRIVKEYCERT;
		return( CRYPT_OK );
		}
	if( type == CRYPT_SESSINFO_CMP_PRIVKEYSET )
		{
		CRYPT_CERTIFICATE privKeyset = *( ( CRYPT_CERTIFICATE * ) data );

		/* Make sure that the value hasn't been set yet */
		if( sessionInfoPtr->privKeyset != CRYPT_ERROR )
			{
			setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_CMP_PRIVKEYSET,
						  CRYPT_ERRTYPE_ATTR_PRESENT );
			return( CRYPT_ERROR_INITED );
			}

		/* Remember that we're using plug-and-play PKI functionality */
		sessionInfoPtr->flags |= SESSION_ISPNPPKI;

		krnlSendNotifier( privKeyset, IMESSAGE_INCREFCOUNT );
		sessionInfoPtr->privKeyset = privKeyset;
		return( CRYPT_OK );
		}

	/* Make sure that the request/cert type is consistent with the operation
	   being performed.  The requirements for this are somewhat more complex 
	   than the basic ACL-based check can manage, so we handle it here with 
	   custom code */
	status = krnlSendMessage( cryptCert, IMESSAGE_GETATTRIBUTE, &value, 
							  CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_NUM1 );
	switch( type )
		{
		case CRYPT_SESSINFO_REQUEST:
			if( value != CRYPT_CERTTYPE_REQUEST_CERT && \
				value != CRYPT_CERTTYPE_REQUEST_REVOCATION )
				return( CRYPT_ARGERROR_NUM1 );

			/* If the request type is already present, make sure that it 
			   matches the request object.  We can't do this check 
			   unconditionally because the request object may be set before 
			   the request type is set */
			if( sessionInfoPtr->cmpRequestType != CRYPT_REQUESTTYPE_NONE )
				{
				const CRYPT_REQUESTTYPE_TYPE requestType = \
										sessionInfoPtr->cmpRequestType;

				if( value == CRYPT_CERTTYPE_REQUEST_CERT )
					{
					if( requestType != CRYPT_REQUESTTYPE_INITIALISATION && \
						requestType != CRYPT_REQUESTTYPE_CERTIFICATE && \
						requestType != CRYPT_REQUESTTYPE_KEYUPDATE )
						status = CRYPT_ERROR_INVALID;
					}
				else
					if( requestType != CRYPT_REQUESTTYPE_REVOCATION )
						status = CRYPT_ERROR_INVALID;
				if( cryptStatusError( status ) )
					{
					setErrorInfo( sessionInfoPtr, 
								  CRYPT_SESSINFO_CMP_REQUESTTYPE,
								  CRYPT_ERRTYPE_CONSTRAINT );
					return( status );
					}
				}

			/* If it's a non-ir cert request, make sure that there's a 
			   subject DN present.  We perform this check because subject 
			   DNs are optional for irs but not for any other request types 
			   and we want to catch this before we get into the CMP exchange
			   itself */
			if( sessionInfoPtr->cmpRequestType == CRYPT_REQUESTTYPE_CERTIFICATE || \
				sessionInfoPtr->cmpRequestType == CRYPT_REQUESTTYPE_KEYUPDATE )
				{
				RESOURCE_DATA msgData = { NULL, 0 };

				status = krnlSendMessage( cryptCert, IMESSAGE_GETATTRIBUTE_S, 
										  &msgData, CRYPT_IATTRIBUTE_SUBJECT );
				if( cryptStatusError( status ) )
					{
					setErrorInfo( sessionInfoPtr, CRYPT_CERTINFO_SUBJECTNAME,
								  CRYPT_ERRTYPE_ATTR_ABSENT );
					return( CRYPT_ARGERROR_NUM1 );
					}
				}
			break;

		case CRYPT_SESSINFO_CACERTIFICATE:
			if( value != CRYPT_CERTTYPE_CERTIFICATE )
				return( CRYPT_ARGERROR_NUM1 );
			break;

		default:
			assert( NOTREACHED );
		}
	if( value == CRYPT_CERTTYPE_CERTIFICATE || \
		value == CRYPT_CERTTYPE_REQUEST_CERT )
		{
		/* Make sure that everything is set up ready to go */
		status = krnlSendMessage( cryptCert, IMESSAGE_GETATTRIBUTE, &value, 
								  CRYPT_CERTINFO_IMMUTABLE );
		if( cryptStatusError( status ) || !value )
			return( CRYPT_ARGERROR_NUM1 );
#if 0	/* RA certs aren't necessarily CA certs */
		if( type == CRYPT_SESSINFO_CACERTIFICATE )
			{
			/* Make sure that it really is a CA cert */
			status = krnlSendMessage( cryptCert, IMESSAGE_CHECK, NULL, 
									  MESSAGE_CHECK_CA );
			if( cryptStatusError( status ) )
				{
				setErrorInfo( sessionInfoPtr, CRYPT_CERTINFO_CA,
							  CRYPT_ERRTYPE_ATTR_ABSENT );
				return( CRYPT_ARGERROR_NUM1 );
				}
			}
#endif /* 0 */
		}
	else
		{
		RESOURCE_DATA msgData = { NULL, 0 };

		/* Make sure that everything is set up ready to go.  Since revocation
		   requests aren't signed like normal cert objects we can't just
		   check the immutable attribute but have to perform a dummy export
		   for which the cert export code will return an error status if
		   there's a problem with the request */
		status = krnlSendMessage( cryptCert, IMESSAGE_CRT_EXPORT, &msgData, 
								  CRYPT_ICERTFORMAT_DATA );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* Add the request and increment its usage count */
	krnlSendNotifier( cryptCert, IMESSAGE_INCREFCOUNT );
	if( type == CRYPT_SESSINFO_CACERTIFICATE )
		sessionInfoPtr->iAuthInContext = cryptCert;
	else
		sessionInfoPtr->iCertRequest = cryptCert;

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Session Access Routines							*
*																			*
****************************************************************************/

int setAccessMethodCMP( SESSION_INFO *sessionInfoPtr )
	{
	static const ALTPROTOCOL_INFO altProtocolInfo = {
		STREAM_PROTOCOL_CMP,		/* Alt.xport protocol type */
		"cmp://",					/* Alt.xport protocol URI type */
		CMP_PORT					/* Alt.xport protocol port */
		};
	static const PROTOCOL_INFO protocolInfo = {
		/* General session information */
		TRUE,						/* Request-response protocol */
		SESSION_ISHTTPTRANSPORT,	/* Flags */
		80,							/* HTTP port */
		0,							/* Client attributes */
		SESSION_NEEDS_PRIVATEKEY |	/* Server attributes */
			SESSION_NEEDS_PRIVKEYSIGN | \
			SESSION_NEEDS_PRIVKEYCERT | \
			SESSION_NEEDS_PRIVKEYCACERT | \
			SESSION_NEEDS_KEYSET | \
			SESSION_NEEDS_CERTSTORE,
		2, 2, 2,					/* Version 2 */
		"application/pkixcmp",		/* Client content-type */
		"application/pkixcmp",		/* Server content-type */
	
		/* Protocol-specific information */
		BUFFER_SIZE_DEFAULT,		/* Buffer size info */
		&altProtocolInfo			/* Alt.transport protocol */
		};

	/* Set the access method pointers */
	sessionInfoPtr->protocolInfo = &protocolInfo;
	if( sessionInfoPtr->flags & SESSION_ISSERVER )
		sessionInfoPtr->transactFunction = serverTransact;
	else
		{
		sessionInfoPtr->connectFunction = clientStartup;
		sessionInfoPtr->transactFunction = clientTransactWrapper;
		}
	sessionInfoPtr->shutdownFunction = shutdownFunction;
	sessionInfoPtr->getAttributeFunction = getAttributeFunction;
	sessionInfoPtr->setAttributeFunction = setAttributeFunction;

	/* Initialise CMP-specific objects */
	sessionInfoPtr->cmpUserInfo = CRYPT_ERROR;
	sessionInfoPtr->cmpSavedMacContext = CRYPT_ERROR;

	return( CRYPT_OK );
	}
#endif /* USE_CMP */

⌨️ 快捷键说明

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