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

📄 cert.h

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 H
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*																			*
*				Certificate Management Structures and Prototypes 			*
*						Copyright Peter Gutmann 1996-2002					*
*																			*
****************************************************************************/

#ifndef _CERT_DEFINED

#define _CERT_DEFINED

#include <time.h>
#ifndef _STREAM_DEFINED
  #if defined( INC_ALL ) || defined( INC_CHILD )
	#include "stream.h"
  #else
	#include "keymgmt/stream.h"
  #endif /* Compiler-specific includes */
#endif /* _STREAM_DEFINED */

/* The character set (or at least ASN.1 string type) for a string.  Sometimes
   we can be fed Unicode strings which are just bloated versions of another
   string type, so we need to account for these as well.  In addition we may
   have an 8859-1 string which can't be encoded in the given type, so we mark
   it as needing conversion to Unicode.  Note that the value for the Unicode
   variant of the basic type must follow the value for the base type since
   the conversion code uses this relationship when reporting the string type.

   Although IA5String and VisibleString/ISO646String are technically
   different, the only real difference is that IA5String allows the full
   range of control characters, which isn't notably useful.  For this reason
   we treat both as ISO646String.

   UTF-8 strings are a pain because they're not supported as any native
   format and aren't needed because almost anything they can do is covered by
   a more sensible character set.  For this reason we currently convert them
   to a more sensible set (ASCII, 8859-1, or Unicode as appropriate) to make
   them usable.  UTF-8 strings are never written */

typedef enum {
	STRINGTYPE_NONE,					/* No string type */
	STRINGTYPE_PRINTABLE,				/* PrintableString */
	STRINGTYPE_UNICODE_PRINTABLE,		/* PrintableString as Unicode */
	STRINGTYPE_IA5,						/* IA5String */
		STRINGTYPE_VISIBLE = STRINGTYPE_IA5,	/* VisibleString */
	STRINGTYPE_UNICODE_IA5,				/* IA5String as Unicode */
		STRINGTYPE_UNICODE_VISIBLE = STRINGTYPE_UNICODE_IA5,
										/* VisibleString as Unicode */
	STRINGTYPE_T61,						/* T61 (8859-1) string */
	STRINGTYPE_UNICODE_T61,				/* T61String as Unicode */
	STRINGTYPE_UNICODE,					/* Unicode string */
	STRINGTYPE_T61_UNICODE,				/* Unicode as T61 string */
	STRINGTYPE_UTF8						/* UTF-8 string (never written) */
	} ASN1_STRINGTYPE;

/* The minimum size of an attribute, SEQUENCE (2), OID (5),
   OCTET STRING (2+3 for payload).  This is the amount of slop to allow when
   reading attributes.  Some software gets the length encoding wrong by a few
   bytes, if what's left at the end of an encoded object is >= this value
   then we look for attributes */

#define MIN_ATTRIBUTE_SIZE		12

/* The maximum size of a PKCS #7 certificate chain */

#define MAX_CHAINLENGTH			16

/* Attribute information flags.  The invalid flag is used to catch accidental
   use of a boolean value for the flag, the critical flag is used to indicate 
   that the extension is marked criticial, the blob flag is used to disable 
   type-checking on the field (needed to handle some certs which have invalid 
   field encodings), the multivalued flag is used to indicate that multiple 
   instantiations of this field are valid, and the default value flag
   indicates that the field has a value which is equal to the default for
   this field, so it doesn't get encoded (this flags is set during the
   encoding preprocessing pass) */

#define ATTR_FLAG_NONE			0x00	/* No flag */
#define ATTR_FLAG_INVALID		0x01	/* To catch use of TRUE */
#define ATTR_FLAG_CRITICAL		0x02	/* Critical cert extension */
#define ATTR_FLAG_BLOB			0x04	/* Non-type-checked blob data */
#define ATTR_FLAG_MULTIVALUED	0x08	/* Multiple instances allowed */
#define ATTR_FLAG_DEFAULTVALUE	0x10	/* Field has default value */

