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

📄 certraw.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*						  Unsigned Cert Object Routines						*
*						Copyright Peter Gutmann 1996-2001					*
*																			*
****************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined( INC_ALL ) ||  defined( INC_CHILD )
  #include "asn1.h"
  #include "asn1objs.h"
  #include "asn1oid.h"
  #include "cert.h"
#else
  #include "keymgmt/asn1.h"
  #include "keymgmt/asn1objs.h"
  #include "keymgmt/asn1oid.h"
  #include "keymgmt/cert.h"
#endif /* Compiler-specific includes */

/****************************************************************************
*																			*
*								Read/Write OCSP Data						*
*																			*
****************************************************************************/

/* The OCSPv1 ID doesn't contain any usable fields so we pre-encode it when 
   the cert is added to the OCSP request and treat it as a blob thereafter */

int sizeofOCSPv1ID( const CERT_INFO *certInfoPtr )
	{
	return( ( int ) sizeofObject( \
						sizeofAlgoID( CRYPT_ALGO_SHA ) + \
						sizeofObject( 20 ) + sizeofObject( 20 ) + \
						sizeofInteger( certInfoPtr->serialNumber, \
									   certInfoPtr->serialNumberLength ) ) );
	}

int writeOCSPv1ID( STREAM *stream, const CERT_INFO *certInfoPtr, 
				   const void *issuerKeyHash )
	{
	HASHFUNCTION hashFunction;
	BYTE hashBuffer[ CRYPT_MAX_HASHSIZE ];
	int hashSize;

	/* Get the issuerName hash */
	getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );
	hashFunction( NULL, hashBuffer, certInfoPtr->issuerDNptr, 
				  certInfoPtr->issuerDNsize, HASH_ALL );

	/* Write the request data */
	writeSequence( stream, sizeofAlgoID( CRYPT_ALGO_SHA ) + \
						   sizeofObject( hashSize ) + \
						   sizeofObject( hashSize ) + \
						   sizeofInteger( certInfoPtr->serialNumber, 
										  certInfoPtr->serialNumberLength ) );
	writeAlgoID( stream, CRYPT_ALGO_SHA );
	writeOctetString( stream, hashBuffer, hashSize, DEFAULT_TAG );
	writeOctetString( stream, issuerKeyHash, KEYID_SIZE, DEFAULT_TAG );
	return( writeInteger( stream, certInfoPtr->serialNumber, 
						  certInfoPtr->serialNumberLength, DEFAULT_TAG ) );
	}

/****************************************************************************
*																			*
*								Read/Write CMS Data							*
*																			*
****************************************************************************/

/* Read signed attributes */

int readCMSAttributes( STREAM *stream, CERT_INFO *attributeInfoPtr )
	{
	/* CMS attributes are straight attribute objects so we just pass the call
	   through */
	return( readAttributes( stream, &attributeInfoPtr->attributes,
							CRYPT_CERTTYPE_CMS_ATTRIBUTES, CRYPT_UNUSED,
							&attributeInfoPtr->errorLocus,
							&attributeInfoPtr->errorType ) );
	}

/* Write signed attributes */

int writeCMSAttributes( STREAM *stream, CERT_INFO *attributeInfoPtr )
	{
	ATTRIBUTE_LIST *attributeListPtr;
	int addDefaultAttributes, attributeSize, status;

	krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE, 
					 RESOURCE_IMESSAGE_GETATTRIBUTE, &addDefaultAttributes, 
					 CRYPT_OPTION_CMS_DEFAULTATTRIBUTES );

	/* Make sure there's a hash and content type present */
	if( findAttributeField( attributeInfoPtr->attributes,
							CRYPT_CERTINFO_CMS_MESSAGEDIGEST,
							CRYPT_ATTRIBUTE_NONE ) == NULL )
		{
		setErrorInfo( attributeInfoPtr, CRYPT_CERTINFO_CMS_MESSAGEDIGEST,
					  CRYPT_ERRTYPE_ATTR_ABSENT );
		return( CRYPT_ERROR_INVALID );
		}
	attributeListPtr = findAttribute( attributeInfoPtr->attributes,
									  CRYPT_CERTINFO_CMS_CONTENTTYPE );
	if( attributeListPtr == NULL )
		{
		const int value = CRYPT_CONTENT_DATA;

		/* If there's no content type and we're not adding it automatically,
		   complain */
		if( !addDefaultAttributes )
			{
			setErrorInfo( attributeInfoPtr, CRYPT_CERTINFO_CMS_CONTENTTYPE,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			return( CRYPT_ERROR_INVALID );
			}

		/* There's no content type present, treat it as straight data (which
		   means this is signedData) */
		status = addCertComponent( attributeInfoPtr, CRYPT_CERTINFO_CMS_CONTENTTYPE,
								   &value, CRYPT_UNUSED );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* If there's no signing time attribute present and we're adding the
	   default attributes, add it now */
	if( addDefaultAttributes && \
		( attributeListPtr = findAttribute( attributeInfoPtr->attributes,
							CRYPT_CERTINFO_CMS_SIGNINGTIME ) ) == NULL )
		{
		const time_t currentTime = time( NULL );

		status = addCertComponent( attributeInfoPtr, CRYPT_CERTINFO_CMS_SIGNINGTIME,
								   &currentTime, sizeof( time_t ) );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Check that the attributes are in order and determine how big the whole
	   mess will be */
	status = checkAttributes( ATTRIBUTE_CMS, attributeInfoPtr->attributes,
							  &attributeInfoPtr->errorLocus,
							  &attributeInfoPtr->errorType );
	if( cryptStatusError( status ) )
		return( status );
	attributeSize = sizeofAttributes( attributeInfoPtr->attributes );

	/* Write the attributes */
	return( writeAttributes( stream, attributeInfoPtr->attributes,
							 CRYPT_CERTTYPE_CMS_ATTRIBUTES, attributeSize ) );
	}

/****************************************************************************
*																			*
*						Read/Write PKI Userinfo Data						*
*																			*
****************************************************************************/

/* The size of the binary authenticator information before checksumming and
   encoding */

#define PKIUSER_AUTHENTICATOR_SIZE		12

/* The size of the encrypted user info: 
   sizeofObject( 2 * sizeofObject( PKIUSER_AUTHENTICATOR_SIZE ) ) + PKCS #5 
   padding = 2 + ( 2 + 12 + 2 + 12 ) = 30 + 2 = 32.  This works for both 64- 
   and 128-bit block ciphers */

#define ENCRYPTED_AUTHENTICATOR_SIZE	32

/* Read PKI user info */

int readPKIUserInfo( STREAM *stream, CERT_INFO *userInfoPtr )
	{
	CRYPT_CONTEXT iCryptContext;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	QUERY_INFO queryInfo;
	STREAM userInfoStream;
	BYTE userInfo[ 128 ];
	int userInfoSize, length, status;

	/* Read the user name and encryption algorithm info and the start of the 
	   encrypted data */
	userInfoPtr->subjectDNptr = sMemBufPtr( stream );
	userInfoPtr->subjectDNsize = ( int ) stell( stream );
	status = readDN( stream, &userInfoPtr->subjectName );
	userInfoPtr->subjectDNsize = ( int ) stell( stream ) - userInfoPtr->subjectDNsize;
	if( cryptStatusOK( status ) )
		status = readContextAlgoID( stream, NULL, &queryInfo, DEFAULT_TAG );
	if( cryptStatusOK( status ) )
		status = readOctetString( stream, userInfo, &userInfoSize, 128 );
	if( cryptStatusError( status ) )
		return( status );
	if( userInfoSize != ENCRYPTED_AUTHENTICATOR_SIZE )
		return( CRYPT_ERROR_BADDATA );

	/* Clone the CA key for our own use, load the IV from the encryption 
	   info, and use the cloned context to decrypt the user info.  We need to 
	   do this to prevent problems if multiple threads try to simultaneously 
	   decrypt with the CA key.  Since user objects aren't fully implemented 
	   yet, we use a fixed key as the CA key for now */
	setMessageCreateObjectInfo( &createInfo, queryInfo.cryptAlgo );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,

⌨️ 快捷键说明

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