Blame tests/multi-alerts.c

Packit aea12f
/*
Packit aea12f
 * Copyright (C) 2016 Red Hat, Inc.
Packit aea12f
 *
Packit aea12f
 * Author: Nikos Mavrogiannopoulos
Packit aea12f
 *
Packit aea12f
 * This file is part of GnuTLS.
Packit aea12f
 *
Packit aea12f
 * GnuTLS is free software; you can redistribute it and/or modify it
Packit aea12f
 * under the terms of the GNU General Public License as published by
Packit aea12f
 * the Free Software Foundation; either version 3 of the License, or
Packit aea12f
 * (at your option) any later version.
Packit aea12f
 *
Packit aea12f
 * GnuTLS is distributed in the hope that it will be useful, but
Packit aea12f
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit aea12f
 * General Public License for more details.
Packit aea12f
 *
Packit aea12f
 * You should have received a copy of the GNU General Public License
Packit aea12f
 * along with GnuTLS; if not, write to the Free Software Foundation,
Packit aea12f
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Packit aea12f
 */
Packit aea12f
Packit aea12f
#ifdef HAVE_CONFIG_H
Packit aea12f
#include <config.h>
Packit aea12f
#endif
Packit aea12f
Packit aea12f
#include <stdio.h>
Packit aea12f
#include <stdlib.h>
Packit aea12f
Packit aea12f
/* In this test we check whether the server will bail out after receiving
Packit aea12f
 * a bunch of warning alerts. That is to avoid DoS due to the assymetry of
Packit aea12f
 * cost of sending an alert vs the cost of receiving.
Packit aea12f
 */
Packit aea12f
Packit aea12f
#if defined(_WIN32)
Packit aea12f
Packit aea12f
/* socketpair isn't supported on Win32. */
Packit aea12f
int main(int argc, char **argv)
Packit aea12f
{
Packit aea12f
	exit(77);
Packit aea12f
}
Packit aea12f
Packit aea12f
#else
Packit aea12f
Packit aea12f
#include <string.h>
Packit aea12f
#include <sys/types.h>
Packit aea12f
#include <sys/socket.h>
Packit aea12f
#if !defined(_WIN32)
Packit aea12f
#include <sys/wait.h>
Packit aea12f
#endif
Packit aea12f
#include <unistd.h>
Packit aea12f
#include <assert.h>
Packit aea12f
#include <gnutls/gnutls.h>
Packit aea12f
Packit aea12f
#include "utils.h"
Packit aea12f
#include "cert-common.h"
Packit aea12f
Packit aea12f
pid_t child;
Packit aea12f
Packit aea12f
static void tls_log_func(int level, const char *str)
Packit aea12f
{
Packit aea12f
	fprintf(stderr, "%s |<%d>| %s", child ? "server" : "client", level,
Packit aea12f
		str);
Packit aea12f
}
Packit aea12f
Packit aea12f
static unsigned char tls_hello[] =
Packit aea12f
	"\x16\x03\x01\x01\x38\x01\x00\x01"
Packit aea12f
	"\x34\x03\x03\xfc\x77\xa8\xc7\x46"
Packit aea12f
	"\xf7\xfd\x04\x5b\x3c\xc6\xfa\xa4"
Packit aea12f
	"\xea\x3e\xfa\x76\x99\xfe\x1a\x2e"
Packit aea12f
	"\xe0\x79\x17\xb2\x27\x06\xc4\x5c"
Packit aea12f
	"\xd8\x78\x31\x00\x00\xb6\xc0\x30"
Packit aea12f
	"\xc0\x2c\xc0\x28\xc0\x24\xc0\x14"
Packit aea12f
	"\xc0\x0a\x00\xa5\x00\xa3\x00\xa1"
Packit aea12f
	"\x00\x9f\x00\x6b\x00\x6a\x00\x69"
Packit aea12f
	"\x00\x68\x00\x39\x00\x38\x00\x37"
