📄 cert.h
字号:
/****************************************************************************
* *
* Certificate Routines Header File *
* Copyright Peter Gutmann 1996-2007 *
* *
****************************************************************************/
#ifndef _CERT_DEFINED
#define _CERT_DEFINED
#include <time.h>
#ifndef _STREAM_DEFINED
#if defined( INC_ALL )
#include "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
/* The size of the FIFO used to encode nested SEQUENCEs */
#define ENCODING_FIFO_SIZE 10
/* Normally we check for a valid time by making sure that it's more recent
than MIN_TIME_VALUE, however when reading a certificate the time can be
much earlier than this if it's an old certificate. To handle this we
define a certificate-specific time value that we use as the oldest valid
time value */
#define MIN_CERT_TIME_VALUE ( ( 1996 - 1970 ) * 365 * 86400L )
/* Attribute information flags. These are:
FLAG_BLOB: Disables all type-checking on the field, needed to handle
some certificates 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_CRITICAL: The extension containing the field is marked criticial.
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 certificate from being rejected if the
field is marked critical.
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_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_MULTIVALUED: Multiple instantiations of this field are allowed */
#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 */
#define ATTR_FLAG_MAX 0xFF /* Maximum possible flag value */
/* Certificate information flags. These are:
FLAG_CERTCOLLECTION: Indicates that a certificate chain object contains
only an unordered collection of (non-duplicate) certificates
rather than a true certificate chain. Note that this is a pure
container object for which only the certificate chain member
contains certificates, the base certificate object doesn't
correspond to an actual certificate.
FLAG_CRLENTRY: The CRL object contains the data from a single CRL entry
rather than being a complete CRL.
FLAG_DATAONLY: Indicates a pure data object with no attached context.
FLAG_PATHKLUDGE: Indicates that although the certificate appears to be a
self-signed (CA root) certificate it's actually a PKIX path
kludge certificate that's used to tie a re-issued CA certificate
(with a new CA key) to existing issued certificates signed with
the old CA key. This kludge requires that issuer DN == subject
DN, which denotes a CA root certificate under normal
circumstances.
FLAG_SELFSIGNED: Indicates that the certificate is self-signed.
FLAG_SIGCHECKED: Caches the check of the certificate signature. This is
done because it's only necessary to perform this once when the
certificate is checked for the first time. Checking of
certificate fields that aren't affected by the issuer
certificate is also cached, but this is handled by the
compliance-level check value rather than a simple boolean flag
since a certificate can be checked at various levels of
standards-compliance */
#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 */
#define CERT_FLAG_MAX 0x3F /* Maximum possible flag value */
/* 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 certificate checking
functions that need to return extended error information but can't modify
the certificate 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. The second set of
tags is for POP of the private key */
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 };
enum { CTAG_CF_POP_NONE, CTAG_CF_POP_SIGNATURE, CTAG_CF_POP_ENCRKEY };
/* Context-specific tags for RTCS responses */
enum { CTAG_RP_EXTENSIONS };
/* Context-specific tags for OCSP requests. The second set of tags
is for each request entry in an overall request */
enum { CTAG_OR_VERSION, CTAG_OR_DUMMY, CTAG_OR_EXTENSIONS };
enum { CTAG_OR_SR_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 */
ARRAY( ENCODING_FIFO_SIZE, fifoPos ) \
int sizeFifo[ ENCODING_FIFO_SIZE + 2 ]; /* Encoded size of SEQUENCE containing
this field, if present */
ARRAY( ENCODING_FIFO_SIZE, fifoPos ) \
void *encodingFifo[ ENCODING_FIFO_SIZE + 2 ];/* Encoding table entry used to
encode this SEQUENCE */
int fifoEnd; /* End of list of SEQUENCE sizes */
int fifoPos; /* Current position in list */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -