tor-browser

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

pkix_pl_lifecycle.c (9618B)


      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_lifecycle.c
      6 *
      7 * Lifecycle Functions for the PKIX PL library.
      8 *
      9 */
     10 
     11 #include "pkix_pl_lifecycle.h"
     12 
     13 PKIX_Boolean pkix_pl_initialized = PKIX_FALSE;
     14 pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
     15 PRLock *classTableLock;
     16 PRLogModuleInfo *pkixLog = NULL;
     17 
     18 /*
     19 * PKIX_ALLOC_ERROR is a special error object hard-coded into the
     20 * pkix_error.o object file. It is thrown if system memory cannot be
     21 * allocated. PKIX_ALLOC_ERROR is immutable.
     22 * IncRef, DecRef, and Settor functions cannot be called.
     23 */
     24 
     25 /* Keep this structure definition here for its is used only once here */
     26 struct PKIX_Alloc_Error_ObjectStruct {
     27        PKIX_PL_Object header;
     28        PKIX_Error error;
     29 };
     30 typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object;
     31 
     32 static const PKIX_Alloc_Error_Object pkix_Alloc_Error_Data = {
     33    {
     34        PKIX_MAGIC_HEADER, 		/* PRUint64    magicHeader */
     35        (PKIX_UInt32)PKIX_ERROR_TYPE,   /* PKIX_UInt32 type */
     36        (PKIX_UInt32)1,                 /* PKIX_UInt32 references */
     37        /* Warning! Cannot Ref Count with NULL lock */
     38        (void *)0,                      /* PRLock *lock */
     39        (PKIX_PL_String *)0,            /* PKIX_PL_String *stringRep */
     40        (PKIX_UInt32)0,                 /* PKIX_UInt32 hashcode */
     41        (PKIX_Boolean)PKIX_FALSE,       /* PKIX_Boolean hashcodeCached */
     42    }, {
     43        (PKIX_ERRORCODE)0,              /* PKIX_ERRORCODE errCode; */
     44        (PKIX_ERRORCLASS)PKIX_FATAL_ERROR,/* PKIX_ERRORCLASS errClass */
     45        (PKIX_UInt32)SEC_ERROR_LIBPKIX_INTERNAL, /* default PL Error Code */
     46        (PKIX_Error *)0,                /* PKIX_Error *cause */
     47        (PKIX_PL_Object *)0,            /* PKIX_PL_Object *info */
     48   }
     49 };
     50 
     51 PKIX_Error* PKIX_ALLOC_ERROR(void)
     52 {
     53    return (PKIX_Error *)&pkix_Alloc_Error_Data.error;
     54 }
     55 
     56 #ifdef PKIX_OBJECT_LEAK_TEST
     57 SECStatus
     58 pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable)
     59 {
     60    int   typeCounter = 0;
     61 
     62    for (; typeCounter < PKIX_NUMTYPES; typeCounter++) {
     63        pkix_ClassTable_Entry *entry = &systemClasses[typeCounter];
     64 
     65        objCountTable[typeCounter] = entry->objCounter;
     66    }
     67 
     68    return SECSuccess;
     69 }
     70 #endif /* PKIX_OBJECT_LEAK_TEST */
     71 
     72 
     73 PKIX_UInt32
     74 pkix_pl_lifecycle_ObjectLeakCheck(int *initObjCountTable)
     75 {
     76        unsigned int typeCounter = 0;
     77        PKIX_UInt32 numObjects = 0;
     78        char  classNameBuff[128];
     79        char *className = NULL;
     80 
     81        for (; typeCounter < PKIX_NUMTYPES; typeCounter++) {
     82                pkix_ClassTable_Entry *entry = &systemClasses[typeCounter];
     83                PKIX_UInt32 objCountDiff = entry->objCounter;
     84 
     85                if (initObjCountTable) {
     86                    PKIX_UInt32 initialCount = initObjCountTable[typeCounter];
     87                    objCountDiff = (entry->objCounter > initialCount) ?
     88                        entry->objCounter - initialCount : 0;
     89                }
     90 
     91                numObjects += objCountDiff;
     92                
     93                if (!pkixLog || !objCountDiff) {
     94                    continue;
     95                }
     96                className = entry->description;
     97                if (!className) {
     98                    className = classNameBuff;
     99                    PR_snprintf(className, 128, "Unknown(ref %d)", 
    100                            entry->objCounter);
    101                }
    102 
    103                PR_LOG(pkixLog, 1, ("Class %s leaked %d objects of "
    104                        "size %d bytes, total = %d bytes\n", className, 
    105                        objCountDiff, entry->typeObjectSize,
    106                        objCountDiff * entry->typeObjectSize));
    107        }
    108 
    109        return numObjects;
    110 }
    111 
    112 /*
    113 * PKIX_PL_Initialize (see comments in pkix_pl_system.h)
    114 */
    115 PKIX_Error *
    116 PKIX_PL_Initialize(
    117        PKIX_Boolean platformInitNeeded,
    118        PKIX_Boolean useArenas,
    119        void **pPlContext)
    120 {
    121        void *plContext = NULL;
    122 
    123        PKIX_ENTER(OBJECT, "PKIX_PL_Initialize");
    124 
    125        /*
    126         * This function can only be called once. If it has already been
    127         * called, we return a positive status.
    128         */
    129        if (pkix_pl_initialized) {
    130            PKIX_RETURN(OBJECT);
    131        }
    132 
    133        classTableLock = PR_NewLock();
    134        if (classTableLock == NULL) {
    135            return PKIX_ALLOC_ERROR();
    136        }
    137 
    138        if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) {
    139            pkixLog = PR_NewLogModule("pkix");
    140        }
    141        /*
    142         * Register Object, it is the base object of all other objects.
    143         */
    144        pkix_pl_Object_RegisterSelf(plContext);
    145 
    146        /*
    147         * Register Error and String, since they will be needed if
    148         * there is a problem in registering any other type.
    149         */
    150        pkix_Error_RegisterSelf(plContext);
    151        pkix_pl_String_RegisterSelf(plContext);
    152 
    153 
    154        /*
    155         * We register all other system types
    156         * (They don't need to be in order, but it's
    157         * easier to keep track of what types are registered
    158         * if we register them in the same order as their
    159         * numbers, defined in pkixt.h.
    160         */
    161        pkix_pl_BigInt_RegisterSelf(plContext);   /* 1-10 */
    162        pkix_pl_ByteArray_RegisterSelf(plContext);
    163        pkix_pl_HashTable_RegisterSelf(plContext);
    164        pkix_List_RegisterSelf(plContext);
    165        pkix_Logger_RegisterSelf(plContext);
    166        pkix_pl_Mutex_RegisterSelf(plContext);
    167        pkix_pl_OID_RegisterSelf(plContext);
    168        pkix_pl_RWLock_RegisterSelf(plContext);
    169 
    170        pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */
    171        pkix_pl_Cert_RegisterSelf(plContext);
    172        pkix_pl_CRL_RegisterSelf(plContext);
    173        pkix_pl_CRLEntry_RegisterSelf(plContext);
    174        pkix_pl_Date_RegisterSelf(plContext);
    175        pkix_pl_GeneralName_RegisterSelf(plContext);
    176        pkix_pl_CertNameConstraints_RegisterSelf(plContext);
    177        pkix_pl_PublicKey_RegisterSelf(plContext);
    178        pkix_TrustAnchor_RegisterSelf(plContext);
    179 
    180        pkix_pl_X500Name_RegisterSelf(plContext);   /* 21-30 */
    181        pkix_pl_HttpCertStoreContext_RegisterSelf(plContext);
    182        pkix_BuildResult_RegisterSelf(plContext);
    183        pkix_ProcessingParams_RegisterSelf(plContext);
    184        pkix_ValidateParams_RegisterSelf(plContext);
    185        pkix_ValidateResult_RegisterSelf(plContext);
    186        pkix_CertStore_RegisterSelf(plContext);
    187        pkix_CertChainChecker_RegisterSelf(plContext);
    188        pkix_RevocationChecker_RegisterSelf(plContext);
    189        pkix_CertSelector_RegisterSelf(plContext);
    190 
    191        pkix_ComCertSelParams_RegisterSelf(plContext);   /* 31-40 */
    192        pkix_CRLSelector_RegisterSelf(plContext);
    193        pkix_ComCRLSelParams_RegisterSelf(plContext);
    194        pkix_pl_CertPolicyInfo_RegisterSelf(plContext);
    195        pkix_pl_CertPolicyQualifier_RegisterSelf(plContext);
    196        pkix_pl_CertPolicyMap_RegisterSelf(plContext);
    197        pkix_PolicyNode_RegisterSelf(plContext);
    198        pkix_TargetCertCheckerState_RegisterSelf(plContext);
    199        pkix_BasicConstraintsCheckerState_RegisterSelf(plContext);
    200        pkix_PolicyCheckerState_RegisterSelf(plContext);
    201 
    202        pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext); /* 41-50 */
    203        pkix_CrlChecker_RegisterSelf(plContext);
    204        pkix_ForwardBuilderState_RegisterSelf(plContext);
    205        pkix_SignatureCheckerState_RegisterSelf(plContext);
    206        pkix_NameConstraintsCheckerState_RegisterSelf(plContext);
    207 #ifndef NSS_PKIX_NO_LDAP
    208        pkix_pl_LdapRequest_RegisterSelf(plContext);
    209        pkix_pl_LdapResponse_RegisterSelf(plContext);
    210        pkix_pl_LdapDefaultClient_RegisterSelf(plContext);
    211 #endif
    212        pkix_pl_Socket_RegisterSelf(plContext);
    213 
    214        pkix_ResourceLimits_RegisterSelf(plContext); /* 51-59 */
    215        pkix_pl_MonitorLock_RegisterSelf(plContext);
    216        pkix_pl_InfoAccess_RegisterSelf(plContext);
    217        pkix_pl_AIAMgr_RegisterSelf(plContext);
    218        pkix_OcspChecker_RegisterSelf(plContext);
    219        pkix_pl_OcspCertID_RegisterSelf(plContext);
    220        pkix_pl_OcspRequest_RegisterSelf(plContext);
    221        pkix_pl_OcspResponse_RegisterSelf(plContext);
    222        pkix_pl_HttpDefaultClient_RegisterSelf(plContext);
    223        pkix_VerifyNode_RegisterSelf(plContext);
    224        pkix_EkuChecker_RegisterSelf(plContext);
    225        pkix_pl_CrlDp_RegisterSelf(plContext);
    226 
    227        if (pPlContext) {
    228            PKIX_CHECK(PKIX_PL_NssContext_Create
    229                       (0, useArenas, NULL, &plContext),
    230                       PKIX_NSSCONTEXTCREATEFAILED);
    231            
    232            *pPlContext = plContext;
    233        }
    234 
    235        pkix_pl_initialized = PKIX_TRUE;
    236 
    237 cleanup:
    238 
    239        PKIX_RETURN(OBJECT);
    240 }
    241 
    242 /*
    243 * PKIX_PL_Shutdown (see comments in pkix_pl_system.h)
    244 */
    245 PKIX_Error *
    246 PKIX_PL_Shutdown(void *plContext)
    247 {
    248 #ifdef DEBUG
    249        PKIX_UInt32 numLeakedObjects = 0;
    250 #endif
    251 
    252        PKIX_ENTER(OBJECT, "PKIX_PL_Shutdown");
    253 
    254        if (!pkix_pl_initialized) {
    255            /* The library was not initilized */
    256            PKIX_RETURN(OBJECT);
    257        }
    258 
    259        PR_DestroyLock(classTableLock);
    260 
    261        pkix_pl_HttpCertStore_Shutdown(plContext);
    262 
    263 #ifdef DEBUG
    264        numLeakedObjects = pkix_pl_lifecycle_ObjectLeakCheck(NULL);
    265        if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) {
    266           PORT_Assert(numLeakedObjects == 0);
    267        }
    268 #else
    269        pkix_pl_lifecycle_ObjectLeakCheck(NULL);
    270 #endif
    271 
    272        if (plContext != NULL) {
    273                PKIX_PL_NssContext_Destroy(plContext);
    274        }
    275 
    276        pkix_pl_initialized = PKIX_FALSE;
    277 
    278        PKIX_RETURN(OBJECT);
    279 }