/* * FUNCTION: pkix_UnlockObject * DESCRIPTION: * * Unlocks the object pointed to by "object". * * PARAMETERS: * "object" * Address of Object. Must be non-NULL * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_UnlockObject( PKIX_PL_Object *object, void *plContext) { PKIX_PL_Object *objectHeader; PRStatus result; PKIX_ENTER(OBJECT, "pkix_UnlockObject"); PKIX_NULLCHECK_ONE(object); if (object == (PKIX_PL_Object *)PKIX_ALLOC_ERROR()) { goto cleanup; } PKIX_OBJECT_DEBUG("\tShifting object pointer).\n"); /* The header is sizeof(PKIX_PL_Object) before the object pointer */ objectHeader = object-1; PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n"); result = PR_Unlock(objectHeader->lock); if (result == PR_FAILURE) { PKIX_OBJECT_DEBUG("\tPR_Unlock failed.).\n"); PKIX_ERROR_FATAL(PKIX_ERRORUNLOCKINGOBJECT); } cleanup: PKIX_RETURN(OBJECT); }
/* * FUNCTION: pkix_LockObject * DESCRIPTION: * * Locks the object pointed to by "object". * * PARAMETERS: * "object" * Address of object. Must be non-NULL * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_LockObject( PKIX_PL_Object *object, void *plContext) { PKIX_PL_Object *objectHeader; PKIX_ENTER(OBJECT, "pkix_LockObject"); PKIX_NULLCHECK_ONE(object); if (object == (PKIX_PL_Object *)PKIX_ALLOC_ERROR()) { goto cleanup; } PKIX_OBJECT_DEBUG("\tShifting object pointer).\n"); /* The header is sizeof(PKIX_PL_Object) before the object pointer */ objectHeader = object-1; PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n"); PR_Lock(objectHeader->lock); cleanup: PKIX_RETURN(OBJECT); }
/* * FUNCTION: PKIX_Error_GetCause (see comments in pkix_util.h) */ PKIX_Error * PKIX_Error_GetCause( PKIX_Error *error, PKIX_Error **pCause, void *plContext) { PKIX_ENTER(ERROR, "PKIX_Error_GetCause"); PKIX_NULLCHECK_TWO(error, pCause); if (error->cause != PKIX_ALLOC_ERROR()){ PKIX_INCREF(error->cause); } *pCause = error->cause; cleanup: PKIX_RETURN(ERROR); }
/* * FUNCTION: PKIX_PL_Object_IncRef (see comments in pkix_pl_system.h) */ PKIX_Error * PKIX_PL_Object_IncRef( PKIX_PL_Object *object, void *plContext) { PKIX_PL_Object *objectHeader = NULL; PKIX_PL_NssContext *context = NULL; PKIX_Int32 refCount = 0; PKIX_ENTER(OBJECT, "PKIX_PL_Object_IncRef"); PKIX_NULLCHECK_ONE(object); if (plContext){ /* * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't * have a header therefore we cannot verify its type before * casting. */ context = (PKIX_PL_NssContext *) plContext; if (context->arena != NULL) { goto cleanup; } } if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) { goto cleanup; } /* Shift pointer from user data to object header */ PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext), PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT); /* This object should never have zero references */ refCount = PR_ATOMIC_INCREMENT(&objectHeader->references); if (refCount <= 1) { PKIX_THROW(FATAL, PKIX_OBJECTWITHNONPOSITIVEREFERENCES); } cleanup: PKIX_RETURN(OBJECT); }
/* * PKIX_PL_Initialize (see comments in pkix_pl_system.h) */ PKIX_Error * PKIX_PL_Initialize( PKIX_Boolean platformInitNeeded, PKIX_Boolean useArenas, void **pPlContext) { void *plContext = NULL; PKIX_ENTER(OBJECT, "PKIX_PL_Initialize"); /* * This function can only be called once. If it has already been * called, we return a positive status. */ if (pkix_pl_initialized) { PKIX_RETURN(OBJECT); } classTableLock = PR_NewLock(); if (classTableLock == NULL) { return PKIX_ALLOC_ERROR(); } if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) { pkixLog = PR_NewLogModule("pkix"); } /* * Register Object, it is the base object of all other objects. */ pkix_pl_Object_RegisterSelf(plContext); /* * Register Error and String, since they will be needed if * there is a problem in registering any other type. */ pkix_Error_RegisterSelf(plContext); pkix_pl_String_RegisterSelf(plContext); /* * We register all other system types * (They don't need to be in order, but it's * easier to keep track of what types are registered * if we register them in the same order as their * numbers, defined in pkixt.h. */ pkix_pl_BigInt_RegisterSelf(plContext); /* 1-10 */ pkix_pl_ByteArray_RegisterSelf(plContext); pkix_pl_HashTable_RegisterSelf(plContext); pkix_List_RegisterSelf(plContext); pkix_Logger_RegisterSelf(plContext); pkix_pl_Mutex_RegisterSelf(plContext); pkix_pl_OID_RegisterSelf(plContext); pkix_pl_RWLock_RegisterSelf(plContext); pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */ pkix_pl_Cert_RegisterSelf(plContext); pkix_pl_CRL_RegisterSelf(plContext); pkix_pl_CRLEntry_RegisterSelf(plContext); pkix_pl_Date_RegisterSelf(plContext); pkix_pl_GeneralName_RegisterSelf(plContext); pkix_pl_CertNameConstraints_RegisterSelf(plContext); pkix_pl_PublicKey_RegisterSelf(plContext); pkix_TrustAnchor_RegisterSelf(plContext); pkix_pl_X500Name_RegisterSelf(plContext); /* 21-30 */ pkix_pl_HttpCertStoreContext_RegisterSelf(plContext); pkix_BuildResult_RegisterSelf(plContext); pkix_ProcessingParams_RegisterSelf(plContext); pkix_ValidateParams_RegisterSelf(plContext); pkix_ValidateResult_RegisterSelf(plContext); pkix_CertStore_RegisterSelf(plContext); pkix_CertChainChecker_RegisterSelf(plContext); pkix_RevocationChecker_RegisterSelf(plContext); pkix_CertSelector_RegisterSelf(plContext); pkix_ComCertSelParams_RegisterSelf(plContext); /* 31-40 */ pkix_CRLSelector_RegisterSelf(plContext); pkix_ComCRLSelParams_RegisterSelf(plContext); pkix_pl_CertPolicyInfo_RegisterSelf(plContext); pkix_pl_CertPolicyQualifier_RegisterSelf(plContext); pkix_pl_CertPolicyMap_RegisterSelf(plContext); pkix_PolicyNode_RegisterSelf(plContext); pkix_TargetCertCheckerState_RegisterSelf(plContext); pkix_BasicConstraintsCheckerState_RegisterSelf(plContext); pkix_PolicyCheckerState_RegisterSelf(plContext); pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext); /* 41-50 */ pkix_CrlChecker_RegisterSelf(plContext); pkix_ForwardBuilderState_RegisterSelf(plContext); pkix_SignatureCheckerState_RegisterSelf(plContext); pkix_NameConstraintsCheckerState_RegisterSelf(plContext); #ifndef NSS_PKIX_NO_LDAP pkix_pl_LdapRequest_RegisterSelf(plContext); pkix_pl_LdapResponse_RegisterSelf(plContext); pkix_pl_LdapDefaultClient_RegisterSelf(plContext); #endif pkix_pl_Socket_RegisterSelf(plContext); pkix_ResourceLimits_RegisterSelf(plContext); /* 51-59 */ pkix_pl_MonitorLock_RegisterSelf(plContext); pkix_pl_InfoAccess_RegisterSelf(plContext); pkix_pl_AIAMgr_RegisterSelf(plContext); pkix_OcspChecker_RegisterSelf(plContext); pkix_pl_OcspCertID_RegisterSelf(plContext); pkix_pl_OcspRequest_RegisterSelf(plContext); pkix_pl_OcspResponse_RegisterSelf(plContext); pkix_pl_HttpDefaultClient_RegisterSelf(plContext); pkix_VerifyNode_RegisterSelf(plContext); pkix_EkuChecker_RegisterSelf(plContext); pkix_pl_CrlDp_RegisterSelf(plContext); if (pPlContext) { PKIX_CHECK(PKIX_PL_NssContext_Create (0, useArenas, NULL, &plContext), PKIX_NSSCONTEXTCREATEFAILED); *pPlContext = plContext; } pkix_pl_initialized = PKIX_TRUE; cleanup: PKIX_RETURN(OBJECT); }
/* * FUNCTION: PKIX_PL_Object_DecRef (see comments in pkix_pl_system.h) */ PKIX_Error * PKIX_PL_Object_DecRef( PKIX_PL_Object *object, void *plContext) { PKIX_Int32 refCount = 0; PKIX_PL_Object *objectHeader = NULL; PKIX_PL_NssContext *context = NULL; PKIX_ENTER(OBJECT, "PKIX_PL_Object_DecRef"); PKIX_NULLCHECK_ONE(object); if (plContext){ /* * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't * have a header therefore we cannot verify its type before * casting. */ context = (PKIX_PL_NssContext *) plContext; if (context->arena != NULL) { goto cleanup; } } if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) { goto cleanup; } /* Shift pointer from user data to object header */ PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext), PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT); refCount = PR_ATOMIC_DECREMENT(&objectHeader->references); if (refCount == 0) { PKIX_PL_DestructorCallback destructor = NULL; pkix_ClassTable_Entry *ctEntry = NULL; PKIX_UInt32 objType = objectHeader->type; /* first, special handling for system types */ if (objType >= PKIX_NUMTYPES){ #ifdef PKIX_USER_OBJECT_TYPE PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n"); PR_Lock(classTableLock); pkixErrorResult = pkix_pl_PrimHashTable_Lookup (classTable, (void *)&objType, objType, NULL, (void **)&ctEntry, plContext); PKIX_OBJECT_DEBUG ("\tCalling PR_Unlock).\n"); PR_Unlock(classTableLock); if (pkixErrorResult){ PKIX_ERROR_FATAL (PKIX_ERRORINGETTINGDESTRUCTOR); } if (ctEntry != NULL){ destructor = ctEntry->destructor; } #else PORT_Assert (0); pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE; pkixErrorClass = PKIX_FATAL_ERROR; goto cleanup; #endif /* PKIX_USER_OBJECT_TYPE */ } else { ctEntry = &systemClasses[objType]; destructor = ctEntry->destructor; } if (destructor != NULL){ /* Call destructor on user data if necessary */ pkixErrorResult = destructor(object, plContext); if (pkixErrorResult) { pkixErrorClass = PKIX_FATAL_ERROR; PKIX_DoAddError(stdVarsPtr, pkixErrorResult, plContext); pkixErrorResult = NULL; } } /* Atomically decrement object counter */ PR_ATOMIC_DECREMENT(&ctEntry->objCounter); /* pkix_pl_Object_Destroy assumes the lock is held */ /* It will call unlock and destroy the object */ pkixErrorResult = pkix_pl_Object_Destroy(object, plContext); goto cleanup; } if (refCount < 0) { PKIX_ERROR_ALLOC_ERROR(); } cleanup: PKIX_RETURN(OBJECT); }