Import OpenSSL 0.9.8x.

This commit is contained in:
Jung-uk Kim 2012-06-27 16:44:58 +00:00
parent fd3744ddb0
commit 2b8b545582
92 changed files with 1862 additions and 1029 deletions

136
CHANGES
View File

@ -2,6 +2,142 @@
OpenSSL CHANGES OpenSSL CHANGES
_______________ _______________
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] Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
*) Disable code workaround for ancient and obsolete Netscape browsers *) Disable code workaround for ancient and obsolete Netscape browsers

View File

@ -371,6 +371,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-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}", "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 [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-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)", "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)",

22
FAQ
View File

@ -10,6 +10,7 @@ OpenSSL - Frequently Asked Questions
* Why aren't tools like 'autoconf' and 'libtool' used? * Why aren't tools like 'autoconf' and 'libtool' used?
* What is an 'engine' version? * What is an 'engine' version?
* How do I check the authenticity of the OpenSSL distribution? * How do I check the authenticity of the OpenSSL distribution?
* How does the versioning scheme work?
[LEGAL] Legal questions [LEGAL] Legal questions
@ -82,7 +83,7 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL? * Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>. The current version is available from <URL: http://www.openssl.org>.
OpenSSL 1.0.0c was released on Dec 2nd, 2010. OpenSSL 1.0.1c was released on May 10th, 2012.
In addition to the current stable release, you can also access daily In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL: snapshots of the OpenSSL development version at <URL:
@ -108,7 +109,9 @@ In addition, you can read the most current versions at
<URL: http://www.openssl.org/docs/>. Note that the online documents refer <URL: http://www.openssl.org/docs/>. Note that the online documents refer
to the very latest development versions of OpenSSL and may include features to the very latest development versions of OpenSSL and may include features
not present in released versions. If in doubt refer to the documentation 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 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 might want to read Ariel Glenn's documentation on SSLeay 0.9, OpenSSL's
@ -173,6 +176,19 @@ just do:
pgp TARBALL.asc 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] ======================================================================= [LEGAL] =======================================================================
* Do I need patent licenses to use OpenSSL? * Do I need patent licenses to use OpenSSL?
@ -284,7 +300,7 @@ current directory in this case, but this has changed with 0.9.6a.)
Check out the CA.pl(1) manual page. This provides a simple wrapper round 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 the 'req', 'verify', 'ca' and 'pkcs12' utilities. For finer control check
out the manual pages for the individual utilities and the certificate 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? * Why can't I create certificate requests?

View File

@ -28,6 +28,7 @@ openssl-*/demos/engines/rsaref
openssl-*/ms openssl-*/ms
openssl-*/op openssl-*/op
openssl-*/os2 openssl-*/os2
openssl-*/perl
openssl-*/shlib/Makefile.hpux10-cc openssl-*/shlib/Makefile.hpux10-cc
openssl-*/shlib/hpux10-cc.sh openssl-*/shlib/hpux10-cc.sh
openssl-*/shlib/irix.sh openssl-*/shlib/irix.sh

View File

@ -11,8 +11,8 @@ First, read http://wiki.freebsd.org/SubversionPrimer/VendorImports
# Xlist # Xlist
setenv XLIST /FreeBSD/work/openssl/svn-FREEBSD-files/FREEBSD-Xlist setenv XLIST /FreeBSD/work/openssl/svn-FREEBSD-files/FREEBSD-Xlist
setenv FSVN "svn+ssh://svn.freebsd.org/base" setenv FSVN "svn+ssh://svn.freebsd.org/base"
setenv OSSLVER 0.9.8k setenv OSSLVER 0.9.8x
# OSSLTAG format: v0_9_8k # OSSLTAG format: v0_9_8x
###setenv OSSLTAG v`echo ${OSSLVER} | tr . _` ###setenv OSSLTAG v`echo ${OSSLVER} | tr . _`
@ -25,13 +25,12 @@ svn co $FSVN/vendor-crypto/openssl/dist dist
tar -x -X $XLIST -f openssl-${OSSLVER}.tar.gz tar -x -X $XLIST -f openssl-${OSSLVER}.tar.gz
cd dist cd dist
svn list -R | grep -v '/$' | sort >../old svn list -R | egrep -v -e '/$' -e '^FREEBSD-(Xlist|upgrade)$' | sort >../old
cd ../openssl-${OSSLVER} cd ../openssl-${OSSLVER}
find . -type f -or -type l | cut -c 3- | sort >../new find . -type f -or -type l | cut -c 3- | sort >../new
cd .. cd ..
# See that files to remove makes sense # See that files to remove makes sense
# FREEBSD-Xlist FREEBSD-upgrade will show up - ignore that.
comm -23 old new comm -23 old new
# See that files to add makes sense # See that files to add makes sense
comm -13 old new comm -13 old new
@ -41,30 +40,43 @@ cd dist
comm -23 ../old ../new | xargs svn rm comm -23 ../old ../new | xargs svn rm
comm -13 ../old ../new | xargs svn --parents add comm -13 ../old ../new | xargs svn --parents add
svn stat
svn ci svn ci
echo svn cp $FSVN/vendor-crypto/openssl/dist $FSVN/vendor-crypto/openssl/$OSSLVER svn cp $FSVN/vendor-crypto/openssl/dist $FSVN/vendor-crypto/openssl/$OSSLVER
# XXX, below this point it's very WIP. # Merge to head
mkdir ../head
cd ../head
svn co $FSVN/head/crypto/openssl crypto/openssl
svn merge $FSVN/vendor-crypto/openssl/dist crypto/openssl
# Resolve conflicts manually # Resolve conflicts manually
cd src/crypto/openssl
cvs ci -m "Resolve conflicts after import of OpenSSL ${OSSLVER}."
cd ../../secure svn co $FSVN/head/secure/lib/libcrypto secure/lib/libcrypto
# Do something so it actually compiles... svn co $FSVN/head/secure/lib/libssl secure/lib/libssl
# Update version number in lib/libcrypto/Makefile.inc svn co $FSVN/head/secure/usr.bin/openssl secure/usr.bin/openssl
cd lib/libcrypto
cd secure/lib/libcrypto
# Update version number and release date in Makefile.inc
# Update all opensslconf-${MACHINE_CPUARCH}.h
# Regen assembly files if necessary
make -f Makefile.asm all
mv *.[Ss] ${MACHINE_CPUARCH}
make -f Makefile.asm clean
# Regen manual pages
make man-makefile-update && make man-update make man-makefile-update && make man-update
cd ../libssl cd ../libssl
make man-makefile-update && make man-update make man-makefile-update && make man-update
cd ../../usr.bin/openssl cd ../../usr.bin/openssl
make man-makefile-update && make man-update make man-makefile-update && make man-update
cd ../.. cd ../../..
cvs add lib/libcrypto/man/*.3 lib/libssl/man/*.3 usr.bin/openssl/man/*.1
cvs update
# check for files not added
cvs ci -m "Upgrade to OpenSSL ${OSSLVER}."
-- simon@ # Commit!
svn ci crypto/openssl secure/lib/libcrypto secure/lib/libssl secure/usr.bin/openssl
-- simon@, jkim@
$FreeBSD$ $FreeBSD$

View File

@ -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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

View File

@ -4,7 +4,7 @@
## Makefile for OpenSSL ## Makefile for OpenSSL
## ##
VERSION=0.9.8q VERSION=0.9.8x
MAJOR=0 MAJOR=0
MINOR=9.8 MINOR=9.8
SHLIB_VERSION_NUMBER=0.9.8 SHLIB_VERSION_NUMBER=0.9.8

39
NEWS
View File

@ -5,6 +5,40 @@
This file gives a brief overview of the major changes between each OpenSSL This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file. release. For more details please read the CHANGES file.
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: Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
o Fix for security issue CVE-2010-4180 o Fix for security issue CVE-2010-4180
@ -181,6 +215,11 @@
o Added initial support for Win64. o Added initial support for Win64.
o Added alternate pkg-config files. 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: Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l:
o Introduce limits to prevent malicious key DoS (CVE-2006-2940) o Introduce limits to prevent malicious key DoS (CVE-2006-2940)

4
README
View File

@ -1,7 +1,7 @@
OpenSSL 0.9.8q 2 Dec 2010 OpenSSL 0.9.8x 10 May 2012
Copyright (c) 1998-2009 The OpenSSL Project Copyright (c) 1998-2011 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
All rights reserved. All rights reserved.

File diff suppressed because it is too large Load Diff

View File

@ -408,6 +408,7 @@ static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
atyp = ASN1_generate_nconf(genstr, cnf); atyp = ASN1_generate_nconf(genstr, cnf);
NCONF_free(cnf); NCONF_free(cnf);
cnf = NULL;
if (!atyp) if (!atyp)
return -1; return -1;

View File

@ -226,6 +226,8 @@ int MAIN(int argc, char **argv)
else if (!strcmp(*args,"-camellia256")) else if (!strcmp(*args,"-camellia256"))
cipher = EVP_camellia_256_cbc(); cipher = EVP_camellia_256_cbc();
#endif #endif
else if (!strcmp (*args, "-debug_decrypt"))
flags |= CMS_DEBUG_DECRYPT;
else if (!strcmp (*args, "-text")) else if (!strcmp (*args, "-text"))
flags |= CMS_TEXT; flags |= CMS_TEXT;
else if (!strcmp (*args, "-nointern")) 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, "-certsout file certificate output file\n");
BIO_printf (bio_err, "-signer file signer certificate 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, "-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, "-in file input file\n");
BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\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"); 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; ret = 4;
if (operation == SMIME_DECRYPT) if (operation == SMIME_DECRYPT)
{ {
if (flags & CMS_DEBUG_DECRYPT)
CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
if (secret_key) if (secret_key)
{ {

View File

@ -141,7 +141,7 @@ localityName = Locality Name (eg, city)
organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default = #organizationalUnitName_default =
commonName = Common Name (eg, YOUR name) commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64 commonName_max = 64
emailAddress = Email Address emailAddress = Email Address

View File

@ -659,7 +659,7 @@ int MAIN(int argc, char **argv)
if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); 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) { if(macver) {
#ifdef CRYPTO_MDEBUG #ifdef CRYPTO_MDEBUG
CRYPTO_push_info("verify MAC"); CRYPTO_push_info("verify MAC");

View File

@ -345,13 +345,7 @@ int MAIN(int argc, char **argv)
char *jpake_secret = NULL; char *jpake_secret = NULL;
#endif #endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_client_method(); 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(); apps_startup();
c_Pause=0; c_Pause=0;

View File

@ -781,13 +781,7 @@ int MAIN(int argc, char *argv[])
tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
#endif #endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_server_method(); 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_argc=argc;
local_argv=argv; local_argv=argv;

View File

@ -969,7 +969,7 @@ int MAIN(int argc, char **argv)
else else
{ {
pk=load_key(bio_err, pk=load_key(bio_err,
keyfile, FORMAT_PEM, 0, keyfile, keyformat, 0,
passin, e, "request key"); passin, e, "request key");
if (pk == NULL) goto end; if (pk == NULL) goto end;
} }

4
config
View File

@ -790,6 +790,10 @@ esac
# options="$options -DATALLA" # options="$options -DATALLA"
#fi #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 # gcc < 2.8 does not support -march=ultrasparc
if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ] if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ]
then then

View File

@ -57,6 +57,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <limits.h>
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/buffer.h> #include <openssl/buffer.h>
#include <openssl/asn1_mac.h> #include <openssl/asn1_mac.h>
@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
BUF_MEM *b; BUF_MEM *b;
unsigned char *p; unsigned char *p;
int i; int i;
int ret=-1;
ASN1_const_CTX c; ASN1_const_CTX c;
int want=HEADER_SIZE; size_t want=HEADER_SIZE;
int eos=0; int eos=0;
#if defined(__GNUC__) && defined(__ia64) size_t off=0;
/* pathetic compiler bug in all known versions as of Nov. 2002 */ size_t len=0;
long off=0;
#else
int off=0;
#endif
int len=0;
b=BUF_MEM_new(); b=BUF_MEM_new();
if (b == NULL) if (b == NULL)
@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{ {
want-=(len-off); want-=(len-off);
if (!BUF_MEM_grow_clean(b,len+want)) if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{ {
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err; goto err;
@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
goto err; goto err;
} }
if (i > 0) if (i > 0)
{
if (len+i < len)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
len+=i; len+=i;
}
} }
/* else data already loaded */ /* else data already loaded */
@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{ {
/* no data body so go round again */ /* no data body so go round again */
eos++; eos++;
if (eos < 0)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE; want=HEADER_SIZE;
} }
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
else else
{ {
/* suck in c.slen bytes of data */ /* suck in c.slen bytes of data */
want=(int)c.slen; want=c.slen;
if (want > (len-off)) if (want > (len-off))
{ {
want-=(len-off); want-=(len-off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want)) if (!BUF_MEM_grow_clean(b,len+want))
{ {
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
ASN1_R_NOT_ENOUGH_DATA); ASN1_R_NOT_ENOUGH_DATA);
goto err; goto err;
} }
/* This can't overflow because
* |len+want| didn't overflow. */
len+=i; len+=i;
want -= i; want-=i;
} }
} }
off+=(int)c.slen; if (off + c.slen < off)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
if (eos <= 0) if (eos <= 0)
{ {
break; break;
@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
} }
} }
if (off > INT_MAX)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
*pb = b; *pb = b;
return off; return off;
err: err:
if (b != NULL) BUF_MEM_free(b); if (b != NULL) BUF_MEM_free(b);
return(ret); return -1;
} }

View File

@ -139,7 +139,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
goto err; goto err;
} }
if (!use_bn && l > (ULONG_MAX / 10L)) if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
{ {
use_bn = 1; use_bn = 1;
if (!bl) if (!bl)
@ -294,7 +294,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
/* Sanity check OID encoding: can't have leading 0x80 in /* Sanity check OID encoding: can't have leading 0x80 in
* subidentifiers, see: X.690 8.19.2 * 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))) if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
{ {

View File

@ -74,6 +74,11 @@
#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) #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 /* Three IO functions for sending data to memory, a BIO and
* and a FILE pointer. * and a FILE pointer.
@ -148,6 +153,13 @@ static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, ch
if(!io_ch(arg, tmphex, 3)) return -1; if(!io_ch(arg, tmphex, 3)) return -1;
return 3; 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; if(!io_ch(arg, &chtmp, 1)) return -1;
return 1; return 1;
} }
@ -292,11 +304,6 @@ static const signed char tag2nbyte[] = {
4, -1, 2 /* 28-30 */ 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 /* This is the main function, print out an
* ASN1_STRING taking note of various escape * ASN1_STRING taking note of various escape
* and display options. Returns number of * and display options. Returns number of

View File

@ -96,7 +96,7 @@ unsigned long ASN1_STRING_get_default_mask(void)
* default: the default value, Printable, T61, BMP. * 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; unsigned long mask;
char *end; char *end;

View File

@ -1051,7 +1051,7 @@ ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
void ASN1_STRING_set_default_mask(unsigned long mask); 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); unsigned long ASN1_STRING_get_default_mask(void);
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask); int inform, unsigned long mask);

View File

@ -418,9 +418,9 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
if(strcmp(hdr->value, "application/x-pkcs7-signature") && if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
strcmp(hdr->value, "application/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); ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
ERR_add_error_data(2, "type: ", hdr->value); ERR_add_error_data(2, "type: ", hdr->value);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
sk_BIO_pop_free(parts, BIO_vfree); sk_BIO_pop_free(parts, BIO_vfree);
return NULL; return NULL;
} }
@ -790,12 +790,17 @@ static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
static int mime_hdr_cmp(const MIME_HEADER * const *a, static int mime_hdr_cmp(const MIME_HEADER * const *a,
const MIME_HEADER * const *b) const MIME_HEADER * const *b)
{ {
if (!(*a)->name || !(*b)->name)
return !!(*a)->name - !!(*b)->name;
return(strcmp((*a)->name, (*b)->name)); return(strcmp((*a)->name, (*b)->name));
} }
static int mime_param_cmp(const MIME_PARAM * const *a, static int mime_param_cmp(const MIME_PARAM * const *a,
const MIME_PARAM * const *b) 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)); return(strcmp((*a)->param_name, (*b)->param_name));
} }

View File

@ -196,7 +196,9 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len
*val = nm.a; *val = nm.a;
*in = p; *in = p;
return ret; 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); ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
return 0; return 0;
} }

View File

@ -367,7 +367,16 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
goto err; 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)
{
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); CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return(ret); return(ret);
err: err:

View File

@ -209,7 +209,7 @@ static int buffer_write(BIO *b, const char *in, int inl)
/* add to buffer and return */ /* add to buffer and return */
if (i >= inl) 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; ctx->obuf_len+=inl;
return(num+inl); return(num+inl);
} }
@ -219,7 +219,7 @@ static int buffer_write(BIO *b, const char *in, int inl)
{ {
if (i > 0) /* lets fill it up if we can */ 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; in+=i;
inl-=i; inl-=i;
num+=i; num+=i;
@ -294,9 +294,9 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_C_GET_BUFF_NUM_LINES: case BIO_C_GET_BUFF_NUM_LINES:
ret=0; ret=0;
p1=ctx->ibuf; 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; break;
case BIO_CTRL_WPENDING: case BIO_CTRL_WPENDING:
@ -399,17 +399,18 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
for (;;) for (;;)
{ {
BIO_clear_retry_flags(b); BIO_clear_retry_flags(b);
if (ctx->obuf_len > ctx->obuf_off) if (ctx->obuf_len > 0)
{ {
r=BIO_write(b->next_bio, r=BIO_write(b->next_bio,
&(ctx->obuf[ctx->obuf_off]), &(ctx->obuf[ctx->obuf_off]),
ctx->obuf_len-ctx->obuf_off); ctx->obuf_len);
#if 0 #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 #endif
BIO_copy_next_retry(b); BIO_copy_next_retry(b);
if (r <= 0) return((long)r); if (r <= 0) return((long)r);
ctx->obuf_off+=r; ctx->obuf_off+=r;
ctx->obuf_len-=r;
} }
else else
{ {

View File

@ -145,6 +145,7 @@ extern "C" {
/* #endif */ /* #endif */
#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ #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_GET_MTU 41 /* get cached value for MTU */
#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for #define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for
* MTU. want to use this * MTU. want to use this
@ -321,6 +322,15 @@ DECLARE_STACK_OF(BIO)
typedef struct bio_f_buffer_ctx_struct 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 */ /* BIO *bio; */ /* this is now in the BIO struct */
int ibuf_size; /* how big is the input buffer */ int ibuf_size; /* how big is the input buffer */
int obuf_size; /* how big is the output buffer */ int obuf_size; /* how big is the output buffer */

View File

@ -57,7 +57,6 @@
* *
*/ */
#ifndef OPENSSL_NO_DGRAM
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
@ -65,6 +64,7 @@
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/bio.h> #include <openssl/bio.h>
#ifndef OPENSSL_NO_DGRAM
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
#include <sys/timeb.h> #include <sys/timeb.h>
@ -288,7 +288,6 @@ static int dgram_read(BIO *b, char *out, int outl)
*/ */
dgram_adjust_rcv_timeout(b); dgram_adjust_rcv_timeout(b);
ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen);
dgram_reset_rcv_timeout(b);
if ( ! data->connected && ret >= 0) if ( ! data->connected && ret >= 0)
BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); 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(); data->_errno = get_last_socket_error();
} }
} }
dgram_reset_rcv_timeout(b);
} }
return(ret); return(ret);
} }
@ -493,6 +494,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0; ret = 0;
#endif #endif
break; break;
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
ret = 576 - 20 - 8;
break;
case BIO_CTRL_DGRAM_GET_MTU: case BIO_CTRL_DGRAM_GET_MTU:
return data->mtu; return data->mtu;
break; break;
@ -654,9 +658,13 @@ static int BIO_dgram_should_retry(int i)
{ {
err=get_last_socket_error(); err=get_last_socket_error();
#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ #if defined(OPENSSL_SYS_WINDOWS)
if ((i == -1) && (err == 0)) /* If the socket return value (i) is -1
return(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 #endif
return(BIO_dgram_non_fatal_error(err)); return(BIO_dgram_non_fatal_error(err));
@ -719,7 +727,6 @@ int BIO_dgram_non_fatal_error(int err)
} }
return(0); return(0);
} }
#endif
static void get_current_time(struct timeval *t) static void get_current_time(struct timeval *t)
{ {
@ -737,3 +744,5 @@ static void get_current_time(struct timeval *t)
gettimeofday(t, NULL); gettimeofday(t, NULL);
#endif #endif
} }
#endif

View File

@ -539,8 +539,10 @@ $sbit=$num;
&jle (&label("sqradd")); &jle (&label("sqradd"));
&mov ($carry,"edx"); &mov ($carry,"edx");
&lea ("edx",&DWP(0,$sbit,"edx",2)); &add ("edx","edx");
&shr ($carry,31); &shr ($carry,31);
&add ("edx",$sbit);
&adc ($carry,0);
&set_label("sqrlast"); &set_label("sqrlast");
&mov ($word,$_n0); &mov ($word,$_n0);
&mov ($inp,$_np); &mov ($inp,$_np);

View File

@ -1039,7 +1039,7 @@ sub data {
addze r11,r0 addze r11,r0
#mul_add_c(a[3],b[2],c3,c1,c2); #mul_add_c(a[3],b[2],c3,c1,c2);
$LD r6,`3*$BNSZ`(r4) $LD r6,`3*$BNSZ`(r4)
$LD r7,`2*$BNSZ`(r4) $LD r7,`2*$BNSZ`(r5)
$UMULL r8,r6,r7 $UMULL r8,r6,r7
$UMULH r9,r6,r7 $UMULH r9,r6,r7
addc r12,r8,r12 addc r12,r8,r12

View File

@ -123,7 +123,7 @@ struct bn_blinding_st
BIGNUM *mod; /* just a reference */ BIGNUM *mod; /* just a reference */
unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; 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 */ * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
unsigned int counter; int counter;
unsigned long flags; unsigned long flags;
BN_MONT_CTX *m_ctx; BN_MONT_CTX *m_ctx;
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
@ -157,7 +157,10 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGN
if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
BN_set_flags(ret->mod, BN_FLG_CONSTTIME); 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); return(ret);
err: err:
if (ret != NULL) BN_BLINDING_free(ret); if (ret != NULL) BN_BLINDING_free(ret);
@ -186,7 +189,10 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
goto err; 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)) !(b->flags & BN_BLINDING_NO_RECREATE))
{ {
/* re-create blinding parameters */ /* re-create blinding parameters */
@ -201,8 +207,8 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
ret=1; ret=1;
err: err:
if (b->counter == 0) if (b->counter == BN_BLINDING_COUNTER)
b->counter = BN_BLINDING_COUNTER; b->counter = 0;
return(ret); return(ret);
} }
@ -223,6 +229,12 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
return(0); 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 (r != NULL)
{ {
if (!BN_copy(r, b->Ai)) ret=0; if (!BN_copy(r, b->Ai)) ret=0;
@ -243,22 +255,19 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct
int ret; int ret;
bn_check_top(n); 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) if (r != NULL)
ret = BN_mod_mul(n, n, r, b->mod, ctx); ret = BN_mod_mul(n, n, r, b->mod, ctx);
else 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); return(0);
}
ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
} }
bn_check_top(n); bn_check_top(n);
return(ret); return(ret);
} }

View File

@ -607,6 +607,7 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{ {
while (!BN_is_odd(u)) while (!BN_is_odd(u))
{ {
if (BN_is_zero(u)) goto err;
if (!BN_rshift1(u, u)) goto err; if (!BN_rshift1(u, u)) goto err;
if (BN_is_odd(b)) if (BN_is_odd(b))
{ {

View File

@ -60,6 +60,11 @@
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/buffer.h> #include <openssl/buffer.h>
/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
* function is applied in several functions in this file and this limit ensures
* that the result fits in an int. */
#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
BUF_MEM *BUF_MEM_new(void) BUF_MEM *BUF_MEM_new(void)
{ {
BUF_MEM *ret; BUF_MEM *ret;
@ -94,6 +99,11 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
char *ret; char *ret;
unsigned int n; unsigned int n;
if (len < 0)
{
BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
return 0;
}
if (str->length >= len) if (str->length >= len)
{ {
str->length=len; str->length=len;
@ -105,6 +115,12 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
str->length=len; str->length=len;
return(len); return(len);
} }
/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
if (len > LIMIT_BEFORE_EXPANSION)
{
BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
return 0;
}
n=(len+3)/3*4; n=(len+3)/3*4;
if (str->data == NULL) if (str->data == NULL)
ret=OPENSSL_malloc(n); ret=OPENSSL_malloc(n);
@ -130,6 +146,11 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int len)
char *ret; char *ret;
unsigned int n; unsigned int n;
if (len < 0)
{
BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
return 0;
}
if (str->length >= len) if (str->length >= len)
{ {
memset(&str->data[len],0,str->length-len); memset(&str->data[len],0,str->length-len);
@ -142,6 +163,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int len)
str->length=len; str->length=len;
return(len); return(len);
} }
/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
if (len > LIMIT_BEFORE_EXPANSION)
{
BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
return 0;
}
n=(len+3)/3*4; n=(len+3)/3*4;
if (str->data == NULL) if (str->data == NULL)
ret=OPENSSL_malloc(n); ret=OPENSSL_malloc(n);

View File

@ -110,6 +110,7 @@ DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest)
#define CMS_PARTIAL 0x4000 #define CMS_PARTIAL 0x4000
#define CMS_REUSE_DIGEST 0x8000 #define CMS_REUSE_DIGEST 0x8000
#define CMS_USE_KEYID 0x10000 #define CMS_USE_KEYID 0x10000
#define CMS_DEBUG_DECRYPT 0x20000
const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);

View File

@ -73,6 +73,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
const EVP_CIPHER *ciph; const EVP_CIPHER *ciph;
X509_ALGOR *calg = ec->contentEncryptionAlgorithm; X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
unsigned char *tkey = NULL;
size_t tkeylen;
int ok = 0; int ok = 0;
@ -137,32 +139,57 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
goto err; goto err;
} }
tkeylen = EVP_CIPHER_CTX_key_length(ctx);
/* Generate random session key */
if (enc && !ec->key) if (!enc || !ec->key)
{ {
/* Generate random key */ tkey = OPENSSL_malloc(tkeylen);
if (!ec->keylen) if (!tkey)
ec->keylen = EVP_CIPHER_CTX_key_length(ctx);
ec->key = OPENSSL_malloc(ec->keylen);
if (!ec->key)
{ {
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
ERR_R_MALLOC_FAILURE); ERR_R_MALLOC_FAILURE);
goto err; goto err;
} }
if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0) if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
goto err; 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 necessary set key length */
if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
{ {
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, /* Only reveal failure if debugging so we don't
CMS_R_INVALID_KEY_LENGTH); * leak information which may be useful in MMA.
goto err; */
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_EncryptedContentInfo *ec)
OPENSSL_free(ec->key); OPENSSL_free(ec->key);
ec->key = NULL; ec->key = NULL;
} }
if (tkey)
{
OPENSSL_cleanse(tkey, tkeylen);
OPENSSL_free(tkey);
}
if (ok) if (ok)
return b; return b;
BIO_free(b); BIO_free(b);

View File

@ -352,6 +352,8 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
unsigned char *ek = NULL; unsigned char *ek = NULL;
int eklen; int eklen;
int ret = 0; int ret = 0;
CMS_EncryptedContentInfo *ec;
ec = cms->d.envelopedData->encryptedContentInfo;
if (ktri->pkey == NULL) if (ktri->pkey == NULL)
{ {
@ -382,8 +384,14 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
ret = 1; ret = 1;
cms->d.envelopedData->encryptedContentInfo->key = ek; if (ec->key)
cms->d.envelopedData->encryptedContentInfo->keylen = eklen; {
OPENSSL_cleanse(ec->key, ec->keylen);
OPENSSL_free(ec->key);
}
ec->key = ek;
ec->keylen = eklen;
err: err:
if (!ret && ek) if (!ret && ek)

View File

@ -112,7 +112,7 @@ static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
cmsbio = tmpbio; cmsbio = tmpbio;
} }
return 1; return r;
} }

View File

@ -175,6 +175,8 @@ struct CMS_EncryptedContentInfo_st
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
unsigned char *key; unsigned char *key;
size_t keylen; size_t keylen;
/* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
int debug;
}; };
struct CMS_RecipientInfo_st struct CMS_RecipientInfo_st

View File

@ -622,7 +622,10 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
STACK_OF(CMS_RecipientInfo) *ris; STACK_OF(CMS_RecipientInfo) *ris;
CMS_RecipientInfo *ri; CMS_RecipientInfo *ri;
int i, r; int i, r;
int debug = 0;
ris = CMS_get0_RecipientInfos(cms); ris = CMS_get0_RecipientInfos(cms);
if (ris)
debug = cms->d.envelopedData->encryptedContentInfo->debug;
for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
{ {
ri = sk_CMS_RecipientInfo_value(ris, i); ri = sk_CMS_RecipientInfo_value(ris, i);
@ -636,17 +639,38 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
CMS_RecipientInfo_set0_pkey(ri, pk); CMS_RecipientInfo_set0_pkey(ri, pk);
r = CMS_RecipientInfo_decrypt(cms, ri); r = CMS_RecipientInfo_decrypt(cms, ri);
CMS_RecipientInfo_set0_pkey(ri, NULL); CMS_RecipientInfo_set0_pkey(ri, NULL);
if (r > 0)
return 1;
if (cert) 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, CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
CMS_R_DECRYPT_ERROR); CMS_R_DECRYPT_ERROR);
return 0; 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); CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
return 0; return 0;
@ -705,9 +729,14 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
} }
if (!dcont && !check_content(cms)) if (!dcont && !check_content(cms))
return 0; 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)) if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
return 0; return 0;
cont = CMS_dataInit(cms, dcont); cont = CMS_dataInit(cms, dcont);
if (!cont) if (!cont)
return 0; return 0;

View File

@ -46,7 +46,7 @@ static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
{ {
int i; int i;
if (olen < (ilen-1)) if (ilen == 0 || olen < (ilen-1))
{ {
/* ZZZZZZZZZZZZZZZZZZZZZZ */ /* ZZZZZZZZZZZZZZZZZZZZZZ */
return(-1); return(-1);
@ -59,4 +59,3 @@ static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
} }
return(ilen-1); return(ilen-1);
} }

View File

@ -64,6 +64,7 @@
#endif #endif
#include <assert.h> #include <assert.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/conf_api.h> #include <openssl/conf_api.h>

View File

@ -396,7 +396,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
ERR_remove_state(0);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
break; break;

View File

@ -588,15 +588,15 @@ int OPENSSL_isservice(void);
#endif /* def OPENSSL_FIPS */ #endif /* def OPENSSL_FIPS */
#define OPENSSL_HAVE_INIT 1
void OPENSSL_init(void);
/* BEGIN ERROR CODES */ /* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes /* 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. * made after this point may be overwritten when the script is next run.
*/ */
void ERR_load_CRYPTO_strings(void); void ERR_load_CRYPTO_strings(void);
#define OPENSSL_HAVE_INIT 1
void OPENSSL_init(void);
/* Error codes for the CRYPTO functions. */ /* Error codes for the CRYPTO functions. */
/* Function codes. */ /* Function codes. */

View File

@ -821,7 +821,7 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_
field_sqr = group->meth->field_sqr; field_sqr = group->meth->field_sqr;
/* only support affine coordinates */ /* only support affine coordinates */
if (!point->Z_is_one) goto err; if (!point->Z_is_one) return -1;
if (ctx == NULL) if (ctx == NULL)
{ {
@ -871,6 +871,9 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT
{ {
return EC_POINT_is_at_infinity(group, b) ? 0 : 1; 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) if (a->Z_is_one && b->Z_is_one)
{ {

View File

@ -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); ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
return 0; 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) if ((ctx = BN_CTX_new()) == NULL)
goto err; goto err;
if ((point = EC_POINT_new(eckey->group)) == NULL) if ((point = EC_POINT_new(eckey->group)) == NULL)

View File

@ -1406,6 +1406,9 @@ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *
{ {
return EC_POINT_is_at_infinity(group, b) ? 0 : 1; 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) if (a->Z_is_one && b->Z_is_one)
{ {

View File

@ -168,10 +168,9 @@ int fbytes(unsigned char *buf, int num)
return 0; return 0;
} }
fbytes_counter ++; fbytes_counter ++;
ret = BN_bn2bin(tmp, buf); if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
if (ret == 0 || ret != num)
ret = 0; ret = 0;
else else
ret = 1; ret = 1;
if (tmp) if (tmp)
BN_free(tmp); BN_free(tmp);
@ -287,9 +286,13 @@ int test_builtin(BIO *out)
size_t crv_len = 0, n = 0; size_t crv_len = 0, n = 0;
EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_KEY *eckey = NULL, *wrong_eckey = NULL;
EC_GROUP *group; EC_GROUP *group;
ECDSA_SIG *ecdsa_sig = NULL;
unsigned char digest[20], wrong_digest[20]; unsigned char digest[20], wrong_digest[20];
unsigned char *signature = NULL; unsigned char *signature = NULL;
unsigned int sig_len; 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; int nid, ret = 0;
/* fill digest values with some random data */ /* fill digest values with some random data */
@ -339,7 +342,8 @@ int test_builtin(BIO *out)
if (EC_KEY_set_group(eckey, group) == 0) if (EC_KEY_set_group(eckey, group) == 0)
goto builtin_err; goto builtin_err;
EC_GROUP_free(group); 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 */ /* drop the curve */
{ {
EC_KEY_free(eckey); EC_KEY_free(eckey);
@ -415,26 +419,89 @@ int test_builtin(BIO *out)
} }
BIO_printf(out, "."); BIO_printf(out, ".");
(void)BIO_flush(out); (void)BIO_flush(out);
/* modify a single byte of the signature */ /* wrong length */
offset = signature[10] % sig_len; if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
dirt = signature[11]; eckey) == 1)
signature[offset] ^= dirt ? dirt : 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) if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
{ {
BIO_printf(out, " failed\n"); BIO_printf(out, " failed\n");
goto builtin_err; 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, "."); BIO_printf(out, ".");
(void)BIO_flush(out); (void)BIO_flush(out);
BIO_printf(out, " ok\n"); BIO_printf(out, " ok\n");
/* cleanup */ /* cleanup */
/* clean bogus errors */
ERR_clear_error();
OPENSSL_free(signature); OPENSSL_free(signature);
signature = NULL; signature = NULL;
EC_KEY_free(eckey); EC_KEY_free(eckey);
eckey = NULL; eckey = NULL;
EC_KEY_free(wrong_eckey); EC_KEY_free(wrong_eckey);
wrong_eckey = NULL; wrong_eckey = NULL;
ECDSA_SIG_free(ecdsa_sig);
ecdsa_sig = NULL;
OPENSSL_free(raw_buf);
raw_buf = NULL;
} }
ret = 1; ret = 1;
@ -443,8 +510,12 @@ int test_builtin(BIO *out)
EC_KEY_free(eckey); EC_KEY_free(eckey);
if (wrong_eckey) if (wrong_eckey)
EC_KEY_free(wrong_eckey); EC_KEY_free(wrong_eckey);
if (ecdsa_sig)
ECDSA_SIG_free(ecdsa_sig);
if (signature) if (signature)
OPENSSL_free(signature); OPENSSL_free(signature);
if (raw_buf)
OPENSSL_free(raw_buf);
if (curves) if (curves)
OPENSSL_free(curves); OPENSSL_free(curves);

View File

