📄 cert.h
字号:
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 subject and/or issuer DN is 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 *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 which 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 */
/* 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 which acts a boolean flag which 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
which 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
which denotes the cert in the chain which 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/OCSP-specific information. The list of revocations for a CRL or
a list of 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 OCSP we
store the URL for the OCSP responder */
REVOCATION_INFO *revocations; /* List of revocations */
REVOCATION_INFO *currentRevocation; /* Currently selected revocation */
time_t revocationTime; /* Default cert revocation time */
char *ocspUrl;
int ocspUrlSize; /* OCSP responder URL */
/* 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 which 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 GeneralName's and DN's which 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) */
CRYPT_ATTRIBUTE_TYPE currentGeneralName;
CRYPT_ATTRIBUTE_TYPE currentDN;
void **currentDNptr;
/* 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 */
/* When we clone an object, there are certain per-instance fields which
don't get cloned. These fields are located after the following
member, and must be initialised by the cloning function */
int _sharedEnd; /* Dummy used for end of shared fields */
/* 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;
/* In multithreaded environments we need to protect the information from
access by other threads while we use it. The following macro declares
the actual variables required to handle the object locking (the actual
values are defined in cryptos.h) */
DECLARE_OBJECT_LOCKING_VARS
} CERT_INFO;
/* Determine whether an attribute list item is a dummy entry which 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 which selects the current DN without changing
the cert itself, a GeneralName selection component, an attribute cursor
movement component, or a general control information component */
#define isDNSelectionComponent( certInfoType ) \
( certInfoType == CRYPT_CERTINFO_ISSUERNAME || \
certInfoType == CRYPT_CERTINFO_SUBJECTNAME || \
certInfoType == CRYPT_CERTINFO_DIRECTORYNAME )
#define isGeneralNameSelectionComponent( certInfoType ) \
( certInfoType == CRYPT_CERTINFO_AUTHORITYINFO_OCSP || \
certInfoType == CRYPT_CERTINFO_AUTHORITYINFO_CAISSUERS || \
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 )
#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_FIRST_DN && certInfoType <= CRYPT_LAST_DN )
#define isGeneralNameComponent( certInfoType ) \
( certInfoType >= CRYPT_FIRST_GENERALNAME && \
certInfoType <= CRYPT_LAST_GENERALNAME )
/* 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 ).savedCurrentGeneralName = ( certInfoPtr )->currentGeneralName; \
( savedState ).savedCurrentDN = ( certInfoPtr )->currentDN; \
( savedState ).savedCurrentDNptr = ( certInfoPtr )->currentDNptr; \
( savedState ).savedAttributeCursor = ( certInfoPtr )->attributeCursor; \
}
#define restoreSelectionState( savedState, certInfoPtr ) \
{ \
( certInfoPtr )->certChainPos = ( savedState ).savedCertChainPos; \
( certInfoPtr )->currentGeneralName = ( savedState ).savedCurrentGeneralName; \
( certInfoPtr )->currentDN = ( savedState ).savedCurrentDN; \
( certInfoPtr )->currentDNptr = ( savedState ).savedCurrentDNptr; \
( certInfoPtr )->attributeCursor = ( savedState ).savedAttributeCursor; \
}
/* The are several types of attributes which can be used depending on the
object they're associated with. The following values are used to select
the type of attribute we want to work with */
typedef enum { ATTRIBUTE_CERTIFICATE, ATTRIBUTE_CMS } ATTRIBUTE_TYPE;
/****************************************************************************
* *
* DN Manipulation Functions *
* *
****************************************************************************/
/* Compare two ASN.1 strings using the rules for matching RDN string types */
BOOLEAN compareASN1string( const void *string1, const int string1len,
const void *string2, const int string2len );
/* DN manipulation routines */
int insertDNComponent( void **dnListHead,
const CRYPT_ATTRIBUTE_TYPE componentType,
const void *value, const int valueLength,
CRYPT_ERRTYPE_TYPE *errorType );
int deleteDNComponent( void **dnListHead, const CRYPT_ATTRIBUTE_TYPE type,
const void *value, const int valueLength );
int getDNComponentValue( const void *dnListHead,
const CRYPT_ATTRIBUTE_TYPE type,
void *value, int *length, const int maxLength );
void deleteDN( void **dnListHead );
/* Copy and compare a DN */
int copyDN( void **dnDest, const void *dnSrc );
BOOLEAN compareDN( const void *dnComponentListHead1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -