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

📄 chk_use.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*																			*
*						Certificate Usage Checking Routines					*
*						Copyright Peter Gutmann 1997-2007					*
*																			*
****************************************************************************/

#if defined( INC_ALL )
  #include "cert.h"
  #include "certattr.h"
#else
  #include "cert/cert.h"
  #include "cert/certattr.h"
#endif /* Compiler-specific includes */

/****************************************************************************
*																			*
*						ExtKeyUsage to Key Usage Routines					*
*																			*
****************************************************************************/

/* The following keyUsage settings are used based on extendedKeyUsage and
   Netscape key usage extensions.  In the following 'Y' = required, 'w' =
   written but apparently not required, S = for signature keys only, E = for
   encryption keys only, KA = for key agreement keys only.

						dig	non	key	dat	key	cer	crl	enc	dec
						sig	rep	enc	enc	agt	sig	sig	onl	onl
   PKIX:				-----------------------------------
	serverAuth			 S		 E		KA					[1]
	clientAuth			 S
	codeSign			 Y
	email				 Y	 Y	 E
	ipsecEndSys			 S		 E		KA
	ipsecTunnel			 S		 E		KA
	ipsecUser			 S		 E		KA
	timeStamping		 Y	 Y
	ocsp				 Y
	directoryService	 ?
   MS:					-----------------------------------
	individualCodeSign	 Y
	commercialCodeSign	 Y
	ctlSign				 Y
	tsa					 Y
	sgc							 E
	encryptedFS					 E
   NS:					-----------------------------------
	sgc							 E
   NS extensions:		-----------------------------------
	sslClient			 Y
	sslServer			 S		 E							[1]
	sMime				 S		 E
	objectSign			 Y
	sslCA                               	 Y	 w
	sMimeCA									 Y	 w
	objectSignCA							 Y	 w
						-----------------------------------
						dig	non	key	dat	key	cer	crl	enc	dec
						sig	rep	enc	enc	agt	sig	sig	onl	onl

   [1] These keys need to potentially perform both decryption for RSA key 
       transport and signing for (authenticating) DH key agreement */

/* Masks for various key usage types */

#define USAGE_SIGN_MASK			( CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
								  CRYPT_KEYUSAGE_NONREPUDIATION | \
								  CRYPT_KEYUSAGE_KEYCERTSIGN | \
								  CRYPT_KEYUSAGE_CRLSIGN )
#define USAGE_CRYPT_MASK		( CRYPT_KEYUSAGE_KEYENCIPHERMENT | \
								  CRYPT_KEYUSAGE_DATAENCIPHERMENT )
#define USAGE_KEYAGREEMENT_MASK	( CRYPT_KEYUSAGE_KEYAGREEMENT | \
								  CRYPT_KEYUSAGE_ENCIPHERONLY | \
								  CRYPT_KEYUSAGE_DECIPHERONLY )

/* Mask for key usage types that we don't check for consistency against
   extended key usages.  The two CA usages don't occur in extended key usage,
   and no-one can agree on what non-repudiation is supposed to mean */

#define USAGE_MASK_NONRELEVANT	( CRYPT_KEYUSAGE_NONREPUDIATION | \
								  CRYPT_KEYUSAGE_KEYCERTSIGN | \
								  CRYPT_KEYUSAGE_CRLSIGN )

/* Flags to denote the algorithm type */

#define ALGO_TYPE_NONE			0
#define ALGO_TYPE_SIGN			1
#define ALGO_TYPE_CRYPT			2
#define ALGO_TYPE_KEYAGREEMENT	4
#define ALGO_TYPE_FLAG_NONE		0		/* Defines for range checking */
#define ALGO_TYPE_FLAG_MAX		0x07

/* Table mapping extended key usage values to key usage flags */

typedef struct {
	const CRYPT_ATTRIBUTE_TYPE usageType;
	const int keyUsageFlags;
	} EXT_USAGE_INFO;
	
static const EXT_USAGE_INFO FAR_BSS extendedUsageInfo[] = {
	{ CRYPT_CERTINFO_EXTKEY_MS_INDIVIDUALCODESIGNING,/* individualCodeSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_MS_COMMERCIALCODESIGNING,/* commercialCodeSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_MS_CERTTRUSTLISTSIGNING,/* certTrustListSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_MS_TIMESTAMPSIGNING,	/* timeStampSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_MS_SERVERGATEDCRYPTO,	/* serverGatedCrypto */
	  CRYPT_KEYUSAGE_KEYENCIPHERMENT },
	{ CRYPT_CERTINFO_EXTKEY_MS_ENCRYPTEDFILESYSTEM,	/* encrypedFileSystem */
	  CRYPT_KEYUSAGE_KEYENCIPHERMENT },
	{ CRYPT_CERTINFO_EXTKEY_SERVERAUTH,				/* serverAuth */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_CLIENTAUTH,				/* clientAuth */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_CODESIGNING,			/* codeSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_EMAILPROTECTION,		/* emailProtection */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_NONREPUDIATION },
	{ CRYPT_CERTINFO_EXTKEY_IPSECENDSYSTEM,			/* ipsecEndSystem */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_IPSECTUNNEL,			/* ipsecTunnel */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_IPSECUSER,				/* ipsecUser */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_TIMESTAMPING,			/* timeStamping */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_NONREPUDIATION },
	{ CRYPT_CERTINFO_EXTKEY_OCSPSIGNING,			/* ocspSigning */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_DIRECTORYSERVICE,		/* directoryService */
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_CERTINFO_EXTKEY_NS_SERVERGATEDCRYPTO,	/* serverGatedCrypto */
	  CRYPT_KEYUSAGE_KEYENCIPHERMENT },
	{ CRYPT_ATTRIBUTE_NONE, 0 }
	};

/* Table mapping Netscape certificate-type flags to extended key usage 
   flags */

typedef struct {
	const int certType;
	const int keyUsageFlags;
	} CERT_TYPE_INFO;
	
static const CERT_TYPE_INFO FAR_BSS certTypeInfo[] = {
	{ CRYPT_NS_CERTTYPE_SSLCLIENT,
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE },
	{ CRYPT_NS_CERTTYPE_SSLSERVER,
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_KEYENCIPHERMENT },
	{ CRYPT_NS_CERTTYPE_SMIME,
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_KEYENCIPHERMENT },
	{ CRYPT_NS_CERTTYPE_OBJECTSIGNING,
	  CRYPT_KEYUSAGE_DIGITALSIGNATURE | CRYPT_KEYUSAGE_NONREPUDIATION },
	{ CRYPT_NS_CERTTYPE_RESERVED, 0 },
	{ CRYPT_NS_CERTTYPE_SSLCA,
	  CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN },
	{ CRYPT_NS_CERTTYPE_SMIMECA,
	  CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN },
	{ CRYPT_NS_CERTTYPE_OBJECTSIGNINGCA,
	  CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN },
	{ 0, 0 }
	};

/* Build up key usage flags consistent with the extended key usage purpose.  
   We don't have to perform any special-case handling for 
   anyExtendedKeyUsage (added in RFC 3280, section 4.2.1.13) since it's a 
   no-op extension whose presence is the equivalent of adding "|| TRUE" to 
   an expression */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int getExtendedKeyUsageFlags( const ATTRIBUTE_LIST *attributes,
									 IN_FLAGS( ALGO_TYPE ) const int algorithmType,
									 OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
										CRYPT_ATTRIBUTE_TYPE *errorLocus )
	{
	int keyUsage = 0, i;

	assert( isReadPtr( attributes, sizeof( ATTRIBUTE_LIST ) ) );
	assert( isWritePtr( errorLocus, sizeof( CRYPT_ATTRIBUTE_TYPE ) ) );

	REQUIRES( algorithmType > ALGO_TYPE_FLAG_NONE && \
			  algorithmType < ALGO_TYPE_FLAG_MAX );

	/* Most certificates don't contain an extendedKeyUsage extension so 
	   rather than iterating through a long list of non-present attribute 
	   fields we perform an early-out check to see whether there's actually
	   anything to do */
	if( !checkAttributePresent( attributes, CRYPT_CERTINFO_EXTKEYUSAGE ) )
		return( 0 );

	/* There's an extendedKeyUsage extension present, build up the key usage
	   flags for it */
	for( i = 0; extendedUsageInfo[ i ].usageType != CRYPT_ATTRIBUTE_NONE && \
				i < FAILSAFE_ARRAYSIZE( extendedUsageInfo, EXT_USAGE_INFO ); 
		 i++ )
		{
		const ATTRIBUTE_LIST *attributeListPtr = \
					findAttributeField( attributes, extendedUsageInfo[ i ].usageType, 
										CRYPT_ATTRIBUTE_NONE );
		int extendedUsage = 0;

		/* If this usage isn't present, continue */
		if( attributeListPtr == NULL )
			continue;

		/* If the usage is consistent with the algorithm type, add it */
		if( algorithmType & ALGO_TYPE_SIGN )
			extendedUsage |= extendedUsageInfo[ i ].keyUsageFlags & USAGE_SIGN_MASK;
		if( algorithmType & ALGO_TYPE_CRYPT )
			extendedUsage |= extendedUsageInfo[ i ].keyUsageFlags & USAGE_CRYPT_MASK;
		if( algorithmType & ALGO_TYPE_KEYAGREEMENT )
			extendedUsage |= extendedUsageInfo[ i ].keyUsageFlags & USAGE_KEYAGREEMENT_MASK;

		/* If there's no key usage consistent with the extended usage and the
		   extended usage isn't some special-case usage, return an error */
		if( extendedUsage == 0 && extendedUsageInfo[ i ].keyUsageFlags != 0 )
			{
			*errorLocus = extendedUsageInfo[ i ].usageType;
			return( CRYPT_ERROR_INVALID );
			}

		keyUsage |= extendedUsage;
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( extendedUsageInfo, EXT_USAGE_INFO ) );

	return( keyUsage );
	}

/* Build up key usage flags consistent with the Netscape certificate-type 
   purpose */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int getNetscapeCertTypeFlags( const ATTRIBUTE_LIST *attributes,
									 IN_FLAGS( ALGO_TYPE ) const int algorithmType,
									 OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
										CRYPT_ATTRIBUTE_TYPE *errorLocus )
	{
	const ATTRIBUTE_LIST *attributeListPtr = \
				findAttributeField( attributes, CRYPT_CERTINFO_NS_CERTTYPE, 
									CRYPT_ATTRIBUTE_NONE );
	int nsCertType, keyUsage = 0, i;

	assert( isReadPtr( attributes, sizeof( ATTRIBUTE_LIST ) ) );
	assert( isWritePtr( errorLocus, sizeof( CRYPT_ATTRIBUTE_TYPE ) ) );

	REQUIRES( algorithmType > ALGO_TYPE_FLAG_NONE && \
			  algorithmType < ALGO_TYPE_FLAG_MAX );

	/* If there isn't a Netscape certificate-type extension present, exit */
	if( attributeListPtr == NULL )
		return( 0 );
	nsCertType = ( int ) attributeListPtr->intValue;

	/* The Netscape certificate-type value is a bitfield containing the 
	   different certificate types.  For each certificate-type flag that's 
	   set we set the corresponding keyUsage flags */
	for( i = 0; certTypeInfo[ i ].certType && \
				i < FAILSAFE_ARRAYSIZE( certTypeInfo, CERT_TYPE_INFO ); i++ )
		{
		int nsUsage = 0;

		/* If this isn't the currently-selected certificate-type, continue */
		if( !( nsCertType & certTypeInfo[ i ].certType ) )
			continue;

		/* If the usage is consistent with the algorithm type, add it */
		if( algorithmType & ALGO_TYPE_SIGN )
			nsUsage |= certTypeInfo[ i ].keyUsageFlags & USAGE_SIGN_MASK;
		if( algorithmType & ALGO_TYPE_CRYPT )
			nsUsage |= certTypeInfo[ i ].keyUsageFlags & USAGE_CRYPT_MASK;

⌨️ 快捷键说明

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