Index: crypto/openssl/CHANGES =================================================================== --- crypto/openssl/CHANGES (revision 248771) +++ crypto/openssl/CHANGES (working copy) @@ -2,6 +2,171 @@ OpenSSL CHANGES _______________ + Changes between 0.9.8x and 0.9.8y [5 Feb 2013] + + *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time. + + This addresses the flaw in CBC record processing discovered by + Nadhem Alfardan and Kenny Paterson. Details of this attack can be found + at: http://www.isg.rhul.ac.uk/tls/ + + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and + Emilia Käsper for the initial patch. + (CVE-2013-0169) + [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson] + + *) Return an error when checking OCSP signatures when key is NULL. + This fixes a DoS attack. (CVE-2013-0166) + [Steve Henson] + + *) Call OCSP Stapling callback after ciphersuite has been chosen, so + the right response is stapled. Also change SSL_get_certificate() + so it returns the certificate actually sent. + See http://rt.openssl.org/Ticket/Display.html?id=2836. + (This is a backport) + [Rob Stradling ] + + *) Fix possible deadlock when decoding public keys. + [Steve Henson] + + Changes between 0.9.8w and 0.9.8x [10 May 2012] + + *) Sanity check record length before skipping explicit IV in DTLS + to fix DoS attack. + + Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic + fuzzing as a service testing platform. + (CVE-2012-2333) + [Steve Henson] + + *) Initialise tkeylen properly when encrypting CMS messages. + Thanks to Solar Designer of Openwall for reporting this issue. + [Steve Henson] + + Changes between 0.9.8v and 0.9.8w [23 Apr 2012] + + *) The fix for CVE-2012-2110 did not take into account that the + 'len' argument to BUF_MEM_grow and BUF_MEM_grow_clean is an + int in OpenSSL 0.9.8, making it still vulnerable. Fix by + rejecting negative len parameter. (CVE-2012-2131) + [Tomas Hoger ] + + Changes between 0.9.8u and 0.9.8v [19 Apr 2012] + + *) Check for potentially exploitable overflows in asn1_d2i_read_bio + BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer + in CRYPTO_realloc_clean. + + Thanks to Tavis Ormandy, Google Security Team, for discovering this + issue and to Adam Langley for fixing it. + (CVE-2012-2110) + [Adam Langley (Google), Tavis Ormandy, Google Security Team] + + Changes between 0.9.8t and 0.9.8u [12 Mar 2012] + + *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness + in CMS and PKCS7 code. When RSA decryption fails use a random key for + content decryption and always return the same error. Note: this attack + needs on average 2^20 messages so it only affects automated senders. The + old behaviour can be reenabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where + an MMA defence is not necessary. + Thanks to Ivan Nestlerode for discovering + this issue. (CVE-2012-0884) + [Steve Henson] + + *) Fix CVE-2011-4619: make sure we really are receiving a + client hello before rejecting multiple SGC restarts. Thanks to + Ivan Nestlerode for discovering this bug. + [Steve Henson] + + Changes between 0.9.8s and 0.9.8t [18 Jan 2012] + + *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. + Thanks to Antonio Martin, Enterprise Secure Access Research and + Development, Cisco Systems, Inc. for discovering this bug and + preparing a fix. (CVE-2012-0050) + [Antonio Martin] + + Changes between 0.9.8r and 0.9.8s [4 Jan 2012] + + *) Nadhem Alfardan and Kenny Paterson have discovered an extension + of the Vaudenay padding oracle attack on CBC mode encryption + which enables an efficient plaintext recovery attack against + the OpenSSL implementation of DTLS. Their attack exploits timing + differences arising during decryption processing. A research + paper describing this attack can be found at: + http://www.isg.rhul.ac.uk/~kp/dtls.pdf + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann + and Michael Tuexen + for preparing the fix. (CVE-2011-4108) + [Robin Seggelmann, Michael Tuexen] + + *) Stop policy check failure freeing same buffer twice. (CVE-2011-4109) + [Ben Laurie, Kasper ] + + *) Clear bytes used for block padding of SSL 3.0 records. + (CVE-2011-4576) + [Adam Langley (Google)] + + *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George + Kadianakis for discovering this issue and + Adam Langley for preparing the fix. (CVE-2011-4619) + [Adam Langley (Google)] + + *) Prevent malformed RFC3779 data triggering an assertion failure. + Thanks to Andrew Chi, BBN Technologies, for discovering the flaw + and Rob Austein for fixing it. (CVE-2011-4577) + [Rob Austein ] + + *) Fix ssl_ciph.c set-up race. + [Adam Langley (Google)] + + *) Fix spurious failures in ecdsatest.c. + [Emilia Käsper (Google)] + + *) Fix the BIO_f_buffer() implementation (which was mixing different + interpretations of the '..._len' fields). + [Adam Langley (Google)] + + *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than + BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent + threads won't reuse the same blinding coefficients. + + This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING + lock to call BN_BLINDING_invert_ex, and avoids one use of + BN_BLINDING_update for each BN_BLINDING structure (previously, + the last update always remained unused). + [Emilia Käsper (Google)] + + *) Fix SSL memory handling for (EC)DH ciphersuites, in particular + for multi-threaded use of ECDH. + [Adam Langley (Google)] + + *) Fix x509_name_ex_d2i memory leak on bad inputs. + [Bodo Moeller] + + *) Add protection against ECDSA timing attacks as mentioned in the paper + by Billy Bob Brumley and Nicola Tuveri, see: + + http://eprint.iacr.org/2011/232.pdf + + [Billy Bob Brumley and Nicola Tuveri] + + Changes between 0.9.8q and 0.9.8r [8 Feb 2011] + + *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 + [Neel Mehta, Adam Langley, Bodo Moeller (Google)] + + *) Fix bug in string printing code: if *any* escaping is enabled we must + escape the escape character (backslash) or the resulting string is + ambiguous. + [Steve Henson] + Changes between 0.9.8p and 0.9.8q [2 Dec 2010] *) Disable code workaround for ancient and obsolete Netscape browsers Index: crypto/openssl/Configure =================================================================== --- crypto/openssl/Configure (revision 248771) +++ crypto/openssl/Configure (working copy) @@ -162,6 +162,7 @@ my %table=( "debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::", "debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::", "debug-ben-debug", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -ggdb3 -O2 -pipe::(unknown)::::::", +"debug-ben-debug-64", "gcc:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-ben-debug-noopt", "gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -ggdb3 -pipe::(unknown)::::::", "debug-ben-strict", "gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::", "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}", @@ -172,10 +173,10 @@ my %table=( "debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-steve", "gcc:-DL_ENDIAN -DREF_CHECK -DCONF_DEBUG -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -m32 -g -pedantic -Wno-long-long -Wall -Werror -Wshadow -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared", "debug-steve-linux-pseudo64", "gcc:-DL_ENDIAN -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG_ALL -DOPENSSL_NO_ASM -g -mcpu=i486 -Wall -Werror -Wshadow -pipe::-D_REENTRANT::-rdynamic -ldl:SIXTY_FOUR_BIT:${no_asm}:dlfcn:linux-shared", -"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -D_POSIX_SOURCE -DPEDANTIC -ggdb -g3 -mcpu=i486 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +"debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +"debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +"debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +"debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-geoff","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "debug-linux-pentium","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn", "debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -DTERMIO -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn", @@ -371,6 +372,9 @@ my %table=( "linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${no_asm}", "linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${no_asm}", +# Android: Linux but without -DTERMIO and pointers to headers and libs. +"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + #### *BSD [do see comment about ${BSDthreads} above!] "BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", "BSD-x86", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", @@ -425,8 +429,8 @@ my %table=( "aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR::aix_ppc64.o::::::::::dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64", # Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE # at build time. $OBJECT_MODE is respected at ./config stage! -"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::BN_LLONG RC4_CHAR::aix_ppc32.o::::::::::dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32", -"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR::aix_ppc64.o::::::::::dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64", +"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR::aix_ppc32.o::::::::::dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32", +"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR::aix_ppc64.o::::::::::dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64", # # Cray T90 and similar (SDSC) Index: crypto/openssl/FAQ =================================================================== --- crypto/openssl/FAQ (revision 248771) +++ crypto/openssl/FAQ (working copy) @@ -10,6 +10,7 @@ OpenSSL - Frequently Asked Questions * Why aren't tools like 'autoconf' and 'libtool' used? * What is an 'engine' version? * How do I check the authenticity of the OpenSSL distribution? +* How does the versioning scheme work? [LEGAL] Legal questions @@ -82,7 +83,7 @@ OpenSSL - Frequently Asked Questions * Which is the current version of OpenSSL? The current version is available from . -OpenSSL 1.0.0c was released on Dec 2nd, 2010. +OpenSSL 1.0.1d was released on Feb 5th, 2013. In addition to the current stable release, you can also access daily snapshots of the OpenSSL development version at . Note that the online documents refer to the very latest development versions of OpenSSL and may include features not present in released versions. If in doubt refer to the documentation -that came with the version of OpenSSL you are using. +that came with the version of OpenSSL you are using. The pod format +documentation is included in each OpenSSL distribution under the docs +directory. For information on parts of libcrypto that are not yet documented, you might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's @@ -173,6 +176,19 @@ just do: pgp TARBALL.asc +* How does the versioning scheme work? + +After the release of OpenSSL 1.0.0 the versioning scheme changed. Letter +releases (e.g. 1.0.1a) can only contain bug and security fixes and no +new features. Minor releases change the last number (e.g. 1.0.2) and +can contain new features that retain binary compatibility. Changes to +the middle number are considered major releases and neither source nor +binary compatibility is guaranteed. + +Therefore the answer to the common question "when will feature X be +backported to OpenSSL 1.0.0/0.9.8?" is "never" but it could appear +in the next minor release. + [LEGAL] ======================================================================= * Do I need patent licenses to use OpenSSL? @@ -284,7 +300,7 @@ current directory in this case, but this has chang Check out the CA.pl(1) manual page. This provides a simple wrapper round the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check out the manual pages for the individual utilities and the certificate -extensions documentation (currently in doc/openssl.txt). +extensions documentation (in ca(1), req(1), x509v3_config(5) ) * Why can't I create certificate requests? Index: crypto/openssl/LICENSE =================================================================== --- crypto/openssl/LICENSE (revision 248771) +++ crypto/openssl/LICENSE (working copy) @@ -12,7 +12,7 @@ --------------- /* ==================================================================== - * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Index: crypto/openssl/Makefile =================================================================== --- crypto/openssl/Makefile (revision 248771) +++ crypto/openssl/Makefile (working copy) @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=0.9.8q +VERSION=0.9.8y MAJOR=0 MINOR=9.8 SHLIB_VERSION_NUMBER=0.9.8 Index: crypto/openssl/NEWS =================================================================== --- crypto/openssl/NEWS (revision 248771) +++ crypto/openssl/NEWS (working copy) @@ -5,6 +5,45 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 0.9.8x and OpenSSL 0.9.8y: + + o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169 + o Fix OCSP bad key DoS attack CVE-2013-0166 + + Major changes between OpenSSL 0.9.8w and OpenSSL 0.9.8x: + + o Fix DTLS record length checking bug CVE-2012-2333 + + Major changes between OpenSSL 0.9.8v and OpenSSL 0.9.8w: + + o Fix for CVE-2012-2131 (corrected fix for 0.9.8 and CVE-2012-2110) + + Major changes between OpenSSL 0.9.8u and OpenSSL 0.9.8v: + + o Fix for ASN1 overflow bug CVE-2012-2110 + + Major changes between OpenSSL 0.9.8t and OpenSSL 0.9.8u: + + o Fix for CMS/PKCS#7 MMA CVE-2012-0884 + o Corrected fix for CVE-2011-4619 + o Various DTLS fixes. + + Major changes between OpenSSL 0.9.8s and OpenSSL 0.9.8t: + + o Fix for DTLS DoS issue CVE-2012-0050 + + Major changes between OpenSSL 0.9.8r and OpenSSL 0.9.8s: + + o Fix for DTLS plaintext recovery attack CVE-2011-4108 + o Fix policy check double free error CVE-2011-4109 + o Clear block padding bytes of SSL 3.0 records CVE-2011-4576 + o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619 + o Check for malformed RFC3779 data CVE-2011-4577 + + Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r: + + o Fix for security issue CVE-2011-0014 + Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q: o Fix for security issue CVE-2010-4180 @@ -181,6 +220,11 @@ o Added initial support for Win64. o Added alternate pkg-config files. + Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m: + + o FIPS 1.1.1 module linking. + o Various ciphersuite selection fixes. + Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l: o Introduce limits to prevent malicious key DoS (CVE-2006-2940) Index: crypto/openssl/README =================================================================== --- crypto/openssl/README (revision 248771) +++ crypto/openssl/README (working copy) @@ -1,7 +1,7 @@ - OpenSSL 0.9.8q 2 Dec 2010 + OpenSSL 0.9.8y 5 Feb 2013 - Copyright (c) 1998-2009 The OpenSSL Project + Copyright (c) 1998-2011 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson All rights reserved. Index: crypto/openssl/apps/apps.c =================================================================== --- crypto/openssl/apps/apps.c (revision 248771) +++ crypto/openssl/apps/apps.c (working copy) @@ -2052,7 +2052,7 @@ X509_NAME *parse_name(char *subject, long chtype, X509_NAME *n = NULL; int nid; - if (!buf || !ne_types || !ne_values) + if (!buf || !ne_types || !ne_values || !mval) { BIO_printf(bio_err, "malloc error\n"); goto error; @@ -2156,6 +2156,7 @@ X509_NAME *parse_name(char *subject, long chtype, OPENSSL_free(ne_values); OPENSSL_free(ne_types); OPENSSL_free(buf); + OPENSSL_free(mval); return n; error: @@ -2164,6 +2165,8 @@ error: OPENSSL_free(ne_values); if (ne_types) OPENSSL_free(ne_types); + if (mval) + OPENSSL_free(mval); if (buf) OPENSSL_free(buf); return NULL; Index: crypto/openssl/apps/asn1pars.c =================================================================== --- crypto/openssl/apps/asn1pars.c (revision 248771) +++ crypto/openssl/apps/asn1pars.c (working copy) @@ -408,6 +408,7 @@ static int do_generate(BIO *bio, char *genstr, cha atyp = ASN1_generate_nconf(genstr, cnf); NCONF_free(cnf); + cnf = NULL; if (!atyp) return -1; Index: crypto/openssl/apps/cms.c =================================================================== --- crypto/openssl/apps/cms.c (revision 248771) +++ crypto/openssl/apps/cms.c (working copy) @@ -226,6 +226,8 @@ int MAIN(int argc, char **argv) else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif + else if (!strcmp (*args, "-debug_decrypt")) + flags |= CMS_DEBUG_DECRYPT; else if (!strcmp (*args, "-text")) flags |= CMS_TEXT; else if (!strcmp (*args, "-nointern")) @@ -611,7 +613,7 @@ int MAIN(int argc, char **argv) BIO_printf (bio_err, "-certsout file certificate output file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); - BIO_printf (bio_err, "-skeyid use subject key identifier\n"); + BIO_printf (bio_err, "-keyid use subject key identifier\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); @@ -1013,6 +1015,8 @@ int MAIN(int argc, char **argv) ret = 4; if (operation == SMIME_DECRYPT) { + if (flags & CMS_DEBUG_DECRYPT) + CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); if (secret_key) { Index: crypto/openssl/apps/dhparam.c =================================================================== --- crypto/openssl/apps/dhparam.c (revision 248771) +++ crypto/openssl/apps/dhparam.c (working copy) @@ -332,7 +332,6 @@ bad: BIO_printf(bio_err,"This is going to take a long time\n"); if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb)) { - if(dh) DH_free(dh); ERR_print_errors(bio_err); goto end; } Index: crypto/openssl/apps/openssl.cnf =================================================================== --- crypto/openssl/apps/openssl.cnf (revision 248771) +++ crypto/openssl/apps/openssl.cnf (working copy) @@ -142,7 +142,7 @@ localityName = Locality Name (eg, city) organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = -commonName = Common Name (eg, YOUR name) +commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address Index: crypto/openssl/apps/pkcs12.c =================================================================== --- crypto/openssl/apps/pkcs12.c (revision 248771) +++ crypto/openssl/apps/pkcs12.c (working copy) @@ -659,7 +659,7 @@ int MAIN(int argc, char **argv) if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); - if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); + if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("verify MAC"); Index: crypto/openssl/apps/s_client.c =================================================================== --- crypto/openssl/apps/s_client.c (revision 248771) +++ crypto/openssl/apps/s_client.c (working copy) @@ -345,13 +345,7 @@ int MAIN(int argc, char **argv) char *jpake_secret = NULL; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_client_method(); -#elif !defined(OPENSSL_NO_SSL3) - meth=SSLv3_client_method(); -#elif !defined(OPENSSL_NO_SSL2) - meth=SSLv2_client_method(); -#endif apps_startup(); c_Pause=0; Index: crypto/openssl/apps/s_server.c =================================================================== --- crypto/openssl/apps/s_server.c (revision 248771) +++ crypto/openssl/apps/s_server.c (working copy) @@ -781,13 +781,7 @@ int MAIN(int argc, char *argv[]) tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_server_method(); -#elif !defined(OPENSSL_NO_SSL3) - meth=SSLv3_server_method(); -#elif !defined(OPENSSL_NO_SSL2) - meth=SSLv2_server_method(); -#endif local_argc=argc; local_argv=argv; @@ -1556,6 +1550,12 @@ end: if (dpass) OPENSSL_free(dpass); #ifndef OPENSSL_NO_TLSEXT + if (tlscstatp.host) + OPENSSL_free(tlscstatp.host); + if (tlscstatp.port) + OPENSSL_free(tlscstatp.port); + if (tlscstatp.path) + OPENSSL_free(tlscstatp.path); if (ctx2 != NULL) SSL_CTX_free(ctx2); if (s_cert2) X509_free(s_cert2); Index: crypto/openssl/apps/x509.c =================================================================== --- crypto/openssl/apps/x509.c (revision 248771) +++ crypto/openssl/apps/x509.c (working copy) @@ -969,7 +969,7 @@ bad: else { pk=load_key(bio_err, - keyfile, FORMAT_PEM, 0, + keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } Index: crypto/openssl/config =================================================================== --- crypto/openssl/config (revision 248771) +++ crypto/openssl/config (working copy) @@ -790,6 +790,10 @@ esac # options="$options -DATALLA" #fi +($CC -Wa,--help -c -o /dev/null -x assembler /dev/null 2>&1 | \ + grep \\--noexecstack) 2>&1 > /dev/null && \ + options="$options -Wa,--noexecstack" + # gcc < 2.8 does not support -march=ultrasparc if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ] then Index: crypto/openssl/crypto/asn1/a_object.c =================================================================== --- crypto/openssl/crypto/asn1/a_object.c (revision 248771) +++ crypto/openssl/crypto/asn1/a_object.c (working copy) @@ -139,7 +139,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); goto err; } - if (!use_bn && l > (ULONG_MAX / 10L)) + if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { use_bn = 1; if (!bl) @@ -294,7 +294,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, cons /* Sanity check OID encoding: can't have leading 0x80 in * subidentifiers, see: X.690 8.19.2 */ - for (i = 0, p = *pp + 1; i < len - 1; i++, p++) + for (i = 0, p = *pp; i < len; i++, p++) { if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { Index: crypto/openssl/crypto/asn1/a_strex.c =================================================================== --- crypto/openssl/crypto/asn1/a_strex.c (revision 248771) +++ crypto/openssl/crypto/asn1/a_strex.c (working copy) @@ -74,7 +74,12 @@ #define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) + /* Three IO functions for sending data to memory, a BIO and * and a FILE pointer. */ @@ -148,6 +153,13 @@ static int do_esc_char(unsigned long c, unsigned c if(!io_ch(arg, tmphex, 3)) return -1; return 3; } + /* If we get this far and do any escaping at all must escape + * the escape character itself: backslash. + */ + if (chtmp == '\\' && flags & ESC_FLAGS) { + if(!io_ch(arg, "\\\\", 2)) return -1; + return 2; + } if(!io_ch(arg, &chtmp, 1)) return -1; return 1; } @@ -292,11 +304,6 @@ static const signed char tag2nbyte[] = { 4, -1, 2 /* 28-30 */ }; -#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB) - /* This is the main function, print out an * ASN1_STRING taking note of various escape * and display options. Returns number of @@ -560,6 +567,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_ if(mbflag == -1) return -1; mbflag |= MBSTRING_FLAG; stmp.data = NULL; + stmp.length = 0; ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); if(ret < 0) return ret; *out = stmp.data; Index: crypto/openssl/crypto/asn1/a_strnid.c =================================================================== --- crypto/openssl/crypto/asn1/a_strnid.c (revision 248771) +++ crypto/openssl/crypto/asn1/a_strnid.c (working copy) @@ -96,7 +96,7 @@ unsigned long ASN1_STRING_get_default_mask(void) * default: the default value, Printable, T61, BMP. */ -int ASN1_STRING_set_default_mask_asc(char *p) +int ASN1_STRING_set_default_mask_asc(const char *p) { unsigned long mask; char *end; Index: crypto/openssl/crypto/asn1/a_verify.c =================================================================== --- crypto/openssl/crypto/asn1/a_verify.c (revision 248771) +++ crypto/openssl/crypto/asn1/a_verify.c (working copy) @@ -138,6 +138,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALG unsigned char *buf_in=NULL; int ret= -1,i,inl; + if (!pkey) + { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + EVP_MD_CTX_init(&ctx); i=OBJ_obj2nid(a->algorithm); type=EVP_get_digestbyname(OBJ_nid2sn(i)); Index: crypto/openssl/crypto/asn1/asn1.h =================================================================== --- crypto/openssl/crypto/asn1/asn1.h (revision 248771) +++ crypto/openssl/crypto/asn1/asn1.h (working copy) @@ -1051,7 +1051,7 @@ ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_vo ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); void ASN1_STRING_set_default_mask(unsigned long mask); -int ASN1_STRING_set_default_mask_asc(char *p); +int ASN1_STRING_set_default_mask_asc(const char *p); unsigned long ASN1_STRING_get_default_mask(void); int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask); Index: crypto/openssl/crypto/asn1/asn_mime.c =================================================================== --- crypto/openssl/crypto/asn1/asn_mime.c (revision 248771) +++ crypto/openssl/crypto/asn1/asn_mime.c (working copy) @@ -418,9 +418,9 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, if(strcmp(hdr->value, "application/x-pkcs7-signature") && strcmp(hdr->value, "application/pkcs7-signature")) { - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE); ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -790,12 +790,17 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, ch static int mime_hdr_cmp(const MIME_HEADER * const *a, const MIME_HEADER * const *b) { + if (!(*a)->name || !(*b)->name) + return !!(*a)->name - !!(*b)->name; + return(strcmp((*a)->name, (*b)->name)); } static int mime_param_cmp(const MIME_PARAM * const *a, const MIME_PARAM * const *b) { + if (!(*a)->param_name || !(*b)->param_name) + return !!(*a)->param_name - !!(*b)->param_name; return(strcmp((*a)->param_name, (*b)->param_name)); } Index: crypto/openssl/crypto/asn1/x_name.c =================================================================== --- crypto/openssl/crypto/asn1/x_name.c (revision 248771) +++ crypto/openssl/crypto/asn1/x_name.c (working copy) @@ -196,7 +196,9 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, cons *val = nm.a; *in = p; return ret; - err: +err: + if (nm.x != NULL) + X509_NAME_free(nm.x); ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; } Index: crypto/openssl/crypto/asn1/x_pubkey.c =================================================================== --- crypto/openssl/crypto/asn1/x_pubkey.c (revision 248771) +++ crypto/openssl/crypto/asn1/x_pubkey.c (working copy) @@ -367,7 +367,19 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) goto err; } - key->pkey = ret; + /* Check to see if another thread set key->pkey first */ + CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + if (key->pkey) + { + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_free(ret); + ret = key->pkey; + } + else + { + key->pkey = ret; + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + } CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); return(ret); err: Index: crypto/openssl/crypto/bio/bf_buff.c =================================================================== --- crypto/openssl/crypto/bio/bf_buff.c (revision 248771) +++ crypto/openssl/crypto/bio/bf_buff.c (working copy) @@ -209,7 +209,7 @@ start: /* add to buffer and return */ if (i >= inl) { - memcpy(&(ctx->obuf[ctx->obuf_len]),in,inl); + memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl); ctx->obuf_len+=inl; return(num+inl); } @@ -219,7 +219,7 @@ start: { if (i > 0) /* lets fill it up if we can */ { - memcpy(&(ctx->obuf[ctx->obuf_len]),in,i); + memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i); in+=i; inl-=i; num+=i; @@ -294,9 +294,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, case BIO_C_GET_BUFF_NUM_LINES: ret=0; p1=ctx->ibuf; - for (i=ctx->ibuf_off; iibuf_len; i++) + for (i=0; iibuf_len; i++) { - if (p1[i] == '\n') ret++; + if (p1[ctx->ibuf_off + i] == '\n') ret++; } break; case BIO_CTRL_WPENDING: @@ -399,17 +399,18 @@ static long buffer_ctrl(BIO *b, int cmd, long num, for (;;) { BIO_clear_retry_flags(b); - if (ctx->obuf_len > ctx->obuf_off) + if (ctx->obuf_len > 0) { r=BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), - ctx->obuf_len-ctx->obuf_off); + ctx->obuf_len); #if 0 -fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r); +fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r); #endif BIO_copy_next_retry(b); if (r <= 0) return((long)r); ctx->obuf_off+=r; + ctx->obuf_len-=r; } else { Index: crypto/openssl/crypto/bio/bio.h =================================================================== --- crypto/openssl/crypto/bio/bio.h (revision 248771) +++ crypto/openssl/crypto/bio/bio.h (working copy) @@ -145,6 +145,7 @@ extern "C" { /* #endif */ #define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 #define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ #define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for * MTU. want to use this @@ -321,6 +322,15 @@ DECLARE_STACK_OF(BIO) typedef struct bio_f_buffer_ctx_struct { + /* Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + /* BIO *bio; */ /* this is now in the BIO struct */ int ibuf_size; /* how big is the input buffer */ int obuf_size; /* how big is the output buffer */ Index: crypto/openssl/crypto/bio/bss_dgram.c =================================================================== --- crypto/openssl/crypto/bio/bss_dgram.c (revision 248771) +++ crypto/openssl/crypto/bio/bss_dgram.c (working copy) @@ -57,7 +57,6 @@ * */ -#ifndef OPENSSL_NO_DGRAM #include #include @@ -65,6 +64,7 @@ #include "cryptlib.h" #include +#ifndef OPENSSL_NO_DGRAM #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) #include @@ -288,7 +288,6 @@ static int dgram_read(BIO *b, char *out, int outl) */ dgram_adjust_rcv_timeout(b); ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); - dgram_reset_rcv_timeout(b); if ( ! data->connected && ret >= 0) BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); @@ -302,6 +301,8 @@ static int dgram_read(BIO *b, char *out, int outl) data->_errno = get_last_socket_error(); } } + + dgram_reset_rcv_timeout(b); } return(ret); } @@ -493,6 +494,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, ret = 0; #endif break; + case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: + ret = 576 - 20 - 8; + break; case BIO_CTRL_DGRAM_GET_MTU: return data->mtu; break; @@ -654,9 +658,13 @@ static int BIO_dgram_should_retry(int i) { err=get_last_socket_error(); -#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ - if ((i == -1) && (err == 0)) - return(1); +#if defined(OPENSSL_SYS_WINDOWS) + /* If the socket return value (i) is -1 + * and err is unexpectedly 0 at this point, + * the error code was overwritten by + * another system call before this error + * handling is called. + */ #endif return(BIO_dgram_non_fatal_error(err)); @@ -719,7 +727,6 @@ int BIO_dgram_non_fatal_error(int err) } return(0); } -#endif static void get_current_time(struct timeval *t) { @@ -737,3 +744,5 @@ static void get_current_time(struct timeval *t) gettimeofday(t, NULL); #endif } + +#endif Index: crypto/openssl/crypto/bn/asm/mo-586.pl =================================================================== --- crypto/openssl/crypto/bn/asm/mo-586.pl (revision 248771) +++ crypto/openssl/crypto/bn/asm/mo-586.pl (working copy) @@ -539,8 +539,10 @@ $sbit=$num; &jle (&label("sqradd")); &mov ($carry,"edx"); - &lea ("edx",&DWP(0,$sbit,"edx",2)); + &add ("edx","edx"); &shr ($carry,31); + &add ("edx",$sbit); + &adc ($carry,0); &set_label("sqrlast"); &mov ($word,$_n0); &mov ($inp,$_np); Index: crypto/openssl/crypto/bn/asm/ppc.pl =================================================================== --- crypto/openssl/crypto/bn/asm/ppc.pl (revision 248771) +++ crypto/openssl/crypto/bn/asm/ppc.pl (working copy) @@ -1039,7 +1039,7 @@ sub data { addze r11,r0 #mul_add_c(a[3],b[2],c3,c1,c2); $LD r6,`3*$BNSZ`(r4) - $LD r7,`2*$BNSZ`(r4) + $LD r7,`2*$BNSZ`(r5) $UMULL r8,r6,r7 $UMULH r9,r6,r7 addc r12,r8,r12 Index: crypto/openssl/crypto/bn/bn_blind.c =================================================================== --- crypto/openssl/crypto/bn/bn_blind.c (revision 248771) +++ crypto/openssl/crypto/bn/bn_blind.c (working copy) @@ -123,7 +123,7 @@ struct bn_blinding_st BIGNUM *mod; /* just a reference */ unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */ - unsigned int counter; + int counter; unsigned long flags; BN_MONT_CTX *m_ctx; int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, @@ -157,7 +157,10 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, cons if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(ret->mod, BN_FLG_CONSTTIME); - ret->counter = BN_BLINDING_COUNTER; + /* Set the counter to the special value -1 + * to indicate that this is never-used fresh blinding + * that does not need updating before first use. */ + ret->counter = -1; return(ret); err: if (ret != NULL) BN_BLINDING_free(ret); @@ -186,7 +189,10 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx goto err; } - if (--(b->counter) == 0 && b->e != NULL && + if (b->counter == -1) + b->counter = 0; + + if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && !(b->flags & BN_BLINDING_NO_RECREATE)) { /* re-create blinding parameters */ @@ -201,8 +207,8 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx ret=1; err: - if (b->counter == 0) - b->counter = BN_BLINDING_COUNTER; + if (b->counter == BN_BLINDING_COUNTER) + b->counter = 0; return(ret); } @@ -223,6 +229,12 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, B return(0); } + if (b->counter == -1) + /* Fresh blinding, doesn't need updating. */ + b->counter = 0; + else if (!BN_BLINDING_update(b,ctx)) + return(0); + if (r != NULL) { if (!BN_copy(r, b->Ai)) ret=0; @@ -243,22 +255,19 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM int ret; bn_check_top(n); - if ((b->A == NULL) || (b->Ai == NULL)) - { - BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED); - return(0); - } if (r != NULL) ret = BN_mod_mul(n, n, r, b->mod, ctx); else - ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); - - if (ret >= 0) { - if (!BN_BLINDING_update(b,ctx)) + if (b->Ai == NULL) + { + BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED); return(0); + } + ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); } + bn_check_top(n); return(ret); } Index: crypto/openssl/crypto/bn/bn_gf2m.c =================================================================== --- crypto/openssl/crypto/bn/bn_gf2m.c (revision 248771) +++ crypto/openssl/crypto/bn/bn_gf2m.c (working copy) @@ -607,6 +607,7 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co { while (!BN_is_odd(u)) { + if (BN_is_zero(u)) goto err; if (!BN_rshift1(u, u)) goto err; if (BN_is_odd(b)) { Index: crypto/openssl/crypto/bn/bn_word.c =================================================================== --- crypto/openssl/crypto/bn/bn_word.c (revision 248771) +++ crypto/openssl/crypto/bn/bn_word.c (working copy) @@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) a->neg=!(a->neg); return(i); } - /* Only expand (and risk failing) if it's possibly necessary */ - if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) && - (bn_wexpand(a,a->top+1) == NULL)) - return(0); - i=0; - for (;;) + for (i=0;w!=0 && itop;i++) { - if (i >= a->top) - l=w; - else - l=(a->d[i]+w)&BN_MASK2; - a->d[i]=l; - if (w > l) - w=1; - else - break; - i++; + a->d[i] = l = (a->d[i]+w)&BN_MASK2; + w = (w>l)?1:0; } - if (i >= a->top) + if (w && i==a->top) + { + if (bn_wexpand(a,a->top+1) == NULL) return 0; a->top++; + a->d[i]=w; + } bn_check_top(a); return(1); } Index: crypto/openssl/crypto/cms/cms.h =================================================================== --- crypto/openssl/crypto/cms/cms.h (revision 248771) +++ crypto/openssl/crypto/cms/cms.h (working copy) @@ -110,6 +110,7 @@ DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) #define CMS_PARTIAL 0x4000 #define CMS_REUSE_DIGEST 0x8000 #define CMS_USE_KEYID 0x10000 +#define CMS_DEBUG_DECRYPT 0x20000 const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); Index: crypto/openssl/crypto/cms/cms_enc.c =================================================================== --- crypto/openssl/crypto/cms/cms_enc.c (revision 248771) +++ crypto/openssl/crypto/cms/cms_enc.c (working copy) @@ -73,6 +73,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedCo const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; + unsigned char *tkey = NULL; + size_t tkeylen; int ok = 0; @@ -137,32 +139,57 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedCo CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } - - - if (enc && !ec->key) + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) { - /* Generate random key */ - if (!ec->keylen) - ec->keylen = EVP_CIPHER_CTX_key_length(ctx); - ec->key = OPENSSL_malloc(ec->keylen); - if (!ec->key) + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0) + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; - keep_key = 1; } - else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx)) + + if (!ec->key) { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } + + if (ec->keylen != tkeylen) + { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_INVALID_KEY_LENGTH); - goto err; + /* Only reveal failure if debugging so we don't + * leak information which may be useful in MMA. + */ + if (enc || ec->debug) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_INVALID_KEY_LENGTH); + goto err; + } + else + { + /* Use random key */ + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); + } } } @@ -198,6 +225,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedCo OPENSSL_free(ec->key); ec->key = NULL; } + if (tkey) + { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } if (ok) return b; BIO_free(b); Index: crypto/openssl/crypto/cms/cms_env.c =================================================================== --- crypto/openssl/crypto/cms/cms_env.c (revision 248771) +++ crypto/openssl/crypto/cms/cms_env.c (working copy) @@ -352,6 +352,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_Cont unsigned char *ek = NULL; int eklen; int ret = 0; + CMS_EncryptedContentInfo *ec; + ec = cms->d.envelopedData->encryptedContentInfo; if (ktri->pkey == NULL) { @@ -382,9 +384,15 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_Cont ret = 1; - cms->d.envelopedData->encryptedContentInfo->key = ek; - cms->d.envelopedData->encryptedContentInfo->keylen = eklen; + if (ec->key) + { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + } + ec->key = ek; + ec->keylen = eklen; + err: if (!ret && ek) OPENSSL_free(ek); Index: crypto/openssl/crypto/cms/cms_io.c =================================================================== --- crypto/openssl/crypto/cms/cms_io.c (revision 248771) +++ crypto/openssl/crypto/cms/cms_io.c (working copy) @@ -112,7 +112,7 @@ static int cms_output_data(BIO *out, BIO *data, AS cmsbio = tmpbio; } - return 1; + return r; } Index: crypto/openssl/crypto/cms/cms_lcl.h =================================================================== --- crypto/openssl/crypto/cms/cms_lcl.h (revision 248771) +++ crypto/openssl/crypto/cms/cms_lcl.h (working copy) @@ -175,6 +175,8 @@ struct CMS_EncryptedContentInfo_st const EVP_CIPHER *cipher; unsigned char *key; size_t keylen; + /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ + int debug; }; struct CMS_RecipientInfo_st Index: crypto/openssl/crypto/cms/cms_smime.c =================================================================== --- crypto/openssl/crypto/cms/cms_smime.c (revision 248771) +++ crypto/openssl/crypto/cms/cms_smime.c (working copy) @@ -622,7 +622,10 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EV STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r; + int debug = 0; ris = CMS_get0_RecipientInfos(cms); + if (ris) + debug = cms->d.envelopedData->encryptedContentInfo->debug; for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ri = sk_CMS_RecipientInfo_value(ris, i); @@ -636,17 +639,38 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EV CMS_RecipientInfo_set0_pkey(ri, pk); r = CMS_RecipientInfo_decrypt(cms, ri); CMS_RecipientInfo_set0_pkey(ri, NULL); - if (r > 0) - return 1; if (cert) { + /* If not debugging clear any error and + * return success to avoid leaking of + * information useful to MMA + */ + if (!debug) + { + ERR_clear_error(); + return 1; + } + if (r > 0) + return 1; CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); return 0; } - ERR_clear_error(); + /* If no cert and not debugging don't leave loop + * after first successful decrypt. Always attempt + * to decrypt all recipients to avoid leaking timing + * of a successful decrypt. + */ + else if (r > 0 && debug) + return 1; } } + /* If no cert and not debugging always return success */ + if (!cert && !debug) + { + ERR_clear_error(); + return 1; + } CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); return 0; @@ -705,9 +729,14 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk } if (!dcont && !check_content(cms)) return 0; + if (flags & CMS_DEBUG_DECRYPT) + cms->d.envelopedData->encryptedContentInfo->debug = 1; + else + cms->d.envelopedData->encryptedContentInfo->debug = 0; + if (!pk && !cert && !dcont && !out) + return 1; if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) return 0; - cont = CMS_dataInit(cms, dcont); if (!cont) return 0; Index: crypto/openssl/crypto/comp/c_rle.c =================================================================== --- crypto/openssl/crypto/comp/c_rle.c (revision 248771) +++ crypto/openssl/crypto/comp/c_rle.c (working copy) @@ -46,7 +46,7 @@ static int rle_expand_block(COMP_CTX *ctx, unsigne { int i; - if (olen < (ilen-1)) + if (ilen == 0 || olen < (ilen-1)) { /* ZZZZZZZZZZZZZZZZZZZZZZ */ return(-1); @@ -59,4 +59,3 @@ static int rle_expand_block(COMP_CTX *ctx, unsigne } return(ilen-1); } - Index: crypto/openssl/crypto/conf/conf_api.c =================================================================== --- crypto/openssl/crypto/conf/conf_api.c (revision 248771) +++ crypto/openssl/crypto/conf/conf_api.c (working copy) @@ -64,6 +64,7 @@ #endif #include +#include #include #include #include Index: crypto/openssl/crypto/cryptlib.c =================================================================== --- crypto/openssl/crypto/cryptlib.c (revision 248771) +++ crypto/openssl/crypto/cryptlib.c (working copy) @@ -396,7 +396,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwR case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: - ERR_remove_state(0); break; case DLL_PROCESS_DETACH: break; @@ -543,3 +542,19 @@ void OpenSSLDie(const char *file,int line,const ch } void *OPENSSL_stderr(void) { return stderr; } + +#ifndef OPENSSL_FIPS + +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) + { + size_t i; + const unsigned char *a = in_a; + const unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; + } +#endif Index: crypto/openssl/crypto/crypto.h =================================================================== --- crypto/openssl/crypto/crypto.h (revision 248771) +++ crypto/openssl/crypto/crypto.h (working copy) @@ -588,15 +588,22 @@ int OPENSSL_isservice(void); #endif /* def OPENSSL_FIPS */ +#define OPENSSL_HAVE_INIT 1 +void OPENSSL_init(void); + +/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It + * takes an amount of time dependent on |len|, but independent of the contents + * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a + * defined order as the return value when a != b is undefined, other than to be + * non-zero. */ +int CRYPTO_memcmp(const void *a, const void *b, size_t len); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ void ERR_load_CRYPTO_strings(void); -#define OPENSSL_HAVE_INIT 1 -void OPENSSL_init(void); - /* Error codes for the CRYPTO functions. */ /* Function codes. */ Index: crypto/openssl/crypto/ec/ec2_smpl.c =================================================================== --- crypto/openssl/crypto/ec/ec2_smpl.c (revision 248771) +++ crypto/openssl/crypto/ec/ec2_smpl.c (working copy) @@ -821,7 +821,7 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *gro field_sqr = group->meth->field_sqr; /* only support affine coordinates */ - if (!point->Z_is_one) goto err; + if (!point->Z_is_one) return -1; if (ctx == NULL) { @@ -871,6 +871,9 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, cons { return EC_POINT_is_at_infinity(group, b) ? 0 : 1; } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; if (a->Z_is_one && b->Z_is_one) { Index: crypto/openssl/crypto/ec/ec_key.c =================================================================== --- crypto/openssl/crypto/ec/ec_key.c (revision 248771) +++ crypto/openssl/crypto/ec/ec_key.c (working copy) @@ -304,7 +304,13 @@ int EC_KEY_check_key(const EC_KEY *eckey) ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); return 0; } - + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) + { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); + goto err; + } + if ((ctx = BN_CTX_new()) == NULL) goto err; if ((point = EC_POINT_new(eckey->group)) == NULL) Index: crypto/openssl/crypto/ec/ecp_smpl.c =================================================================== --- crypto/openssl/crypto/ec/ecp_smpl.c (revision 248771) +++ crypto/openssl/crypto/ec/ecp_smpl.c (working copy) @@ -1406,6 +1406,9 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const { return EC_POINT_is_at_infinity(group, b) ? 0 : 1; } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; if (a->Z_is_one && b->Z_is_one) { Index: crypto/openssl/crypto/ecdsa/ecdsatest.c =================================================================== --- crypto/openssl/crypto/ecdsa/ecdsatest.c (revision 248771) +++ crypto/openssl/crypto/ecdsa/ecdsatest.c (working copy) @@ -168,10 +168,9 @@ int fbytes(unsigned char *buf, int num) return 0; } fbytes_counter ++; - ret = BN_bn2bin(tmp, buf); - if (ret == 0 || ret != num) + if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) ret = 0; - else + else ret = 1; if (tmp) BN_free(tmp); @@ -287,9 +286,13 @@ int test_builtin(BIO *out) size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; + ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; - unsigned char *signature = NULL; - unsigned int sig_len; + unsigned char *signature = NULL; + const unsigned char *sig_ptr; + unsigned char *sig_ptr2; + unsigned char *raw_buf = NULL; + unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ @@ -339,7 +342,8 @@ int test_builtin(BIO *out) if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); - if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160) + degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); + if (degree < 160) /* drop the curve */ { EC_KEY_free(eckey); @@ -415,26 +419,89 @@ int test_builtin(BIO *out) } BIO_printf(out, "."); (void)BIO_flush(out); - /* modify a single byte of the signature */ - offset = signature[10] % sig_len; - dirt = signature[11]; - signature[offset] ^= dirt ? dirt : 1; + /* wrong length */ + if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, + eckey) == 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + + /* Modify a single byte of the signature: to ensure we don't + * garble the ASN1 structure, we read the raw signature and + * modify a byte in one of the bignums directly. */ + sig_ptr = signature; + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + + /* Store the two BIGNUMs in raw_buf. */ + r_len = BN_num_bytes(ecdsa_sig->r); + s_len = BN_num_bytes(ecdsa_sig->s); + bn_len = (degree + 7) / 8; + if ((r_len > bn_len) || (s_len > bn_len)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + buf_len = 2 * bn_len; + if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) + goto builtin_err; + /* Pad the bignums with leading zeroes. */ + memset(raw_buf, 0, buf_len); + BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); + BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); + + /* Modify a single byte in the buffer. */ + offset = raw_buf[10] % buf_len; + dirt = raw_buf[11] ? raw_buf[11] : 1; + raw_buf[offset] ^= dirt; + /* Now read the BIGNUMs back in from raw_buf. */ + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } + /* Sanity check: undo the modification and verify signature. */ + raw_buf[offset] ^= dirt; + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ + /* clean bogus errors */ + ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; + ECDSA_SIG_free(ecdsa_sig); + ecdsa_sig = NULL; + OPENSSL_free(raw_buf); + raw_buf = NULL; } ret = 1; @@ -443,8 +510,12 @@ builtin_err: EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); + if (ecdsa_sig) + ECDSA_SIG_free(ecdsa_sig); if (signature) OPENSSL_free(signature); + if (raw_buf) + OPENSSL_free(raw_buf); if (curves) OPENSSL_free(curves); Index: crypto/openssl/crypto/ecdsa/ecs_ossl.c =================================================================== --- crypto/openssl/crypto/ecdsa/ecs_ossl.c (revision 248771) +++ crypto/openssl/crypto/ecdsa/ecs_ossl.c (working copy) @@ -144,6 +144,14 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX } while (BN_is_zero(k)); + /* We do not want timing information to leak the length of k, + * so we compute G*k using an equivalent scalar of fixed + * bit-length. */ + + if (!BN_add(k, k, order)) goto err; + if (BN_num_bits(k) <= BN_num_bits(order)) + if (!BN_add(k, k, order)) goto err; + /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { Index: crypto/openssl/crypto/evp/evp_test.c =================================================================== --- crypto/openssl/crypto/evp/evp_test.c (revision 248771) +++ crypto/openssl/crypto/evp/evp_test.c (working copy) @@ -435,6 +435,7 @@ int main(int argc,char **argv) EXIT(3); } } + fclose(f); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); Index: crypto/openssl/crypto/o_init.c =================================================================== --- crypto/openssl/crypto/o_init.c (revision 248771) +++ crypto/openssl/crypto/o_init.c (working copy) @@ -93,4 +93,18 @@ void OPENSSL_init(void) #endif } +#ifdef OPENSSL_FIPS +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) + { + size_t i; + const unsigned char *a = in_a; + const unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; + } +#endif Index: crypto/openssl/crypto/ocsp/ocsp_lib.c =================================================================== --- crypto/openssl/crypto/ocsp/ocsp_lib.c (revision 248771) +++ crypto/openssl/crypto/ocsp/ocsp_lib.c (working copy) @@ -169,14 +169,14 @@ int OCSP_parse_url(char *url, char **phost, char * char *host, *port; + *phost = NULL; + *pport = NULL; + *ppath = NULL; + /* dup the buffer since we are going to mess with it */ buf = BUF_strdup(url); if (!buf) goto mem_err; - *phost = NULL; - *pport = NULL; - *ppath = NULL; - /* Check for initial colon */ p = strchr(buf, ':'); Index: crypto/openssl/crypto/ocsp/ocsp_vfy.c =================================================================== --- crypto/openssl/crypto/ocsp/ocsp_vfy.c (revision 248771) +++ crypto/openssl/crypto/ocsp/ocsp_vfy.c (working copy) @@ -91,10 +91,13 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF { EVP_PKEY *skey; skey = X509_get_pubkey(signer); - ret = OCSP_BASICRESP_verify(bs, skey, 0); - EVP_PKEY_free(skey); - if(ret <= 0) + if (skey) { + ret = OCSP_BASICRESP_verify(bs, skey, 0); + EVP_PKEY_free(skey); + } + if(!skey || ret <= 0) + { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); goto end; } @@ -108,6 +111,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs); if(!init_res) { + ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB); goto end; } Index: crypto/openssl/crypto/opensslv.h =================================================================== --- crypto/openssl/crypto/opensslv.h (revision 248771) +++ crypto/openssl/crypto/opensslv.h (working copy) @@ -25,11 +25,11 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x0090811f +#define OPENSSL_VERSION_NUMBER 0x0090819fL #ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q-fips 2 Dec 2010" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8y-fips 5 Feb 2013" #else -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q 2 Dec 2010" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8y 5 Feb 2013" #endif #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT @@ -83,7 +83,7 @@ * should only keep the versions that are binary compatible with the current. */ #define SHLIB_VERSION_HISTORY "" -#define SHLIB_VERSION_NUMBER "0.9.8" +#define SHLIB_VERSION_NUMBER "6" #endif /* HEADER_OPENSSLV_H */ Index: crypto/openssl/crypto/perlasm/cbc.pl =================================================================== --- crypto/openssl/crypto/perlasm/cbc.pl (revision 248771) +++ crypto/openssl/crypto/perlasm/cbc.pl (working copy) @@ -158,7 +158,6 @@ sub cbc &jmp_ptr($count); &set_label("ej7"); - &xor("edx", "edx") if $ppro; # ppro friendly &movb(&HB("edx"), &BP(6,$in,"",0)); &shl("edx",8); &set_label("ej6"); @@ -170,7 +169,6 @@ sub cbc &jmp(&label("ejend")); &set_label("ej3"); &movb(&HB("ecx"), &BP(2,$in,"",0)); - &xor("ecx", "ecx") if $ppro; # ppro friendly &shl("ecx",8); &set_label("ej2"); &movb(&HB("ecx"), &BP(1,$in,"",0)); Index: crypto/openssl/crypto/pkcs7/pk7_smime.c =================================================================== --- crypto/openssl/crypto/pkcs7/pk7_smime.c (revision 248771) +++ crypto/openssl/crypto/pkcs7/pk7_smime.c (working copy) @@ -486,15 +486,34 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 return 0; } ret = SMIME_text(bread, data); + if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) + { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } BIO_free_all(bread); return ret; } else { for(;;) { i = BIO_read(tmpmem, buf, sizeof(buf)); - if(i <= 0) break; - BIO_write(data, buf, i); + if(i <= 0) + { + ret = 1; + if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) + { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + + break; + } + if (BIO_write(data, buf, i) != i) + { + ret = 0; + break; + } } BIO_free_all(tmpmem); - return 1; + return ret; } } Index: crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl =================================================================== --- crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl (revision 248771) +++ crypto/openssl/crypto/rc4/asm/rc4-x86_64.pl (working copy) @@ -167,7 +167,7 @@ $code.=<<___; movzb ($dat,$XX[0]),$TX[0]#d test \$-8,$len jz .Lcloop1 - cmp \$0,260($dat) + cmpl \$0,260($dat) jnz .Lcloop1 push %rbx jmp .Lcloop8 Index: crypto/openssl/crypto/rc4/rc4_skey.c =================================================================== --- crypto/openssl/crypto/rc4/rc4_skey.c (revision 248771) +++ crypto/openssl/crypto/rc4/rc4_skey.c (working copy) @@ -138,9 +138,9 @@ void RC4_set_key(RC4_KEY *key, int len, const unsi */ #ifdef OPENSSL_FIPS unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); - if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { + if (ia32cap_ptr && (*ia32cap_ptr & (1<<20))) { #else - if (OPENSSL_ia32cap_P & (1<<28)) { + if (OPENSSL_ia32cap_P & (1<<20)) { #endif unsigned char *cp=(unsigned char *)d; Index: crypto/openssl/crypto/rsa/rsa_eay.c =================================================================== --- crypto/openssl/crypto/rsa/rsa_eay.c (revision 248771) +++ crypto/openssl/crypto/rsa/rsa_eay.c (working copy) @@ -312,51 +312,56 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int return ret; } -static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, - BIGNUM *r, BN_CTX *ctx) -{ - if (local) +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) + { + if (unblind == NULL) + /* Local blinding: store the unblinding factor + * in BN_BLINDING. */ return BN_BLINDING_convert_ex(f, NULL, b, ctx); else { + /* Shared blinding: store the unblinding factor + * outside BN_BLINDING. */ int ret; - CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); - ret = BN_BLINDING_convert_ex(f, r, b, ctx); - CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING); - return ret; - } -} - -static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, - BIGNUM *r, BN_CTX *ctx) -{ - if (local) - return BN_BLINDING_invert_ex(f, NULL, b, ctx); - else - { - int ret; CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); - ret = BN_BLINDING_invert_ex(f, r, b, ctx); + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); return ret; } -} + } +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) + { + /* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex + * will use the unblinding factor stored in BN_BLINDING. + * If BN_BLINDING is shared between threads, unblind must be non-null: + * BN_BLINDING_invert_ex will then use the local unblinding factor, + * and will only read the modulus from BN_BLINDING. + * In both cases it's safe to access the blinding without a lock. + */ + return BN_BLINDING_invert_ex(f, unblind, b, ctx); + } + /* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - BIGNUM *f, *ret, *br, *res; + BIGNUM *f, *ret, *res; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; + /* Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. */ + BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); - br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); @@ -404,8 +409,15 @@ static int RSA_eay_private_encrypt(int flen, const } if (blinding != NULL) - if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && @@ -439,7 +451,7 @@ static int RSA_eay_private_encrypt(int flen, const } if (blinding) - if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) @@ -478,18 +490,21 @@ err: static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - BIGNUM *f, *ret, *br; + BIGNUM *f, *ret; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; + /* Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. */ + BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); - br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); @@ -527,8 +542,15 @@ static int RSA_eay_private_decrypt(int flen, const } if (blinding != NULL) - if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || @@ -562,7 +584,7 @@ static int RSA_eay_private_decrypt(int flen, const } if (blinding) - if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p=buf; Index: crypto/openssl/crypto/rsa/rsa_oaep.c =================================================================== --- crypto/openssl/crypto/rsa/rsa_oaep.c (revision 248771) +++ crypto/openssl/crypto/rsa/rsa_oaep.c (working copy) @@ -143,7 +143,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL); - if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) + if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) goto decoding_err; else { Index: crypto/openssl/crypto/symhacks.h =================================================================== --- crypto/openssl/crypto/symhacks.h (revision 248771) +++ crypto/openssl/crypto/symhacks.h (working copy) @@ -252,15 +252,15 @@ #define EC_POINT_set_compressed_coordinates_GF2m \ EC_POINT_set_compr_coords_GF2m #undef ec_GF2m_simple_group_clear_finish -#define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +#define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish #undef ec_GF2m_simple_group_check_discriminant #define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim #undef ec_GF2m_simple_point_clear_finish -#define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +#define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish #undef ec_GF2m_simple_point_set_to_infinity -#define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +#define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf #undef ec_GF2m_simple_points_make_affine -#define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +#define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine #undef ec_GF2m_simple_point_set_affine_coordinates #define ec_GF2m_simple_point_set_affine_coordinates \ ec_GF2m_smp_pt_set_af_coords @@ -288,8 +288,6 @@ #define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf #undef ec_GFp_simple_points_make_affine #define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine -#undef ec_GFp_simple_group_get_curve_GFp -#define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp #undef ec_GFp_simple_set_Jprojective_coordinates_GFp #define ec_GFp_simple_set_Jprojective_coordinates_GFp \ ec_GFp_smp_set_Jproj_coords_GFp Index: crypto/openssl/crypto/x509/x509_vfy.c =================================================================== --- crypto/openssl/crypto/x509/x509_vfy.c (revision 248771) +++ crypto/openssl/crypto/x509/x509_vfy.c (working copy) @@ -1097,7 +1097,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time atm.length=sizeof(buff2); atm.data=(unsigned char *)buff2; - if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) + if (X509_time_adj(&atm, offset*60, cmp_time) == NULL) return 0; if (ctm->type == V_ASN1_UTCTIME) Index: crypto/openssl/crypto/x509v3/v3_addr.c =================================================================== --- crypto/openssl/crypto/x509v3/v3_addr.c (revision 248771) +++ crypto/openssl/crypto/x509v3/v3_addr.c (working copy) @@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAddressFamily * Expand the bitstring form of an address into a raw byte array. * At the moment this is coded for simplicity, not speed. */ -static void addr_expand(unsigned char *addr, +static int addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, const unsigned char fill) { - OPENSSL_assert(bs->length >= 0 && bs->length <= length); + if (bs->length < 0 || bs->length > length) + return 0; if (bs->length > 0) { memcpy(addr, bs->data, bs->length); if ((bs->flags & 7) != 0) { @@ -159,6 +160,7 @@ unsigned int v3_addr_get_afi(const IPAddressFamily } } memset(addr + bs->length, fill, length - bs->length); + return 1; } /* @@ -177,13 +179,17 @@ static int i2r_address(BIO *out, unsigned char addr[ADDR_RAW_BUF_LEN]; int i, n; + if (bs->length < 0) + return 0; switch (afi) { case IANA_AFI_IPV4: - addr_expand(addr, bs, 4, fill); + if (!addr_expand(addr, bs, 4, fill)) + return 0; BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); break; case IANA_AFI_IPV6: - addr_expand(addr, bs, 16, fill); + if (!addr_expand(addr, bs, 16, fill)) + return 0; for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2) ; for (i = 0; i < n; i += 2) @@ -309,6 +315,12 @@ static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *met /* * Sort comparison function for a sequence of IPAddressOrRange * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. */ static int IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, @@ -321,22 +333,26 @@ static int IPAddressOrRange_cmp(const IPAddressOrR switch (a->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_a, a->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; prefixlen_a = addr_prefixlen(a->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_a, a->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; prefixlen_a = length * 8; break; } switch (b->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_b, b->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; prefixlen_b = addr_prefixlen(b->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_b, b->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; prefixlen_b = length * 8; break; } @@ -378,6 +394,7 @@ static int range_should_be_prefix(const unsigned c unsigned char mask; int i, j; + OPENSSL_assert(memcmp(min, max, length) <= 0); for (i = 0; i < length && min[i] == max[i]; i++) ; for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) @@ -651,22 +668,22 @@ int v3_addr_add_range(IPAddrBlocks *addr, /* * Extract min and max values from an IPAddressOrRange. */ -static void extract_min_max(IPAddressOrRange *aor, +static int extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, int length) { - OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + if (aor == NULL || min == NULL || max == NULL) + return 0; switch (aor->type) { case IPAddressOrRange_addressPrefix: - addr_expand(min, aor->u.addressPrefix, length, 0x00); - addr_expand(max, aor->u.addressPrefix, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && + addr_expand(max, aor->u.addressPrefix, length, 0xFF)); case IPAddressOrRange_addressRange: - addr_expand(min, aor->u.addressRange->min, length, 0x00); - addr_expand(max, aor->u.addressRange->max, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && + addr_expand(max, aor->u.addressRange->max, length, 0xFF)); } + return 0; } /* @@ -682,9 +699,10 @@ int v3_addr_get_range(IPAddressOrRange *aor, if (aor == NULL || min == NULL || max == NULL || afi_length == 0 || length < afi_length || (aor->type != IPAddressOrRange_addressPrefix && - aor->type != IPAddressOrRange_addressRange)) + aor->type != IPAddressOrRange_addressRange) || + !extract_min_max(aor, min, max, afi_length)) return 0; - extract_min_max(aor, min, max, afi_length); + return afi_length; } @@ -766,8 +784,9 @@ int v3_addr_is_canonical(IPAddrBlocks *addr) IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; /* * Punt misordered list, overlapping start, or inverted range. @@ -795,15 +814,18 @@ int v3_addr_is_canonical(IPAddrBlocks *addr) } /* - * Check final range to see if it should be a prefix. + * Check range to see if it's inverted or should be a + * prefix. */ j = sk_IPAddressOrRange_num(aors) - 1; { IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); - if (a->type == IPAddressOrRange_addressRange) { - extract_min_max(a, a_min, a_max, length); - if (range_should_be_prefix(a_min, a_max, length) >= 0) + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(a, a_min, a_max, length)) return 0; + if (memcmp(a_min, a_max, length) > 0 || + range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; } } } @@ -836,10 +858,18 @@ static int IPAddressOrRanges_canonize(IPAddressOrR unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; /* + * Punt inverted ranges. + */ + if (memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* * Punt overlaps. */ if (memcmp(a_max, b_min, length) >= 0) @@ -864,6 +894,20 @@ static int IPAddressOrRanges_canonize(IPAddressOrR } } + /* + * Check for inverted final range. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + extract_min_max(a, a_min, a_max, length); + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + } + return 1; } @@ -1012,6 +1056,11 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method X509V3_conf_err(val); goto err; } + if (memcmp(min, max, length_from_afi(afi)) > 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } if (!v3_addr_add_range(addr, afi, safi, min, max)) { X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); goto err; @@ -1097,13 +1146,15 @@ static int addr_contains(IPAddressOrRanges *parent p = 0; for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - extract_min_max(sk_IPAddressOrRange_value(child, c), - c_min, c_max, length); + if (!extract_min_max(sk_IPAddressOrRange_value(child, c), + c_min, c_max, length)) + return -1; for (;; p++) { if (p >= sk_IPAddressOrRange_num(parent)) return 0; - extract_min_max(sk_IPAddressOrRange_value(parent, p), - p_min, p_max, length); + if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), + p_min, p_max, length)) + return 0; if (memcmp(p_max, c_max, length) < 0) continue; if (memcmp(p_min, c_min, length) > 0) Index: crypto/openssl/crypto/x509v3/v3_asid.c =================================================================== --- crypto/openssl/crypto/x509v3/v3_asid.c (revision 248771) +++ crypto/openssl/crypto/x509v3/v3_asid.c (working copy) @@ -61,7 +61,6 @@ #include #include -#include #include "cryptlib.h" #include #include @@ -172,11 +171,11 @@ static int ASIdOrRange_cmp(const ASIdOrRange * con { const ASIdOrRange *a = *a_, *b = *b_; - assert((a->type == ASIdOrRange_id && a->u.id != NULL) || + OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || (a->type == ASIdOrRange_range && a->u.range != NULL && a->u.range->min != NULL && a->u.range->max != NULL)); - assert((b->type == ASIdOrRange_id && b->u.id != NULL) || + OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || (b->type == ASIdOrRange_range && b->u.range != NULL && b->u.range->min != NULL && b->u.range->max != NULL)); @@ -215,7 +214,7 @@ int v3_asid_add_inherit(ASIdentifiers *asid, int w if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - assert((*choice)->u.inherit == NULL); + OPENSSL_assert((*choice)->u.inherit == NULL); if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) return 0; (*choice)->type = ASIdentifierChoice_inherit; @@ -250,7 +249,7 @@ int v3_asid_add_id_or_range(ASIdentifiers *asid, if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - assert((*choice)->u.asIdsOrRanges == NULL); + OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); if ((*choice)->u.asIdsOrRanges == NULL) return 0; @@ -286,7 +285,7 @@ static void extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max) { - assert(aor != NULL && min != NULL && max != NULL); + OPENSSL_assert(aor != NULL && min != NULL && max != NULL); switch (aor->type) { case ASIdOrRange_id: *min = aor->u.id; @@ -359,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdent goto done; } + /* + * Check for inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + ret = 1; done: @@ -373,7 +386,7 @@ static int ASIdentifierChoice_is_canonical(ASIdent int v3_asid_is_canonical(ASIdentifiers *asid) { return (asid == NULL || - (ASIdentifierChoice_is_canonical(asid->asnum) || + (ASIdentifierChoice_is_canonical(asid->asnum) && ASIdentifierChoice_is_canonical(asid->rdi))); } @@ -393,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifie return 1; /* - * We have a list. Sort it. + * If not a list, or if empty list, it's broken. */ - assert(choice->type == ASIdentifierChoice_asIdsOrRanges); + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + return 0; + } + + /* + * We have a non-empty list. Sort it. + */ sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); /* @@ -413,9 +435,16 @@ static int ASIdentifierChoice_canonize(ASIdentifie /* * Make sure we're properly sorted (paranoia). */ - assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); /* + * Punt inverted ranges. + */ + if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* * Check for overlaps. */ if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { @@ -466,14 +495,28 @@ static int ASIdentifierChoice_canonize(ASIdentifie break; } ASIdOrRange_free(b); - (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); + (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); i--; continue; } } - assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + /* + * Check for final inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + ret = 1; done: @@ -499,6 +542,7 @@ static void *v2i_ASIdentifiers(struct v3_ext_metho struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values) { + ASN1_INTEGER *min = NULL, *max = NULL; ASIdentifiers *asid = NULL; int i; @@ -509,7 +553,6 @@ static void *v2i_ASIdentifiers(struct v3_ext_metho for (i = 0; i < sk_CONF_VALUE_num(values); i++) { CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - ASN1_INTEGER *min = NULL, *max = NULL; int i1, i2, i3, is_range, which; /* @@ -579,18 +622,19 @@ static void *v2i_ASIdentifiers(struct v3_ext_metho max = s2i_ASN1_INTEGER(NULL, s + i2); OPENSSL_free(s); if (min == NULL || max == NULL) { - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); goto err; } + if (ASN1_INTEGER_cmp(min, max) > 0) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, X509V3_R_EXTENSION_VALUE_ERROR); + goto err; + } } if (!v3_asid_add_id_or_range(asid, which, min, max)) { - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); goto err; } + min = max = NULL; } /* @@ -602,6 +646,8 @@ static void *v2i_ASIdentifiers(struct v3_ext_metho err: ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); return NULL; } @@ -709,9 +755,9 @@ static int v3_asid_validate_path_internal(X509_STO int i, ret = 1, inherit_as = 0, inherit_rdi = 0; X509 *x = NULL; - assert(chain != NULL && sk_X509_num(chain) > 0); - assert(ctx != NULL || ext != NULL); - assert(ctx == NULL || ctx->verify_cb != NULL); + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); /* * Figure out where to start. If we don't have an extension to @@ -723,7 +769,7 @@ static int v3_asid_validate_path_internal(X509_STO } else { i = 0; x = sk_X509_value(chain, i); - assert(x != NULL); + OPENSSL_assert(x != NULL); if ((ext = x->rfc3779_asid) == NULL) goto done; } @@ -756,7 +802,7 @@ static int v3_asid_validate_path_internal(X509_STO */ for (i++; i < sk_X509_num(chain); i++) { x = sk_X509_value(chain, i); - assert(x != NULL); + OPENSSL_assert(x != NULL); if (x->rfc3779_asid == NULL) { if (child_as != NULL || child_rdi != NULL) validation_err(X509_V_ERR_UNNESTED_RESOURCE); Index: crypto/openssl/doc/HOWTO/proxy_certificates.txt =================================================================== --- crypto/openssl/doc/HOWTO/proxy_certificates.txt (revision 248771) +++ crypto/openssl/doc/HOWTO/proxy_certificates.txt (working copy) @@ -57,7 +57,7 @@ following methods: - in all other cases, proxy certificate validation can be enabled before starting the application by setting the envirnoment variable - OPENSSL_ALLOW_PROXY with some non-empty value. + OPENSSL_ALLOW_PROXY_CERTS with some non-empty value. There are thoughts to allow proxy certificates with a line in the default openssl.cnf, but that's still in the future. Index: crypto/openssl/doc/apps/CA.pl.pod =================================================================== --- crypto/openssl/doc/apps/CA.pl.pod (revision 248771) +++ crypto/openssl/doc/apps/CA.pl.pod (working copy) @@ -39,13 +39,13 @@ prints a usage message. =item B<-newcert> -creates a new self signed certificate. The private key and certificate are -written to the file "newreq.pem". +creates a new self signed certificate. The private key is written to the file +"newkey.pem" and the request written to the file "newreq.pem". =item B<-newreq> -creates a new certificate request. The private key and request are -written to the file "newreq.pem". +creates a new certificate request. The private key is written to the file +"newkey.pem" and the request written to the file "newreq.pem". =item B<-newreq-nodes> Index: crypto/openssl/doc/apps/ca.pod =================================================================== --- crypto/openssl/doc/apps/ca.pod (revision 248771) +++ crypto/openssl/doc/apps/ca.pod (working copy) @@ -88,7 +88,7 @@ section for information on the required format. =item B<-infiles> if present this should be the last option, all subsequent arguments -are assumed to the the names of files containing certificate requests. +are assumed to be the names of files containing certificate requests. =item B<-out filename> Index: crypto/openssl/doc/apps/dgst.pod =================================================================== --- crypto/openssl/doc/apps/dgst.pod (revision 248771) +++ crypto/openssl/doc/apps/dgst.pod (working copy) @@ -68,7 +68,7 @@ see the B section in L -verify the signature using the the public key in "filename". +verify the signature using the public key in "filename". The output is either "Verification OK" or "Verification Failure". =item B<-prverify filename> Index: crypto/openssl/doc/crypto/engine.pod =================================================================== --- crypto/openssl/doc/crypto/engine.pod (revision 248771) +++ crypto/openssl/doc/crypto/engine.pod (working copy) @@ -517,7 +517,7 @@ implemented by ENGINEs should be numbered from. An this symbol is considered a "generic" command is handled directly by the OpenSSL core routines. -It is using these "core" control commands that one can discover the the control +It is using these "core" control commands that one can discover the control commands implemented by a given ENGINE, specifically the commands; #define ENGINE_HAS_CTRL_FUNCTION 10 Index: crypto/openssl/doc/ssl/SSL_clear.pod =================================================================== --- crypto/openssl/doc/ssl/SSL_clear.pod (revision 248771) +++ crypto/openssl/doc/ssl/SSL_clear.pod (working copy) @@ -39,10 +39,16 @@ for a description of the method's properties. SSL_clear() resets the SSL object to allow for another connection. The reset operation however keeps several settings of the last sessions (some of these settings were made automatically during the last -handshake). It only makes sense when opening a new session (or reusing -an old one) with the same peer that shares these settings. -SSL_clear() is not a short form for the sequence -L; L; . +handshake). It only makes sense for a new connection with the exact +same peer that shares these settings, and may fail if that peer +changes its settings between connections. Use the sequence +L; +L; +L; +L +instead to avoid such failures +(or simply L; L +if session reuse is not desired). =head1 RETURN VALUES Index: crypto/openssl/engines/e_capi.c =================================================================== --- crypto/openssl/engines/e_capi.c (revision 248771) +++ crypto/openssl/engines/e_capi.c (working copy) @@ -420,29 +420,37 @@ static int capi_init(ENGINE *e) CAPI_CTX *ctx; const RSA_METHOD *ossl_rsa_meth; const DSA_METHOD *ossl_dsa_meth; - capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); - cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); + if (capi_idx < 0) + { + capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); + if (capi_idx < 0) + goto memerr; + + cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); + + /* Setup RSA_METHOD */ + rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_rsa_meth = RSA_PKCS1_SSLeay(); + capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; + capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; + capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; + capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; + + /* Setup DSA Method */ + dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_dsa_meth = DSA_OpenSSL(); + capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; + capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; + capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; + } + ctx = capi_ctx_new(); - if (!ctx || (capi_idx < 0)) + if (!ctx) goto memerr; ENGINE_set_ex_data(e, capi_idx, ctx); - /* Setup RSA_METHOD */ - rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_rsa_meth = RSA_PKCS1_SSLeay(); - capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; - capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; - capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; - capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; - /* Setup DSA Method */ - dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_dsa_meth = DSA_OpenSSL(); - capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; - capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; - capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; - #ifdef OPENSSL_CAPIENG_DIALOG { HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); @@ -1133,6 +1141,7 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO { CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); capi_addlasterror(); + CryptReleaseContext(hprov, 0); return 0; } CAPI_trace(ctx, "Got max container len %d\n", buflen); @@ -1400,10 +1409,13 @@ static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec) { CAPI_KEY *key; + DWORD dwFlags = 0; key = OPENSSL_malloc(sizeof(CAPI_KEY)); CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", contname, provname, ptype); - if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0)) + if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) + dwFlags = CRYPT_MACHINE_KEYSET; + if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, dwFlags)) { CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); capi_addlasterror(); @@ -1550,6 +1562,8 @@ static int capi_ctx_set_provname(CAPI_CTX *ctx, LP } CryptReleaseContext(hprov, 0); } + if (ctx->cspname) + OPENSSL_free(ctx->cspname); ctx->cspname = BUF_strdup(pname); ctx->csptype = type; return 1; @@ -1559,9 +1573,12 @@ static int capi_ctx_set_provname_idx(CAPI_CTX *ctx { LPSTR pname; DWORD type; + int res; if (capi_get_provname(ctx, &pname, &type, idx) != 1) return 0; - return capi_ctx_set_provname(ctx, pname, type, 0); + res = capi_ctx_set_provname(ctx, pname, type, 0); + OPENSSL_free(pname); + return res; } static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) Index: crypto/openssl/engines/e_capi_err.h =================================================================== --- crypto/openssl/engines/e_capi_err.h (revision 248771) +++ crypto/openssl/engines/e_capi_err.h (working copy) @@ -55,6 +55,10 @@ #ifndef HEADER_CAPI_ERR_H #define HEADER_CAPI_ERR_H +#ifdef __cplusplus +extern "C" { +#endif + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. Index: crypto/openssl/fips/fips_canister.c =================================================================== --- crypto/openssl/fips/fips_canister.c (revision 248771) +++ crypto/openssl/fips/fips_canister.c (working copy) @@ -19,6 +19,7 @@ (defined(__linux) && (defined(__arm) || defined(__arm__))) || \ (defined(__i386) || defined(__i386__)) || \ (defined(__x86_64) || defined(__x86_64__)) || \ + defined(__ANDROID__) || \ (defined(vax) || defined(__vax__)) # define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION # endif Index: crypto/openssl/openssl.spec =================================================================== --- crypto/openssl/openssl.spec (revision 248771) +++ crypto/openssl/openssl.spec (working copy) @@ -2,7 +2,7 @@ %define libmaj 0 %define libmin 9 %define librel 8 -%define librev q +%define librev y Release: 1 %define openssldir /var/ssl Index: crypto/openssl/ssl/Makefile =================================================================== --- crypto/openssl/ssl/Makefile (revision 248771) +++ crypto/openssl/ssl/Makefile (working copy) @@ -22,7 +22,7 @@ LIB=$(TOP)/libssl.a SHARED_LIB= libssl$(SHLIB_EXT) LIBSRC= \ s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ - s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ + s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \ s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ @@ -33,7 +33,7 @@ LIBSRC= \ bio_ssl.c ssl_err.c kssl.c t1_reneg.c LIBOBJ= \ s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ - s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ + s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \ s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ @@ -545,6 +545,27 @@ s3_both.o: ../include/openssl/ssl23.h ../include/o s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h +s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h +s3_cbc.o: ../include/openssl/bn.h ../include/openssl/buffer.h +s3_cbc.o: ../include/openssl/comp.h ../include/openssl/crypto.h +s3_cbc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h +s3_cbc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h +s3_cbc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h +s3_cbc.o: ../include/openssl/err.h ../include/openssl/evp.h +s3_cbc.o: ../include/openssl/fips.h ../include/openssl/hmac.h +s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h +s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h +s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h +s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h +s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h +s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h +s3_cbc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h +s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h +s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h +s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h +s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h +s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h +s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h Index: crypto/openssl/ssl/bio_ssl.c =================================================================== --- crypto/openssl/ssl/bio_ssl.c (revision 248771) +++ crypto/openssl/ssl/bio_ssl.c (working copy) @@ -348,7 +348,11 @@ static long ssl_ctrl(BIO *b, int cmd, long num, vo break; case BIO_C_SET_SSL: if (ssl != NULL) + { ssl_free(b); + if (!ssl_new(b)) + return 0; + } b->shutdown=(int)num; ssl=(SSL *)ptr; ((BIO_SSL *)b->ptr)->ssl=ssl; Index: crypto/openssl/ssl/d1_both.c =================================================================== --- crypto/openssl/ssl/d1_both.c (revision 248771) +++ crypto/openssl/ssl/d1_both.c (working copy) @@ -153,12 +153,11 @@ #endif static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; -static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; +static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; /* XDTLS: figure out the right values */ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; -static unsigned int dtls1_min_mtu(void); static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len); @@ -228,14 +227,14 @@ int dtls1_do_write(SSL *s, int type) unsigned int len, frag_off, mac_size, blocksize; /* AHA! Figure out the MTU, and stick to the right size */ - if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) + if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); /* I've seen the kernel return bogus numbers when it doesn't know * (initial write), so just make sure we have a reasonable number */ - if ( s->d1->mtu < dtls1_min_mtu()) + if (s->d1->mtu < dtls1_min_mtu()) { s->d1->mtu = 0; s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); @@ -264,11 +263,10 @@ int dtls1_do_write(SSL *s, int type) return ret; mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); } +#endif - OPENSSL_assert(mtu > 0); /* should have something reasonable now */ + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */ -#endif - if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) OPENSSL_assert(s->init_num == (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); @@ -464,20 +462,9 @@ again: memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - s->d1->handshake_read_seq++; - /* we just read a handshake message from the other side: - * this means that we don't need to retransmit of the - * buffered messages. - * XDTLS: may be able clear out this - * buffer a little sooner (i.e if an out-of-order - * handshake message/record is received at the record - * layer. - * XDTLS: exception is that the server needs to - * know that change cipher spec and finished messages - * have been received by the client before clearing this - * buffer. this can simply be done by waiting for the - * first data segment, but is there a better way? */ - dtls1_clear_record_buffer(s); + /* Don't change sequence numbers while listening */ + if (!s->d1->listen) + s->d1->handshake_read_seq++; s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; @@ -806,16 +793,24 @@ dtls1_get_message_fragment(SSL *s, int st1, int st *ok = 0; return i; } - OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); + /* Handshake fails if message header is incomplete */ + if (i != DTLS1_HM_HEADER_LENGTH) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } /* parse the message fragment header */ dtls1_get_message_header(wire, &msg_hdr); /* * if this is a future (or stale) message it gets buffered - * (or dropped)--no further processing at this time + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) */ - if ( msg_hdr.seq != s->d1->handshake_read_seq) + if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1)) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); len = msg_hdr.msg_len; @@ -876,7 +871,12 @@ dtls1_get_message_fragment(SSL *s, int st1, int st /* XDTLS: an incorrectly formatted fragment should cause the * handshake to fail */ - OPENSSL_assert(i == (int)frag_len); + if (i != (int)frag_len) + { + al=SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER); + goto f_err; + } *ok = 1; @@ -1326,7 +1326,8 @@ unsigned char * dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, unsigned long len, unsigned long frag_off, unsigned long frag_len) { - if ( frag_off == 0) + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; s->d1->next_handshake_write_seq++; @@ -1379,7 +1380,7 @@ dtls1_write_message_header(SSL *s, unsigned char * return p; } -static unsigned int +unsigned int dtls1_min_mtu(void) { return (g_probable_mtu[(sizeof(g_probable_mtu) / Index: crypto/openssl/ssl/d1_clnt.c =================================================================== --- crypto/openssl/ssl/d1_clnt.c (revision 248771) +++ crypto/openssl/ssl/d1_clnt.c (working copy) @@ -257,7 +257,6 @@ int dtls1_connect(SSL *s) if (ret <= 0) goto end; else { - dtls1_stop_timer(s); if (s->hit) s->state=SSL3_ST_CR_FINISHED_A; else @@ -350,6 +349,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CR_SRVR_DONE_B: ret=ssl3_get_server_done(s); if (ret <= 0) goto end; + dtls1_stop_timer(s); if (s->s3->tmp.cert_req) s->state=SSL3_ST_CW_CERT_A; else @@ -403,7 +403,8 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: - dtls1_start_timer(s); + if (!s->hit) + dtls1_start_timer(s); ret=dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; @@ -438,7 +439,8 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: - dtls1_start_timer(s); + if (!s->hit) + dtls1_start_timer(s); ret=dtls1_send_finished(s, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, s->method->ssl3_enc->client_finished_label, Index: crypto/openssl/ssl/d1_enc.c =================================================================== --- crypto/openssl/ssl/d1_enc.c (revision 248771) +++ crypto/openssl/ssl/d1_enc.c (working copy) @@ -126,16 +126,30 @@ #include #endif +/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. */ int dtls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i,ii,j,k; + int bs,i,j,k,mac_size=0; const EVP_CIPHER *enc; if (send) { + if (s->write_hash) + { + mac_size=EVP_MD_size(s->write_hash); + if (mac_size < 0) + return -1; + } ds=s->enc_write_ctx; rec= &(s->s3->wrec); if (s->enc_write_ctx == NULL) @@ -156,6 +170,11 @@ int dtls1_enc(SSL *s, int send) } else { + if (s->read_hash) + { + mac_size=EVP_MD_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); + } ds=s->enc_read_ctx; rec= &(s->s3->rrec); if (s->enc_read_ctx == NULL) @@ -220,11 +239,7 @@ int dtls1_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - { - SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; - } } EVP_Cipher(ds,rec->data,rec->input,l); @@ -239,43 +254,7 @@ int dtls1_enc(SSL *s, int send) #endif /* KSSL_DEBUG */ if ((bs != 1) && !send) - { - ii=i=rec->data[l-1]; /* padding_length */ - i++; - if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) - { - /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, - "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) - s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - i--; - } - /* TLS 1.0 does not bound the number of padding bytes by the block size. - * All of them must have value 'padding_length'. */ - if (i > (int)rec->length) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) - */ - return -1; - } - for (j=(int)(l-i); j<(int)l; j++) - { - if (rec->data[j] != ii) - { - /* Incorrect padding */ - return -1; - } - } - rec->length-=i; - - rec->data += bs; /* skip the implicit IV */ - rec->input += bs; - rec->length -= bs; - } + return tls1_cbc_remove_padding(s, rec, bs, mac_size); } return(1); } Index: crypto/openssl/ssl/d1_lib.c =================================================================== --- crypto/openssl/ssl/d1_lib.c (revision 248771) +++ crypto/openssl/ssl/d1_lib.c (working copy) @@ -145,26 +145,33 @@ int dtls1_new(SSL *s) return(1); } -void dtls1_free(SSL *s) +static void dtls1_clear_queues(SSL *s) { pitem *item = NULL; hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; - ssl3_free(s); - while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + if (rdata->rbuf.buf) + { + OPENSSL_free(rdata->rbuf.buf); + } OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(s->d1->unprocessed_rcds.q); while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + if (rdata->rbuf.buf) + { + OPENSSL_free(rdata->rbuf.buf); + } OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(s->d1->processed_rcds.q); while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) { @@ -173,7 +180,6 @@ int dtls1_new(SSL *s) OPENSSL_free(frag); pitem_free(item); } - pqueue_free(s->d1->buffered_messages); while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) { @@ -182,15 +188,26 @@ int dtls1_new(SSL *s) OPENSSL_free(frag); pitem_free(item); } - pqueue_free(s->d1->sent_messages); while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) - { + { frag = (hm_fragment *)item->data; OPENSSL_free(frag->fragment); OPENSSL_free(frag); pitem_free(item); + } } + +void dtls1_free(SSL *s) + { + ssl3_free(s); + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->processed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); pqueue_free(s->d1->buffered_app_data.q); pq_64bit_free(&(s->d1->bitmap.map)); @@ -204,6 +221,61 @@ int dtls1_new(SSL *s) void dtls1_clear(SSL *s) { + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + + if (s->d1) + { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + processed_rcds = s->d1->processed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + + dtls1_clear_queues(s); + + pq_64bit_free(&(s->d1->bitmap.map)); + pq_64bit_free(&(s->d1->bitmap.max_seq_num)); + + pq_64bit_free(&(s->d1->next_bitmap.map)); + pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); + + memset(s->d1, 0, sizeof(*(s->d1))); + + if (s->server) + { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) + { + s->d1->mtu = mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->processed_rcds.q = processed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + +#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST) + s->d1->bitmap.length=64; +#else + s->d1->bitmap.length=sizeof(s->d1->bitmap.map) * 8; +#endif + pq_64bit_init(&(s->d1->bitmap.map)); + pq_64bit_init(&(s->d1->bitmap.max_seq_num)); + + s->d1->next_bitmap.length = s->d1->bitmap.length; + pq_64bit_init(&(s->d1->next_bitmap.map)); + pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); + } + ssl3_clear(s); if (s->options & SSL_OP_CISCO_ANYCONNECT) s->version=DTLS1_BAD_VER; @@ -349,35 +421,51 @@ void dtls1_double_timeout(SSL *s) void dtls1_stop_timer(SSL *s) { /* Reset everything */ + memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); s->d1->timeout_duration = 1; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_record_buffer(s); } -int dtls1_handle_timeout(SSL *s) +int dtls1_check_timeout_num(SSL *s) { - DTLS1_STATE *state; + s->d1->timeout.num_alerts++; - /* if no timer is expired, don't do anything */ - if (!dtls1_is_timer_expired(s)) + /* Reduce MTU after 2 unsuccessful retransmissions */ + if (s->d1->timeout.num_alerts > 2) { - return 0; + s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); } - dtls1_double_timeout(s); - state = s->d1; - state->timeout.num_alerts++; - if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) + if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED); + SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED); + return -1; + } + + return 0; + } + +int dtls1_handle_timeout(SSL *s) + { + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) + { return 0; } - state->timeout.read_timeouts++; - if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) + dtls1_double_timeout(s); + + if (dtls1_check_timeout_num(s) < 0) + return -1; + + s->d1->timeout.read_timeouts++; + if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { - state->timeout.read_timeouts = 1; + s->d1->timeout.read_timeouts = 1; } dtls1_start_timer(s); Index: crypto/openssl/ssl/d1_pkt.c =================================================================== --- crypto/openssl/ssl/d1_pkt.c (revision 248771) +++ crypto/openssl/ssl/d1_pkt.c (working copy) @@ -139,7 +139,6 @@ static int dtls1_process_record(SSL *s); #if PQ_64BIT_IS_INTEGER static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); #endif -static void dtls1_clear_timeouts(SSL *s); /* copy buffered record into SSL structure */ static int @@ -328,15 +327,13 @@ dtls1_get_buffered_record(SSL *s) static int dtls1_process_record(SSL *s) { - int al; - int clear=0; - int enc_err; + int i,al; + int enc_err; SSL_SESSION *sess; - SSL3_RECORD *rr; - unsigned int mac_size; + SSL3_RECORD *rr; + unsigned int mac_size, orig_len; unsigned char md[EVP_MAX_MD_SIZE]; - rr= &(s->s3->rrec); sess = s->session; @@ -365,15 +362,18 @@ dtls1_process_record(SSL *s) /* decrypt in place in 'rr->input' */ rr->data=rr->input; + orig_len=rr->length; enc_err = s->method->ssl3_enc->enc(s,0); - if (enc_err <= 0) + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { - if (enc_err == 0) - /* SSLerr() and ssl3_send_alert() have been called */ - goto err; - - /* otherwise enc_err == -1 */ + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + s->packet_length = 0; goto err; } @@ -384,44 +384,66 @@ printf("\n"); #endif /* r->length is now the compressed data plus mac */ -if ( (sess == NULL) || - (s->enc_read_ctx == NULL) || - (s->read_hash == NULL)) - clear=1; - - if (!clear) + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && + (s->read_hash != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; mac_size=EVP_MD_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size+1)) { -#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ - al=SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); - goto f_err; -#else - goto err; -#endif - } - /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length < mac_size) - { -#if 0 /* OK only for stream ciphers */ al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; -#else - goto err; -#endif } - rr->length-=mac_size; - s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - goto err; + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; } + else + { + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i=s->method->ssl3_enc->mac(s,md,0 /* not send */); + if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) + enc_err = -1; } + if (enc_err < 0) + { + /* decryption failed, silently discard message */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + /* r->length is now just compressed */ if (s->expand != NULL) { @@ -615,10 +637,12 @@ again: /* If this record is from the next epoch (either HM or ALERT), * and a handshake is currently in progress, buffer it since it - * cannot be processed at this time. */ + * cannot be processed at this time. However, do not buffer + * anything while listening. + */ if (is_next_epoch) { - if (SSL_in_init(s) || s->in_handshake) + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); } @@ -634,7 +658,6 @@ again: goto again; /* get another record */ } - dtls1_clear_timeouts(s); /* done waiting */ return(1); } @@ -1103,6 +1126,9 @@ start: */ if (msg_hdr.type == SSL3_MT_FINISHED) { + if (dtls1_check_timeout_num(s) < 0) + return -1; + dtls1_retransmit_buffered_messages(s); rr->length = 0; goto start; @@ -1806,10 +1832,3 @@ bytes_to_long_long(unsigned char *bytes, PQ_64BIT return _num; } #endif - - -static void -dtls1_clear_timeouts(SSL *s) - { - memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st)); - } Index: crypto/openssl/ssl/d1_srvr.c =================================================================== --- crypto/openssl/ssl/d1_srvr.c (revision 248771) +++ crypto/openssl/ssl/d1_srvr.c (working copy) @@ -148,6 +148,7 @@ int dtls1_accept(SSL *s) void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; + int listen; RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); @@ -157,11 +158,15 @@ int dtls1_accept(SSL *s) cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; + + listen = s->d1->listen; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); + s->d1->listen = listen; + if (s->cert == NULL) { SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); @@ -271,11 +276,23 @@ int dtls1_accept(SSL *s) s->init_num=0; + /* Reflect ClientHello sequence to remain stateless while listening */ + if (listen) + { + memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); + } + /* If we're just listening, stop here */ - if (s->d1->listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; s->d1->listen = 0; + /* Set expected sequence numbers + * to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; goto end; } @@ -284,7 +301,6 @@ int dtls1_accept(SSL *s) case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - dtls1_start_timer(s); ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; @@ -457,15 +473,16 @@ int dtls1_accept(SSL *s) ret = ssl3_check_client_hello(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); if (ret == 2) + { + dtls1_stop_timer(s); s->state = SSL3_ST_SR_CLNT_HELLO_C; + } else { /* could be sent for a DH cert, even if we * have not asked for it :-) */ ret=ssl3_get_client_certificate(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); s->init_num=0; s->state=SSL3_ST_SR_KEY_EXCH_A; } @@ -475,7 +492,6 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; @@ -497,7 +513,6 @@ int dtls1_accept(SSL *s) /* we should decide if we expected this one */ ret=ssl3_get_cert_verify(s); if (ret <= 0) goto end; - dtls1_stop_timer(s); s->state=SSL3_ST_SR_FINISHED_A; s->init_num=0; @@ -713,9 +728,6 @@ int dtls1_send_hello_verify_request(SSL *s) /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); } /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ @@ -736,7 +748,7 @@ int dtls1_send_server_hello(SSL *s) p=s->s3->server_random; Time=(unsigned long)time(NULL); /* Time */ l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); + RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4); /* Do the message type and length last */ d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); Index: crypto/openssl/ssl/s2_clnt.c =================================================================== --- crypto/openssl/ssl/s2_clnt.c (revision 248771) +++ crypto/openssl/ssl/s2_clnt.c (working copy) @@ -935,7 +935,7 @@ static int get_server_verify(SSL *s) s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ p += 1; - if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) + if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); Index: crypto/openssl/ssl/s2_pkt.c =================================================================== --- crypto/openssl/ssl/s2_pkt.c (revision 248771) +++ crypto/openssl/ssl/s2_pkt.c (working copy) @@ -267,8 +267,7 @@ static int ssl2_read_internal(SSL *s, void *buf, i s->s2->ract_data_length-=mac_size; ssl2_mac(s,mac,0); s->s2->ract_data_length-=s->s2->padding; - if ( (memcmp(mac,s->s2->mac_data, - (unsigned int)mac_size) != 0) || + if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) || (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); Index: crypto/openssl/ssl/s2_srvr.c =================================================================== --- crypto/openssl/ssl/s2_srvr.c (revision 248771) +++ crypto/openssl/ssl/s2_srvr.c (working copy) @@ -403,13 +403,14 @@ static int get_client_master_key(SSL *s) p+=3; n2s(p,i); s->s2->tmp.clear=i; n2s(p,i); s->s2->tmp.enc=i; - n2s(p,i); s->session->key_arg_length=i; - if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH) + n2s(p,i); + if(i > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); return -1; } + s->session->key_arg_length=i; s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; } Index: crypto/openssl/ssl/s3_both.c =================================================================== --- crypto/openssl/ssl/s3_both.c (revision 248771) +++ crypto/openssl/ssl/s3_both.c (working copy) @@ -242,7 +242,7 @@ int ssl3_get_finished(SSL *s, int a, int b) goto f_err; } - if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) + if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); Index: crypto/openssl/ssl/s3_cbc.c =================================================================== --- crypto/openssl/ssl/s3_cbc.c (revision 0) +++ crypto/openssl/ssl/s3_cbc.c (working copy) @@ -0,0 +1,762 @@ +/* ssl/s3_cbc.c */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" + +#include +#include + +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length + * field. (SHA-384/512 have 128-bit length.) */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * supported by TLS.) */ +#define MAX_HASH_BLOCK_SIZE 128 + +/* Some utility functions are needed: + * + * These macros return the given value with the MSB copied to all the other + * bits. They use the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to replace + * them with something else on odd CPUs. */ +#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) +#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) + +/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */ +static unsigned constant_time_ge(unsigned a, unsigned b) + { + a -= b; + return DUPLICATE_MSB_TO_ALL(~a); + } + +/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */ +static unsigned char constant_time_eq_8(unsigned char a, unsigned char b) + { + unsigned c = a ^ b; + c--; + return DUPLICATE_MSB_TO_ALL_8(c); + } + +/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC + * record in |rec| by updating |rec->length| in constant time. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int ssl3_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size) + { + unsigned padding_length, good; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + + /* These lengths are all public so we can test them in non-constant + * time. */ + if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length-1]; + good = constant_time_ge(rec->length, padding_length+overhead); + /* SSLv3 requires that the padding is minimal. */ + good &= constant_time_ge(block_size, padding_length+1); + padding_length = good & (padding_length+1); + rec->length -= padding_length; + rec->type |= padding_length<<8; /* kludge: pass padding length */ + return (int)((good & 1) | (~good & -1)); +} + +/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC + * record in |rec| in constant time and returns 1 if the padding is valid and + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int tls1_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size) + { + unsigned padding_length, good, to_check, i; + const char has_explicit_iv = s->version == DTLS1_VERSION; + const unsigned overhead = 1 /* padding length byte */ + + mac_size + + (has_explicit_iv ? block_size : 0); + + /* These lengths are all public so we can test them in non-constant + * time. */ + if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length-1]; + + /* NB: if compression is in operation the first packet may not be of + * even length so the padding bug check cannot be performed. This bug + * workaround has been around since SSLeay so hopefully it is either + * fixed now or no buggy implementation supports compression [steve] + */ + if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) + { + /* First packet is even in size, so check */ + if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && + !(padding_length & 1)) + { + s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; + } + if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && + padding_length > 0) + { + padding_length--; + } + } + + good = constant_time_ge(rec->length, overhead+padding_length); + /* The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the + * length byte. Thus, with the length byte included, there are i+1 + * bytes of padding. + * + * We can't check just |padding_length+1| bytes because that leaks + * decrypted information. Therefore we always have to check the maximum + * amount of padding possible. (Again, the length of the record is + * public information so we can use it.) */ + to_check = 255; /* maximum amount of padding. */ + if (to_check > rec->length-1) + to_check = rec->length-1; + + for (i = 0; i < to_check; i++) + { + unsigned char mask = constant_time_ge(padding_length, i); + unsigned char b = rec->data[rec->length-1-i]; + /* The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. */ + good &= ~(mask&(padding_length ^ b)); + } + + /* If any of the final |padding_length+1| bytes had the wrong value, + * one or more of the lower eight bits of |good| will be cleared. We + * AND the bottom 8 bits together and duplicate the result to all the + * bits. */ + good &= good >> 4; + good &= good >> 2; + good &= good >> 1; + good <<= sizeof(good)*8-1; + good = DUPLICATE_MSB_TO_ALL(good); + + padding_length = good & (padding_length+1); + rec->length -= padding_length; + rec->type |= padding_length<<8; /* kludge: pass padding length */ + + /* We can always safely skip the explicit IV. We check at the beginning + * of this function that the record has at least enough space for the + * IV, MAC and padding length byte. (These can be checked in + * non-constant time because it's all public information.) So, if the + * padding was invalid, then we didn't change |rec->length| and this is + * safe. If the padding was valid then we know that we have at least + * overhead+padding_length bytes of space and so this is still safe + * because overhead accounts for the explicit IV. */ + if (has_explicit_iv) + { + rec->data += block_size; + rec->input += block_size; + rec->length -= block_size; + } + + return (int)((good & 1) | (~good & -1)); + } + +#if defined(_M_AMD64) || defined(__x86_64__) +#define CBC_MAC_ROTATE_IN_PLACE +#endif + +/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single cache-line, then the variable memory accesses don't actually affect + * the timing. This has been tested to be true on Intel amd64 chips. + */ +void ssl3_cbc_copy_mac(unsigned char* out, + const SSL3_RECORD *rec, + unsigned md_size,unsigned orig_len) + { +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[EVP_MAX_MD_SIZE*2]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* mac_end is the index of |rec->data| just after the end of the MAC. */ + unsigned mac_end = rec->length; + unsigned mac_start = mac_end - md_size; + /* scan_start contains the number of bytes that we can ignore because + * the MAC's position can only vary by 255 bytes. */ + unsigned scan_start = 0; + unsigned i, j; + unsigned div_spoiler; + unsigned rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = (unsigned char*) (((intptr_t)(rotated_mac_buf + 64)) & ~63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it + * to prove that md_size is always even, which I hope is beyond it. */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler)-1)*8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + memset(rotated_mac, 0, md_size); + for (i = scan_start; i < orig_len;) + { + for (j = 0; j < md_size && i < orig_len; i++, j++) + { + unsigned char mac_started = constant_time_ge(i, mac_start); + unsigned char mac_ended = constant_time_ge(i, mac_end); + unsigned char b = 0; + b = rec->data[i]; + rotated_mac[j] |= b & mac_started & ~mac_ended; + } + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) + { + unsigned char offset = (div_spoiler + rotate_offset + i) % md_size; + out[j++] = rotated_mac[offset]; + } +#else + memset(out, 0, md_size); + for (i = 0; i < md_size; i++) + { + unsigned char offset = (div_spoiler + md_size - rotate_offset + i) % md_size; + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, offset); + } +#endif + } + +/* These functions serialize the state of a hash and thus perform the standard + * "final" operation without adding the padding and length that such a function + * typically does. */ +static void tls1_md5_final_raw(void* ctx, unsigned char *md_out) + { + MD5_CTX *md5 = ctx; + l2n(md5->A, md_out); + l2n(md5->B, md_out); + l2n(md5->C, md_out); + l2n(md5->D, md_out); + } + +static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out) + { + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); + } +#define LARGEST_DIGEST_CTX SHA_CTX + +#ifndef OPENSSL_NO_SHA256 +static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out) + { + SHA256_CTX *sha256 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) + { + l2n(sha256->h[i], md_out); + } + } +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA256_CTX +#endif + +#ifndef OPENSSL_NO_SHA512 +static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out) + { + SHA512_CTX *sha512 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) + { + l2n8(sha512->h[i], md_out); + } + } +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA512_CTX +#endif + +/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. */ +char ssl3_cbc_record_digest_supported(const EVP_MD *digest) + { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 0; +#endif + switch (EVP_MD_type(digest)) + { + case NID_md5: + case NID_sha1: +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + case NID_sha256: +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + case NID_sha512: +#endif + return 1; + default: + return 0; + } + } + +/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) */ +void ssl3_cbc_digest_record( + const EVP_MD *digest, + unsigned char* md_out, + size_t* md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, + char is_sslv3) + { + union { double align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; + void (*md_final_raw)(void *ctx, unsigned char *md_out); + void (*md_transform)(void *ctx, const unsigned char *block); + unsigned md_size, md_block_size = 64; + unsigned sslv3_pad_length = 40, header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned i, j, md_out_size_u; + EVP_MD_CTX md_ctx; + /* mdLengthSize is the number of bytes in the length field that terminates + * the hash. */ + unsigned md_length_size = 8; + + /* This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); + + switch (EVP_MD_type(digest)) + { + case NID_md5: + MD5_Init((MD5_CTX*)md_state.c); + md_final_raw = tls1_md5_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; + md_size = 16; + sslv3_pad_length = 48; + break; + case NID_sha1: + SHA1_Init((SHA_CTX*)md_state.c); + md_final_raw = tls1_sha1_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; + md_size = 20; + break; +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + SHA224_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 224/8; + break; + case NID_sha256: + SHA256_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 32; + break; +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + SHA384_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 384/8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + SHA512_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; +#endif + default: + /* ssl3_cbc_record_digest_supported should have been + * called first to check that the hash function is + * supported. */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = -1; + return; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + if (is_sslv3) + { + header_length = + mac_secret_length + + sslv3_pad_length + + 8 /* sequence number */ + + 1 /* record type */ + + 2 /* record length */; + } + + /* variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. + * + * In SSLv3, the padding must be minimal so the end of the plaintext + * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that + * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash + * termination (0x80 + 64-bit length) don't fit in the final block, we + * say that the final two blocks can vary based on the padding. + * + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks + * can vary based on the padding. + * + * Later in the function, if the message is short and there obviously + * cannot be this many blocks then variance_blocks can be reduced. */ + variance_blocks = is_sslv3 ? 2 : 6; + /* From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) or 71/75 bytes + * (SSLv3) */ + len = data_plus_mac_plus_padding_size + header_length; + /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including + * |header|, assuming that there's no padding. */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; + /* In order to calculate the MAC in constant time we have to handle + * the final blocks specially because the padding value could cause the + * end to appear somewhere in the final |variance_blocks| blocks and we + * can't leak where. However, |num_starting_blocks| worth of data can + * be hashed right away because no padding value can affect whether + * they are plaintext. */ + num_starting_blocks = 0; + /* k is the starting byte offset into the conceptual header||data where + * we start processing. */ + k = 0; + /* mac_end_offset is the index just past the end of the data to be + * MACed. */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* c is the index of the 0x80 byte in the final hash block that + * contains application data. */ + c = mac_end_offset % md_block_size; + /* index_a is the hash block number that contains the 0x80 terminating + * value. */ + index_a = mac_end_offset / md_block_size; + /* index_b is the hash block number that contains the 64-bit hash + * length, in bits. */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* bits is the hash-length in bits. It includes the additional hash + * block for the masked HMAC key, or whole of |header| in the case of + * SSLv3. */ + + /* For SSLv3, if we're going to have any starting blocks then we need + * at least two because the header is larger than a single block. */ + if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) + { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size*num_starting_blocks; + } + + bits = 8*mac_end_offset; + if (!is_sslv3) + { + /* Compute the initial HMAC block. For SSLv3, the padding and + * secret bytes are included in |header| because they take more + * than a single block. */ + bits += 8*md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + } + + memset(length_bytes,0,md_length_size-4); + length_bytes[md_length_size-4] = (unsigned char)(bits>>24); + length_bytes[md_length_size-3] = (unsigned char)(bits>>16); + length_bytes[md_length_size-2] = (unsigned char)(bits>>8); + length_bytes[md_length_size-1] = (unsigned char)bits; + + if (k > 0) + { + if (is_sslv3) + { + /* The SSLv3 header is larger than a single block. + * overhang is the number of bytes beyond a single + * block that the header consumes: either 7 bytes + * (SHA1) or 11 bytes (MD5). */ + unsigned overhang = header_length-md_block_size; + md_transform(md_state.c, header); + memcpy(first_block, header + md_block_size, overhang); + memcpy(first_block + overhang, data, md_block_size-overhang); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size - 1; i++) + md_transform(md_state.c, data + md_block_size*i - overhang); + } + else + { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block+13, data, md_block_size-13); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size; i++) + md_transform(md_state.c, data + md_block_size*i - 13); + } + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* We now process the final hash blocks. For each block, we construct + * it in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. */ + for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++) + { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) + { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + b = data[k-header_length]; + k++; + + is_past_c = is_block_a & constant_time_ge(j, c); + is_past_cp1 = is_block_a & constant_time_ge(j, c+1); + /* If this is the block containing the end of the + * application data, and we are at the offset for the + * 0x80 value, then overwrite b with 0x80. */ + b = (b&~is_past_c) | (0x80&is_past_c); + /* If this the the block containing the end of the + * application data and we're past the 0x80 value then + * just write zero. */ + b = b&~is_past_cp1; + /* If this is index_b (the final block), but not + * index_a (the end of the data), then the 64-bit + * length didn't fit into index_a and we're having to + * add an extra block of zeros. */ + b &= ~is_block_b | is_block_a; + + /* The final bytes of one of the blocks contains the + * length. */ + if (j >= md_block_size - md_length_size) + { + /* If this is index_b, write a length byte. */ + b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j]&is_block_b; + } + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit_ex(&md_ctx, digest, NULL /* engine */); + if (is_sslv3) + { + /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ + memset(hmac_pad, 0x5c, sslv3_pad_length); + + EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); + EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } + else + { + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + } + +#ifdef OPENSSL_FIPS + +/* Due to the need to use EVP in FIPS mode we can't reimplement digests but + * we can ensure the number of blocks processed is equal for all cases + * by digesting additional data. + */ + +void tls_fips_digest_extra( + const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, + const unsigned char *data, size_t data_len, size_t orig_len) + { + size_t block_size, digest_pad, blocks_data, blocks_orig; + if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) + return; + block_size = EVP_MD_block_size(hash); + /* We are in FIPS mode if we get this far so we know we have only SHA* + * digests and TLS to deal with. + * Minimum digest padding length is 17 for SHA384/SHA512 and 9 + * otherwise. + * Additional header is 13 bytes. To get the number of digest blocks + * processed round up the amount of data plus padding to the nearest + * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. + * So we have: + * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size + * equivalently: + * blocks = (payload_len + digest_pad + 12)/block_size + 1 + * HMAC adds a constant overhead. + * We're ultimately only interested in differences so this becomes + * blocks = (payload_len + 29)/128 + * for SHA384/SHA512 and + * blocks = (payload_len + 21)/64 + * otherwise. + */ + digest_pad = block_size == 64 ? 21 : 29; + blocks_orig = (orig_len + digest_pad)/block_size; + blocks_data = (data_len + digest_pad)/block_size; + /* MAC enough blocks to make up the difference between the original + * and actual lengths plus one extra block to ensure this is never a + * no op. The "data" pointer should always have enough space to + * perform this operation as it is large enough for a maximum + * length TLS buffer. + */ + HMAC_Update(hctx, data, + (blocks_orig - blocks_data + 1) * block_size); + } +#endif Index: crypto/openssl/ssl/s3_clnt.c =================================================================== --- crypto/openssl/ssl/s3_clnt.c (revision 248771) +++ crypto/openssl/ssl/s3_clnt.c (working copy) @@ -262,7 +262,16 @@ int ssl3_connect(SSL *s) ret=ssl3_get_server_hello(s); if (ret <= 0) goto end; if (s->hit) + { s->state=SSL3_ST_CR_FINISHED_A; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) + { + /* receive renewed session ticket */ + s->state=SSL3_ST_CR_SESSION_TICKET_A; + } +#endif + } else s->state=SSL3_ST_CR_CERT_A; s->init_num=0; @@ -878,7 +887,7 @@ int ssl3_get_server_hello(SSL *s) /* wrong packet length */ al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH); - goto err; + goto f_err; } return(1); @@ -1713,7 +1722,7 @@ int ssl3_get_new_session_ticket(SSL *s) if (n < 6) { /* need at least ticket_lifetime_hint + ticket length */ - al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1724,7 +1733,7 @@ int ssl3_get_new_session_ticket(SSL *s) /* ticket_lifetime_hint + ticket_length + ticket */ if (ticklen + 6 != n) { - al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); goto f_err; } Index: crypto/openssl/ssl/s3_enc.c =================================================================== --- crypto/openssl/ssl/s3_enc.c (revision 248771) +++ crypto/openssl/ssl/s3_enc.c (working copy) @@ -433,12 +433,21 @@ void ssl3_cleanup_key_block(SSL *s) s->s3->tmp.key_block_length=0; } +/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding is invalid or, if sending, an internal error + * occured. + */ int ssl3_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i; + int bs,i,mac_size=0; const EVP_CIPHER *enc; if (send) @@ -489,32 +498,17 @@ int ssl3_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - { - SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; - } /* otherwise, rec->length >= bs */ } EVP_Cipher(ds,rec->data,rec->input,l); + if (s->read_hash != NULL) + mac_size = EVP_MD_size(s->read_hash); + if ((bs != 1) && !send) - { - i=rec->data[l-1]+1; - /* SSL 3.0 bounds the number of padding bytes by the block size; - * padding bytes (except the last one) are arbitrary */ - if (i > bs) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ - return -1; - } - /* now i <= bs <= rec->length */ - rec->length-=i; - } + return ssl3_cbc_remove_padding(s, rec, bs, mac_size); } return(1); } @@ -591,7 +585,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send EVP_MD_CTX md_ctx; const EVP_MD *hash; unsigned char *p,rec_char; - unsigned int md_size; + size_t md_size, orig_len; int npad; if (send) @@ -612,29 +606,73 @@ int ssl3_mac(SSL *ssl, unsigned char *md, int send md_size=EVP_MD_size(hash); npad=(48/md_size)*md_size; - /* Chop the digest off the end :-) */ - EVP_MD_CTX_init(&md_ctx); + /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */ + orig_len = rec->length+md_size+((unsigned int)rec->type>>8); + rec->type &= 0xff; - EVP_DigestInit_ex( &md_ctx,hash, NULL); - EVP_DigestUpdate(&md_ctx,mac_sec,md_size); - EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); - EVP_DigestUpdate(&md_ctx,seq,8); - rec_char=rec->type; - EVP_DigestUpdate(&md_ctx,&rec_char,1); - p=md; - s2n(rec->length,p); - EVP_DigestUpdate(&md_ctx,md,2); - EVP_DigestUpdate(&md_ctx,rec->input,rec->length); - EVP_DigestFinal_ex( &md_ctx,md,NULL); + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(hash)) + { + /* This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of + * data we are hashing because that gives an attacker a + * timing-oracle. */ - EVP_DigestInit_ex( &md_ctx,hash, NULL); - EVP_DigestUpdate(&md_ctx,mac_sec,md_size); - EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); - EVP_DigestUpdate(&md_ctx,md,md_size); - EVP_DigestFinal_ex( &md_ctx,md,&md_size); + /* npad is, at most, 48 bytes and that's with MD5: + * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. + * + * With SHA-1 (the largest hash speced for SSLv3) the hash size + * goes up 4, but npad goes down by 8, resulting in a smaller + * total size. */ + unsigned char header[75]; + unsigned j = 0; + memcpy(header+j, mac_sec, md_size); + j += md_size; + memcpy(header+j, ssl3_pad_1, npad); + j += npad; + memcpy(header+j, seq, 8); + j += 8; + header[j++] = rec->type; + header[j++] = rec->length >> 8; + header[j++] = rec->length & 0xff; - EVP_MD_CTX_cleanup(&md_ctx); + ssl3_cbc_digest_record( + hash, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + mac_sec, md_size, + 1 /* is SSLv3 */); + } + else + { + unsigned int md_size_u; + /* Chop the digest off the end :-) */ + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit_ex( &md_ctx,hash, NULL); + EVP_DigestUpdate(&md_ctx,mac_sec,md_size); + EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); + EVP_DigestUpdate(&md_ctx,seq,8); + rec_char=rec->type; + EVP_DigestUpdate(&md_ctx,&rec_char,1); + p=md; + s2n(rec->length,p); + EVP_DigestUpdate(&md_ctx,md,2); + EVP_DigestUpdate(&md_ctx,rec->input,rec->length); + EVP_DigestFinal_ex( &md_ctx,md,NULL); + + EVP_DigestInit_ex( &md_ctx,hash, NULL); + EVP_DigestUpdate(&md_ctx,mac_sec,md_size); + EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); + EVP_DigestUpdate(&md_ctx,md,md_size); + EVP_DigestFinal_ex( &md_ctx,md,&md_size_u); + md_size = md_size_u; + + EVP_MD_CTX_cleanup(&md_ctx); + } + ssl3_record_sequence_update(seq); return(md_size); } Index: crypto/openssl/ssl/s3_lib.c =================================================================== --- crypto/openssl/ssl/s3_lib.c (revision 248771) +++ crypto/openssl/ssl/s3_lib.c (working copy) @@ -2641,4 +2641,3 @@ need to go to SSL_ST_ACCEPT. } return(ret); } - Index: crypto/openssl/ssl/s3_pkt.c =================================================================== --- crypto/openssl/ssl/s3_pkt.c (revision 248771) +++ crypto/openssl/ssl/s3_pkt.c (working copy) @@ -246,11 +246,8 @@ static int ssl3_get_record(SSL *s) unsigned char *p; unsigned char md[EVP_MAX_MD_SIZE]; short version; - unsigned int mac_size; - int clear=0; + unsigned mac_size, orig_len; size_t extra; - int decryption_failed_or_bad_record_mac = 0; - unsigned char *mac = NULL; rr= &(s->s3->rrec); sess=s->session; @@ -354,19 +351,18 @@ again: /* decrypt in place in 'rr->input' */ rr->data=rr->input; + orig_len=rr->length; enc_err = s->method->ssl3_enc->enc(s,0); - if (enc_err <= 0) + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { - if (enc_err == 0) - /* SSLerr() and ssl3_send_alert() have been called */ - goto err; - - /* Otherwise enc_err == -1, which indicates bad padding - * (rec->length has not been changed in this case). - * To minimize information leaked via timing, we will perform - * the MAC computation anyway. */ - decryption_failed_or_bad_record_mac = 1; + al=SSL_AD_DECRYPTION_FAILED; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + goto f_err; } #ifdef TLS_DEBUG @@ -376,51 +372,59 @@ printf("\n"); #endif /* r->length is now the compressed data plus mac */ - if ( (sess == NULL) || - (s->enc_read_ctx == NULL) || - (s->read_hash == NULL)) - clear=1; - - if (!clear) + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && + (s->read_hash != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; mac_size=EVP_MD_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size+1)) { -#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ - al=SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; -#else - decryption_failed_or_bad_record_mac = 1; -#endif } - /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length >= mac_size) + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); rr->length -= mac_size; - mac = &rr->data[rr->length]; } else { - /* record (minus padding) is too short to contain a MAC */ -#if 0 /* OK only for stream ciphers */ - al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); - goto f_err; -#else - decryption_failed_or_bad_record_mac = 1; - rr->length = 0; -#endif + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; } - i=s->method->ssl3_enc->mac(s,md,0); - if (mac == NULL || memcmp(md, mac, mac_size) != 0) - { - decryption_failed_or_bad_record_mac = 1; - } + + i=s->method->ssl3_enc->mac(s,md,0 /* not send */); + if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) + enc_err = -1; } - if (decryption_failed_or_bad_record_mac) + if (enc_err < 0) { /* A separate 'decryption_failed' alert was introduced with TLS 1.0, * SSL 3.0 only has 'bad_record_mac'. But unless a decryption Index: crypto/openssl/ssl/s3_srvr.c =================================================================== --- crypto/openssl/ssl/s3_srvr.c (revision 248771) +++ crypto/openssl/ssl/s3_srvr.c (working copy) @@ -1005,7 +1005,7 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } } - if (ssl_check_clienthello_tlsext(s) <= 0) { + if (ssl_check_clienthello_tlsext_early(s) <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } @@ -1131,6 +1131,16 @@ int ssl3_get_client_hello(SSL *s) * s->tmp.new_cipher - the new cipher to use. */ + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) + { + if (ssl_check_clienthello_tlsext_late(s) <= 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + } + if (ret < 0) ret=1; if (0) { @@ -1571,6 +1581,7 @@ int ssl3_send_server_key_exchange(SSL *s) (unsigned char *)encodedPoint, encodedlen); OPENSSL_free(encodedPoint); + encodedPoint = NULL; p += encodedlen; } #endif @@ -1960,6 +1971,7 @@ int ssl3_get_client_key_exchange(SSL *s) if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); + BN_clear_free(pub); goto err; } Index: crypto/openssl/ssl/ssl.h =================================================================== --- crypto/openssl/ssl/ssl.h (revision 248771) +++ crypto/openssl/ssl/ssl.h (working copy) @@ -1682,6 +1682,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_DTLS1_ACCEPT 246 #define SSL_F_DTLS1_ADD_CERT_TO_BUF 280 #define SSL_F_DTLS1_BUFFER_RECORD 247 +#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 293 #define SSL_F_DTLS1_CLIENT_HELLO 248 #define SSL_F_DTLS1_CONNECT 249 #define SSL_F_DTLS1_ENC 250 @@ -1819,6 +1820,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_GET_NEW_SESSION 181 #define SSL_F_SSL_GET_PREV_SESSION 217 #define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 #define SSL_F_SSL_GET_SIGN_PKEY 183 #define SSL_F_SSL_INIT_WBIO_BUFFER 184 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 Index: crypto/openssl/ssl/ssl_ciph.c =================================================================== --- crypto/openssl/ssl/ssl_ciph.c (revision 248771) +++ crypto/openssl/ssl/ssl_ciph.c (working copy) @@ -303,6 +303,7 @@ static void load_builtin_compressions(void) sk_SSL_COMP_push(ssl_comp_methods,comp); } } + sk_SSL_COMP_sort(ssl_comp_methods); } MemCheck_on(); } Index: crypto/openssl/ssl/ssl_err.c =================================================================== --- crypto/openssl/ssl/ssl_err.c (revision 248771) +++ crypto/openssl/ssl/ssl_err.c (working copy) @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -80,6 +80,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"}, {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, +{ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "DTLS1_CHECK_TIMEOUT_NUM"}, {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"}, {ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"}, {ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"}, @@ -217,6 +218,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"}, {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, +{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"}, {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, Index: crypto/openssl/ssl/ssl_lib.c =================================================================== --- crypto/openssl/ssl/ssl_lib.c (revision 248771) +++ crypto/openssl/ssl/ssl_lib.c (working copy) @@ -1000,6 +1000,11 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) s->max_cert_list=larg; return(l); case SSL_CTRL_SET_MTU: +#ifndef OPENSSL_NO_DTLS1 + if (larg < (long)dtls1_min_mtu()) + return 0; +#endif + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { @@ -1938,7 +1943,7 @@ int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHE } /* THIS NEEDS CLEANING UP */ -X509 *ssl_get_server_send_cert(SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) { unsigned long alg,kalg; CERT *c; @@ -1988,14 +1993,22 @@ int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHE } else /* if (kalg & SSL_aNULL) */ { - SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR); return(NULL); } - if (c->pkeys[i].x509 == NULL) return(NULL); - return(c->pkeys[i].x509); + return c->pkeys + i; } +X509 *ssl_get_server_send_cert(const SSL *s) + { + CERT_PKEY *cpk; + cpk = ssl_get_server_send_pkey(s); + if (!cpk) + return NULL; + return cpk->x509; + } + EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher) { unsigned long alg; @@ -2415,7 +2428,9 @@ void ssl_clear_cipher_ctx(SSL *s) /* Fix this function so that it takes an optional type parameter */ X509 *SSL_get_certificate(const SSL *s) { - if (s->cert != NULL) + if (s->server) + return(ssl_get_server_send_cert(s)); + else if (s->cert != NULL) return(s->cert->key->x509); else return(NULL); Index: crypto/openssl/ssl/ssl_locl.h =================================================================== --- crypto/openssl/ssl/ssl_locl.h (revision 248771) +++ crypto/openssl/ssl/ssl_locl.h (working copy) @@ -189,6 +189,15 @@ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l) )&0xff)) +#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + #define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ l|=((BN_ULLONG)(*((c)++)))<<32, \ l|=((BN_ULLONG)(*((c)++)))<<24, \ @@ -740,7 +749,8 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *s int ssl_undefined_function(SSL *s); int ssl_undefined_void_function(void); int ssl_undefined_const_function(const SSL *s); -X509 *ssl_get_server_send_cert(SSL *); +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +X509 *ssl_get_server_send_cert(const SSL *); EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *); int ssl_cert_type(X509 *x,EVP_PKEY *pkey); void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher); @@ -870,6 +880,7 @@ void dtls1_get_ccs_header(unsigned char *data, str void dtls1_reset_seq_numbers(SSL *s, int rw); long dtls1_default_timeout(void); struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); +int dtls1_check_timeout_num(SSL *s); int dtls1_handle_timeout(SSL *s); SSL_CIPHER *dtls1_get_cipher(unsigned int u); void dtls1_start_timer(SSL *s); @@ -877,6 +888,7 @@ void dtls1_stop_timer(SSL *s); int dtls1_is_timer_expired(SSL *s); void dtls1_double_timeout(SSL *s); int dtls1_send_newsession_ticket(SSL *s); +unsigned int dtls1_min_mtu(void); /* some client-only functions */ @@ -977,7 +989,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); int ssl_prepare_clienthello_tlsext(SSL *s); int ssl_prepare_serverhello_tlsext(SSL *s); -int ssl_check_clienthello_tlsext(SSL *s); +int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); #ifdef OPENSSL_NO_SHA256 @@ -999,5 +1012,33 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, un int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, int *al); #endif +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char* out, + const SSL3_RECORD *rec, + unsigned md_size,unsigned orig_len); +int ssl3_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size); +int tls1_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD *hash); +void ssl3_cbc_digest_record( + const EVP_MD *hash, + unsigned char* md_out, + size_t* md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, + char is_sslv3); +void tls_fips_digest_extra( + const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, + const unsigned char *data, size_t data_len, size_t orig_len); + #endif Index: crypto/openssl/ssl/t1_enc.c =================================================================== --- crypto/openssl/ssl/t1_enc.c (revision 248771) +++ crypto/openssl/ssl/t1_enc.c (working copy) @@ -264,7 +264,7 @@ int tls1_change_cipher_state(SSL *s, int which) { int ki; for (ki=0; kis3->tmp.key_block_length; ki++) - printf("%02x", key_block[ki]); printf("\n"); + printf("%02x", s->s3->tmp.key_block[ki]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -528,12 +528,21 @@ err: return(0); } +/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ int tls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i,ii,j,k; + int bs,i,j,k,pad=0,ret,mac_size=0; const EVP_CIPHER *enc; if (send) @@ -559,11 +568,11 @@ int tls1_enc(SSL *s, int send) printf("tls1_enc(%d)\n", send); #endif /* KSSL_DEBUG */ - if ((s->session == NULL) || (ds == NULL) || - (enc == NULL)) + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data,rec->input,rec->length); rec->input=rec->data; + ret = 1; } else { @@ -591,14 +600,13 @@ int tls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long ui; + unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - (void *)ds,rec->data,rec->input,l); - printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", - ds->buf_len, ds->cipher->key_len, - (unsigned long)DES_KEY_SZ, - (unsigned long)DES_SCHEDULE_SZ, - ds->cipher->iv_len); + ds,rec->data,rec->input,l); + printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", + ds->buf_len, ds->cipher->key_len, + DES_KEY_SZ, DES_SCHEDULE_SZ, + ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); printf("\n"); @@ -611,11 +619,7 @@ int tls1_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - { - SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; - } } EVP_Cipher(ds,rec->data,rec->input,l); @@ -629,49 +633,15 @@ int tls1_enc(SSL *s, int send) } #endif /* KSSL_DEBUG */ + ret = 1; + if (s->read_hash != NULL) + mac_size = EVP_MD_size(s->read_hash); if ((bs != 1) && !send) - { - ii=i=rec->data[l-1]; /* padding_length */ - i++; - /* NB: if compression is in operation the first packet - * may not be of even length so the padding bug check - * cannot be performed. This bug workaround has been - * around since SSLeay so hopefully it is either fixed - * now or no buggy implementation supports compression - * [steve] - */ - if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) - && !s->expand) - { - /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, - "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) - s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - i--; - } - /* TLS 1.0 does not bound the number of padding bytes by the block size. - * All of them must have value 'padding_length'. */ - if (i > (int)rec->length) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ - return -1; - } - for (j=(int)(l-i); j<(int)l; j++) - { - if (rec->data[j] != ii) - { - /* Incorrect padding */ - return -1; - } - } - rec->length-=i; - } + ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); + if (pad && !send) + rec->length -= pad; } - return(1); + return ret; } int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out) @@ -719,10 +689,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send SSL3_RECORD *rec; unsigned char *mac_sec,*seq; const EVP_MD *hash; - unsigned int md_size; + size_t md_size, orig_len; int i; HMAC_CTX hmac; - unsigned char buf[5]; + unsigned char header[13]; if (send) { @@ -741,20 +711,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send md_size=EVP_MD_size(hash); - buf[0]=rec->type; - if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) - { - buf[1]=TLS1_VERSION_MAJOR; - buf[2]=TLS1_VERSION_MINOR; - } - else { - buf[1]=(unsigned char)(ssl->version>>8); - buf[2]=(unsigned char)(ssl->version); - } - - buf[3]=rec->length>>8; - buf[4]=rec->length&0xff; - /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ HMAC_CTX_init(&hmac); HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); @@ -766,16 +722,57 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); memcpy (p,&seq[2],6); - HMAC_Update(&hmac,dtlsseq,8); + memcpy(header, dtlsseq, 8); } else - HMAC_Update(&hmac,seq,8); + memcpy(header, seq, 8); - HMAC_Update(&hmac,buf,5); - HMAC_Update(&hmac,rec->input,rec->length); - HMAC_Final(&hmac,md,&md_size); + /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ + orig_len = rec->length+md_size+((unsigned int)rec->type>>8); + rec->type &= 0xff; + + header[8]=rec->type; + header[9]=(unsigned char)(ssl->version>>8); + header[10]=(unsigned char)(ssl->version); + header[11]=(rec->length)>>8; + header[12]=(rec->length)&0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(hash)) + { + /* This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of + * data we are hashing because that gives an attacker a + * timing-oracle. */ + ssl3_cbc_digest_record( + hash, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + ssl->s3->read_mac_secret, + EVP_MD_size(ssl->read_hash), + 0 /* not SSLv3 */); + } + else + { + unsigned mds; + + HMAC_Update(&hmac,header,sizeof(header)); + HMAC_Update(&hmac,rec->input,rec->length); + HMAC_Final(&hmac,md,&mds); + md_size = mds; +#ifdef OPENSSL_FIPS + if (!send && FIPS_mode()) + tls_fips_digest_extra( + ssl->enc_read_ctx, + hash, + &hmac, rec->input, + rec->length, orig_len); +#endif + } + HMAC_CTX_cleanup(&hmac); - #ifdef TLS_DEBUG printf("sec="); {unsigned int z; for (z=0; z 0) { + if (s->tlsext_ocsp_exts) + { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, &sdata, dsize); @@ -739,7 +745,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned return 1; } -int ssl_check_clienthello_tlsext(SSL *s) +int ssl_check_clienthello_tlsext_early(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; @@ -749,13 +755,49 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); + switch (ret) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + + default: + return 1; + } + } + +int ssl_check_clienthello_tlsext_late(SSL *s) + { + int ret = SSL_TLSEXT_ERR_OK; + int al; + /* If status request then ask callback what to do. * Note: this must be called after servername callbacks in case - * the certificate has changed. + * the certificate has changed, and must be called after the cipher + * has been chosen because this may influence which certificate is sent */ - if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb) + if (s->tlsext_status_type != -1 && s->ctx && s->ctx->tlsext_status_cb) { int r; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) + { + s->tlsext_status_expected = 0; + return 1; + } + /* Set current certificate to one we will use so + * SSL_get_certificate et al can pick it up. + */ + s->cert->key = certpkey; r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); switch (r) { @@ -779,7 +821,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned } else s->tlsext_status_expected = 0; - err: + + err: switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: @@ -789,11 +832,9 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned case SSL_TLSEXT_ERR_ALERT_WARNING: ssl3_send_alert(s,SSL3_AL_WARNING,al); return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done=0; - default: - return 1; + + default: + return 1; } } @@ -971,7 +1012,7 @@ static int tls_decrypt_ticket(SSL *s, const unsign HMAC_Update(&hctx, etick, eticklen); HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); - if (memcmp(tick_hmac, etick + eticklen, mlen)) + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) goto tickerr; /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ Index: crypto/openssl/util/fipslink.pl =================================================================== --- crypto/openssl/util/fipslink.pl (revision 248771) +++ crypto/openssl/util/fipslink.pl (working copy) @@ -43,7 +43,12 @@ die "First stage Link failure" if $? != 0; print "$fips_premain_dso $fips_target\n"; -$fips_hash=`$fips_premain_dso $fips_target`; +system("$fips_premain_dso $fips_target >$fips_target.sha1"); +die "Get hash failure" if $? != 0; +open my $sha1_res, '<', $fips_target.".sha1" or die "Get hash failure"; +$fips_hash=<$sha1_res>; +close $sha1_res; +unlink $fips_target.".sha1"; chomp $fips_hash; die "Get hash failure" if $? != 0; Index: crypto/openssl/util/libeay.num =================================================================== --- crypto/openssl/util/libeay.num (revision 248771) +++ crypto/openssl/util/libeay.num (working copy) @@ -3510,6 +3510,7 @@ BIO_get_callback_arg 3902 EXIST BIO_set_callback 3903 EXIST::FUNCTION: d2i_ASIdOrRange 3904 EXIST::FUNCTION:RFC3779 i2d_ASIdentifiers 3905 EXIST::FUNCTION:RFC3779 +CRYPTO_memcmp 3906 EXIST::FUNCTION: SEED_decrypt 3908 EXIST::FUNCTION:SEED SEED_encrypt 3909 EXIST::FUNCTION:SEED SEED_cbc_encrypt 3910 EXIST::FUNCTION:SEED Index: crypto/openssl/util/mkerr.pl =================================================================== --- crypto/openssl/util/mkerr.pl (revision 248771) +++ crypto/openssl/util/mkerr.pl (working copy) @@ -313,7 +313,7 @@ foreach $lib (keys %csrc) } else { push @out, "/* ====================================================================\n", -" * Copyright (c) 2001-2010 The OpenSSL Project. All rights reserved.\n", +" * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n", " *\n", " * Redistribution and use in source and binary forms, with or without\n", " * modification, are permitted provided that the following conditions\n", @@ -487,7 +487,7 @@ EOF print OUT <<"EOF"; /* $cfile */ /* ==================================================================== - * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -680,7 +680,7 @@ EOF undef %err_reason_strings; } -if($debug && defined(%notrans)) { +if($debug && %notrans) { print STDERR "The following function codes were not translated:\n"; foreach(sort keys %notrans) { Index: crypto/openssl/util/pl/VC-32.pl =================================================================== --- crypto/openssl/util/pl/VC-32.pl (revision 248771) +++ crypto/openssl/util/pl/VC-32.pl (working copy) @@ -391,7 +391,7 @@ sub do_lib_rule $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n"; $ret.="\tSET FIPS_TARGET=$target\n"; $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n"; - $ret.="\t\$(FIPSLINK) \$(MLFLAGS) /map $base_arg $efile$target "; + $ret.="\t\$(FIPSLINK) \$(MLFLAGS) /fixed /map $base_arg $efile$target "; $ret.="$name @<<\n \$(SHLIB_EX_OBJ) $objs "; $ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n"; } @@ -434,7 +434,7 @@ sub do_link_rule $ret.="\tSET FIPS_TARGET=$target\n"; $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n"; $ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\n"; - $ret.="\t\$(FIPSLINK) \$(LFLAGS) /map $efile$target @<<\n"; + $ret.="\t\$(FIPSLINK) \$(LFLAGS) /fixed /map $efile$target @<<\n"; $ret.="\t\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n"; } else Index: secure/lib/libcrypto/Makefile.inc =================================================================== --- secure/lib/libcrypto/Makefile.inc (revision 248771) +++ secure/lib/libcrypto/Makefile.inc (working copy) @@ -3,8 +3,8 @@ .include # OpenSSL version used for manual page generation -OPENSSL_VER= 0.9.8q -OPENSSL_DATE= 2010-12-02 +OPENSSL_VER= 0.9.8y +OPENSSL_DATE= 2013-02-05 LCRYPTO_SRC= ${.CURDIR}/../../../crypto/openssl LCRYPTO_DOC= ${.CURDIR}/../../../crypto/openssl/doc Index: secure/lib/libssl/Makefile =================================================================== --- secure/lib/libssl/Makefile (revision 248771) +++ secure/lib/libssl/Makefile (working copy) @@ -14,7 +14,8 @@ SRCS= bio_ssl.c d1_meth.c d1_srvr.c d1_clnt.c d1_l d1_both.c d1_enc.c \ s23_clnt.c s23_lib.c s23_meth.c s23_pkt.c s23_srvr.c \ s2_clnt.c s2_enc.c s2_lib.c s2_meth.c s2_pkt.c s2_srvr.c \ - s3_both.c s3_clnt.c s3_enc.c s3_lib.c s3_meth.c s3_pkt.c \ + s3_both.c s3_cbc.c s3_clnt.c s3_enc.c s3_lib.c s3_meth.c \ + s3_pkt.c \ s3_srvr.c ssl_algs.c ssl_asn1.c ssl_cert.c ssl_ciph.c \ ssl_err.c ssl_err2.c ssl_lib.c ssl_rsa.c ssl_sess.c ssl_stat.c \ ssl_txt.c t1_clnt.c t1_enc.c t1_lib.c t1_meth.c t1_reneg.c t1_srvr.c