Blame tests/handshake-large-cert.c

Packit aea12f
/*
Packit aea12f
 * Copyright (C) 2016-2018 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 Lesser General Public License
Packit aea12f
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
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
#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
#include <signal.h>
Packit aea12f
#endif
Packit aea12f
#include <unistd.h>
Packit aea12f
#include <gnutls/gnutls.h>
Packit aea12f
#include <assert.h>
Packit aea12f
Packit aea12f
#include "utils.h"
Packit aea12f
Packit aea12f
/* This test checks whether a large certificate packet can be sent by
Packit aea12f
 * server and received by client. */
Packit aea12f
const char *side = "";
Packit aea12f
Packit aea12f
static void tls_log_func(int level, const char *str)
Packit aea12f
{
Packit aea12f
	fprintf(stderr, "%s|<%d>| %s", side, level, str);
Packit aea12f
}
Packit aea12f
Packit aea12f
static void client(int sd, const char *prio)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
	gnutls_session_t session;
Packit aea12f
	char buf[1];
Packit aea12f
	gnutls_certificate_credentials_t clientx509cred;
Packit aea12f
Packit aea12f
	global_init();
Packit aea12f
	gnutls_global_set_log_function(tls_log_func);
Packit aea12f
	if (debug)
Packit aea12f
		gnutls_global_set_log_level(4711);
Packit aea12f
Packit aea12f
	side = "client";
Packit aea12f
Packit aea12f
	assert(gnutls_certificate_allocate_credentials(&clientx509cred)>=0);
Packit aea12f
Packit aea12f
	assert(gnutls_init(&session, GNUTLS_CLIENT)>=0);
Packit aea12f
Packit aea12f
	assert(gnutls_priority_set_direct(session, prio, NULL) >= 0);
Packit aea12f
Packit aea12f
	/* put the anonymous credentials to the current session
Packit aea12f
	 */
Packit aea12f
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
Packit aea12f
				clientx509cred);
Packit aea12f
Packit aea12f
	gnutls_transport_set_int(session, sd);
Packit aea12f
	gnutls_handshake_set_timeout(session, 60 * 1000);
Packit aea12f
Packit aea12f
	do {
Packit aea12f
		ret = gnutls_handshake(session);
Packit aea12f
	} while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
Packit aea12f
Packit aea12f
	if (ret < 0) {
Packit aea12f
		fail("client: Handshake failed\n");
Packit aea12f
	} else {
Packit aea12f
		if (debug)
Packit aea12f
			success("client: Handshake was completed\n");
Packit aea12f
	}
Packit aea12f
Packit aea12f
	do {
Packit aea12f
		ret = gnutls_record_recv(session, buf, 1);
Packit aea12f
	} while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
Packit aea12f
	assert(ret == 0);
Packit aea12f
Packit aea12f
	close(sd);
Packit aea12f
Packit aea12f
	gnutls_deinit(session);
Packit aea12f
Packit aea12f
	gnutls_certificate_free_credentials(clientx509cred);
Packit aea12f
Packit aea12f
	gnutls_global_deinit();
Packit aea12f
}
Packit aea12f
Packit aea12f
static unsigned char server_key_pem[] =
Packit aea12f
	"-----BEGIN RSA PRIVATE KEY-----\n"
Packit aea12f
	"MIIEowIBAAKCAQEAwJo7662RNezA254WRsXlbuzkPV5eNX7pX5Pj66T8/RKfz7rL\n"
Packit aea12f
	"GpKs4fNxhhIMSUDjy2KbEQXPUH9MWROgU8V//CfcnagLYCHtniqRE+eXv0fCLwWU\n"
Packit aea12f
	"SrA8n0qCBj94/NMA4kSmHf6dE5YdjDSpukyza5IshAuxZ32MDevE3JqMjvnZ5vY7\n"
Packit aea12f
	"drJSfal0V5gof3/7J41ZVxl+WJph50e2pY1E27/hY8q5yQ3DXnE5kTQjX664ozQ8\n"
Packit aea12f
	"UPtqGfkr4YjYe4e6PUWAjU27mQng0O0K+/w8gg6xBxN/AH3U7dg5/cY5IKDsN+Iq\n"
