I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
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
|