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

📄 certdn.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*																			*
*							Certificate DN Routines							*
*						Copyright Peter Gutmann 1996-2002					*
*																			*
****************************************************************************/

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#if defined( INC_ALL ) ||  defined( INC_CHILD )
  #include "cert.h"
  #include "../misc/asn1_rw.h"
#else
  #include "cert/cert.h"
  #include "misc/asn1_rw.h"
#endif /* Compiler-specific includes */

/* DN component info flags.  Some implementations may place more than one
   AVA into a RDN.  In this case we set a flag to indicate that the RDN
   continues in the next DN component structure.  If the RDN/DN was set by
   specifying the entire DN at once using a free-format text DN string, it's
   not a good idea to allow random changes to it so we mark the components
   as locked.  If we're reading data from an external source the DN can
   contain all sorts of strange stuff, so we set a flag to tell the DN
   component-handling code not to perform any validity checking on the
   components as they're added */

#define DN_FLAG_CONTINUED	0x01	/* RDN continues with another AVA */
#define DN_FLAG_LOCKED		0x02	/* RDN can't be modified */
#define DN_FLAG_NOCHECK		0x04	/* Don't check validity of components */

/* The structure to hold a DN component */

typedef struct DC {
	/* DN component type and type information */
	CRYPT_ATTRIBUTE_TYPE type;		/* cryptlib component type */
	const void *typeInfo;			/* Type info for this component */
	int flags;

	/* DN component data */
	void *value;					/* DN component value */
	int valueLength;				/* DN component valu elength */

	/* Encoding information: The overall size of the RDN data (without the
	   tag and length) if this is the first or only component of an RDN, and
	   the size of the AVA data */
	int encodedRDNdataSize, encodedAVAdataSize;

	/* The next and previous list element in the linked list of DN
	   components */
	struct DC *next, *prev;

	/* Variable-length storage for the DN data */
	DECLARE_VARSTRUCT_VARS;
	} DN_COMPONENT;

/****************************************************************************
*																			*
*							DN Information Tables							*
*																			*
****************************************************************************/

/* The sort order for DN components */

static int dnSortTable[] = {
	0,								/* countryName */
	1,								/* stateOrProvinceName */
	2,								/* locationName */
	3,								/* organizationName */
	4,								/* organizationalUnitName */
	5								/* commonName */
	};

#define dnSortOrder( value )	\
		dnSortTable[ ( value ) - CRYPT_CERTINFO_COUNTRYNAME ]

/* A macro to make make declaring DN OID's simpler */

#define MKDNOID( value )	( ( const BYTE * ) "\x06\x03" value )

/* Type information for DN components */

typedef struct {
	const CRYPT_ATTRIBUTE_TYPE type;/* cryptlib type */
	const BYTE *oid;				/* OID for this type */
	const char *name, *altName;		/* Name for this type */
	const int maxLength;			/* Maximum allowed length for this type */
	const BOOLEAN ia5OK;			/* Whether IA5 is allowed for this comp.*/
	const BOOLEAN wcsOK;			/* Whether widechar is allowed for comp.*/
	} DN_COMPONENT_INFO;

