Blame tests/multi-alerts.c

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