static int
openssl_iostream_set(struct ssl_iostream *ssl_io,
		     const struct ssl_iostream_settings *set,
		     const char **error_r)
{
	const struct ssl_iostream_settings *ctx_set = ssl_io->ctx->set;
	int verify_flags;

	if (set->verbose)
		SSL_set_info_callback(ssl_io->ssl, openssl_info_callback);

       if (set->cipher_list != NULL &&
	    strcmp(ctx_set->cipher_list, set->cipher_list) != 0) {
		if (!SSL_set_cipher_list(ssl_io->ssl, set->cipher_list)) {
			*error_r = t_strdup_printf(
				"Can't set cipher list to '%s': %s",
				set->cipher_list, openssl_iostream_error());
			return -1;
		}
	}
	if (set->protocols != NULL) {
		SSL_clear_options(ssl_io->ssl, OPENSSL_ALL_PROTOCOL_OPTIONS);
		SSL_set_options(ssl_io->ssl,
				openssl_get_protocol_options(set->protocols));
	}

	if (set->cert != NULL && strcmp(ctx_set->cert, set->cert) != 0) {
		if (openssl_iostream_use_certificate(ssl_io, set->cert, error_r) < 0)
			return -1;
	}
	if (set->key != NULL && strcmp(ctx_set->key, set->key) != 0) {
		if (openssl_iostream_use_key(ssl_io, set, error_r) < 0)
			return -1;
	}
	if (set->verify_remote_cert) {
		if (ssl_io->ctx->client_ctx)
			verify_flags = SSL_VERIFY_NONE;
		else
			verify_flags = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
		SSL_set_verify(ssl_io->ssl, verify_flags,
			       openssl_iostream_verify_client_cert);
	}

	if (set->cert_username_field != NULL) {
		ssl_io->username_nid = OBJ_txt2nid(set->cert_username_field);
		if (ssl_io->username_nid == NID_undef) {
			*error_r = t_strdup_printf(
				"Invalid cert_username_field: %s",
				set->cert_username_field);
			return -1;
		}
	} else {
		ssl_io->username_nid = ssl_io->ctx->username_nid;
	}

	ssl_io->verbose = set->verbose;
	ssl_io->verbose_invalid_cert = set->verbose_invalid_cert || set->verbose;
	ssl_io->require_valid_cert = set->require_valid_cert;
	return 0;
}
Beispiel #2
0
/* Select the appropriate server CTX.
 * Returns SSL_TLSEXT_ERR_OK if a match was found.
 * If |ignore| is 1, returns SSL_TLSEXT_ERR_NOACK on mismatch.
 * Otherwise, returns SSL_TLSEXT_ERR_ALERT_FATAL on mismatch.
 * An empty SNI extension also returns SSL_TSLEXT_ERR_NOACK.
 */
