📄 cert.h
字号:
/* 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 */
BUFFER_OPT_FIXED( valueLength ) \
void *value; /* Attribute value */
int valueLength; /* Attribute value length */
/* The OID, for blob-type attributes */
BYTE *oid; /* Attribute OID */
/* The previous and next list element in the linked list of elements */
struct AL *prev, *next;
/* 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 certificate
components. The usage of this information is too complex to explain
here, see the comments at the start of comp_get.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 ) \
memset( &( certInfoPtr )->currentSelection, 0, sizeof( SELECTION_INFO ) ); \
( certInfoPtr )->currentSelection.dnPtr = &( ( certInfoPtr )->subjectName ); \
( certInfoPtr )->currentSelection.generalName = CRYPT_CERTINFO_SUBJECTALTNAME;
/* Sometimes we need to manipulate an internal component which is addressed
indirectly as a side-effect of some other processing operation. We can't
change the selection information for the certificate object since this will
affect any future operations that the user performs so we provide the
following macros to save and restore the selection state around these
operations */
typedef struct {
int savedChainPos; /* Current cert.chain position */
SELECTION_INFO savedSelectionInfo; /* Current DN/GN selection info */
ATTRIBUTE_LIST *savedAttributeCursor; /* Atribute cursor pos.*/
} SELECTION_STATE;
#define saveSelectionState( savedState, certInfoPtr ) \
{ \
memset( &( savedState ), 0, sizeof( SELECTION_STATE ) ); \
if( ( certInfoPtr )->type == CRYPT_CERTTYPE_CERTCHAIN ) \
( savedState ).savedChainPos = ( certInfoPtr )->cCertCert->chainPos; \
( savedState ).savedSelectionInfo = ( certInfoPtr )->currentSelection; \
( savedState ).savedAttributeCursor = ( certInfoPtr )->attributeCursor; \
}
#define restoreSelectionState( savedState, certInfoPtr ) \
{ \
if( ( certInfoPtr )->type == CRYPT_CERTTYPE_CERTCHAIN ) \
( certInfoPtr )->cCertCert->chainPos = ( savedState ).savedChainPos; \
( certInfoPtr )->currentSelection = ( savedState ).savedSelectionInfo; \
( certInfoPtr )->attributeCursor = ( savedState ).savedAttributeCursor; \
}
/* The structure to hold a validity information entry */
typedef struct VI {
/* Certificate ID information */
BUFFER_FIXED( KEYID_SIZE ) \
BYTE data[ KEYID_SIZE + 8 ];
int dCheck; /* Data checksum for quick match */
/* 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 certificate 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
certificate hash or issuerID (for OCSP requests/responses). In
addition this could also be a pre-encoded OCSP certID, which is
treated as an opaque blob of type CRYPT_ATTRIBUTE_NONE since it can't
be used in any useful way. If we're using OCSP and an alternative ID
is supplied as an ESSCertID we point to this value (inside the
ESSCertID) in the altIdPtr field.
Usually the certificate ID information fits in the id field, if it's
longer than that (which can only occur with enormous serial numbers)
it's held in the dynamically-allocated idPtr value */
CRYPT_KEYID_TYPE idType; /* ID type */
BUFFER( 128, idLength ) \
BYTE id[ 128 + 8 ], *idPtr;
int idLength; /* ID information */
int idCheck; /* Data checksum for quick match */
CRYPT_KEYID_TYPE altIdType; /* Alt.ID type for OCSP */
BUFFER_FIXED( KEYID_SIZE ) \
BYTE altID[ KEYID_SIZE + 8 ]; /* Alt.ID for OCSP */
/* 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 certificate 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 internal fields in a certificate that hold subtype-specific data for
the various certificate object types */
typedef struct {
/* The certificate serial number. This is stored in the buffer if it
fits (it almost always does), otherwise in a dynamically-allocated
buffer */
BUFFER( SERIALNO_BUFSIZE, serialNumberLength ) \
BYTE serialNumberBuffer[ SERIALNO_BUFSIZE + 8 ];
BUFFER_OPT_FIXED( serialNumberLength ) \
void *serialNumber;
int serialNumberLength; /* Certificate serial number */
/* The highest compliance level at which a certificate has been checked.
We have to record this high water-mark level because increasing the
compliance level may invalidate an earlier check performed at a lower
level */
int maxCheckLevel;
/* The allowed usage for a certificate can be further controlled by the
user. The trustedUsage value is a mask which is applied to the key
usage extension to further constrain usage, alongside this there is
an additional implicit trustImplicit value that acts a boolean flag
that indicates whether the user implicitly trusts this certificate
(without requiring further checking upstream). This value isn't
stored with the certificate since it's a property of any
instantiation of the certificate rather than just the current one so
when the user queries it it's obtained dynamically from the trust
manager */
int trustedUsage;
/* Certificate chains are a special variant of standard certificates,
being complex container objects that contain further certificates
leading up to a CA root certificate. The reason why they're combined
with standard certificates is because when we're building a chain
from a certificate collection or assembling it from a certificate
source we can't tell at the time of certificate creation which
certificate will be the leaf certificate so that any certificate
potentially has to be able to act as the chain container (another way
of looking at this is that all standard certificates are a special
case of a chain with a length of one).
A possible alternative to this way of handling chains is to make the
chain object a pure container object used only to hold pointers to
the actual certificates, but this requires an extra level of
indirection every time a certificate chain object is used since in
virtually all cases what'll be used is the leaf certificate with
which the chain-as-standard-certificate model is the default
certificate but with the chain-as-container model requires an extra
object dereference to obtain.
In theory we should use a linked list to store chains but since the
longest chain ever seen in the wild has a length of 4 using a fixed
maximum length seveal times this size shouldn't be a problem. The
certificates in the chain are ordered from the parent of the leaf
certificate up to the root certificate with the leaf certificate
corresponding to the [-1]th entry in the list. We also maintain a
current position in the certificate chain that denotes the
certificate in the chain that will be accessed by the
component-manipulation functions. This is set to CRYPT_ERROR if the
current certificate is the leaf certificate */
ARRAY( MAX_CHAINLENGTH, chainEnd ) \
CRYPT_CERTIFICATE chain[ MAX_CHAINLENGTH + 8 ];
int chainEnd; /* Length of cert chain */
int chainPos; /* Currently selected cert in chain */
/* The hash algorithm used to sign the certificate. Although a part of
the signature, a second copy of the algorithm ID is embedded inside
the signed certificate data because of a theoretical attack that
doesn't actually work with any standard signature padding
technique */
CRYPT_ALGO_TYPE hashAlgo;
/* The (deprecated) X.509v2 unique ID */
BUFFER_OPT_FIXED( issuerUniqueIDlength ) \
void *issuerUniqueID;
BUFFER_OPT_FIXED( subjectUniqueIDlength ) \
void *subjectUniqueID;
int issuerUniqueIDlength, subjectUniqueIDlength;
} CERT_CERT_INFO;
typedef struct {
/* The certificate serial number, used when requesting a revocation by
issuerAndSerialNumber. This is stored in the buffer if it fits (it
almost always does), otherwise in a dynamically-allocated buffer */
BUFFER( SERIALNO_BUFSIZE, serialNumberLength ) \
BYTE serialNumberBuffer[ SERIALNO_BUFSIZE + 8 ];
BUFFER_OPT_FIXED( serialNumberLength ) \
void *serialNumber;
int serialNumberLength; /* Certificate serial number */
/* The certificate ID of the PKI user or certificate that authorised
this request. This is from an external source, supplied when the
request is used as part of the CMP protocol */
BUFFER_FIXED( KEYID_SIZE ) \
BYTE authCertID[ KEYID_SIZE + 8 ];
} CERT_REQ_INFO;
typedef struct {
/* The list of revocations for a CRL or a list of OCSP request or response
entries, and a pointer to the revocation/request/response which is
currently being accessed */
REVOCATION_INFO *revocations; /* List of revocations */
REVOCATION_INFO *currentRevocation; /* Currently selected revocation */
/* The default revocation time for a CRL, used for if no explicit time
is set for a revocation */
time_t revocationTime; /* Default certificate revocation time */
/* The URL for the OCSP responder */
BUFFER_OPT_FIXED( responderUrlSize ) \
char *responderUrl;
int responderUrlSize; /* OCSP responder URL */
/* The hash algorithm used to sign the certificate. Although a part of
the signature, a second copy of the algorithm ID is embedded inside
the signed certificate data because of a theoretical attack that
doesn't actually work with any standard signature padding
technique */
CRYPT_ALGO_TYPE hashAlgo;
/* Signed OCSP requests can include varying levels of detail in the
signature. The following value determines how much information is
included in the signature */
CRYPT_SIGNATURELEVEL_TYPE signatureLevel;
} CERT_REV_INFO;
typedef struct {
/* A list of RTCS request or response entries and a pointer to the
request/response which is currently being accessed */
VALIDITY_INFO *validityInfo; /* List of validity info */
VALIDITY_INFO *currentValidity; /* Currently selected validity info */
/* The URL for the RTCS responder */
BUFFER_OPT_FIXED( responderUrlSize ) \
char *responderUrl; /* RTCS responder URL */
int responderUrlSize;
/* Since RTCS allows for a variety of response types, we include an
indication of the request/response format */
RTCSRESPONSE_TYPE responseType; /* Request/response format */
} CERT_VAL_INFO;
typedef struct {
/* The authenticator used for authenticating certificate issue and
revocation requests */
BUFFER_FIXED( 16 ) \
BYTE pkiIssuePW[ 16 + 8 ];
BUFFER_FIXED( 16 ) \
BYTE pkiRevPW[ 16 + 8 ];
} CERT_PKIUSER_INFO;
/* Defines to make access to the union fields less messy */
#define cCertCert certInfo.certInfo
#define cCertReq certInfo.reqInfo
#define cCertRev certInfo.revInfo
#define cCertVal certInfo.valInfo
#define cCertUser certInfo.pkiUserInfo
/* The structure that stores information on a certificate object */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -