biginteger OpenSSLRSAPermutation::computeRSA(biginteger elementP) {
	ERR_load_crypto_strings();
	//SSL_load_error_strings();
	// Seed the random geneartor.
#ifdef _WIN32
	RAND_screen(); // only defined for windows, reseeds from screen contents
#else
	RAND_poll(); // reseeds using hardware state (clock, interrupts, etc).
#endif

	// Allocate a new byte array to hold the output.
	int size = RSA_size(rsa);
	std::shared_ptr<byte> ret(new byte[size], std::default_delete<byte[]>());

	size_t encodedSize = bytesCount(elementP);
	std::shared_ptr<byte> encodedBi(new byte[encodedSize], std::default_delete<byte[]>());
	encodeBigInteger(elementP, encodedBi.get(), encodedSize);
	int success = RSA_public_encrypt(encodedSize, encodedBi.get(), ret.get(), rsa, RSA_NO_PADDING);
	if (-1 == success)
	{
		string error(ERR_reason_error_string(ERR_get_error()));
		throw runtime_error("failed to compute rsa " + error);
	}
	biginteger result = decodeBigInteger(ret.get(), size);
	return result;
}
Exemplo n.º 2
0
void OpenSSL::ClassInit() {
	MS_TRACE();

	MS_DEBUG("loaded openssl version: %s", SSLeay_version(SSLEAY_VERSION));

	// First initialize OpenSSL stuff.
	SSL_load_error_strings();
	SSL_library_init();
	RAND_poll();

	// Make OpenSSL thread-safe.
	OpenSSL::mutexes = new pthread_mutex_t[CRYPTO_num_locks()];
	if (! OpenSSL::mutexes)
		MS_THROW_ERROR("allocation of mutexes failed");

	OpenSSL::numMutexes = CRYPTO_num_locks();

	for (int i=0; i<OpenSSL::numMutexes; i++) {
		int err = pthread_mutex_init(&OpenSSL::mutexes[i], nullptr);
		if (err)
			MS_THROW_ERROR("pthread_mutex_init() failed with return code %d\n", err);
	}

	CRYPTO_THREADID_set_callback(OpenSSL::SetThreadId);
	CRYPTO_set_locking_callback(OpenSSL::LockingFunction);
	CRYPTO_set_dynlock_create_callback(OpenSSL::DynCreateFunction);
	CRYPTO_set_dynlock_lock_callback(OpenSSL::DynLockFunction);
	CRYPTO_set_dynlock_destroy_callback(OpenSSL::DynDestroyFunction);
}
Exemplo n.º 3
0
static SSL_CTX *
evssl_init(void)
{
    SSL_CTX  *server_ctx;

    /* Initialize the OpenSSL library */
    SSL_load_error_strings();
    SSL_library_init();
    /* We MUST have entropy, or else there's no point to crypto. */
    if (!RAND_poll())
        return NULL;

    server_ctx = SSL_CTX_new(SSLv23_server_method());

    if (! SSL_CTX_use_certificate_chain_file(server_ctx, "cert") ||
            ! SSL_CTX_use_PrivateKey_file(server_ctx, "pkey", SSL_FILETYPE_PEM)) {
        puts("Couldn't read 'pkey' or 'cert' file.  To generate a key\n"
             "and self-signed certificate, run:\n"
             "  openssl genrsa -out pkey 2048\n"
             "  openssl req -new -key pkey -out cert.req\n"
             "  openssl x509 -req -days 365 -in cert.req -signkey pkey -out cert");
        return NULL;
    }
    SSL_CTX_set_options(server_ctx, SSL_OP_NO_SSLv2);

    return server_ctx;
}
Exemplo n.º 4
0
void openssl_bioBS_random()
{
	int size;
	const char *p;
	unsigned char outs[SHA_DIGEST_LENGTH + 16] = { 0 };
	char buf[32], filename[COMM_LEN];

	strcpy(buf, "bioBS random");
	RAND_add(buf, 32, strlen(buf));
	strcpy(buf, "beike2012");
	RAND_seed(buf, 32);
	while (1) {
		if (RAND_status() == 1)
			break;
		else
			RAND_poll();
	}

	p = RAND_file_name(filename, COMM_LEN);
	RAND_write_file(p);
	RAND_load_file(p, MAX1_LEN);
	RAND_bytes(outs, sizeof(outs));
	printf("\nBIO_RANDOM() = ");
	for (size = 0; size < strlen((char *)&outs); size++)
		printf("%.02x", outs[size]);
	printf("\n");
	RAND_cleanup();
}
Exemplo n.º 5
0
/*
 * 执行ssl请求,返回chttp_str_t *  需要释放内存
 */
chttp_str_t* chttp_ssl_request(chttp_socket_t socket, void *buffer, size_t size)
{
#if defined(_HTTPS)
	SSL_CTX *ctx = NULL;
	SSL *ssl = NULL;
	int ret = 0;
	char text[1024];
	chttp_str_t *html = NULL;

	SSL_library_init();
	SSL_load_error_strings();

	ctx = SSL_CTX_new(SSLv23_client_method());
	if (ctx == NULL)
		return NULL;

	ssl = SSL_new(ctx);
	if (ssl == NULL)
		return NULL;

	ret = SSL_set_fd(ssl, socket);
	if (0 == ret)
		return NULL;

	RAND_poll();
	while (RAND_status() == 0)
	{
		unsigned short rand_ret = rand() % 65536;
		RAND_seed(&rand_ret, sizeof(rand_ret));
	}

	ret = SSL_connect(ssl);
	if (ret != 1)
		return NULL;

	if (!(SSL_write(ssl, buffer, size)))
	{
		return NULL;
	}

	while ((ret = SSL_read(ssl, text, 1024)) > 0)
	{
		html = chttp_str_size_append(html, text, ret);
	}

	//free resource
	if (ssl)
	{
		SSL_free(ssl);
		SSL_CTX_free(ctx);
		ERR_free_strings();
	}

	return html;
#else
	printf("不支持https方式请求,请在编译的时候加入开启 _HTTPS \n");
	exit(1);
#endif
}
Exemplo n.º 6
0
Global::Global() {
  SSL_library_init();
  ERR_load_CRYPTO_strings();
  SSL_load_error_strings();
  OpenSSL_add_all_algorithms();
  RAND_poll();
  event_base = event_base_new();
  dns_base = evdns_base_new(event_base, 1);
};
Exemplo n.º 7
0
QByteArray KeyHelper::getRandomBytes(int bytes)
{
    RAND_poll();

    unsigned char buff1[bytes];
    memset(buff1, 0, bytes);
    RAND_bytes(buff1, bytes);
    return QByteArray::fromRawData((const char *)buff1, bytes);
}
Exemplo n.º 8
0
golle_error golle_random_seed (void) {
  LOAD_HARDWARE_ENGINE;
    
  /* Only seed when needed */
  if (!RAND_status ()) {
    RAND_poll ();
  }
  return GOLLE_OK;
}
Exemplo n.º 9
0
SSL_CTX *
evssl_init()
{
	DH		*dh;
	SSL_CTX		*ctx;

	SSL_load_error_strings();
	SSL_library_init();
	RAND_poll();

	if ((passport = pki_passport_load_from_file(cfg->cert,
	    cfg->pkey, cfg->tcert)) == NULL) {
		return NULL;
	}

	if ((ctx = SSL_CTX_new(TLSv1_2_client_method())) == NULL) {
		jlog(L_ERROR, "SSL_CTX_new failed");
		return NULL;
	}

	if ((dh = get_dh_1024()) == NULL) {
		jlog(L_ERROR, "get_dh_1024 failed");
		goto out;
	}

	if ((SSL_CTX_set_tmp_dh(ctx, dh)) == 0) {
		jlog(L_ERROR, "SSL_CTX_set_tmp_dh failed");
		goto out;
	}

	//SSL_CTX_set_cipher_list(ctx, "ECDHE-ECDSA-AES256-GCM-SHA384");
	if ((SSL_CTX_set_cipher_list(ctx, "AES256-GCM-SHA384")) == 0) {
		jlog(L_ERROR, "SSL_CTX_set_cipher failed");
		goto out;
	}

	SSL_CTX_set_cert_store(ctx, passport->cacert_store);

	if ((SSL_CTX_use_certificate(ctx, passport->certificate)) == 0) {
		jlog(L_ERROR, "SSL_CTX_use_certificate failed");
		goto out;
	}

	if ((SSL_CTX_use_PrivateKey(ctx, passport->keyring)) == 0) {
		jlog(L_ERROR, "SSL_CTX_use_PrivateKey failed");
		goto out;
	}

	DH_free(dh);
	return ctx;

out:
	DH_free(dh);
	SSL_CTX_free(ctx);
	return NULL;
}
Exemplo n.º 10
0
QByteArray KeyHelper::generateSenderKey()
{
    RAND_poll();

    unsigned char buff1[32];
    memset(buff1, 0, 32);
    RAND_bytes(buff1, 32);

    QByteArray key = QByteArray::fromRawData((const char*)buff1, 32);
    return key;
}
Exemplo n.º 11
0
static int rand_status(void)
{
    CRYPTO_THREAD_ID cur;
    int ret;
    int do_not_lock;

    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
        return 0;

    cur = CRYPTO_THREAD_get_current_id();
    /*
     * check if we already have the lock (could happen if a RAND_poll()
     * implementation calls RAND_status())
     */
    if (crypto_lock_rand) {
        CRYPTO_THREAD_read_lock(rand_tmp_lock);
        do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
        CRYPTO_THREAD_unlock(rand_tmp_lock);
    } else
        do_not_lock = 0;

    if (!do_not_lock) {
        CRYPTO_THREAD_write_lock(rand_lock);
        /*
         * Prevent deadlocks in case we end up in an async engine
         */
        ASYNC_block_pause();

        /*
         * prevent rand_bytes() from trying to obtain the lock again
         */
        CRYPTO_THREAD_write_lock(rand_tmp_lock);
        locking_threadid = cur;
        CRYPTO_THREAD_unlock(rand_tmp_lock);
        crypto_lock_rand = 1;
    }

    if (!initialized) {
        RAND_poll();
        initialized = 1;
    }

    ret = entropy >= ENTROPY_NEEDED;

    if (!do_not_lock) {
        /* before unlocking, we must clear 'crypto_lock_rand' */
        crypto_lock_rand = 0;

        ASYNC_unblock_pause();
        CRYPTO_THREAD_unlock(rand_lock);
    }

    return ret;
}
Exemplo n.º 12
0
quint64 KeyHelper::getRandomFFFF()
{
    RAND_poll();

    unsigned char buff1[2];
    memset(buff1, 0, 2);
    RAND_bytes(buff1, 2);
    quint64 rand1 = ((unsigned int)buff1[1] << 8) + (unsigned int)buff1[0];

    return rand1;
}
Exemplo n.º 13
0
quint64 KeyHelper::getRandomFFFFFFFF()
{
    RAND_poll();

    unsigned char buff1[4];
    memset(buff1, 0, 4);
    RAND_bytes(buff1, 4);
    quint64 rand1 = ((unsigned long)buff1[3] << 24) + ((unsigned int)buff1[2] << 16)
                       +  ((unsigned int)buff1[1] << 8)  +  (unsigned int)buff1[0];

    return rand1;
}
Exemplo n.º 14
0
Global::Global() {
  SSL_library_init();
  ERR_load_CRYPTO_strings();
  SSL_load_error_strings();
  OpenSSL_add_all_algorithms();
  RAND_poll();
#ifndef _NO_LIBEVENT_THREADS
  evthread_use_pthreads();
#endif
  event_base = event_base_new();
  dns_base = evdns_base_new(event_base, 1);
};
Exemplo n.º 15
0
void
ntp_crypto_srandom(
	void
	)
{
#ifdef USE_OPENSSL_CRYPTO_RAND
	if (!crypto_rand_init) {
		RAND_poll();
		crypto_rand_init = 1;
	}
#else
	/* No initialization needed for arc4random() */
#endif
}
Exemplo n.º 16
0
bool SecureRNG::seed()
{
#if QT_VERSION >= 0x040700
    QElapsedTimer timer;
    timer.start();
#endif

#ifdef Q_OS_WIN
    /* RAND_poll is very unreliable on windows; with older versions of OpenSSL,
     * it can take up to several minutes to run and has been known to crash.
     * Even newer versions seem to take around 400ms, which is far too long for
     * interactive startup. Random data from the windows CSP is used as a seed
     * instead, as it should be very high quality random and fast. */
    HCRYPTPROV provider = 0;
    if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
    {
        qWarning() << "Failed to acquire CSP context for RNG seed:" << hex << GetLastError();
        return false;
    }

    /* Same amount of entropy OpenSSL uses, apparently. */
    char buf[32];

    if (!CryptGenRandom(provider, sizeof(buf), reinterpret_cast<BYTE*>(buf)))
    {
        qWarning() << "Failed to get entropy from CSP for RNG seed: " << hex << GetLastError();
        CryptReleaseContext(provider, 0);
        return false;
    }

    CryptReleaseContext(provider, 0);

    RAND_seed(buf, sizeof(buf));
    memset(buf, 0, sizeof(buf));
#else
    if (!RAND_poll())
    {
        qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error();
        return false;
    }
#endif

#if QT_VERSION >= 0x040700
    qDebug() << "RNG seed took" << timer.elapsed() << "ms";
#endif

    return true;
}
Exemplo n.º 17
0
quint64 KeyHelper::getRandom7FFFFFFF()
{
    RAND_poll();

    quint64 rand2 = 0;
    for (int i = 0; i < 0x80; i++) {
        unsigned char buff0[3];
        memset(buff0, 0, 3);
        RAND_bytes(buff0, 3);
        rand2 += ((unsigned int)buff0[2] << 16);
        rand2 += ((unsigned int)buff0[1] << 8);
        rand2 += (unsigned int)buff0[0];
    }

    return rand2;
}
Exemplo n.º 18
0
static int ssleay_rand_status(void)
	{
	CRYPTO_THREADID cur;
	int ret;
	int do_not_lock;

	CRYPTO_THREADID_current(&cur);
	/* check if we already have the lock
	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
	if (crypto_lock_rand)
		{
		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);
		
		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
		CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
		CRYPTO_THREADID_cpy(&locking_threadid, &cur);
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
		crypto_lock_rand = 1;
		}
	
	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}

	ret = entropy >= ENTROPY_NEEDED;

	if (!do_not_lock)
		{
		/* before unlocking, we must clear 'crypto_lock_rand' */
		crypto_lock_rand = 0;
		
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		}
	
	return ret;
	}
Exemplo n.º 19
0
static SSL_CTX * ssl_server_init(const char *keypath, const char *certpath)
{
    SSL_CTX *ctx;
    ENGINE *e;

    ENGINE_load_builtin_engines();
    ENGINE_register_all_complete();

    e = ENGINE_by_id("padlock");
    if (e) {
        fprintf(stderr, "[*] Using padlock engine for default ciphers\n");
        ENGINE_set_default_ciphers(ENGINE_by_id("padlock"));
        use_padlock_engine = 1;
    } else {
        fprintf(stderr, "[*] Padlock engine not available\n");
        use_padlock_engine = 0;
    }

    SSL_load_error_strings();
    SSL_library_init();

    if (!RAND_poll())
	return NULL;

    ctx = SSL_CTX_new(SSLv23_server_method());

    if (!SSL_CTX_use_certificate_chain_file(ctx, certpath) ||
	    !SSL_CTX_use_PrivateKey_file(ctx, keypath, SSL_FILETYPE_PEM)) {
	fprintf(stderr, "Could not read %s or %s file\n", keypath, certpath);
	fprintf(stderr, "To generate a key and self-signed certificate, run:\n");
	fprintf(stderr, "\topenssl genrsa -out key.pem 2048\n");
	fprintf(stderr, "\topenssl req -new -key key.pem -out cert.req\n");
	fprintf(stderr, "\topenssl x509 -req -days 365 -in cert.req -signkey key.pem -out cert.pem\n");
	return NULL;
    }

    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
    if (use_padlock_engine == 1) {
	if (SSL_CTX_set_cipher_list(ctx, "AES+SHA") != 1) {
	    fprintf(stderr, "Error setting client cipher list\n");
	    return NULL;
	}
    }
    return ctx;
}
Exemplo n.º 20
0
/*
 * DRBG has two sets of callbacks; we only discuss the "entropy" one
 * here.  When the DRBG needs additional randomness bits (called entropy
 * in the NIST document), it calls the get_entropy callback which fills in
 * a pointer and returns the number of bytes. When the DRBG is finished with
 * the buffer, it calls the cleanup_entropy callback, with the value of
 * the buffer that the get_entropy callback filled in.
 *
 * Get entropy from the system, via RAND_poll if needed.  The |entropy|
 * is the bits of randomness required, and is expected to fit into a buffer
 * of |min_len|..|max__len| size.  We assume we're getting high-quality
 * randomness from the system, and that |min_len| bytes will do.
 */
