📄 cert.h
字号:
/****************************************************************************
* *
* 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 + -