@ -144,6 +144,14 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
} }
while (BN_is_zero(k)); 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 */ /* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
{ {

View File

@ -435,6 +435,7 @@ int main(int argc,char **argv)
EXIT(3); EXIT(3);
} }
} }
fclose(f);
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
ENGINE_cleanup(); ENGINE_cleanup();

View File

@ -372,6 +372,10 @@ void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
if (num <= 0) return NULL; if (num <= 0) return NULL;
/* We don't support shrinking the buffer. Note the memcpy that copies
* |old_len| bytes to the new buffer, below. */
if (num < old_len) return NULL;
if (realloc_debug_func != NULL) if (realloc_debug_func != NULL)
realloc_debug_func(str, NULL, num, file, line, 0); realloc_debug_func(str, NULL, num, file, line, 0);
ret=malloc_ex_func(num,file,line); ret=malloc_ex_func(num,file,line);

View File

@ -169,14 +169,14 @@ int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pss
char *host, *port; char *host, *port;
/* dup the buffer since we are going to mess with it */
buf = BUF_strdup(url);
if (!buf) goto mem_err;
*phost = NULL; *phost = NULL;
*pport = NULL; *pport = NULL;
*ppath = NULL; *ppath = NULL;
/* dup the buffer since we are going to mess with it */
buf = BUF_strdup(url);
if (!buf) goto mem_err;
/* Check for initial colon */ /* Check for initial colon */
p = strchr(buf, ':'); p = strchr(buf, ':');

View File

@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta) * major minor fix final patch/beta)
*/ */
#define OPENSSL_VERSION_NUMBER 0x0090811f #define OPENSSL_VERSION_NUMBER 0x0090818fL
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q-fips 2 Dec 2010" #define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8x-fips 10 May 2012"
#else #else
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q 2 Dec 2010" #define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8x 10 May 2012"
#endif #endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@ -158,7 +158,6 @@ sub cbc
&jmp_ptr($count); &jmp_ptr($count);
&set_label("ej7"); &set_label("ej7");
&xor("edx", "edx") if $ppro; # ppro friendly
&movb(&HB("edx"), &BP(6,$in,"",0)); &movb(&HB("edx"), &BP(6,$in,"",0));
&shl("edx",8); &shl("edx",8);
&set_label("ej6"); &set_label("ej6");
@ -170,7 +169,6 @@ sub cbc
&jmp(&label("ejend")); &jmp(&label("ejend"));
&set_label("ej3"); &set_label("ej3");
&movb(&HB("ecx"), &BP(2,$in,"",0)); &movb(&HB("ecx"), &BP(2,$in,"",0));
&xor("ecx", "ecx") if $ppro; # ppro friendly
&shl("ecx",8); &shl("ecx",8);
&set_label("ej2"); &set_label("ej2");
&movb(&HB("ecx"), &BP(1,$in,"",0)); &movb(&HB("ecx"), &BP(1,$in,"",0));

View File

@ -420,6 +420,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
int max; int max;
X509_OBJECT ret; X509_OBJECT ret;
#endif #endif
unsigned char *tkey = NULL;
int tkeylen;
int jj; int jj;
if ((etmp=BIO_new(BIO_f_cipher())) == NULL) if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
@ -461,36 +463,42 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
if (pcert == NULL) if (pcert == NULL)
{ {
/* Temporary storage in case EVP_PKEY_decrypt
* overwrites output buffer on error.
*/
unsigned char *tmp2;
tmp2 = OPENSSL_malloc(jj);
if (!tmp2)
goto err;
jj = -1;
/* Always attempt to decrypt all cases to avoid
* leaking timing information about a successful
* decrypt.
*/
for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
{ {
int tret;
ri=sk_PKCS7_RECIP_INFO_value(rsk,i); ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
jj=EVP_PKEY_decrypt(tmp, tret=EVP_PKEY_decrypt(tmp2,
M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_data(ri->enc_key),
M_ASN1_STRING_length(ri->enc_key), M_ASN1_STRING_length(ri->enc_key),
pkey); pkey);
if (jj > 0) if (tret > 0)
break; {
memcpy(tmp, tmp2, tret);
OPENSSL_cleanse(tmp2, tret);
jj = tret;
}
ERR_clear_error(); ERR_clear_error();
ri = NULL;
}
if (ri == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
goto err;
} }
OPENSSL_free(tmp2);
} }
else else
{ {
jj=EVP_PKEY_decrypt(tmp, jj=EVP_PKEY_decrypt(tmp,
M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_data(ri->enc_key),
M_ASN1_STRING_length(ri->enc_key), pkey); M_ASN1_STRING_length(ri->enc_key), pkey);
if (jj <= 0) ERR_clear_error();
{
PKCS7err(PKCS7_F_PKCS7_DATADECODE,
ERR_R_EVP_LIB);
goto err;
}
} }
evp_ctx=NULL; evp_ctx=NULL;
@ -499,24 +507,49 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
goto err; goto err;
if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
goto err; goto err;
/* Generate random key to counter MMA */
tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
tkey = OPENSSL_malloc(tkeylen);
if (!tkey)
goto err;
if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
goto err;
/* If we have no key use random key */
if (jj <= 0)
{
OPENSSL_free(tmp);
jj = tkeylen;
tmp = tkey;
tkey = NULL;
}
if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { if (jj != tkeylen) {
/* Some S/MIME clients don't use the same key /* Some S/MIME clients don't use the same key
* and effective key length. The key length is * and effective key length. The key length is
* determined by the size of the decrypted RSA key. * determined by the size of the decrypted RSA key.
*/ */
if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
{ {
PKCS7err(PKCS7_F_PKCS7_DATADECODE, /* As MMA defence use random key instead */
PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); OPENSSL_cleanse(tmp, jj);
goto err; OPENSSL_free(tmp);
jj = tkeylen;
tmp = tkey;
tkey = NULL;
} }
} }
ERR_clear_error();
if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0)
goto err; goto err;
OPENSSL_cleanse(tmp,jj); OPENSSL_cleanse(tmp,jj);
if (tkey)
{
OPENSSL_cleanse(tkey, tkeylen);
OPENSSL_free(tkey);
}
if (out == NULL) if (out == NULL)
out=etmp; out=etmp;
else else

View File

@ -486,15 +486,34 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
return 0; return 0;
} }
ret = SMIME_text(bread, data); 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); BIO_free_all(bread);
return ret; return ret;
} else { } else {
for(;;) { for(;;) {
i = BIO_read(tmpmem, buf, sizeof(buf)); i = BIO_read(tmpmem, buf, sizeof(buf));
if(i <= 0) break; if(i <= 0)
BIO_write(data, buf, i); {
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); BIO_free_all(tmpmem);
return 1; return ret;
} }
} }

View File

@ -167,7 +167,7 @@ $code.=<<___;
movzb ($dat,$XX[0]),$TX[0]#d movzb ($dat,$XX[0]),$TX[0]#d
test \$-8,$len test \$-8,$len
jz .Lcloop1 jz .Lcloop1
cmp \$0,260($dat) cmpl \$0,260($dat)
jnz .Lcloop1 jnz .Lcloop1
push %rbx push %rbx
jmp .Lcloop8 jmp .Lcloop8

View File

@ -138,9 +138,9 @@ void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
*/ */
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc();
if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { if (ia32cap_ptr && (*ia32cap_ptr & (1<<20))) {
#else #else
if (OPENSSL_ia32cap_P & (1<<28)) { if (OPENSSL_ia32cap_P & (1<<20)) {
#endif #endif
unsigned char *cp=(unsigned char *)d; unsigned char *cp=(unsigned char *)d;

View File

@ -312,51 +312,56 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
return ret; return ret;
} }
static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
BIGNUM *r, BN_CTX *ctx) BN_CTX *ctx)
{ {
if (local) if (unblind == NULL)
/* Local blinding: store the unblinding factor
* in BN_BLINDING. */
return BN_BLINDING_convert_ex(f, NULL, b, ctx); return BN_BLINDING_convert_ex(f, NULL, b, ctx);
else else
{ {
int ret; /* Shared blinding: store the unblinding factor
CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); * outside BN_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; int ret;
CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); 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); CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
return ret; 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 */ /* signing */
static int RSA_eay_private_encrypt(int flen, const unsigned char *from, static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding) unsigned char *to, RSA *rsa, int padding)
{ {
BIGNUM *f, *ret, *br, *res; BIGNUM *f, *ret, *res;
int i,j,k,num=0,r= -1; int i,j,k,num=0,r= -1;
unsigned char *buf=NULL; unsigned char *buf=NULL;
BN_CTX *ctx=NULL; BN_CTX *ctx=NULL;
int local_blinding = 0; 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; BN_BLINDING *blinding = NULL;
if ((ctx=BN_CTX_new()) == NULL) goto err; if ((ctx=BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx); BN_CTX_start(ctx);
f = BN_CTX_get(ctx); f = BN_CTX_get(ctx);
br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx); ret = BN_CTX_get(ctx);
num = BN_num_bytes(rsa->n); num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num); buf = OPENSSL_malloc(num);
@ -404,8 +409,15 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
} }
if (blinding != NULL) 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; goto err;
}
if (!rsa_blinding_convert(blinding, f, unblind, ctx))
goto err;
}
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) && ((rsa->p != NULL) &&
@ -439,7 +451,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
} }
if (blinding) if (blinding)
if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err; goto err;
if (padding == RSA_X931_PADDING) if (padding == RSA_X931_PADDING)
@ -478,18 +490,21 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
static int RSA_eay_private_decrypt(int flen, const unsigned char *from, static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding) unsigned char *to, RSA *rsa, int padding)
{ {
BIGNUM *f, *ret, *br; BIGNUM *f, *ret;
int j,num=0,r= -1; int j,num=0,r= -1;
unsigned char *p; unsigned char *p;
unsigned char *buf=NULL; unsigned char *buf=NULL;
BN_CTX *ctx=NULL; BN_CTX *ctx=NULL;
int local_blinding = 0; 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; BN_BLINDING *blinding = NULL;
if((ctx = BN_CTX_new()) == NULL) goto err; if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx); BN_CTX_start(ctx);
f = BN_CTX_get(ctx); f = BN_CTX_get(ctx);
br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx); ret = BN_CTX_get(ctx);
num = BN_num_bytes(rsa->n); num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num); buf = OPENSSL_malloc(num);
@ -527,8 +542,15 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
} }
if (blinding != NULL) 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; goto err;
}
if (!rsa_blinding_convert(blinding, f, unblind, ctx))
goto err;
}
/* do the decrypt */ /* do the decrypt */
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@ -562,7 +584,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
} }
if (blinding) if (blinding)
if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
goto err; goto err;
p=buf; p=buf;

View File

@ -1097,7 +1097,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
atm.length=sizeof(buff2); atm.length=sizeof(buff2);
atm.data=(unsigned char *)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; return 0;
if (ctm->type == V_ASN1_UTCTIME) if (ctm->type == V_ASN1_UTCTIME)

View File

@ -70,8 +70,6 @@ static int ref_cmp(const X509_POLICY_REF * const *a,
static void policy_map_free(X509_POLICY_REF *map) static void policy_map_free(X509_POLICY_REF *map)
{ {
if (map->subjectDomainPolicy)
ASN1_OBJECT_free(map->subjectDomainPolicy);
OPENSSL_free(map); OPENSSL_free(map);
} }
@ -95,6 +93,7 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
{ {
POLICY_MAPPING *map; POLICY_MAPPING *map;
X509_POLICY_REF *ref = NULL; X509_POLICY_REF *ref = NULL;
ASN1_OBJECT *subjectDomainPolicyRef;
X509_POLICY_DATA *data; X509_POLICY_DATA *data;
X509_POLICY_CACHE *cache = x->policy_cache; X509_POLICY_CACHE *cache = x->policy_cache;
int i; int i;
@ -153,13 +152,16 @@ int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
if (!sk_ASN1_OBJECT_push(data->expected_policy_set, if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
map->subjectDomainPolicy)) map->subjectDomainPolicy))
goto bad_mapping; goto bad_mapping;
/* map->subjectDomainPolicy will be freed when
* cache->data is freed. Set it to NULL to avoid double-free. */
subjectDomainPolicyRef = map->subjectDomainPolicy;
map->subjectDomainPolicy = NULL;
ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); ref = OPENSSL_malloc(sizeof(X509_POLICY_REF));
if (!ref) if (!ref)
goto bad_mapping; goto bad_mapping;
ref->subjectDomainPolicy = map->subjectDomainPolicy; ref->subjectDomainPolicy = subjectDomainPolicyRef;
map->subjectDomainPolicy = NULL;
ref->data = data; ref->data = data;
if (!sk_X509_POLICY_REF_push(cache->maps, ref)) if (!sk_X509_POLICY_REF_push(cache->maps, ref))