size_t drbg_entropy_from_system(RAND_DRBG *drbg,
                                unsigned char **pout,
                                int entropy, size_t min_len, size_t max_len)
{
    int i;


    if (min_len > (size_t)drbg->size) {
        /* Should not happen.  See comment near RANDOMNESS_NEEDED. */
        min_len = drbg->size;
    }

    if (drbg->filled) {
        /* Re-use what we have. */
        *pout = drbg->randomness;
        return drbg->size;
    }

    drbg->randomness = drbg->secure ? OPENSSL_secure_malloc(drbg->size)
                                    : OPENSSL_malloc(drbg->size);

    /* If we don't have enough, try to get more. */
    CRYPTO_THREAD_write_lock(rand_bytes.lock);
    for (i = RAND_POLL_RETRIES; rand_bytes.curr < min_len && --i >= 0; ) {
        CRYPTO_THREAD_unlock(rand_bytes.lock);
        RAND_poll();
        CRYPTO_THREAD_write_lock(rand_bytes.lock);
    }

    /* Get desired amount, but no more than we have. */
    if (min_len > rand_bytes.curr)
        min_len = rand_bytes.curr;
    if (min_len != 0) {
        memcpy(drbg->randomness, rand_bytes.buff, min_len);
        drbg->filled = 1;
        /* Update amount left and shift it down. */
        rand_bytes.curr -= min_len;
        if (rand_bytes.curr != 0)
            memmove(rand_bytes.buff, &rand_bytes.buff[min_len], rand_bytes.curr);
    }
    CRYPTO_THREAD_unlock(rand_bytes.lock);
    *pout = drbg->randomness;
    return min_len;
}
Exemplo n.º 21
0
static void RandomSeed(void)
{
    /* 1. Seed the weak C PRNGs. */

    /* Mix various stuff. */
    pid_t pid = getpid();
    size_t fqdn_len = strlen(VFQNAME) > 0 ? strlen(VFQNAME) : 1;
    time_t start_time = CFSTARTTIME;
    time_t now = time(NULL);

    srand((unsigned) pid      * start_time ^
          (unsigned) fqdn_len * now);
    srand48((long)  pid      * start_time ^
            (long)  fqdn_len * now);

    /* 2. Seed the strong OpenSSL PRNG. */

#ifndef __MINGW32__                                     /* windows may hang */
    RAND_poll();
#else
    RAND_screen();
#endif

    if (RAND_status() != 1)
    {
        /* randseed file is written on deinitialization of crypto system */
        char randfile[CF_BUFSIZE];
        snprintf(randfile, CF_BUFSIZE, "%s%crandseed",
                 CFWORKDIR, FILE_SEPARATOR);
        Log(LOG_LEVEL_VERBOSE, "Looking for a source of entropy in '%s'",
            randfile);

        if (RAND_load_file(randfile, -1) != 1024)
        {
            Log(LOG_LEVEL_CRIT,
                "Could not read randomness from '%s'", randfile);
            unlink(randfile); /* kill randseed if error reading it */
        }

        /* If we've used the random seed, then delete */
        unlink(randfile);
    }
}
Exemplo n.º 22
0
/**
 * Initialize Droplet global data.
 *
 * Initializes global data used by the library.  Must be called once
 * and only once before any other Droplet library functions.  The next
 * step after calling `dpl_init()` is probably `dpl_ctx_new()`.
 *
 * @retval DPL_SUCCESS this function cannot currently fail
 */
dpl_status_t
dpl_init()
{
  SSL_library_init();
  SSL_load_error_strings();
  ERR_load_crypto_strings();

  /* RAND_seed(randbuf, strlen(randbuf)); */
  int ret = RAND_status();
  if (0 == ret) {
    DPL_LOG(NULL, DPL_WARNING, "PRNG not properly seeded, seeding it...");
    RAND_poll();
    ret = RAND_status();
    DPL_LOG(NULL, DPL_INFO, "PRNG state after seeding: %d", ret);
  } else if (1 == ret) {
    DPL_LOG(NULL, DPL_INFO, "PRNG has been seeded with enough data");
  }

  dpl_base64_init();

  return DPL_SUCCESS;
}
Exemplo n.º 23
0
int LOF_CONNECTION_FetionConnection_ssl_connection_start(LOF_CONNECTION_FetionConnectionType* conn)
{
    int ret;
    SSL_load_error_strings();
    SSL_library_init();
    conn->ssl_ctx = SSL_CTX_new(SSLv23_client_method());

    if ( conn->ssl_ctx == NULL ) {
        LOF_debug_info("Init SSL CTX failed");
        return -1;
    }
    conn->ssl = SSL_new(conn->ssl_ctx);

    if ( conn->ssl == NULL ) {
        LOF_debug_info("New SSL with created CTX failed");
        return -1;
    }
    ret = SSL_set_fd(conn->ssl, conn->socketfd);

    if ( ret == 0 ) {
        LOF_debug_info("Add ssl to tcp socket failed");
        return -1;
    }
    RAND_poll();
    while ( RAND_status() == 0 )
    {
        unsigned short rand_ret = rand() % 65536;
        RAND_seed(&rand_ret, sizeof(rand_ret));
    }
    ret = SSL_connect(conn->ssl);
    if( ret != 1 )
    {
        LOF_debug_info("SSL connection failed");
        return -1;
    }
    return 0;
}
Exemplo n.º 24
0
static int ssleay_rand_status(void)
	{
	int ret;
	int do_not_lock;

	/* check if we already have the lock
	 * (could happen if a RAND_poll() implementation calls RAND_status()) */
	do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id());
	
	if (!do_not_lock)
		{
		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
		
		/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
		crypto_lock_rand = 1;
		locking_thread = CRYPTO_thread_id();
		}
	
	if (!initialized)
		{
		RAND_poll();
		initialized = 1;
		}

	ret = entropy >= ENTROPY_NEEDED;

	if (!do_not_lock)
		{
		/* before unlocking, we must clear 'crypto_lock_rand' */
		crypto_lock_rand = 0;
		locking_thread = 0;
		
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		}
	
	return ret;
	}
