📄 cert.h
字号:
/****************************************************************************
* *
* Certificate Management Structures and Prototypes *
* Copyright Peter Gutmann 1996-2003 *
* *
****************************************************************************/
#ifndef _CERT_DEFINED
#define _CERT_DEFINED
#include <time.h>
#ifndef _STREAM_DEFINED
#if defined( INC_ALL )
#include "stream.h"
#elif defined( INC_CHILD )
#include "../misc/stream.h"
#else
#include "misc/stream.h"
#endif /* Compiler-specific includes */
#endif /* _STREAM_DEFINED */
/* 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
/* The size of the built-in serial number buffer (anything larger than this
uses a dynamically-allocated buffer) and the maximum size in bytes of a
serial number (for example in a certificate or CRL). Technically values
of any size are allowed, but anything larger than this is probably an
error */
#define SERIALNO_BUFSIZE 32
#define MAX_SERIALNO_SIZE 256
/* The size of the PKI user binary authenticator information before
checksumming and encoding, and 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 PKIUSER_AUTHENTICATOR_SIZE 12
#define PKIUSER_ENCR_AUTHENTICATOR_SIZE 32
/* 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
all type-checking on the field (needed to handle some certs that have
invalid field encodings), the blob-data flag is used to disable type
checking on the field payload (for example that the string data is valid
for the string type), 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_LOCKED 0x04 /* Field can't be modified */
#define ATTR_FLAG_BLOB 0x08 /* Non-type-checked blob data */
#define ATTR_FLAG_BLOB_PAYLOAD 0x10 /* Payload is non-type-checked blob data */
#define ATTR_FLAG_MULTIVALUED 0x20 /* Multiple instances allowed */
#define ATTR_FLAG_DEFAULTVALUE 0x40 /* Field has default value */
/* Certificate information flags. The sigChecked flags is used to cache
the check of the cert signature since it's only necessary to perform this
once when the cert is imported or checked for the first time. Checking of
cert fields that aren't affected by the issuer cert is also cached, but
this is handled by the compliance-level check value rather than a simple
boolean flag since a cert can be checked at various levels of standards-
compliance. The data-only flag indicates a pure data object with no
attached context. The CRL-entry flag is used to indicate that the CRL
object contains the data from a single CRL entry rather than being a
complete CRL. The cert-collection flag indicates that a cert chain object
contains only an unordered collection of (non-duplicate) certs rather than
a true cert chain */
#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_DATAONLY 0x04 /* Cert is data-only (no context) */
#define CERT_FLAG_CRLENTRY 0x08 /* CRL is a standalone single entry */
#define CERT_FLAG_CERTCOLLECTION 0x10 /* Cert chain is unordered collection */
/* When creating RTCS and OCSP responses from a request, there are several
subtypes that we can use based on a format specifier in the request. When
we turn the request into a response we check the format specifiers and
record the response format as being one of the following */
typedef enum {
RTCSRESPONSE_TYPE_NONE, /* No response type */
RTCSRESPONSE_TYPE_BASIC, /* Basic response */
RTCSRESPONSE_TYPE_EXTENDED, /* Extended response */
RTCSRESPONSE_TYPE_LAST /* Last valid response type */
} RTCSRESPONSE_TYPE;
typedef enum {
OCSPRESPONSE_TYPE_NONE, /* No response type */
OCSPRESPONSE_TYPE_OCSP, /* OCSP standard response */
OCSPRESPONSE_TYPE_LAST /* Last valid response type */
} OCSPRESPONSE_TYPE;
/****************************************************************************
* *
* Certificate Element Tags *
* *
****************************************************************************/
/* Context-specific tags for certificates */
enum { CTAG_CE_VERSION, CTAG_CE_ISSUERUNIQUEID, CTAG_CE_SUBJECTUNIQUEID,
CTAG_CE_EXTENSIONS };
/* Context-specific tags for attribute certificates */
enum { CTAG_AC_BASECERTIFICATEID, CTAG_AC_ENTITYNAME,
CTAG_AC_OBJECTDIGESTINFO };
/* Context-specific tags for certification requests */
enum { CTAG_CR_ATTRIBUTES };
/* Context-specific tags for CRLs */
enum { CTAG_CL_EXTENSIONS };
/* Context-specific tags for CRMF certification requests */
enum { CTAG_CF_VERSION, CTAG_CF_SERIALNUMBER, CTAG_CF_SIGNINGALG,
CTAG_CF_ISSUER, CTAG_CF_VALIDITY, CTAG_CF_SUBJECT, CTAG_CF_PUBLICKEY,
CTAG_CF_ISSUERUID, CTAG_CF_SUBJECTUID, CTAG_CF_EXTENSIONS };
/* Context-specific tags for RTCS responses */
enum { CTAG_RP_EXTENSIONS };
/* Context-specific tags for OCSP requests */
enum { CTAG_OR_VERSION, CTAG_OR_DUMMY, CTAG_OR_EXTENSIONS };
/* Context-specific tags for OCSP responses */
enum { CTAG_OP_VERSION, CTAG_OP_EXTENSIONS };
/* Context-specific tags for CMS attributes */
enum { CTAG_SI_AUTHENTICATEDATTRIBUTES };
/****************************************************************************
* *
* 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
numeric data such as a simple boolean, bitstring, or small integer,
we store it in the intValue member. If it's an OID or some form of
string we store it in the variable-length buffer */
long intValue; /* Integer value for simple types */
void *value; /* Attribute value */
int valueLength; /* Attribute value length */
/* The OID, for blob-type attributes */
BYTE *oid; /* Attribute OID */
/* The next and previous list element in the linked list of elements */
struct AL *next, *prev;
/* Variable-length storage for the attribute data */
DECLARE_VARSTRUCT_VARS;
} ATTRIBUTE_LIST;
/* The structure to hold information on the current selection of attribute/
GeneralName/DN data used when adding/reading/deleting cert components.
The usage of this information is too complex to explain here, see the
comments at the start of certcomp.c for more information */
typedef struct {
void **dnPtr; /* Pointer to current DN */
CRYPT_ATTRIBUTE_TYPE generalName; /* Selected GN */
BOOLEAN dnInExtension; /* Whether DN is in extension */
BOOLEAN updateCursor; /* Whether to upate attr.cursor */
} SELECTION_INFO;
#define initSelectionInfo( certInfoPtr ) \
( certInfoPtr )->currentSelection.dnPtr = &( ( certInfoPtr )->subjectName ); \
( certInfoPtr )->currentSelection.generalName = CRYPT_CERTINFO_SUBJECTALTNAME;
/* 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 */
SELECTION_INFO savedSelectionInfo; /* Current DN/GN selection info */
ATTRIBUTE_LIST *savedAttributeCursor; /* Atribute cursor pos.*/
} SELECTION_STATE;
/* The structure to hold a validity information entry */
typedef struct VI {
/* Certificate ID information */
BYTE data[ KEYID_SIZE ];
int dCheck; /* Data checksum */
/* Validity information */
BOOLEAN status; /* Valid/not valid */
int extStatus; /* Extended validity status */
time_t invalidityTime; /* Cert invalidity 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 RTCS entries present */
ATTRIBUTE_LIST *attributes; /* RTCS entry attributes */
int attributeSize; /* Encoded size of attributes */
/* The next element in the linked list of elements */
struct VI *next;
} VALIDITY_INFO;
/* 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 fits 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 */
int dCheck; /* Data checksum */
/* 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 that 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 would fail */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -