tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pkix_pl_ocspcertid.c (7828B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /*
      5 * pkix_pl_ocspcertid.c
      6 *
      7 * Certificate ID Object for OCSP
      8 *
      9 */
     10 
     11 #include "pkix_pl_ocspcertid.h"
     12 
     13 /* --Private-Cert-Functions------------------------------------- */
     14 
     15 /*
     16 * FUNCTION: pkix_pl_OcspCertID_Destroy
     17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     18 */
     19 static PKIX_Error *
     20 pkix_pl_OcspCertID_Destroy(
     21        PKIX_PL_Object *object,
     22        void *plContext)
     23 {
     24        PKIX_PL_OcspCertID *certID = NULL;
     25 
     26        PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy");
     27 
     28        PKIX_NULLCHECK_ONE(object);
     29 
     30        PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext),
     31                    PKIX_OBJECTNOTOCSPCERTID);
     32 
     33        certID = (PKIX_PL_OcspCertID *)object;
     34 
     35        if (certID->certID) {
     36                CERT_DestroyOCSPCertID(certID->certID);
     37        }
     38 
     39 cleanup:
     40 
     41        PKIX_RETURN(OCSPCERTID);
     42 }
     43 
     44 /*
     45 * FUNCTION: pkix_pl_OcspCertID_RegisterSelf
     46 * DESCRIPTION:
     47 *  Registers PKIX_PUBLICKEY_TYPE and its related functions 
     48 *  with systemClasses[]
     49 * THREAD SAFETY:
     50 *  Not Thread Safe - for performance and complexity reasons
     51 *
     52 *  Since this function is only called by PKIX_PL_Initialize, which should
     53 *  only be called once, it is acceptable that this function is not
     54 *  thread-safe.
     55 */
     56 PKIX_Error *
     57 pkix_pl_OcspCertID_RegisterSelf(void *plContext)
     58 {
     59        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
     60        pkix_ClassTable_Entry entry;
     61 
     62        PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_RegisterSelf");
     63 
     64        entry.description = "OcspCertID";
     65        entry.objCounter = 0;
     66        entry.typeObjectSize = sizeof(PKIX_PL_OcspCertID);
     67        entry.destructor = pkix_pl_OcspCertID_Destroy;
     68        entry.equalsFunction = NULL;
     69        entry.hashcodeFunction = NULL;
     70        entry.toStringFunction = NULL;
     71        entry.comparator = NULL;
     72        entry.duplicateFunction = pkix_duplicateImmutable;
     73        systemClasses[PKIX_OCSPCERTID_TYPE] = entry;
     74 
     75        PKIX_RETURN(OCSPCERTID);
     76 }
     77 
     78 /* --Public-Functions------------------------------------------------------- */
     79 
     80 /*
     81 * FUNCTION: PKIX_PL_OcspCertID_Create
     82 * DESCRIPTION:
     83 *
     84 *  This function creates an OcspCertID for a given certificate,
     85 *  to be used with OCSP transactions.
     86 *
     87 *  If a Date is provided in "validity" it may be used in the search for the
     88 *  issuer of "cert" but has no effect on the request itself.
     89 *
     90 * PARAMETERS:
     91 *  "cert"
     92 *     Address of the Cert for which an OcspCertID is to be created. Must be
     93 *     non-NULL.
     94 *  "validity"
     95 *     Address of the Date for which the Cert's validity is to be determined.
     96 *     May be NULL.
     97 *  "object"
     98 *     Address at which the result is stored. Must be non-NULL.
     99 *  "plContext"
    100 *      Platform-specific context pointer.
    101 * THREAD SAFETY:
    102 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    103 * RETURNS:
    104 *  Returns NULL if the function succeeds.
    105 *  Returns an OcspCertID Error if the function fails in a non-fatal way.
    106 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    107 */
    108 PKIX_Error *
    109 PKIX_PL_OcspCertID_Create(
    110        PKIX_PL_Cert *cert,
    111        PKIX_PL_Date *validity,
    112        PKIX_PL_OcspCertID **object,
    113        void *plContext)
    114 {
    115        PKIX_PL_OcspCertID *cid = NULL;
    116        PRTime time = 0;
    117 
    118        PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_Create");
    119        PKIX_NULLCHECK_TWO(cert, object);
    120    
    121        PKIX_CHECK(PKIX_PL_Object_Alloc
    122                    (PKIX_OCSPCERTID_TYPE,
    123                    sizeof (PKIX_PL_OcspCertID),
    124                    (PKIX_PL_Object **)&cid,
    125                    plContext),
    126                    PKIX_COULDNOTCREATEOBJECT);
    127 
    128        if (validity != NULL) {
    129                PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
    130                        PKIX_DATEGETPRTIMEFAILED);
    131        } else {
    132                time = PR_Now();
    133        }
    134 
    135        cid->certID = CERT_CreateOCSPCertID(cert->nssCert, time);
    136        if (!cid->certID) {
    137                PKIX_ERROR(PKIX_COULDNOTCREATEOBJECT);
    138        }
    139 
    140        *object = cid;
    141        cid = NULL;
    142 cleanup:
    143        PKIX_DECREF(cid);
    144        PKIX_RETURN(OCSPCERTID);
    145 }
    146 
    147 /*
    148 * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus
    149 * DESCRIPTION:
    150 *
    151 *  This function may return cached OCSP results for the provided
    152 *  certificate, but only if stored information is still considered to be
    153 *  fresh.
    154 *
    155 * PARAMETERS
    156 *  "cid"
    157 *      A certificate ID as used by OCSP
    158 *  "validity"
    159 *      Optional date parameter to request validity for a specifc time.
    160 *  "hasFreshStatus"
    161 *      Output parameter, if the function successed to find fresh cached
    162 *      information, this will be set to true. Must be non-NULL.
    163 *  "statusIsGood"
    164 *      The good/bad result stored in the cache. Must be non-NULL.
    165 *  "missingResponseError"
    166 *      If OCSP status is "bad", this variable may indicate the exact
    167 *      reason why the previous OCSP request had failed.
    168 *  "plContext"
    169 *      Platform-specific context pointer.
    170 * RETURNS:
    171 *  Returns NULL if the function succeeds.
    172 *  Returns an OcspCertID Error if the function fails in a non-fatal way.
    173 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    174 */
    175 PKIX_Error *
    176 PKIX_PL_OcspCertID_GetFreshCacheStatus(
    177        PKIX_PL_OcspCertID *cid, 
    178        PKIX_PL_Date *validity,
    179        PKIX_Boolean *hasFreshStatus,
    180        PKIX_Boolean *statusIsGood,
    181        SECErrorCodes *missingResponseError,
    182        void *plContext)
    183 {
    184        PRTime time = 0;
    185        SECStatus rv;
    186        SECStatus rvOcsp;
    187        OCSPFreshness freshness;
    188 
    189        PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
    190        PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);
    191 
    192        if (validity != NULL) {
    193                PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
    194                        PKIX_DATEGETPRTIMEFAILED);
    195        } else {
    196                time = PR_Now();
    197        }
    198 
    199        rv = ocsp_GetCachedOCSPResponseStatus(
    200                cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/
    201                &rvOcsp, missingResponseError, &freshness);
    202 
    203        *hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh);
    204        if (*hasFreshStatus) {
    205                *statusIsGood = (rvOcsp == SECSuccess);
    206        }
    207 cleanup:
    208        PKIX_RETURN(OCSPCERTID);
    209 }
    210 
    211 /*
    212 * FUNCTION: PKIX_PL_OcspCertID_RememberOCSPProcessingFailure
    213 * DESCRIPTION:
    214 *
    215 *  Information about the current failure associated to the given certID
    216 *  will be remembered in the cache, potentially allowing future calls
    217 *  to prevent repetitive OCSP requests.
    218 *  After this function got called, it may no longer be safe to
    219 *  use the provided cid parameter, because ownership might have been
    220 *  transfered to the cache. This status will be recorded inside the
    221 *  cid object.
    222 *
    223 * PARAMETERS
    224 *  "cid"
    225 *      The certificate ID associated to a failed OCSP processing.
    226 *  "plContext"
    227 *      Platform-specific context pointer.
    228 * RETURNS:
    229 *  Returns NULL if the function succeeds.
    230 *  Returns an OcspCertID Error if the function fails in a non-fatal way.
    231 *  Returns a Fatal Error if the function fails in an unrecoverable way.
    232 */
    233 PKIX_Error *
    234 PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
    235        PKIX_PL_OcspCertID *cid, 
    236        void *plContext)
    237 {
    238        PRBool certIDWasConsumed = PR_FALSE;
    239 
    240        PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure");
    241        PKIX_NULLCHECK_TWO(cid, cid->certID);
    242 
    243        cert_RememberOCSPProcessingFailure(cid->certID, &certIDWasConsumed);
    244 
    245        if (certIDWasConsumed) {
    246                cid->certID = NULL;
    247        }
    248 
    249        PKIX_RETURN(OCSPCERTID);
    250 }