static int select_server_ctx(SSL *s, void *arg, int ignore)
{
    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
    HANDSHAKE_EX_DATA *ex_data =
        (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));

    if (servername == NULL) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    }

    if (strcmp(servername, "server2") == 0) {
        SSL_CTX *new_ctx = (SSL_CTX*)arg;
        SSL_set_SSL_CTX(s, new_ctx);
        /*
         * Copy over all the SSL_CTX options - reasonable behavior
         * allows testing of cases where the options between two
         * contexts differ/conflict
         */
        SSL_clear_options(s, 0xFFFFFFFFL);
        SSL_set_options(s, SSL_CTX_get_options(new_ctx));

        ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
        return SSL_TLSEXT_ERR_OK;
    } else if (strcmp(servername, "server1") == 0) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_OK;
    } else if (ignore) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    } else {
        /* Don't set an explicit alert, to test library defaults. */
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }
}
Beispiel #3
0
/* OpenSSL < 0.9.8m does not have SSL_clear_options() */
long HsOpenSSL_SSL_clear_options(SSL* ssl, long options) {
#if defined(SSL_clear_options)
    return SSL_clear_options(ssl, options);
#else
    long tmp = SSL_get_options(ssl);
    return SSL_set_options(ssl, tmp & ~options);
#endif
}
Beispiel #4
0
int main(int argc, char *argv[])
{
    BIO *err;
    int testresult = 0;
    int currtest = 0;

    SSL_library_init();
    SSL_load_error_strings();

    err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    CRYPTO_malloc_debug_init();
    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);


    confctx = SSL_CONF_CTX_new();
    ctx = SSL_CTX_new(SSLv23_method());
    ssl = SSL_new(ctx);
    if (confctx == NULL || ctx == NULL)
        goto end;

    SSL_CONF_CTX_set_flags(confctx, SSL_CONF_FLAG_FILE
                                    | SSL_CONF_FLAG_CLIENT
                                    | SSL_CONF_FLAG_SERVER);

    /*
     * For each test set up an SSL_CTX and SSL and see whether SSLv2 is enabled
     * as expected after various SSL_CONF_cmd("Protocol", ...) calls.
     */
    for (currtest = 0; currtest < TOTAL_NUM_TESTS; currtest++) {
        BIO_printf(err, "SSLv2 CONF Test number %d\n", currtest);
        if (currtest == TEST_SSL_CTX)
            SSL_CONF_CTX_set_ssl_ctx(confctx, ctx);
        else
            SSL_CONF_CTX_set_ssl(confctx, ssl);

        /* SSLv2 should be off by default */
        if (!checksslv2(currtest, SSLV2OFF)) {
            BIO_printf(err, "SSLv2 CONF Test: Off by default test FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "ALL") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");
            goto end;
        }

        /* Should still be off even after ALL Protocols on */
        if (!checksslv2(currtest, SSLV2OFF)) {
            BIO_printf(err, "SSLv2 CONF Test: Off after config #1 FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "SSLv2") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");
            goto end;
        }

        /* Should still be off even if explicitly asked for */
        if (!checksslv2(currtest, SSLV2OFF)) {
            BIO_printf(err, "SSLv2 CONF Test: Off after config #2 FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "-SSLv2") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");;
            goto end;
        }

        if (!checksslv2(currtest, SSLV2OFF)) {
            BIO_printf(err, "SSLv2 CONF Test: Off after config #3 FAIL\n");
            goto end;
        }

        if (currtest == TEST_SSL_CTX)
            SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2);
        else
            SSL_clear_options(ssl, SSL_OP_NO_SSLv2);

        if (!checksslv2(currtest, SSLV2ON)) {
            BIO_printf(err, "SSLv2 CONF Test: On after clear FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "ALL") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");
            goto end;
        }

        /* Option has been cleared and config says have SSLv2 so should be on */
        if (!checksslv2(currtest, SSLV2ON)) {
            BIO_printf(err, "SSLv2 CONF Test: On after config #1 FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "SSLv2") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");
            goto end;
        }

        /* Option has been cleared and config says have SSLv2 so should be on */
        if (!checksslv2(currtest, SSLV2ON)) {
            BIO_printf(err, "SSLv2 CONF Test: On after config #2 FAIL\n");
            goto end;
        }

        if (SSL_CONF_cmd(confctx, "Protocol", "-SSLv2") != 2
                || !SSL_CONF_CTX_finish(confctx)) {
            BIO_printf(err, "SSLv2 CONF Test: SSL_CONF command FAIL\n");
            goto end;
        }

        /* Option has been cleared but config says no SSLv2 so should be off */
        if (!checksslv2(currtest, SSLV2OFF)) {
            BIO_printf(err, "SSLv2 CONF Test: Off after config #4 FAIL\n");
            goto end;
        }

    }

    testresult = 1;

 end:
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    SSL_CONF_CTX_free(confctx);

    if (!testresult) {
        printf("SSLv2 CONF test: FAILED (Test %d)\n", currtest);
        ERR_print_errors(err);
    } else {
        printf("SSLv2 CONF test: PASSED\n");
    }

    ERR_free_strings();
    ERR_remove_thread_state(NULL);
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    CRYPTO_mem_leaks(err);
    BIO_free(err);

    return testresult ? EXIT_SUCCESS : EXIT_FAILURE;
}
Beispiel #5
0
static int ssl_servername_cb(SSL *cnx, int *al, void *arg)
{
    CertResult  result;
    const char *sni_name;

    (void) al;
    (void) arg;
    if ((sni_name = SSL_get_servername(cnx, TLSEXT_NAMETYPE_host_name))
        == NULL || *sni_name == 0 || validate_sni_name(sni_name) != 0) {
        return SSL_TLSEXT_ERR_NOACK;
    }
    logfile(LOG_INFO, "SNI: [%s]", sni_name);
    if (chrooted != 0 || loggedin != 0) {
        return SSL_TLSEXT_ERR_NOACK;
    }
    if (use_extcert == 0) {
        return SSL_TLSEXT_ERR_OK;
    }
    memset(&result, 0, sizeof result);
    tls_extcert_get(&result, sni_name);
    if (result.cert_ok != 1) {
        die(400, LOG_ERR, "Cert handler not ready");
    }
    if (result.action == CERT_ACTION_DENY) {
        die(400, LOG_INFO, MSG_LOGOUT);
    }
    if (result.action == CERT_ACTION_DEFAULT) {
        return SSL_TLSEXT_ERR_OK;
    }
    if (result.cert_file == NULL) {
        if (result.action == CERT_ACTION_STRICT) {
            die(400, LOG_ERR, "Missing certificate");
        } else {
            return SSL_TLSEXT_ERR_OK;
        }
    }
    if (result.key_file == NULL) {
        result.key_file = result.cert_file;
    }
    SSL_CTX_free(tls_ctx);
    tls_ctx = NULL;
    if (tls_create_new_context(result.cert_file, result.key_file) != 0) {
        if (result.action != CERT_ACTION_FALLBACK) {
            die(400, LOG_ERR, "Invalid certificate");
        }
        if (tls_create_new_context(cert_file, key_file) != 0) {
            die(400, LOG_ERR, "SSL error");
        }
    }
    if ((client_sni_name = strdup(sni_name)) == NULL) {
        die_mem();
    }
    if (tls_cnx != NULL) {
        const long ctx_options = SSL_CTX_get_options(tls_ctx);
        SSL_set_SSL_CTX(tls_cnx, tls_ctx);
# ifdef SSL_CTRL_CLEAR_OPTIONS
        SSL_clear_options(tls_cnx,
                          SSL_get_options(tls_cnx) & ~ctx_options);
# endif
        SSL_set_options(tls_cnx, ctx_options);
    }
    if (tls_data_cnx != NULL) {
        const long ctx_options = SSL_CTX_get_options(tls_ctx);
        SSL_set_SSL_CTX(tls_data_cnx, tls_ctx);
# ifdef SSL_CTRL_CLEAR_OPTIONS
        SSL_clear_options(tls_data_cnx,
                          SSL_get_options(tls_cnx) & ~ctx_options);
# endif
        SSL_set_options(tls_data_cnx, ctx_options);
    }
    return SSL_TLSEXT_ERR_OK;
}