diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
commit | 36082a2fe36ecd800d784ae44c14f1f18c66a7e9 (patch) | |
tree | 6c68e0c0097987aff85a01dabddd34b862309a7c /src/tests.c | |
parent | Initial commit. (diff) | |
download | gnutls28-upstream.tar.xz gnutls28-upstream.zip |
Adding upstream version 3.7.9.upstream/3.7.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tests.c')
-rw-r--r-- | src/tests.c | 1770 |
1 files changed, 1770 insertions, 0 deletions
diff --git a/src/tests.c b/src/tests.c new file mode 100644 index 0000000..85c4b66 --- /dev/null +++ b/src/tests.c @@ -0,0 +1,1770 @@ +/* + * Copyright (C) 2000-2012 Free Software Foundation, Inc. + * + * This file is part of GnuTLS. + * + * GnuTLS is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> + +#ifndef _WIN32 +#include <unistd.h> +#include <signal.h> +#else +#include <errno.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <common.h> +#include <tests.h> + +void _gnutls_record_set_default_version(gnutls_session_t session, + unsigned char major, + unsigned char minor); + +void _gnutls_hello_set_default_version(gnutls_session_t session, + unsigned char major, + unsigned char minor); + + +extern gnutls_srp_client_credentials_t srp_cred; +extern gnutls_anon_client_credentials_t anon_cred; +extern gnutls_certificate_credentials_t xcred; + +extern unsigned int verbose; + +const char *ext_text = ""; +static int tls_ext_ok = 1; +static int tls1_ok = 0; +static int ssl3_ok = 0; +static int tls1_1_ok = 0; +static int tls1_2_ok = 0; +static int tls1_3_ok = 0; +static int send_record_ok = 0; + +/* keep session info */ +static char *session_data = NULL; +static char session_id[32]; +static size_t session_data_size = 0, session_id_size = 0; +static int sfree = 0; +static int handshake_output = 0; + +static int test_do_handshake(gnutls_session_t session) +{ + int ret, alert; + + do { + ret = gnutls_handshake(session); + } + while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + + handshake_output = ret; + + if (ret < 0 && verbose > 1) { + if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { + alert = gnutls_alert_get(session); + printf("\n"); + printf("*** Received alert [%d]: %s\n", + alert, gnutls_alert_get_name(alert)); + } + } + + if (ret < 0) + return TEST_FAILED; + gnutls_session_get_data(session, NULL, &session_data_size); + + if (sfree != 0) { + free(session_data); + sfree = 0; + } + session_data = malloc(session_data_size); + sfree = 1; + if (session_data == NULL) { + fprintf(stderr, "Memory error\n"); + exit(1); + } + gnutls_session_get_data(session, session_data, &session_data_size); + + session_id_size = sizeof(session_id); + gnutls_session_get_id(session, session_id, &session_id_size); + + return TEST_SUCCEED; +} + +char protocol_str[] = + "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; +char protocol_all_str[] = + "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; +char prio_str[768] = ""; + +#ifdef ENABLE_GOST +#define GOST_CIPHERS ":+GOST28147-TC26Z-CNT" +#define GOST_MACS ":+GOST28147-TC26Z-IMIT" +#define GOST_KX ":+VKO-GOST-12" +#define GOST_REST ":+SIGN-GOSTR341012-512:+SIGN-GOSTR341012-256:+SIGN-GOSTR341001:+GROUP-GOST-ALL" +#else +#define GOST_CIPHERS +#define GOST_MACS +#define GOST_KX +#define GOST_REST +#endif + +#define ALL_CIPHERS "+CIPHER-ALL:+ARCFOUR-128:+3DES-CBC" GOST_CIPHERS +#define BLOCK_CIPHERS "+3DES-CBC:+AES-128-CBC:+CAMELLIA-128-CBC:+AES-256-CBC:+CAMELLIA-256-CBC" +#define SSL3_CIPHERS "+ARCFOUR-128:+3DES-CBC" +#define ALL_COMP "+COMP-NULL" +#define ALL_MACS "+MAC-ALL:+MD5:+SHA1" GOST_MACS +#define SSL3_MACS "+MD5:+SHA1" +#define ALL_KX "+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+ECDHE-RSA:+ECDHE-ECDSA:+ANON-ECDH" GOST_KX +#define SSL3_KX "+RSA:+DHE-RSA:+DHE-DSS" +#define INIT_STR "NONE:" +char rest[384] = "%UNSAFE_RENEGOTIATION:+SIGN-ALL:+GROUP-ALL" GOST_REST; + +#define _gnutls_priority_set_direct(s, str) { \ + int _ret; \ + if ((_ret=__gnutls_priority_set_direct(s, str, __LINE__)) != TEST_SUCCEED) { \ + return _ret; \ + } \ + } + +static inline int +__gnutls_priority_set_direct(gnutls_session_t session, const char *str, int line) +{ + const char *err; + int ret = gnutls_priority_set_direct(session, str, &err); + + if (ret < 0) { + /* this can happen when some cipher is disabled system-wide */ + if (ret == GNUTLS_E_NO_PRIORITIES_WERE_SET) + return TEST_IGNORE; + + fprintf(stderr, "Error at %d with string %s\n", line, str); + fprintf(stderr, "Error at %s: %s\n", err, + gnutls_strerror(ret)); + exit(1); + } + + return TEST_SUCCEED; +} + +test_code_t test_server(gnutls_session_t session) +{ + int ret, i = 0; + static char buf[5 * 1024]; + char *p; + const char snd_buf[] = "GET / HTTP/1.0\r\n\r\n"; + + buf[sizeof(buf) - 1] = 0; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":" ALL_KX ":" "%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret != TEST_SUCCEED) + return TEST_FAILED; + + gnutls_record_send(session, snd_buf, sizeof(snd_buf) - 1); + ret = gnutls_record_recv(session, buf, sizeof(buf) - 1); + if (ret < 0) + return TEST_FAILED; + + ext_text = "unknown"; + p = strstr(buf, "Server:"); + if (p != NULL) { + p+=7; + if (*p == ' ') p++; + ext_text = p; + while (*p != 0 && *p != '\r' && *p != '\n') { + p++; + i++; + if (i > 128) + break; + } + *p = 0; + } + + return TEST_SUCCEED; +} + +static gnutls_datum_t pubkey = { NULL, 0 }; + +test_code_t test_dhe(gnutls_session_t session) +{ +#ifdef ENABLE_DHE + int ret; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + gnutls_dh_get_pubkey(session, &pubkey); + + return ret; +#endif + return TEST_IGNORE; +} + +test_code_t test_rfc7919(gnutls_session_t session) +{ +#ifdef ENABLE_DHE + int ret; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+DHE-RSA:+DHE-DSS:+GROUP-ALL:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret != TEST_FAILED && (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_RFC7919)) + return TEST_SUCCEED; + else + return TEST_FAILED; +#endif + return TEST_IGNORE; +} + +test_code_t test_ecdhe(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+ECDHE-RSA:+ECDHE-ECDSA:+CURVE-ALL:%s", protocol_all_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + return ret; +} + +#ifdef ENABLE_GOST +test_code_t test_vko_gost_12(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+VKO-GOST-12:%s", protocol_all_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + return ret; +} +#endif + +test_code_t test_rsa(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+RSA:%s", protocol_all_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + return ret; +} + +static +test_code_t test_ecdhe_curve(gnutls_session_t session, const char *curve, unsigned id) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + /* We always enable all the curves but set our selected as first. That is + * because list of curves may be also used by the server to select a cert. */ + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+ECDHE-RSA:+ECDHE-ECDSA:%s:%s", protocol_all_str, curve, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + if (gnutls_ecc_curve_get(session) != id) + return TEST_FAILED; + + return TEST_SUCCEED; +} + +test_code_t test_ecdhe_secp256r1(gnutls_session_t session) +{ + return test_ecdhe_curve(session, "+CURVE-SECP256R1", GNUTLS_ECC_CURVE_SECP256R1); +} + +test_code_t test_ecdhe_secp384r1(gnutls_session_t session) +{ + return test_ecdhe_curve(session, "+CURVE-SECP384R1", GNUTLS_ECC_CURVE_SECP384R1); +} + +test_code_t test_ecdhe_secp521r1(gnutls_session_t session) +{ + return test_ecdhe_curve(session, "+CURVE-SECP521R1", GNUTLS_ECC_CURVE_SECP521R1); +} + +test_code_t test_ecdhe_x25519(gnutls_session_t session) +{ + return test_ecdhe_curve(session, "+CURVE-X25519", GNUTLS_ECC_CURVE_X25519); +} + +test_code_t test_rfc7507(gnutls_session_t session) +{ + int ret; + const char *pstr = NULL; + + if (tls1_2_ok && tls1_1_ok) + pstr = "-VERS-TLS-ALL:+VERS-TLS1.1:%FALLBACK_SCSV"; + else if (tls1_1_ok && tls1_ok) + pstr = "-VERS-TLS-ALL:+VERS-TLS1.0:%FALLBACK_SCSV"; +#ifdef ENABLE_SSL3 + else if (tls1_ok && ssl3_ok) + pstr = "-VERS-TLS-ALL:+VERS-SSL3.0:%FALLBACK_SCSV"; +#endif + else + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":"ALL_KX":%s", pstr, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret < 0) + return TEST_IGNORE2; + + if (handshake_output < 0) + return TEST_SUCCEED; + + return TEST_FAILED; +} + + +test_code_t test_safe_renegotiation(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":" ALL_KX ":%s:%%SAFE_RENEGOTIATION", rest, protocol_str); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + return ret; +} + +#ifdef ENABLE_OCSP +test_code_t test_ocsp_status(gnutls_session_t session) +{ + int ret; + gnutls_datum_t resp; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":" ALL_KX":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + ret = gnutls_ocsp_status_request_get(session, &resp); + if (ret == 0) + return TEST_SUCCEED; + + + return TEST_FAILED; +} + +#endif + +test_code_t test_ext_master_secret(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":%s:" ALL_KX, rest, protocol_str); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + if (gnutls_session_ext_master_secret_status(session) != 0) + return TEST_SUCCEED; + + return TEST_FAILED; +} + +test_code_t test_etm(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + "+AES-128-CBC:+AES-256-CBC:" ALL_COMP ":%s:" ALL_MACS + ":%s:" ALL_KX, rest, protocol_str); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + if (ret < 0) + return TEST_FAILED; + + if (gnutls_session_etm_status(session) != 0) + return TEST_SUCCEED; + + return TEST_FAILED; +} + +test_code_t test_safe_renegotiation_scsv(gnutls_session_t session) +{ + int ret; + + if (ssl3_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":+VERS-TLS1.0:" + ALL_MACS ":" ALL_KX ":%%SAFE_RENEGOTIATION"); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + return ret; +} + +test_code_t test_dhe_group(gnutls_session_t session) +{ + int ret, ret2; + gnutls_datum_t gen, prime, pubkey2; + const char *print; + FILE *fp; + + (void)remove("debug-dh.out"); + + if (verbose == 0 || pubkey.data == NULL) + return TEST_IGNORE; + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":+DHE-RSA:+DHE-DSS:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + + ret2 = gnutls_dh_get_group(session, &gen, &prime); + if (ret2 >= 0) { + + fp = fopen("debug-dh.out", "w"); + if (fp == NULL) + return TEST_FAILED; + + ext_text = "saved in debug-dh.out"; + + print = raw_to_string(gen.data, gen.size); + if (print) { + fprintf(fp, " Generator [%d bits]: %s\n", gen.size * 8, + print); + } + + print = raw_to_string(prime.data, prime.size); + if (print) { + fprintf(fp, " Prime [%d bits]: %s\n", prime.size * 8, + print); + } + + gnutls_dh_get_pubkey(session, &pubkey2); + print = raw_to_string(pubkey2.data, pubkey2.size); + if (print) { + fprintf(fp, " Pubkey [%d bits]: %s\n", pubkey2.size * 8, + print); + } + + if (pubkey2.data && pubkey2.size == pubkey.size && + memcmp(pubkey.data, pubkey2.data, pubkey.size) == 0) { + fprintf + (fp, " (public key seems to be static among sessions)\n"); + } + + { + /* save the PKCS #3 params */ + gnutls_dh_params_t dhp; + gnutls_datum_t p3; + + ret2 = gnutls_dh_params_init(&dhp); + if (ret2 < 0) { + fclose(fp); + return TEST_FAILED; + } + + ret2 = gnutls_dh_params_import_raw(dhp, &prime, &gen); + if (ret2 < 0) { + gnutls_dh_params_deinit(dhp); + fclose(fp); + return TEST_FAILED; + } + + ret2 = gnutls_dh_params_export2_pkcs3(dhp, GNUTLS_X509_FMT_PEM, &p3); + if (ret2 < 0) { + gnutls_dh_params_deinit(dhp); + fclose(fp); + return TEST_FAILED; + } + + gnutls_dh_params_deinit(dhp); + fprintf(fp, "\n%s\n", p3.data); + gnutls_free(p3.data); + } + + fclose(fp); + } + return ret; +} + +test_code_t test_ssl3(gnutls_session_t session) +{ + int ret; + sprintf(prio_str, INIT_STR + SSL3_CIPHERS ":" ALL_COMP ":+VERS-SSL3.0:%%NO_EXTENSIONS:" + SSL3_MACS ":" SSL3_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + ssl3_ok = 1; + + return ret; +} + +test_code_t test_ssl3_with_extensions(gnutls_session_t session) +{ + int ret; + sprintf(prio_str, INIT_STR + SSL3_CIPHERS ":" ALL_COMP ":+VERS-SSL3.0:" + SSL3_MACS ":" SSL3_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ssl3_ok != 0 && ret != TEST_SUCCEED) { + /* We need to disable extensions before trying TLS 1.0, because + * it also may not work with extensions. There are known servers + * which partially support both SSL 3.0 and TLS 1.0, but *both* + * only with disabled extensions: + * https://gitlab.com/gnutls/gnutls/-/issues/958#note_309267384 + */ + tls_ext_ok = 0; + strcat(rest, ":%NO_EXTENSIONS"); + } + + return ret; +} + +test_code_t test_ssl3_unknown_ciphersuites(gnutls_session_t session) +{ + int ret; + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":+VERS-SSL3.0:" + ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + ssl3_ok = 1; + + return ret; +} + +static int alrm = 0; +static void got_alarm(int k) +{ + alrm = 1; +} + +test_code_t test_bye(gnutls_session_t session) +{ + int ret; + char data[20]; + int secs = 6; +#ifndef _WIN32 + struct sigaction sa, old_sa; + + signal(SIGALRM, got_alarm); +#endif + + sprintf(prio_str, INIT_STR + ALL_CIPHERS ":" ALL_COMP ":%s:" ALL_MACS + ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + ret = gnutls_bye(session, GNUTLS_SHUT_WR); + if (ret < 0) + return TEST_FAILED; + +#ifndef _WIN32 + (void) sigaction (SIGALRM, NULL, &sa); + sa.sa_flags &= ~SA_RESTART; + sigaction(SIGALRM, &sa, &old_sa); + alarm(secs); +#else + setsockopt((int) gnutls_transport_get_ptr(session), SOL_SOCKET, + SO_RCVTIMEO, (char *) &secs, sizeof(int)); +#endif + + do { + ret = gnutls_record_recv(session, data, sizeof(data)); + } + while (ret > 0); + +#ifndef _WIN32 + sigaction(SIGALRM, &old_sa, NULL); +#else + if (WSAGetLastError() == WSAETIMEDOUT || + WSAGetLastError() == WSAECONNABORTED) + alrm = 1; +#endif + if (ret == 0) + return TEST_SUCCEED; + + if (alrm == 0) + return TEST_UNSURE; + + return TEST_FAILED; +} + + + +test_code_t test_aes(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, INIT_STR + "+AES-128-CBC:+AES-256-CBC:" ALL_COMP ":%s:" ALL_MACS + ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_aes_gcm(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, INIT_STR + "+AES-128-GCM:+AES-256-GCM:" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_aes_ccm(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, INIT_STR + "+AES-128-CCM:+AES-256-CCM:" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_aes_ccm_8(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, INIT_STR + "+AES-128-CCM-8:+AES-256-CCM-8:" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_camellia_cbc(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR "+CAMELLIA-128-CBC:+CAMELLIA-256-CBC:" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_camellia_gcm(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR "+CAMELLIA-128-GCM:+CAMELLIA-256-GCM:" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_unknown_ciphersuites(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":%s:" ALL_MACS ":" ALL_KX ":%s", + protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_md5(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":%s:+MD5:" ALL_KX ":%s", protocol_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_sha(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":%s:+SHA1:" ALL_KX ":%s", protocol_str, + rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_sha256(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":%s:+SHA256:" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +#ifdef ENABLE_GOST +test_code_t test_gost_imit(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":%s:+GOST28147-TC26Z-IMIT:" ALL_KX ":%s", + protocol_all_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} +#endif + +test_code_t test_3des(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR "+3DES-CBC:" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_arcfour(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR "+ARCFOUR-128:" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_chacha20(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR "+CHACHA20-POLY1305:" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} + +#ifdef ENABLE_GOST +test_code_t test_gost_cnt(gnutls_session_t session) +{ + int ret; + + if (gnutls_fips140_mode_enabled()) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR "+GOST28147-TC26Z-CNT:" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + return ret; +} +#endif + +test_code_t test_tls1(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.0:%%SSL3_RECORD_VERSION:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_ok = 1; + + return ret; + +} + +test_code_t test_tls1_nossl3(gnutls_session_t session) +{ + int ret; + + if (tls1_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.0:%%LATEST_RECORD_VERSION:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) { + strcat(rest, ":%LATEST_RECORD_VERSION"); + tls1_ok = 1; + } + + return ret; + +} + +test_code_t test_record_padding(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR BLOCK_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:-VERS-SSL3.0:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) { + tls1_ok = 1; + } else { + sprintf(prio_str, + INIT_STR BLOCK_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:-VERS-SSL3.0:" ALL_MACS ":" ALL_KX ":%%COMPAT:%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) { + tls1_ok = 1; + strcat(rest, ":%COMPAT"); + } else + ret = TEST_IGNORE2; /* neither succeeded */ + } + + return ret; +} + +test_code_t test_no_extensions(gnutls_session_t session) +{ + int ret; + +#ifdef ENABLE_SSL3 + /* If already disabled by test_ssl3_with_extensions */ + if (ssl3_ok != 0 && tls_ext_ok == 0) + return TEST_FAILED; +#endif + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 4096); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) { + tls_ext_ok = 1; + } else { + sprintf(prio_str, + INIT_STR BLOCK_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:-VERS-SSL3.0:" ALL_MACS ":" ALL_KX ":%%NO_EXTENSIONS:%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) { + tls_ext_ok = 0; + strcat(rest, ":%NO_EXTENSIONS"); + } else + ret = TEST_IGNORE2; /* neither succeeded */ + } + + return ret; +} + +test_code_t test_known_protocols(gnutls_session_t session) +{ + if (tls1_2_ok == 0 && tls1_1_ok == 0 && tls1_ok == 0 && + ssl3_ok == 0 && tls1_3_ok == 0) + return TEST_FAILED; + + return TEST_SUCCEED; +} + +test_code_t test_tls1_2(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.2:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_2_ok = 1; + + return ret; + +} + +test_code_t test_tls1_3(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.3:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_3_ok = 1; + + return ret; + +} + +test_code_t test_tls1_1(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.1:" ALL_MACS ":" ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_SUCCEED) + tls1_1_ok = 1; + + return ret; + +} + +test_code_t test_tls1_1_fallback(gnutls_session_t session) +{ + int ret; + if (tls1_1_ok) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0:" ALL_MACS ":" + ALL_KX ":%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret != TEST_SUCCEED) + return TEST_FAILED; + + if (gnutls_protocol_get_version(session) == GNUTLS_TLS1) + return TEST_SUCCEED; + else if (gnutls_protocol_get_version(session) == GNUTLS_SSL3) + return TEST_UNSURE; + + return TEST_FAILED; + +} + +test_code_t test_tls1_6_fallback(gnutls_session_t session) +{ + int ret; + + /* we remove RSA as there is a version check in the key exchange + * message we do not properly set in this test */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP + ":+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0:" ALL_MACS ":" + ALL_KX ":-RSA:%s", rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_hello_set_default_version(session, 3, 7); + + ret = test_do_handshake(session); + if (ret != TEST_SUCCEED) + return TEST_FAILED; + + ext_text = gnutls_protocol_get_name(gnutls_protocol_get_version(session)); + return TEST_SUCCEED; +} + +/* Advertise both TLS 1.0 and SSL 3.0. If the connection fails, + * but the previous SSL 3.0 test succeeded then disable TLS 1.0. + */ +test_code_t test_tls_disable0(gnutls_session_t session) +{ + int ret; + if (tls1_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) { + /* disable TLS 1.0 */ + if (ssl3_ok != 0) { + strcpy(protocol_str, "+VERS-SSL3.0"); + } + } + return ret; + +} + +test_code_t test_tls_disable1(gnutls_session_t session) +{ + int ret; + + if (tls1_1_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) { + /* disable TLS 1.1 */ + snprintf(protocol_str, sizeof(protocol_str), "+VERS-TLS1.0:+VERS-SSL3.0"); + } + return ret; +} + +test_code_t test_tls_disable2(gnutls_session_t session) +{ + int ret; + + if (tls1_2_ok != 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) { + /* disable TLS 1.2 */ + snprintf(protocol_str, sizeof(protocol_str), "+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"); + } + return ret; +} + + +test_code_t test_rsa_pms(gnutls_session_t session) +{ + int ret; + + /* here we enable both SSL 3.0 and TLS 1.0 + * and try to connect and use rsa authentication. + * If the server is old, buggy and only supports + * SSL 3.0 then the handshake will fail. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":+RSA:%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return TEST_FAILED; + + if (gnutls_protocol_get_version(session) == GNUTLS_TLS1) + return TEST_SUCCEED; + return TEST_UNSURE; +} + +test_code_t test_max_record_size(gnutls_session_t session) +{ + int ret; + + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 512); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + ret = gnutls_record_get_max_size(session); + if (ret == 512) + return TEST_SUCCEED; + + return TEST_FAILED; +} + +test_code_t test_heartbeat_extension(gnutls_session_t session) +{ + if (tls_ext_ok == 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 4096); + + gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); + test_do_handshake(session); + + switch (gnutls_heartbeat_allowed(session, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND)) { + case 0: + return TEST_FAILED; + default: + return TEST_SUCCEED; + } +} + +test_code_t test_small_records(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_record_set_max_size(session, 512); + + ret = test_do_handshake(session); + return ret; +} + +test_code_t test_version_rollback(gnutls_session_t session) +{ + int ret; + if (tls1_ok == 0) + return TEST_IGNORE; + + /* here we enable both SSL 3.0 and TLS 1.0 + * and we connect using a 3.1 client hello version, + * and a 3.0 record version. Some implementations + * are buggy (and vulnerable to man in the middle + * attacks which allow a version downgrade) and this + * connection will fail. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_record_set_default_version(session, 3, 0); + + ret = test_do_handshake(session); + if (ret != TEST_SUCCEED) + return ret; + + if (tls1_ok != 0 + && gnutls_protocol_get_version(session) == GNUTLS_SSL3) + return TEST_FAILED; + + return TEST_SUCCEED; +} + +/* See if the server tolerates out of bounds + * record layer versions in the first client hello + * message. + */ +test_code_t test_version_oob(gnutls_session_t session) +{ + int ret; + /* here we enable both SSL 3.0 and TLS 1.0 + * and we connect using a 5.5 record version. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_record_set_default_version(session, 5, 5); + + ret = test_do_handshake(session); + return ret; +} + +void _gnutls_rsa_pms_set_version(gnutls_session_t session, + unsigned char major, unsigned char minor); + +test_code_t test_rsa_pms_version_check(gnutls_session_t session) +{ + int ret; + /* here we use an arbitrary version in the RSA PMS + * to see whether to server will check this version. + * + * A normal server would abort this handshake. + */ + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + _gnutls_rsa_pms_set_version(session, 5, 5); /* use SSL 5.5 version */ + + ret = test_do_handshake(session); + return ret; + +} + +#ifdef ENABLE_ANON +test_code_t test_anonymous(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":+ANON-DH:+ANON-ECDH:+CURVE-ALL:%s", + protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); + + ret = test_do_handshake(session); + + if (ret == TEST_SUCCEED) + gnutls_dh_get_pubkey(session, &pubkey); + + return ret; +} +#endif + +test_code_t test_session_resume2(gnutls_session_t session) +{ + int ret; + char tmp_session_id[32]; + size_t tmp_session_id_size; + + if (session == NULL) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred); + + gnutls_session_set_data(session, session_data, session_data_size); + + memcpy(tmp_session_id, session_id, session_id_size); + tmp_session_id_size = session_id_size; + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + /* check if we actually resumed the previous session */ + + session_id_size = sizeof(session_id); + gnutls_session_get_id(session, session_id, &session_id_size); + + if (session_id_size == 0) + return TEST_FAILED; + + if (gnutls_session_is_resumed(session)) + return TEST_SUCCEED; + + if (tmp_session_id_size == session_id_size && + memcmp(tmp_session_id, session_id, tmp_session_id_size) == 0) + return TEST_SUCCEED; + else + return TEST_FAILED; +} + +extern char *hostname; + +test_code_t test_certificate(gnutls_session_t session) +{ + int ret; + FILE *fp; + + (void)remove("debug-certs.out"); + + if (verbose == 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + fp = fopen("debug-certs.out", "w"); + if (fp != NULL) { + fprintf(fp, "\n"); + print_cert_info2(session, GNUTLS_CRT_PRINT_FULL, fp, verbose); + fclose(fp); + ext_text = "saved in debug-certs.out"; + return TEST_SUCCEED; + } + return TEST_FAILED; +} + +test_code_t test_chain_order(gnutls_session_t session) +{ + int ret; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size = 0; + unsigned int i; + unsigned p_size; + gnutls_datum_t t; + gnutls_x509_crt_t *certs; + char *p, *pos; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake(session); + if (ret == TEST_FAILED) + return ret; + + if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509) + return TEST_IGNORE2; + + cert_list = gnutls_certificate_get_peers(session, &cert_list_size); + if (cert_list_size == 0) { + ext_text = "No certificates found!"; + return TEST_IGNORE2; + } + + if (cert_list_size == 1) + return TEST_SUCCEED; + + p = 0; + p_size = 0; + pos = NULL; + for (i=0;i<cert_list_size;i++) { + char *new_p; + t.data = NULL; + ret = gnutls_pem_base64_encode_alloc("CERTIFICATE", &cert_list[i], &t); + if (ret < 0) { + free(p); + return TEST_FAILED; + } + + new_p = realloc(p, p_size+t.size+1); + if (!new_p) { + free(p); + return TEST_FAILED; + } + p = new_p; + pos = p + p_size; + + memcpy(pos, t.data, t.size); + p_size += t.size; + pos += t.size; + + gnutls_free(t.data); + } + *pos = 0; + + t.size = p_size; + t.data = (void*)p; + + p_size = 0; + ret = gnutls_x509_crt_list_import2(&certs, &p_size, &t, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); + if (ret < 0) { + return TEST_FAILED; + } + + for (i=0;i<p_size;i++) { + gnutls_x509_crt_deinit(certs[i]); + } + gnutls_free(certs); + free(p); + + return TEST_SUCCEED; +} + +/* A callback function to be used at the certificate selection time. + */ +static int +cert_callback(gnutls_session_t session, + const gnutls_datum_t * req_ca_rdn, int nreqs, + const gnutls_pk_algorithm_t * sign_algos, + int sign_algos_length, gnutls_retr2_st * st) +{ + char issuer_dn[256]; + int i, ret; + size_t len; + FILE *fp; + + if (verbose == 0) + return -1; + + fp = fopen("debug-cas.out", "w"); + if (fp == NULL) + return -1; + + /* Print the server's trusted CAs + */ + printf("\n"); + if (nreqs > 0) + fprintf(fp, "- Server's trusted authorities:\n"); + else + fprintf + (fp, "- Server did not send us any trusted authorities names.\n"); + + /* print the names (if any) */ + for (i = 0; i < nreqs; i++) { + len = sizeof(issuer_dn); + ret = gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len); + if (ret >= 0) { + fprintf(fp, " [%d]: ", i); + fprintf(fp, "%s\n", issuer_dn); + } + } + fclose(fp); + + return -1; + +} + +/* Prints the trusted server's CAs. This is only + * if the server sends a certificate request packet. + */ +test_code_t test_server_cas(gnutls_session_t session) +{ + int ret; + + (void)remove("debug-cas.out"); + if (verbose == 0) + return TEST_IGNORE; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + gnutls_certificate_set_retrieve_function(xcred, cert_callback); + + ret = test_do_handshake(session); + gnutls_certificate_set_retrieve_function(xcred, NULL); + + if (ret == TEST_FAILED) + return ret; + + if (access("debug-cas.out", R_OK) == 0) + ext_text = "saved in debug-cas.out"; + else + ext_text = "none"; + return TEST_SUCCEED; +} + +static test_code_t +test_do_handshake_and_send_record(gnutls_session_t session) +{ + int ret; + /* This will be padded to 512 bytes. */ + const char snd_buf[] = "GET / HTTP/1.0\r\n\r\n"; + static char buf[5 * 1024]; + + ret = test_do_handshake(session); + if (ret != TEST_SUCCEED) + return ret; + + gnutls_record_send(session, snd_buf, sizeof(snd_buf) - 1); + ret = gnutls_record_recv(session, buf, sizeof(buf) - 1); + if (ret < 0) + return TEST_FAILED; + + return TEST_SUCCEED; +} + +/* These tests shall be sent in this order to check if the server + * advertises smaller limits than our default 512. and we can work it + * around with %ALLOW_SMALL_RECORDS. */ +test_code_t test_send_record(gnutls_session_t session) +{ + int ret; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake_and_send_record(session); + if (ret == TEST_SUCCEED) + send_record_ok = 1; + return ret; +} + +test_code_t test_send_record_with_allow_small_records(gnutls_session_t session) +{ + int ret; + + /* If test_send_record succeeded, we don't need to check. */ + if (send_record_ok) + return TEST_FAILED; + + sprintf(prio_str, + INIT_STR ALL_CIPHERS ":" ALL_COMP ":%s:" + ALL_MACS ":" ALL_KX ":%%ALLOW_SMALL_RECORDS:%s", + protocol_str, rest); + _gnutls_priority_set_direct(session, prio_str); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); + + ret = test_do_handshake_and_send_record(session); + if (ret == TEST_SUCCEED) + strcat(rest, ":%ALLOW_SMALL_RECORDS"); + return ret; +} |