Beispiel #1
0
void
PORT_DestroyCheapArena(PORTCheapArenaPool *pool)
{
    (void)PR_CallOnce(&setupUseFreeListOnce, &SetupUseFreeList);
    if (useFreeList) {
        PL_FreeArenaPool(&pool->arena);
    } else {
        PL_FinishArenaPool(&pool->arena);
    }
}
Beispiel #2
0
static PRStatus LockArena( void )
{
#ifdef	__APPLE__
    return pthread_mutex_lock(&arenaLock) ? PR_FAILURE : PR_SUCCESS;
#else
    PRStatus rc = PR_CallOnce( &once, InitializeArenas );

    if ( PR_FAILURE != rc )
        PR_Lock( arenaLock );
    return(rc);
#endif	/* __APPLE__ */
} /* end LockArena() */
Beispiel #3
0
/*
 * The structures created by this function can be called concurrently on
 * multiple threads if the server is multi-threaded.  A monitor is used to
 * ensure that only one thread can access the structures that change over time,
 * but no such guarantee is provided for configuration data.
 *
 * Functions that read from static configuration data depend on there being a
 * memory barrier between the setup and use of this function.
 */
SECStatus
SSLExp_SetupAntiReplay(PRTime window, unsigned int k, unsigned int bits)
{
    SECStatus rv;

    if (k == 0 || bits == 0) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if ((k * (bits + 7) / 8) > SSL_MAX_BLOOM_FILTER_SIZE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (PR_SUCCESS != PR_CallOnce(&ssl_anti_replay.init,
                                  tls13_AntiReplayInit)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    (void)tls13_AntiReplayReset(NULL, NULL);

    ssl_anti_replay.lock = PZ_NewMonitor(nssILockSSL);
    if (!ssl_anti_replay.lock) {
        goto loser; /* Code already set. */
    }

    rv = tls13_AntiReplayKeyGen();
    if (rv != SECSuccess) {
        goto loser; /* Code already set. */
    }

    rv = sslBloom_Init(&ssl_anti_replay.filters[0], k, bits);
    if (rv != SECSuccess) {
        goto loser; /* Code already set. */
    }
    rv = sslBloom_Init(&ssl_anti_replay.filters[1], k, bits);
    if (rv != SECSuccess) {
        goto loser; /* Code already set. */
    }
    /* When starting out, ensure that 0-RTT is not accepted until the window is
     * updated.  A ClientHello might have been accepted prior to a restart. */
    sslBloom_Fill(&ssl_anti_replay.filters[1]);

    ssl_anti_replay.current = 0;
    ssl_anti_replay.nextUpdate = ssl_TimeUsec() + window;
    ssl_anti_replay.window = window;
    return SECSuccess;

loser:
    (void)tls13_AntiReplayReset(NULL, NULL);
    return SECFailure;
}
Beispiel #4
0
/*
 * Install NSPR thread functions into ld (if ld is NULL, they are installed
 * as the default functions for new LDAP * handles).
 *
 * Returns 0 if all goes well and -1 if not.
 */
int
prldap_install_thread_functions( LDAP *ld, int shared )
{
    struct ldap_thread_fns		tfns;
    struct ldap_extra_thread_fns	xtfns;

    if ( PR_CallOnce( &prldap_callonce_init_tpd, prldap_init_tpd )
		!= PR_SUCCESS ) {
	ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL );
	return( -1 );
    }

    /* set thread function pointers */
    memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
    tfns.ltf_get_errno = prldap_get_system_errno;
    tfns.ltf_set_errno = prldap_set_system_errno;
    if ( shared ) {
	tfns.ltf_mutex_alloc = prldap_mutex_alloc;
	tfns.ltf_mutex_free = prldap_mutex_free;
	tfns.ltf_mutex_lock = prldap_mutex_lock;
	tfns.ltf_mutex_unlock = prldap_mutex_unlock;
	tfns.ltf_get_lderrno = prldap_get_ld_error;
	tfns.ltf_set_lderrno = prldap_set_ld_error;
	if ( ld != NULL ) {
	    /*
	     * If this is a real ld (i.e., we are not setting the global
	     * defaults) allocate thread private data for error information.
	     * If ld is NULL we do not do this here but it is done in
	     * prldap_thread_new_handle().
	     */
	    if (( tfns.ltf_lderrno_arg = (void *)prldap_allocate_map( ld ))
		    == NULL ) {
		return( -1 );
	    }
	}
    }

    if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS,
	    (void *)&tfns ) != 0 ) {
	prldap_return_map( (PRLDAP_TPDMap *)tfns.ltf_lderrno_arg );
	return( -1 );
    }

    /* set extended thread function pointers */
    memset( &xtfns, '\0', sizeof(struct ldap_extra_thread_fns) );
    xtfns.ltf_threadid_fn = prldap_get_thread_id;
    if ( ldap_set_option( ld, LDAP_OPT_EXTRA_THREAD_FN_PTRS,
	    (void *)&xtfns ) != 0 ) {
	return( -1 );
    }

    return( 0 );
}
BlockingResourceBase::BlockingResourceBase(
    const char* aName,
    BlockingResourceBase::BlockingResourceType aType)
{
    // PR_CallOnce guaranatees that InitStatics is called in a
    // thread-safe way
    if (PR_SUCCESS != PR_CallOnce(&sCallOnce, InitStatics))
        NS_RUNTIMEABORT("can't initialize blocking resource static members");

    mDDEntry = new BlockingResourceBase::DeadlockDetectorEntry(aName, aType);
    mChainPrev = 0;
    sDeadlockDetector->Add(mDDEntry);
}
Beispiel #6
0
static void at_bind(AddThread *at)
{
    int ret;
    int retry = 0;
#if defined(USE_OPENLDAP)
    char *ldapurl = NULL;

    at->ld = NULL;
    ldapurl = PR_smprintf("ldap://%s:%d", hostname, port);
    if (PR_SUCCESS != PR_CallOnce(&ol_init_callOnce, internal_ol_init_init)) {
        fprintf(stderr, "Could not perform internal ol_init init\n");
        return;
    }

    PR_Lock(ol_init_lock);
    ret = ldap_initialize(&at->ld, ldapurl);
    PR_Unlock(ol_init_lock);
    PR_smprintf_free(ldapurl);
    ldapurl = NULL;
	if (ret) {
        fprintf(stderr, "T%d: failed to init: %s port %d: %d:%s\n", at->id, hostname, port,
                ret, ldap_err2string(ret));
        return;
	}
#else
    at->ld = ldap_init(hostname, port);
#endif
    if (! at->ld) {
        fprintf(stderr, "T%d: failed to init: %s port %d\n", at->id, hostname, port);
        return;
    }
    while (retry < 10)
    {
        struct berval bvcreds = {0, NULL};
        bvcreds.bv_val = password;
        bvcreds.bv_len = password ? strlen(password) : 0;
        ret = ldap_sasl_bind_s(at->ld, username, LDAP_SASL_SIMPLE, &bvcreds,
                               NULL, NULL, NULL);
        if (LDAP_SUCCESS == ret) {
            return;        /* ok */
        } else if (LDAP_CONNECT_ERROR == ret) {
            retry++;
        } else {
            break;
        }
    }
    fprintf(stderr, "T%d: failed to bind, ldap_sasl_bind_s returned %d\n", 
                   at->id,  ret);
}
Beispiel #7
0
/*
 * Make this public if we need it.
 */
