Beispiel #1
0
int ircd_client_init_ssl(struct ircd_client* const client)
{
	if (ssl_init(&client->ssl_ctx) != 0)
		return -1;

	// We are a server
	(void) ssl_set_endpoint(&client->ssl_ctx, SSL_IS_SERVER);

	// Tell the library how to send and receive data to the client
	(void) ssl_set_bio(&client->ssl_ctx, net_recv, &client->fd, net_send, &client->fd);

	// Tell the library how to generate random data for the client (e.g. session ticket encryption key)
	(void) ssl_set_rng(&client->ssl_ctx, hmac_drbg_random, &ircd_ssl_hmac_drbg_ctx);

	// Normally DHE- ciphersuites are enabled anyway, but do so with a stronger prime
	(void) ssl_set_dh_param_ctx(&client->ssl_ctx, &ircd_ssl_dh_ctx);

	// To request (but not require) a certificate from the client
	(void) ssl_set_authmode(&client->ssl_ctx, SSL_VERIFY_OPTIONAL);
	//(void) ssl_set_ca_chain(&client->ssl_ctx, &ircd_ssl_ca_certificates, NULL, NULL);
	(void) ssl_set_ca_chain(&client->ssl_ctx, &ircd_ssl_certificate, NULL, NULL);

	// To test if the client supports RC4 (bad, in violation of TLS standards; see RFC 7465)
	(void) ssl_set_arc4_support(&client->ssl_ctx, SSL_ARC4_ENABLED);

	// To test if the client supports SNI (good)
	(void) ssl_set_sni(&client->ssl_ctx, ircd_server_ssl_sni_cb, (void*) client);

	// To test if the client supports Session Tickets (concerning)
	(void) ssl_set_session_tickets(&client->ssl_ctx, SSL_SESSION_TICKETS_ENABLED);
	(void) ssl_set_session_ticket_lifetime(&client->ssl_ctx, 300);

	// We could do this in the SNI callback, but that would require all clients to support SNI
	(void) ssl_set_own_cert(&client->ssl_ctx, &ircd_ssl_certificate, &ircd_ssl_private_key);

#ifdef POLARSSL_SSL_CIPHERSUITES_CB
	// This is an addition of mine to the library - see the patch in patches/
	(void) ssl_set_cs_cb(&client->ssl_ctx, ircd_server_ssl_cs_cb, (void*) client);
#endif

#ifdef POLARSSL_SSL_TICKETS_CB
	// This is an addition of mine to the library - see the patch in patches/
	(void) ssl_set_tick_cb(&client->ssl_ctx, ircd_server_ssl_tick_cb, (void*) client);
#endif

	return 0;
}
Beispiel #2
0
/* Accept incoming SSL connection
 */
