📄 cert.h
字号:
/****************************************************************************
* *
* Certificate Management Structures and Prototypes *
* Copyright Peter Gutmann 1996-2004 *
* *
****************************************************************************/
#ifndef _CERT_DEFINED
#define _CERT_DEFINED
#include <time.h>
#ifndef _STREAM_DEFINED
#if defined( INC_ALL )
#include "stream.h"
#elif defined( INC_CHILD )
#include "../io/stream.h"
#else
#include "io/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 default size of the serial number, 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 DEFAULT_SERIALNO_SIZE 8
#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
/* When processing items such as nested attributes, we include guards on some
of the more complex loops to avoid getting stuck in an endless loop. The
following value defines how many times we can iterate a loop before
bailing out */
#define CERT_MAX_ITERATIONS 256
/* Attribute information flags. These are:
FLAG_INVALID: Used to catch accidental use of a boolean value for the
flag (an early version of the code used a simple boolean
isCritical in place of the current multi-purpose flags).
FLAG_CRITICAL: The extension containing the field is marked criticial.
FLAG_LOCKED: The attribute can't be deleted once set, needed to handle
fields that are added internally by cryptlib that shouldn't be
deleted by users once set.
FLAG_BLOB: Disables all type-checking on the field, needed to handle
some certs that have invalid field encodings.
FLAG_BLOB_PAYLOAD: Disables type checking on the field payload, for
example checking that the chars in the string are valid for the
given ASN.1 string type.
FLAG_MULTIVALUED: Multiple instantiations of this field are allowed.
FLAG_DEFAULTVALUE: The field has a value which is equal to the default
for this field, so it doesn't get encoded. This flag is set
during the encoding pre-processing pass.
FLAG_IGNORED: The field is recognised but was ignored at this compliance
level. This prevents the cert from being rejected if the field
is marked critical */
#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 */
#define ATTR_FLAG_IGNORED 0x80 /* Attribute ignored at this compl.level */
/* Certificate information flags. These are:
FLAG_SELFSIGNED: Indicates that the certificate is self-signed.
FLAG_SIGCHECKED: Caches the check of the cert signature. This is done
because it's only necessary to perform this once when the cert
is 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.
FLAG_DATAONLY: Indicates a pure data object with no attached context.
FLAG_CRLENTRY: The CRL object contains the data from a single CRL entry
rather than being a complete CRL.
FLAG_CERTCOLLECTION: Indicates that a cert chain object contains only an
unordered collection of (non-duplicate) certs rather than a true
cert chain. Note that this is a pure container object for which
only the cert chain member contains certs, the base cert object
doesn't correspond to an actual cert.
FLAG_PATHKLUDGE: Indicates that although the cert appears to be a self-
signed (CA root) cert, it's actually a PKIX path kludge cert
that's used to tie a re-issued CA cert (with a new CA key) to
existing issued certs signed with the old CA key. This kludge
requires that issuer DN == subject DN, which denotes a CA root
cert under normal circumstances */
#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 */
#define CERT_FLAG_PATHKLUDGE 0x20 /* Cert is a PKIX path kludge */
/* When creating RTCS 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;
/* Set the error locus and type. This is used for cert checking functions
that need to return extended error information but can't modify the cert.
info, so that setErrorInfo() can't be used */
#define setErrorValues( locus, type ) \
*errorLocus = ( locus ); *errorType = ( type )
/* The are several types of attributes that can be used depending on the
object that they're associated with. The following values are used to
select the type of attribute that we want to work with */
typedef enum {
ATTRIBUTE_CERTIFICATE, /* Certificate attribute */
ATTRIBUTE_CMS, /* CMS / S/MIME attribute */
ATTRIBUTE_LAST /* Last valid attribute type */
} ATTRIBUTE_TYPE;
/* When checking policy constraints there are several different types of
checking that we can apply, depending on the presence of other
constraints in the issuing certificate(s) and the level of checking that
we're performing. Policies can be optional, required, or a specific-
policy check that disallows the wildcard anyPolicy as a matching policy */
typedef enum { /* Issuer Subject */
POLICY_NONE, /* - - */
POLICY_NONE_SPECIFIC, /* -, !any -, !any */
POLICY_SUBJECT, /* - yes */
POLICY_SUBJECT_SPECIFIC, /* - yes, !any */
POLICY_BOTH, /* yes yes */
POLICY_BOTH_SPECIFIC, /* yes, !any yes, !any */
POLICY_LAST /* Last valid policy type */
} POLICY_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 GeneralNames, 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 is 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -