コード例 #1
0
ファイル: md_rand.c プロジェクト: DmitryOlshansky/openssl
static int ssleay_rand_add(const void *buf, int num, double add)
	{
	int i,j,k,st_idx;
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
	EVP_MD_CTX m;
	int do_not_lock;
	int rv = 0;

	/*
	 * (Based on the rand(3) manpage)
	 *
	 * The input is chopped up into units of 20 bytes (or less for
	 * the last block).  Each of these blocks is run through the hash
	 * function as follows:  The data passed to the hash function
	 * is the current 'md', the same number of bytes from the 'state'
	 * (the location determined by in incremented looping index) as
	 * the current 'block', the new key data 'block', and 'count'
	 * (which is incremented after each use).
	 * The result of this is kept in 'md' and also xored into the
	 * 'state' at the same locations that were used as input into the
         * hash function.
	 */

	EVP_MD_CTX_init(&m);
	/* check if we already have the lock */
	if (crypto_lock_rand)
		{
		CRYPTO_THREADID cur;
		CRYPTO_THREADID_current(&cur);
		CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
		do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
		CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
		}
	else
		do_not_lock = 0;

	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	st_idx=state_index;

	/* use our own copies of the counters so that even
	 * if a concurrent thread seeds with exactly the
	 * same data and uses the same subarray there's _some_
	 * difference */
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];

	memcpy(local_md, md, sizeof md);

	/* state_index <= state_num <= STATE_SIZE */
	state_index += num;
	if (state_index >= STATE_SIZE)
		{
		state_index%=STATE_SIZE;
		state_num=STATE_SIZE;
		}
	else if (state_num < STATE_SIZE)	
		{
		if (state_index > state_num)
			state_num=state_index;
		}
	/* state_index <= state_num <= STATE_SIZE */

	/* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
	 * are what we will use now, but other threads may use them
	 * as well */

	md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);

	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	for (i=0; i<num; i+=MD_DIGEST_LENGTH)
		{
		j=(num-i);
		j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;

		if (!MD_Init(&m))
			goto err;
		if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
			goto err;
		k=(st_idx+j)-STATE_SIZE;
		if (k > 0)
			{
			if (!MD_Update(&m,&(state[st_idx]),j-k))
				goto err;
			if (!MD_Update(&m,&(state[0]),k))
				goto err;
			}
		else
			if (!MD_Update(&m,&(state[st_idx]),j))
				goto err;

		/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
		if (!MD_Update(&m,buf,j))
			goto err;
		/* We know that line may cause programs such as
		   purify and valgrind to complain about use of
		   uninitialized data.  The problem is not, it's
		   with the caller.  Removing that line will make
		   sure you get really bad randomness and thereby
		   other problems such as very insecure keys. */

		if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
			goto err;
		if (!MD_Final(&m,local_md))
			goto err;
		md_c[1]++;

		buf=(const char *)buf + j;

		for (k=0; k<j; k++)
			{
			/* Parallel threads may interfere with this,
			 * but always each byte of the new state is
			 * the XOR of some previous value of its
			 * and local_md (itermediate values may be lost).
			 * Alway using locking could hurt performance more
			 * than necessary given that conflicts occur only
			 * when the total seeding is longer than the random
			 * state. */
			state[st_idx++]^=local_md[k];
			if (st_idx >= STATE_SIZE)
				st_idx=0;
			}
		}

	if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	/* Don't just copy back local_md into md -- this could mean that
	 * other thread's seeding remains without effect (except for
	 * the incremented counter).  By XORing it we keep at least as
	 * much entropy as fits into md. */
	for (k = 0; k < (int)sizeof(md); k++)
		{
		md[k] ^= local_md[k];
		}
	if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
	    entropy += add;
	if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
	
#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
	assert(md_c[1] == md_count[1]);
#endif
	rv = 1;
	err:
	EVP_MD_CTX_cleanup(&m);
	return rv;
	}