static nsresult NS_TimelineMarkV(const char *text, va_list args)
{
    PRTime elapsed,tmp;

    PR_CallOnce(&initonce, TimelineInit);

    TimelineThreadData *thread = GetThisThreadData();

    tmp = Now();
    LL_SUB(elapsed, tmp, thread->initTime);

    PrintTime(elapsed, text, args);

    return NS_OK;
}
Beispiel #8
0
PRFileDesc *memio_CreateIOLayer(int readbufsize, int writebufsize)
{
    PRFileDesc *fd;
    struct PRFilePrivate *secret;
    static PRCallOnceType once;

    PR_CallOnce(&once, memio_InitializeLayerName);

    fd = PR_CreateIOLayerStub(memio_identity, &memio_layer_methods);
    secret = malloc(sizeof(struct PRFilePrivate));
    memset(secret, 0, sizeof(*secret));

    memio_buffer_new(&secret->readbuf, readbufsize);
    memio_buffer_new(&secret->writebuf, writebufsize);
    fd->secret = secret;
    return fd;
}
Beispiel #9
0
static error_stack *
error_get_my_stack ( void)
{
  PRStatus st;
  error_stack *rv;
  PRUintn new_size;
  PRUint32 new_bytes;
  error_stack *new_stack;

  if( INVALID_TPD_INDEX == error_stack_index ) {
    st = PR_CallOnce(&error_call_once, error_once_function);
    if( PR_SUCCESS != st ) {
      return (error_stack *)NULL;
    }
  }

  rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
  if( (error_stack *)NULL == rv ) {
    /* Doesn't exist; create one */
    new_size = 16;
  } else if( rv->header.count == rv->header.space  &&
             rv->header.count  < NSS_MAX_ERROR_STACK_COUNT ) {
    /* Too small, expand it */
    new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
  } else {
    /* Okay, return it */
    return rv;
  }

  new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
  /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
  new_stack = PR_Calloc(1, new_bytes);
  
  if( (error_stack *)NULL != new_stack ) {
    if( (error_stack *)NULL != rv ) {
	(void)nsslibc_memcpy(new_stack,rv,rv->header.space);
    }
    new_stack->header.space = new_size;
  }

  /* Set the value, whether or not the allocation worked */
  PR_SetThreadPrivate(error_stack_index, new_stack);
  return new_stack;
}
NSAPI_PUBLIC int session_alloc_thread_slot(SlotDestructorFuncPtr destructor)
{
    PR_CallOnce(&_session_thread_once, &session_thread_init);

    PR_Lock(_session_thread_lock);

    int slot = _session_thread_slots;
    _session_thread_slots++;

    _session_thread_destructors = (SlotDestructorFuncPtr*)
        PERM_REALLOC(_session_thread_destructors,
                     sizeof(_session_thread_destructors[0]) *
                     _session_thread_slots);
    _session_thread_destructors[slot] = destructor;

    PR_Unlock(_session_thread_lock);

    return slot;
}
Beispiel #11
0
/* lazyInit means that the call is not happening during a 1-time
 * initialization function, but rather during dynamic, lazy initialization
 */