int connect_ssl_server(struct sockaddr_in *server, SSL *ssl) {
	int s;
	int ret;
	if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		print_line("ソケットの生成に失敗しました。");
		return -1;
	}

	if(connect(s, (struct sockaddr *)server, sizeof(*server)) == -1) {
		print_line("connect に失敗しました。");
		return -1;
	}
	
	/* ここからが SSL */
	
	ret = SSL_set_fd(ssl, s);
	if(ret == 0) {
		ERR_print_errors_fp(stderr);
		return -1;
	}

	/* PRNG 初期化 */
	RAND_poll();
	while(RAND_status() == 0) {
		unsigned short rand_ret = rand() % 65536;
		RAND_seed(&rand_ret, sizeof(rand_ret));
	}

	/* SSL で接続 */
	ret = SSL_connect(ssl);
	if(ret != 1) {
		ERR_print_errors_fp(stderr);
		return -1;
	}
	return s;
}
Exemplo n.º 26
0
static void li_rand_init (void)
{
    /* (intended to be called at init and after fork() in order to re-seed PRNG
     *  so that forked children, grandchildren, etc do not share PRNG seed)
     * https://github.com/ramsey/uuid/issues/80
     * https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux
     *   (issue in early version of libressl has since been fixed)
     * https://github.com/libressl-portable/portable/commit/32d9eeeecf4e951e1566d5f4a42b36ea37b60f35
     */
    unsigned int u;
    li_rand_inited = 1;
    if (1 == li_rand_device_bytes((unsigned char *)xsubi, (int)sizeof(xsubi))) {
        u = ((unsigned int)xsubi[0] << 16) | xsubi[1];
    }
    else {
      #ifdef HAVE_ARC4RANDOM_BUF
        u = arc4random();
        arc4random_buf(xsubi, sizeof(xsubi));
      #else
        /* NOTE: not cryptographically random !!! */
        srand((unsigned int)(time(NULL) ^ getpid()));
        for (u = 0; u < sizeof(unsigned short); ++u)
            /* coverity[dont_call : FALSE] */
            xsubi[u] = (unsigned short)(rand() & 0xFFFF);
        u = ((unsigned int)xsubi[0] << 16) | xsubi[1];
      #endif
    }
    srand(u);   /*(initialize just in case rand() used elsewhere)*/
  #ifdef HAVE_SRANDOM
    srandom(u); /*(initialize just in case random() used elsewhere)*/
  #endif
  #ifdef USE_OPENSSL_CRYPTO
    RAND_poll();
    RAND_seed(xsubi, (int)sizeof(xsubi));
  #endif
}
Exemplo n.º 27
0
Arquivo: tor.c Projeto: postfix/libtor
bool
tor_add_entropy (void)
{
	return RAND_poll();
}
Exemplo n.º 28
0
Arquivo: ocsp.c Projeto: ciz/openssl
/*
 * Loop spawning up to `multi` child processes, only child processes return
 * from this function.  The parent process loops until receiving a termination
 * signal, kills extant children and exits without returning.
 */