コード例 #2
0
static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
    int to_return = 1;

    switch(cmd)
    {
    case HWCRHK_CMD_SO_PATH:
        if(hwcrhk_dso)
        {
            HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
            return 0;
        }
        if(p == NULL)
        {
            HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
            return 0;
        }
        return set_HWCRHK_LIBNAME((const char *)p);
    case ENGINE_CTRL_SET_LOGSTREAM:
    {
        BIO *bio = (BIO *)p;

        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        if (logstream)
        {
            BIO_free(logstream);
            logstream = NULL;
        }
        if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
            logstream = bio;
        else
            HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
    }
    CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
    break;
    case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        password_context.password_callback = (pem_password_cb *)f;
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;
    case ENGINE_CTRL_SET_USER_INTERFACE:
    case HWCRHK_CMD_SET_USER_INTERFACE:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        password_context.ui_method = (UI_METHOD *)p;
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;
    case ENGINE_CTRL_SET_CALLBACK_DATA:
    case HWCRHK_CMD_SET_CALLBACK_DATA:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        password_context.callback_data = p;
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;
    /* this enables or disables the "SimpleForkCheck" flag used in the
     * initialisation structure. */
    case ENGINE_CTRL_CHIL_SET_FORKCHECK:
    case HWCRHK_CMD_FORK_CHECK:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        if(i)
            hwcrhk_globals.flags |=
                HWCryptoHook_InitFlags_SimpleForkCheck;
        else
            hwcrhk_globals.flags &=
                ~HWCryptoHook_InitFlags_SimpleForkCheck;
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;
    /* This will prevent the initialisation function from "installing"
     * the mutex-handling callbacks, even if they are available from
     * within the library (or were provided to the library from the
     * calling application). This is to remove any baggage for
     * applications not using multithreading. */
    case ENGINE_CTRL_CHIL_NO_LOCKING:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        disable_mutex_callbacks = 1;
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;
    case HWCRHK_CMD_THREAD_LOCKING:
        CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
        disable_mutex_callbacks = ((i == 0) ? 0 : 1);
        CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
        break;

    /* The command isn't understood by this engine */
    default:
        HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
                  HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        to_return = 0;
        break;
    }

    return to_return;
}
コード例 #3
0
static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
{
	BN_BLINDING *ret;
	int got_write_lock = 0;
	CRYPTO_THREADID cur;

	CRYPTO_r_lock(CRYPTO_LOCK_RSA);

	if (rsa->blinding == NULL)
		{
		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
		got_write_lock = 1;

		if (rsa->blinding == NULL)
			rsa->blinding = RSA_setup_blinding(rsa, ctx);
		}

	ret = rsa->blinding;
	if (ret == NULL)
		goto err;

	CRYPTO_THREADID_current(&cur);
	if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
		{
		/* rsa->blinding is ours! */

		*local = 1;
		}
	else
		{
		/* resort to rsa->mt_blinding instead */

		*local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
		             * that the BN_BLINDING is shared, meaning that accesses
		             * require locks, and that the blinding factor must be
		             * stored outside the BN_BLINDING
		             */

		if (rsa->mt_blinding == NULL)
			{
			if (!got_write_lock)
				{
				CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
				got_write_lock = 1;
				}
			
			if (rsa->mt_blinding == NULL)
				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
			}
		ret = rsa->mt_blinding;
		}

 err:
	if (got_write_lock)
		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
	else
		CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
	return ret;
}
コード例 #4
0
ファイル: eng_list.c プロジェクト: Valbonjv/QuickSMS
ENGINE *ENGINE_by_id(const char *id)
	{
	ENGINE *iterator;
	char *load_dir = NULL;
	if(id == NULL)
		{
		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
			ERR_R_PASSED_NULL_PARAMETER);
		return NULL;
		}
	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
	iterator = engine_list_head;
	while(iterator && (strcmp(id, iterator->id) != 0))
		iterator = iterator->next;
	if(iterator)
		{
		/* We need to return a structural reference. If this is an
		 * ENGINE type that returns copies, make a duplicate - otherwise
		 * increment the existing ENGINE's reference count. */
		if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
			{
			ENGINE *cp = ENGINE_new();
			if(!cp)
				iterator = NULL;
			else
				{
				engine_cpy(cp, iterator);
				iterator = cp;
				}
			}
		else
			{
			iterator->struct_ref++;
			engine_ref_debug(iterator, 0, 1)
			}
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
#if 0
	if(iterator == NULL)
		{
		ENGINEerr(ENGINE_F_ENGINE_BY_ID,
			ENGINE_R_NO_SUCH_ENGINE);
		ERR_add_error_data(2, "id=", id);
		}
	return iterator;
#else
	/* EEK! Experimental code starts */
	if(iterator) return iterator;
	/* Prevent infinite recusrion if we're looking for the dynamic engine. */
	if (strcmp(id, "dynamic"))
		{
#ifdef OPENSSL_SYS_VMS
		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
#else
		if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
#endif
		iterator = ENGINE_by_id("dynamic");
		if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
				!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
				!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
					load_dir, 0) ||
				!ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
				!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
				goto notfound;
		return iterator;
		}
notfound:
	ENGINE_free(iterator);
	ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
	ERR_add_error_data(2, "id=", id);
	return NULL;
	/* EEK! Experimental code ends */
#endif
	}
コード例 #5
0
static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
{
    CRYPTO_w_unlock(mt->lockid);
}
コード例 #6
0
void CRYPTO_mem_leaks(BIO *b)
	{
	MEM_LEAK ml;
	char buf[80];

	if (mh == NULL && amih == NULL)
		return;

	MemCheck_off(); /* obtain MALLOC2 lock */

	ml.bio=b;
	ml.bytes=0;
	ml.chunks=0;
	if (mh != NULL)
		lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml);
	if (ml.chunks != 0)
		{
		sprintf(buf,"%ld bytes leaked in %d chunks\n",
			ml.bytes,ml.chunks);
		BIO_puts(b,buf);
		}
	else
		{
		/* Make sure that, if we found no leaks, memory-leak debugging itself
		 * does not introduce memory leaks (which might irritate
		 * external debugging tools).
		 * (When someone enables leak checking, but does not call
		 * this function, we declare it to be their fault.)
		 *
		 * XXX    This should be in CRYPTO_mem_leaks_cb,
		 * and CRYPTO_mem_leaks should be implemented by
		 * using CRYPTO_mem_leaks_cb.
		 * (Also their should be a variant of lh_doall_arg
		 * that takes a function pointer instead of a void *;
		 * this would obviate the ugly and illegal
		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
		 * Otherwise the code police will come and get us.)
		 */
		int old_mh_mode;

		CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);

		/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
		 * which uses CRYPTO_is_mem_check_on */
		old_mh_mode = mh_mode;
		mh_mode = CRYPTO_MEM_CHECK_OFF;

		if (mh != NULL)
			{
			lh_free(mh);
			mh = NULL;
			}
		if (amih != NULL)
			{
			if (lh_num_items(amih) == 0) 
				{
				lh_free(amih);
				amih = NULL;
				}
			}

		mh_mode = old_mh_mode;
		CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
		}
	MemCheck_on(); /* release MALLOC2 lock */
	}