View File

@ -612,6 +612,10 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
case 2: case 2:
return 1; return 1;
/* Some internal error */
case -1:
return -1;
/* Some internal error */ /* Some internal error */
case 0: case 0:
return 0; return 0;
@ -691,4 +695,3 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
return 0; return 0;
} }

View File

@ -142,12 +142,13 @@ unsigned int v3_addr_get_afi(const IPAddressFamily *f)
* Expand the bitstring form of an address into a raw byte array. * Expand the bitstring form of an address into a raw byte array.
* At the moment this is coded for simplicity, not speed. * 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 ASN1_BIT_STRING *bs,
const int length, const int length,
const unsigned char fill) 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) { if (bs->length > 0) {
memcpy(addr, bs->data, bs->length); memcpy(addr, bs->data, bs->length);
if ((bs->flags & 7) != 0) { if ((bs->flags & 7) != 0) {
@ -159,6 +160,7 @@ static void addr_expand(unsigned char *addr,
} }
} }
memset(addr + bs->length, fill, length - bs->length); 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]; unsigned char addr[ADDR_RAW_BUF_LEN];
int i, n; int i, n;
if (bs->length < 0)
return 0;
switch (afi) { switch (afi) {
case IANA_AFI_IPV4: 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]); BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
break; break;
case IANA_AFI_IPV6: 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 (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)
; ;
for (i = 0; i < n; i += 2) for (i = 0; i < n; i += 2)
@ -309,6 +315,12 @@ static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,
/* /*
* Sort comparison function for a sequence of IPAddressOrRange * Sort comparison function for a sequence of IPAddressOrRange
* elements. * 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, static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
const IPAddressOrRange *b, const IPAddressOrRange *b,
@ -321,22 +333,26 @@ static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
switch (a->type) { switch (a->type) {
case IPAddressOrRange_addressPrefix: 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); prefixlen_a = addr_prefixlen(a->u.addressPrefix);
break; break;
case IPAddressOrRange_addressRange: 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; prefixlen_a = length * 8;
break; break;
} }
switch (b->type) { switch (b->type) {
case IPAddressOrRange_addressPrefix: 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); prefixlen_b = addr_prefixlen(b->u.addressPrefix);
break; break;
case IPAddressOrRange_addressRange: 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; prefixlen_b = length * 8;
break; break;
} }
@ -378,6 +394,7 @@ static int range_should_be_prefix(const unsigned char *min,
unsigned char mask; unsigned char mask;
int i, j; int i, j;
OPENSSL_assert(memcmp(min, max, length) <= 0);
for (i = 0; i < length && min[i] == max[i]; i++) for (i = 0; i < length && min[i] == max[i]; i++)
; ;
for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) 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. * 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 *min,
unsigned char *max, unsigned char *max,
int length) int length)
{ {
OPENSSL_assert(aor != NULL && min != NULL && max != NULL); if (aor == NULL || min == NULL || max == NULL)
return 0;
switch (aor->type) { switch (aor->type) {
case IPAddressOrRange_addressPrefix: case IPAddressOrRange_addressPrefix:
addr_expand(min, aor->u.addressPrefix, length, 0x00); return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
addr_expand(max, aor->u.addressPrefix, length, 0xFF); addr_expand(max, aor->u.addressPrefix, length, 0xFF));
return;
case IPAddressOrRange_addressRange: case IPAddressOrRange_addressRange:
addr_expand(min, aor->u.addressRange->min, length, 0x00); return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
addr_expand(max, aor->u.addressRange->max, length, 0xFF); addr_expand(max, aor->u.addressRange->max, length, 0xFF));
return;
} }
return 0;
} }
/* /*
@ -682,9 +699,10 @@ int v3_addr_get_range(IPAddressOrRange *aor,
if (aor == NULL || min == NULL || max == NULL || if (aor == NULL || min == NULL || max == NULL ||
afi_length == 0 || length < afi_length || afi_length == 0 || length < afi_length ||
(aor->type != IPAddressOrRange_addressPrefix && (aor->type != IPAddressOrRange_addressPrefix &&
aor->type != IPAddressOrRange_addressRange)) aor->type != IPAddressOrRange_addressRange) ||
!extract_min_max(aor, min, max, afi_length))
return 0; return 0;
extract_min_max(aor, min, max, afi_length);
return afi_length; return afi_length;
} }
@ -766,8 +784,9 @@ int v3_addr_is_canonical(IPAddrBlocks *addr)
IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
extract_min_max(a, a_min, a_max, length); if (!extract_min_max(a, a_min, a_max, length) ||
extract_min_max(b, b_min, b_max, length); !extract_min_max(b, b_min, b_max, length))
return 0;
/* /*
* Punt misordered list, overlapping start, or inverted range. * Punt misordered list, overlapping start, or inverted range.
@ -795,14 +814,17 @@ 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; j = sk_IPAddressOrRange_num(aors) - 1;
{ {
IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
if (a->type == IPAddressOrRange_addressRange) { if (a != NULL && a->type == IPAddressOrRange_addressRange) {
extract_min_max(a, a_min, a_max, length); if (!extract_min_max(a, a_min, a_max, length))
if (range_should_be_prefix(a_min, a_max, length) >= 0) return 0;
if (memcmp(a_min, a_max, length) > 0 ||
range_should_be_prefix(a_min, a_max, length) >= 0)
return 0; return 0;
} }
} }
@ -836,8 +858,16 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; 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]; unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
extract_min_max(a, a_min, a_max, length); if (!extract_min_max(a, a_min, a_max, length) ||
extract_min_max(b, b_min, b_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. * Punt overlaps.
@ -864,6 +894,20 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
} }
} }
/*
* 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; return 1;
} }
@ -1012,6 +1056,11 @@ static void *v2i_IPAddrBlocks(struct v3_ext_method *method,
X509V3_conf_err(val); X509V3_conf_err(val);
goto err; 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)) { if (!v3_addr_add_range(addr, afi, safi, min, max)) {
X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
goto err; goto err;
@ -1097,13 +1146,15 @@ static int addr_contains(IPAddressOrRanges *parent,
p = 0; p = 0;
for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
extract_min_max(sk_IPAddressOrRange_value(child, c), if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
c_min, c_max, length); c_min, c_max, length))
return -1;
for (;; p++) { for (;; p++) {
if (p >= sk_IPAddressOrRange_num(parent)) if (p >= sk_IPAddressOrRange_num(parent))
return 0; return 0;
extract_min_max(sk_IPAddressOrRange_value(parent, p), if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
p_min, p_max, length); p_min, p_max, length))
return 0;
if (memcmp(p_max, c_max, length) < 0) if (memcmp(p_max, c_max, length) < 0)
continue; continue;
if (memcmp(p_min, c_min, length) > 0) if (memcmp(p_min, c_min, length) > 0)

View File

@ -61,7 +61,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
@ -172,11 +171,11 @@ static int ASIdOrRange_cmp(const ASIdOrRange * const *a_,
{ {
const ASIdOrRange *a = *a_, *b = *b_; 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->type == ASIdOrRange_range && a->u.range != NULL &&
a->u.range->min != NULL && a->u.range->max != 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->type == ASIdOrRange_range && b->u.range != NULL &&
b->u.range->min != NULL && b->u.range->max != NULL)); b->u.range->min != NULL && b->u.range->max != NULL));
@ -215,7 +214,7 @@ int v3_asid_add_inherit(ASIdentifiers *asid, int which)
if (*choice == NULL) { if (*choice == NULL) {
if ((*choice = ASIdentifierChoice_new()) == NULL) if ((*choice = ASIdentifierChoice_new()) == NULL)
return 0; return 0;
assert((*choice)->u.inherit == NULL); OPENSSL_assert((*choice)->u.inherit == NULL);
if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
return 0; return 0;
(*choice)->type = ASIdentifierChoice_inherit; (*choice)->type = ASIdentifierChoice_inherit;
@ -250,7 +249,7 @@ int v3_asid_add_id_or_range(ASIdentifiers *asid,
if (*choice == NULL) { if (*choice == NULL) {
if ((*choice = ASIdentifierChoice_new()) == NULL) if ((*choice = ASIdentifierChoice_new()) == NULL)
return 0; return 0;
assert((*choice)->u.asIdsOrRanges == NULL); OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
(*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
if ((*choice)->u.asIdsOrRanges == NULL) if ((*choice)->u.asIdsOrRanges == NULL)
return 0; return 0;
@ -286,7 +285,7 @@ static void extract_min_max(ASIdOrRange *aor,
ASN1_INTEGER **min, ASN1_INTEGER **min,
ASN1_INTEGER **max) ASN1_INTEGER **max)
{ {
assert(aor != NULL && min != NULL && max != NULL); OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
switch (aor->type) { switch (aor->type) {
case ASIdOrRange_id: case ASIdOrRange_id:
*min = aor->u.id; *min = aor->u.id;
@ -359,6 +358,20 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
goto done; 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; ret = 1;
done: done:
@ -373,7 +386,7 @@ static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
int v3_asid_is_canonical(ASIdentifiers *asid) int v3_asid_is_canonical(ASIdentifiers *asid)
{ {
return (asid == NULL || return (asid == NULL ||
(ASIdentifierChoice_is_canonical(asid->asnum) || (ASIdentifierChoice_is_canonical(asid->asnum) &&
ASIdentifierChoice_is_canonical(asid->rdi))); ASIdentifierChoice_is_canonical(asid->rdi)));
} }
@ -393,9 +406,18 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
return 1; return 1;
/* /*
* We have a list. Sort it. * If not a list, or if empty list, it's broken.
*/
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.
*/ */
assert(choice->type == ASIdentifierChoice_asIdsOrRanges);
sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
/* /*
@ -413,7 +435,14 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
/* /*
* Make sure we're properly sorted (paranoia). * 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. * Check for overlaps.
@ -466,13 +495,27 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
break; break;
} }
ASIdOrRange_free(b); ASIdOrRange_free(b);
(void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); (void) sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
i--; i--;
continue; 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; ret = 1;
@ -499,6 +542,7 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
struct v3_ext_ctx *ctx, struct v3_ext_ctx *ctx,
STACK_OF(CONF_VALUE) *values) STACK_OF(CONF_VALUE) *values)
{ {
ASN1_INTEGER *min = NULL, *max = NULL;
ASIdentifiers *asid = NULL; ASIdentifiers *asid = NULL;
int i; int i;
@ -509,7 +553,6 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
for (i = 0; i < sk_CONF_VALUE_num(values); i++) { for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
CONF_VALUE *val = sk_CONF_VALUE_value(values, i); CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
ASN1_INTEGER *min = NULL, *max = NULL;
int i1, i2, i3, is_range, which; int i1, i2, i3, is_range, which;
/* /*
@ -579,18 +622,19 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
max = s2i_ASN1_INTEGER(NULL, s + i2); max = s2i_ASN1_INTEGER(NULL, s + i2);
OPENSSL_free(s); OPENSSL_free(s);
if (min == NULL || max == NULL) { if (min == NULL || max == NULL) {
ASN1_INTEGER_free(min);
ASN1_INTEGER_free(max);
X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err; 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)) { 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); X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
goto err; goto err;
} }
min = max = NULL;
} }
/* /*
@ -602,6 +646,8 @@ static void *v2i_ASIdentifiers(struct v3_ext_method *method,
err: err:
ASIdentifiers_free(asid); ASIdentifiers_free(asid);
ASN1_INTEGER_free(min);
ASN1_INTEGER_free(max);
return NULL; return NULL;
} }
@ -709,9 +755,9 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
int i, ret = 1, inherit_as = 0, inherit_rdi = 0; int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
X509 *x = NULL; X509 *x = NULL;
assert(chain != NULL && sk_X509_num(chain) > 0); OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
assert(ctx != NULL || ext != NULL); OPENSSL_assert(ctx != NULL || ext != NULL);
assert(ctx == NULL || ctx->verify_cb != NULL); OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
/* /*
* Figure out where to start. If we don't have an extension to * 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_STORE_CTX *ctx,
} else { } else {
i = 0; i = 0;
x = sk_X509_value(chain, i); x = sk_X509_value(chain, i);
assert(x != NULL); OPENSSL_assert(x != NULL);
if ((ext = x->rfc3779_asid) == NULL) if ((ext = x->rfc3779_asid) == NULL)
goto done; goto done;
} }
@ -756,7 +802,7 @@ static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx,
*/ */
for (i++; i < sk_X509_num(chain); i++) { for (i++; i < sk_X509_num(chain); i++) {
x = sk_X509_value(chain, i); x = sk_X509_value(chain, i);
assert(x != NULL); OPENSSL_assert(x != NULL);
if (x->rfc3779_asid == NULL) { if (x->rfc3779_asid == NULL) {
if (child_as != NULL || child_rdi != NULL) if (child_as != NULL || child_rdi != NULL)
validation_err(X509_V_ERR_UNNESTED_RESOURCE); validation_err(X509_V_ERR_UNNESTED_RESOURCE);

View File

@ -57,7 +57,7 @@ following methods:
- in all other cases, proxy certificate validation can be enabled - in all other cases, proxy certificate validation can be enabled
before starting the application by setting the envirnoment variable 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 There are thoughts to allow proxy certificates with a line in the
default openssl.cnf, but that's still in the future. default openssl.cnf, but that's still in the future.

View File

@ -39,10 +39,16 @@ for a description of the method's properties.
SSL_clear() resets the SSL object to allow for another connection. The SSL_clear() resets the SSL object to allow for another connection. The
reset operation however keeps several settings of the last sessions reset operation however keeps several settings of the last sessions
(some of these settings were made automatically during the last (some of these settings were made automatically during the last
handshake). It only makes sense when opening a new session (or reusing handshake). It only makes sense for a new connection with the exact
an old one) with the same peer that shares these settings. same peer that shares these settings, and may fail if that peer
SSL_clear() is not a short form for the sequence changes its settings between connections. Use the sequence
L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>; . 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 =head1 RETURN VALUES

View File

@ -420,28 +420,36 @@ static int capi_init(ENGINE *e)
CAPI_CTX *ctx; CAPI_CTX *ctx;
const RSA_METHOD *ossl_rsa_meth; const RSA_METHOD *ossl_rsa_meth;
const DSA_METHOD *ossl_dsa_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(); ctx = capi_ctx_new();
if (!ctx || (capi_idx < 0)) if (!ctx)
goto memerr; goto memerr;
ENGINE_set_ex_data(e, capi_idx, ctx); 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 #ifdef OPENSSL_CAPIENG_DIALOG
{ {
@ -1133,6 +1141,7 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
{ {
CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
capi_addlasterror(); capi_addlasterror();
CryptReleaseContext(hprov, 0);
return 0; return 0;
} }
CAPI_trace(ctx, "Got max container len %d\n", buflen); CAPI_trace(ctx, "Got max container len %d\n", buflen);
@ -1550,6 +1559,8 @@ static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int che
} }
CryptReleaseContext(hprov, 0); CryptReleaseContext(hprov, 0);
} }
if (ctx->cspname)
OPENSSL_free(ctx->cspname);
ctx->cspname = BUF_strdup(pname); ctx->cspname = BUF_strdup(pname);
ctx->csptype = type; ctx->csptype = type;
return 1; return 1;
@ -1559,9 +1570,12 @@ static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
{ {
LPSTR pname; LPSTR pname;
DWORD type; DWORD type;
int res;
if (capi_get_provname(ctx, &pname, &type, idx) != 1) if (capi_get_provname(ctx, &pname, &type, idx) != 1)
return 0; 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) static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)

View File

@ -55,6 +55,10 @@
#ifndef HEADER_CAPI_ERR_H #ifndef HEADER_CAPI_ERR_H
#define HEADER_CAPI_ERR_H #define HEADER_CAPI_ERR_H
#ifdef __cplusplus
extern "C" {
#endif
/* BEGIN ERROR CODES */ /* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes /* 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. * made after this point may be overwritten when the script is next run.

View File

@ -19,6 +19,7 @@
(defined(__linux) && (defined(__arm) || defined(__arm__))) || \ (defined(__linux) && (defined(__arm) || defined(__arm__))) || \
(defined(__i386) || defined(__i386__)) || \ (defined(__i386) || defined(__i386__)) || \
(defined(__x86_64) || defined(__x86_64__)) || \ (defined(__x86_64) || defined(__x86_64__)) || \
defined(__ANDROID__) || \
(defined(vax) || defined(__vax__)) (defined(vax) || defined(__vax__))
# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION # define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
# endif # endif

View File

@ -2,7 +2,7 @@
%define libmaj 0 %define libmaj 0
%define libmin 9 %define libmin 9
%define librel 8 %define librel 8
%define librev q %define librev x
Release: 1 Release: 1
%define openssldir /var/ssl %define openssldir /var/ssl

View File

@ -348,7 +348,11 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
break; break;
case BIO_C_SET_SSL: case BIO_C_SET_SSL:
if (ssl != NULL) if (ssl != NULL)
{
ssl_free(b); ssl_free(b);
if (!ssl_new(b))
return 0;
}
b->shutdown=(int)num; b->shutdown=(int)num;
ssl=(SSL *)ptr; ssl=(SSL *)ptr;
((BIO_SSL *)b->ptr)->ssl=ssl; ((BIO_SSL *)b->ptr)->ssl=ssl;

View File

@ -153,12 +153,11 @@
#endif #endif
static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; 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 */ /* XDTLS: figure out the right values */
static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; 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 unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
unsigned long frag_len); unsigned long frag_len);
@ -228,14 +227,14 @@ int dtls1_do_write(SSL *s, int type)
unsigned int len, frag_off, mac_size, blocksize; unsigned int len, frag_off, mac_size, blocksize;
/* AHA! Figure out the MTU, and stick to the right size */ /* 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 = s->d1->mtu =
BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 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 /* I've seen the kernel return bogus numbers when it doesn't know
* (initial write), so just make sure we have a reasonable number */ * (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 = 0;
s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
@ -264,11 +263,10 @@ int dtls1_do_write(SSL *s, int type)
return ret; return ret;
mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
} }
OPENSSL_assert(mtu > 0); /* should have something reasonable now */
#endif #endif
OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */
if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
OPENSSL_assert(s->init_num == OPENSSL_assert(s->init_num ==
(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
@ -464,20 +462,9 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
s->d1->handshake_read_seq++; /* Don't change sequence numbers while listening */
/* we just read a handshake message from the other side: if (!s->d1->listen)
* this means that we don't need to retransmit of the s->d1->handshake_read_seq++;
* 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);
s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
return s->init_num; return s->init_num;
@ -806,16 +793,24 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
*ok = 0; *ok = 0;
return i; 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 */ /* parse the message fragment header */
dtls1_get_message_header(wire, &msg_hdr); dtls1_get_message_header(wire, &msg_hdr);
/* /*
* if this is a future (or stale) message it gets buffered * 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); return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
len = msg_hdr.msg_len; len = msg_hdr.msg_len;
@ -876,7 +871,12 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
/* XDTLS: an incorrectly formatted fragment should cause the /* XDTLS: an incorrectly formatted fragment should cause the
* handshake to fail */ * 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; *ok = 1;
@ -1326,7 +1326,8 @@ unsigned char *
dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
unsigned long len, unsigned long frag_off, unsigned long frag_len) 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->handshake_write_seq = s->d1->next_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 *p)
return p; return p;
} }
static unsigned int unsigned int
dtls1_min_mtu(void) dtls1_min_mtu(void)
{ {
return (g_probable_mtu[(sizeof(g_probable_mtu) / return (g_probable_mtu[(sizeof(g_probable_mtu) /

View File

@ -257,7 +257,6 @@ int dtls1_connect(SSL *s)
if (ret <= 0) goto end; if (ret <= 0) goto end;
else else
{ {
dtls1_stop_timer(s);
if (s->hit) if (s->hit)
s->state=SSL3_ST_CR_FINISHED_A; s->state=SSL3_ST_CR_FINISHED_A;
else else
@ -350,6 +349,7 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CR_SRVR_DONE_B: case SSL3_ST_CR_SRVR_DONE_B:
ret=ssl3_get_server_done(s); ret=ssl3_get_server_done(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
dtls1_stop_timer(s);
if (s->s3->tmp.cert_req) if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A; s->state=SSL3_ST_CW_CERT_A;
else else
@ -403,7 +403,8 @@ int dtls1_connect(SSL *s)
case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_CW_CHANGE_B: case SSL3_ST_CW_CHANGE_B:
dtls1_start_timer(s); if (!s->hit)
dtls1_start_timer(s);
ret=dtls1_send_change_cipher_spec(s, ret=dtls1_send_change_cipher_spec(s,
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
if (ret <= 0) goto end; 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_A:
case SSL3_ST_CW_FINISHED_B: case SSL3_ST_CW_FINISHED_B:
dtls1_start_timer(s); if (!s->hit)
dtls1_start_timer(s);
ret=dtls1_send_finished(s, ret=dtls1_send_finished(s,
SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
s->method->ssl3_enc->client_finished_label, s->method->ssl3_enc->client_finished_label,

View File

@ -220,11 +220,7 @@ int dtls1_enc(SSL *s, int send)
if (!send) if (!send)
{ {
if (l == 0 || l%bs != 0) if (l == 0 || l%bs != 0)
{ return -1;
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); EVP_Cipher(ds,rec->data,rec->input,l);
@ -253,7 +249,7 @@ int dtls1_enc(SSL *s, int send)
} }
/* TLS 1.0 does not bound the number of padding bytes by the block size. /* TLS 1.0 does not bound the number of padding bytes by the block size.
* All of them must have value 'padding_length'. */ * All of them must have value 'padding_length'. */
if (i > (int)rec->length) if (i + bs > (int)rec->length)
{ {
/* Incorrect padding. SSLerr() and ssl3_alert are done /* Incorrect padding. SSLerr() and ssl3_alert are done
* by caller: we don't want to reveal whether this is * by caller: we don't want to reveal whether this is

View File

@ -145,26 +145,33 @@ int dtls1_new(SSL *s)
return(1); return(1);
} }
void dtls1_free(SSL *s) static void dtls1_clear_queues(SSL *s)
{ {
pitem *item = NULL; pitem *item = NULL;
hm_fragment *frag = NULL; hm_fragment *frag = NULL;
DTLS1_RECORD_DATA *rdata;
ssl3_free(s);
while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) 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); OPENSSL_free(item->data);
pitem_free(item); pitem_free(item);
} }
pqueue_free(s->d1->unprocessed_rcds.q);
while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) 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); OPENSSL_free(item->data);
pitem_free(item); pitem_free(item);
} }
pqueue_free(s->d1->processed_rcds.q);
while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
{ {
@ -173,7 +180,6 @@ void dtls1_free(SSL *s)
OPENSSL_free(frag); OPENSSL_free(frag);
pitem_free(item); pitem_free(item);
} }
pqueue_free(s->d1->buffered_messages);
while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
{ {
@ -182,15 +188,26 @@ void dtls1_free(SSL *s)
OPENSSL_free(frag); OPENSSL_free(frag);
pitem_free(item); pitem_free(item);
} }
pqueue_free(s->d1->sent_messages);
while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
{ {
frag = (hm_fragment *)item->data; frag = (hm_fragment *)item->data;
OPENSSL_free(frag->fragment); OPENSSL_free(frag->fragment);
OPENSSL_free(frag); OPENSSL_free(frag);
pitem_free(item); 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); pqueue_free(s->d1->buffered_app_data.q);
pq_64bit_free(&(s->d1->bitmap.map)); pq_64bit_free(&(s->d1->bitmap.map));
@ -204,6 +221,61 @@ void dtls1_free(SSL *s)
void dtls1_clear(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); ssl3_clear(s);
if (s->options & SSL_OP_CISCO_ANYCONNECT) if (s->options & SSL_OP_CISCO_ANYCONNECT)
s->version=DTLS1_BAD_VER; s->version=DTLS1_BAD_VER;
@ -349,15 +421,36 @@ void dtls1_double_timeout(SSL *s)
void dtls1_stop_timer(SSL *s) void dtls1_stop_timer(SSL *s)
{ {
/* Reset everything */ /* Reset everything */
memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1; s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); 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_check_timeout_num(SSL *s)
{
s->d1->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
if (s->d1->timeout.num_alerts > 2)
{
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
}
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
{
/* fail the connection, enough alerts have been sent */
SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
}
return 0;
} }
int dtls1_handle_timeout(SSL *s) int dtls1_handle_timeout(SSL *s)
{ {
DTLS1_STATE *state;
/* if no timer is expired, don't do anything */ /* if no timer is expired, don't do anything */
if (!dtls1_is_timer_expired(s)) if (!dtls1_is_timer_expired(s))
{ {
@ -365,19 +458,14 @@ int dtls1_handle_timeout(SSL *s)
} }
dtls1_double_timeout(s); dtls1_double_timeout(s);
state = s->d1;
state->timeout.num_alerts++;
if ( state->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);
return 0;
}
state->timeout.read_timeouts++; if (dtls1_check_timeout_num(s) < 0)
if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) 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); dtls1_start_timer(s);

View File

@ -139,7 +139,6 @@ static int dtls1_process_record(SSL *s);
#if PQ_64BIT_IS_INTEGER #if PQ_64BIT_IS_INTEGER
static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
#endif #endif
static void dtls1_clear_timeouts(SSL *s);
/* copy buffered record into SSL structure */ /* copy buffered record into SSL structure */
static int static int
@ -335,6 +334,8 @@ dtls1_process_record(SSL *s)
SSL3_RECORD *rr; SSL3_RECORD *rr;
unsigned int mac_size; unsigned int mac_size;
unsigned char md[EVP_MAX_MD_SIZE]; unsigned char md[EVP_MAX_MD_SIZE];
int decryption_failed_or_bad_record_mac = 0;
unsigned char *mac = NULL;
rr= &(s->s3->rrec); rr= &(s->s3->rrec);
@ -369,12 +370,10 @@ dtls1_process_record(SSL *s)
enc_err = s->method->ssl3_enc->enc(s,0); enc_err = s->method->ssl3_enc->enc(s,0);
if (enc_err <= 0) if (enc_err <= 0)
{ {
if (enc_err == 0) /* To minimize information leaked via timing, we will always
/* SSLerr() and ssl3_send_alert() have been called */ * perform all computations before discarding the message.
goto err; */
decryption_failed_or_bad_record_mac = 1;
/* otherwise enc_err == -1 */
goto err;
} }
#ifdef TLS_DEBUG #ifdef TLS_DEBUG
@ -400,28 +399,32 @@ if ( (sess == NULL) ||
SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
goto f_err; goto f_err;
#else #else
goto err; decryption_failed_or_bad_record_mac = 1;
#endif #endif
} }
/* check the MAC for rr->input (it's in mac_size bytes at the tail) */ /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
if (rr->length < mac_size) if (rr->length >= mac_size)
{ {
#if 0 /* OK only for stream ciphers */ rr->length -= mac_size;
al=SSL_AD_DECODE_ERROR; mac = &rr->data[rr->length];
SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
goto f_err;
#else
goto err;
#endif
} }
rr->length-=mac_size; else
rr->length = 0;
s->method->ssl3_enc->mac(s,md,0); s->method->ssl3_enc->mac(s,md,0);
if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) if (mac == NULL || memcmp(md, mac, mac_size) != 0)
{ {
goto err; decryption_failed_or_bad_record_mac = 1;
} }
} }
if (decryption_failed_or_bad_record_mac)
{
/* decryption failed, silently discard message */
rr->length = 0;
s->packet_length = 0;
goto err;
}
/* r->length is now just compressed */ /* r->length is now just compressed */
if (s->expand != NULL) if (s->expand != NULL)
{ {
@ -615,10 +618,12 @@ int dtls1_get_record(SSL *s)
/* If this record is from the next epoch (either HM or ALERT), /* If this record is from the next epoch (either HM or ALERT),
* and a handshake is currently in progress, buffer it since it * 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 (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); dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
} }
@ -634,7 +639,6 @@ int dtls1_get_record(SSL *s)
goto again; /* get another record */ goto again; /* get another record */
} }
dtls1_clear_timeouts(s); /* done waiting */
return(1); return(1);
} }
@ -1103,6 +1107,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
*/ */
if (msg_hdr.type == SSL3_MT_FINISHED) if (msg_hdr.type == SSL3_MT_FINISHED)
{ {
if (dtls1_check_timeout_num(s) < 0)
return -1;
dtls1_retransmit_buffered_messages(s); dtls1_retransmit_buffered_messages(s);
rr->length = 0; rr->length = 0;
goto start; goto start;
@ -1806,10 +1813,3 @@ bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num)
return _num; return _num;
} }
#endif #endif
static void
dtls1_clear_timeouts(SSL *s)
{
memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
}

View File

@ -148,6 +148,7 @@ int dtls1_accept(SSL *s)
void (*cb)(const SSL *ssl,int type,int val)=NULL; void (*cb)(const SSL *ssl,int type,int val)=NULL;
int ret= -1; int ret= -1;
int new_state,state,skip=0; int new_state,state,skip=0;
int listen;
RAND_add(&Time,sizeof(Time),0); RAND_add(&Time,sizeof(Time),0);
ERR_clear_error(); ERR_clear_error();
@ -157,11 +158,15 @@ int dtls1_accept(SSL *s)
cb=s->info_callback; cb=s->info_callback;
else if (s->ctx->info_callback != NULL) else if (s->ctx->info_callback != NULL)
cb=s->ctx->info_callback; cb=s->ctx->info_callback;
listen = s->d1->listen;
/* init things to blank */ /* init things to blank */
s->in_handshake++; s->in_handshake++;
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
s->d1->listen = listen;
if (s->cert == NULL) if (s->cert == NULL)
{ {
SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
@ -271,11 +276,23 @@ int dtls1_accept(SSL *s)
s->init_num=0; 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 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; ret = 2;
s->d1->listen = 0; 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; 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_A:
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
dtls1_start_timer(s);
ret = dtls1_send_hello_verify_request(s); ret = dtls1_send_hello_verify_request(s);
if ( ret <= 0) goto end; if ( ret <= 0) goto end;
s->state=SSL3_ST_SW_FLUSH; s->state=SSL3_ST_SW_FLUSH;
@ -457,15 +473,16 @@ int dtls1_accept(SSL *s)
ret = ssl3_check_client_hello(s); ret = ssl3_check_client_hello(s);
if (ret <= 0) if (ret <= 0)
goto end; goto end;
dtls1_stop_timer(s);
if (ret == 2) if (ret == 2)
{
dtls1_stop_timer(s);
s->state = SSL3_ST_SR_CLNT_HELLO_C; s->state = SSL3_ST_SR_CLNT_HELLO_C;
}
else { else {
/* could be sent for a DH cert, even if we /* could be sent for a DH cert, even if we
* have not asked for it :-) */ * have not asked for it :-) */
ret=ssl3_get_client_certificate(s); ret=ssl3_get_client_certificate(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
dtls1_stop_timer(s);
s->init_num=0; s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A; s->state=SSL3_ST_SR_KEY_EXCH_A;
} }
@ -475,7 +492,6 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SR_KEY_EXCH_B: case SSL3_ST_SR_KEY_EXCH_B:
ret=ssl3_get_client_key_exchange(s); ret=ssl3_get_client_key_exchange(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
dtls1_stop_timer(s);
s->state=SSL3_ST_SR_CERT_VRFY_A; s->state=SSL3_ST_SR_CERT_VRFY_A;
s->init_num=0; s->init_num=0;
@ -497,7 +513,6 @@ int dtls1_accept(SSL *s)
/* we should decide if we expected this one */ /* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s); ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
dtls1_stop_timer(s);
s->state=SSL3_ST_SR_FINISHED_A; s->state=SSL3_ST_SR_FINISHED_A;
s->init_num=0; s->init_num=0;
@ -713,9 +728,6 @@ int dtls1_send_hello_verify_request(SSL *s)
/* number of bytes to write */ /* number of bytes to write */
s->init_num=p-buf; s->init_num=p-buf;
s->init_off=0; 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 */ /* 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; p=s->s3->server_random;
Time=(unsigned long)time(NULL); /* Time */ Time=(unsigned long)time(NULL); /* Time */
l2n(Time,p); 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 */ /* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);

View File

@ -403,13 +403,14 @@ static int get_client_master_key(SSL *s)
p+=3; p+=3;
n2s(p,i); s->s2->tmp.clear=i; n2s(p,i); s->s2->tmp.clear=i;
n2s(p,i); s->s2->tmp.enc=i; n2s(p,i); s->s2->tmp.enc=i;
n2s(p,i); s->session->key_arg_length=i; n2s(p,i);
if(s->session->key_arg_length > SSL_MAX_KEY_ARG_LENGTH) if(i > SSL_MAX_KEY_ARG_LENGTH)
{ {
ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG);
return -1; return -1;
} }
s->session->key_arg_length=i;
s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B; s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
} }

View File

@ -878,7 +878,7 @@ int ssl3_get_server_hello(SSL *s)
/* wrong packet length */ /* wrong packet length */
al=SSL_AD_DECODE_ERROR; al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH); SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH);
goto err; goto f_err;
} }
return(1); return(1);
@ -1713,7 +1713,7 @@ int ssl3_get_new_session_ticket(SSL *s)
if (n < 6) if (n < 6)
{ {
/* need at least ticket_lifetime_hint + ticket length */ /* 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); SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
goto f_err; goto f_err;
} }
@ -1724,7 +1724,7 @@ int ssl3_get_new_session_ticket(SSL *s)
/* ticket_lifetime_hint + ticket_length + ticket */ /* ticket_lifetime_hint + ticket_length + ticket */
if (ticklen + 6 != n) 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); SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
goto f_err; goto f_err;
} }

View File

@ -479,6 +479,9 @@ int ssl3_enc(SSL *s, int send)
/* we need to add 'i-1' padding bytes */ /* we need to add 'i-1' padding bytes */
l+=i; l+=i;
/* the last of these zero bytes will be overwritten
* with the padding length. */
memset(&rec->input[rec->length], 0, i);
rec->length+=i; rec->length+=i;
rec->input[l-1]=(i-1); rec->input[l-1]=(i-1);
} }

View File

@ -1722,11 +1722,17 @@ void ssl3_clear(SSL *s)
} }
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
if (s->s3->tmp.dh != NULL) if (s->s3->tmp.dh != NULL)
{
DH_free(s->s3->tmp.dh); DH_free(s->s3->tmp.dh);
s->s3->tmp.dh = NULL;
}
#endif #endif
#ifndef OPENSSL_NO_ECDH #ifndef OPENSSL_NO_ECDH
if (s->s3->tmp.ecdh != NULL) if (s->s3->tmp.ecdh != NULL)
{
EC_KEY_free(s->s3->tmp.ecdh); EC_KEY_free(s->s3->tmp.ecdh);
s->s3->tmp.ecdh = NULL;
}
#endif #endif
rp = s->s3->rbuf.buf; rp = s->s3->rbuf.buf;
@ -2635,4 +2641,3 @@ need to go to SSL_ST_ACCEPT.
} }
return(ret); return(ret);
} }

View File

@ -235,6 +235,7 @@ int ssl3_accept(SSL *s)
} }
s->init_num=0; s->init_num=0;
s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
if (s->state != SSL_ST_RENEGOTIATE) if (s->state != SSL_ST_RENEGOTIATE)
{ {
@ -709,10 +710,15 @@ int ssl3_check_client_hello(SSL *s)
s->s3->tmp.reuse_message = 1; s->s3->tmp.reuse_message = 1;
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
{ {
/* We only allow the client to restart the handshake once per
* negotiation. */
if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
{
SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
return -1;
}
/* Throw away what we have done so far in the current handshake, /* Throw away what we have done so far in the current handshake,
* which will now be aborted. (A full SSL_clear would be too much.) * which will now be aborted. (A full SSL_clear would be too much.) */
* I hope that tmp.dh is the only thing that may need to be cleared
* when a handshake is not completed ... */
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
if (s->s3->tmp.dh != NULL) if (s->s3->tmp.dh != NULL)
{ {
@ -720,6 +726,14 @@ int ssl3_check_client_hello(SSL *s)
s->s3->tmp.dh = NULL; s->s3->tmp.dh = NULL;
} }
#endif #endif
#ifndef OPENSSL_NO_ECDH
if (s->s3->tmp.ecdh != NULL)
{
EC_KEY_free(s->s3->tmp.ecdh);
s->s3->tmp.ecdh = NULL;
}
#endif
s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
return 2; return 2;
} }
return 1; return 1;
@ -1329,7 +1343,6 @@ int ssl3_send_server_key_exchange(SSL *s)
if (s->s3->tmp.dh != NULL) if (s->s3->tmp.dh != NULL)
{ {
DH_free(dh);
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err; goto err;
} }
@ -1390,7 +1403,6 @@ int ssl3_send_server_key_exchange(SSL *s)
if (s->s3->tmp.ecdh != NULL) if (s->s3->tmp.ecdh != NULL)
{ {
EC_KEY_free(s->s3->tmp.ecdh);
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err; goto err;
} }
@ -1401,12 +1413,11 @@ int ssl3_send_server_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err; goto err;
} }
if (!EC_KEY_up_ref(ecdhp)) if ((ecdh = EC_KEY_dup(ecdhp)) == NULL)
{ {
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
goto err; goto err;
} }
ecdh = ecdhp;
s->s3->tmp.ecdh=ecdh; s->s3->tmp.ecdh=ecdh;
if ((EC_KEY_get0_public_key(ecdh) == NULL) || if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
@ -1560,6 +1571,7 @@ int ssl3_send_server_key_exchange(SSL *s)
(unsigned char *)encodedPoint, (unsigned char *)encodedPoint,
encodedlen); encodedlen);
OPENSSL_free(encodedPoint); OPENSSL_free(encodedPoint);
encodedPoint = NULL;
p += encodedlen; p += encodedlen;
} }
#endif #endif
@ -1949,6 +1961,7 @@ int ssl3_get_client_key_exchange(SSL *s)
if (i <= 0) if (i <= 0)
{ {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
BN_clear_free(pub);
goto err; goto err;
} }
@ -2262,6 +2275,12 @@ int ssl3_get_client_key_exchange(SSL *s)
/* Get encoded point length */ /* Get encoded point length */
i = *p; i = *p;
p += 1; p += 1;
if (n != 1 + i)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
ERR_R_EC_LIB);
goto err;
}
if (EC_POINT_oct2point(group, if (EC_POINT_oct2point(group,
clnt_ecpoint, p, i, bn_ctx) == 0) clnt_ecpoint, p, i, bn_ctx) == 0)
{ {

View File

@ -1682,6 +1682,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_DTLS1_ACCEPT 246 #define SSL_F_DTLS1_ACCEPT 246
#define SSL_F_DTLS1_ADD_CERT_TO_BUF 280 #define SSL_F_DTLS1_ADD_CERT_TO_BUF 280
#define SSL_F_DTLS1_BUFFER_RECORD 247 #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_CLIENT_HELLO 248
#define SSL_F_DTLS1_CONNECT 249 #define SSL_F_DTLS1_CONNECT 249
#define SSL_F_DTLS1_ENC 250 #define SSL_F_DTLS1_ENC 250
@ -1739,6 +1740,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL3_CALLBACK_CTRL 233 #define SSL_F_SSL3_CALLBACK_CTRL 233
#define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 #define SSL_F_SSL3_CHANGE_CIPHER_STATE 129
#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130
#define SSL_F_SSL3_CHECK_CLIENT_HELLO 292
#define SSL_F_SSL3_CLIENT_HELLO 131 #define SSL_F_SSL3_CLIENT_HELLO 131
#define SSL_F_SSL3_CONNECT 132 #define SSL_F_SSL3_CONNECT 132
#define SSL_F_SSL3_CTRL 213 #define SSL_F_SSL3_CTRL 213
@ -1974,6 +1976,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_MISSING_TMP_RSA_KEY 172 #define SSL_R_MISSING_TMP_RSA_KEY 172
#define SSL_R_MISSING_TMP_RSA_PKEY 173 #define SSL_R_MISSING_TMP_RSA_PKEY 173
#define SSL_R_MISSING_VERIFY_MESSAGE 174 #define SSL_R_MISSING_VERIFY_MESSAGE 174
#define SSL_R_MULTIPLE_SGC_RESTARTS 325
#define SSL_R_NON_SSLV2_INITIAL_PACKET 175 #define SSL_R_NON_SSLV2_INITIAL_PACKET 175
#define SSL_R_NO_CERTIFICATES_RETURNED 176 #define SSL_R_NO_CERTIFICATES_RETURNED 176
#define SSL_R_NO_CERTIFICATE_ASSIGNED 177 #define SSL_R_NO_CERTIFICATE_ASSIGNED 177

View File

@ -333,6 +333,17 @@ typedef struct ssl3_buffer_st
#define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002
#define SSL3_FLAGS_POP_BUFFER 0x0004 #define SSL3_FLAGS_POP_BUFFER 0x0004
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
* restart a handshake because of MS SGC and so prevents us
* from restarting the handshake in a loop. It's reset on a
* renegotiation, so effectively limits the client to one restart
* per negotiation. This limits the possibility of a DDoS
* attack where the client handshakes in a loop using SGC to
* restart. Servers which permit renegotiation can still be
* effected, but we can't prevent that.
*/
#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040
typedef struct ssl3_state_st typedef struct ssl3_state_st
{ {

View File

@ -303,6 +303,7 @@ static void load_builtin_compressions(void)
sk_SSL_COMP_push(ssl_comp_methods,comp); sk_SSL_COMP_push(ssl_comp_methods,comp);
} }
} }
sk_SSL_COMP_sort(ssl_comp_methods);
} }
MemCheck_on(); MemCheck_on();
} }

View File

@ -1,6 +1,6 @@
/* ssl/ssl_err.c */ /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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_ACCEPT), "DTLS1_ACCEPT"},
{ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, {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_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_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"}, {ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"},
{ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"}, {ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"},
@ -137,6 +138,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"},
{ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"},
{ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"},
{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"},
{ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"},
{ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"},
@ -375,6 +377,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"}, {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"},
{ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) ,"missing tmp rsa pkey"}, {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) ,"missing tmp rsa pkey"},
{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"}, {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"}, {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"}, {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"}, {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},

View File

@ -1000,6 +1000,11 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
s->max_cert_list=larg; s->max_cert_list=larg;
return(l); return(l);
case SSL_CTRL_SET_MTU: case SSL_CTRL_SET_MTU:
#ifndef OPENSSL_NO_DTLS1
if (larg < (long)dtls1_min_mtu())
return 0;
#endif
if (SSL_version(s) == DTLS1_VERSION || if (SSL_version(s) == DTLS1_VERSION ||
SSL_version(s) == DTLS1_BAD_VER) SSL_version(s) == DTLS1_BAD_VER)
{ {

View File

@ -870,6 +870,7 @@ void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
void dtls1_reset_seq_numbers(SSL *s, int rw); void dtls1_reset_seq_numbers(SSL *s, int rw);
long dtls1_default_timeout(void); long dtls1_default_timeout(void);
struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
int dtls1_check_timeout_num(SSL *s);
int dtls1_handle_timeout(SSL *s); int dtls1_handle_timeout(SSL *s);
SSL_CIPHER *dtls1_get_cipher(unsigned int u); SSL_CIPHER *dtls1_get_cipher(unsigned int u);
void dtls1_start_timer(SSL *s); void dtls1_start_timer(SSL *s);
@ -877,6 +878,7 @@ void dtls1_stop_timer(SSL *s);
int dtls1_is_timer_expired(SSL *s); int dtls1_is_timer_expired(SSL *s);
void dtls1_double_timeout(SSL *s); void dtls1_double_timeout(SSL *s);
int dtls1_send_newsession_ticket(SSL *s); int dtls1_send_newsession_ticket(SSL *s);
unsigned int dtls1_min_mtu(void);
/* some client-only functions */ /* some client-only functions */

View File

@ -521,6 +521,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
} }
n2s(data, idsize); n2s(data, idsize);
dsize -= 2 + idsize; dsize -= 2 + idsize;
size -= 2 + idsize;
if (dsize < 0) if (dsize < 0)
{ {
*al = SSL_AD_DECODE_ERROR; *al = SSL_AD_DECODE_ERROR;
@ -559,9 +560,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
} }
/* Read in request_extensions */ /* Read in request_extensions */
if (size < 2)
{
*al = SSL_AD_DECODE_ERROR;
return 0;
}
n2s(data,dsize); n2s(data,dsize);
size -= 2; size -= 2;
if (dsize > size) if (dsize != size)
{ {
*al = SSL_AD_DECODE_ERROR; *al = SSL_AD_DECODE_ERROR;
return 0; return 0;
@ -569,6 +575,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
sdata = data; sdata = data;
if (dsize > 0) if (dsize > 0)
{ {
if (s->tlsext_ocsp_exts)
{
sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
X509_EXTENSION_free);
}
s->tlsext_ocsp_exts = s->tlsext_ocsp_exts =
d2i_X509_EXTENSIONS(NULL, d2i_X509_EXTENSIONS(NULL,
&sdata, dsize); &sdata, dsize);

View File

@ -43,7 +43,12 @@ die "First stage Link failure" if $? != 0;
print "$fips_premain_dso $fips_target\n"; 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; chomp $fips_hash;
die "Get hash failure" if $? != 0; die "Get hash failure" if $? != 0;

View File

@ -313,7 +313,7 @@ foreach $lib (keys %csrc)
} else { } else {
push @out, push @out,
"/* ====================================================================\n", "/* ====================================================================\n",
" * Copyright (c) 2001-2010 The OpenSSL Project. All rights reserved.\n", " * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n",
" *\n", " *\n",
" * Redistribution and use in source and binary forms, with or without\n", " * Redistribution and use in source and binary forms, with or without\n",
" * modification, are permitted provided that the following conditions\n", " * modification, are permitted provided that the following conditions\n",
@ -487,7 +487,7 @@ EOF
print OUT <<"EOF"; print OUT <<"EOF";
/* $cfile */ /* $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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -680,7 +680,7 @@ EOF
undef %err_reason_strings; undef %err_reason_strings;
} }
if($debug && defined(%notrans)) { if($debug && %notrans) {
print STDERR "The following function codes were not translated:\n"; print STDERR "The following function codes were not translated:\n";
foreach(sort keys %notrans) foreach(sort keys %notrans)
{ {

View File

@ -391,7 +391,7 @@ sub do_lib_rule
$ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n"; $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
$ret.="\tSET FIPS_TARGET=$target\n"; $ret.="\tSET FIPS_TARGET=$target\n";
$ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\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.="$name @<<\n \$(SHLIB_EX_OBJ) $objs ";
$ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n"; $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_TARGET=$target\n";
$ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n"; $ret.="\tSET FIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\n";
$ret.="\tSET FIPSLIB_D=\$(FIPSLIB_D)\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"; $ret.="\t\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n";
} }
else else