예제 #1
0
int
listen_sslctx_setup(void* ctxt)
{
#ifdef HAVE_SSL
	SSL_CTX* ctx = (SSL_CTX*)ctxt;
	/* no SSLv2, SSLv3 because has defects */
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
		!= SSL_OP_NO_SSLv2){
		log_crypto_err("could not set SSL_OP_NO_SSLv2");
		return 0;
	}
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
		!= SSL_OP_NO_SSLv3){
		log_crypto_err("could not set SSL_OP_NO_SSLv3");
		return 0;
	}
#if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1)
	/* if we have tls 1.1 disable 1.0 */
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
		!= SSL_OP_NO_TLSv1){
		log_crypto_err("could not set SSL_OP_NO_TLSv1");
		return 0;
	}
#endif
#if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2)
	/* if we have tls 1.2 disable 1.1 */
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
		!= SSL_OP_NO_TLSv1_1){
		log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
		return 0;
	}
#endif
#if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA)
	/* if we have sha256, set the cipher list to have no known vulns */
	if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"))
		log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list");
#endif

	if((SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE) &
		SSL_OP_CIPHER_SERVER_PREFERENCE) !=
		SSL_OP_CIPHER_SERVER_PREFERENCE) {
		log_crypto_err("could not set SSL_OP_CIPHER_SERVER_PREFERENCE");
		return 0;
	}

#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
	SSL_CTX_set_security_level(ctx, 0);
#endif
#else
	(void)ctxt;
#endif /* HAVE_SSL */
	return 1;
}
예제 #2
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(struct config_file* cfg)
{
	char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
	SSL_CTX* ctx;

	if(cfg->remote_control_use_cert) {
		s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
		c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
		c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
		if(!s_cert || !c_key || !c_cert)
			fatal_exit("out of memory");
	}
	ctx = SSL_CTX_new(SSLv23_client_method());
	if(!ctx)
		ssl_err("could not allocate SSL_CTX pointer");
	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
		!= SSL_OP_NO_SSLv2)
		ssl_err("could not set SSL_OP_NO_SSLv2");
	if(cfg->remote_control_use_cert) {
		if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
			!= SSL_OP_NO_SSLv3)
			ssl_err("could not set SSL_OP_NO_SSLv3");
		if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
		    !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
		    || !SSL_CTX_check_private_key(ctx))
			ssl_err("Error setting up SSL_CTX client key and cert");
		if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
			ssl_err("Error setting up SSL_CTX verify, server cert");
		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

		free(s_cert);
		free(c_key);
		free(c_cert);
	} else {
		/* Use ciphers that don't require authentication  */
#if defined(SSL_OP_NO_TLSv1_3)
		/* in openssl 1.1.1, negotiation code for tls 1.3 does
		 * not allow the unauthenticated aNULL and eNULL ciphers */
		SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
#endif
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
		SSL_CTX_set_security_level(ctx, 0);
#endif
		if(!SSL_CTX_set_cipher_list(ctx, "aNULL:eNULL"))
			ssl_err("Error setting NULL cipher!");
	}
	return ctx;
}
예제 #3
0
int main(void)
{
    SSL_CTX *ctx = SSL_CTX_new(DTLS_method());
    STACK_OF(SSL_CIPHER) *ciphers;
    int i, rv = 0;

    SSL_CTX_set_psk_server_callback(ctx, srvr_psk_callback);
    SSL_CTX_set_psk_client_callback(ctx, clnt_psk_callback);
    SSL_CTX_set_security_level(ctx, 0);

    /* We only care about iterating over each enc/mac; we don't
     * want to repeat the test for each auth/kx variant.
     * So keep life simple and only do (non-DH) PSK. */
    if (!SSL_CTX_set_cipher_list(ctx, "PSK")) {
        fprintf(stderr, "Failed to set PSK cipher list\n");
        goto out;
    }

    ciphers = SSL_CTX_get_ciphers(ctx);
    for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
        const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
        const char *cipher_name = SSL_CIPHER_get_name(cipher);

        /* As noted above, only one test for each enc/mac variant. */
        if (strncmp(cipher_name, "PSK-", 4))
            continue;

        rv = mtu_test(ctx, cipher_name, 0);
        if (!rv)
            break;

        printf("DTLS MTU test OK for %s\n", cipher_name);
        if (rv == 1)
            continue;

        /* mtu_test() returns 2 if it used Encrypt-then-MAC */
        rv = mtu_test(ctx, cipher_name, 1);
        if (!rv)
            break;

        printf("DTLS MTU test OK for %s without Encrypt-then-MAC\n", cipher_name);
    }
 out:
    SSL_CTX_free(ctx);

    return !rv;
}
예제 #4
0
TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
{
    long    off = 0;
    int     cachable;
    int     scache_timeout;
    SSL_CTX *client_ctx;
    TLS_APPL_STATE *app_ctx;
    int     log_mask;

    /*
     * Convert user loglevel to internal logmask.
     */
    log_mask = tls_log_mask(props->log_param, props->log_level);

    if (log_mask & TLS_LOG_VERBOSE)
	msg_info("initializing the client-side TLS engine");

    /*
     * Load (mostly cipher related) TLS-library internal main.cf parameters.
     */
    tls_param_init();

    /*
     * Detect mismatch between compile-time headers and run-time library.
     */
    tls_check_version();

#if OPENSSL_VERSION_NUMBER < 0x10100000L

    /*
     * Initialize the OpenSSL library by the book! To start with, we must
     * initialize the algorithms. We want cleartext error messages instead of
     * just error codes, so we load the error_strings.
     */
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
#endif

    /*
     * Create an application data index for SSL objects, so that we can
     * attach TLScontext information; this information is needed inside
     * tls_verify_certificate_callback().
     */
    if (TLScontext_index < 0) {
	if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0) {
	    msg_warn("Cannot allocate SSL application data index: "
		     "disabling TLS support");
	    return (0);
	}
    }

    /*
     * If the administrator specifies an unsupported digest algorithm, fail
     * now, rather than in the middle of a TLS handshake.
     */
    if (!tls_validate_digest(props->mdalg)) {
	msg_warn("disabling TLS support");
	return (0);
    }

    /*
     * Initialize the PRNG (Pseudo Random Number Generator) with some seed
     * from external and internal sources. Don't enable TLS without some real
     * entropy.
     */
    if (tls_ext_seed(var_tls_daemon_rand_bytes) < 0) {
	msg_warn("no entropy for TLS key generation: disabling TLS support");
	return (0);
    }
    tls_int_seed();

    /*
     * The SSL/TLS specifications require the client to send a message in the
     * oldest specification it understands with the highest level it
     * understands in the message. RFC2487 is only specified for TLSv1, but
     * we want to be as compatible as possible, so we will start off with a
     * SSLv2 greeting allowing the best we can offer: TLSv1. We can restrict
     * this with the options setting later, anyhow.
     */
    ERR_clear_error();
    client_ctx = SSL_CTX_new(TLS_client_method());
    if (client_ctx == 0) {
	msg_warn("cannot allocate client SSL_CTX: disabling TLS support");
	tls_print_errors();
	return (0);
    }
#ifdef SSL_SECOP_PEER
    /* Backwards compatible security as a base for opportunistic TLS. */
    SSL_CTX_set_security_level(client_ctx, 0);