コード例 #7
0
/**
  Verification callback function to override any existing callbacks in OpenSSL
  for intermediate certificate supports.

  @param[in]  Status   Original status before calling this callback.
  @param[in]  Context  X509 store context.

  @retval     1        Current X509 certificate is verified successfully.
  @retval     0        Verification failed.

**/
int
X509VerifyCb (
  IN int            Status,
  IN X509_STORE_CTX *Context
  )
{
  X509_OBJECT  *Obj;
  INTN         Error;
  INTN         Index;
  INTN         Count;

  Obj   = NULL;
  Error = (INTN) X509_STORE_CTX_get_error (Context);

  //
  // X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT and X509_V_ERR_UNABLE_TO_GET_ISSUER_
  // CERT_LOCALLY mean a X509 certificate is not self signed and its issuer
  // can not be found in X509_verify_cert of X509_vfy.c.
  // In order to support intermediate certificate node, we override the
  // errors if the certification is obtained from X509 store, i.e. it is
  // a trusted ceritifcate node that is enrolled by user.
  // Besides,X509_V_ERR_CERT_UNTRUSTED and X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
  // are also ignored to enable such feature.
  //
  if ((Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) ||
      (Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)) {
    Obj = (X509_OBJECT *) malloc (sizeof (X509_OBJECT));
    if (Obj == NULL) {
      return 0;
    }

    Obj->type      = X509_LU_X509;
    Obj->data.x509 = Context->current_cert;

    CRYPTO_w_lock (CRYPTO_LOCK_X509_STORE);

    if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
      Status = 1;
    } else {
      //
      // If any certificate in the chain is enrolled as trusted certificate,
      // pass the certificate verification.
      //
      if (Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
        Count = (INTN) sk_X509_num (Context->chain);
        for (Index = 0; Index < Count; Index++) {
          Obj->data.x509 = sk_X509_value (Context->chain, (int) Index);
          if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
            Status = 1;
            break;
          }
        }
      }
    }

    CRYPTO_w_unlock (CRYPTO_LOCK_X509_STORE);
  }

  if ((Error == X509_V_ERR_CERT_UNTRUSTED) ||
      (Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) {
    Status = 1;
  }

  if (Obj != NULL) {
    OPENSSL_free (Obj);
  }

  return Status;
}
コード例 #8
0
ファイル: e_aep.c プロジェクト: jiangzhu1212/oooii
static int aep_rand(unsigned char *buf,int len )
	{
	AEP_RV rv = AEP_R_OK;
	AEP_CONNECTION_HNDL hConnection;

	CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/*Can the request be serviced with what's already in the buffer?*/
	if (len <= rand_block_bytes)
		{
		memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
		rand_block_bytes -= len;
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		}
	else
		/*If not the get another block of random bytes*/
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

		rv = aep_get_connection(&hConnection);
		if (rv !=  AEP_R_OK)
			{ 
			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
			goto err_nounlock;
			}

		if (len > RAND_BLK_SIZE)
			{
			rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
			if (rv !=  AEP_R_OK)
				{  
				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
				goto err_nounlock;
				}
			}
		else
			{
			CRYPTO_w_lock(CRYPTO_LOCK_RAND);

			rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
			if (rv !=  AEP_R_OK)
				{       
				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
	      
				goto err;
				}

			rand_block_bytes = RAND_BLK_SIZE;

			memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
			rand_block_bytes -= len;

			CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
			}

		rv = aep_return_connection(hConnection);
		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
	  
			goto err_nounlock;
			}
		}
  
	return 1;
 err:
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
 err_nounlock:
	return 0;
	}
コード例 #9
0
ファイル: e_aep.c プロジェクト: jiangzhu1212/oooii
static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
	{
	int count;
	AEP_RV rv = AEP_R_OK;

	/*Get the current process id*/
	pid_t curr_pid;

	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);

	curr_pid = getpid();

	/*Check if this is the first time this is being called from the current
	  process*/
	if (recorded_pid != curr_pid)
		{
		/*Remember our pid so we can check if we're in a new process*/
		recorded_pid = curr_pid;

		/*Call Finalize to make sure we have not inherited some data
		  from a parent process*/
		p_AEP_Finalize();
     
		/*Initialise the AEP API*/
		rv = p_AEP_Initialize(NULL);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
			recorded_pid = 0;
			goto end;
			}

		/*Set the AEP big num call back functions*/
		rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
			&ConvertAEPBigNum);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
			recorded_pid = 0;
			goto end;
			}

#ifdef AEPRAND
		/*Reset the rand byte count*/
		rand_block_bytes = 0;
#endif

		/*Init the structures*/
		for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
			{
			aep_app_conn_table[count].conn_state = NotConnected;
			aep_app_conn_table[count].conn_hndl  = 0;
			}

		/*Open a connection*/
		rv = p_AEP_OpenConnection(phConnection);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
			recorded_pid = 0;
			goto end;
			}

		aep_app_conn_table[0].conn_state = InUse;
		aep_app_conn_table[0].conn_hndl = *phConnection;
		goto end;
		}
	/*Check the existing connections to see if we can find a free one*/
	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_state == Connected)
			{
			aep_app_conn_table[count].conn_state = InUse;
			*phConnection = aep_app_conn_table[count].conn_hndl;
			goto end;
			}
		}
	/*If no connections available, we're going to have to try
	  to open a new one*/
	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_state == NotConnected)
			{
			/*Open a connection*/
			rv = p_AEP_OpenConnection(phConnection);

			if (rv != AEP_R_OK)
				{	      
				AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
				goto end;
				}

			aep_app_conn_table[count].conn_state = InUse;
			aep_app_conn_table[count].conn_hndl = *phConnection;
			goto end;
			}
		}
	rv = AEP_R_GENERAL_ERROR;
 end:
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	return rv;
	}
コード例 #10
0
ファイル: rsa_impl.c プロジェクト: RobinWuDev/Qt
/* rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by
 * allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If
 * none are free, the cache will be extended by a extra element and the new
 * BN_BLINDING is returned.
 *
 * On success, the index of the assigned BN_BLINDING is written to
 * |*index_used| and must be passed to |rsa_blinding_release| when finished. */
static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used,
                                     BN_CTX *ctx) {
  BN_BLINDING *ret = NULL;
  BN_BLINDING **new_blindings;
  uint8_t *new_blindings_inuse;
  char overflow = 0;

  CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
  if (rsa->num_blindings > 0) {
    unsigned i, starting_index;
    CRYPTO_THREADID threadid;

    /* We start searching the array at a value based on the
     * threadid in order to try avoid bouncing the BN_BLINDING
     * values around different threads. It's harmless if
     * threadid.val is always set to zero. */
    CRYPTO_THREADID_current(&threadid);
    starting_index = threadid.val % rsa->num_blindings;

    for (i = starting_index;;) {
      if (rsa->blindings_inuse[i] == 0) {
        rsa->blindings_inuse[i] = 1;
        ret = rsa->blindings[i];
        *index_used = i;
        break;
      }
      i++;
      if (i == rsa->num_blindings) {
        i = 0;
      }
      if (i == starting_index) {
        break;
      }
    }
  }

  if (ret != NULL) {
    CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
    return ret;
  }

  overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA;

  /* We didn't find a free BN_BLINDING to use so increase the length of
   * the arrays by one and use the newly created element. */

  CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
  ret = rsa_setup_blinding(rsa, ctx);
  if (ret == NULL) {
    return NULL;
  }

  if (overflow) {
    /* We cannot add any more cached BN_BLINDINGs so we use |ret|
     * and mark it for destruction in |rsa_blinding_release|. */
    *index_used = MAX_BLINDINGS_PER_RSA;
    return ret;
  }

  CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);

  new_blindings =
      OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1));
  if (new_blindings == NULL) {
    goto err1;
  }
  memcpy(new_blindings, rsa->blindings,
         sizeof(BN_BLINDING *) * rsa->num_blindings);
  new_blindings[rsa->num_blindings] = ret;

  new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1);
  if (new_blindings_inuse == NULL) {
    goto err2;
  }
  memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings);
  new_blindings_inuse[rsa->num_blindings] = 1;
  *index_used = rsa->num_blindings;

  if (rsa->blindings != NULL) {
    OPENSSL_free(rsa->blindings);
  }
  rsa->blindings = new_blindings;
  if (rsa->blindings_inuse != NULL) {
    OPENSSL_free(rsa->blindings_inuse);
  }
  rsa->blindings_inuse = new_blindings_inuse;
  rsa->num_blindings++;

  CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
  return ret;

err2:
  OPENSSL_free(new_blindings);

err1:
  CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
  BN_BLINDING_free(ret);
  return NULL;
}
コード例 #11
0
COMP_METHOD *COMP_zlib(void)
	{
	COMP_METHOD *meth = &zlib_method_nozlib;

#ifdef ZLIB_SHARED
	if (!zlib_loaded)
		{
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
		zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
#else
		zlib_dso = DSO_load(NULL, "z", NULL, 0);
#endif
		if (zlib_dso != NULL)
			{
			p_compress
				= (compress_ft) DSO_bind_func(zlib_dso,
					"compress");
			p_inflateEnd
				= (inflateEnd_ft) DSO_bind_func(zlib_dso,
					"inflateEnd");
			p_inflate
				= (inflate_ft) DSO_bind_func(zlib_dso,
					"inflate");
			p_inflateInit_
				= (inflateInit__ft) DSO_bind_func(zlib_dso,
					"inflateInit_");
			p_deflateEnd
				= (deflateEnd_ft) DSO_bind_func(zlib_dso,
					"deflateEnd");
			p_deflate
				= (deflate_ft) DSO_bind_func(zlib_dso,
					"deflate");
			p_deflateInit_
				= (deflateInit__ft) DSO_bind_func(zlib_dso,
					"deflateInit_");

			if (p_compress && p_inflateEnd && p_inflate
				&& p_inflateInit_ && p_deflateEnd
				&& p_deflate && p_deflateInit_)
				zlib_loaded++;
			}
		}

#endif
#ifdef ZLIB_SHARED
	if (zlib_loaded)
#endif
#if defined(ZLIB) || defined(ZLIB_SHARED)
		{
		/* init zlib_stateful_ex_idx here so that in a multi-process
		 * application it's enough to intialize openssl before forking
		 * (idx will be inherited in all the children) */
		if (zlib_stateful_ex_idx == -1)
			{
			CRYPTO_w_lock(CRYPTO_LOCK_COMP);
			if (zlib_stateful_ex_idx == -1)
				zlib_stateful_ex_idx =
					CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
						0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
			CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
			if (zlib_stateful_ex_idx == -1)
				goto err;
			}
		
		meth = &zlib_stateful_method;
		}
err:	
#endif

	return(meth);
	}
コード例 #12
0
ファイル: resolver.c プロジェクト: NickolasLapp/stunnel
NOEXPORT int getaddrinfo(const char *node, const char *service,
        const struct addrinfo *hints, struct addrinfo **res) {
    struct hostent *h;
#ifndef _WIN32_WCE
    struct servent *p;
#endif
    u_short port;
    struct addrinfo *ai;
    int retval;
    char *tmpstr;

    if(!node)
        node=hints->ai_flags&AI_PASSIVE ? DEFAULT_ANY : DEFAULT_LOOPBACK;
#if defined(USE_WIN32) && !defined(_WIN32_WCE)
    if(s_getaddrinfo)
        return s_getaddrinfo(node, service, hints, res);
#endif
    /* decode service name */
    port=htons((u_short)strtol(service, &tmpstr, 10));
    if(tmpstr==service || *tmpstr) { /* not a number */
#ifdef _WIN32_WCE
        return EAI_NONAME;
#else /* defined(_WIN32_WCE) */
        p=getservbyname(service, "tcp");
        if(!p)
            return EAI_NONAME;
        port=(u_short)p->s_port;
#endif /* defined(_WIN32_WCE) */
    }

    /* allocate addrlist structure */
    ai=str_alloc(sizeof(struct addrinfo));
    if(hints)
        memcpy(ai, hints, sizeof(struct addrinfo));

    /* try to decode numerical address */
#if defined(USE_IPv6) && !defined(USE_WIN32)
    ai->ai_family=AF_INET6;
    ai->ai_addrlen=sizeof(struct sockaddr_in6);
    ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
    ai->ai_addr->sa_family=AF_INET6;
    if(inet_pton(AF_INET6, node,
            &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr)>0) {
#else
    ai->ai_family=AF_INET;
    ai->ai_addrlen=sizeof(struct sockaddr_in);
    ai->ai_addr=str_alloc(ai->ai_addrlen);
    ai->ai_addr->sa_family=AF_INET;
    ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr=inet_addr(node);
    if(((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr+1) {
    /* (signed)((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr!=-1 */
#endif
        ((struct sockaddr_in *)ai->ai_addr)->sin_port=port;
        *res=ai;
        return 0; /* numerical address resolved */
    }
    str_free(ai->ai_addr);
    str_free(ai);

    /* not numerical: need to call resolver library */
    *res=NULL;
    ai=NULL;
    CRYPTO_w_lock(stunnel_locks[LOCK_INET]);
#ifdef HAVE_GETHOSTBYNAME2
    h=gethostbyname2(node, AF_INET6);
    if(h) /* some IPv6 addresses found */
        alloc_addresses(h, hints, port, res, &ai); /* ignore the error */
#endif
    h=gethostbyname(node); /* get list of addresses */
    if(h)
        retval=ai ?
            alloc_addresses(h, hints, port, &ai->ai_next, &ai) :
            alloc_addresses(h, hints, port, res, &ai);
    else if(!*res)
        retval=EAI_NONAME; /* no results */
    else
        retval=0;
#ifdef HAVE_ENDHOSTENT
    endhostent();
#endif
    CRYPTO_w_unlock(stunnel_locks[LOCK_INET]);
    if(retval) { /* error: free allocated memory */
        freeaddrinfo(*res);
        *res=NULL;
    }
    return retval;
}

NOEXPORT int alloc_addresses(struct hostent *h, const struct addrinfo *hints,
        u_short port, struct addrinfo **head, struct addrinfo **tail) {
    int i;
    struct addrinfo *ai;

    /* copy addresses */
    for(i=0; h->h_addr_list[i]; i++) {
        ai=str_alloc(sizeof(struct addrinfo));
        if(hints)
            memcpy(ai, hints, sizeof(struct addrinfo));
        ai->ai_next=NULL; /* just in case */
        if(*tail) { /* list not empty: add a node */
            (*tail)->ai_next=ai;
            *tail=ai;
        } else { /* list empty: create it */
            *head=ai;
            *tail=ai;
        }
        ai->ai_family=h->h_addrtype;
#if defined(USE_IPv6)
        if(h->h_addrtype==AF_INET6) {
            ai->ai_addrlen=sizeof(struct sockaddr_in6);
            ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
            memcpy(&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
                h->h_addr_list[i], (size_t)h->h_length);
        } else
#endif
        {
            ai->ai_addrlen=sizeof(struct sockaddr_in);
            ai->ai_addr=str_alloc((size_t)ai->ai_addrlen);
            memcpy(&((struct sockaddr_in *)ai->ai_addr)->sin_addr,
                h->h_addr_list[i], (size_t)h->h_length);
        }
        ai->ai_addr->sa_family=(u_short)h->h_addrtype;
        /* offsets of sin_port and sin6_port should be the same */
        ((struct sockaddr_in *)ai->ai_addr)->sin_port=port;
    }
    return 0; /* success */
}
コード例 #13
0
ファイル: ssl_sess.c プロジェクト: bbbrumley/openbsd
int
SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
{
	int ret = 0;
	SSL_SESSION *s;

	/*
	 * Add just 1 reference count for the SSL_CTX's session cache
	 * even though it has two ways of access: each session is in a
	 * doubly linked list and an lhash.
	 */
	CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION);

	/*
	 * If session c is in already in cache, we take back the increment
	 * later.
	 */
	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
	s = lh_SSL_SESSION_insert(ctx->internal->sessions, c);

	/*
	 * s != NULL iff we already had a session with the given PID.
	 * In this case, s == c should hold (then we did not really modify
	 * ctx->internal->sessions), or we're in trouble.
	 */
	if (s != NULL && s != c) {
		/* We *are* in trouble ... */
		SSL_SESSION_list_remove(ctx, s);
		SSL_SESSION_free(s);
		/*
		 * ... so pretend the other session did not exist in cache
		 * (we cannot handle two SSL_SESSION structures with identical
		 * session ID in the same cache, which could happen e.g. when
		 * two threads concurrently obtain the same session from an
		 * external cache).
		 */
		s = NULL;
	}

	/* Put at the head of the queue unless it is already in the cache */
	if (s == NULL)
		SSL_SESSION_list_add(ctx, c);

	if (s != NULL) {
		/*
		 * existing cache entry -- decrement previously incremented
		 * reference count because it already takes into account the
		 * cache.
		 */
		SSL_SESSION_free(s); /* s == c */
		ret = 0;
	} else {
		/*
		 * New cache entry -- remove old ones if cache has become
		 * too large.
		 */

		ret = 1;

		if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
			while (SSL_CTX_sess_number(ctx) >
			    SSL_CTX_sess_get_cache_size(ctx)) {
				if (!remove_session_lock(ctx,
				    ctx->internal->session_cache_tail, 0))
					break;
				else
					ctx->internal->stats.sess_cache_full++;
			}
		}
	}
	CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
	return (ret);
}
static int ssleay_rand_bytes(unsigned char *buf, int num)
	{
	static volatile int stirred_pool = 0;
	int i,j,k,st_num,st_idx;
	int num_ceil;
	int ok;
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
	EVP_MD_CTX m;
#ifndef GETPID_IS_MEANINGLESS
	pid_t curr_pid = getpid();
#endif
	int do_stir_pool = 0;

#ifdef PREDICT
	if (rand_predictable)
		{
		static unsigned char val=0;

		for (i=0; i<num; i++)
			buf[i]=val++;
		return(1);
		}
#endif

	if (num <= 0)
		return 1;

	EVP_MD_CTX_init(&m);
	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);

	/*
	 * (Based on the rand(3) manpage:)
	 *
	 * For each group of 10 bytes (or less), we do the following:
	 *
	 * Input into the hash function the local 'md' (which is initialized from
	 * the global 'md' before any bytes are generated), the bytes that are to
	 * be overwritten by the random bytes, and bytes from the 'state'
	 * (incrementing looping index). From this digest output (which is kept
	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
	 * bottom 10 bytes are xored into the 'state'.
	 * 
	 * Finally, after we have finished 'num' random bytes for the
	 * caller, 'count' (which is incremented) and the local and global 'md'
	 * are fed into the hash function and the results are kept in the
	 * global 'md'.
	 */

	CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
	locking_thread = CRYPTO_thread_id();
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
	crypto_lock_rand = 1;

	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}
	
	if (!stirred_pool)
		do_stir_pool = 1;
	
	ok = (entropy >= ENTROPY_NEEDED);
	if (!ok)
		{
		/* If the PRNG state is not yet unpredictable, then seeing
		 * the PRNG output may help attackers to determine the new
		 * state; thus we have to decrease the entropy estimate.
		 * Once we've had enough initial seeding we don't bother to
		 * adjust the entropy count, though, because we're not ambitious
		 * to provide *information-theoretic* randomness.
		 *
		 * NOTE: This approach fails if the program forks before
		 * we have enough entropy. Entropy should be collected
		 * in a separate input pool and be transferred to the
		 * output pool only when the entropy limit has been reached.
		 */
		entropy -= num;
		if (entropy < 0)
			entropy = 0;
		}

	if (do_stir_pool)
		{
		/* In the output function only half of 'md' remains secret,
		 * so we better make sure that the required entropy gets
		 * 'evenly distributed' through 'state', our randomness pool.
		 * The input function (ssleay_rand_add) chains all of 'md',
		 * which makes it more suitable for this purpose.
		 */

		int n = STATE_SIZE; /* so that the complete pool gets accessed */
		while (n > 0)
			{
#if MD_DIGEST_LENGTH > 20
# error "Please adjust DUMMY_SEED."
#endif
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
			/* Note that the seed does not matter, it's just that
			 * ssleay_rand_add expects to have something to hash. */
			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
			n -= MD_DIGEST_LENGTH;
			}
		if (ok)
			stirred_pool = 1;
		}

	st_idx=state_index;
	st_num=state_num;
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];
	memcpy(local_md, md, sizeof md);

	state_index+=num_ceil;
	if (state_index > state_num)
		state_index %= state_num;

	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
	 * are now ours (but other threads may use them too) */

	md_count[0] += 1;

	/* before unlocking, we must clear 'crypto_lock_rand' */
	crypto_lock_rand = 0;
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
		{
		/* num_ceil -= MD_DIGEST_LENGTH/2 */
		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
		num-=j;
		MD_Init(&m);
#ifndef GETPID_IS_MEANINGLESS
		if (curr_pid) /* just in the first iteration to save time */
			{
			MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
			curr_pid = 0;
			}
#endif
		MD_Update(&m,local_md,MD_DIGEST_LENGTH);
		MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
#if 0
		MD_Update(&m,buf,j); /* purify and valgrind complains */
#endif
		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
		if (k > 0)
			{
			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
			MD_Update(&m,&(state[0]),k);
			}
		else
			MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
		MD_Final(&m,local_md);

		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
			{
			state[st_idx++]^=local_md[i]; /* may compete with other threads */
			if (st_idx >= st_num)
				st_idx=0;
			if (i < j)
				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
			}
		}

	MD_Init(&m);
	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	MD_Update(&m,md,MD_DIGEST_LENGTH);
	MD_Final(&m,md);
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	EVP_MD_CTX_cleanup(&m);
	if (ok)
		return(1);
	else
		{
		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
			"http://www.openssl.org/support/faq.html");
		return(0);
		}
	}