SECStatus
ssl_InitSessionCacheLocks(PRBool lazyInit)
{
    if (LocksInitializedEarly) {
        return SECSuccess;
    }

    if (lazyInit) {
        return (PR_SUCCESS ==
                PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ?
               SECSuccess : SECFailure;
    }
     
    if (SECSuccess == InitSessionCacheLocks()) {
        LocksInitializedEarly = PR_TRUE;
        return SECSuccess;
    }

    return SECFailure;
}
NSAPI_PUBLIC void session_destroy_thread(Session *sn)
{
    PR_CallOnce(&_session_thread_once, &session_thread_init);

    PR_Lock(_session_thread_lock);

    SessionThreadData *thread_data = find_thread_data(sn);
    if (thread_data) {
        // Call the destructors for all non-NULL slots
        for (int i = 0; i < thread_data->count && i < _session_thread_slots; i++) {
            if (thread_data->slots[i]) {
                if (_session_thread_destructors[i])
                    (_session_thread_destructors[i])(thread_data->slots[i]);
                thread_data->slots[i] = NULL;
            }
        }
    }

    PR_Unlock(_session_thread_lock);
}
Beispiel #13
0
PR_IMPLEMENT(nsresult) NS_TimelineMark(const char *text, ...)
{
    va_list args;

    PR_CallOnce(&initonce, TimelineInit);

    if (gTimelineDisabled)
        return NS_ERROR_NOT_AVAILABLE;

    TimelineThreadData *thread = GetThisThreadData();

    if (thread->disabled)
        return NS_ERROR_NOT_AVAILABLE;

    va_start(args, text);
    NS_TimelineMarkV(text, args);
    va_end(args);

    return NS_OK;
}
LdapSessionPool::LdapSessionPool(LdapRealm *ldapRealm,int limit)
{
    _ldapRealm = ldapRealm;
    _maxSessions = (limit < 1 ? 1 : limit);
    _waiters = 0;
    _lock = PR_NewLock();
    assert(_lock);
    _cvar = PR_NewCondVar(_lock);
    assert(_cvar);

    // add new pool to list of all pools
    if (_poolListLock == NULL) {
        static PRCallOnceType once = { 0, 0, (PRStatus)0 };
        PR_CallOnce(&once, PoolListCreate);
    }
    PR_Lock(_poolListLock);
    _nextPool = _poolList;
    _poolList = this;
    PR_Unlock(_poolListLock);
}
/*
 * This function is based on CERT_DecodeCertPackage from lib/pkcs7/certread.c
 * read an old style ascii or binary certificate chain
 */
PKIX_Error *
pkix_pl_HttpCertStore_DecodeCertPackage
        (const char *certbuf,
        int certlen,
        CERTImportCertificateFunc f,
        void *arg,
        void *plContext)
{
   
        PRStatus status;
        SECStatus rv;

        PKIX_ENTER
                (HTTPCERTSTORECONTEXT,
                "pkix_pl_HttpCertStore_DecodeCertPackage");
        PKIX_NULLCHECK_TWO(certbuf, f);

        status = PR_CallOnce(&pkix_decodeFunc.once, pkix_getDecodeFunction);

        if (status != PR_SUCCESS) {
               PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
        }

        /* paranoia, shouldn't happen if status == PR_SUCCESS); */
        if (!pkix_decodeFunc.func) {
               PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
        }

        rv = (*pkix_decodeFunc.func)((char*)certbuf, certlen, f, arg);

        if (rv != SECSuccess) {
                PKIX_ERROR (PKIX_SECREADPKCS7CERTSFAILED);
        }
    

cleanup:

        PKIX_RETURN(HTTPCERTSTORECONTEXT);
}
NSTP_Initialize (const NSTPGlobalConfig *config, PRIntn *vmin, PRIntn *vmax)
{
    PRStatus rv = PR_SUCCESS;
	
    /* Return the minimum and maximum version numbers if possible */
    if (vmin)
        *vmin = NSTP_API_VERSION_MIN;
    if (vmax)
        *vmax = NSTP_API_VERSION_MAX;
	
    /* If configuration is present, validate version number */
    if (config && (config -> version < NSTP_API_VERSION_MIN ||
		config -> version > NSTP_API_VERSION_MAX))
	{
        rv = PR_FAILURE;
    }
    else
	{
		hasTimeout = config -> tmoEnable;
        rv = PR_CallOnce (&once, InitializePoolLock);
    }
	
    return rv;
}
Beispiel #17
0
SECStatus
NSS_InitializePRErrorTable(void)
{
    return (PR_SUCCESS == PR_CallOnce(&once, nss_InitializePRErrorTableOnce))
		? SECSuccess : SECFailure;
}
 State()
 {
   PR_CallOnce(&ARENA_POISON_guard, ARENA_POISON_init);
 }
 State()
 {
   mFreeLists.Init();
   PL_INIT_ARENA_POOL(&mPool, "PresArena", ARENA_PAGE_SIZE);
   PR_CallOnce(&ARENA_POISON_guard, ARENA_POISON_init);
 }
Beispiel #20
0
/*
 * load a new module into our address space and initialize it.
 */
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
    PRLibrary *library = NULL;
    CK_C_GetFunctionList entry = NULL;
    CK_INFO info;
    CK_ULONG slotCount = 0;
    SECStatus rv;
    PRBool alreadyLoaded = PR_FALSE;
    char *disableUnload = NULL;

    if (mod->loaded)
        return SECSuccess;

    /* internal modules get loaded from their internal list */
    if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_TEST_BUILD
        entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
        /*
         * Loads softoken as a dynamic library,
         * even though the rest of NSS assumes this as the "internal" module.
         */
        if (!softokenLib &&
            PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
            return SECFailure;

        PR_ATOMIC_INCREMENT(&softokenLoadCount);

        if (mod->isFIPS) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "FC_GetFunctionList");
        } else {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
        }

        if (!entry)
            return SECFailure;
#endif

        if (mod->isModuleDB) {
            mod->moduleDBFunc = (CK_C_GetFunctionList)
#ifdef NSS_TEST_BUILD
                NSC_ModuleDBFunc;
#else
                PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
#endif
        }

        if (mod->moduleDBOnly) {
            mod->loaded = PR_TRUE;
            return SECSuccess;
        }
    } else {
        /* Not internal, load the DLL and look up C_GetFunctionList */
        if (mod->dllName == NULL) {
            return SECFailure;
        }

        /* load the library. If this succeeds, then we have to remember to
         * unload the library if anything goes wrong from here on out...
         */
        library = PR_LoadLibrary(mod->dllName);
        mod->library = (void *)library;

        if (library == NULL) {
            return SECFailure;
        }

        /*
         * now we need to get the entry point to find the function pointers
         */
        if (!mod->moduleDBOnly) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(library, "C_GetFunctionList");
        }
        if (mod->isModuleDB) {
            mod->moduleDBFunc = (void *)
                PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
        }
        if (mod->moduleDBFunc == NULL)
            mod->isModuleDB = PR_FALSE;
        if (entry == NULL) {
            if (mod->isModuleDB) {
                mod->loaded = PR_TRUE;
                mod->moduleDBOnly = PR_TRUE;
                return SECSuccess;
            }
            PR_UnloadLibrary(library);
            return SECFailure;
        }
    }

    /*
     * We need to get the function list
     */
    if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
        goto fail;

#ifdef DEBUG_MODULE
    if (PR_TRUE) {
        modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
        if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
            mod->functionList = (void *)nss_InsertDeviceLog(
                (CK_FUNCTION_LIST_PTR)mod->functionList);
        }
    }
#endif

    mod->isThreadSafe = PR_TRUE;

    /* Now we initialize the module */
    rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
    if (rv != SECSuccess) {
        goto fail;
    }

    /* module has been reloaded, this module itself is done,
     * return to the caller */
    if (mod->functionList == NULL) {
        mod->loaded = PR_TRUE; /* technically the module is loaded.. */
        return SECSuccess;
    }

    /* check the version number */
    if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
        goto fail2;
    if (info.cryptokiVersion.major != 2)
        goto fail2;
    /* all 2.0 are a priori *not* thread safe */
    if (info.cryptokiVersion.minor < 1) {
        if (!loadSingleThreadedModules) {
            PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
            goto fail2;
        } else {
            mod->isThreadSafe = PR_FALSE;
        }
    }
    mod->cryptokiVersion = info.cryptokiVersion;

    /* If we don't have a common name, get it from the PKCS 11 module */
    if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
        mod->commonName = PK11_MakeString(mod->arena, NULL,
                                          (char *)info.libraryDescription, sizeof(info.libraryDescription));
        if (mod->commonName == NULL)
            goto fail2;
    }

    /* initialize the Slots */
    if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
        CK_SLOT_ID *slotIDs;
        int i;
        CK_RV crv;

        mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
                                                      sizeof(PK11SlotInfo *) * slotCount);
        if (mod->slots == NULL)
            goto fail2;

        slotIDs = (CK_SLOT_ID *)PORT_Alloc(sizeof(CK_SLOT_ID) * slotCount);
        if (slotIDs == NULL) {
            goto fail2;
        }
        crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
        if (crv != CKR_OK) {
            PORT_Free(slotIDs);
            goto fail2;
        }

        /* Initialize each slot */
        for (i = 0; i < (int)slotCount; i++) {
            mod->slots[i] = PK11_NewSlotInfo(mod);
            PK11_InitSlot(mod, slotIDs[i], mod->slots[i]);
            /* look down the slot info table */
            PK11_LoadSlotList(mod->slots[i], mod->slotInfo, mod->slotInfoCount);
            SECMOD_SetRootCerts(mod->slots[i], mod);
            /* explicitly mark the internal slot as such if IsInternalKeySlot()
             * is set */
            if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
                pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
            }
        }
        mod->slotCount = slotCount;
        mod->slotInfoCount = 0;
        PORT_Free(slotIDs);
    }

    mod->loaded = PR_TRUE;
    mod->moduleID = nextModuleID++;
    return SECSuccess;
fail2:
    if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
        PK11_GETTAB(mod)->C_Finalize(NULL);
    }