#endif

    /*
     * See the verify callback in tls_verify.c
     */
    SSL_CTX_set_verify_depth(client_ctx, props->verifydepth + 1);

    /*
     * Protocol selection is destination dependent, so we delay the protocol
     * selection options to the per-session SSL object.
     */
    off |= tls_bug_bits();
    SSL_CTX_set_options(client_ctx, off);

    /*
     * Set the call-back routine for verbose logging.
     */
    if (log_mask & TLS_LOG_DEBUG)
	SSL_CTX_set_info_callback(client_ctx, tls_info_callback);

    /*
     * Load the CA public key certificates for both the client cert and for
     * the verification of server certificates. As provided by OpenSSL we
     * support two types of CA certificate handling: One possibility is to
     * add all CA certificates to one large CAfile, the other possibility is
     * a directory pointed to by CApath, containing separate files for each
     * CA with softlinks named after the hash values of the certificate. The
     * first alternative has the advantage that the file is opened and read
     * at startup time, so that you don't have the hassle to maintain another
     * copy of the CApath directory for chroot-jail.
     */
    if (tls_set_ca_certificate_info(client_ctx,
				    props->CAfile, props->CApath) < 0) {
	/* tls_set_ca_certificate_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * We do not need a client certificate, so the certificates are only
     * loaded (and checked) if supplied. A clever client would handle
     * multiple client certificates and decide based on the list of
     * acceptable CAs, sent by the server, which certificate to submit.
     * OpenSSL does however not do this and also has no call-back hooks to
     * easily implement it.
     * 
     * Load the client public key certificate and private key from file and
     * check whether the cert matches the key. We can use RSA certificates
     * ("cert") DSA certificates ("dcert") or ECDSA certificates ("eccert").
     * All three can be made available at the same time. The CA certificates
     * for all three are handled in the same setup already finished. Which
     * one is used depends on the cipher negotiated (that is: the first
     * cipher listed by the client which does match the server). The client
     * certificate is presented after the server chooses the session cipher,
     * so we will just present the right cert for the chosen cipher (if it
     * uses certificates).
     */
    if (tls_set_my_certificate_key_info(client_ctx,
					props->cert_file,
					props->key_file,
					props->dcert_file,
					props->dkey_file,
					props->eccert_file,
					props->eckey_file) < 0) {
	/* tls_set_my_certificate_key_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
     */
#if OPENSSL_VERSION_NUMBER < 0x10100000L

    /*
     * According to the OpenSSL documentation, temporary RSA key is needed
     * export ciphers are in use. We have to provide one, so well, we just do
     * it.
     */
    SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb);
#endif

    /*
     * With OpenSSL 1.0.2 and later the client EECDH curve list becomes
     * configurable with the preferred curve negotiated via the supported
     * curves extension.
     */
    tls_auto_eecdh_curves(client_ctx);

    /*
     * Finally, the setup for the server certificate checking, done "by the
     * book".
     */
    SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE,
		       tls_verify_certificate_callback);

    /*
     * Initialize the session cache.
     * 
     * Since the client does not search an internal cache, we simply disable it.
     * It is only useful for expiring old sessions, but we do that in the
     * tlsmgr(8).
     * 
     * This makes SSL_CTX_remove_session() not useful for flushing broken
     * sessions from the external cache, so we must delete them directly (not
     * via a callback).
     */
    if (tls_mgr_policy(props->cache_type, &cachable,
		       &scache_timeout) != TLS_MGR_STAT_OK)
	scache_timeout = 0;
    if (scache_timeout <= 0)
	cachable = 0;

    /*
     * Allocate an application context, and populate with mandatory protocol
     * and cipher data.
     */
    app_ctx = tls_alloc_app_context(client_ctx, log_mask);

    /*
     * The external session cache is implemented by the tlsmgr(8) process.
     */
    if (cachable) {

	app_ctx->cache_type = mystrdup(props->cache_type);

	/*
	 * OpenSSL does not use callbacks to load sessions from a client
	 * cache, so we must invoke that function directly. Apparently,
	 * OpenSSL does not provide a way to pass session names from here to
	 * call-back routines that do session lookup.
	 * 
	 * OpenSSL can, however, automatically save newly created sessions for
	 * us by callback (we create the session name in the call-back
	 * function).
	 * 
	 * XXX gcc 2.95 can't compile #ifdef .. #endif in the expansion of
	 * SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE |
	 * SSL_SESS_CACHE_NO_AUTO_CLEAR.
	 */
#ifndef SSL_SESS_CACHE_NO_INTERNAL_STORE
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0
#endif

	SSL_CTX_set_session_cache_mode(client_ctx,
				       SSL_SESS_CACHE_CLIENT |
				       SSL_SESS_CACHE_NO_INTERNAL_STORE |
				       SSL_SESS_CACHE_NO_AUTO_CLEAR);
	SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);

	/*
	 * OpenSSL ignores timed-out sessions. We need to set the internal
	 * cache timeout at least as high as the external cache timeout. This
	 * applies even if no internal cache is used.  We set the session to
	 * twice the cache lifetime.  This way a session always lasts longer
	 * than its lifetime in the cache.
	 */
	SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
    }
    return (app_ctx);
}