📄 cert.h
字号:
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
addition some certificates are imported as data-only certificates,
denoted by the CERT_FLAG_DATAONLY being set. These constitute a
container object that contain no public-key context, and are used for
cert chains (when read from atrusted source) and to store cert
information associated with a private-key context. Since it's not
known during the import stage whether a cert in a chain will be a
data-only or standard cert (it's not known until the entire chain has
been processed which cert is the leaf cert), cert chains from a
trusted source are imported as data-only certs and then the leaf
has its context instantiated */
CRYPT_CONTEXT iPubkeyContext; /* Public-key context */
CRYPT_ALGO_TYPE publicKeyAlgo; /* Key algorithm */
int publicKeyFeatures; /* Key features */
void *publicKeyInfo; /* Encoded key information */
int publicKeyInfoSize;
BYTE publicKeyID[ KEYID_SIZE ]; /* Key ID */
/* General certificate object information */
BYTE serialNumberBuffer[ SERIALNO_BUFSIZE ];
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 cert's 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
inside the encoded certificate object */
void *subjectDNptr, *issuerDNptr; /* Pointer to encoded DN blobs */
int subjectDNsize, issuerDNsize; /* Size of encoded DN blobs */
/* For some objects the public key and/or subject DN and/or issuer DN are
copied in from an external source before the object is signed so we
can't just point the issuerDNptr at the encoded object, we have to
allocate a separate data area to copy the DN into. This is used in
cases where we don't copy in a full subhect/issuerName but only use
an encoded DN blob for the reasons described above */
void *publicKeyData, *subjectDNdata, *issuerDNdata;
/* For chaining we may also need to use key identifiers, unfortunately
this rarely works as intended because most certs don't contain key
identifiers or contain them in some peculiar form that isn't useful
or in an incorrect form. This isn't helped by the fact that the
subject and authority key identifiers have different forms and can't
be compared by matching the encoded blobs. For this reason we only
try to chain on key identifiers if chaining on names fails */
void *subjectKeyIDptr, *issuerKeyIDptr; /* Pointer to encoded key ID blobs */
int subjectKeyIDsize, issuerKeyIDsize; /* Size of encoded key ID blobs */
/* The certificate hash/fingerprint/oobCertID/thumbprint/whatever. This
is used so frequently that it's cached here for future re-use */
BYTE certHash[ KEYID_SIZE ]; /* Cached cert hash */
BOOLEAN certHashSet; /* Whether hash has been set */
/* Some signed objects 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;
/* The highest compliance level at which a certificate has been checked.
We have to record this because increasing the compliance level may
invalidate an earlier check performed at a lower level */
int maxCheckLevel;
/* Certificate-specific information. 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-chain specific information. These are complex container objects
that contain further certificates leading up to a CA root cert. 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 certChain[ MAX_CHAINLENGTH ];
int certChainEnd; /* Length of cert chain */
int certChainPos; /* Currently selected cert in chain */
/* CRL/RTCS/OCSP-specific information. The list of revocations for a
CRL or a list of RTCS/OCSP request entries or responses, and a
pointer to the revocation/request/response which is currently being
accessed. In addition for a CRL we store the default revocation time
which is used for revocations if no explicit time is set for them, and
for RTCS/OCSP we store the URL for the responder. Finally, since OCSP
allows for a variety of response types, we include a flag indicating
whether we should use the extended rather than basic response format */
VALIDITY_INFO *validityInfo; /* List of validity info */
VALIDITY_INFO *currentValidity; /* Currently selected validity info */
REVOCATION_INFO *revocations; /* List of revocations */
REVOCATION_INFO *currentRevocation; /* Currently selected revocation */
time_t revocationTime; /* Default cert revocation time */
char *responderUrl;
int responderUrlSize; /* RTCS/OCSP responder URL */
OCSPRESPONSE_TYPE responseType; /* OCSP response format */
/* PKI user-specific information. The authenticator used for
authenticating certificate issue and revocation requests */
BYTE pkiIssuePW[ 16 ], pkiRevPW[ 16 ];
/* Cert request-specific information. The cert ID of the PKI user or
cert that authorised this request (supplied externally when the
request is received) */
BYTE authCertID[ KEYID_SIZE ];
/* Certificate object attributes are stored in two ways, as the native
field types for the attributes we recognise (or at least for the ones
we care about), and as a list of encoded blobs for the rest */
ATTRIBUTE_LIST *attributes; /* Certificate object attributes */
/* The cursor into the attribute list. This can be moved by the user on
a per-attribute, per-field, and per-component basis. We also remember
whether there's been an attempt to set the attribute cursor so that
we can differentiate between the case where the cursor is NULL because
no attempt was made to set it, or because there are no attributes
present */
ATTRIBUTE_LIST *attributeCursor;
/* The currently selected GeneralName and DN and DN pointer. A cert can
contain multiple GeneralNames and DNs that can be selected by their
field types, after which adding DN components will affected the
selected DN. This value contains the currently selected GeneralName
and DN, and a pointer to the DN data if it exists (when creating a new
DN, the pointer will be null after it's selected since it won't be
instantiated until data is added to it in later calls) */
SELECTION_INFO currentSelection;
/* Save area for the currently selected GeneralName and DN, and position
in the cert chain. The current values are saved to this area when the
object receives a lock object message, and restored when the object
receives the corresponding unlock message. This guarantees that any
changes made during processing while the cert is locked don't get
reflected back to external users */
SELECTION_STATE selectionState;
/* Error information */
CRYPT_ATTRIBUTE_TYPE errorLocus;/* Error locus */
CRYPT_ERRTYPE_TYPE errorType; /* Error type */
/* The object's handle and the handle of the user who owns this object.
The former is used when sending messages to the object when only the
xxx_INFO is available, the latter is used to avoid having to fetch the
same information from the system object table */
CRYPT_HANDLE objectHandle;
CRYPT_USER ownerHandle;
} CERT_INFO;
/* Cert read/write methods for the different format types */
typedef struct {
const CRYPT_CERTTYPE_TYPE type;
int ( *readFunction )( STREAM *stream, CERT_INFO *certInfoPtr );
} CERTREAD_INFO;
typedef struct {
const CRYPT_CERTTYPE_TYPE type;
int ( *writeFunction )( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext );
} CERTWRITE_INFO;
extern const CERTREAD_INFO certReadTable[];
extern const CERTWRITE_INFO certWriteTable[];
/* Determine whether an attribute list item is a dummy entry that denotes
either that this field isn't present in the list but has a default value
or that this field isn't present in the list but represents an entire
(constructed) attribute, or whether it contains a single blob-type
attribute */
#define DEFAULTFIELD_VALUE { 0, CRYPT_ERROR, 0 }
#define COMPLETEATTRIBUTE_VALUE { CRYPT_ERROR, 0, 0 }
#define isDefaultFieldValue( attributeListPtr ) \
( ( attributeListPtr )->fieldID == CRYPT_ERROR && \
( attributeListPtr )->attributeID == 0 )
#define isCompleteAttribute( attributeListPtr ) \
( ( attributeListPtr )->fieldID == 0 && \
( attributeListPtr )->attributeID == CRYPT_ERROR )
#define isBlobAttribute( attributeListPtr ) \
( ( attributeListPtr )->fieldID == 0 && \
( attributeListPtr )->attributeID == 0 )
/* Determine whether a component which is being added to a cert is a special-
case DN selection component that selects the current DN without changing
the cert itself, a GeneralName selection component, an attribute cursor
movement component, or a general control information component. We also
define an alternate form for the GeneralName components to allow them to
be used in a switch() statement */
#define isDNSelectionComponent( certInfoType ) \
( ( certInfoType ) == CRYPT_CERTINFO_ISSUERNAME || \
( certInfoType ) == CRYPT_CERTINFO_SUBJECTNAME || \
( certInfoType ) == CRYPT_CERTINFO_DIRECTORYNAME )
#define isGeneralNameSelectionComponent( certInfoType ) \
( ( certInfoType ) == CRYPT_CERTINFO_AUTHORITYINFO_RTCS || \
( certInfoType ) == CRYPT_CERTINFO_AUTHORITYINFO_OCSP || \
( certInfoType ) == CRYPT_CERTINFO_AUTHORITYINFO_CAISSUERS || \
( certInfoType ) == CRYPT_CERTINFO_AUTHORITYINFO_TIMESTAMPING || \
( certInfoType ) == CRYPT_CERTINFO_SUBJECTINFO_CAREPOSITORY || \
( certInfoType ) == CRYPT_CERTINFO_SUBJECTINFO_TIMESTAMPING || \
( certInfoType ) == CRYPT_CERTINFO_SIGG_PROCURE_SIGNINGFOR || \
( certInfoType ) == CRYPT_CERTINFO_SUBJECTALTNAME || \
( certInfoType ) == CRYPT_CERTINFO_ISSUERALTNAME || \
( certInfoType ) == CRYPT_CERTINFO_ISSUINGDIST_FULLNAME || \
( certInfoType ) == CRYPT_CERTINFO_CERTIFICATEISSUER || \
( certInfoType ) == CRYPT_CERTINFO_PERMITTEDSUBTREES || \
( certInfoType ) == CRYPT_CERTINFO_EXCLUDEDSUBTREES || \
( certInfoType ) == CRYPT_CERTINFO_CRLDIST_FULLNAME || \
( certInfoType ) == CRYPT_CERTINFO_CRLDIST_CRLISSUER || \
( certInfoType ) == CRYPT_CERTINFO_AUTHORITY_CERTISSUER || \
( certInfoType ) == CRYPT_CERTINFO_FRESHESTCRL_FULLNAME || \
( certInfoType ) == CRYPT_CERTINFO_FRESHESTCRL_CRLISSUER || \
( certInfoType ) == CRYPT_CERTINFO_CMS_RECEIPT_TO || \
( certInfoType ) == CRYPT_CERTINFO_CMS_MLEXP_INSTEADOF || \
( certInfoType ) == CRYPT_CERTINFO_CMS_MLEXP_INADDITIONTO )
#define isCursorComponent( certInfoType ) \
( ( certInfoType ) == CRYPT_CERTINFO_CURRENT_CERTIFICATE || \
( certInfoType ) == CRYPT_CERTINFO_CURRENT_EXTENSION || \
( certInfoType ) == CRYPT_CERTINFO_CURRENT_FIELD || \
( certInfoType ) == CRYPT_CERTINFO_CURRENT_COMPONENT )
#define isControlComponent( certInfoType ) \
( ( certInfoType ) == CRYPT_CERTINFO_TRUSTED_USAGE || \
( certInfoType ) == CRYPT_CERTINFO_TRUSTED_IMPLICIT )
/* Determine whether a component which is being added is a DN or GeneralName
component */
#define isDNComponent( certInfoType ) \
( ( certInfoType ) >= CRYPT_CERTINFO_FIRST_DN && \
( certInfoType ) <= CRYPT_CERTINFO_LAST_DN )
#define isGeneralNameComponent( certInfoType ) \
( ( certInfoType ) >= CRYPT_CERTINFO_FIRST_GENERALNAME && \
( certInfoType ) <= CRYPT_CERTINFO_LAST_GENERALNAME )
/* Determine whether a component which is being added is pseudo-information
that corresponds to certificate control information rather than a normal
cert attribute */
#define isPseudoInformation( certInfoType ) \
( ( certInfoType ) >= CRYPT_CERTINFO_FIRST_PSEUDOINFO && \
( certInfoType ) <= CRYPT_CERTINFO_LAST_PSEUDOINFO )
/* Determine whether a component which is being added to a CRL or OCSP
request/response is a standard attribute or a per-entry attribute */
#define isRevocationEntryComponent( certInfoType ) \
( ( certInfoType ) == CRYPT_CERTINFO_CRLREASON || \
( certInfoType ) == CRYPT_CERTINFO_HOLDINSTRUCTIONCODE || \
( certInfoType ) == CRYPT_CERTINFO_INVALIDITYDATE )
/* 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 since this will affect any future
operations the user performs, so we provide the following macros to save
and restore the selection state around these operations */
#define saveSelectionState( savedState, certInfoPtr ) \
{ \
( savedState ).savedCertChainPos = ( certInfoPtr )->certChainPos; \
( savedState ).savedSelectionInfo = ( certInfoPtr )->currentSelection; \
( savedState ).savedAttributeCursor = ( certInfoPtr )->attributeCursor; \
}
#define restoreSelectionState( savedState, certInfoPtr ) \
{ \
( certInfoPtr )->certChainPos = ( savedState ).savedCertChainPos; \
( certInfoPtr )->currentSelection = ( savedState ).savedSelectionInfo; \
( certInfoPtr )->attributeCursor = ( savedState ).savedAttributeCursor; \
}
/* Set the error locus and type. This is used for checking functions that
need to return extended error information but can't modify the cert.info
(so that setErrorInfo() can't be used) but */
#define setErrorValues( locus, type ) \
*errorLocus = ( locus ); *errorType = ( type )
/* Selection options when working with DNs/GeneralNames in extensions. These
are used internally when handling user get/set/delete DN/GeneralName
requests */
typedef enum {
MAY_BE_ABSENT, /* Component may be absent */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -