Fix OpenSSL multiple vulnerabilities. [13:03] Fix BIND remote denial of service. [13:04] Security: CVE-2013-0166, CVE-2013-0169 Security: FreeBSD-SA-13:03.openssl Security: CVE-2013-2266 Security: FreeBSD-SA-13:04.bind
5576 lines
191 KiB
Diff
5576 lines
191 KiB
Diff
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 <rob.stradling@comodo.com>]
|
|
+
|
|
+ *) 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 <thoger@redhat.com>]
|
|
+
|
|
+ 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 <agl@chromium.org> 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 <inestlerode@us.ibm.com> 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 <inestlerode@us.ibm.com> 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
|
|
+ <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
|
|
+ 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 <ekasper@google.com>]
|
|
+
|
|
+ *) 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 <desnacked@gmail.com> 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 <sra@hactrn.net> for fixing it. (CVE-2011-4577)
|
|
+ [Rob Austein <sra@hactrn.net>]
|
|
+
|
|
+ *) 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 <URL: http://www.openssl.org>.
|
|
-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 <URL:
|
|
@@ -108,7 +109,9 @@ In addition, you can read the most current version
|
|
<URL: http://www.openssl.org/docs/>. 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; i<ctx->ibuf_len; i++)
|
|
+ for (i=0; i<ctx->ibuf_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 <stdio.h>
|
|
#include <errno.h>
|
|
@@ -65,6 +64,7 @@
|
|
#include "cryptlib.h"
|
|
|
|
#include <openssl/bio.h>
|
|
+#ifndef OPENSSL_NO_DGRAM
|
|
|
|
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
|
|
#include <sys/timeb.h>
|
|
@@ -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 && i<a->top;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 <assert.h>
|
|
+#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <openssl/conf.h>
|
|
#include <openssl/conf_api.h>
|
|
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 <stdio.h>
|
|
#include <string.h>
|
|
-#include <assert.h>
|
|
#include "cryptlib.h"
|
|
#include <openssl/conf.h>
|
|
#include <openssl/asn1.h>
|
|
@@ -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<PASS PHRASE ARGUMENTS> section in L<open
|
|
|
|
=item B<-verify filename>
|
|
|
|
-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<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>; .
|
|
+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<SSL_get_session(3)|SSL_get_session(3)>;
|
|
+L<SSL_new(3)|SSL_new(3)>;
|
|
+L<SSL_set_session(3)|SSL_set_session(3)>;
|
|
+L<SSL_free(3)|SSL_free(3)>
|
|
+instead to avoid such failures
|
|
+(or simply L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>
|
|
+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 <openssl/des.h>
|
|
#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 <openssl/md5.h>
|
|
+#include <openssl/sha.h>
|
|
+
|
|
+/* 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; ki<s->s3->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; i<ds->cipher->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<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
|
|
Index: crypto/openssl/ssl/t1_lib.c
|
|
===================================================================
|
|
--- crypto/openssl/ssl/t1_lib.c (revision 248771)
|
|
+++ crypto/openssl/ssl/t1_lib.c (working copy)
|
|
@@ -575,6 +575,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned
|
|
sdata = data;
|
|
if (dsize > 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 <bsd.own.mk>
|
|
|
|
# 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
|