Packit aea12f
	"4UrcCgXWjhosv9IlIXqzK7IBMMphPmRMCLMH2QIDAQABAoIBAGpOdxZdZdH6zHQr\n"
Packit aea12f
	"rKYBouJ39H5+8MbcNtmfWmT9WvogZn8U3ffbz3qjkRxsJ8XjABiJY4egyk3nBXAB\n"
Packit aea12f
	"KjQyxbKbGeUXFLhJ4cq0OgFfid11MRQdIz2aSsutJ1llfVUm7cz2ES5rE6305Hg3\n"
Packit aea12f
	"tRr0LPAJ7XIwtgmmPUCNysnsr/pVrmPLfAnl/CfbLF2v/SfpbSpkgUTrZCNUMC44\n"
Packit aea12f
	"929K4c7cFEM4SP6pUad6MipPzY/SmxZ9yhX3MsROcLp+XLCOOJhhkqoB6LWiess2\n"
Packit aea12f
	"d7odweFRZ0Q0gBD/9EMMy3J5iUwfasf8b5n7z8AgPg9CeB+p/As2/RhRPXnwlS0A\n"
Packit aea12f
	"2KrxWQECgYEA0wM+5fJeL91s19vozCqi3mKVXTv68aL9iQJQNJc4UQm+yu7JvMn9\n"
Packit aea12f
	"koPri74QUpYkmyttaJsGNc90Oj54rSsR/cmEFJKgHOEAYSLeVetyO2XNoQvKdyB9\n"
Packit aea12f
	"UVof6joMLxQ368YCahfz4ogHTQqpzN0BD2TTnKXwCXQDikN/EBb4fHkCgYEA6aov\n"
Packit aea12f
	"8XVIVlxUY4VB/9PQ03OwxTLi+zTJMFJvNJozkat6MLJjAv2zxMt2kmlb0xx3wftD\n"
Packit aea12f
	"VJKHIQCeZmU8qWEZS0G58OPg+TPvQPqdnZmRz3bGfW6F++IDAqV4DEhQ+zXQL8Js\n"
Packit aea12f
	"j9+ocre+s0zXq1HkHgemBGOHy5/jN9cXnH3XTmECgYATRFiZ5mdzN2SY0RuQiNQW\n"
Packit aea12f
	"OiopOTDQn3FG8U8hfi1GOP2Syfrhog/lMOZw/AnBgLQW9wAmbQFEKI0URGAAb85U\n"
Packit aea12f
	"vfGxbzHvcRv3wpdKgRUNF16PNeRmvDC1HOWNHX+/TLlObeYKieVa6dDA2Bho/ET8\n"
Packit aea12f
	"gthPlVc1hcJM/Zy8e1x1AQKBgQCuLDiugGDaVtpkkIlAu8/WPk9Ovv6oh5FMHrZb\n"
Packit aea12f
	"/HFiLPLY56+cJCZjE9Kfkj9rHrY59yQaH1rwg7iO1PmhvAoRqb2DTSl+OHMn+WeR\n"
Packit aea12f
	"eU5R2dRc3QysU60wxMy2QxVyG4vCfedUW0ABuutAVZARWOp0Y/khHluzscu57O/h\n"
Packit aea12f
	"q3/ZIQKBgEXHmOjftWrkWV+/zfZT64k2Z1g7s3dpXW/SFK9jPrt6oqI1GNkYz6Ds\n"
Packit aea12f
	"O1dUiPsNXDCLytUtvYrvrT3rJaPjJDRU2HrN/cYdxXgf6HSEr3Cdcpqyp/5rOOxD\n"
Packit aea12f
	"ALEix6R4MZlsQV8FfgWjvTAET7NtY303JrCdFPqIigwl/PFGPLiB\n"
Packit aea12f
	"-----END RSA PRIVATE KEY-----\n";