static void spawn_loop(void)
{
    pid_t *kidpids = NULL;
    int status;
    int procs = 0;
    int i;

    openlog(prog, LOG_PID, LOG_DAEMON);

    if (setpgid(0, 0)) {
        syslog(LOG_ERR, "fatal: error detaching from parent process group: %s",
               strerror(errno));
        exit(1);
    }
    kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array");
    for (i = 0; i < multi; ++i)
        kidpids[i] = 0;

    signal(SIGINT, noteterm);
    signal(SIGTERM, noteterm);

    while (termsig == 0) {
        pid_t fpid;

        /*
         * Wait for a child to replace when we're at the limit.
         * Slow down if a child exited abnormally or waitpid() < 0
         */
        while (termsig == 0 && procs >= multi) {
            if ((fpid = waitpid(-1, &status, 0)) > 0) {
                for (i = 0; i < procs; ++i) {
                    if (kidpids[i] == fpid) {
                        kidpids[i] = 0;
                        --procs;
                        break;
                    }
                }
                if (i >= multi) {
                    syslog(LOG_ERR, "fatal: internal error: "
                           "no matching child slot for pid: %ld",
                           (long) fpid);
                    killall(1, kidpids);
                }
                if (status != 0) {
                    if (WIFEXITED(status))
                        syslog(LOG_WARNING, "child process: %ld, exit status: %d",
                               (long)fpid, WEXITSTATUS(status));
                    else if (WIFSIGNALED(status))
                        syslog(LOG_WARNING, "child process: %ld, term signal %d%s",
                               (long)fpid, WTERMSIG(status),
#ifdef WCOREDUMP
                               WCOREDUMP(status) ? " (core dumped)" :
#endif
                               "");
                    sleep(1);
                }
                break;
            } else if (errno != EINTR) {
                syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno));
                killall(1, kidpids);
            }
        }
        if (termsig)
            break;

        switch(fpid = fork()) {
        case -1:            /* error */
            /* System critically low on memory, pause and try again later */
            sleep(30);
            break;
        case 0:             /* child */
            OPENSSL_free(kidpids);
            signal(SIGINT, SIG_DFL);
            signal(SIGTERM, SIG_DFL);
            if (termsig)
                _exit(0);
            if (RAND_poll() <= 0) {
                syslog(LOG_ERR, "fatal: RAND_poll() failed");
                _exit(1);
            }
            return;
        default:            /* parent */
            for (i = 0; i < multi; ++i) {
                if (kidpids[i] == 0) {
                    kidpids[i] = fpid;
                    procs++;
                    break;
                }
            }
            if (i >= multi) {
                syslog(LOG_ERR, "fatal: internal error: no free child slots");
                killall(1, kidpids);
            }
            break;
        }
    }

    /* The loop above can only break on termsig */
    syslog(LOG_INFO, "terminating on signal: %d", termsig);
    killall(0, kidpids);
}
Exemplo n.º 29
0
int
main(int argc, char **argv)
{
	int r;

	struct evhttp_uri *http_uri = NULL;
	const char *url = NULL, *data_file = NULL;
	const char *crt = "/etc/ssl/certs/ca-certificates.crt";
	const char *scheme, *host, *path, *query;
	char uri[256];
	int port;
	int retries = 0;
	int timeout = -1;

	SSL_CTX *ssl_ctx = NULL;
	SSL *ssl = NULL;
	struct bufferevent *bev;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req;
	struct evkeyvalq *output_headers;
	struct evbuffer *output_buffer;

	int i;
	int ret = 0;
	enum { HTTP, HTTPS } type = HTTP;

	for (i = 1; i < argc; i++) {
		if (!strcmp("-url", argv[i])) {
			if (i < argc - 1) {
				url = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-crt", argv[i])) {
			if (i < argc - 1) {
				crt = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-ignore-cert", argv[i])) {
			ignore_cert = 1;
		} else if (!strcmp("-data", argv[i])) {
			if (i < argc - 1) {
				data_file = argv[i + 1];
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-retries", argv[i])) {
			if (i < argc - 1) {
				retries = atoi(argv[i + 1]);
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-timeout", argv[i])) {
			if (i < argc - 1) {
				timeout = atoi(argv[i + 1]);
			} else {
				syntax();
				goto error;
			}
		} else if (!strcmp("-help", argv[i])) {
			syntax();
			goto error;
		}
	}

	if (!url) {
		syntax();
		goto error;
	}

#ifdef _WIN32
	{
		WORD wVersionRequested;
		WSADATA wsaData;
		int err;

		wVersionRequested = MAKEWORD(2, 2);

		err = WSAStartup(wVersionRequested, &wsaData);
		if (err != 0) {
			printf("WSAStartup failed with error: %d\n", err);
			goto error;
		}
	}
#endif // _WIN32

	http_uri = evhttp_uri_parse(url);
	if (http_uri == NULL) {
		err("malformed url");
		goto error;
	}

	scheme = evhttp_uri_get_scheme(http_uri);
	if (scheme == NULL || (strcasecmp(scheme, "https") != 0 &&
	                       strcasecmp(scheme, "http") != 0)) {
		err("url must be http or https");
		goto error;
	}

	host = evhttp_uri_get_host(http_uri);
	if (host == NULL) {
		err("url must have a host");
		goto error;
	}

	port = evhttp_uri_get_port(http_uri);
	if (port == -1) {
		port = (strcasecmp(scheme, "http") == 0) ? 80 : 443;
	}

	path = evhttp_uri_get_path(http_uri);
	if (strlen(path) == 0) {
		path = "/";
	}

	query = evhttp_uri_get_query(http_uri);
	if (query == NULL) {
		snprintf(uri, sizeof(uri) - 1, "%s", path);
	} else {
		snprintf(uri, sizeof(uri) - 1, "%s?%s", path, query);
	}
	uri[sizeof(uri) - 1] = '\0';

#if OPENSSL_VERSION_NUMBER < 0x10100000L
	// Initialize OpenSSL
	SSL_library_init();
	ERR_load_crypto_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
#endif

	/* This isn't strictly necessary... OpenSSL performs RAND_poll
	 * automatically on first use of random number generator. */
	r = RAND_poll();
	if (r == 0) {
		err_openssl("RAND_poll");
		goto error;
	}

	/* Create a new OpenSSL context */
	ssl_ctx = SSL_CTX_new(SSLv23_method());
	if (!ssl_ctx) {
		err_openssl("SSL_CTX_new");
		goto error;
	}

#ifndef _WIN32
	/* TODO: Add certificate loading on Windows as well */

	/* Attempt to use the system's trusted root certificates.
	 * (This path is only valid for Debian-based systems.) */
	if (1 != SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL)) {
		err_openssl("SSL_CTX_load_verify_locations");
		goto error;
	}
	/* Ask OpenSSL to verify the server certificate.  Note that this
	 * does NOT include verifying that the hostname is correct.
	 * So, by itself, this means anyone with any legitimate
	 * CA-issued certificate for any website, can impersonate any
	 * other website in the world.  This is not good.  See "The
	 * Most Dangerous Code in the World" article at
	 * https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html
	 */
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
	/* This is how we solve the problem mentioned in the previous
	 * comment.  We "wrap" OpenSSL's validation routine in our
	 * own routine, which also validates the hostname by calling
	 * the code provided by iSECPartners.  Note that even though
	 * the "Everything You've Always Wanted to Know About
	 * Certificate Validation With OpenSSL (But Were Afraid to
	 * Ask)" paper from iSECPartners says very explicitly not to
	 * call SSL_CTX_set_cert_verify_callback (at the bottom of
	 * page 2), what we're doing here is safe because our
	 * cert_verify_callback() calls X509_verify_cert(), which is
	 * OpenSSL's built-in routine which would have been called if
	 * we hadn't set the callback.  Therefore, we're just
	 * "wrapping" OpenSSL's routine, not replacing it. */
	SSL_CTX_set_cert_verify_callback(ssl_ctx, cert_verify_callback,
					  (void *) host);
#else // _WIN32
	(void)crt;
#endif // _WIN32

	// Create event base
	base = event_base_new();
	if (!base) {
		perror("event_base_new()");
		goto error;
	}

	// Create OpenSSL bufferevent and stack evhttp on top of it
	ssl = SSL_new(ssl_ctx);
	if (ssl == NULL) {
		err_openssl("SSL_new()");
		goto error;
	}

	#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	// Set hostname for SNI extension
	SSL_set_tlsext_host_name(ssl, host);
	#endif

	if (strcasecmp(scheme, "http") == 0) {
		bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
	} else {
		type = HTTPS;
		bev = bufferevent_openssl_socket_new(base, -1, ssl,
			BUFFEREVENT_SSL_CONNECTING,
			BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
	}

	if (bev == NULL) {
		fprintf(stderr, "bufferevent_openssl_socket_new() failed\n");
		goto error;
	}

	bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);

	// For simplicity, we let DNS resolution block. Everything else should be
	// asynchronous though.
	evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev,
		host, port);
	if (evcon == NULL) {
		fprintf(stderr, "evhttp_connection_base_bufferevent_new() failed\n");
		goto error;
	}

	if (retries > 0) {
		evhttp_connection_set_retries(evcon, retries);
	}
	if (timeout >= 0) {
		evhttp_connection_set_timeout(evcon, timeout);
	}

	// Fire off the request
	req = evhttp_request_new(http_request_done, bev);
	if (req == NULL) {
		fprintf(stderr, "evhttp_request_new() failed\n");
		goto error;
	}

	output_headers = evhttp_request_get_output_headers(req);
	evhttp_add_header(output_headers, "Host", host);
	evhttp_add_header(output_headers, "Connection", "close");

	if (data_file) {
		/* NOTE: In production code, you'd probably want to use
		 * evbuffer_add_file() or evbuffer_add_file_segment(), to
		 * avoid needless copying. */
		FILE * f = fopen(data_file, "rb");
		char buf[1024];
		size_t s;
		size_t bytes = 0;

		if (!f) {
			syntax();
			goto error;
		}

		output_buffer = evhttp_request_get_output_buffer(req);
		while ((s = fread(buf, 1, sizeof(buf), f)) > 0) {
			evbuffer_add(output_buffer, buf, s);
			bytes += s;
		}
		evutil_snprintf(buf, sizeof(buf)-1, "%lu", (unsigned long)bytes);
		evhttp_add_header(output_headers, "Content-Length", buf);
		fclose(f);
	}

	r = evhttp_make_request(evcon, req, data_file ? EVHTTP_REQ_POST : EVHTTP_REQ_GET, uri);
	if (r != 0) {
		fprintf(stderr, "evhttp_make_request() failed\n");
		goto error;
	}

	event_base_dispatch(base);
	goto cleanup;

error:
	ret = 1;
cleanup:
	if (evcon)
		evhttp_connection_free(evcon);
	if (http_uri)
		evhttp_uri_free(http_uri);
	event_base_free(base);

	if (ssl_ctx)
		SSL_CTX_free(ssl_ctx);
	if (type == HTTP && ssl)
		SSL_free(ssl);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	EVP_cleanup();
	ERR_free_strings();

#ifdef EVENT__HAVE_ERR_REMOVE_THREAD_STATE
	ERR_remove_thread_state(NULL);
#else
	ERR_remove_state(0);
#endif
	CRYPTO_cleanup_all_ex_data();

	sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
#endif /*OPENSSL_VERSION_NUMBER < 0x10100000L */

#ifdef _WIN32
	WSACleanup();
#endif

	return ret;
}
Exemplo n.º 30
0
bool OpenSslLib::init(const char* path)
{
    if(ssl_ctx_client_ || ssl_ctx_server_) {
        return true;
    }
    
    std::string cert_path;
    if(path == NULL) {
        cert_path = getCurrentModulePath();
    } else {
        cert_path = path;
        if(cert_path.empty()) {
            cert_path = getCurrentModulePath();
        } else if(cert_path.at(cert_path.length() - 1) != PATH_SEPARATOR) {
            cert_path += PATH_SEPARATOR;
        }
    }
    
    std::string server_cert_file = cert_path + "server.cer";
    std::string server_key_file = cert_path + "server.key";
    std::string client_cert_file;// = cert_path + "cleint.cer";
    std::string client_key_file;// = cert_path + "client.key";
    std::string ca_cert_file = cert_path + "ca.cer";
    
    SSL_library_init();
    //OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    
    bool server_ctx_ok = false;
    bool client_ctx_ok = false;
    do {
        ssl_ctx_server_ = SSL_CTX_new(SSLv23_server_method());
        if(NULL == ssl_ctx_server_) {
            KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_new failed, err="<<ERR_reason_error_string(ERR_get_error()));
            break;
        }
        
        //const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
        //SSL_CTX_set_options(ssl_ctx_server_, flags);
        SSL_CTX_set_options(ssl_ctx_server_, SSL_OP_NO_SSLv2);
        SSL_CTX_set_mode(ssl_ctx_server_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
        SSL_CTX_set_mode(ssl_ctx_server_, SSL_MODE_ENABLE_PARTIAL_WRITE);
        
        if(!server_cert_file.empty() && !server_key_file.empty()) {
            if(SSL_CTX_use_certificate_file(ssl_ctx_server_, server_cert_file.c_str(), SSL_FILETYPE_PEM) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_use_certificate_file failed, file="<<server_cert_file
                               <<", err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
            if(SSL_CTX_use_PrivateKey_file(ssl_ctx_server_, server_key_file.c_str(), SSL_FILETYPE_PEM) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_use_PrivateKey_file failed, file:"<<server_key_file
                               <<", err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
            if(SSL_CTX_check_private_key(ssl_ctx_server_) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_check_private_key failed, err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
        }
        
        /*
         SSL_CTX_set_verify(ssl_ctx_client_, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyCallback);
         app_verify_arg arg0;
         SSL_CTX_set_cert_verify_callback(ssl_ctx_server_, appVerifyCallback, &arg0);
         
         int session_id_context = 1;
         if(SSL_CTX_set_session_id_context(ssl_ctx_server_, (unsigned char *)&session_id_context, sizeof(session_id_context)) != 1)
         {
         }
         */
        server_ctx_ok = true;
    } while(0);
    
    do {
        ssl_ctx_client_ = SSL_CTX_new(SSLv23_client_method());
        if(NULL == ssl_ctx_client_) {
            KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_new failed, err="<<ERR_reason_error_string(ERR_get_error()));
            break;
        }
        
        SSL_CTX_set_verify(ssl_ctx_client_, SSL_VERIFY_PEER, verifyCallback);
        //SSL_CTX_set_verify_depth(ssl_ctx_client_, 4);
        //app_verify_arg arg1;
        //SSL_CTX_set_cert_verify_callback(ssl_ctx_client_, appVerifyCallback, &arg1);
        
        //const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
        //SSL_CTX_set_options(ssl_ctx_client_, flags);
        SSL_CTX_set_options(ssl_ctx_client_, SSL_OP_NO_SSLv2);
        SSL_CTX_set_mode(ssl_ctx_client_, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
        SSL_CTX_set_mode(ssl_ctx_client_, SSL_MODE_ENABLE_PARTIAL_WRITE);
        
        // set AES256_SHA cipher for client.
        //if(SSL_CTX_set_cipher_list(ssl_ctx_client_,"AES256-SHA") != 1)
        //{
        //	KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_set_cipher_list failed, err="<<ERR_reason_error_string(ERR_get_error()));
        //}
        
        if(!client_cert_file.empty() && !client_key_file.empty()) {
            if(SSL_CTX_use_certificate_file(ssl_ctx_client_, client_cert_file.c_str(), SSL_FILETYPE_PEM) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_use_certificate_file failed, file="<<client_cert_file
                               <<", err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
            if(SSL_CTX_use_PrivateKey_file(ssl_ctx_client_, client_key_file.c_str(), SSL_FILETYPE_PEM) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_use_PrivateKey_file failed, file="<<client_key_file
                               <<", err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
            if(SSL_CTX_check_private_key(ssl_ctx_client_) != 1) {
                KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_check_private_key failed, err="<<ERR_reason_error_string(ERR_get_error()));
                break;
            }
        }
        
        if(!ca_cert_file.empty() &&
           SSL_CTX_load_verify_locations(ssl_ctx_client_, ca_cert_file.c_str(), NULL) != 1) {
            KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_load_verify_locations failed, file="<<ca_cert_file
                           <<", err="<<ERR_reason_error_string(ERR_get_error()));
            break;
        }
        if(SSL_CTX_set_default_verify_paths(ssl_ctx_client_) != 1) {
            KUMA_WARNTRACE("OpenSslLib::init, SSL_CTX_set_default_verify_paths failed, err="
                           <<ERR_reason_error_string(ERR_get_error()));
            break;
        }
        client_ctx_ok = true;
    } while(0);
    
    if(!server_ctx_ok && ssl_ctx_server_) {
        SSL_CTX_free(ssl_ctx_server_);
        ssl_ctx_server_ = NULL;
    }
    if(!client_ctx_ok && ssl_ctx_client_) {
        SSL_CTX_free(ssl_ctx_client_);
        ssl_ctx_client_ = NULL;
    }
    if(!server_ctx_ok && !client_ctx_ok) {
        return false;
    }
    
    ssl_locks_ = new std::mutex[CRYPTO_num_locks()];
    CRYPTO_set_id_callback(threadIdCallback);
    CRYPTO_set_locking_callback(lockingCallback);
    
    // PRNG
    RAND_poll();
    while(RAND_status() == 0) {
        unsigned short rand_ret = rand() % 65536;
        RAND_seed(&rand_ret, sizeof(rand_ret));
    }
    
    return true;
}