fail:
    mod->functionList = NULL;
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (library && !disableUnload) {
        PR_UnloadLibrary(library);
    }
    return SECFailure;
}
Beispiel #21
0
static SECStatus
get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
                    mp_int *f, mp_int *g)
{
    SECStatus rv = SECSuccess;
    mp_err err = MP_OKAY;
    int cmp;
    PRCList *el;
    struct RSABlindingParamsStr *rsabp = NULL;
    /* Init the list if neccessary (the init function is only called once!) */
    if (blindingParamsList.lock == NULL) {
	if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) {
	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	    return SECFailure;
	}
    }
    /* Acquire the list lock */
    PZ_Lock(blindingParamsList.lock);
    /* Walk the list looking for the private key */
    for (el = PR_NEXT_LINK(&blindingParamsList.head);
         el != &blindingParamsList.head;
         el = PR_NEXT_LINK(el)) {
	rsabp = (struct RSABlindingParamsStr *)el;
	cmp = SECITEM_CompareItem(&rsabp->modulus, &key->modulus);
	if (cmp == 0) {
	    /* Check the usage counter for the parameters */
	    if (--rsabp->counter <= 0) {
		/* Regenerate the blinding parameters */
		CHECK_SEC_OK( generate_blinding_params(rsabp, key, n, modLen) );
	    }
	    /* Return the parameters */
	    CHECK_MPI_OK( mp_copy(&rsabp->f, f) );
	    CHECK_MPI_OK( mp_copy(&rsabp->g, g) );
	    /* Now that the params are located, release the list lock. */
	    PZ_Unlock(blindingParamsList.lock); /* XXX when fails? */
	    return SECSuccess;
	} else if (cmp > 0) {
	    /* The key is not in the list.  Break to param creation. */
	    break;
	}
    }
    /* At this point, the key is not in the list.  el should point to the
    ** list element that this key should be inserted before.  NOTE: the list
    ** lock is still held, so there cannot be a race condition here.
    */
    rsabp = (struct RSABlindingParamsStr *)
              PORT_ZAlloc(sizeof(struct RSABlindingParamsStr));
    if (!rsabp) {
	PORT_SetError(SEC_ERROR_NO_MEMORY);
	goto cleanup;
    }
    /* Initialize the list pointer for the element */
    PR_INIT_CLIST(&rsabp->link);
    /* Initialize the blinding parameters 
    ** This ties up the list lock while doing some heavy, element-specific
    ** operations, but we don't want to insert the element until it is valid,
    ** which requires computing the blinding params.  If this proves costly,
    ** it could be done after the list lock is released, and then if it fails
    ** the lock would have to be reobtained and the invalid element removed.
    */
    rv = init_blinding_params(rsabp, key, n, modLen);
    if (rv != SECSuccess) {
	PORT_ZFree(rsabp, sizeof(struct RSABlindingParamsStr));
	goto cleanup;
    }
    /* Insert the new element into the list
    ** If inserting in the middle of the list, el points to the link
    ** to insert before.  Otherwise, the link needs to be appended to
    ** the end of the list, which is the same as inserting before the
    ** head (since el would have looped back to the head).
    */
    PR_INSERT_BEFORE(&rsabp->link, el);
    /* Return the parameters */
    CHECK_MPI_OK( mp_copy(&rsabp->f, f) );
    CHECK_MPI_OK( mp_copy(&rsabp->g, g) );
    /* Release the list lock */
    PZ_Unlock(blindingParamsList.lock); /* XXX when fails? */
    return SECSuccess;
cleanup:
    /* It is possible to reach this after the lock is already released.
    ** Ignore the error in that case.
    */
    PZ_Unlock(blindingParamsList.lock);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    return SECFailure;
}
Beispiel #22
0
static void*
GetNetUtilsLibHandle()
{
  PR_CallOnce(&sInitNetUtilsLib, InitNetUtilsLib);
  return sNetUtilsLib;
}
Beispiel #23
0
SECStatus   
AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, 
	        const unsigned char *iv, int mode, unsigned int encrypt,
	        unsigned int blocksize)
{
#if USE_HW_AES
    static int has_intel_aes;
    PRBool use_hw_aes = PR_FALSE;
#endif
    unsigned int Nk;
    /* According to Rijndael AES Proposal, section 12.1, block and key
     * lengths between 128 and 256 bits are supported, as long as the
     * length in bytes is divisible by 4.
     */
    if (key == NULL || 
        keysize < RIJNDAEL_MIN_BLOCKSIZE   || 
	keysize > RIJNDAEL_MAX_BLOCKSIZE   || 
	keysize % 4 != 0 ||
        blocksize < RIJNDAEL_MIN_BLOCKSIZE || 
	blocksize > RIJNDAEL_MAX_BLOCKSIZE || 
	blocksize % 4 != 0) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (mode != NSS_AES && mode != NSS_AES_CBC) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (mode == NSS_AES_CBC && iv == NULL) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (!cx) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
    	return SECFailure;
    }
#if USE_HW_AES
    if (has_intel_aes == 0) {
	unsigned long eax, ebx, ecx, edx;
	char *disable_hw_aes = getenv("NSS_DISABLE_HW_AES");

	if (disable_hw_aes == NULL) {
	    freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
	    has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
	} else {
	    has_intel_aes = -1;
	}
    }
    use_hw_aes = (PRBool)
		(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
#endif
    /* Nb = (block size in bits) / 32 */
    cx->Nb = blocksize / 4;
    /* Nk = (key size in bits) / 32 */
    Nk = keysize / 4;
    /* Obtain number of rounds from "table" */
    cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
    /* copy in the iv, if neccessary */
    if (mode == NSS_AES_CBC) {
	memcpy(cx->iv, iv, blocksize);
#if USE_HW_AES
	if (use_hw_aes) {
	    cx->worker = intel_aes_cbc_worker(encrypt, keysize);
	} else
#endif
	    cx->worker = (encrypt
			  ? &rijndael_encryptCBC : &rijndael_decryptCBC);
    } else {
#if  USE_HW_AES
	if (use_hw_aes) {
	    cx->worker = intel_aes_ecb_worker(encrypt, keysize);
	} else
#endif
	    cx->worker = (encrypt
			  ? &rijndael_encryptECB : &rijndael_decryptECB);
    }
    PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
    if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	goto cleanup;
    }
#ifdef USE_HW_AES
    if (use_hw_aes) {
	intel_aes_init(encrypt, keysize);
    } else
#endif
    {

#if defined(RIJNDAEL_GENERATE_TABLES) ||  \
	defined(RIJNDAEL_GENERATE_TABLES_MACRO)
	if (rijndaelTables == NULL) {
	    if (PR_CallOnce(&coRTInit, init_rijndael_tables)
	      != PR_SUCCESS) {
		return SecFailure;
	    }
	}
#endif
	/* Generate expanded key */
	if (encrypt) {
	    if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
		goto cleanup;
	} else {
	    if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess)
		goto cleanup;
	}
    }
    return SECSuccess;