Packit aea12f
Packit aea12f
static void server(int sd, const char *prio)
Packit aea12f
{
Packit aea12f
	gnutls_certificate_credentials_t serverx509cred;
Packit aea12f
	const gnutls_datum_t key = { server_key_pem,
Packit aea12f
		sizeof(server_key_pem)-1
Packit aea12f
	};
Packit aea12f
	int ret;
Packit aea12f
	gnutls_session_t session;
Packit aea12f
	gnutls_datum_t cert;
Packit aea12f
	const char *src = getenv("srcdir");
Packit aea12f
	char cert_path[256];
Packit aea12f
Packit aea12f
	if (src == NULL)
Packit aea12f
		src = ".";
Packit aea12f
Packit aea12f
	global_init();
Packit aea12f
	gnutls_global_set_log_function(tls_log_func);
Packit aea12f
	if (debug)
Packit aea12f
		gnutls_global_set_log_level(4711);
Packit aea12f
Packit aea12f
	side = "server";
Packit aea12f
Packit aea12f
	snprintf(cert_path, sizeof(cert_path), "%s/data/large-cert.pem", src);
Packit aea12f
Packit aea12f
	assert(gnutls_load_file(cert_path, &cert)>=0);
Packit aea12f
Packit aea12f
	assert(gnutls_certificate_allocate_credentials(&serverx509cred)>=0);
Packit aea12f
	assert(gnutls_certificate_set_x509_key_mem(serverx509cred,
Packit aea12f
					    &cert, &key,
Packit aea12f
					    GNUTLS_X509_FMT_PEM)>=0);
Packit aea12f
Packit aea12f
	gnutls_free(cert.data);
Packit aea12f
Packit aea12f
	assert(gnutls_init(&session, GNUTLS_SERVER)>=0);
Packit aea12f
Packit aea12f
	assert(gnutls_priority_set_direct(session, prio, NULL) >= 0);
Packit aea12f
Packit aea12f
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
Packit aea12f
				serverx509cred);
Packit aea12f
Packit aea12f
	gnutls_transport_set_int(session, sd);
Packit aea12f
	gnutls_handshake_set_timeout(session, 60 * 1000);
Packit aea12f
Packit aea12f
	do {
Packit aea12f
		ret = gnutls_handshake(session);
Packit aea12f
	} while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
Packit aea12f
Packit aea12f
	if (ret < 0) {
Packit aea12f
		close(sd);
Packit aea12f
		gnutls_deinit(session);
Packit aea12f
		fail("server: Handshake has failed (%s)\n\n",
Packit aea12f
		     gnutls_strerror(ret));
Packit aea12f
		return;
Packit aea12f
	}
Packit aea12f
	if (debug)
Packit aea12f
		success("server: Handshake was completed\n");
Packit aea12f
Packit aea12f
	gnutls_bye(session, GNUTLS_SHUT_WR);
Packit aea12f
Packit aea12f
	close(sd);
Packit aea12f
	gnutls_deinit(session);
Packit aea12f
Packit aea12f
	gnutls_certificate_free_credentials(serverx509cred);
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
static
Packit aea12f
void start(const char *name, const char *prio)
Packit aea12f
{
Packit aea12f
	pid_t child;
Packit aea12f
	int sockets[2];
Packit aea12f
	int err;
Packit aea12f
Packit aea12f
	success("testing %s\n", name);
Packit aea12f
Packit aea12f
	signal(SIGPIPE, SIG_IGN);
Packit aea12f
	signal(SIGCHLD, SIG_IGN);
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 = 0;
Packit aea12f
		/* parent */
Packit aea12f
		close(sockets[0]);
Packit aea12f
		client(sockets[1], prio);
Packit aea12f
		wait(&status);
Packit aea12f
		check_wait_status(status);
Packit aea12f
	} else {
Packit aea12f
		close(sockets[1]);
Packit aea12f
		server(sockets[0], prio);
Packit aea12f
		exit(0);
Packit aea12f
	}
Packit aea12f
}
Packit aea12f
Packit aea12f
void doit(void)
Packit aea12f
{
Packit aea12f
	start("tls1.2", "NORMAL:-VERS-ALL:+VERS-TLS1.2");
Packit aea12f
	start("tls1.3", "NORMAL:-VERS-ALL:+VERS-TLS1.3");
Packit aea12f
	start("default", "NORMAL");
Packit aea12f
}
Packit aea12f
Packit aea12f
#endif				/* _WIN32 */