diff options
Diffstat (limited to 'patches/source/gnutls/gnutls-2.8.4_CVE-2014-3466.diff')
-rw-r--r-- | patches/source/gnutls/gnutls-2.8.4_CVE-2014-3466.diff | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/patches/source/gnutls/gnutls-2.8.4_CVE-2014-3466.diff b/patches/source/gnutls/gnutls-2.8.4_CVE-2014-3466.diff new file mode 100644 index 00000000..b135bbc1 --- /dev/null +++ b/patches/source/gnutls/gnutls-2.8.4_CVE-2014-3466.diff @@ -0,0 +1,312 @@ +From 7fc8bb1f29a2ca1ddedc7f5aa0204ab091c69431 Mon Sep 17 00:00:00 2001 +From: mancha <mancha1@zoho.com> +Date: Mon, 2 Jun 2014 +Subject: CVE-2014-3466 + +This is a backport adaptation for use with GnuTLS 2.8.4. + +Relevant upstream commit(s): +------------------------- +https://gitorious.org/gnutls/gnutls/commit/688ea6428a432c +https://gitorious.org/gnutls/gnutls/commit/a7be326f0e33cf + +--- + lib/gnutls_handshake.c | 2 + tests/Makefile.am | 2 + tests/long-session-id.c | 268 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 270 insertions(+), 2 deletions(-) + +--- a/lib/gnutls_handshake.c ++++ b/lib/gnutls_handshake.c +@@ -1518,7 +1518,7 @@ _gnutls_read_server_hello (gnutls_sessio + DECR_LEN (len, 1); + session_id_len = data[pos++]; + +- if (len < session_id_len) ++ if (len < session_id_len || session_id_len > TLS_MAX_SESSION_ID_SIZE) + { + gnutls_assert (); + return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -56,7 +56,8 @@ + ctests = simple gc set_pkcs12_cred certder mpi \ + certificate_set_x509_crl dn parse_ca moredn crypto_rng mini \ + finished hostname-check cve-2008-4989 pkcs12_s2k chainverify \ +- crq_key_id x509sign-verify cve-2009-1415 cve-2009-1416 mini-eagain ++ crq_key_id x509sign-verify cve-2009-1415 cve-2009-1416 \ ++ mini-eagain long-session-id + + if ENABLE_OPENSSL + ctests += openssl +--- /dev/null ++++ b/tests/long-session-id.c +@@ -0,0 +1,268 @@ ++/* ++ * Copyright (C) 2012 Free Software Foundation, Inc. ++ * ++ * Author: Nikos Mavrogiannopoulos ++ * ++ * 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 <config.h> ++#endif ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++#if defined(_WIN32) ++ ++int main() ++{ ++ exit(77); ++} ++ ++#else ++ ++#include <string.h> ++#include <sys/types.h> ++#include <netinet/in.h> ++#include <sys/socket.h> ++#include <sys/wait.h> ++#include <arpa/inet.h> ++#include <unistd.h> ++#include <gnutls/gnutls.h> ++#include <signal.h> ++ ++static int debug = 0; ++static void terminate(int); ++ ++/* This program tests the robustness of record ++ * decoding. ++ */ ++ ++static void client_log_func(int level, const char *str) ++{ ++ fprintf(stderr, "client|<%d>| %s", level, str); ++} ++ ++static unsigned char server_cert_pem[] = ++ "-----BEGIN CERTIFICATE-----\n" ++ "MIICVjCCAcGgAwIBAgIERiYdMTALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n" ++ "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTIxWhcNMDgwNDE3MTMyOTIxWjA3MRsw\n" ++ "GQYDVQQKExJHbnVUTFMgdGVzdCBzZXJ2ZXIxGDAWBgNVBAMTD3Rlc3QuZ251dGxz\n" ++ "Lm9yZzCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGA17pcr6MM8C6pJ1aqU46o63+B\n" ++ "dUxrmL5K6rce+EvDasTaDQC46kwTHzYWk95y78akXrJutsoKiFV1kJbtple8DDt2\n" ++ "DZcevensf9Op7PuFZKBroEjOd35znDET/z3IrqVgbtm2jFqab7a+n2q9p/CgMyf1\n" ++ "tx2S5Zacc1LWn9bIjrECAwEAAaOBkzCBkDAMBgNVHRMBAf8EAjAAMBoGA1UdEQQT\n" ++ "MBGCD3Rlc3QuZ251dGxzLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8B\n" ++ "Af8EBQMDB6AAMB0GA1UdDgQWBBTrx0Vu5fglyoyNgw106YbU3VW0dTAfBgNVHSME\n" ++ "GDAWgBTpPBz7rZJu5gakViyi4cBTJ8jylTALBgkqhkiG9w0BAQUDgYEAaFEPTt+7\n" ++ "bzvBuOf7+QmeQcn29kT6Bsyh1RHJXf8KTk5QRfwp6ogbp94JQWcNQ/S7YDFHglD1\n" ++ "AwUNBRXwd3riUsMnsxgeSDxYBfJYbDLeohNBsqaPDJb7XailWbMQKfAbFQ8cnOxg\n" ++ "rOKLUQRWJ0K3HyXRMhbqjdLIaQiCvQLuizo=\n" "-----END CERTIFICATE-----\n"; ++ ++const gnutls_datum_t server_cert = { server_cert_pem, ++ sizeof(server_cert_pem) ++}; ++ ++static unsigned char server_key_pem[] = ++ "-----BEGIN RSA PRIVATE KEY-----\n" ++ "MIICXAIBAAKBgQDXulyvowzwLqknVqpTjqjrf4F1TGuYvkrqtx74S8NqxNoNALjq\n" ++ "TBMfNhaT3nLvxqResm62ygqIVXWQlu2mV7wMO3YNlx696ex/06ns+4VkoGugSM53\n" ++ "fnOcMRP/PciupWBu2baMWppvtr6far2n8KAzJ/W3HZLllpxzUtaf1siOsQIDAQAB\n" ++ "AoGAYAFyKkAYC/PYF8e7+X+tsVCHXppp8AoP8TEZuUqOZz/AArVlle/ROrypg5kl\n" ++ "8YunrvUdzH9R/KZ7saNZlAPLjZyFG9beL/am6Ai7q7Ma5HMqjGU8kTEGwD7K+lbG\n" ++ "iomokKMOl+kkbY/2sI5Czmbm+/PqLXOjtVc5RAsdbgvtmvkCQQDdV5QuU8jap8Hs\n" ++ "Eodv/tLJ2z4+SKCV2k/7FXSKWe0vlrq0cl2qZfoTUYRnKRBcWxc9o92DxK44wgPi\n" ++ "oMQS+O7fAkEA+YG+K9e60sj1K4NYbMPAbYILbZxORDecvP8lcphvwkOVUqbmxOGh\n" ++ "XRmTZUuhBrJhJKKf6u7gf3KWlPl6ShKEbwJASC118cF6nurTjuLf7YKARDjNTEws\n" ++ "qZEeQbdWYINAmCMj0RH2P0mvybrsXSOD5UoDAyO7aWuqkHGcCLv6FGG+qwJAOVqq\n" ++ "tXdUucl6GjOKKw5geIvRRrQMhb/m5scb+5iw8A4LEEHPgGiBaF5NtJZLALgWfo5n\n" ++ "hmC8+G8F0F78znQtPwJBANexu+Tg5KfOnzSILJMo3oXiXhf5PqXIDmbN0BKyCKAQ\n" ++ "LfkcEcUbVfmDaHpvzwY9VEaoMOKVLitETXdNSxVpvWM=\n" ++ "-----END RSA PRIVATE KEY-----\n"; ++ ++const gnutls_datum_t server_key = { server_key_pem, ++ sizeof(server_key_pem) ++}; ++ ++ ++/* A very basic TLS client, with anonymous authentication. ++ */ ++ ++static void client(int fd, const char *prio) ++{ ++ int ret; ++ gnutls_anon_client_credentials_t anoncred; ++ gnutls_certificate_credentials_t x509_cred; ++ gnutls_session_t session; ++ /* Need to enable anonymous KX specifically. */ ++ ++ gnutls_global_init(); ++ ++ if (debug) { ++ gnutls_global_set_log_function(client_log_func); ++ gnutls_global_set_log_level(7); ++ } ++ ++ gnutls_anon_allocate_client_credentials(&anoncred); ++ gnutls_certificate_allocate_credentials(&x509_cred); ++ ++ /* Initialize TLS session ++ */ ++ gnutls_init(&session, GNUTLS_CLIENT); ++ ++ /* Use default priorities */ ++ gnutls_priority_set_direct(session, prio, NULL); ++ ++ /* put the anonymous credentials to the current session ++ */ ++ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); ++ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); ++ ++ gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd); ++ ++ /* Perform the TLS handshake ++ */ ++ do { ++ ret = gnutls_handshake(session); ++ } ++ while (ret < 0 && gnutls_error_is_fatal(ret) == 0); ++ ++ if (ret < 0) { ++ fprintf(stderr, "client: Handshake failed (expected)\n"); ++ gnutls_perror(ret); ++ exit(0); ++ } else { ++ if (debug) ++ fprintf(stderr, "client: Handshake was completed\n"); ++ } ++ ++ close(fd); ++ ++ gnutls_deinit(session); ++ ++ gnutls_anon_free_client_credentials(anoncred); ++ gnutls_certificate_free_credentials(x509_cred); ++ ++ gnutls_global_deinit(); ++} ++ ++ ++/* These are global */ ++pid_t child; ++ ++static void terminate(int ret) ++{ ++ kill(child, SIGTERM); ++ exit(ret); ++} ++ ++static void server(int fd, const char *prio) ++{ ++ int ret; ++ uint8_t id[255]; ++ uint8_t buffer[] = "\x16\x03\x00\x01\x25" ++ "\x02\x00\x01\x21" ++ "\x03\x00"/*Server Version */ ++ /*Random*/"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00" ++ /*SessionID*/"\xfe"; ++ ++ ret = read(fd, id, sizeof(id)); ++ if (ret < 0) { ++ abort(); ++ } ++ ++ ret = write(fd, buffer, sizeof(buffer)); ++ if (ret < 0) { ++ return; ++ } ++ ++ memset(id, 0xff, sizeof(id)); ++ ret = write(fd, id, sizeof(id)); ++ if (ret < 0) { ++ return; ++ } ++ ++ memset(id, 0xff, sizeof(id)); ++ ret = write(fd, id, sizeof(id)); ++ if (ret < 0) { ++ return; ++ } ++ sleep(3); ++ ++ return; ++} ++ ++static void start(const char *prio) ++{ ++ int fd[2]; ++ int ret; ++ ++ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd); ++ if (ret < 0) { ++ perror("socketpair"); ++ exit(1); ++ } ++ ++ child = fork(); ++ if (child < 0) { ++ perror("fork"); ++ exit(1); ++ } ++ ++ if (child) { ++ /* parent */ ++ close(fd[1]); ++ server(fd[0], prio); ++ kill(child, SIGTERM); ++ } else { ++ close(fd[0]); ++ client(fd[1], prio); ++ exit(0); ++ } ++} ++ ++static void ch_handler(int sig) ++{ ++ int status, ret = 0; ++ wait(&status); ++ if (WEXITSTATUS(status) != 0 || ++ (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) { ++ if (WIFSIGNALED(status)) { ++ fprintf(stderr, "Child died with sigsegv\n"); ++ ret = 1; ++ } else { ++ fprintf(stderr, "Child died with status %d\n", ++ WEXITSTATUS(status)); ++ } ++ terminate(ret); ++ } ++ return; ++} ++ ++int main(int argc, char **argv) ++{ ++ signal(SIGCHLD, ch_handler); ++ ++ if (argc > 1) ++ debug = 1; ++ ++ start("NORMAL"); ++ return 0; ++} ++ ++#endif /* _WIN32 */ |