Skip to content

CERTCertificate

Endi S. Dewata edited this page Jul 11, 2022 · 6 revisions

Data Structure

/*
** An X.509 certificate object (the unsigned form)
*/
struct CERTCertificateStr {
    /* the arena is used to allocate any data structures that have the same
     * lifetime as the cert.  This is all stuff that hangs off of the cert
     * structure, and is all freed at the same time.  It is used when the
     * cert is decoded, destroyed, and at some times when it changes
     * state
     */
    PLArenaPool *arena;

    /* The following fields are static after the cert has been decoded */
    char *subjectName;
    char *issuerName;
    CERTSignedData signatureWrap; /* XXX */
    SECItem derCert;              /* original DER for the cert */
    SECItem derIssuer;            /* DER for issuer name */
    SECItem derSubject;           /* DER for subject name */
    SECItem derPublicKey;         /* DER for the public key */
    SECItem certKey;              /* database key for this cert */
    SECItem version;
    SECItem serialNumber;
    SECAlgorithmID signature;
    CERTName issuer;
    CERTValidity validity;
    CERTName subject;
    CERTSubjectPublicKeyInfo subjectPublicKeyInfo;
    SECItem issuerID;
    SECItem subjectID;
    CERTCertExtension **extensions;
    char *emailAddr;
    CERTCertDBHandle *dbhandle;
    SECItem subjectKeyID;     /* x509v3 subject key identifier */
    PRBool keyIDGenerated;    /* was the keyid generated? */
    unsigned int keyUsage;    /* what uses are allowed for this cert */
    unsigned int rawKeyUsage; /* value of the key usage extension */
    PRBool keyUsagePresent;   /* was the key usage extension present */
    PRUint32 nsCertType;      /* value of the ns cert type extension */
                              /* must be 32-bit for PR_ATOMIC_SET */

    /* these values can be set by the application to bypass certain checks
     * or to keep the cert in memory for an entire session.
     * XXX - need an api to set these
     */
    PRBool keepSession;         /* keep this cert for entire session*/
    PRBool timeOK;              /* is the bad validity time ok? */
    CERTOKDomainName *domainOK; /* these domain names are ok */

    /*
     * these values can change when the cert changes state.  These state
     * changes include transitions from temp to perm or vice-versa, and
     * changes of trust flags
     */
    PRBool isperm;
    PRBool istemp;
    char *nickname;
    char *dbnickname;
    struct NSSCertificateStr *nssCertificate; /* This is Stan stuff. */
    CERTCertTrust *trust;

    /* the reference count is modified whenever someone looks up, dups
     * or destroys a certificate
     */
    int referenceCount;

    /* The subject list is a list of all certs with the same subject name.
     * It can be modified any time a cert is added or deleted from either
     * the in-memory(temporary) or on-disk(permanent) database.
     */
    CERTSubjectList *subjectList;

    /* these belong in the static section, but are here to maintain
     * the structure's integrity
     */
    CERTAuthKeyID *authKeyID; /* x509v3 authority key identifier */
    PRBool isRoot;            /* cert is the end of a chain */

    /* these fields are used by client GUI code to keep track of ssl sockets
     * that are blocked waiting on GUI feedback related to this cert.
     * XXX - these should be moved into some sort of application specific
     *       data structure.  They are only used by the browser right now.
     */
    union {
        void *apointer; /* was struct SECSocketNode* authsocketlist */
        struct {
            unsigned int hasUnsupportedCriticalExt : 1;
            /* add any new option bits needed here */
        } bits;
    } options;
    int series; /* was int authsocketcount; record the series of the pkcs11ID */

    /* This is PKCS #11 stuff. */
    PK11SlotInfo *slot;        /*if this cert came of a token, which is it*/
    CK_OBJECT_HANDLE pkcs11ID; /*and which object on that token is it */
    PRBool ownSlot;            /*true if the cert owns the slot reference */
    /* These fields are used in nssckbi/builtins CAs. */
    CERTCertDistrust *distrust;
};

Importing Certificate

To import a certificate:

PK11SlotInfo *slot = ...
CERTCertificate *cert = ...

SECStatus rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE);

See also:

Changing Certificate Trust

To change certificate trust:

CERTCertDBHandle *handle = ...
CERTCertificate *cert = ...
char *flags = ...

CERTCertTrust *trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
SECStatus rv = CERT_DecodeTrustString(trust, flags);
rv = CERT_ChangeCertTrust(handle, cert, trust);

See also:

Validating Certificate

To validate a certificate:

rv = CERT_VerifyCertificate(handle, cert, checkSig, usage,
    timeBoundary, pwdata, log, &usage);

if ( log ) {
    if ( log->head == NULL ) {
        fprintf(stdout, "%s: certificate is valid\n", progName);
        GEN_BREAK (SECSuccess)

    } else {
        char *name;
        CERTVerifyLogNode *node;

        node = log->head;
        while ( node ) {
            if ( node->cert->nickname != NULL ) {
                name = node->cert->nickname;
            } else {
                name = node->cert->subjectName;
            }
            fprintf(stderr, "%s : %s\n", name,
                SECU_Strerror(node->error));
            CERT_DestroyCertificate(node->cert);
            node = node->next;
        }
    }

} else {

    if (rv != SECSuccess) {
        PRErrorCode perr = PORT_GetError();
        fprintf(stdout, "%s: certificate is invalid: %s\n",
            progName, SECU_Strerror(perr));
            GEN_BREAK (SECFailure)
    }

    fprintf(stdout, "%s: certificate is valid\n", progName);
    GEN_BREAK (SECSuccess)
}

OCSP

CERT_DisableOCSPChecking(certdb);

status = CERT_SetOCSPDefaultResponder(
    certdb,
    ocspResponderURL_string,
    ocspResponderCertNickname_string
);

CERT_EnableOCSPDefaultResponder(certdb);

CERT_EnableOCSPChecking(certdb);

rv = CERT_OCSPCacheSettings(
    ocsp_cache_size,
    ocsp_min_cache_entry_duration,
    ocsp_max_cache_entry_duration
);

rv = CERT_SetOCSPTimeout(ocsp_timeout);

See also:

Methods

  • SECKEYPublicKey* CERT_ExtractPublicKey(CERTCertificate *cert)

  • SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert, void *wincx)