📄 cert.h
字号:
/* 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 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 cert 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 ) \
{ \
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 */
BYTE data[ KEYID_SIZE ];
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 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 since 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 for quick match */
/* 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 internal fields in a cert that hold subtype-specific data for the
various cert object types */
typedef struct {
/* The cert serial number. This is stored in the buffer if it fits (it
almost always does), otherwise in a dynamically-allocated buffer */
BYTE serialNumberBuffer[ SERIALNO_BUFSIZE ];
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 cert since it's a property of any instantiation of
the cert rather than just the current one, so when the user queries
it it's obtained dynamically from the trust manager */
int trustedUsage;
/* Cert chains are a special variant of standard certs, being complex
container objects that contain further certificates leading up to a
CA root cert. The reason why they're combined with standard certs
is because when we're building a chain from a cert collection or
assembling it from a cert source we can't tell at the time of cert
creation which cert will be the leaf cert, so that any cert
potentially has to be able to act as the chain container (another way
of looking at this is that all standard certs 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 certs, but this requires an extra level of indirection
every time a cert chain object is used, since in virtually all cases
what'll be used is the leaf cert with which the chain-as-standard-
cert model is the default cert 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
certs in the chain are ordered from the parent of the leaf cert up to
the root cert, with the leaf cert corresponding to the [-1]th entry
in the list. We also maintain a current position in the cert chain
that denotes the cert in the chain that will be accessed by the
component-manipulation functions. This is set to CRYPT_ERROR if the
current cert is the leaf cert */
CRYPT_CERTIFICATE chain[ MAX_CHAINLENGTH ];
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 */
void *issuerUniqueID, *subjectUniqueID;
int issuerUniqueIDlength, subjectUniqueIDlength;
} CERT_CERT_INFO;
typedef struct {
/* The cert 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 */
BYTE serialNumberBuffer[ SERIALNO_BUFSIZE ];
void *serialNumber;
int serialNumberLength; /* Certificate serial number */
/* The cert ID of the PKI user or cert that authorised this request.
This is from an external source, supplied when the request is
used as part of the CMP protocol */
BYTE authCertID[ KEYID_SIZE ];
} 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 cert revocation time */
/* The URL for the OCSP responder */
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 */
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 */
BYTE pkiIssuePW[ 16 ], pkiRevPW[ 16 ];
} 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 */
typedef struct {
/* General certificate information */
CRYPT_CERTTYPE_TYPE type; /* Certificate type */
int flags; /* Certificate flags */
int version; /* Cert object version */
/* Cert type-specific information */
union {
CERT_CERT_INFO *certInfo;
CERT_REQ_INFO *reqInfo;
CERT_REV_INFO *revInfo;
CERT_VAL_INFO *valInfo;
CERT_PKIUSER_INFO *pkiUserInfo;
} certInfo;
/* 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 */
void *certificate;
int certificateSize;
/* The public key associated with this certificate. When the cert is in
the low (unsigned state), this consists of the encoded public-key data
and associated attributes. When the cert is in the high (signed)
state, either by being imported from an external source or by being
signed by cryptlib, this consists of a public-key context. In
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -