/* * Copyright (C) 2010-2012 Free Software Foundation, Inc. * Author: Ludovic Courtès * * 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 GNUTLS; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef HAVE_CONFIG_H #include #endif #if !defined(_WIN32) #include #include #include "utils.h" #include #include #include #include #include #include #include #include #include /* This is the same test as openpgp-auth but tests * openpgp under the latest TLS protocol (TLSv1.2). In * addition it tests DSS signatures under that. */ static const char message[] = "Hello, brave GNU world!"; /* The OpenPGP key pair for use and the key ID in those keys. */ static const char pub_key_file[] = "../guile/tests/openpgp-pub.asc"; static const char priv_key_file[] = "../guile/tests/openpgp-sec.asc"; static const char *key_id = NULL /* FIXME: The values below don't work as expected. */ /* "auto" */ /* "bd572cdcccc07c35" */ ; static void log_message(int level, const char *message) { fprintf(stderr, "[%5d|%2d] %s", getpid(), level, message); } void doit() { int err; int sockets[2]; const char *srcdir; char pub_key_path[512], priv_key_path[512]; pid_t child; global_init(); srcdir = getenv("srcdir") ? getenv("srcdir") : "."; if (debug) { gnutls_global_set_log_level(10); gnutls_global_set_log_function(log_message); } err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); if (err != 0) fail("socketpair %s\n", strerror(errno)); if (sizeof(pub_key_path) < strlen(srcdir) + strlen(pub_key_file) + 2) abort(); strcpy(pub_key_path, srcdir); strcat(pub_key_path, "/"); strcat(pub_key_path, pub_key_file); if (sizeof(priv_key_path) < strlen(srcdir) + strlen(priv_key_file) + 2) abort(); strcpy(priv_key_path, srcdir); strcat(priv_key_path, "/"); strcat(priv_key_path, priv_key_file); child = fork(); if (child == -1) fail("fork %s\n", strerror(errno)); if (child == 0) { /* Child process (client). */ gnutls_session_t session; gnutls_certificate_credentials_t cred; ssize_t sent; if (debug) printf("client process %i\n", getpid()); err = gnutls_init(&session, GNUTLS_CLIENT); if (err != 0) fail("client session %d\n", err); gnutls_priority_set_direct(session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_int(session, sockets[0]); err = gnutls_certificate_allocate_credentials(&cred); if (err != 0) fail("client credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2(cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail("client openpgp keys %d\n", err); err = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail("client credential_set %d\n", err); gnutls_dh_set_prime_bits(session, 1024); err = gnutls_handshake(session); if (err != 0) fail("client handshake %s (%d) \n", gnutls_strerror(err), err); else if (debug) printf("client handshake successful\n"); sent = gnutls_record_send(session, message, sizeof(message)); if (sent != sizeof(message)) fail("client sent %li vs. %li\n", (long) sent, (long) sizeof(message)); err = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (err != 0) fail("client bye %d\n", err); if (debug) printf("client done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials(cred); } else { /* Parent process (server). */ gnutls_session_t session; gnutls_dh_params_t dh_params; gnutls_certificate_credentials_t cred; char greetings[sizeof(message) * 2]; ssize_t received; pid_t done; int status; const gnutls_datum_t p3 = { (void *) pkcs3, strlen(pkcs3) }; if (debug) printf("server process %i (child %i)\n", getpid(), child); err = gnutls_init(&session, GNUTLS_SERVER); if (err != 0) fail("server session %d\n", err); gnutls_priority_set_direct(session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_int(session, sockets[1]); err = gnutls_certificate_allocate_credentials(&cred); if (err != 0) fail("server credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2(cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail("server openpgp keys %d\n", err); err = gnutls_dh_params_init(&dh_params); if (err) fail("server DH params init %d\n", err); err = gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); if (err) fail("server DH params generate %d\n", err); gnutls_certificate_set_dh_params(cred, dh_params); err = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail("server credential_set %d\n", err); gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE); err = gnutls_handshake(session); if (err != 0) fail("server handshake %s (%d) \n", gnutls_strerror(err), err); received = gnutls_record_recv(session, greetings, sizeof(greetings)); if (received != sizeof(message) || memcmp(greetings, message, sizeof(message))) fail("server received %li vs. %li\n", (long) received, (long) sizeof(message)); err = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (err != 0) fail("server bye %s (%d) \n", gnutls_strerror(err), err); if (debug) printf("server done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials(cred); gnutls_dh_params_deinit(dh_params); done = wait(&status); if (done < 0) fail("wait %s\n", strerror(errno)); if (done != child) fail("who's that?! %d\n", done); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) fail("child exited with status %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) fail("child stopped by signal %d\n", WTERMSIG(status)); else fail("child failed: %d\n", status); } gnutls_global_deinit(); } #else #include void doit() { exit(77); } #endif