static const FAR_BSS DN_COMPONENT_INFO certInfoOIDs[] = {
	/* Useful components */
	{ CRYPT_CERTINFO_COMMONNAME, MKDNOID( "\x55\x04\x03" ), "cn", "oid.2.5.4.3", CRYPT_MAX_TEXTSIZE, FALSE, TRUE },
	{ CRYPT_CERTINFO_COUNTRYNAME, MKDNOID( "\x55\x04\x06" ), "c", "oid.2.5.4.6", 2, FALSE, FALSE },
	{ CRYPT_CERTINFO_LOCALITYNAME, MKDNOID( "\x55\x04\x07" ), "l", "oid.2.5.4.7", 128, FALSE, TRUE },
	{ CRYPT_CERTINFO_STATEORPROVINCENAME, MKDNOID( "\x55\x04\x08" ), "sp", "oid.2.5.4.8", 128, FALSE, TRUE },
	{ CRYPT_CERTINFO_ORGANIZATIONNAME, MKDNOID( "\x55\x04\x0A" ), "o", "oid.2.5.4.10", CRYPT_MAX_TEXTSIZE, FALSE, TRUE },
	{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, MKDNOID( "\x55\x04\x0B" ), "ou", "oid.2.5.4.11", CRYPT_MAX_TEXTSIZE, FALSE, TRUE },

	/* Non-useful components */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x01" ), "oid.2.5.4.1", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* aliasObjectName (2 5 4 1) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x02" ), "oid.2.5.4.2", NULL, MAX_ATTRIBUTE_SIZE /*32768*/, FALSE, FALSE },
							/* knowledgeInformation (2 5 4 2) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x04" ), "s", "oid.2.5.4.4", CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* surname (2 5 4 4) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x05" ), "sn", "oid.2.5.4.5", CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* serialNumber (2 5 4 5) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x09" ), "st", "oid.2.5.4.9", 128, FALSE, FALSE },
							/* streetAddress (2 5 4 9) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x0C" ), "t", "oid.2.5.4.12", CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* title (2 5 4 12) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x0D" ), "d", "oid.2.5.4.13", 1024, FALSE, FALSE },
							/* description (2 5 4 13) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x0E" ), "oid.2.5.4.14", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* searchGuide (2 5 4 14) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x0F" ), "bc", "oid.2.5.4.15", 128, FALSE, FALSE },
							/* businessCategory (2 5 4 15) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x10" ), "oid.2.5.4.16", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* postalAddress (2 5 4 16) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x11" ), "oid.2.5.4.17", NULL, 40, FALSE, FALSE },
							/* postalCode (2 5 4 17) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x12" ), "oid.2.5.4.18", NULL, 40, FALSE, FALSE },
							/* postOfficeBox (2 5 4 18) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x13" ), "oid.2.5.4.19", NULL, 128, FALSE, FALSE },
							/* physicalDeliveryOfficeName (2 5 4 19) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x14" ), "oid.2.5.4.20", NULL, 32, FALSE, FALSE },
							/* telephoneNumber (2 5 4 20) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x15" ), "oid.2.5.4.21", NULL, 14, FALSE, FALSE },
							/* telexNumber (2 5 4 21) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x16" ), "oid.2.5.4.22", NULL, 24, FALSE, FALSE },
							/* teletexTerminalIdentifier (2 5 4 22) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x17" ), "oid.2.5.4.23", NULL, 32, FALSE, FALSE },
							/* facsimileTelephoneNumber (2 5 4 23) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x18" ), "oid.2.5.4.24", NULL, 15, FALSE, FALSE },
							/* x121Address (2 5 4 24) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x19" ), "isdn", "oid.2.5.4.25", 16, FALSE, FALSE },
							/* internationalISDNNumber (2 5 4 25) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1A" ), "oid.2.5.4.26", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* registeredAddress (2 5 4 26) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1B" ), "oid.2.5.4.27", NULL, 128, FALSE, FALSE },
							/* destinationIndicator (2 5 4 27) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1C" ), "oid.2.5.4.28", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* preferredDeliveryMethod (2 5 4 28) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1D" ), "oid.2.5.4.29", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* presentationAddress (2 5 4 29) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1E" ), "oid.2.5.4.30", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* supportedApplicationContext (2 5 4 30) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x1F" ), "oid.2.5.4.31", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* member (2 5 4 31) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x20" ), "oid.2.5.4.32", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* owner (2 5 4 32) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x21" ), "oid.2.5.4.33", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* roleOccupant (2 5 4 33) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x22" ), "oid.2.5.4.34", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* seeAlso (2 5 4 34) */
							/* 0x23-0x28 are certs/CRLs and some weird encrypted directory components */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x29" ), "oid.2.5.4.41", NULL, MAX_ATTRIBUTE_SIZE /*32768*/, FALSE, FALSE },
							/* name (2 5 4 41) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x2A" ), "g", "oid.2.5.4.42", CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* givenName (2 5 4 42) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x2B" ), "i", "oid.2.5.4.43", CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* initials (2 5 4 43) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x2C" ), "oid.2.5.4.44", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* generationQualifier (2 5 4 44) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x2D" ), "oid.2.5.4.45", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* uniqueIdentifier (2 5 4 45) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x2E" ), "oid.2.5.4.46", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* dnQualifier (2 5 4 46) */
							/* 0x2F-0x30 are directory components */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x31" ), "oid.2.5.4.49", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* distinguishedName (2 5 4 49) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x32" ), "oid.2.5.4.50", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* uniqueMember (2 5 4 50) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x33" ), "oid.2.5.4.51", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* houseIdentifier (2 5 4 51) */
							/* 0x34-0x3A are more certs and weird encrypted directory components */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x41" ), "oid.2.5.4.65", NULL, 128, FALSE, FALSE },
							/* pseudonym (2 5 4 65) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x42" ), "oid.2.5.4.66", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* communicationsService (2 5 4 66) */
	{ CRYPT_ATTRIBUTE_NONE, MKDNOID( "\x55\x04\x43" ), "oid.2.5.4.67", NULL, CRYPT_MAX_TEXTSIZE, FALSE, FALSE },
							/* communicationsNetwork (2 5 4 67) */
							/* 0x44-0x49 are more PKI-related attributes */
	{ CRYPT_ATTRIBUTE_NONE, ( const BYTE * ) "\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01", "uid", NULL, CRYPT_MAX_TEXTSIZE, TRUE, FALSE },
							/* userid (0 9 2342 19200300 100 1 1) */
	{ CRYPT_ATTRIBUTE_NONE, ( const BYTE * ) "\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x03", "oid.0.9.2342.19200300.100.1.3", NULL, CRYPT_MAX_TEXTSIZE, TRUE, FALSE },
							/* rfc822Mailbox (0 9 2342 19200300 100 1 3) */
	{ CRYPT_ATTRIBUTE_NONE, ( const BYTE * ) "\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19", "dc", "oid.0.9.2342.19200300.100.1.25", CRYPT_MAX_TEXTSIZE, TRUE, FALSE },
							/* domainComponent (0 9 2342 19200300 100 1 25) */
	{ CRYPT_ATTRIBUTE_NONE, ( const BYTE * ) "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01", "email", "oid.1.2.840.113549.1.9.1", CRYPT_MAX_TEXTSIZE, TRUE, FALSE },
							/* emailAddress (1 2 840 113549 1 9 1) */
	{ CRYPT_ATTRIBUTE_NONE, ( const BYTE * ) "\x06\x07\x02\x82\x06\x01\x0A\x07\x14", "oid.0.2.262.1.10.7.20", NULL, CRYPT_MAX_TEXTSIZE, TRUE, FALSE },
							/* nameDistinguisher (0 2 262 1 10 7 20) */

	{ CRYPT_ATTRIBUTE_NONE, NULL }
	} ;

/* If the OID doesn't correspond to a valid cryptlib component (i.e. it's one
   of the 1,001 other odd things which can be crammed into a DN), we can't
   directly identify it with a type but instead return the index in the OID
   info table, offset by a suitable amount */

#define DN_OID_OFFSET	10000

/* Check that a country code is valid */

#define xA	( 1 << 0 )
#define xB	( 1 << 1 )
#define xC	( 1 << 2 )
#define xD	( 1 << 3 )
#define xE	( 1 << 4 )
#define xF	( 1 << 5 )
#define xG	( 1 << 6 )
#define xH	( 1 << 7 )
#define xI	( 1 << 8 )
#define xJ	( 1 << 9 )
#define xK	( 1 << 10 )
#define xL	( 1 << 11 )
#define xM	( 1 << 12 )
#define xN	( 1 << 13 )
#define xO	( 1 << 14 )
#define xP	( 1 << 15 )
#define xQ	( 1 << 16 )
#define xR	( 1 << 17 )
#define xS	( 1 << 18 )
#define xT	( 1 << 19 )
#define xU	( 1 << 20 )
#define xV	( 1 << 21 )
#define xW	( 1 << 22 )
#define xX	( 1 << 23 )
#define xY	( 1 << 24 )
#define xZ	( 1 << 25 )

static BOOLEAN checkCountryCode( const char *countryCode )
	{
	static const long countryCodes[] = {	/* ISO 3166 code table */
	/*	 A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z */
  /*A*/			 xD|xE|xF|xG|	xI|		 xL|xM|xN|xO|	xQ|xR|xS|xT|xU|	  xW|	   xZ,
  /*B*/	xA|xB|	 xD|xE|xF|xG|xH|xI|xJ|		xM|xN|xO|	   xR|xS|xT|   xV|xW|	xY|xZ,
  /*C*/	xA|	  xC|xD|   xF|xG|xH|xI|	  xK|xL|xM|xN|xO|	   xR|		xU|xV|	 xX|xY|xZ,
  /*D*/				xE|			   xJ|xK|	xM|	  xO|							   xZ,
  /*E*/		  xC|	xE|	  xG|xH|						   xR|xS|xT,
  /*F*/							xI|xJ|xK|	xM|	  xO|	   xR,
  /*G*/	xA|xB|	 xD|xE|xF|	 xH|xI|		 xL|xM|xN|	 xP|xQ|xR|xS|xT|xU|	  xW|	xY,
  /*H*/								  xK|	xM|xN|		   xR|	 xT|xU,
  /*I*/			 xD|xE|					 xL|   xN|xO|	xQ|xR|xS|xT,
  /*J*/										xM|	  xO|xP,
  /*K*/				xE|	  xG|xH|xI|			xM|xN|	 xP|   xR|			  xW|	xY|xZ,
  /*L*/	xA|xB|xC|				xI|	  xK|				   xR|xS|xT|xU|xV|		xY,
  /*M*/	xA|	  xC|xD|	  xG|xH|	  xK|xL|xM|xN|xO|xP|xQ|xR|xS|xT|xU|xV|xW|xX|xY|xZ,
  /*N*/	xA|	  xC|	xE|xF|xG|	xI|		 xL|	  xO|xP|   xR|		xU|			   xZ,
  /*O*/										xM,
  /*P*/	xA|			xE|xF|xG|xH|	  xK|xL|xM|xN|		   xR|xS|xT|	  xW|	xY,
  /*Q*/	xA,
  /*R*/				xE|							  xO|				xU|	  xW,
  /*S*/	xA|xB|xC|xD|xE|	  xG|xH|xI|xJ|xK|xL|xM|xN|xO|	   xR|	 xT|   xV|		xY|xZ,
  /*T*/		  xC|xD|   xF|xG|xH|   xJ|xK|xL|xM|xN|xO|	   xR|	 xT|   xV|xW|	   xZ,
  /*U*/	xA|				  xG|				xM|				  xS|				xY|xZ,
  /*V*/	xA|	  xC|	xE|	  xG|	xI|			   xN|					xU,
  /*W*/				   xF|									  xS,
  /*X*/	0,
  /*Y*/				xE|											 xT|xU,
  /*Z*/	xA|									xM|							  xW,
		0, 0	/* Catch overflows */
		};
	const int cc0 = countryCode[ 0 ] - 'A';
	const int cc1 = countryCode[ 1 ] - 'A';

	/* Check that the country code is present in the table of valid ISO 3166
	   codes */
	if( cc0 < 0 || cc0 > 25 || cc1 < 0 || cc1 > 25 )
		return( FALSE );
	return( ( countryCodes[ cc0 ] & ( 1 << cc1 ) ) ? TRUE : FALSE );
	}

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

/* Find a DN component in a DN component list by type and by OID */

static DN_COMPONENT *findDNComponent( const void *dnListHead,
									  const CRYPT_ATTRIBUTE_TYPE type,
									  const void *value,
									  const int valueLength )
	{
	DN_COMPONENT *listPtr = ( DN_COMPONENT * ) dnListHead;

	/* Find the position of this component in the list */
	while( listPtr != NULL )
		{
		assert( isReadPtr( listPtr, DN_COMPONENT ) );

		if( listPtr->type == type && \
			( ( value == NULL ) || \
			  ( listPtr->valueLength == valueLength && \
				!memcmp( listPtr->value, value, valueLength ) ) ) )
			break;
		listPtr = listPtr->next;
		}

	return( listPtr );
	}

static DN_COMPONENT *findDNComponentByOID( const void *dnListHead,
										   const BYTE *oid )
	{
	DN_COMPONENT *listPtr = ( DN_COMPONENT * ) dnListHead;
	const int oidLen = sizeofOID( oid );

	/* Find the position of this component in the list */
	while( listPtr != NULL )
		{
		const DN_COMPONENT_INFO *dnComponentInfo = listPtr->typeInfo;

		if( !memcmp( dnComponentInfo->oid, oid, oidLen ) )
			break;
		listPtr = listPtr->next;
		}

	return( listPtr );
	}

/****************************************************************************
*																			*
*								Insert/Delete DNs							*
*																			*

⌨️ 快捷键说明

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