コード例 #15
0
ファイル: md_rand.c プロジェクト: DmitryOlshansky/openssl
static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
	{
	static volatile int stirred_pool = 0;
	int i,j,k,st_num,st_idx;
	int num_ceil;
	int ok;
	long md_c[2];
	unsigned char local_md[MD_DIGEST_LENGTH];
	EVP_MD_CTX m;
#ifndef GETPID_IS_MEANINGLESS
	pid_t curr_pid = getpid();
#endif
	time_t curr_time = time(NULL);
	int do_stir_pool = 0;
/* time value for various platforms */
#ifdef OPENSSL_SYS_WIN32
	FILETIME tv;
# ifdef _WIN32_WCE
	SYSTEMTIME t;
	GetSystemTime(&t);
	SystemTimeToFileTime(&t, &tv);
# else
	GetSystemTimeAsFileTime(&tv);
# endif
#elif defined(OPENSSL_SYS_VXWORKS)
	struct timespec tv;
	clock_gettime(CLOCK_REALTIME, &ts);
#elif defined(OPENSSL_SYSNAME_DSPBIOS)
	unsigned long long tv, OPENSSL_rdtsc();
	tv = OPENSSL_rdtsc();
#else
	struct timeval tv;
	gettimeofday(&tv, NULL);
#endif

#ifdef PREDICT
	if (rand_predictable)
		{
		static unsigned char val=0;

		for (i=0; i<num; i++)
			buf[i]=val++;
		return(1);
		}
#endif

	if (num <= 0)
		return 1;

	EVP_MD_CTX_init(&m);
	/* round upwards to multiple of MD_DIGEST_LENGTH/2 */
	num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);

	/*
	 * (Based on the rand(3) manpage:)
	 *
	 * For each group of 10 bytes (or less), we do the following:
	 *
	 * Input into the hash function the local 'md' (which is initialized from
	 * the global 'md' before any bytes are generated), the bytes that are to
	 * be overwritten by the random bytes, and bytes from the 'state'
	 * (incrementing looping index). From this digest output (which is kept
	 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
	 * bottom 10 bytes are xored into the 'state'.
	 * 
	 * Finally, after we have finished 'num' random bytes for the
	 * caller, 'count' (which is incremented) and the local and global 'md'
	 * are fed into the hash function and the results are kept in the
	 * global 'md'.
	 */

	CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
	CRYPTO_THREADID_current(&locking_threadid);
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
	crypto_lock_rand = 1;

	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}
	
	if (!stirred_pool)
		do_stir_pool = 1;
	
	ok = (entropy >= ENTROPY_NEEDED);
	if (!ok)
		{
		/* If the PRNG state is not yet unpredictable, then seeing
		 * the PRNG output may help attackers to determine the new
		 * state; thus we have to decrease the entropy estimate.
		 * Once we've had enough initial seeding we don't bother to
		 * adjust the entropy count, though, because we're not ambitious
		 * to provide *information-theoretic* randomness.
		 *
		 * NOTE: This approach fails if the program forks before
		 * we have enough entropy. Entropy should be collected
		 * in a separate input pool and be transferred to the
		 * output pool only when the entropy limit has been reached.
		 */
		entropy -= num;
		if (entropy < 0)
			entropy = 0;
		}

	if (do_stir_pool)
		{
		/* In the output function only half of 'md' remains secret,
		 * so we better make sure that the required entropy gets
		 * 'evenly distributed' through 'state', our randomness pool.
		 * The input function (ssleay_rand_add) chains all of 'md',
		 * which makes it more suitable for this purpose.
		 */

		int n = STATE_SIZE; /* so that the complete pool gets accessed */
		while (n > 0)
			{
#if MD_DIGEST_LENGTH > 20
# error "Please adjust DUMMY_SEED."
#endif
#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
			/* Note that the seed does not matter, it's just that
			 * ssleay_rand_add expects to have something to hash. */
			ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
			n -= MD_DIGEST_LENGTH;
			}
		if (ok)
			stirred_pool = 1;
		}

	st_idx=state_index;
	st_num=state_num;
	md_c[0] = md_count[0];
	md_c[1] = md_count[1];
	memcpy(local_md, md, sizeof md);

	state_index+=num_ceil;
	if (state_index > state_num)
		state_index %= state_num;

	/* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
	 * are now ours (but other threads may use them too) */

	md_count[0] += 1;

	/* before unlocking, we must clear 'crypto_lock_rand' */
	crypto_lock_rand = 0;
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	while (num > 0)
		{
		/* num_ceil -= MD_DIGEST_LENGTH/2 */
		j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
		num-=j;
		if (!MD_Init(&m))
			goto err;
#ifndef GETPID_IS_MEANINGLESS
		if (curr_pid) /* just in the first iteration to save time */
			{
			if (!MD_Update(&m,(unsigned char*)&curr_pid,
				       sizeof curr_pid))
				goto err;
			curr_pid = 0;
			}
#endif
		if (curr_time) /* just in the first iteration to save time */
			{
			if (!MD_Update(&m,(unsigned char*)&curr_time,
				       sizeof curr_time))
				goto err;
			if (!MD_Update(&m,(unsigned char*)&tv,
				       sizeof tv))
				goto err;
			curr_time = 0;
			rand_hw_seed(&m);
			}
		if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
			goto err;
		if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
			goto err;

#ifndef PURIFY /* purify complains */
		/* The following line uses the supplied buffer as a small
		 * source of entropy: since this buffer is often uninitialised
		 * it may cause programs such as purify or valgrind to
		 * complain. So for those builds it is not used: the removal
		 * of such a small source of entropy has negligible impact on
		 * security.
		 */
		if (!MD_Update(&m,buf,j))
			goto err;
#endif

		k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
		if (k > 0)
			{
			if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k))
				goto err;
			if (!MD_Update(&m,&(state[0]),k))
				goto err;
			}
		else
			if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2))
				goto err;
		if (!MD_Final(&m,local_md))
			goto err;

		for (i=0; i<MD_DIGEST_LENGTH/2; i++)
			{
			state[st_idx++]^=local_md[i]; /* may compete with other threads */
			if (st_idx >= st_num)
				st_idx=0;
			if (i < j)
				*(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
			}
		}

	if (!MD_Init(&m)
		|| !MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c))
		|| !MD_Update(&m,local_md,MD_DIGEST_LENGTH))
		goto err;
	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
	if (!MD_Update(&m,md,MD_DIGEST_LENGTH) || !MD_Final(&m,md))
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		goto err;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

	EVP_MD_CTX_cleanup(&m);
	if (ok)
		return(1);
	else if (pseudo)
		return 0;
	else 
		{
		RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
		ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
			"http://www.openssl.org/support/faq.html");
		return(0);
		}
	err:
	EVP_MD_CTX_cleanup(&m);
	RANDerr(RAND_F_SSLEAY_RAND_BYTES,ERR_R_EVP_LIB);
	return 0;

	}
コード例 #16
0
ファイル: b_sock.c プロジェクト: Acidburn0zzz/tcpcrypt
struct hostent *BIO_gethostbyname(const char *name)
	{
#if 1
	/* Caching gethostbyname() results forever is wrong,
	 * so we have to let the true gethostbyname() worry about this */
#if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
	return gethostbyname((char*)name);
#else
	return gethostbyname(name);
#endif
#else
	struct hostent *ret;
	int i,lowi=0,j;
	unsigned long low= (unsigned long)-1;


#  if 0
	/* It doesn't make sense to use locking here: The function interface
	 * is not thread-safe, because threads can never be sure when
	 * some other thread destroys the data they were given a pointer to.
	 */
	CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME);
#  endif
	j=strlen(name);
	if (j < 128)
		{
		for (i=0; i<GHBN_NUM; i++)
			{
			if (low > ghbn_cache[i].order)
				{
				low=ghbn_cache[i].order;
				lowi=i;
				}
			if (ghbn_cache[i].order > 0)
				{
				if (strncmp(name,ghbn_cache[i].name,128) == 0)
					break;
				}
			}
		}
	else
		i=GHBN_NUM;

	if (i == GHBN_NUM) /* no hit*/
		{
		BIO_ghbn_miss++;
		/* Note: under VMS with SOCKETSHR, it seems like the first
		 * parameter is 'char *', instead of 'const char *'
		 */
#  ifndef CONST_STRICT
		ret=gethostbyname((char *)name);
#  else
		ret=gethostbyname(name);
#  endif

		if (ret == NULL)
			goto end;
		if (j > 128) /* too big to cache */
			{
#  if 0
			/* If we were trying to make this function thread-safe (which
			 * is bound to fail), we'd have to give up in this case
			 * (or allocate more memory). */
			ret = NULL;
#  endif
			goto end;
			}

		/* else add to cache */
		if (ghbn_cache[lowi].ent != NULL)
			ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */
		ghbn_cache[lowi].name[0] = '\0';

		if((ret=ghbn_cache[lowi].ent=ghbn_dup(ret)) == NULL)
			{
			BIOerr(BIO_F_BIO_GETHOSTBYNAME,ERR_R_MALLOC_FAILURE);
			goto end;
			}
		strncpy(ghbn_cache[lowi].name,name,128);
		ghbn_cache[lowi].order=BIO_ghbn_miss+BIO_ghbn_hits;
		}
	else
		{
		BIO_ghbn_hits++;
		ret= ghbn_cache[i].ent;
		ghbn_cache[i].order=BIO_ghbn_miss+BIO_ghbn_hits;
		}
end:
#  if 0
	CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME);
#  endif
	return(ret);
#endif
	}
コード例 #17
0
ファイル: eng_table.c プロジェクト: prestocore/browser
ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
#endif
	{
	ENGINE *ret = NULL;
	ENGINE_PILE tmplate, *fnd=NULL;
	int initres, loop = 0;

	if(!(*table))
		{
#ifdef ENGINE_TABLE_DEBUG
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
			"registered!\n", f, l, nid);
#endif
		return NULL;
		}
	ERR_set_mark();
	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
	/* Check again inside the lock otherwise we could race against cleanup
	 * operations. But don't worry about a fprintf(stderr). */
	if(!int_table_check(table, 0)) goto end;
	tmplate.nid = nid;
	fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
	if(!fnd) goto end;
	if(fnd->funct && engine_unlocked_init(fnd->funct))
		{
#ifdef ENGINE_TABLE_DEBUG
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
			"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
#endif
		ret = fnd->funct;
		goto end;
		}
	if(fnd->uptodate)
		{
		ret = fnd->funct;
		goto end;
		}
trynext:
	ret = sk_ENGINE_value(fnd->sk, loop++);
	if(!ret)
		{
#ifdef ENGINE_TABLE_DEBUG
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
				"registered implementations would initialise\n",
				f, l, nid);
#endif
		goto end;
		}
	/* Try to initialise the ENGINE? */
	if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
		initres = engine_unlocked_init(ret);
	else
		initres = 0;
	if(initres)
		{
		/* Update 'funct' */
		if((fnd->funct != ret) && engine_unlocked_init(ret))
			{
			/* If there was a previous default we release it. */
			if(fnd->funct)
				engine_unlocked_finish(fnd->funct, 0);
			fnd->funct = ret;
#ifdef ENGINE_TABLE_DEBUG
			fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
				"setting default to '%s'\n", f, l, nid, ret->id);
#endif
			}
#ifdef ENGINE_TABLE_DEBUG
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
				"newly initialised '%s'\n", f, l, nid, ret->id);
#endif
		goto end;
		}
	goto trynext;
end:
	/* If it failed, it is unlikely to succeed again until some future
	 * registrations have taken place. In all cases, we cache. */
	if(fnd) fnd->uptodate = 1;
#ifdef ENGINE_TABLE_DEBUG
	if(ret)
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
				"ENGINE '%s'\n", f, l, nid, ret->id);
	else
		fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
				"'no matching ENGINE'\n", f, l, nid);
#endif
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	/* Whatever happened, any failed init()s are not failures in this
	 * context, so clear our error state. */
	ERR_pop_to_mark();
	return ret;
	}
コード例 #18
0
int CRYPTO_mem_ctrl(int mode)
	{
	int ret=mh_mode;

	CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
	switch (mode)
		{
	/* for applications (not to be called while multiple threads
	 * use the library): */
	case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
		mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
		num_disable = 0;
		break;
	case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
		mh_mode = 0;
		num_disable = 0; /* should be true *before* MemCheck_stop is used,
		                    or there'll be a lot of confusion */
		break;

	/* switch off temporarily (for library-internal use): */
	case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
		if (mh_mode & CRYPTO_MEM_CHECK_ON)
			{
			if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */
				{
				/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
				 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
				 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
				 * it because we block entry to this function).
				 * Give them a chance, first, and then claim the locks in
				 * appropriate order (long-time lock first).
				 */
				CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
				/* Note that after we have waited for CRYPTO_LOCK_MALLOC2
				 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
				 * "case" and "if" branch because MemCheck_start and
				 * MemCheck_stop may never be used while there are multiple
				 * OpenSSL threads. */
				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
				CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
				mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
				disabling_thread=CRYPTO_thread_id();
				}
			num_disable++;
			}
		break;
	case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
		if (mh_mode & CRYPTO_MEM_CHECK_ON)
			{
			if (num_disable) /* always true, or something is going wrong */
				{
				num_disable--;
				if (num_disable == 0)
					{
					mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
					CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
					}
				}
			}
		break;

	default:
		break;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
	return(ret);
	}