cleanup:
    return SECFailure;
}
Beispiel #24
0
JSInt64
PRMJ_Now(void)
{
#ifdef XP_OS2
    JSInt64 s, us, ms2us, s2us;
    struct timeb b;
#endif
#ifdef XP_WIN
    static int nCalls = 0;
    long double lowresTime, highresTimerValue;
    FILETIME ft;
    LARGE_INTEGER now;
    JSBool calibrated = JS_FALSE;
    JSBool needsCalibration = JS_FALSE;
    JSInt64 returnedTime;
    long double cachedOffset = 0.0;
#endif
#if defined(XP_UNIX) || defined(XP_BEOS)
    struct timeval tv;
    JSInt64 s, us, s2us;
#endif /* XP_UNIX */

#ifdef XP_OS2
    ftime(&b);
    JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
    JSLL_UI2L(s, b.time);
    JSLL_UI2L(us, b.millitm);
    JSLL_MUL(us, us, ms2us);
    JSLL_MUL(s, s, s2us);
    JSLL_ADD(s, s, us);
    return s;
#endif
#ifdef XP_WIN

    /* To avoid regressing startup time (where high resolution is likely
       not needed), give the old behavior for the first few calls.
       This does not appear to be needed on Vista as the timeBegin/timeEndPeriod
       calls seem to immediately take effect. */
    int thiscall = JS_ATOMIC_INCREMENT(&nCalls);
    /* 10 seems to be the number of calls to load with a blank homepage */
    if (thiscall <= 10) {
        GetSystemTimeAsFileTime(&ft);
        return (FILETIME2INT64(ft)-win2un)/10L;
    }

    /* For non threadsafe platforms, NowInit is not necessary */
#ifdef JS_THREADSAFE
    PR_CallOnce(&calibrationOnce, NowInit);
#endif
    do {
        if (!calibration.calibrated || needsCalibration) {
            MUTEX_LOCK(&calibration.calibration_lock);
            MUTEX_LOCK(&calibration.data_lock);

            /* Recalibrate only if no one else did before us */
            if(calibration.offset == cachedOffset) {
                /* Since calibration can take a while, make any other
                   threads immediately wait */
                MUTEX_SETSPINCOUNT(&calibration.data_lock, 0);

                NowCalibrate();

                calibrated = JS_TRUE;

                /* Restore spin count */
                MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT);
            }
            MUTEX_UNLOCK(&calibration.data_lock);
            MUTEX_UNLOCK(&calibration.calibration_lock);
        }


        /* Calculate a low resolution time */
        GetSystemTimeAsFileTime(&ft);
        lowresTime = 0.1*(long double)(FILETIME2INT64(ft) - win2un);

        if (calibration.freq > 0.0) {
            long double highresTime, diff;

            DWORD timeAdjustment, timeIncrement;
            BOOL timeAdjustmentDisabled;

            /* Default to 15.625 ms if the syscall fails */
            long double skewThreshold = 15625.25;
            /* Grab high resolution time */
            QueryPerformanceCounter(&now);
            highresTimerValue = (long double)now.QuadPart;

            MUTEX_LOCK(&calibration.data_lock);
            highresTime = calibration.offset + PRMJ_USEC_PER_SEC*
                 (highresTimerValue-calibration.timer_offset)/calibration.freq;
            cachedOffset = calibration.offset;

            /* On some dual processor/core systems, we might get an earlier time
               so we cache the last time that we returned */
            calibration.last = max(calibration.last,(JSInt64)highresTime);
            returnedTime = calibration.last;
            MUTEX_UNLOCK(&calibration.data_lock);

            /* Rather than assume the NT kernel ticks every 15.6ms, ask it */
            if (GetSystemTimeAdjustment(&timeAdjustment,
                                        &timeIncrement,
                                        &timeAdjustmentDisabled)) {
                if (timeAdjustmentDisabled) {
                    /* timeAdjustment is in units of 100ns */
                    skewThreshold = timeAdjustment/10.0;
                } else {
                    /* timeIncrement is in units of 100ns */
                    skewThreshold = timeIncrement/10.0;
                }
            }

            /* Check for clock skew */
            diff = lowresTime - highresTime;

            /* For some reason that I have not determined, the skew can be
               up to twice a kernel tick. This does not seem to happen by
               itself, but I have only seen it triggered by another program
               doing some kind of file I/O. The symptoms are a negative diff
               followed by an equally large positive diff. */
            if (fabs(diff) > 2*skewThreshold) {
                /*fprintf(stderr,"Clock skew detected (diff = %f)!\n", diff);*/

                if (calibrated) {
                    /* If we already calibrated once this instance, and the
                       clock is still skewed, then either the processor(s) are
                       wildly changing clockspeed or the system is so busy that
                       we get switched out for long periods of time. In either
                       case, it would be infeasible to make use of high
                       resolution results for anything, so let's resort to old
                       behavior for this call. It's possible that in the
                       future, the user will want the high resolution timer, so
                       we don't disable it entirely. */
                    returnedTime = (JSInt64)lowresTime;
                    needsCalibration = JS_FALSE;
                } else {
                    /* It is possible that when we recalibrate, we will return a
                       value less than what we have returned before; this is
                       unavoidable. We cannot tell the different between a
                       faulty QueryPerformanceCounter implementation and user
                       changes to the operating system time. Since we must
                       respect user changes to the operating system time, we
                       cannot maintain the invariant that Date.now() never
                       decreases; the old implementation has this behavior as
                       well. */
                    needsCalibration = JS_TRUE;
                }
            } else {
                /* No detectable clock skew */
                returnedTime = (JSInt64)highresTime;
                needsCalibration = JS_FALSE;
            }
        } else {
            /* No high resolution timer is available, so fall back */
            returnedTime = (JSInt64)lowresTime;
        }
    } while (needsCalibration);

    return returnedTime;