Packit aea12f
	"\x00\x36\x00\x88\x00\x87\x00\x86"
Packit aea12f
	"\x00\x85\xc0\x32\xc0\x2e\xc0\x2a"
Packit aea12f
	"\xc0\x26\xc0\x0f\xc0\x05\x00\x9d"
Packit aea12f
	"\x00\x3d\x00\x35\x00\x84\xc0\x2f"
Packit aea12f
	"\xc0\x2b\xc0\x27\xc0\x23\xc0\x13"
Packit aea12f
	"\xc0\x09\x00\xa4\x00\xa2\x00\xa0"
Packit aea12f
	"\x00\x9e\x00\x67\x00\x40\x00\x3f"
Packit aea12f
	"\x00\x3e\x00\x33\x00\x32\x00\x31"
Packit aea12f
	"\x00\x30\x00\x9a\x00\x99\x00\x98"
Packit aea12f
	"\x00\x97\x00\x45\x00\x44\x00\x43"
Packit aea12f
	"\x00\x42\xc0\x31\xc0\x2d\xc0\x29"
Packit aea12f
	"\xc0\x25\xc0\x0e\xc0\x04\x00\x9c"
Packit aea12f
	"\x00\x3c\x00\x2f\x00\x96\x00\x41"
Packit aea12f
	"\x00\x07\xc0\x11\xc0\x07\xc0\x0c"
Packit aea12f
	"\xc0\x02\x00\x05\x00\x04\xc0\x12"
Packit aea12f
	"\xc0\x08\x00\x16\x00\x13\x00\x10"
Packit aea12f
	"\x00\x0d\xc0\x0d\xc0\x03\x00\x0a"
Packit aea12f
	"\x00\x15\x00\x12\x00\x0f\x00\x0c"
Packit aea12f
	"\x00\x09\x00\xff\x01\x00\x00\x55"
Packit aea12f
	"\x00\x0b\x00\x04\x03\x00\x01\x02"
Packit aea12f
	"\x00\x0a\x00\x1c\x00\x1a\x00\x17"
Packit aea12f
	"\x00\x19\x00\x1c\x00\x1b\x00\x18"
Packit aea12f
	"\x00\x1a\x00\x16\x00\x0e\x00\x0d"
Packit aea12f
	"\x00\x0b\x00\x0c\x00\x09\x00\x0a"
Packit aea12f
	"\x00\x23\x00\x00\x00\x0d\x00\x20"
Packit aea12f
	"\x00\x1e\x06\x01\x06\x02\x06\x03"
Packit aea12f
	"\x05\x01\x05\x02\x05\x03\x04\x01"
Packit aea12f
	"\x04\x02\x04\x03\x03\x01\x03\x02"
Packit aea12f
	"\x03\x03\x02\x01\x02\x02\x02\x03"
Packit aea12f
	"\x00\x0f\x00\x01\x01";
Packit aea12f
Packit aea12f
static unsigned char tls_alert[] = 
Packit aea12f
	"\x15\x03\x03\x00\x02\x00\x0A";