int ssl_accept(t_ssl_accept_data *sad) {
	int result, handshake;
	struct timeval timer;
	time_t start_time;

	if (ssl_init(sad->context) != 0) {
		return -1;
	}

	ssl_set_endpoint(sad->context, SSL_IS_SERVER);
	if (sad->ca_certificate == NULL) {
		ssl_set_authmode(sad->context, SSL_VERIFY_NONE);
	} else {
		ssl_set_authmode(sad->context, SSL_VERIFY_REQUIRED);
		ssl_set_ca_chain(sad->context, sad->ca_certificate, sad->ca_crl, NULL);
		sad->timeout = HS_TIMEOUT_CERT_SELECT;
	}

	ssl_set_min_version(sad->context, SSL_MAJOR_VERSION_3, sad->min_ssl_version);
	ssl_set_renegotiation(sad->context, SSL_RENEGOTIATION_DISABLED);
	ssl_set_rng(sad->context, ssl_random, &ctr_drbg);
#ifdef ENABLE_DEBUG
	ssl_set_dbg(sad->context, ssl_debug, stderr);
#endif
	ssl_set_bio(sad->context, net_recv, sad->client_fd, net_send, sad->client_fd);
	ssl_set_sni(sad->context, sni_callback, sad);
	ssl_set_session_cache(sad->context, ssl_get_cache, &cache, ssl_set_cache, &cache);

#if POLARSSL_VERSION_NUMBER >= 0x01020700
	ssl_set_ciphersuites_for_version(sad->context, ciphersuites, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0);
	ssl_set_ciphersuites_for_version(sad->context, ciphersuites, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1);
	ssl_set_ciphersuites_for_version(sad->context, ciphersuites + 1, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2);
	ssl_set_ciphersuites_for_version(sad->context, ciphersuites_tls12, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3);
#else
	int skip = 0;
	if ((sad->min_ssl_version >= SSL_MINOR_VERSION_2) && (ciphersuites[0] == TLS_RSA_WITH_RC4_128_SHA)) {
		skip = 1;
	}
	ssl_set_ciphersuites(sad->context, ciphersuites + skip);
#endif

	ssl_set_own_cert(sad->context, sad->certificate, sad->private_key);
	if (sad->dh_size == 1024) {
		ssl_set_dh_param(sad->context, POLARSSL_DHM_RFC5114_MODP_1024_P, POLARSSL_DHM_RFC5114_MODP_1024_G);
	} else if (sad->dh_size == 2048) {
		ssl_set_dh_param(sad->context, POLARSSL_DHM_RFC5114_MODP_2048_P, POLARSSL_DHM_RFC5114_MODP_2048_G);
	} else if (sad->dh_size == 4096) {
		ssl_set_dh_param(sad->context, dhm_4096_P, dhm_4096_G);
	}

	timer.tv_sec = sad->timeout;
	timer.tv_usec = 0;
	setsockopt(*(sad->client_fd), SOL_SOCKET, SO_RCVTIMEO, (void*)&timer, sizeof(struct timeval));
	start_time = time(NULL);

	result = 0;
	while ((handshake = ssl_handshake(sad->context)) != 0) {
		if ((handshake != POLARSSL_ERR_NET_WANT_READ) && (handshake != POLARSSL_ERR_NET_WANT_WRITE)) {
			ssl_free(sad->context);
			sad->context = NULL;
			result = -1;
			break;
		}
		if (time(NULL) - start_time >= sad->timeout) {
			ssl_free(sad->context);
			sad->context = NULL;
			result = -2;
			break;
		}
	}

	timer.tv_sec = 0;
	timer.tv_usec = 0;
	setsockopt(*(sad->client_fd), SOL_SOCKET, SO_RCVTIMEO, (void*)&timer, sizeof(struct timeval));

	return result;
}
Beispiel #3
0
ngx_int_t
ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
    ngx_uint_t flags)
{
    ngx_ssl_connection_t     *sc;
    ngx_ssl_conn_t           *ssl_ctx;
    ngx_ssl_session_cache_t  *cache;
    int                       sslerr;

    sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
    if (sc == NULL) {
        return NGX_ERROR;
    }

    sc->buffer = ((flags % NGX_SSL_BUFFER) != 0);

    /* Allocate the PolarSSL context */

    ssl_ctx = ngx_pcalloc(c->pool, sizeof(ngx_ssl_conn_t));
    if (sc == NULL) {
        return NGX_ERROR;
    }

    /*
     * Initialize this PolarSSL context
     *
     * Note: We also setup the options traditionally set in ngx_ssl_create
     * here since each ssl_ctx is unique to each fd.
     */

    sslerr = ssl_init(ssl_ctx);
    if (sslerr != 0) {
        ngx_mbedtls_error(NGX_LOG_ALERT, ssl->log, 0, sslerr,
                           "ssl_init failed");
        return NGX_ERROR;
    }

    if (flags & NGX_SSL_CLIENT) {
        ssl_set_endpoint(ssl_ctx, SSL_IS_CLIENT);

        if (ssl->have_own_cert) {
            ssl_set_own_cert(ssl_ctx, &ssl->own_cert, &ssl->own_key);
        }
    } else {
        ssl_set_endpoint(ssl_ctx, SSL_IS_SERVER);
        ssl_set_own_cert(ssl_ctx, &ssl->own_cert, &ssl->own_key);
    }

    if (ssl->have_ca_cert) {
        if (ssl->have_ca_crl) {
            ssl_set_ca_chain(ssl_ctx, &ssl->ca_cert, &ssl->ca_crl, NULL);
        } else {
            ssl_set_ca_chain(ssl_ctx, &ssl->ca_cert, NULL, NULL);
        }

        /*
         * ngx_event_openssl has the callback rigged to allow the handshake
         * to continue even if verification fails.  We shall do the same.
         */

        ssl_set_authmode(ssl_ctx, SSL_VERIFY_OPTIONAL);
    } else {
        ssl_set_authmode(ssl_ctx, SSL_VERIFY_NONE);
    }

    ssl_set_min_version(ssl_ctx, SSL_MAJOR_VERSION_3, ssl->minor_min);
    ssl_set_max_version(ssl_ctx, SSL_MAJOR_VERSION_3, ssl->minor_max);

    ssl_set_renegotiation(ssl_ctx, SSL_RENEGOTIATION_ENABLED);
    ssl_legacy_renegotiation(ssl_ctx, SSL_LEGACY_NO_RENEGOTIATION);

    ssl_set_rng(ssl_ctx, ngx_mbedtls_rng, &ngx_ctr_drbg);
    ssl_set_bio(ssl_ctx, net_recv, &c->fd, net_send, &c->fd);

    ssl_set_dh_param_ctx(ssl_ctx, &ssl->dhm_ctx);
    ssl_set_ciphersuites(ssl_ctx, ssl->ciphersuites);

    if (ssl->builtin_session_cache == NGX_SSL_NONE_SCACHE) {
        ssl_set_session_cache(ssl_ctx,
                ngx_mbedtls_get_cache, NULL,
                ngx_mbedtls_set_cache, NULL);
    }

    if (ssl->builtin_session_cache != NGX_SSL_NO_SCACHE) {
        cache = ssl->cache_shm_zone->data;
        cache->ttl = ssl->cache_ttl;

        ssl_set_session_cache(ssl_ctx,
                ngx_mbedtls_get_cache, ssl->cache_shm_zone,
                ngx_mbedtls_set_cache, ssl->cache_shm_zone);
    }

    if (ssl->sni_fn) {
        ssl_set_sni(ssl_ctx, ssl->sni_fn, c);
    }

    /* All done, the connection is good to go now */

    sc->connection = ssl_ctx;
    c->ssl = sc;
    
    return NGX_OK;
}