#endif

#if defined(XP_UNIX) || defined(XP_BEOS)
#ifdef _SVID_GETTOD   /* Defined only on Solaris, see Solaris <sys/types.h> */
    gettimeofday(&tv);
#else
    gettimeofday(&tv, 0);
#endif /* _SVID_GETTOD */
    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
    JSLL_UI2L(s, tv.tv_sec);
    JSLL_UI2L(us, tv.tv_usec);
    JSLL_MUL(s, s, s2us);
    JSLL_ADD(s, s, us);
    return s;
#endif /* XP_UNIX */
}
Beispiel #25
0
int64_t
PRMJ_Now(void)
{
    static int nCalls = 0;
    long double lowresTime, highresTimerValue;
    FILETIME ft;
    LARGE_INTEGER now;
    bool calibrated = false;
    bool needsCalibration = false;
    int64_t returnedTime;
    long double cachedOffset = 0.0;

    /* For non threadsafe platforms, NowInit is not necessary */
#ifdef JS_THREADSAFE
    PR_CallOnce(&calibrationOnce, NowInit);
#endif
    do {
        if (!calibration.calibrated || needsCalibration) {
            MUTEX_LOCK(&calibration.calibration_lock);
            MUTEX_LOCK(&calibration.data_lock);

            /* Recalibrate only if no one else did before us */
            if(calibration.offset == cachedOffset) {
                /* Since calibration can take a while, make any other
                   threads immediately wait */
                MUTEX_SETSPINCOUNT(&calibration.data_lock, 0);

                NowCalibrate();

                calibrated = true;

                /* Restore spin count */
                MUTEX_SETSPINCOUNT(&calibration.data_lock, DATALOCK_SPINCOUNT);
            }
            MUTEX_UNLOCK(&calibration.data_lock);
            MUTEX_UNLOCK(&calibration.calibration_lock);
        }


        /* Calculate a low resolution time */
        GetSystemTimeAsFileTime(&ft);
        lowresTime = 0.1*(long double)(FILETIME2INT64(ft) - win2un);

        if (calibration.freq > 0.0) {
            long double highresTime, diff;

            DWORD timeAdjustment, timeIncrement;
            BOOL timeAdjustmentDisabled;

            /* Default to 15.625 ms if the syscall fails */
            long double skewThreshold = 15625.25;
            /* Grab high resolution time */
            QueryPerformanceCounter(&now);
            highresTimerValue = (long double)now.QuadPart;

            MUTEX_LOCK(&calibration.data_lock);
            highresTime = calibration.offset + PRMJ_USEC_PER_SEC*
                 (highresTimerValue-calibration.timer_offset)/calibration.freq;
            cachedOffset = calibration.offset;

            /* On some dual processor/core systems, we might get an earlier time
               so we cache the last time that we returned */
            calibration.last = js::Max(calibration.last, int64_t(highresTime));
            returnedTime = calibration.last;
            MUTEX_UNLOCK(&calibration.data_lock);

            /* Rather than assume the NT kernel ticks every 15.6ms, ask it */
            if (GetSystemTimeAdjustment(&timeAdjustment,
                                        &timeIncrement,
                                        &timeAdjustmentDisabled)) {
                if (timeAdjustmentDisabled) {
                    /* timeAdjustment is in units of 100ns */
                    skewThreshold = timeAdjustment/10.0;
                } else {
                    /* timeIncrement is in units of 100ns */
                    skewThreshold = timeIncrement/10.0;
                }
            }

            /* Check for clock skew */
            diff = lowresTime - highresTime;

            /* For some reason that I have not determined, the skew can be
               up to twice a kernel tick. This does not seem to happen by
               itself, but I have only seen it triggered by another program
               doing some kind of file I/O. The symptoms are a negative diff
               followed by an equally large positive diff. */
            if (mozilla::Abs(diff) > 2 * skewThreshold) {
                /*fprintf(stderr,"Clock skew detected (diff = %f)!\n", diff);*/

                if (calibrated) {
                    /* If we already calibrated once this instance, and the
                       clock is still skewed, then either the processor(s) are
                       wildly changing clockspeed or the system is so busy that
                       we get switched out for long periods of time. In either
                       case, it would be infeasible to make use of high
                       resolution results for anything, so let's resort to old
                       behavior for this call. It's possible that in the
                       future, the user will want the high resolution timer, so
                       we don't disable it entirely. */
                    returnedTime = int64_t(lowresTime);
                    needsCalibration = false;
                } else {
                    /* It is possible that when we recalibrate, we will return a
                       value less than what we have returned before; this is
                       unavoidable. We cannot tell the different between a
                       faulty QueryPerformanceCounter implementation and user
                       changes to the operating system time. Since we must
                       respect user changes to the operating system time, we
                       cannot maintain the invariant that Date.now() never
                       decreases; the old implementation has this behavior as
                       well. */
                    needsCalibration = true;
                }
            } else {
                /* No detectable clock skew */
                returnedTime = int64_t(highresTime);
                needsCalibration = false;
            }
        } else {
            /* No high resolution timer is available, so fall back */
            returnedTime = int64_t(lowresTime);
        }
    } while (needsCalibration);

    return returnedTime;
}
Beispiel #26
0
void
EnsureIdentityInfoLoaded()
{
  (void) PR_CallOnce(&sIdentityInfoCallOnce, IdentityInfoInit);
}
NS_IMETHODIMP
nsNSSComponent::EnsureIdentityInfoLoaded()
{
  PRStatus rv = PR_CallOnce(&mIdentityInfoCallOnce, IdentityInfoInit);
  return (rv == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE; 
}
Beispiel #28
0
static int st_bind(SearchThread *st)
{
    if (!st->ld) {
#if defined(USE_OPENLDAP)
        int ret = 0;
        char *ldapurl = NULL;

        st->ld = NULL;
        ldapurl = PR_smprintf("ldap://%s:%d", hostname, port);
        if (PR_SUCCESS != PR_CallOnce(&ol_init_callOnce, internal_ol_init_init)) {
            fprintf(stderr, "Could not perform internal ol_init init\n");
            return 0;
        }

        PR_Lock(ol_init_lock);
        ret = ldap_initialize(&st->ld, ldapurl);
        PR_Unlock(ol_init_lock);
        PR_smprintf_free(ldapurl);
        ldapurl = NULL;
        if (ret) {
            fprintf(stderr, "T%d: failed to init: %s port %d: %d:%s\n", st->id, hostname, port,
                    ret, ldap_err2string(ret));
            return 0;
        }
#else
        st->ld = ldap_init(hostname, port);
#endif
        if (!st->ld) {
            fprintf(stderr, "T%d: failed to init\n", st->id);
            return 0;
        }
    }
    if (!st->ld2) {        /* aux LDAP handle */
#if defined(USE_OPENLDAP)
        int ret = 0;
        char *ldapurl = NULL;

        st->ld2 = NULL;
        ldapurl = PR_smprintf("ldap://%s:%d", hostname, port);
        if (PR_SUCCESS != PR_CallOnce(&ol_init_callOnce, internal_ol_init_init)) {
            fprintf(stderr, "Could not perform internal ol_init init\n");
            return 0;
        }

        PR_Lock(ol_init_lock);
        ret = ldap_initialize(&st->ld2, ldapurl);
        PR_Unlock(ol_init_lock);
        PR_smprintf_free(ldapurl);
        ldapurl = NULL;
        if (ret) {
            fprintf(stderr, "T%d: failed to init: %s port %d: %d:%s\n", st->id, hostname, port,
                    ret, ldap_err2string(ret));
            return 0;
        }
#else
        st->ld2 = ldap_init(hostname, port);
#endif
        if (!st->ld2) {
            fprintf(stderr, "T%d: failed to init 2\n", st->id);
            return 0;
        }
        if (0 == st_bind_core(st, &(st->ld2), strlen(bindDN) ? bindDN : NULL,
            strlen(bindPW) ? bindPW : NULL)) {
            return 0;
        }
    }

    if (opType != op_delete && opType != op_modify && opType != op_idxmodify &&
               sdattable && sdt_getlen(sdattable) > 0) {
        int e;
        char *dn, *uid, *upw;

        do {
            e = sdt_getrand(sdattable);
        } while (e < 0);
        dn = sdt_dn_get(sdattable, e);
        uid = sdt_uid_get(sdattable, e);
		/*  in this test, assuming uid == password unless told otherwise */
		upw = (userPW) ? userPW : uid;

        if (useBFile) {

            if (dn) {
                if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                    return 0;
                }
            } else if (uid) {
                char *filterBuffer = NULL;
                char *filterTemplate = (uidFilter) ? uidFilter : "(uid=%s)";
                struct timeval timeout;
                int scope = LDAP_SCOPE_SUBTREE, attrsOnly = 0;
                LDAPMessage *result;
                int retry = 0;
    
                filterBuffer = PR_smprintf(filterTemplate, uid);
                timeout.tv_sec = 3600;
                timeout.tv_usec = 0;
                while (1) {
                    int ret = ldap_search_ext_s(st->ld2, suffix, scope, filterBuffer,
                                                NULL, attrsOnly, NULL, NULL,
                                                &timeout, -1, &result);
                    if (LDAP_SUCCESS == ret) {
                        break;
                    } else if ((LDAP_CONNECT_ERROR == ret ||
                               (LDAP_TIMEOUT == ret)) && retry < 10) {
                        retry++;
                    } else {
                        fprintf(stderr, "T%d: failed to search 1, error=0x%x\n",
                                st->id, ret);
                        PR_smprintf_free(filterBuffer);
                        return 0;
                    }
                }
                PR_smprintf_free(filterBuffer);
                dn = ldap_get_dn(st->ld2, result);
    
                if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                    return 0;
                }
            } else {
                fprintf(stderr, "T%d: no data found, dn: %p, uid: %p\n", 
                        st->id, dn, uid);
                return 0;
            }
        } else {
            if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                return 0;
            }
        }
    } else {
        if (0 == st_bind_core(st, &(st->ld), strlen(bindDN) ? bindDN : NULL,
                              strlen(bindPW) ? bindPW : NULL)) {
            return 0;
        }
    }
    if (st->soc < 0) {
        if (ldap_get_option(st->ld, LDAP_OPT_DESC, (void *)&st->soc)
            != LDAP_SUCCESS) {
            fprintf(stderr, "T%d: failed on ldap_get_option\n", st->id);
            return 0;
        }
    }
    if (setLinger) {
        int val;
        struct linger l;
        val = sizeof(struct linger);
        l.l_onoff = 1;
        l.l_linger = 0;
        if (setsockopt(st->soc, SOL_SOCKET, SO_LINGER, (char *)&l, val) < 0) {
            fprintf(stderr, "T%d: failed in setsockopt 2, errno %d (%d)\n",
                    st->id, errno, (int)st->soc);
            st->soc = -1;
            return 0;
        }
    }
    return 1;
}