Packit aea12f
Packit aea12f
static void client(int sd)
Packit aea12f
{
Packit aea12f
	char buf[1024];
Packit aea12f
	int ret;
Packit aea12f
	unsigned i;
Packit aea12f
Packit aea12f
	/* send a TLS hello, and then a list of warning alerts */
Packit aea12f
Packit aea12f
	ret = send(sd, tls_hello, sizeof(tls_hello)-1, 0);
Packit aea12f
	if (ret < 0)
Packit aea12f
		fail("error sending hello\n");
Packit aea12f
Packit aea12f
	ret = recv(sd, buf, sizeof(buf), 0);
Packit aea12f
	if (ret < 0)
Packit aea12f
		fail("error receiving hello\n");
Packit aea12f
Packit aea12f
	for (i=0;i<128;i++) {
Packit aea12f
		ret = send(sd, tls_alert, sizeof(tls_alert)-1, 0);
Packit aea12f
		if (ret < 0)
Packit aea12f
			fail("error sending hello\n");
Packit aea12f
	}
Packit aea12f
Packit aea12f
	close(sd);
Packit aea12f
}
Packit aea12f
Packit aea12f
static void server(int sd)
Packit aea12f
{
Packit aea12f
	gnutls_certificate_credentials_t x509_cred;
Packit aea12f
	gnutls_session_t session;
Packit aea12f
	int ret;
Packit aea12f
	unsigned loops;
Packit aea12f
Packit aea12f
	/* this must be called once in the program
Packit aea12f
	 */
Packit aea12f
	global_init();
Packit aea12f
Packit aea12f
	gnutls_global_set_log_function(tls_log_func);
Packit aea12f
	if (debug)
Packit aea12f
		gnutls_global_set_log_level(6);
Packit aea12f
Packit aea12f
	gnutls_certificate_allocate_credentials(&x509_cred);
Packit aea12f
	gnutls_certificate_set_x509_trust_mem(x509_cred, &ca3_cert,
Packit aea12f
					      GNUTLS_X509_FMT_PEM);
Packit aea12f
Packit aea12f
	gnutls_certificate_set_x509_key_mem(x509_cred, &server_ca3_localhost_cert,
Packit aea12f
					    &server_ca3_key,
Packit aea12f
					    GNUTLS_X509_FMT_PEM);
Packit aea12f
Packit aea12f
	if (debug)
Packit aea12f
		success("Launched, generating DH parameters...\n");
Packit aea12f
Packit aea12f
	gnutls_init(&session, GNUTLS_SERVER);
Packit aea12f
Packit aea12f
	/* avoid calling all the priority functions, since the defaults
Packit aea12f
	 * are adequate.
Packit aea12f
	 */
Packit aea12f
	assert(gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.2", NULL)>=0);
Packit aea12f
Packit aea12f
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
Packit aea12f
Packit aea12f
	gnutls_transport_set_int(session, sd);
Packit aea12f
	loops = 0;
Packit aea12f
	do {
Packit aea12f
		ret = gnutls_handshake(session);
Packit aea12f
		loops++;
Packit aea12f
		if (loops > 64)
Packit aea12f
			fail("Too many loops in the handshake!\n");
Packit aea12f
	} while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED);
Packit aea12f
Packit aea12f
	if (ret >= 0) {
Packit aea12f
		fail("server: Handshake succeeded unexpectedly\n");
Packit aea12f
	}
Packit aea12f
Packit aea12f
	close(sd);
Packit aea12f
	gnutls_deinit(session);
Packit aea12f
Packit aea12f
	gnutls_certificate_free_credentials(x509_cred);
Packit aea12f
Packit aea12f
	gnutls_global_deinit();
Packit aea12f
Packit aea12f
	if (debug)
Packit aea12f
		success("server: finished\n");
Packit aea12f
}
Packit aea12f
Packit aea12f
Packit aea12f
void doit(void)
Packit aea12f
{
Packit aea12f
	int sockets[2];
Packit aea12f
	int err;
Packit aea12f
Packit aea12f
	err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
Packit aea12f
	if (err == -1) {
Packit aea12f
		perror("socketpair");
Packit aea12f
		fail("socketpair failed\n");
Packit aea12f
		return;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	child = fork();
Packit aea12f
	if (child < 0) {
Packit aea12f
		perror("fork");
Packit aea12f
		fail("fork");
Packit aea12f
		return;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	if (child) {
Packit aea12f
		int status;
Packit aea12f
Packit aea12f
		server(sockets[0]);
Packit aea12f
		wait(&status);
Packit aea12f
		check_wait_status(status);
Packit aea12f
	} else {
Packit aea12f
		client(sockets[1]);
Packit aea12f
		exit(0);
Packit aea12f
	}
Packit aea12f
}
Packit aea12f
Packit aea12f
#endif				/* _WIN32 */