cryptapi.c

来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,895 行 · 第 1/5 页

C
1,895
字号
				return( CRYPT_ERROR );

		/* Process the fixed message header and make sure it's valid */
		bufPtr = buffer + COMMAND_FIXED_DATA_SIZE;
		status = getMessageWord( bufPtr );
		if( cryptStatusError( status ) )
			{
			/* The push data command is a special case since it returns a 
			   bytes copied value even if an error occurs */
			if( sentCmd.type == COMMAND_PUSHDATA )
				{
				const long bytesCopied = \
							getMessageWord( bufPtr + COMMAND_WORDSIZE );

				if( bytesCopied < 0 )
					return( CRYPT_ERROR );
				cmdResult.arg[ 0 ] = cmd->arg[ 0 ] + bytesCopied;
				cmdResult.noArgs = 1;
				}
			*cmd = cmdResult;
			return( status );
			}
		assert( cryptStatusOK( status ) );
		
		/* Read the rest of the server's message */
		resultLength = getMessageWord( bufPtr + COMMAND_WORDSIZE );
		if( isPushPop )
			{
			/* It's a variable-length transformation, we have to return a
			   non-negative number of bytes */
			if( resultLength <= 0 )
				{
				if( resultLength == 0 )
					/* We've run out of data, return to the caller */
					break;
				return( CRYPT_ERROR );
				}
			cmd->arg[ 0 ] += resultLength;
			if( sentCmd.type == COMMAND_POPDATA )
				{
				memcpy( payloadPtr, payloadStartPtr + COMMAND_WORDSIZE, 
						resultLength );

				/* If we got less than what we asked for, there's nothing
				   more available, exit */
				if( resultLength < fragmentLength )
					dataLength = resultLength;
				}
			}
		else
			{
			/* It's an encrypt/decrypt, the result must be a 1:1 
			   transformation unless it's a hash in which case nothing is
			   returned */
			if( resultLength )
				{
				if( resultLength != fragmentLength )
					return( CRYPT_ERROR );
				memcpy( payloadPtr, payloadStartPtr + COMMAND_WORDSIZE, 
						resultLength );
				}
			else
				/* If no data was returned, it was a hash, set a pseudo-
				   result length which is the same size as the amount of
				   data fed in */
				resultLength = fragmentLength;
			}

		/* Move on to the next fragment */
		payloadPtr += resultLength;
		dataLength -= resultLength;
		}
	while( dataLength > 0 );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Internal parameter errors are reported in terms of the parameter type (eg
   invalid object, invalid attribute), but externally they're reported in
   terms of parameter numbers.  Before we return error values to the caller,
   we have to map them from the internal representation to the position they
   occur in in the function parameter list.  The following function takes a
   list of parameter types and maps the returned parameter type error to a
   parameter position error */

typedef enum { 
	ARG_D,			/* Dummy placeholder */
	ARG_O,			/* Object */
	ARG_V,			/* Value (attribute) */
	ARG_N,			/* Numeric arg */
	ARG_S,			/* String arg */
	ARG_LAST
	} ERRORMAP;