/* Certificate information flags.  The xxx_checked flags are used to cache 
   the check of the cert signature, and all fields which aren't affected by 
   the issuer cert since it's only necessary to perform this once when the 
   cert is imported or checked for the first time.  The data-only flag 
   indicates a pure data object with no attached context */

#define CERT_FLAG_NONE			0x00	/* No flag */
#define CERT_FLAG_SELFSIGNED	0x01	/* Certificate is self-signed */
#define CERT_FLAG_SIGCHECKED	0x02	/* Signature has been checked */
#define CERT_FLAG_CERTCHECKED	0x04	/* Cert fields have been checked */
#define CERT_FLAG_DATAONLY		0x08	/* Cert is data-only (no context) */

/****************************************************************************
*																			*
*							Certificate Data Structures						*
*																			*
****************************************************************************/

/* The structure to hold a field of a certificate attribute */

typedef struct AL {
	/* Identification and encoding information for this attribute field or
	   attribute.  This consists of the field ID for the attribute as a
	   whole, for the attribute field (that is, a field of an attribute, not
	   an attribute field) and for the subfield of the attribute field in the
	   case of composite fields like GeneralName's, a pointer to the sync
	   point used when encoding the attribute, and the encoded size of this
	   field.  If it's a special-case attribute field, the attributeID and
	   fieldID are set to special values decoded by the isXXX() macros
	   further down.  The subFieldID is only set if the fieldID is for a
	   GeneralName field

	   Although the field type information is contained in the
	   attributeInfoPtr, it's sometimes needed before this has been set up
	   to handle special formatting requirements (for example to enable
	   special-case handling for a DN attribute field or to specify that an
	   OID needs to be decoded into its string representation before being
	   returned to the caller).  Because of this we store the field type here
	   to allow for this special processing */
	CRYPT_ATTRIBUTE_TYPE attributeID;/* Attribute ID */
	CRYPT_ATTRIBUTE_TYPE fieldID;	/* Attribute field ID */
	CRYPT_ATTRIBUTE_TYPE subFieldID;	/* Attribute subfield ID */
	void *attributeInfoPtr;			/* Pointer to encoding sync point */
	int encodedSize;				/* Encoded size of this field */
	int fieldType;					/* Attribute field type */
	int flags;						/* Flags for this field */

	/* Sometimes a field is part of a constructed object, or even a nested
	   series of constructed objects (these are always SEQUENCEs).  Since
	   this purely an encoding issue, there are no attribute list entries for
	   the SEQUENCE fields, so when we perform the first pass over the
	   attribute list prior to encoding we remember the lengths of the
	   SEQUENCES for later use.  Since we can have nested SEQUENCEs
	   containing a given field, we store the lengths and pointers to the
	   table entries used to encode them in a fifo, with the innermost one
	   first and successive outer ones following it */
	int sizeFifo[ 10 ];				/* Encoded size of SEQUENCE containing
									   this field, if present */
	void *encodingFifo[ 10 ];		/* Encoding table entry used to encode
									   this SEQUENCE */
	int fifoEnd;					/* End of list of SEQUENCE sizes */
	int fifoPos;					/* Current position in list */

	/* The data payload for this attribute field or attribute.  If it's an
	   attribute field and the data is a simple boolean, bitstring, or small
	   integer, we store it in the value member.  If it's an OID or some form
	   of string which will fit into a small buffer we store it in the
	   smallData buffer (most attributes fall into this category).  If it's a
	   longer string or a blob-type attribute, we store it in a dynamically-
	   allocated buffer */
	long value;						/* Value for simple types */
	BYTE smallData[ CRYPT_MAX_TEXTSIZE ];
	void *data;						/* Attribute data payload */
	int dataLength;					/* Value for short objects */

	/* The OID for blob-type attributes */
	BYTE oid[ CRYPT_MAX_TEXTSIZE ];

	/* The next and previous list element in the linked list of elements */
	struct AL *next, *prev;
	} ATTRIBUTE_LIST;

/* The structure to hold the current volatile state of a certificate object:
   which certificate in a chain is selected, and which GeneralName/DN/
   attribute is selected */

typedef struct {
	int savedCertChainPos;			/* Current cert.chain position */
	CRYPT_ATTRIBUTE_TYPE savedCurrentGeneralName;	/* Current GN */
	CRYPT_ATTRIBUTE_TYPE savedCurrentDN;	/* Current DN */
	void *savedCurrentDNptr;		/* Pointer to DN start */
	ATTRIBUTE_LIST *savedAttributeCursor;	/* Atribute cursor pos.*/
	} SELECTION_STATE;

/* The structure to hold a revocation information entry (either a CRL entry
   or OCSP request/response information) */

typedef struct RI {
	/* Certificate ID information. either a serial number (for CRLs) or a
	   cert hash or issuerID (for OCSP requests/responses).  In addition
	   this could also be a pre-encoded OCSP v1 certID, which is treated as
	   an opaque blob of type CRYPT_ATTRIBUTE_NONE (it can't be used in any
	   useful way).  Usually the information fit in the data value, if it's 
	   longer than that (which can only occur with enormous serial numbers)
	   it's held in the dynamically-allocated dataPtr value */
	CRYPT_ATTRIBUTE_TYPE type;		/* ID type */
	BYTE data[ 128 ], *dataPtr;
	int dataLength;					/* ID information */

	/* Revocation information */
	int status;						/* OCSP revocation status */
	time_t revocationTime;			/* Cert revocation time */

	/* Per-entry attributes.  These are a rather ugly special case for the
	   user because, unlike the attributes for all other cert objects where
	   cryptlib can provide the illusion of a flat type<->value mapping,
	   there can be multiple sets of identical per-entry attributes present
	   if there are multiple CRL/OCSP entries present */
	ATTRIBUTE_LIST *attributes;		/* CRL/OCSP entry attributes */
	int attributeSize;				/* Encoded size of attributes */

	/* The next element in the linked list of elements */
	struct RI *next;
	} REVOCATION_INFO;

/* The structure which stores information on a certificate object */

typedef struct {
	/* General certificate information */
	CRYPT_CERTTYPE_TYPE type;		/* Certificate type */
	int flags;						/* Certificate flags */
	int version;					/* Cert object version */

	/* The encoded certificate object.  We save this when we import it
	   because there are many different interpretations of how a cert should
	   be encoded and if we parse and re-encode the cert object, the
	   signature check may fail */
	void *certificate;
	int certificateSize;

	/* The encryption context containing the key stored in this certificate */
	CRYPT_CONTEXT iCryptContext;

	/* Some certificates are data-only certificates (denoted by the 
	   CERT_FLAG_DATAONLY being set).  These constitute a container object 
	   which contains certificate-related data but no key information or 
	   copy of the encoded certificate, and are used for cert chain 
	   validation and to store cert information in a private-key context.  
	   The publicKeyInfo field contains a pointer to the start of the 
	   encoded public key info in the stored encoded certificate.  This is 
	   used where it's not known yet during the import stage whether the 
	   cert will be a data-only or standard cert (this happens when importing 
	   cert chains, when it's not known until the entire chain has been 
	   processed which cert is the leaf cert) */
	void *publicKeyInfo;			/* Public key information */

	/* General certificate object information */
	void *serialNumber;
	int serialNumberLength;			/* Certificate serial number */
	time_t startTime;				/* Validity start or update time */
	time_t endTime;					/* Validity end or next update time */
	void *issuerUniqueID, *subjectUniqueID;
	int issuerUniqueIDlength, subjectUniqueIDlength;
									/* Certificate serial number */
	/* Name fields */
	void *issuerName;				/* Issuer name */
	void *subjectName;				/* Subject name */

	/* In theory we can just copy the subject DN of a CA cert into the issuer
	   DN of a subject cert, however due to broken implementations this will
	   break chaining if we correct any problems in the DN.  Because of this
	   we need to preserve a copy of the certs subject DN so we can write it
	   as a blob to the issuer DN field of any certs it signs.  We also need
	   to remember the encoded issuer DN so we can chain upwards.

	   The following fields identify the size and location of the encoded DNs

⌨️ 快捷键说明

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