static int mapError( const ERRORMAP *errorMap, const int status )
	{
	ERRORMAP type;
	int count = 0, i;

	/* If it's not an internal parameter error, let it out */
	if( !cryptArgError( status ) )
		{
		assert( status <= 0 && status >= CRYPT_ENVELOPE_RESOURCE );
		return( status );
		}

	/* Map the parameter error to a position error */
	switch( status )
		{
		case CRYPT_ARGERROR_OBJECT:
			type = ARG_O;
			break;
		case CRYPT_ARGERROR_VALUE:
			type = ARG_V;
			break;
		case CRYPT_ARGERROR_NUM1:
		case CRYPT_ARGERROR_NUM2:
			type = ARG_N;
			count = CRYPT_ARGERROR_NUM1 - status;
			break;
		case CRYPT_ARGERROR_STR1:
		case CRYPT_ARGERROR_STR2:
			type = ARG_S;
			count = CRYPT_ARGERROR_STR1 - status;
			break;
		default:
			assert( NOTREACHED );
		}
	for( i = 0; errorMap[ i ] != ARG_LAST; i++ )
		if( errorMap[ i ] == type && !count-- )
			return( CRYPT_ERROR_PARAM1 - i );
	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/****************************************************************************
*																			*
*								Create/Destroy Objects						*
*																			*
****************************************************************************/

/* Create an encryption context */

C_RET cryptCreateContext( C_OUT CRYPT_CONTEXT C_PTR cryptContext,
						  C_IN CRYPT_USER cryptUser,
						  C_IN CRYPT_ALGO cryptAlgo )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 3, 0, 
		  { SYSTEM_OBJECT_HANDLE, OBJECT_TYPE_CONTEXT } };
	static const ERRORMAP errorMap[] = \
		{ ARG_D, ARG_O, ARG_N, ARG_N, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic client-side error checking */
	if( checkBadPtrWrite( cryptContext, sizeof( CRYPT_CONTEXT ) ) )
		return( CRYPT_ERROR_PARAM1 );
	*cryptContext = CRYPT_ERROR;
	if( cryptUser != CRYPT_UNUSED && !checkHandleRange( cryptUser ) )
		return( CRYPT_ERROR_PARAM2 );
	if( ( cryptAlgo <= CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) && \
		cryptAlgo != CRYPT_USE_DEFAULT )
		return( CRYPT_ERROR_PARAM3 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	if( cryptUser != CRYPT_UNUSED )
		cmd.arg[ 0 ] = cryptUser;
	cmd.arg[ 2 ] = cryptAlgo;
	status = dispatchCommand( &cmd );
	if( cryptStatusOK( status ) )
		{
		*cryptContext = cmd.arg[ 0 ];
		return( CRYPT_OK );
		}
	return( mapError( errorMap, status ) );
	}

/* Create an encryption context via the device */

C_RET cryptDeviceCreateContext( C_IN CRYPT_DEVICE device,
							    C_OUT CRYPT_CONTEXT C_PTR cryptContext,
							    C_IN CRYPT_ALGO cryptAlgo )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 3, 0, 
		  { 0, OBJECT_TYPE_CONTEXT } };
	static const ERRORMAP errorMap[] = \
		{ ARG_O, ARG_D, ARG_N, ARG_N, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic client-side error checking */
	if( !checkHandleRange( device ) )
		return( CRYPT_ERROR_PARAM1 );
	if( checkBadPtrWrite( cryptContext, sizeof( CRYPT_CONTEXT ) ) )
		return( CRYPT_ERROR_PARAM2 );
	*cryptContext = CRYPT_ERROR;
	if( ( cryptAlgo <= CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) && \
		cryptAlgo != CRYPT_USE_DEFAULT )
		return( CRYPT_ERROR_PARAM3 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	cmd.arg[ 0 ] = device;
	cmd.arg[ 2 ] = cryptAlgo;
	status = dispatchCommand( &cmd );
	if( cryptStatusOK( status ) )
		{
		*cryptContext = cmd.arg[ 0 ];
		return( CRYPT_OK );
		}
	return( mapError( errorMap, status ) );
	}

/* Create a certificate */

C_RET cryptCreateCert( C_OUT CRYPT_CERTIFICATE C_PTR certificate,
					   C_IN CRYPT_USER cryptUser,
					   C_IN CRYPT_CERTTYPE_TYPE certType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 3, 0, 
		  { SYSTEM_OBJECT_HANDLE, OBJECT_TYPE_CERTIFICATE } };
	static const ERRORMAP errorMap[] = \
		{ ARG_D, ARG_O, ARG_N, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic client-side error checking */
	if( checkBadPtrWrite( certificate, sizeof( CRYPT_CERTIFICATE ) ) )
		return( CRYPT_ERROR_PARAM1 );
	*certificate = CRYPT_ERROR;
	if( cryptUser != CRYPT_UNUSED && !checkHandleRange( cryptUser ) )
		return( CRYPT_ERROR_PARAM2 );
	if( certType <= CRYPT_CERTTYPE_NONE || \
		certType >= CRYPT_CERTTYPE_LAST_EXTERNAL )
		return( CRYPT_ERROR_PARAM3 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	if( cryptUser != CRYPT_UNUSED )
		cmd.arg[ 0 ] = cryptUser;
	cmd.arg[ 2 ] = certType;
	status = dispatchCommand( &cmd );
	if( cryptStatusOK( status ) )
		{
		*certificate = cmd.arg[ 0 ];
		return( CRYPT_OK );
		}
	return( mapError( errorMap, status ) );
	}

/* Open a device */

C_RET cryptDeviceOpen( C_OUT CRYPT_DEVICE C_PTR device,
					   C_IN CRYPT_USER cryptUser,
					   C_IN CRYPT_DEVICE_TYPE deviceType,
					   C_IN char C_PTR name )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 3, 1,
		  { SYSTEM_OBJECT_HANDLE, OBJECT_TYPE_DEVICE } };
	static const ERRORMAP errorMap[] = \
		{ ARG_D, ARG_O, ARG_N, ARG_S, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic error checking */
	if( checkBadPtrRead( device, sizeof( CRYPT_DEVICE ) ) )
		return( CRYPT_ERROR_PARAM1 );
	*device = CRYPT_ERROR;
	if( cryptUser != CRYPT_UNUSED && !checkHandleRange( cryptUser ) )
		return( CRYPT_ERROR_PARAM2 );
	if( deviceType <= CRYPT_DEVICE_NONE || deviceType >= CRYPT_DEVICE_LAST )
		return( CRYPT_ERROR_PARAM3 );
	if( deviceType == CRYPT_DEVICE_PKCS11 && \
		( checkBadPtrRead( name, 2 ) || \
		  strlen( name ) >= MAX_ATTRIBUTE_SIZE ) )
		return( CRYPT_ERROR_PARAM4 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	if( cryptUser != CRYPT_UNUSED )
		cmd.arg[ 0 ] = cryptUser;
	cmd.arg[ 2 ] = deviceType;
	cmd.strArg[ 0 ] = ( void * ) name;
	if( name != NULL )
		cmd.strArgLen[ 0 ] = strlen( name );
	status = dispatchCommand( &cmd );
	if( cryptStatusOK( status ) )
		{
		*device = cmd.arg[ 0 ];
		return( CRYPT_OK );
		}
	return( mapError( errorMap, status ) );
	}

/* Create an envelope */

C_RET cryptCreateEnvelope( C_OUT CRYPT_ENVELOPE C_PTR envelope,
						   C_IN CRYPT_USER cryptUser,
						   C_IN CRYPT_FORMAT_TYPE formatType )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 3, 0,
		  { SYSTEM_OBJECT_HANDLE, OBJECT_TYPE_ENVELOPE } };
	static const ERRORMAP errorMap[] = \
		{ ARG_D, ARG_O, ARG_N, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic error checking */
	if( checkBadPtrWrite( envelope, sizeof( CRYPT_ENVELOPE ) ) )
		return( CRYPT_ERROR_PARAM1 );
	*envelope = CRYPT_ERROR;
	if( cryptUser != CRYPT_UNUSED && !checkHandleRange( cryptUser ) )
		return( CRYPT_ERROR_PARAM2 );
	if( formatType <= CRYPT_FORMAT_NONE || \
		formatType >= CRYPT_FORMAT_LAST )
		return( CRYPT_ERROR_PARAM3 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	if( cryptUser != CRYPT_UNUSED )
		cmd.arg[ 0 ] = cryptUser;
	cmd.arg[ 2 ] = formatType;
	status = dispatchCommand( &cmd );
	if( cryptStatusOK( status ) )
		{
		*envelope = cmd.arg[ 0 ];
		return( CRYPT_OK );
		}
	return( mapError( errorMap, status ) );
	}

/* Open/create a keyset */

C_RET cryptKeysetOpen( C_OUT CRYPT_KEYSET C_PTR keyset, 
					   C_IN CRYPT_USER cryptUser,
					   C_IN CRYPT_KEYSET_TYPE keysetType,
					   C_IN char C_PTR name, C_IN CRYPT_KEYOPT_TYPE options )
	{
	static const COMMAND_INFO cmdTemplate = \
		{ COMMAND_CREATEOBJECT, COMMAND_FLAG_NONE, 4, 1,
		  { SYSTEM_OBJECT_HANDLE, OBJECT_TYPE_KEYSET } };
	static const ERRORMAP errorMap[] = \
		{ ARG_D, ARG_O, ARG_N, ARG_S, ARG_N, ARG_LAST };
	COMMAND_INFO cmd;
	int status;

	/* Perform basic error checking */
	if( checkBadPtrRead( keyset, sizeof( CRYPT_KEYSET ) ) )
		return( CRYPT_ERROR_PARAM1 );
	*keyset = CRYPT_ERROR;
	if( cryptUser != CRYPT_UNUSED && !checkHandleRange( cryptUser ) )
		return( CRYPT_ERROR_PARAM2 );
	if( keysetType <= CRYPT_KEYSET_NONE || keysetType >= CRYPT_KEYSET_LAST )
		return( CRYPT_ERROR_PARAM3 );
	if( checkBadPtrRead( name, 2 ) || strlen( name ) >= MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ERROR_PARAM4 );
	if( options < CRYPT_KEYOPT_NONE || \
		options >= CRYPT_KEYOPT_LAST_EXTERNAL )
		/* CRYPT_KEYOPT_NONE is a valid setting for this parameter */
		return( CRYPT_ERROR_PARAM4 );

	/* Dispatch the command */
	memcpy( &cmd, &cmdTemplate, sizeof( COMMAND_INFO ) );
	if( cryptUser != CRYPT_UNUSED )
		cmd.arg[ 0 ] = cryptUser;
	cmd.arg[ 2 ] = keysetType;
	cmd.

⌨️ 快捷键说明

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