diff options
author | jkim <jkim@FreeBSD.org> | 2016-09-22 14:57:48 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2016-09-22 14:57:48 +0000 |
commit | 5ced369491e2445d728a27ad06e09d01930f0c6b (patch) | |
tree | 73fe15f4db2d52cd64cd8952bb5f8f991a9dc558 /crypto/openssl | |
parent | 65eee2e6f94289d9f4d416f06c304a714747b721 (diff) | |
download | FreeBSD-src-5ced369491e2445d728a27ad06e09d01930f0c6b.zip FreeBSD-src-5ced369491e2445d728a27ad06e09d01930f0c6b.tar.gz |
MFC: r306193
Merge OpenSSL 1.0.2u.
Diffstat (limited to 'crypto/openssl')
222 files changed, 3936 insertions, 1347 deletions
diff --git a/crypto/openssl/CHANGES b/crypto/openssl/CHANGES index 4a55765..4bdd390 100644 --- a/crypto/openssl/CHANGES +++ b/crypto/openssl/CHANGES @@ -2,6 +2,166 @@ OpenSSL CHANGES _______________ + Changes between 1.0.2h and 1.0.2i [22 Sep 2016] + + *) OCSP Status Request extension unbounded memory growth + + A malicious client can send an excessively large OCSP Status Request + extension. If that client continually requests renegotiation, sending a + large OCSP Status Request extension each time, then there will be unbounded + memory growth on the server. This will eventually lead to a Denial Of + Service attack through memory exhaustion. Servers with a default + configuration are vulnerable even if they do not support OCSP. Builds using + the "no-ocsp" build time option are not affected. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-6304) + [Matt Caswell] + + *) In order to mitigate the SWEET32 attack, the DES ciphers were moved from + HIGH to MEDIUM. + + This issue was reported to OpenSSL Karthikeyan Bhargavan and Gaetan + Leurent (INRIA) + (CVE-2016-2183) + [Rich Salz] + + *) OOB write in MDC2_Update() + + An overflow can occur in MDC2_Update() either if called directly or + through the EVP_DigestUpdate() function using MDC2. If an attacker + is able to supply very large amounts of input data after a previous + call to EVP_EncryptUpdate() with a partial block then a length check + can overflow resulting in a heap corruption. + + The amount of data needed is comparable to SIZE_MAX which is impractical + on most platforms. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-6303) + [Stephen Henson] + + *) Malformed SHA512 ticket DoS + + If a server uses SHA512 for TLS session ticket HMAC it is vulnerable to a + DoS attack where a malformed ticket will result in an OOB read which will + ultimately crash. + + The use of SHA512 in TLS session tickets is comparatively rare as it requires + a custom server callback and ticket lookup mechanism. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-6302) + [Stephen Henson] + + *) OOB write in BN_bn2dec() + + The function BN_bn2dec() does not check the return value of BN_div_word(). + This can cause an OOB write if an application uses this function with an + overly large BIGNUM. This could be a problem if an overly large certificate + or CRL is printed out from an untrusted source. TLS is not affected because + record limits will reject an oversized certificate before it is parsed. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-2182) + [Stephen Henson] + + *) OOB read in TS_OBJ_print_bio() + + The function TS_OBJ_print_bio() misuses OBJ_obj2txt(): the return value is + the total length the OID text representation would use and not the amount + of data written. This will result in OOB reads when large OIDs are + presented. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-2180) + [Stephen Henson] + + *) Pointer arithmetic undefined behaviour + + Avoid some undefined pointer arithmetic + + A common idiom in the codebase is to check limits in the following manner: + "p + len > limit" + + Where "p" points to some malloc'd data of SIZE bytes and + limit == p + SIZE + + "len" here could be from some externally supplied data (e.g. from a TLS + message). + + The rules of C pointer arithmetic are such that "p + len" is only well + defined where len <= SIZE. Therefore the above idiom is actually + undefined behaviour. + + For example this could cause problems if some malloc implementation + provides an address for "p" such that "p + len" actually overflows for + values of len that are too big and therefore p + len < limit. + + This issue was reported to OpenSSL by Guido Vranken + (CVE-2016-2177) + [Matt Caswell] + + *) Constant time flag not preserved in DSA signing + + Operations in the DSA signing algorithm should run in constant time in + order to avoid side channel attacks. A flaw in the OpenSSL DSA + implementation means that a non-constant time codepath is followed for + certain operations. This has been demonstrated through a cache-timing + attack to be sufficient for an attacker to recover the private DSA key. + + This issue was reported by César Pereida (Aalto University), Billy Brumley + (Tampere University of Technology), and Yuval Yarom (The University of + Adelaide and NICTA). + (CVE-2016-2178) + [César Pereida] + + *) DTLS buffered message DoS + + In a DTLS connection where handshake messages are delivered out-of-order + those messages that OpenSSL is not yet ready to process will be buffered + for later use. Under certain circumstances, a flaw in the logic means that + those messages do not get removed from the buffer even though the handshake + has been completed. An attacker could force up to approx. 15 messages to + remain in the buffer when they are no longer required. These messages will + be cleared when the DTLS connection is closed. The default maximum size for + a message is 100k. Therefore the attacker could force an additional 1500k + to be consumed per connection. By opening many simulataneous connections an + attacker could cause a DoS attack through memory exhaustion. + + This issue was reported to OpenSSL by Quan Luo. + (CVE-2016-2179) + [Matt Caswell] + + *) DTLS replay protection DoS + + A flaw in the DTLS replay attack protection mechanism means that records + that arrive for future epochs update the replay protection "window" before + the MAC for the record has been validated. This could be exploited by an + attacker by sending a record for the next epoch (which does not have to + decrypt or have a valid MAC), with a very large sequence number. This means + that all subsequent legitimate packets are dropped causing a denial of + service for a specific DTLS connection. + + This issue was reported to OpenSSL by the OCAP audit team. + (CVE-2016-2181) + [Matt Caswell] + + *) Certificate message OOB reads + + In OpenSSL 1.0.2 and earlier some missing message length checks can result + in OOB reads of up to 2 bytes beyond an allocated buffer. There is a + theoretical DoS risk but this has not been observed in practice on common + platforms. + + The messages affected are client certificate, client certificate request + and server certificate. As a result the attack can only be performed + against a client or a server which enables client authentication. + + This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.) + (CVE-2016-6306) + [Stephen Henson] + Changes between 1.0.2g and 1.0.2h [3 May 2016] *) Prevent padding oracle in AES-NI CBC MAC check diff --git a/crypto/openssl/CONTRIBUTING b/crypto/openssl/CONTRIBUTING index 9d63d8a..07115e5 100644 --- a/crypto/openssl/CONTRIBUTING +++ b/crypto/openssl/CONTRIBUTING @@ -1,38 +1,75 @@ -HOW TO CONTRIBUTE TO OpenSSL ----------------------------- +HOW TO CONTRIBUTE TO PATCHES OpenSSL +------------------------------------ -Development is coordinated on the openssl-dev mailing list (see -http://www.openssl.org for information on subscribing). If you -would like to submit a patch, send it to rt@openssl.org with -the string "[PATCH]" in the subject. Please be sure to include a -textual explanation of what your patch does. - -You can also make GitHub pull requests. If you do this, please also send -mail to rt@openssl.org with a brief description and a link to the PR so -that we can more easily keep track of it. +(Please visit https://www.openssl.org/community/getting-started.html for +other ideas about how to contribute.) +Development is coordinated on the openssl-dev mailing list (see the +above link or https://mta.openssl.org for information on subscribing). If you are unsure as to whether a feature will be useful for the general -OpenSSL community please discuss it on the openssl-dev mailing list first. -Someone may be already working on the same thing or there may be a good -reason as to why that feature isn't implemented. +OpenSSL community you might want to discuss it on the openssl-dev mailing +list first. Someone may be already working on the same thing or there +may be a good reason as to why that feature isn't implemented. -Patches should be as up to date as possible, preferably relative to the -current Git or the last snapshot. They should follow our coding style -(see https://www.openssl.org/policies/codingstyle.html) and compile without -warnings using the --strict-warnings flag. OpenSSL compiles on many varied -platforms: try to ensure you only use portable features. +The best way to submit a patch is to make a pull request on GitHub. +(It is not necessary to send mail to rt@openssl.org to open a ticket!) +If you think the patch could use feedback from the community, please +start a thread on openssl-dev. -Our preferred format for patch files is "git format-patch" output. For example -to provide a patch file containing the last commit in your local git repository -use the following command: +You can also submit patches by sending it as mail to rt@openssl.org. +Please include the word "PATCH" and an explanation of what the patch +does in the subject line. If you do this, our preferred format is "git +format-patch" output. For example to provide a patch file containing the +last commit in your local git repository use the following command: -# git format-patch --stdout HEAD^ >mydiffs.patch + % git format-patch --stdout HEAD^ >mydiffs.patch Another method of creating an acceptable patch file without using git is as follows: -# cd openssl-work -# [your changes] -# ./Configure dist; make clean -# cd .. -# diff -ur openssl-orig openssl-work > mydiffs.patch + % cd openssl-work + ...make your changes... + % ./Configure dist; make clean + % cd .. + % diff -ur openssl-orig openssl-work >mydiffs.patch + +Note that pull requests are generally easier for the team, and community, to +work with. Pull requests benefit from all of the standard GitHub features, +including code review tools, simpler integration, and CI build support. + +No matter how a patch is submitted, the following items will help make +the acceptance and review process faster: + + 1. Anything other than trivial contributions will require a contributor + licensing agreement, giving us permission to use your code. See + https://www.openssl.org/policies/cla.html for details. + + 2. All source files should start with the following text (with + appropriate comment characters at the start of each line and the + year(s) updated): + + Copyright 20xx-20yy The OpenSSL Project Authors. All Rights Reserved. + + Licensed under the OpenSSL license (the "License"). You may not use + this file except in compliance with the License. You can obtain a copy + in the file LICENSE in the source distribution or at + https://www.openssl.org/source/license.html + + 3. Patches should be as current as possible. When using GitHub, please + expect to have to rebase and update often. Note that we do not accept merge + commits. You will be asked to remove them before a patch is considered + acceptable. + + 4. Patches should follow our coding style (see + https://www.openssl.org/policies/codingstyle.html) and compile without + warnings. Where gcc or clang is availble you should use the + --strict-warnings Configure option. OpenSSL compiles on many varied + platforms: try to ensure you only use portable features. + + 5. When at all possible, patches should include tests. These can either be + added to an existing test, or completely new. Please see test/README + for information on the test framework. + + 6. New features or changed functionality must include documentation. Please + look at the "pod" files in doc/apps, doc/crypto and doc/ssl for examples of + our style. diff --git a/crypto/openssl/Configure b/crypto/openssl/Configure index c98107a..c39f71a 100755 --- a/crypto/openssl/Configure +++ b/crypto/openssl/Configure @@ -799,7 +799,7 @@ my @experimental = (); # This is what $depflags will look like with the above defaults # (we need this to see if we should advise the user to run "make depend"): -my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_LIBUNBOUND -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL_TRACE -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST"; +my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_LIBUNBOUND -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL_TRACE -DOPENSSL_NO_SSL2 -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST -DOPENSSL_NO_WEAK_SSL_CIPHERS"; # Explicit "no-..." options will be collected in %disabled along with the defaults. # To remove something from %disabled, use "enable-foo" (unless it's experimental). @@ -1082,11 +1082,6 @@ if (defined($disabled{"md5"}) || defined($disabled{"sha"}) $disabled{"tls1"} = "forced"; } -if (defined($disabled{"tls1"})) - { - $disabled{"tlsext"} = "forced"; - } - if (defined($disabled{"ec"}) || defined($disabled{"dsa"}) || defined($disabled{"dh"})) { @@ -1254,6 +1249,7 @@ my $shared_extension = $fields[$idx_shared_extension]; my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib]; my $ar = $ENV{'AR'} || "ar"; my $arflags = $fields[$idx_arflags]; +my $windres = $ENV{'RC'} || $ENV{'WINDRES'} || "windres"; my $multilib = $fields[$idx_multilib]; # if $prefix/lib$multilib is not an existing directory, then @@ -1562,8 +1558,15 @@ $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); $des_obj=$des_enc unless ($des_obj =~ /\.o$/); $bf_obj=$bf_enc unless ($bf_obj =~ /\.o$/); $cast_obj=$cast_enc unless ($cast_obj =~ /\.o$/); -$rc4_obj=$rc4_enc unless ($rc4_obj =~ /\.o$/); $rc5_obj=$rc5_enc unless ($rc5_obj =~ /\.o$/); +if ($rc4_obj =~ /\.o$/) + { + $cflags.=" -DRC4_ASM"; + } +else + { + $rc4_obj=$rc4_enc; + } if ($sha1_obj =~ /\.o$/) { # $sha1_obj=$sha1_enc; @@ -1717,12 +1720,14 @@ while (<IN>) s/^AR=\s*/AR= \$\(CROSS_COMPILE\)/; s/^NM=\s*/NM= \$\(CROSS_COMPILE\)/; s/^RANLIB=\s*/RANLIB= \$\(CROSS_COMPILE\)/; + s/^RC=\s*/RC= \$\(CROSS_COMPILE\)/; s/^MAKEDEPPROG=.*$/MAKEDEPPROG= \$\(CROSS_COMPILE\)$cc/ if $cc eq "gcc"; } else { s/^CC=.*$/CC= $cc/; s/^AR=\s*ar/AR= $ar/; s/^RANLIB=.*/RANLIB= $ranlib/; + s/^RC=.*/RC= $windres/; s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc"; s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $ecc eq "gcc" || $ecc eq "clang"; } diff --git a/crypto/openssl/Makefile b/crypto/openssl/Makefile index a26a24f..58daaa5 100644 --- a/crypto/openssl/Makefile +++ b/crypto/openssl/Makefile @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2h +VERSION=1.0.2i MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 @@ -68,6 +68,7 @@ EXE_EXT= ARFLAGS= AR= ar $(ARFLAGS) r RANLIB= /usr/bin/ranlib +RC= windres NM= nm PERL= /usr/bin/perl TAR= tar @@ -210,6 +211,7 @@ BUILDENV= LC_ALL=C PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)'\ CC='$(CC)' CFLAG='$(CFLAG)' \ AS='$(CC)' ASFLAG='$(CFLAG) -c' \ AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)' \ + RC='$(RC)' \ CROSS_COMPILE='$(CROSS_COMPILE)' \ PERL='$(PERL)' ENGDIRS='$(ENGDIRS)' \ SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)' \ @@ -368,6 +370,7 @@ libcrypto.pc: Makefile echo 'exec_prefix=$${prefix}'; \ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ echo 'includedir=$${prefix}/include'; \ + echo 'enginesdir=$${libdir}/engines'; \ echo ''; \ echo 'Name: OpenSSL-libcrypto'; \ echo 'Description: OpenSSL cryptography library'; \ diff --git a/crypto/openssl/Makefile.org b/crypto/openssl/Makefile.org index 15c1c9f..e544022 100644 --- a/crypto/openssl/Makefile.org +++ b/crypto/openssl/Makefile.org @@ -66,6 +66,7 @@ EXE_EXT= ARFLAGS?= r AR=ar $(ARFLAGS) RANLIB= ranlib +RC= windres NM= nm PERL= perl TAR= tar @@ -208,6 +209,7 @@ BUILDENV= LC_ALL=C PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)'\ CC='$(CC)' CFLAG='$(CFLAG)' \ AS='$(CC)' ASFLAG='$(CFLAG) -c' \ AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)' \ + RC='$(RC)' \ CROSS_COMPILE='$(CROSS_COMPILE)' \ PERL='$(PERL)' ENGDIRS='$(ENGDIRS)' \ SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)' \ @@ -366,6 +368,7 @@ libcrypto.pc: Makefile echo 'exec_prefix=$${prefix}'; \ echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ echo 'includedir=$${prefix}/include'; \ + echo 'enginesdir=$${libdir}/engines'; \ echo ''; \ echo 'Name: OpenSSL-libcrypto'; \ echo 'Description: OpenSSL cryptography library'; \ diff --git a/crypto/openssl/Makefile.shared b/crypto/openssl/Makefile.shared index a2aa980..e8d222a 100644 --- a/crypto/openssl/Makefile.shared +++ b/crypto/openssl/Makefile.shared @@ -293,7 +293,7 @@ link_a.cygwin: fi; \ dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \ $(PERL) util/mkrc.pl $$dll_name | \ - $(CROSS_COMPILE)windres -o rc.o; \ + $(RC) -o rc.o; \ extras="$$extras rc.o"; \ ALLSYMSFLAGS='-Wl,--whole-archive'; \ NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ diff --git a/crypto/openssl/NEWS b/crypto/openssl/NEWS index 6c85116..5a65284 100644 --- a/crypto/openssl/NEWS +++ b/crypto/openssl/NEWS @@ -5,6 +5,20 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.0.2h and OpenSSL 1.0.2i [22 Sep 2016] + + o OCSP Status Request extension unbounded memory growth (CVE-2016-6304) + o SWEET32 Mitigation (CVE-2016-2183) + o OOB write in MDC2_Update() (CVE-2016-6303) + o Malformed SHA512 ticket DoS (CVE-2016-6302) + o OOB write in BN_bn2dec() (CVE-2016-2182) + o OOB read in TS_OBJ_print_bio() (CVE-2016-2180) + o Pointer arithmetic undefined behaviour (CVE-2016-2177) + o Constant time flag not preserved in DSA signing (CVE-2016-2178) + o DTLS buffered message DoS (CVE-2016-2179) + o DTLS replay protection DoS (CVE-2016-2181) + o Certificate message OOB reads (CVE-2016-6306) + Major changes between OpenSSL 1.0.2g and OpenSSL 1.0.2h [3 May 2016] o Prevent padding oracle in AES-NI CBC MAC check (CVE-2016-2107) diff --git a/crypto/openssl/README b/crypto/openssl/README index b880eec..70d4ddd 100644 --- a/crypto/openssl/README +++ b/crypto/openssl/README @@ -1,5 +1,5 @@ - OpenSSL 1.0.2h 3 May 2016 + OpenSSL 1.0.2i 22 Sep 2016 Copyright (c) 1998-2015 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/crypto/openssl/apps/CA.pl b/crypto/openssl/apps/CA.pl index a3965ec..43c20b2 100755 --- a/crypto/openssl/apps/CA.pl +++ b/crypto/openssl/apps/CA.pl @@ -64,7 +64,7 @@ $RET = 0; foreach (@ARGV) { if ( /^(-\?|-h|-help)$/ ) { - print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; + print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-signcert|-verify\n"; exit 0; } elsif (/^-newcert$/) { # create a certificate @@ -186,4 +186,3 @@ while (<IN>) { } } } - diff --git a/crypto/openssl/apps/CA.pl.in b/crypto/openssl/apps/CA.pl.in index c783a6e..3bf4c99 100644 --- a/crypto/openssl/apps/CA.pl.in +++ b/crypto/openssl/apps/CA.pl.in @@ -64,7 +64,7 @@ $RET = 0; foreach (@ARGV) { if ( /^(-\?|-h|-help)$/ ) { - print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; + print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-signcert|-verify\n"; exit 0; } elsif (/^-newcert$/) { # create a certificate @@ -186,4 +186,3 @@ while (<IN>) { } } } - diff --git a/crypto/openssl/apps/apps.c b/crypto/openssl/apps/apps.c index b1dd970..9fdc3e0 100644 --- a/crypto/openssl/apps/apps.c +++ b/crypto/openssl/apps/apps.c @@ -215,7 +215,8 @@ int args_from_file(char *file, int *argc, char **argv[]) if (arg != NULL) OPENSSL_free(arg); arg = (char **)OPENSSL_malloc(sizeof(char *) * (i * 2)); - + if (arg == NULL) + return 0; *argv = arg; num = 0; p = buf; @@ -2374,6 +2375,8 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_PARTIAL_CHAIN; else if (!strcmp(arg, "-no_alt_chains")) flags |= X509_V_FLAG_NO_ALT_CHAINS; + else if (!strcmp(arg, "-allow_proxy_certs")) + flags |= X509_V_FLAG_ALLOW_PROXY_CERTS; else return 0; @@ -3195,6 +3198,36 @@ int app_isdir(const char *name) #endif /* raw_read|write section */ +#if defined(__VMS) +# include "vms_term_sock.h" +static int stdin_sock = -1; + +static void close_stdin_sock(void) +{ + TerminalSocket (TERM_SOCK_DELETE, &stdin_sock); +} + +int fileno_stdin(void) +{ + if (stdin_sock == -1) { + TerminalSocket(TERM_SOCK_CREATE, &stdin_sock); + atexit(close_stdin_sock); + } + + return stdin_sock; +} +#else +int fileno_stdin(void) +{ + return fileno(stdin); +} +#endif + +int fileno_stdout(void) +{ + return fileno(stdout); +} + #if defined(_WIN32) && defined(STD_INPUT_HANDLE) int raw_read_stdin(void *buf, int siz) { @@ -3204,10 +3237,17 @@ int raw_read_stdin(void *buf, int siz) else return (-1); } +#elif defined(__VMS) +#include <sys/socket.h> + +int raw_read_stdin(void *buf, int siz) +{ + return recv(fileno_stdin(), buf, siz, 0); +} #else int raw_read_stdin(void *buf, int siz) { - return read(fileno(stdin), buf, siz); + return read(fileno_stdin(), buf, siz); } #endif @@ -3223,6 +3263,6 @@ int raw_write_stdout(const void *buf, int siz) #else int raw_write_stdout(const void *buf, int siz) { - return write(fileno(stdout), buf, siz); + return write(fileno_stdout(), buf, siz); } #endif diff --git a/crypto/openssl/apps/apps.h b/crypto/openssl/apps/apps.h index 19bf5cc..c6c3881 100644 --- a/crypto/openssl/apps/apps.h +++ b/crypto/openssl/apps/apps.h @@ -375,6 +375,8 @@ void store_setup_crl_download(X509_STORE *st); # define SERIAL_RAND_BITS 64 int app_isdir(const char *); +int fileno_stdin(void); +int fileno_stdout(void); int raw_read_stdin(void *, int); int raw_write_stdout(const void *, int); diff --git a/crypto/openssl/apps/ca.c b/crypto/openssl/apps/ca.c index 0b66095..a0ec583 100644 --- a/crypto/openssl/apps/ca.c +++ b/crypto/openssl/apps/ca.c @@ -2103,25 +2103,23 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, goto err; /* We now just add it to the database */ - row[DB_type] = (char *)OPENSSL_malloc(2); - tm = X509_get_notAfter(ret); - row[DB_exp_date] = (char *)OPENSSL_malloc(tm->length + 1); - memcpy(row[DB_exp_date], tm->data, tm->length); - row[DB_exp_date][tm->length] = '\0'; - - row[DB_rev_date] = NULL; - - /* row[DB_serial] done already */ - row[DB_file] = (char *)OPENSSL_malloc(8); + row[DB_type] = OPENSSL_malloc(2); + row[DB_exp_date] = OPENSSL_malloc(tm->length + 1); + row[DB_rev_date] = OPENSSL_malloc(1); + row[DB_file] = OPENSSL_malloc(8); row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0); - if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || + (row[DB_rev_date] == NULL) || (row[DB_file] == NULL) || (row[DB_name] == NULL)) { BIO_printf(bio_err, "Memory allocation failure\n"); goto err; } - BUF_strlcpy(row[DB_file], "unknown", 8); + + memcpy(row[DB_exp_date], tm->data, tm->length); + row[DB_exp_date][tm->length] = '\0'; + row[DB_rev_date][0] = '\0'; + strcpy(row[DB_file], "unknown"); row[DB_type][0] = 'V'; row[DB_type][1] = '\0'; @@ -2307,6 +2305,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, j = NETSCAPE_SPKI_verify(spki, pktmp); if (j <= 0) { + EVP_PKEY_free(pktmp); BIO_printf(bio_err, "signature verification failed on SPKAC public key\n"); goto err; diff --git a/crypto/openssl/apps/dgst.c b/crypto/openssl/apps/dgst.c index 95e5fa3..26afcd7 100644 --- a/crypto/openssl/apps/dgst.c +++ b/crypto/openssl/apps/dgst.c @@ -243,6 +243,11 @@ int MAIN(int argc, char **argv) argv++; } + if (keyfile != NULL && argc > 1) { + BIO_printf(bio_err, "Can only sign or verify one file\n"); + goto end; + } + if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); diff --git a/crypto/openssl/apps/enc.c b/crypto/openssl/apps/enc.c index 7b7c70b..8e2ef27 100644 --- a/crypto/openssl/apps/enc.c +++ b/crypto/openssl/apps/enc.c @@ -509,7 +509,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "invalid hex salt value\n"); goto end; } - } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0) + } else if (RAND_bytes(salt, sizeof salt) <= 0) goto end; /* * If -P option then don't bother writing diff --git a/crypto/openssl/apps/passwd.c b/crypto/openssl/apps/passwd.c index 5ff53b5..798a6d5 100644 --- a/crypto/openssl/apps/passwd.c +++ b/crypto/openssl/apps/passwd.c @@ -416,7 +416,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, if (*salt_malloc_p == NULL) goto err; } - if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0) + if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0) goto err; (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */ (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */ @@ -437,7 +437,7 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p, if (*salt_malloc_p == NULL) goto err; } - if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0) + if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0) goto err; for (i = 0; i < 8; i++) diff --git a/crypto/openssl/apps/pkcs12.c b/crypto/openssl/apps/pkcs12.c index cbb75b7..82182c2 100644 --- a/crypto/openssl/apps/pkcs12.c +++ b/crypto/openssl/apps/pkcs12.c @@ -832,6 +832,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, EVP_PKEY *pkey; PKCS8_PRIV_KEY_INFO *p8; X509 *x509; + int ret = 0; switch (M_PKCS12_bag_type(bag)) { case NID_keyBag: @@ -844,7 +845,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, if (!(pkey = EVP_PKCS82PKEY(p8))) return 0; print_attribs(out, p8->attributes, "Key Attributes"); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; @@ -864,7 +865,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, } print_attribs(out, p8->attributes, "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; @@ -884,7 +885,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, if (!(x509 = PKCS12_certbag2x509(bag))) return 0; dump_cert_text(out, x509); - PEM_write_bio_X509(out, x509); + ret = PEM_write_bio_X509(out, x509); X509_free(x509); break; @@ -902,7 +903,7 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, return 1; break; } - return 1; + return ret; } /* Given a single certificate return a verified chain or NULL if error */ @@ -931,16 +932,70 @@ static int get_cert_chain(X509 *cert, X509_STORE *store, int alg_print(BIO *x, X509_ALGOR *alg) { - PBEPARAM *pbe; - const unsigned char *p; - p = alg->parameter->value.sequence->data; - pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); - if (!pbe) - return 1; - BIO_printf(bio_err, "%s, Iteration %ld\n", - OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), - ASN1_INTEGER_get(pbe->iter)); - PBEPARAM_free(pbe); + int pbenid, aparamtype; + ASN1_OBJECT *aoid; + void *aparam; + PBEPARAM *pbe = NULL; + + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg); + + pbenid = OBJ_obj2nid(aoid); + + BIO_printf(x, "%s", OBJ_nid2ln(pbenid)); + + /* + * If PBE algorithm is PBES2 decode algorithm parameters + * for additional details. + */ + if (pbenid == NID_pbes2) { + PBE2PARAM *pbe2 = NULL; + int encnid; + if (aparamtype == V_ASN1_SEQUENCE) + pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM)); + if (pbe2 == NULL) { + BIO_puts(x, "<unsupported parameters>"); + goto done; + } + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc); + pbenid = OBJ_obj2nid(aoid); + X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption); + encnid = OBJ_obj2nid(aoid); + BIO_printf(x, ", %s, %s", OBJ_nid2ln(pbenid), + OBJ_nid2sn(encnid)); + /* If KDF is PBKDF2 decode parameters */ + if (pbenid == NID_id_pbkdf2) { + PBKDF2PARAM *kdf = NULL; + int prfnid; + if (aparamtype == V_ASN1_SEQUENCE) + kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM)); + if (kdf == NULL) { + BIO_puts(x, "<unsupported parameters>"); + goto done; + } + + if (kdf->prf == NULL) { + prfnid = NID_hmacWithSHA1; + } else { + X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf); + prfnid = OBJ_obj2nid(aoid); + } + BIO_printf(x, ", Iteration %ld, PRF %s", + ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid)); + PBKDF2PARAM_free(kdf); + } + PBE2PARAM_free(pbe2); + } else { + if (aparamtype == V_ASN1_SEQUENCE) + pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM)); + if (pbe == NULL) { + BIO_puts(x, "<unsupported parameters>"); + goto done; + } + BIO_printf(x, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter)); + PBEPARAM_free(pbe); + } + done: + BIO_puts(x, "\n"); return 1; } diff --git a/crypto/openssl/apps/req.c b/crypto/openssl/apps/req.c index e818bd2..d1411c9 100644 --- a/crypto/openssl/apps/req.c +++ b/crypto/openssl/apps/req.c @@ -332,9 +332,10 @@ int MAIN(int argc, char **argv) subject = 1; else if (strcmp(*argv, "-text") == 0) text = 1; - else if (strcmp(*argv, "-x509") == 0) + else if (strcmp(*argv, "-x509") == 0) { + newreq = 1; x509 = 1; - else if (strcmp(*argv, "-asn1-kludge") == 0) + } else if (strcmp(*argv, "-asn1-kludge") == 0) kludge = 1; else if (strcmp(*argv, "-no-asn1-kludge") == 0) kludge = 0; @@ -756,7 +757,7 @@ int MAIN(int argc, char **argv) } } - if (newreq || x509) { + if (newreq) { if (pkey == NULL) { BIO_printf(bio_err, "you need to specify a private key\n"); goto end; @@ -1331,12 +1332,11 @@ static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, break; } #ifndef CHARSET_EBCDIC - if (*p == '+') + if (*type == '+') { #else - if (*p == os_toascii['+']) + if (*type == os_toascii['+']) { #endif - { - p++; + type++; mval = -1; } else mval = 0; diff --git a/crypto/openssl/apps/s_apps.h b/crypto/openssl/apps/s_apps.h index 5b54bfd..5ba1e1d 100644 --- a/crypto/openssl/apps/s_apps.h +++ b/crypto/openssl/apps/s_apps.h @@ -199,7 +199,8 @@ int load_excert(SSL_EXCERT **pexc, BIO *err); void print_ssl_summary(BIO *bio, SSL *s); #ifdef HEADER_SSL_H int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, - int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr); + int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr, + int *no_prot_opt); int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake); int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, diff --git a/crypto/openssl/apps/s_cb.c b/crypto/openssl/apps/s_cb.c index 5b5e711..d1a99a7 100644 --- a/crypto/openssl/apps/s_cb.c +++ b/crypto/openssl/apps/s_cb.c @@ -1507,11 +1507,18 @@ void print_ssl_summary(BIO *bio, SSL *s) } int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, - int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr) + int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr, + int *no_prot_opt) { char *arg = **pargs, *argn = (*pargs)[1]; int rv; + if (strcmp(arg, "-no_ssl2") == 0 || strcmp(arg, "-no_ssl3") == 0 + || strcmp(arg, "-no_tls1") == 0 || strcmp(arg, "-no_tls1_1") == 0 + || strcmp(arg, "-no_tls1_2") == 0) { + *no_prot_opt = 1; + } + /* Attempt to run SSL configuration command */ rv = SSL_CONF_cmd_argv(cctx, pargc, pargs); /* If parameter not recognised just return */ diff --git a/crypto/openssl/apps/s_client.c b/crypto/openssl/apps/s_client.c index 0c1102b..41a326f 100644 --- a/crypto/openssl/apps/s_client.c +++ b/crypto/openssl/apps/s_client.c @@ -242,9 +242,9 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, unsigned char *psk, unsigned int max_psk_len) { - unsigned int psk_len = 0; int ret; - BIGNUM *bn = NULL; + long key_len; + unsigned char *key; if (c_debug) BIO_printf(bio_c_out, "psk_client_cb\n"); @@ -265,32 +265,29 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, if (c_debug) BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, ret); - ret = BN_hex2bn(&bn, psk_key); - if (!ret) { - BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", + + /* convert the PSK key to binary */ + key = string_to_hex(psk_key, &key_len); + if (key == NULL) { + BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", psk_key); - if (bn) - BN_free(bn); return 0; } - - if ((unsigned int)BN_num_bytes(bn) > max_psk_len) { + if ((unsigned long)key_len > (unsigned long)max_psk_len) { BIO_printf(bio_err, - "psk buffer of callback is too small (%d) for key (%d)\n", - max_psk_len, BN_num_bytes(bn)); - BN_free(bn); + "psk buffer of callback is too small (%d) for key (%ld)\n", + max_psk_len, key_len); + OPENSSL_free(key); return 0; } - psk_len = BN_bn2bin(bn, psk); - BN_free(bn); - if (psk_len == 0) - goto out_err; + memcpy(psk, key, key_len); + OPENSSL_free(key); if (c_debug) - BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len); + BIO_printf(bio_c_out, "created PSK len=%ld\n", key_len); - return psk_len; + return key_len; out_err: if (c_debug) BIO_printf(bio_err, "Error in PSK client callback\n"); @@ -747,6 +744,7 @@ int MAIN(int argc, char **argv) int crl_format = FORMAT_PEM; int crl_download = 0; STACK_OF(X509_CRL) *crls = NULL; + int prot_opt = 0, no_prot_opt = 0; meth = SSLv23_client_method(); @@ -850,7 +848,8 @@ int MAIN(int argc, char **argv) if (badarg) goto bad; continue; - } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) { + } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args, + &no_prot_opt)) { if (badarg) goto bad; continue; @@ -942,31 +941,42 @@ int MAIN(int argc, char **argv) } #endif #ifndef OPENSSL_NO_SSL2 - else if (strcmp(*argv, "-ssl2") == 0) + else if (strcmp(*argv, "-ssl2") == 0) { meth = SSLv2_client_method(); + prot_opt++; + } #endif #ifndef OPENSSL_NO_SSL3_METHOD - else if (strcmp(*argv, "-ssl3") == 0) + else if (strcmp(*argv, "-ssl3") == 0) { meth = SSLv3_client_method(); + prot_opt++; + } #endif #ifndef OPENSSL_NO_TLS1 - else if (strcmp(*argv, "-tls1_2") == 0) + else if (strcmp(*argv, "-tls1_2") == 0) { meth = TLSv1_2_client_method(); - else if (strcmp(*argv, "-tls1_1") == 0) + prot_opt++; + } else if (strcmp(*argv, "-tls1_1") == 0) { meth = TLSv1_1_client_method(); - else if (strcmp(*argv, "-tls1") == 0) + prot_opt++; + } else if (strcmp(*argv, "-tls1") == 0) { meth = TLSv1_client_method(); + prot_opt++; + } #endif #ifndef OPENSSL_NO_DTLS1 else if (strcmp(*argv, "-dtls") == 0) { meth = DTLS_client_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-dtls1") == 0) { meth = DTLSv1_client_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-dtls1_2") == 0) { meth = DTLSv1_2_client_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-timeout") == 0) enable_timeouts = 1; else if (strcmp(*argv, "-mtu") == 0) { @@ -1149,6 +1159,17 @@ int MAIN(int argc, char **argv) } #endif + if (prot_opt > 1) { + BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); + goto end; + } + + if (prot_opt == 1 && no_prot_opt) { + BIO_printf(bio_err, "Cannot supply both a protocol flag and " + "\"-no_<prot>\"\n"); + goto end; + } + OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); @@ -1540,7 +1561,10 @@ int MAIN(int argc, char **argv) SSL_set_connect_state(con); /* ok, lets connect */ - width = SSL_get_fd(con) + 1; + if (fileno_stdin() > SSL_get_fd(con)) + width = fileno_stdin() + 1; + else + width = SSL_get_fd(con) + 1; read_tty = 1; write_tty = 0; @@ -1723,9 +1747,11 @@ int MAIN(int argc, char **argv) #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5) if (tty_on) { if (read_tty) - openssl_fdset(fileno(stdin), &readfds); + openssl_fdset(fileno_stdin(), &readfds); +#if !defined(OPENSSL_SYS_VMS) if (write_tty) - openssl_fdset(fileno(stdout), &writefds); + openssl_fdset(fileno_stdout(), &writefds); +#endif } if (read_ssl) openssl_fdset(SSL_get_fd(con), &readfds); @@ -1795,14 +1821,14 @@ int MAIN(int argc, char **argv) /* Under BeOS-R5 the situation is similar to DOS */ i = 0; stdin_set = 0; - (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + (void)fcntl(fileno_stdin(), F_SETFL, O_NONBLOCK); if (!write_tty) { if (read_tty) { tv.tv_sec = 1; tv.tv_usec = 0; i = select(width, (void *)&readfds, (void *)&writefds, NULL, &tv); - if (read(fileno(stdin), sbuf, 0) >= 0) + if (read(fileno_stdin(), sbuf, 0) >= 0) stdin_set = 1; if (!i && (stdin_set != 1 || !read_tty)) continue; @@ -1810,7 +1836,7 @@ int MAIN(int argc, char **argv) i = select(width, (void *)&readfds, (void *)&writefds, NULL, timeoutp); } - (void)fcntl(fileno(stdin), F_SETFL, 0); + (void)fcntl(fileno_stdin(), F_SETFL, 0); #else i = select(width, (void *)&readfds, (void *)&writefds, NULL, timeoutp); @@ -1886,11 +1912,11 @@ int MAIN(int argc, char **argv) goto shut; } } -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) || defined(OPENSSL_SYS_VMS) /* Assume Windows/DOS/BeOS can always write */ else if (!ssl_pending && write_tty) #else - else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds)) + else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds)) #endif { #ifdef CHARSET_EBCDIC @@ -1988,7 +2014,7 @@ int MAIN(int argc, char **argv) #elif defined(OPENSSL_SYS_BEOS_R5) else if (stdin_set) #else - else if (FD_ISSET(fileno(stdin), &readfds)) + else if (FD_ISSET(fileno_stdin(), &readfds)) #endif { if (crlf) { diff --git a/crypto/openssl/apps/s_server.c b/crypto/openssl/apps/s_server.c index 09c755b..857a70e 100644 --- a/crypto/openssl/apps/s_server.c +++ b/crypto/openssl/apps/s_server.c @@ -353,9 +353,8 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len) { - unsigned int psk_len = 0; - int ret; - BIGNUM *bn = NULL; + long key_len = 0; + unsigned char *key; if (s_debug) BIO_printf(bio_s_out, "psk_server_cb\n"); @@ -377,32 +376,26 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, BIO_printf(bio_s_out, "PSK client identity found\n"); /* convert the PSK key to binary */ - ret = BN_hex2bn(&bn, psk_key); - if (!ret) { - BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", + key = string_to_hex(psk_key, &key_len); + if (key == NULL) { + BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", psk_key); - if (bn) - BN_free(bn); return 0; } - if (BN_num_bytes(bn) > (int)max_psk_len) { + if (key_len > (int)max_psk_len) { BIO_printf(bio_err, - "psk buffer of callback is too small (%d) for key (%d)\n", - max_psk_len, BN_num_bytes(bn)); - BN_free(bn); + "psk buffer of callback is too small (%d) for key (%ld)\n", + max_psk_len, key_len); + OPENSSL_free(key); return 0; } - ret = BN_bn2bin(bn, psk); - BN_free(bn); - - if (ret < 0) - goto out_err; - psk_len = (unsigned int)ret; + memcpy(psk, key, key_len); + OPENSSL_free(key); if (s_debug) - BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len); - return psk_len; + BIO_printf(bio_s_out, "fetched PSK len=%ld\n", key_len); + return key_len; out_err: if (s_debug) BIO_printf(bio_err, "Error in PSK server callback\n"); @@ -1144,6 +1137,7 @@ int MAIN(int argc, char *argv[]) int crl_format = FORMAT_PEM; int crl_download = 0; STACK_OF(X509_CRL) *crls = NULL; + int prot_opt = 0, no_prot_opt = 0; meth = SSLv23_server_method(); @@ -1307,7 +1301,8 @@ int MAIN(int argc, char *argv[]) if (badarg) goto bad; continue; - } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) { + } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args, + &no_prot_opt)) { if (badarg) goto bad; continue; @@ -1451,32 +1446,40 @@ int MAIN(int argc, char *argv[]) else if (strcmp(*argv, "-ssl2") == 0) { no_ecdhe = 1; meth = SSLv2_server_method(); + prot_opt++; } #endif #ifndef OPENSSL_NO_SSL3_METHOD else if (strcmp(*argv, "-ssl3") == 0) { meth = SSLv3_server_method(); + prot_opt++; } #endif #ifndef OPENSSL_NO_TLS1 else if (strcmp(*argv, "-tls1") == 0) { meth = TLSv1_server_method(); + prot_opt++; } else if (strcmp(*argv, "-tls1_1") == 0) { meth = TLSv1_1_server_method(); + prot_opt++; } else if (strcmp(*argv, "-tls1_2") == 0) { meth = TLSv1_2_server_method(); + prot_opt++; } #endif #ifndef OPENSSL_NO_DTLS1 else if (strcmp(*argv, "-dtls") == 0) { meth = DTLS_server_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-dtls1") == 0) { meth = DTLSv1_server_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-dtls1_2") == 0) { meth = DTLSv1_2_server_method(); socket_type = SOCK_DGRAM; + prot_opt++; } else if (strcmp(*argv, "-timeout") == 0) enable_timeouts = 1; else if (strcmp(*argv, "-mtu") == 0) { @@ -1586,6 +1589,17 @@ int MAIN(int argc, char *argv[]) } #endif + if (prot_opt > 1) { + BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); + goto end; + } + + if (prot_opt == 1 && no_prot_opt) { + BIO_printf(bio_err, "Cannot supply both a protocol flag and " + "\"-no_<prot>\"\n"); + goto end; + } + SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); @@ -2293,7 +2307,10 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) } #endif - width = s + 1; + if (fileno_stdin() > s) + width = fileno_stdin() + 1; + else + width = s + 1; for (;;) { int read_from_terminal; int read_from_sslcon; @@ -2304,7 +2321,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) if (!read_from_sslcon) { FD_ZERO(&readfds); #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5) - openssl_fdset(fileno(stdin), &readfds); + openssl_fdset(fileno_stdin(), &readfds); #endif openssl_fdset(s, &readfds); /* @@ -2332,13 +2349,13 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) /* Under BeOS-R5 the situation is similar to DOS */ tv.tv_sec = 1; tv.tv_usec = 0; - (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + (void)fcntl(fileno_stdin(), F_SETFL, O_NONBLOCK); i = select(width, (void *)&readfds, NULL, NULL, &tv); - if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0)) + if ((i < 0) || (!i && read(fileno_stdin(), buf, 0) < 0)) continue; - if (read(fileno(stdin), buf, 0) >= 0) + if (read(fileno_stdin(), buf, 0) >= 0) read_from_terminal = 1; - (void)fcntl(fileno(stdin), F_SETFL, 0); + (void)fcntl(fileno_stdin(), F_SETFL, 0); #else if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_get_timeout(con, &timeout)) @@ -2355,7 +2372,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) if (i <= 0) continue; - if (FD_ISSET(fileno(stdin), &readfds)) + if (FD_ISSET(fileno_stdin(), &readfds)) read_from_terminal = 1; #endif if (FD_ISSET(s, &readfds)) @@ -2382,6 +2399,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context) assert(lf_num == 0); } else i = raw_read_stdin(buf, bufsize); + if (!s_quiet && !s_brief) { if ((i <= 0) || (buf[0] == 'Q')) { BIO_printf(bio_s_out, "DONE\n"); @@ -3371,7 +3389,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id, { unsigned int count = 0; do { - if (RAND_pseudo_bytes(id, *id_len) < 0) + if (RAND_bytes(id, *id_len) <= 0) return 0; /* * Prefix the session_id with the required prefix. NB: If our prefix diff --git a/crypto/openssl/apps/speed.c b/crypto/openssl/apps/speed.c index 95adcc1..b862868 100644 --- a/crypto/openssl/apps/speed.c +++ b/crypto/openssl/apps/speed.c @@ -2614,6 +2614,10 @@ static int do_multi(int multi) static char sep[] = ":"; fds = malloc(multi * sizeof *fds); + if (fds == NULL) { + fprintf(stderr, "Out of memory in speed (do_multi)\n"); + exit(1); + } for (n = 0; n < multi; ++n) { if (pipe(fd) == -1) { fprintf(stderr, "pipe failure\n"); diff --git a/crypto/openssl/apps/srp.c b/crypto/openssl/apps/srp.c index c0ff417..c75052f 100644 --- a/crypto/openssl/apps/srp.c +++ b/crypto/openssl/apps/srp.c @@ -765,4 +765,6 @@ int MAIN(int argc, char **argv) OPENSSL_EXIT(ret); } +#else +static void *dummy = &dummy; #endif diff --git a/crypto/openssl/apps/verify.c b/crypto/openssl/apps/verify.c index 78e729f..b5ae6b3 100644 --- a/crypto/openssl/apps/verify.c +++ b/crypto/openssl/apps/verify.c @@ -115,43 +115,43 @@ int MAIN(int argc, char **argv) if (argc >= 1) { if (strcmp(*argv, "-CApath") == 0) { if (argc-- < 1) - goto end; + goto usage; CApath = *(++argv); } else if (strcmp(*argv, "-CAfile") == 0) { if (argc-- < 1) - goto end; + goto usage; CAfile = *(++argv); } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { if (badarg) - goto end; + goto usage; continue; } else if (strcmp(*argv, "-untrusted") == 0) { if (argc-- < 1) - goto end; + goto usage; untfile = *(++argv); } else if (strcmp(*argv, "-trusted") == 0) { if (argc-- < 1) - goto end; + goto usage; trustfile = *(++argv); } else if (strcmp(*argv, "-CRLfile") == 0) { if (argc-- < 1) - goto end; + goto usage; crlfile = *(++argv); } else if (strcmp(*argv, "-crl_download") == 0) crl_download = 1; #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) - goto end; + goto usage; engine = *(++argv); } #endif else if (strcmp(*argv, "-help") == 0) - goto end; + goto usage; else if (strcmp(*argv, "-verbose") == 0) v_verbose = 1; else if (argv[0][0] == '-') - goto end; + goto usage; else break; argc--; @@ -228,7 +228,7 @@ int MAIN(int argc, char **argv) ret = -1; } - end: + usage: if (ret == 1) { BIO_printf(bio_err, "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); @@ -247,6 +247,7 @@ int MAIN(int argc, char **argv) X509_PURPOSE_get0_name(ptmp)); } } + end: if (vpm) X509_VERIFY_PARAM_free(vpm); if (cert_ctx != NULL) diff --git a/crypto/openssl/apps/x509.c b/crypto/openssl/apps/x509.c index 7c215bc..17cb62d 100644 --- a/crypto/openssl/apps/x509.c +++ b/crypto/openssl/apps/x509.c @@ -1105,6 +1105,10 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, EVP_PKEY *upkey; upkey = X509_get_pubkey(xca); + if (upkey == NULL) { + BIO_printf(bio_err, "Error obtaining CA X509 public key\n"); + goto end; + } EVP_PKEY_copy_parameters(upkey, pkey); EVP_PKEY_free(upkey); @@ -1217,6 +1221,8 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, EVP_PKEY *pktmp; pktmp = X509_get_pubkey(x); + if (pktmp == NULL) + goto err; EVP_PKEY_copy_parameters(pktmp, pkey); EVP_PKEY_save_parameters(pktmp, 1); EVP_PKEY_free(pktmp); diff --git a/crypto/openssl/crypto/LPdir_unix.c b/crypto/openssl/crypto/LPdir_unix.c index bead6ab..c97e260 100644 --- a/crypto/openssl/crypto/LPdir_unix.c +++ b/crypto/openssl/crypto/LPdir_unix.c @@ -1,8 +1,4 @@ /* - * $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp - * $ - */ -/* * Copyright (c) 2004, Richard Levitte <richard@levitte.org> * All rights reserved. * diff --git a/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl b/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl index fcc81d1..83343e2 100755 --- a/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl +++ b/crypto/openssl/crypto/aes/asm/bsaes-armv7.pl @@ -1797,8 +1797,6 @@ $code.=<<___; b .Lxts_enc_done .align 4 .Lxts_enc_6: - vst1.64 {@XMM[14]}, [r0,:128] @ next round tweak - veor @XMM[4], @XMM[4], @XMM[12] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -1834,8 +1832,6 @@ $code.=<<___; .align 5 .Lxts_enc_5: - vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak - veor @XMM[3], @XMM[3], @XMM[11] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -1864,8 +1860,6 @@ $code.=<<___; b .Lxts_enc_done .align 4 .Lxts_enc_4: - vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak - veor @XMM[2], @XMM[2], @XMM[10] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -1891,8 +1885,6 @@ $code.=<<___; b .Lxts_enc_done .align 4 .Lxts_enc_3: - vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak - veor @XMM[1], @XMM[1], @XMM[9] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -1917,8 +1909,6 @@ $code.=<<___; b .Lxts_enc_done .align 4 .Lxts_enc_2: - vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak - veor @XMM[0], @XMM[0], @XMM[8] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -1941,7 +1931,7 @@ $code.=<<___; .align 4 .Lxts_enc_1: mov r0, sp - veor @XMM[0], @XMM[8] + veor @XMM[0], @XMM[0], @XMM[8] mov r1, sp vst1.8 {@XMM[0]}, [sp,:128] mov r2, $key @@ -2251,8 +2241,6 @@ $code.=<<___; b .Lxts_dec_done .align 4 .Lxts_dec_5: - vst1.64 {@XMM[13]}, [r0,:128] @ next round tweak - veor @XMM[3], @XMM[3], @XMM[11] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -2281,8 +2269,6 @@ $code.=<<___; b .Lxts_dec_done .align 4 .Lxts_dec_4: - vst1.64 {@XMM[12]}, [r0,:128] @ next round tweak - veor @XMM[2], @XMM[2], @XMM[10] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -2308,8 +2294,6 @@ $code.=<<___; b .Lxts_dec_done .align 4 .Lxts_dec_3: - vst1.64 {@XMM[11]}, [r0,:128] @ next round tweak - veor @XMM[1], @XMM[1], @XMM[9] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -2334,8 +2318,6 @@ $code.=<<___; b .Lxts_dec_done .align 4 .Lxts_dec_2: - vst1.64 {@XMM[10]}, [r0,:128] @ next round tweak - veor @XMM[0], @XMM[0], @XMM[8] #ifndef BSAES_ASM_EXTENDED_KEY add r4, sp, #0x90 @ pass key schedule @@ -2358,12 +2340,12 @@ $code.=<<___; .align 4 .Lxts_dec_1: mov r0, sp - veor @XMM[0], @XMM[8] + veor @XMM[0], @XMM[0], @XMM[8] mov r1, sp vst1.8 {@XMM[0]}, [sp,:128] + mov r5, $magic @ preserve magic mov r2, $key mov r4, $fp @ preserve fp - mov r5, $magic @ preserve magic bl AES_decrypt diff --git a/crypto/openssl/crypto/asn1/a_bytes.c b/crypto/openssl/crypto/asn1/a_bytes.c index 385b539..65e5394 100644 --- a/crypto/openssl/crypto/asn1/a_bytes.c +++ b/crypto/openssl/crypto/asn1/a_bytes.c @@ -60,7 +60,12 @@ #include "cryptlib.h" #include <openssl/asn1.h> -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c); +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, + int depth); +static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, + const unsigned char **pp, long length, + int Ptag, int Pclass, int depth, + int *perr); /* * type is a 'bitmap' of acceptable string types. */ @@ -99,7 +104,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, ret = (*a); if (len != 0) { - s = (unsigned char *)OPENSSL_malloc((int)len + 1); + s = OPENSSL_malloc((int)len + 1); if (s == NULL) { i = ERR_R_MALLOC_FAILURE; goto err; @@ -154,15 +159,38 @@ int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass) return (r); } +/* + * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be + * encountered in pratice. + */ + +#define ASN1_BYTES_MAXDEPTH 20 + ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int Ptag, int Pclass) { + int err = 0; + ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err); + if (err != 0) + ASN1err(ASN1_F_D2I_ASN1_BYTES, err); + return s; +} + +static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, + const unsigned char **pp, long length, + int Ptag, int Pclass, + int depth, int *perr) +{ ASN1_STRING *ret = NULL; const unsigned char *p; unsigned char *s; long len; int inf, tag, xclass; - int i = 0; + + if (depth > ASN1_BYTES_MAXDEPTH) { + *perr = ASN1_R_NESTED_ASN1_STRING; + return NULL; + } if ((a == NULL) || ((*a) == NULL)) { if ((ret = ASN1_STRING_new()) == NULL) @@ -173,18 +201,19 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, p = *pp; inf = ASN1_get_object(&p, &len, &tag, &xclass, length); if (inf & 0x80) { - i = ASN1_R_BAD_OBJECT_HEADER; + *perr = ASN1_R_BAD_OBJECT_HEADER; goto err; } if (tag != Ptag) { - i = ASN1_R_WRONG_TAG; + *perr = ASN1_R_WRONG_TAG; goto err; } if (inf & V_ASN1_CONSTRUCTED) { ASN1_const_CTX c; + c.error = 0; c.pp = pp; c.p = p; c.inf = inf; @@ -192,17 +221,18 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, c.tag = Ptag; c.xclass = Pclass; c.max = (length == 0) ? 0 : (p + length); - if (!asn1_collate_primitive(ret, &c)) + if (!asn1_collate_primitive(ret, &c, depth)) { + *perr = c.error; goto err; - else { + } else { p = c.p; } } else { if (len != 0) { if ((ret->length < len) || (ret->data == NULL)) { - s = (unsigned char *)OPENSSL_malloc((int)len + 1); + s = OPENSSL_malloc((int)len + 1); if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; + *perr = ERR_R_MALLOC_FAILURE; goto err; } if (ret->data != NULL) @@ -230,7 +260,6 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_STRING_free(ret); - ASN1err(ASN1_F_D2I_ASN1_BYTES, i); return (NULL); } @@ -242,7 +271,8 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, * There have been a few bug fixes for this function from Paul Keogh * <paul.keogh@sse.ie>, many thanks to him */ -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, + int depth) { ASN1_STRING *os = NULL; BUF_MEM b; @@ -270,9 +300,8 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) } c->q = c->p; - if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass) - == NULL) { - c->error = ERR_R_ASN1_LIB; + if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass, + depth + 1, &c->error) == NULL) { goto err; } @@ -297,7 +326,6 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) ASN1_STRING_free(os); return (1); err: - ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error); if (os != NULL) ASN1_STRING_free(os); if (b.data != NULL) diff --git a/crypto/openssl/crypto/asn1/a_object.c b/crypto/openssl/crypto/asn1/a_object.c index 27f9c16..229a40f 100644 --- a/crypto/openssl/crypto/asn1/a_object.c +++ b/crypto/openssl/crypto/asn1/a_object.c @@ -73,7 +73,7 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) return (0); objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); - if (pp == NULL) + if (pp == NULL || objsize == -1) return objsize; p = *pp; @@ -174,8 +174,12 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) if (!tmp) goto err; } - while (blsize--) - tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); + while (blsize--) { + BN_ULONG t = BN_div_word(bl, 0x80L); + if (t == (BN_ULONG)-1) + goto err; + tmp[i++] = (unsigned char)t; + } } else { for (;;) { diff --git a/crypto/openssl/crypto/asn1/a_set.c b/crypto/openssl/crypto/asn1/a_set.c index bf3f971..5fb5865 100644 --- a/crypto/openssl/crypto/asn1/a_set.c +++ b/crypto/openssl/crypto/asn1/a_set.c @@ -57,6 +57,7 @@ */ #include <stdio.h> +#include <limits.h> #include "cryptlib.h" #include <openssl/asn1_mac.h> @@ -98,10 +99,14 @@ int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, if (a == NULL) return (0); - for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) + for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) { + int tmplen = i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); + if (tmplen > INT_MAX - ret) + return -1; ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); + } r = ASN1_object_size(1, ret, ex_tag); - if (pp == NULL) + if (pp == NULL || r == -1) return (r); p = *pp; diff --git a/crypto/openssl/crypto/asn1/a_strex.c b/crypto/openssl/crypto/asn1/a_strex.c index 35fd44cd2..2d562f9 100644 --- a/crypto/openssl/crypto/asn1/a_strex.c +++ b/crypto/openssl/crypto/asn1/a_strex.c @@ -337,7 +337,7 @@ static const signed char tag2nbyte[] = { -1, -1, -1, -1, -1, /* 5-9 */ -1, -1, 0, -1, /* 10-13 */ -1, -1, -1, -1, /* 15-17 */ - -1, 1, 1, /* 18-20 */ + 1, 1, 1, /* 18-20 */ -1, 1, 1, 1, /* 21-24 */ -1, 1, -1, /* 25-27 */ 4, -1, 2 /* 28-30 */ diff --git a/crypto/openssl/crypto/asn1/a_strnid.c b/crypto/openssl/crypto/asn1/a_strnid.c index 5224345..2d2303d 100644 --- a/crypto/openssl/crypto/asn1/a_strnid.c +++ b/crypto/openssl/crypto/asn1/a_strnid.c @@ -250,6 +250,7 @@ int ASN1_STRING_TABLE_add(int nid, } tmp->flags = flags | STABLE_FLAGS_MALLOC; tmp->nid = nid; + tmp->minsize = tmp->maxsize = -1; new_nid = 1; } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; diff --git a/crypto/openssl/crypto/asn1/ameth_lib.c b/crypto/openssl/crypto/asn1/ameth_lib.c index 5389c04..43ddebb 100644 --- a/crypto/openssl/crypto/asn1/ameth_lib.c +++ b/crypto/openssl/crypto/asn1/ameth_lib.c @@ -93,7 +93,9 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { &eckey_asn1_meth, #endif &hmac_asn1_meth, +#ifndef OPENSSL_NO_CMAC &cmac_asn1_meth, +#endif #ifndef OPENSSL_NO_DH &dhx_asn1_meth #endif diff --git a/crypto/openssl/crypto/asn1/asn1_lib.c b/crypto/openssl/crypto/asn1/asn1_lib.c index 874b1af8..e63e82a 100644 --- a/crypto/openssl/crypto/asn1/asn1_lib.c +++ b/crypto/openssl/crypto/asn1/asn1_lib.c @@ -256,26 +256,30 @@ static void asn1_put_length(unsigned char **pp, int length) int ASN1_object_size(int constructed, int length, int tag) { - int ret; - - ret = length; - ret++; + int ret = 1; + if (length < 0) + return -1; if (tag >= 31) { while (tag > 0) { tag >>= 7; ret++; } } - if (constructed == 2) - return ret + 3; - ret++; - if (length > 127) { - while (length > 0) { - length >>= 8; - ret++; + if (constructed == 2) { + ret += 3; + } else { + ret++; + if (length > 127) { + int tmplen = length; + while (tmplen > 0) { + tmplen >>= 8; + ret++; + } } } - return (ret); + if (ret >= INT_MAX - length) + return -1; + return ret + length; } static int _asn1_Finish(ASN1_const_CTX *c) @@ -324,7 +328,7 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length) return (0); } if (c->inf == (1 | V_ASN1_CONSTRUCTED)) - c->slen = *length + *(c->pp) - c->p; + c->slen = *length; c->eos = 0; return (1); } @@ -366,7 +370,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) else len = strlen(data); } - if ((str->length < len) || (str->data == NULL)) { + if ((str->length <= len) || (str->data == NULL)) { c = str->data; if (c == NULL) str->data = OPENSSL_malloc(len + 1); diff --git a/crypto/openssl/crypto/asn1/asn_mime.c b/crypto/openssl/crypto/asn1/asn_mime.c index 96110c5..5170906 100644 --- a/crypto/openssl/crypto/asn1/asn_mime.c +++ b/crypto/openssl/crypto/asn1/asn_mime.c @@ -289,7 +289,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, if ((flags & SMIME_DETACHED) && data) { /* We want multipart/signed */ /* Generate a random boundary */ - if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0) + if (RAND_bytes((unsigned char *)bound, 32) <= 0) return 0; for (i = 0; i < 32; i++) { c = bound[i] & 0xf; @@ -623,6 +623,8 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) if (bpart) sk_BIO_push(parts, bpart); bpart = BIO_new(BIO_s_mem()); + if (bpart == NULL) + return 1; BIO_set_mem_eof_return(bpart, 0); } else if (eol) BIO_write(bpart, "\r\n", 2); diff --git a/crypto/openssl/crypto/asn1/bio_asn1.c b/crypto/openssl/crypto/asn1/bio_asn1.c index 60189b3..c3afff6 100644 --- a/crypto/openssl/crypto/asn1/bio_asn1.c +++ b/crypto/openssl/crypto/asn1/bio_asn1.c @@ -170,10 +170,12 @@ static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) ctx->copylen = 0; ctx->asn1_class = V_ASN1_UNIVERSAL; ctx->asn1_tag = V_ASN1_OCTET_STRING; - ctx->ex_buf = 0; - ctx->ex_pos = 0; + ctx->ex_buf = NULL; ctx->ex_len = 0; + ctx->ex_pos = 0; ctx->state = ASN1_STATE_START; + ctx->prefix = ctx->prefix_free = ctx->suffix = ctx->suffix_free = NULL; + ctx->ex_arg = NULL; return 1; } diff --git a/crypto/openssl/crypto/asn1/bio_ndef.c b/crypto/openssl/crypto/asn1/bio_ndef.c index 31949b8..8d70466 100644 --- a/crypto/openssl/crypto/asn1/bio_ndef.c +++ b/crypto/openssl/crypto/asn1/bio_ndef.c @@ -136,6 +136,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) ndef_aux->ndef_bio = sarg.ndef_bio; ndef_aux->boundary = sarg.boundary; ndef_aux->out = out; + ndef_aux->derbuf = NULL; BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); diff --git a/crypto/openssl/crypto/asn1/charmap.pl b/crypto/openssl/crypto/asn1/charmap.pl index 25ebf2c..12ac34a 100644 --- a/crypto/openssl/crypto/asn1/charmap.pl +++ b/crypto/openssl/crypto/asn1/charmap.pl @@ -67,17 +67,19 @@ $arr[ord("?")] |= $PSTRING_CHAR; # Now generate the C code print <<EOF; -/* Auto generated with chartype.pl script. - * Mask of various character properties +/* + * Auto generated with chartype.pl script. Mask of various character + * properties */ -static unsigned char char_type[] = { +static const unsigned char char_type[] = { EOF +print " "; for($i = 0; $i < 128; $i++) { - print("\n") if($i && (($i % 16) == 0)); - printf("%2d", $arr[$i]); + print("\n ") if($i && (($i % 16) == 0)); + printf(" %d", $arr[$i]); print(",") if ($i != 127); } -print("\n};\n\n"); +print("\n};\n"); diff --git a/crypto/openssl/crypto/asn1/d2i_pr.c b/crypto/openssl/crypto/asn1/d2i_pr.c index d21829a..86dcf5f 100644 --- a/crypto/openssl/crypto/asn1/d2i_pr.c +++ b/crypto/openssl/crypto/asn1/d2i_pr.c @@ -97,15 +97,17 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, if (!ret->ameth->old_priv_decode || !ret->ameth->old_priv_decode(ret, &p, length)) { if (ret->ameth->priv_decode) { + EVP_PKEY *tmp; PKCS8_PRIV_KEY_INFO *p8 = NULL; p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); if (!p8) goto err; - EVP_PKEY_free(ret); - ret = EVP_PKCS82PKEY(p8); + tmp = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); - if (ret == NULL) + if (tmp == NULL) goto err; + EVP_PKEY_free(ret); + ret = tmp; } else { ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); goto err; diff --git a/crypto/openssl/crypto/asn1/f_enum.c b/crypto/openssl/crypto/asn1/f_enum.c index 591c3b5..94cd54d 100644 --- a/crypto/openssl/crypto/asn1/f_enum.c +++ b/crypto/openssl/crypto/asn1/f_enum.c @@ -160,8 +160,6 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) i * 2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); - if (s != NULL) - OPENSSL_free(s); goto err; } s = sp; @@ -199,5 +197,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) err_sl: ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE); } + if (ret != 1) + OPENSSL_free(s); return (ret); } diff --git a/crypto/openssl/crypto/asn1/f_int.c b/crypto/openssl/crypto/asn1/f_int.c index 4a81f81..2bdc78d 100644 --- a/crypto/openssl/crypto/asn1/f_int.c +++ b/crypto/openssl/crypto/asn1/f_int.c @@ -172,8 +172,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) sp = OPENSSL_realloc_clean(s, slen, num + i * 2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); - if (s != NULL) - OPENSSL_free(s); goto err; } s = sp; @@ -211,5 +209,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) err_sl: ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); } + if (ret != 1) + OPENSSL_free(s); return (ret); } diff --git a/crypto/openssl/crypto/asn1/f_string.c b/crypto/openssl/crypto/asn1/f_string.c index 6a6cf34..0f7b9cf 100644 --- a/crypto/openssl/crypto/asn1/f_string.c +++ b/crypto/openssl/crypto/asn1/f_string.c @@ -166,8 +166,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) i * 2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE); - if (s != NULL) - OPENSSL_free(s); goto err; } s = sp; @@ -205,5 +203,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) err_sl: ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE); } + if (ret != 1) + OPENSSL_free(s); return (ret); } diff --git a/crypto/openssl/crypto/asn1/i2d_pr.c b/crypto/openssl/crypto/asn1/i2d_pr.c index 4d338ac..12966ec 100644 --- a/crypto/openssl/crypto/asn1/i2d_pr.c +++ b/crypto/openssl/crypto/asn1/i2d_pr.c @@ -69,10 +69,13 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) } if (a->ameth && a->ameth->priv_encode) { PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); - int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); - PKCS8_PRIV_KEY_INFO_free(p8); + int ret = 0; + if (p8 != NULL) { + ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); + PKCS8_PRIV_KEY_INFO_free(p8); + } return ret; } ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return (-1); + return -1; } diff --git a/crypto/openssl/crypto/asn1/p5_pbe.c b/crypto/openssl/crypto/asn1/p5_pbe.c index bdbfdcd..e2a1def 100644 --- a/crypto/openssl/crypto/asn1/p5_pbe.c +++ b/crypto/openssl/crypto/asn1/p5_pbe.c @@ -101,7 +101,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, sstr = ASN1_STRING_data(pbe->salt); if (salt) memcpy(sstr, salt, saltlen); - else if (RAND_pseudo_bytes(sstr, saltlen) < 0) + else if (RAND_bytes(sstr, saltlen) <= 0) goto err; if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { diff --git a/crypto/openssl/crypto/asn1/p5_pbev2.c b/crypto/openssl/crypto/asn1/p5_pbev2.c index 73ba4a3..388053e 100644 --- a/crypto/openssl/crypto/asn1/p5_pbev2.c +++ b/crypto/openssl/crypto/asn1/p5_pbev2.c @@ -120,7 +120,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, if (EVP_CIPHER_iv_length(cipher)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); - else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) + else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0) goto err; } @@ -225,7 +225,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, if (salt) memcpy(osalt->data, salt, saltlen); - else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0) + else if (RAND_bytes(osalt->data, saltlen) <= 0) goto merr; if (iter <= 0) diff --git a/crypto/openssl/crypto/asn1/t_req.c b/crypto/openssl/crypto/asn1/t_req.c index 024553a..70aba4c 100644 --- a/crypto/openssl/crypto/asn1/t_req.c +++ b/crypto/openssl/crypto/asn1/t_req.c @@ -196,6 +196,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, if (BIO_puts(bp, ":") <= 0) goto err; if ((type == V_ASN1_PRINTABLESTRING) || + (type == V_ASN1_UTF8STRING) || (type == V_ASN1_T61STRING) || (type == V_ASN1_IA5STRING)) { if (BIO_write(bp, (char *)bs->data, bs->length) diff --git a/crypto/openssl/crypto/asn1/tasn_dec.c b/crypto/openssl/crypto/asn1/tasn_dec.c index 6bdcd5c..d254027 100644 --- a/crypto/openssl/crypto/asn1/tasn_dec.c +++ b/crypto/openssl/crypto/asn1/tasn_dec.c @@ -400,7 +400,9 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, if (tt->flags & ASN1_TFLG_ADB_MASK) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); + seqtt = asn1_do_adb(pval, tt, 0); + if (seqtt == NULL) + continue; pseqval = asn1_get_field_ptr(pval, seqtt); ASN1_template_free(pseqval, seqtt); } @@ -411,7 +413,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) + if (seqtt == NULL) goto err; pseqval = asn1_get_field_ptr(pval, seqtt); /* Have we ran out of data? */ @@ -476,7 +478,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, for (; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) + if (seqtt == NULL) goto err; if (seqtt->flags & ASN1_TFLG_OPTIONAL) { ASN1_VALUE **pseqval; diff --git a/crypto/openssl/crypto/asn1/tasn_enc.c b/crypto/openssl/crypto/asn1/tasn_enc.c index f7f83e5..081a9d5 100644 --- a/crypto/openssl/crypto/asn1/tasn_enc.c +++ b/crypto/openssl/crypto/asn1/tasn_enc.c @@ -59,6 +59,7 @@ #include <stddef.h> #include <string.h> +#include <limits.h> #include "cryptlib.h" #include <openssl/asn1.h> #include <openssl/asn1t.h> @@ -216,17 +217,19 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; + int tmplen; seqtt = asn1_do_adb(pval, tt, 1); if (!seqtt) return 0; pseqval = asn1_get_field_ptr(pval, seqtt); - /* FIXME: check for errors in enhanced version */ - seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, - -1, aclass); + tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); + if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) + return -1; + seqcontlen += tmplen; } seqlen = ASN1_object_size(ndef, seqcontlen, tag); - if (!out) + if (!out || seqlen == -1) return seqlen; /* Output SEQUENCE header */ ASN1_put_object(out, ndef, seqcontlen, tag, aclass); @@ -339,19 +342,24 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, /* Determine total length of items */ skcontlen = 0; for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + int tmplen; skitem = sk_ASN1_VALUE_value(sk, i); - skcontlen += ASN1_item_ex_i2d(&skitem, NULL, - ASN1_ITEM_ptr(tt->item), - -1, iclass); + tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), + -1, iclass); + if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) + return -1; + skcontlen += tmplen; } sklen = ASN1_object_size(ndef, skcontlen, sktag); + if (sklen == -1) + return -1; /* If EXPLICIT need length of surrounding tag */ if (flags & ASN1_TFLG_EXPTAG) ret = ASN1_object_size(ndef, sklen, ttag); else ret = sklen; - if (!out) + if (!out || ret == -1) return ret; /* Now encode this lot... */ @@ -380,7 +388,7 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, return 0; /* Find length of EXPLICIT tag */ ret = ASN1_object_size(ndef, i, ttag); - if (out) { + if (out && ret != -1) { /* Output tag and item */ ASN1_put_object(out, ndef, i, ttag, tclass); ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); diff --git a/crypto/openssl/crypto/asn1/tasn_prn.c b/crypto/openssl/crypto/asn1/tasn_prn.c index 5e7d53e..f628cad 100644 --- a/crypto/openssl/crypto/asn1/tasn_prn.c +++ b/crypto/openssl/crypto/asn1/tasn_prn.c @@ -204,7 +204,8 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, } else asn1_cb = 0; - if (*fld == NULL) { + if (((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) { if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) { if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) return 0; @@ -446,6 +447,8 @@ static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, char *s; int ret = 1; s = i2s_ASN1_INTEGER(NULL, str); + if (s == NULL) + return 0; if (BIO_puts(out, s) <= 0) ret = 0; OPENSSL_free(s); @@ -496,11 +499,16 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, return 0; if (pf && pf->prim_print) return pf->prim_print(out, fld, it, indent, pctx); - str = (ASN1_STRING *)*fld; - if (it->itype == ASN1_ITYPE_MSTRING) + if (it->itype == ASN1_ITYPE_MSTRING) { + str = (ASN1_STRING *)*fld; utype = str->type & ~V_ASN1_NEG; - else + } else { utype = it->utype; + if (utype == V_ASN1_BOOLEAN) + str = NULL; + else + str = (ASN1_STRING *)*fld; + } if (utype == V_ASN1_ANY) { ASN1_TYPE *atype = (ASN1_TYPE *)*fld; utype = atype->type; diff --git a/crypto/openssl/crypto/asn1/tasn_utl.c b/crypto/openssl/crypto/asn1/tasn_utl.c index 41726d8..e14889f 100644 --- a/crypto/openssl/crypto/asn1/tasn_utl.c +++ b/crypto/openssl/crypto/asn1/tasn_utl.c @@ -234,7 +234,7 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, sfld = offset2ptr(*pval, adb->offset); /* Check if NULL */ - if (!sfld) { + if (*sfld == NULL) { if (!adb->null_tt) goto err; return adb->null_tt; diff --git a/crypto/openssl/crypto/asn1/x_bignum.c b/crypto/openssl/crypto/asn1/x_bignum.c index eaf0466..c644199 100644 --- a/crypto/openssl/crypto/asn1/x_bignum.c +++ b/crypto/openssl/crypto/asn1/x_bignum.c @@ -78,6 +78,8 @@ static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); +static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx); static ASN1_PRIMITIVE_FUNCS bignum_pf = { NULL, 0, @@ -85,7 +87,8 @@ static ASN1_PRIMITIVE_FUNCS bignum_pf = { bn_free, 0, bn_c2i, - bn_i2c + bn_i2c, + bn_print }; ASN1_ITEM_start(BIGNUM) @@ -151,3 +154,13 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } return 1; } + +static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx) +{ + if (!BN_print(out, *(BIGNUM **)pval)) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + return 1; +} diff --git a/crypto/openssl/crypto/asn1/x_name.c b/crypto/openssl/crypto/asn1/x_name.c index a858c29..26378fd 100644 --- a/crypto/openssl/crypto/asn1/x_name.c +++ b/crypto/openssl/crypto/asn1/x_name.c @@ -199,10 +199,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, int i, j, ret; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; - if (len > X509_NAME_MAX) { - ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG); - return 0; - } + if (len > X509_NAME_MAX) + len = X509_NAME_MAX; q = p; /* Get internal representation of Name */ diff --git a/crypto/openssl/crypto/asn1/x_x509.c b/crypto/openssl/crypto/asn1/x_x509.c index e31e1e7..aada4a8 100644 --- a/crypto/openssl/crypto/asn1/x_x509.c +++ b/crypto/openssl/crypto/asn1/x_x509.c @@ -199,12 +199,26 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) return NULL; } -int i2d_X509_AUX(X509 *a, unsigned char **pp) +/* + * Serialize trusted certificate to *pp or just return the required buffer + * length if pp == NULL. We ultimately want to avoid modifying *pp in the + * error path, but that depends on similar hygiene in lower-level functions. + * Here we avoid compounding the problem. + */ +static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) { int length, tmplen; unsigned char *start = pp != NULL ? *pp : NULL; + + OPENSSL_assert(pp == NULL || *pp != NULL); + + /* + * This might perturb *pp on error, but fixing that belongs in i2d_X509() + * not here. It should be that if a == NULL length is zero, but we check + * both just in case. + */ length = i2d_X509(a, pp); - if (length < 0 || a == NULL) + if (length <= 0 || a == NULL) return length; tmplen = i2d_X509_CERT_AUX(a->aux, pp); @@ -218,6 +232,42 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp) return length; } +/* + * Serialize trusted certificate to *pp, or just return the required buffer + * length if pp == NULL. + * + * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since + * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do + * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the + * allocated buffer. + */ +int i2d_X509_AUX(X509 *a, unsigned char **pp) +{ + int length; + unsigned char *tmp; + + /* Buffer provided by caller */ + if (pp == NULL || *pp != NULL) + return i2d_x509_aux_internal(a, pp); + + /* Obtain the combined length */ + if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) + return length; + + /* Allocate requisite combined storage */ + *pp = tmp = OPENSSL_malloc(length); + if (tmp == NULL) + return -1; /* Push error onto error stack? */ + + /* Encode, but keep *pp at the originally malloced pointer */ + length = i2d_x509_aux_internal(a, &tmp); + if (length <= 0) { + OPENSSL_free(*pp); + *pp = NULL; + } + return length; +} + int i2d_re_X509_tbs(X509 *x, unsigned char **pp) { x->cert_info->enc.modified = 1; diff --git a/crypto/openssl/crypto/bio/b_print.c b/crypto/openssl/crypto/bio/b_print.c index 90248fa..987fe06 100644 --- a/crypto/openssl/crypto/bio/b_print.c +++ b/crypto/openssl/crypto/bio/b_print.c @@ -423,9 +423,15 @@ _dopr(char **sbuffer, break; } } - *truncated = (currlen > *maxlen - 1); - if (*truncated) - currlen = *maxlen - 1; + /* + * We have to truncate if there is no dynamic buffer and we have filled the + * static buffer. + */ + if (buffer == NULL) { + *truncated = (currlen > *maxlen - 1); + if (*truncated) + currlen = *maxlen - 1; + } if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) return 0; *retlen = currlen - 1; diff --git a/crypto/openssl/crypto/bio/bf_nbio.c b/crypto/openssl/crypto/bio/bf_nbio.c index a04f32a..4842bb4 100644 --- a/crypto/openssl/crypto/bio/bf_nbio.c +++ b/crypto/openssl/crypto/bio/bf_nbio.c @@ -139,7 +139,7 @@ static int nbiof_read(BIO *b, char *out, int outl) BIO_clear_retry_flags(b); #if 1 - if (RAND_pseudo_bytes(&n, 1) < 0) + if (RAND_bytes(&n, 1) <= 0) return -1; num = (n & 0x07); @@ -179,7 +179,7 @@ static int nbiof_write(BIO *b, const char *in, int inl) num = nt->lwn; nt->lwn = 0; } else { - if (RAND_pseudo_bytes(&n, 1) < 0) + if (RAND_bytes(&n, 1) <= 0) return -1; num = (n & 7); } diff --git a/crypto/openssl/crypto/bio/bio.h b/crypto/openssl/crypto/bio/bio.h index 6790aed..8f2438c 100644 --- a/crypto/openssl/crypto/bio/bio.h +++ b/crypto/openssl/crypto/bio/bio.h @@ -559,11 +559,11 @@ int BIO_read_filename(BIO *b, const char *name); # define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) # define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) # define BIO_set_ssl_renegotiate_bytes(b,num) \ - BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) # define BIO_get_num_renegotiates(b) \ - BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL); + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) # define BIO_set_ssl_renegotiate_timeout(b,seconds) \ - BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) /* defined in evp.h */ /* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ diff --git a/crypto/openssl/crypto/bio/bss_bio.c b/crypto/openssl/crypto/bio/bss_bio.c index 4d8727f..3dd8187 100644 --- a/crypto/openssl/crypto/bio/bss_bio.c +++ b/crypto/openssl/crypto/bio/bss_bio.c @@ -149,9 +149,13 @@ static int bio_new(BIO *bio) return 0; b->peer = NULL; + b->closed = 0; + b->len = 0; + b->offset = 0; /* enough for one TLS record (just a default) */ b->size = 17 * 1024; b->buf = NULL; + b->request = 0; bio->ptr = b; return 1; @@ -655,16 +659,15 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) break; case BIO_CTRL_EOF: - { - BIO *other_bio = ptr; - - if (other_bio) { - struct bio_bio_st *other_b = other_bio->ptr; + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; - assert(other_b != NULL); - ret = other_b->len == 0 && other_b->closed; - } else + if (peer_b->len == 0 && peer_b->closed) ret = 1; + else + ret = 0; + } else { + ret = 1; } break; diff --git a/crypto/openssl/crypto/bio/bss_file.c b/crypto/openssl/crypto/bio/bss_file.c index bfba93e..a6e3b3a 100644 --- a/crypto/openssl/crypto/bio/bss_file.c +++ b/crypto/openssl/crypto/bio/bss_file.c @@ -174,7 +174,11 @@ BIO *BIO_new_file(const char *filename, const char *mode) if (file == NULL) { SYSerr(SYS_F_FOPEN, get_last_sys_error()); ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); - if (errno == ENOENT) + if (errno == ENOENT +# ifdef ENXIO + || errno == ENXIO +# endif + ) BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); else BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); diff --git a/crypto/openssl/crypto/bio/bss_rtcp.c b/crypto/openssl/crypto/bio/bss_rtcp.c index 09f14f4..5c98a82 100644 --- a/crypto/openssl/crypto/bio/bss_rtcp.c +++ b/crypto/openssl/crypto/bio/bss_rtcp.c @@ -170,6 +170,8 @@ static int rtcp_new(BIO *bi) bi->num = 0; bi->flags = 0; bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx)); + if (bi->ptr == NULL) + return (0); ctx = (struct rpc_ctx *)bi->ptr; ctx->filled = 0; ctx->pos = 0; diff --git a/crypto/openssl/crypto/bn/asm/x86-mont.pl b/crypto/openssl/crypto/bn/asm/x86-mont.pl index 89f4de6..1c4003e 100755 --- a/crypto/openssl/crypto/bn/asm/x86-mont.pl +++ b/crypto/openssl/crypto/bn/asm/x86-mont.pl @@ -63,27 +63,26 @@ $frame=32; # size of above frame rounded up to 16n &lea ("esi",&wparam(0)); # put aside pointer to argument block &lea ("edx",&wparam(1)); # load ap - &mov ("ebp","esp"); # saved stack pointer! &add ("edi",2); # extra two words on top of tp &neg ("edi"); - &lea ("esp",&DWP(-$frame,"esp","edi",4)); # alloca($frame+4*(num+2)) + &lea ("ebp",&DWP(-$frame,"esp","edi",4)); # future alloca($frame+4*(num+2)) &neg ("edi"); # minimize cache contention by arraning 2K window between stack # pointer and ap argument [np is also position sensitive vector, # but it's assumed to be near ap, as it's allocated at ~same # time]. - &mov ("eax","esp"); + &mov ("eax","ebp"); &sub ("eax","edx"); &and ("eax",2047); - &sub ("esp","eax"); # this aligns sp and ap modulo 2048 + &sub ("ebp","eax"); # this aligns sp and ap modulo 2048 - &xor ("edx","esp"); + &xor ("edx","ebp"); &and ("edx",2048); &xor ("edx",2048); - &sub ("esp","edx"); # this splits them apart modulo 4096 + &sub ("ebp","edx"); # this splits them apart modulo 4096 - &and ("esp",-64); # align to cache line + &and ("ebp",-64); # align to cache line # Some OSes, *cough*-dows, insist on stack being "wired" to # physical memory in strictly sequential manner, i.e. if stack @@ -91,20 +90,28 @@ $frame=32; # size of above frame rounded up to 16n # be punishable by SEGV. But page walking can do good even on # other OSes, because it guarantees that villain thread hits # the guard page before it can make damage to innocent one... - &mov ("eax","ebp"); - &sub ("eax","esp"); + &mov ("eax","esp"); + &sub ("eax","ebp"); &and ("eax",-4096); -&set_label("page_walk"); - &mov ("edx",&DWP(0,"esp","eax")); - &sub ("eax",4096); - &data_byte(0x2e); - &jnc (&label("page_walk")); + &mov ("edx","esp"); # saved stack pointer! + &lea ("esp",&DWP(0,"ebp","eax")); + &mov ("eax",&DWP(0,"esp")); + &cmp ("esp","ebp"); + &ja (&label("page_walk")); + &jmp (&label("page_walk_done")); + +&set_label("page_walk",16); + &lea ("esp",&DWP(-4096,"esp")); + &mov ("eax",&DWP(0,"esp")); + &cmp ("esp","ebp"); + &ja (&label("page_walk")); +&set_label("page_walk_done"); ################################# load argument block... &mov ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp &mov ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap &mov ("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp - &mov ("edx",&DWP(3*4,"esi"));# const BN_ULONG *np + &mov ("ebp",&DWP(3*4,"esi"));# const BN_ULONG *np &mov ("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0 #&mov ("edi",&DWP(5*4,"esi"));# int num @@ -112,11 +119,11 @@ $frame=32; # size of above frame rounded up to 16n &mov ($_rp,"eax"); # ... save a copy of argument block &mov ($_ap,"ebx"); &mov ($_bp,"ecx"); - &mov ($_np,"edx"); + &mov ($_np,"ebp"); &mov ($_n0,"esi"); &lea ($num,&DWP(-3,"edi")); # num=num-1 to assist modulo-scheduling #&mov ($_num,$num); # redundant as $num is not reused - &mov ($_sp,"ebp"); # saved stack pointer! + &mov ($_sp,"edx"); # saved stack pointer! if($sse2) { $acc0="mm0"; # mmx register bank layout diff --git a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c index d77dc43..1729b47 100644 --- a/crypto/openssl/crypto/bn/asm/x86_64-gcc.c +++ b/crypto/openssl/crypto/bn/asm/x86_64-gcc.c @@ -194,7 +194,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) BN_ULONG ret, waste; asm("divq %4":"=a"(ret), "=d"(waste) - : "a"(l), "d"(h), "g"(d) + : "a"(l), "d"(h), "r"(d) : "cc"); return ret; diff --git a/crypto/openssl/crypto/bn/asm/x86_64-mont.pl b/crypto/openssl/crypto/bn/asm/x86_64-mont.pl index 8fb6c99..044fd7e 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-mont.pl @@ -97,6 +97,8 @@ $code=<<___; .type bn_mul_mont,\@function,6 .align 16 bn_mul_mont: + mov ${num}d,${num}d + mov %rsp,%rax test \$3,${num}d jnz .Lmul_enter cmp \$8,${num}d @@ -121,29 +123,36 @@ $code.=<<___; push %r14 push %r15 - mov ${num}d,${num}d - lea 2($num),%r10 + neg $num mov %rsp,%r11 - neg %r10 - lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+2)) - and \$-1024,%rsp # minimize TLB usage + lea -16(%rsp,$num,8),%r10 # future alloca(8*(num+2)) + neg $num # restore $num + and \$-1024,%r10 # minimize TLB usage - mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp -.Lmul_body: # Some OSes, *cough*-dows, insist on stack being "wired" to # physical memory in strictly sequential manner, i.e. if stack # allocation spans two pages, then reference to farmost one can # be punishable by SEGV. But page walking can do good even on # other OSes, because it guarantees that villain thread hits # the guard page before it can make damage to innocent one... - sub %rsp,%r11 + sub %r10,%r11 and \$-4096,%r11 + lea (%r10,%r11),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + +.align 16 .Lmul_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x66,0x2e # predict non-taken - jnc .Lmul_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul_body: mov $bp,%r12 # reassign $bp ___ $bp="%r12"; @@ -314,13 +323,13 @@ $code.=<<___; mov 8(%rsp,$num,8),%rsi # restore %rsp mov \$1,%rax - mov (%rsi),%r15 - mov 8(%rsi),%r14 - mov 16(%rsi),%r13 - mov 24(%rsi),%r12 - mov 32(%rsi),%rbp - mov 40(%rsi),%rbx - lea 48(%rsi),%rsp + mov -48(%rsi),%r15 + mov -40(%rsi),%r14 + mov -32(%rsi),%r13 + mov -24(%rsi),%r12 + mov -16(%rsi),%rbp + mov -8(%rsi),%rbx + lea (%rsi),%rsp .Lmul_epilogue: ret .size bn_mul_mont,.-bn_mul_mont @@ -332,6 +341,8 @@ $code.=<<___; .type bn_mul4x_mont,\@function,6 .align 16 bn_mul4x_mont: + mov ${num}d,${num}d + mov %rsp,%rax .Lmul4x_enter: ___ $code.=<<___ if ($addx); @@ -347,23 +358,29 @@ $code.=<<___; push %r14 push %r15 - mov ${num}d,${num}d - lea 4($num),%r10 + neg $num mov %rsp,%r11 - neg %r10 - lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+4)) - and \$-1024,%rsp # minimize TLB usage + lea -32(%rsp,$num,8),%r10 # future alloca(8*(num+4)) + neg $num # restore + and \$-1024,%r10 # minimize TLB usage - mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp -.Lmul4x_body: - sub %rsp,%r11 + sub %r10,%r11 and \$-4096,%r11 + lea (%r10,%r11),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + .Lmul4x_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lmul4x_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul4x_body: mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp mov %rdx,%r12 # reassign $bp ___ @@ -742,13 +759,13 @@ ___ $code.=<<___; mov 8(%rsp,$num,8),%rsi # restore %rsp mov \$1,%rax - mov (%rsi),%r15 - mov 8(%rsi),%r14 - mov 16(%rsi),%r13 - mov 24(%rsi),%r12 - mov 32(%rsi),%rbp - mov 40(%rsi),%rbx - lea 48(%rsi),%rsp + mov -48(%rsi),%r15 + mov -40(%rsi),%r14 + mov -32(%rsi),%r13 + mov -24(%rsi),%r12 + mov -16(%rsi),%rbp + mov -8(%rsi),%rbx + lea (%rsi),%rsp .Lmul4x_epilogue: ret .size bn_mul4x_mont,.-bn_mul4x_mont @@ -778,14 +795,15 @@ $code.=<<___; .type bn_sqr8x_mont,\@function,6 .align 32 bn_sqr8x_mont: -.Lsqr8x_enter: mov %rsp,%rax +.Lsqr8x_enter: push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lsqr8x_prologue: mov ${num}d,%r10d shl \$3,${num}d # convert $num to bytes @@ -798,33 +816,42 @@ bn_sqr8x_mont: # do its job. # lea -64(%rsp,$num,2),%r11 + mov %rsp,%rbp mov ($n0),$n0 # *n0 sub $aptr,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lsqr8x_sp_alt - sub %r11,%rsp # align with $aptr - lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num) + sub %r11,%rbp # align with $aptr + lea -64(%rbp,$num,2),%rbp # future alloca(frame+2*$num) jmp .Lsqr8x_sp_done .align 32 .Lsqr8x_sp_alt: lea 4096-64(,$num,2),%r10 # 4096-frame-2*$num - lea -64(%rsp,$num,2),%rsp # alloca(frame+2*$num) + lea -64(%rbp,$num,2),%rbp # future alloca(frame+2*$num) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lsqr8x_sp_done: - and \$-64,%rsp - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lsqr8x_page_walk + jmp .Lsqr8x_page_walk_done + +.align 16 .Lsqr8x_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lsqr8x_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lsqr8x_page_walk +.Lsqr8x_page_walk_done: mov $num,%r10 neg $num @@ -948,30 +975,38 @@ $code.=<<___; .type bn_mulx4x_mont,\@function,6 .align 32 bn_mulx4x_mont: -.Lmulx4x_enter: mov %rsp,%rax +.Lmulx4x_enter: push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lmulx4x_prologue: shl \$3,${num}d # convert $num to bytes - .byte 0x67 xor %r10,%r10 sub $num,%r10 # -$num mov ($n0),$n0 # *n0 - lea -72(%rsp,%r10),%rsp # alloca(frame+$num+8) - and \$-128,%rsp - mov %rax,%r11 - sub %rsp,%r11 + lea -72(%rsp,%r10),%rbp # future alloca(frame+$num+8) + and \$-128,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + +.align 16 .Lmulx4x_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x66,0x2e # predict non-taken - jnc .Lmulx4x_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: lea ($bp,$num),%r10 ############################################################## @@ -1332,22 +1367,8 @@ mul_handler: mov 192($context),%r10 # pull $num mov 8(%rax,%r10,8),%rax # pull saved stack pointer - lea 48(%rax),%rax - - mov -8(%rax),%rbx - mov -16(%rax),%rbp - mov -24(%rax),%r12 - mov -32(%rax),%r13 - mov -40(%rax),%r14 - mov -48(%rax),%r15 - mov %rbx,144($context) # restore context->Rbx - mov %rbp,160($context) # restore context->Rbp - mov %r12,216($context) # restore context->R12 - mov %r13,224($context) # restore context->R13 - mov %r14,232($context) # restore context->R14 - mov %r15,240($context) # restore context->R15 - jmp .Lcommon_seh_tail + jmp .Lcommon_pop_regs .size mul_handler,.-mul_handler .type sqr_handler,\@abi-omnipotent @@ -1375,15 +1396,21 @@ sqr_handler: cmp %r10,%rbx # context->Rip<.Lsqr_body jb .Lcommon_seh_tail + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # body label + cmp %r10,%rbx # context->Rip>=.Lsqr_epilogue + jb .Lcommon_pop_regs + mov 152($context),%rax # pull context->Rsp - mov 4(%r11),%r10d # HandlerData[1] + mov 8(%r11),%r10d # HandlerData[2] lea (%rsi,%r10),%r10 # epilogue label cmp %r10,%rbx # context->Rip>=.Lsqr_epilogue jae .Lcommon_seh_tail mov 40(%rax),%rax # pull saved stack pointer +.Lcommon_pop_regs: mov -8(%rax),%rbx mov -16(%rax),%rbp mov -24(%rax),%r12 @@ -1470,13 +1497,15 @@ $code.=<<___; .LSEH_info_bn_sqr8x_mont: .byte 9,0,0,0 .rva sqr_handler - .rva .Lsqr8x_body,.Lsqr8x_epilogue # HandlerData[] + .rva .Lsqr8x_prologue,.Lsqr8x_body,.Lsqr8x_epilogue # HandlerData[] +.align 8 ___ $code.=<<___ if ($addx); .LSEH_info_bn_mulx4x_mont: .byte 9,0,0,0 .rva sqr_handler - .rva .Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[] + .rva .Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[] +.align 8 ___ } diff --git a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl index 938e170..f1fbb45 100755 --- a/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/openssl/crypto/bn/asm/x86_64-mont5.pl @@ -86,6 +86,8 @@ $code=<<___; .type bn_mul_mont_gather5,\@function,6 .align 64 bn_mul_mont_gather5: + mov ${num}d,${num}d + mov %rsp,%rax test \$7,${num}d jnz .Lmul_enter ___ @@ -97,10 +99,7 @@ $code.=<<___; .align 16 .Lmul_enter: - mov ${num}d,${num}d - mov %rsp,%rax movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument - lea .Linc(%rip),%r10 push %rbx push %rbp push %r12 @@ -108,26 +107,36 @@ $code.=<<___; push %r14 push %r15 - lea 2($num),%r11 - neg %r11 - lea -264(%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)+256+8) - and \$-1024,%rsp # minimize TLB usage + neg $num + mov %rsp,%r11 + lea -280(%rsp,$num,8),%r10 # future alloca(8*(num+2)+256+8) + neg $num # restore $num + and \$-1024,%r10 # minimize TLB usage - mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp -.Lmul_body: # Some OSes, *cough*-dows, insist on stack being "wired" to # physical memory in strictly sequential manner, i.e. if stack # allocation spans two pages, then reference to farmost one can # be punishable by SEGV. But page walking can do good even on # other OSes, because it guarantees that villain thread hits # the guard page before it can make damage to innocent one... - sub %rsp,%rax - and \$-4096,%rax + sub %r10,%r11 + and \$-4096,%r11 + lea (%r10,%r11),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul_page_walk + jmp .Lmul_page_walk_done + .Lmul_page_walk: - mov (%rsp,%rax),%r11 - sub \$4096,%rax - .byte 0x2e # predict non-taken - jnc .Lmul_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r11 + cmp %r10,%rsp + ja .Lmul_page_walk +.Lmul_page_walk_done: + + lea .Linc(%rip),%r10 + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul_body: lea 128($bp),%r12 # reassign $bp (+size optimization) ___ @@ -433,6 +442,8 @@ $code.=<<___; .type bn_mul4x_mont_gather5,\@function,6 .align 32 bn_mul4x_mont_gather5: + .byte 0x67 + mov %rsp,%rax .Lmul4x_enter: ___ $code.=<<___ if ($addx); @@ -441,14 +452,13 @@ $code.=<<___ if ($addx); je .Lmulx4x_enter ___ $code.=<<___; - .byte 0x67 - mov %rsp,%rax push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lmul4x_prologue: .byte 0x67 shl \$3,${num}d # convert $num to bytes @@ -465,32 +475,40 @@ $code.=<<___; # calculated from 7th argument, the index.] # lea -320(%rsp,$num,2),%r11 + mov %rsp,%rbp sub $rp,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lmul4xsp_alt - sub %r11,%rsp # align with $rp - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256) + sub %r11,%rbp # align with $rp + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256) jmp .Lmul4xsp_done .align 32 .Lmul4xsp_alt: lea 4096-320(,$num,2),%r10 - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256) + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lmul4xsp_done: - and \$-64,%rsp - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmul4x_page_walk + jmp .Lmul4x_page_walk_done + .Lmul4x_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lmul4x_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmul4x_page_walk +.Lmul4x_page_walk_done: neg $num @@ -1034,6 +1052,7 @@ $code.=<<___; .type bn_power5,\@function,6 .align 32 bn_power5: + mov %rsp,%rax ___ $code.=<<___ if ($addx); mov OPENSSL_ia32cap_P+8(%rip),%r11d @@ -1042,13 +1061,13 @@ $code.=<<___ if ($addx); je .Lpowerx5_enter ___ $code.=<<___; - mov %rsp,%rax push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lpower5_prologue: shl \$3,${num}d # convert $num to bytes lea ($num,$num,2),%r10d # 3*$num @@ -1063,32 +1082,40 @@ $code.=<<___; # calculated from 7th argument, the index.] # lea -320(%rsp,$num,2),%r11 + mov %rsp,%rbp sub $rptr,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lpwr_sp_alt - sub %r11,%rsp # align with $aptr - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256) + sub %r11,%rbp # align with $aptr + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256) jmp .Lpwr_sp_done .align 32 .Lpwr_sp_alt: lea 4096-320(,$num,2),%r10 - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*num*8+256) + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*num*8+256) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lpwr_sp_done: - and \$-64,%rsp - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lpwr_page_walk + jmp .Lpwr_page_walk_done + .Lpwr_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lpwr_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lpwr_page_walk +.Lpwr_page_walk_done: mov $num,%r10 neg $num @@ -2028,6 +2055,7 @@ bn_from_mont8x: push %r13 push %r14 push %r15 +.Lfrom_prologue: shl \$3,${num}d # convert $num to bytes lea ($num,$num,2),%r10 # 3*$num in bytes @@ -2042,32 +2070,40 @@ bn_from_mont8x: # last operation, we use the opportunity to cleanse it. # lea -320(%rsp,$num,2),%r11 + mov %rsp,%rbp sub $rptr,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lfrom_sp_alt - sub %r11,%rsp # align with $aptr - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + sub %r11,%rbp # align with $aptr + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) jmp .Lfrom_sp_done .align 32 .Lfrom_sp_alt: lea 4096-320(,$num,2),%r10 - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lfrom_sp_done: - and \$-64,%rsp - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lfrom_page_walk + jmp .Lfrom_page_walk_done + .Lfrom_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lfrom_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lfrom_page_walk +.Lfrom_page_walk_done: mov $num,%r10 neg $num @@ -2173,14 +2209,15 @@ $code.=<<___; .type bn_mulx4x_mont_gather5,\@function,6 .align 32 bn_mulx4x_mont_gather5: -.Lmulx4x_enter: mov %rsp,%rax +.Lmulx4x_enter: push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lmulx4x_prologue: shl \$3,${num}d # convert $num to bytes lea ($num,$num,2),%r10 # 3*$num in bytes @@ -2197,31 +2234,39 @@ bn_mulx4x_mont_gather5: # calculated from 7th argument, the index.] # lea -320(%rsp,$num,2),%r11 + mov %rsp,%rbp sub $rp,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lmulx4xsp_alt - sub %r11,%rsp # align with $aptr - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + sub %r11,%rbp # align with $aptr + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) jmp .Lmulx4xsp_done .Lmulx4xsp_alt: lea 4096-320(,$num,2),%r10 - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lmulx4xsp_done: - and \$-64,%rsp # ensure alignment - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp # ensure alignment + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmulx4x_page_walk + jmp .Lmulx4x_page_walk_done + .Lmulx4x_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lmulx4x_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lmulx4x_page_walk +.Lmulx4x_page_walk_done: ############################################################## # Stack layout @@ -2629,14 +2674,15 @@ $code.=<<___; .type bn_powerx5,\@function,6 .align 32 bn_powerx5: -.Lpowerx5_enter: mov %rsp,%rax +.Lpowerx5_enter: push %rbx push %rbp push %r12 push %r13 push %r14 push %r15 +.Lpowerx5_prologue: shl \$3,${num}d # convert $num to bytes lea ($num,$num,2),%r10 # 3*$num in bytes @@ -2651,32 +2697,40 @@ bn_powerx5: # calculated from 7th argument, the index.] # lea -320(%rsp,$num,2),%r11 + mov %rsp,%rbp sub $rptr,%r11 and \$4095,%r11 cmp %r11,%r10 jb .Lpwrx_sp_alt - sub %r11,%rsp # align with $aptr - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + sub %r11,%rbp # align with $aptr + lea -320(%rbp,$num,2),%rbp # future alloca(frame+2*$num*8+256) jmp .Lpwrx_sp_done .align 32 .Lpwrx_sp_alt: lea 4096-320(,$num,2),%r10 - lea -320(%rsp,$num,2),%rsp # alloca(frame+2*$num*8+256) + lea -320(%rbp,$num,2),%rbp # alloca(frame+2*$num*8+256) sub %r10,%r11 mov \$0,%r10 cmovc %r10,%r11 - sub %r11,%rsp + sub %r11,%rbp .Lpwrx_sp_done: - and \$-64,%rsp - mov %rax,%r11 - sub %rsp,%r11 + and \$-64,%rbp + mov %rsp,%r11 + sub %rbp,%r11 and \$-4096,%r11 + lea (%rbp,%r11),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lpwrx_page_walk + jmp .Lpwrx_page_walk_done + .Lpwrx_page_walk: - mov (%rsp,%r11),%r10 - sub \$4096,%r11 - .byte 0x2e # predict non-taken - jnc .Lpwrx_page_walk + lea -4096(%rsp),%rsp + mov (%rsp),%r10 + cmp %rbp,%rsp + ja .Lpwrx_page_walk +.Lpwrx_page_walk_done: mov $num,%r10 neg $num @@ -3607,9 +3661,14 @@ mul_handler: cmp %r10,%rbx # context->Rip<end of prologue label jb .Lcommon_seh_tail + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jb .Lcommon_pop_regs + mov 152($context),%rax # pull context->Rsp - mov 4(%r11),%r10d # HandlerData[1] + mov 8(%r11),%r10d # HandlerData[2] lea (%rsi,%r10),%r10 # epilogue label cmp %r10,%rbx # context->Rip>=epilogue label jae .Lcommon_seh_tail @@ -3621,11 +3680,11 @@ mul_handler: mov 192($context),%r10 # pull $num mov 8(%rax,%r10,8),%rax # pull saved stack pointer - jmp .Lbody_proceed + jmp .Lcommon_pop_regs .Lbody_40: mov 40(%rax),%rax # pull saved stack pointer -.Lbody_proceed: +.Lcommon_pop_regs: mov -8(%rax),%rbx mov -16(%rax),%rbp mov -24(%rax),%r12 @@ -3716,34 +3775,34 @@ $code.=<<___; .LSEH_info_bn_mul_mont_gather5: .byte 9,0,0,0 .rva mul_handler - .rva .Lmul_body,.Lmul_epilogue # HandlerData[] + .rva .Lmul_body,.Lmul_body,.Lmul_epilogue # HandlerData[] .align 8 .LSEH_info_bn_mul4x_mont_gather5: .byte 9,0,0,0 .rva mul_handler - .rva .Lmul4x_body,.Lmul4x_epilogue # HandlerData[] + .rva .Lmul4x_prologue,.Lmul4x_body,.Lmul4x_epilogue # HandlerData[] .align 8 .LSEH_info_bn_power5: .byte 9,0,0,0 .rva mul_handler - .rva .Lpower5_body,.Lpower5_epilogue # HandlerData[] + .rva .Lpower5_prologue,.Lpower5_body,.Lpower5_epilogue # HandlerData[] .align 8 .LSEH_info_bn_from_mont8x: .byte 9,0,0,0 .rva mul_handler - .rva .Lfrom_body,.Lfrom_epilogue # HandlerData[] + .rva .Lfrom_prologue,.Lfrom_body,.Lfrom_epilogue # HandlerData[] ___ $code.=<<___ if ($addx); .align 8 .LSEH_info_bn_mulx4x_mont_gather5: .byte 9,0,0,0 .rva mul_handler - .rva .Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[] + .rva .Lmulx4x_prologue,.Lmulx4x_body,.Lmulx4x_epilogue # HandlerData[] .align 8 .LSEH_info_bn_powerx5: .byte 9,0,0,0 .rva mul_handler - .rva .Lpowerx5_body,.Lpowerx5_epilogue # HandlerData[] + .rva .Lpowerx5_prologue,.Lpowerx5_body,.Lpowerx5_epilogue # HandlerData[] ___ $code.=<<___; .align 8 diff --git a/crypto/openssl/crypto/bn/bn.h b/crypto/openssl/crypto/bn/bn.h index 86264ae..633d1b1 100644 --- a/crypto/openssl/crypto/bn/bn.h +++ b/crypto/openssl/crypto/bn/bn.h @@ -842,6 +842,8 @@ int RAND_pseudo_bytes(unsigned char *buf, int num); if (*(ftl--)) break; \ (a)->top = tmp_top; \ } \ + if ((a)->top == 0) \ + (a)->neg = 0; \ bn_pollute(a); \ } diff --git a/crypto/openssl/crypto/bn/bn_div.c b/crypto/openssl/crypto/bn/bn_div.c index 72e6ce3..bc37671 100644 --- a/crypto/openssl/crypto/bn/bn_div.c +++ b/crypto/openssl/crypto/bn/bn_div.c @@ -155,7 +155,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, ({ asm volatile ( \ "divl %4" \ : "=a"(q), "=d"(rem) \ - : "a"(n1), "d"(n0), "g"(d0) \ + : "a"(n1), "d"(n0), "r"(d0) \ : "cc"); \ q; \ }) @@ -170,7 +170,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, ({ asm volatile ( \ "divq %4" \ : "=a"(q), "=d"(rem) \ - : "a"(n1), "d"(n0), "g"(d0) \ + : "a"(n1), "d"(n0), "r"(d0) \ : "cc"); \ q; \ }) diff --git a/crypto/openssl/crypto/bn/bn_lib.c b/crypto/openssl/crypto/bn/bn_lib.c index 80105ff..10b78f5 100644 --- a/crypto/openssl/crypto/bn/bn_lib.c +++ b/crypto/openssl/crypto/bn/bn_lib.c @@ -569,7 +569,7 @@ void BN_clear(BIGNUM *a) { bn_check_top(a); if (a->d != NULL) - memset(a->d, 0, a->dmax * sizeof(a->d[0])); + OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); a->top = 0; a->neg = 0; } diff --git a/crypto/openssl/crypto/bn/bn_print.c b/crypto/openssl/crypto/bn/bn_print.c index bfa31ef..f121fb6 100644 --- a/crypto/openssl/crypto/bn/bn_print.c +++ b/crypto/openssl/crypto/bn/bn_print.c @@ -72,12 +72,9 @@ char *BN_bn2hex(const BIGNUM *a) char *buf; char *p; - if (a->neg && BN_is_zero(a)) { - /* "-0" == 3 bytes including NULL terminator */ - buf = OPENSSL_malloc(3); - } else { - buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); - } + if (BN_is_zero(a)) + return OPENSSL_strdup("0"); + buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); if (buf == NULL) { BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE); goto err; @@ -111,6 +108,7 @@ char *BN_bn2dec(const BIGNUM *a) char *p; BIGNUM *t = NULL; BN_ULONG *bn_data = NULL, *lp; + int bn_data_num; /*- * get an upper bound for the length of the decimal integer @@ -120,9 +118,9 @@ char *BN_bn2dec(const BIGNUM *a) */ i = BN_num_bits(a) * 3; num = (i / 10 + i / 1000 + 1) + 1; - bn_data = - (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); - buf = (char *)OPENSSL_malloc(num + 3); + bn_data_num = num / BN_DEC_NUM + 1; + bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = OPENSSL_malloc(num + 3); if ((buf == NULL) || (bn_data == NULL)) { BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); goto err; @@ -140,9 +138,12 @@ char *BN_bn2dec(const BIGNUM *a) if (BN_is_negative(t)) *p++ = '-'; - i = 0; while (!BN_is_zero(t)) { + if (lp - bn_data >= bn_data_num) + goto err; *lp = BN_div_word(t, BN_DEC_CONV); + if (*lp == (BN_ULONG)-1) + goto err; lp++; } lp--; @@ -240,10 +241,12 @@ int BN_hex2bn(BIGNUM **bn, const char *a) } ret->top = h; bn_correct_top(ret); - ret->neg = neg; *bn = ret; bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; return (num); err: if (*bn == NULL) @@ -295,7 +298,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a) if (j == BN_DEC_NUM) j = 0; l = 0; - while (*a) { + while (--i >= 0) { l *= 10; l += *a - '0'; a++; @@ -306,11 +309,13 @@ int BN_dec2bn(BIGNUM **bn, const char *a) j = 0; } } - ret->neg = neg; bn_correct_top(ret); *bn = ret; bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; return (num); err: if (*bn == NULL) @@ -321,6 +326,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a) int BN_asc2bn(BIGNUM **bn, const char *a) { const char *p = a; + if (*p == '-') p++; @@ -331,7 +337,8 @@ int BN_asc2bn(BIGNUM **bn, const char *a) if (!BN_dec2bn(bn, p)) return 0; } - if (*a == '-') + /* Don't set the negative flag if it's zero. */ + if (*a == '-' && (*bn)->top != 0) (*bn)->neg = 1; return 1; } diff --git a/crypto/openssl/crypto/bn/bn_rand.c b/crypto/openssl/crypto/bn/bn_rand.c index f9fb2e9..60d3f22 100644 --- a/crypto/openssl/crypto/bn/bn_rand.c +++ b/crypto/openssl/crypto/bn/bn_rand.c @@ -121,15 +121,14 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) int ret = 0, bit, bytes, mask; time_t tim; - if (bits < 0 || (bits == 1 && top > 0)) { - BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); - return 0; - } - if (bits == 0) { + if (top != -1 || bottom != 0) + goto toosmall; BN_zero(rnd); return 1; } + if (bits < 0 || (bits == 1 && top > 0)) + goto toosmall; bytes = (bits + 7) / 8; bit = (bits - 1) % 8; @@ -145,13 +144,9 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) time(&tim); RAND_add(&tim, sizeof(tim), 0.0); - if (pseudorand) { - if (RAND_pseudo_bytes(buf, bytes) == -1) - goto err; - } else { - if (RAND_bytes(buf, bytes) <= 0) - goto err; - } + /* We ignore the value of pseudorand and always call RAND_bytes */ + if (RAND_bytes(buf, bytes) <= 0) + goto err; #if 1 if (pseudorand == 2) { @@ -199,6 +194,10 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) } bn_check_top(rnd); return (ret); + +toosmall: + BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); + return 0; } int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) diff --git a/crypto/openssl/crypto/bn/bn_word.c b/crypto/openssl/crypto/bn/bn_word.c index b031a60..9b5f9cb 100644 --- a/crypto/openssl/crypto/bn/bn_word.c +++ b/crypto/openssl/crypto/bn/bn_word.c @@ -72,10 +72,32 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) if (w == 0) return (BN_ULONG)-1; +#ifndef BN_LLONG + /* + * If |w| is too long and we don't have BN_ULLONG then we need to fall + * back to using BN_div_word + */ + if (w > ((BN_ULONG)1 << BN_BITS4)) { + BIGNUM *tmp = BN_dup(a); + if (tmp == NULL) + return (BN_ULONG)-1; + + ret = BN_div_word(tmp, w); + BN_free(tmp); + + return ret; + } +#endif + bn_check_top(a); w &= BN_MASK2; for (i = a->top - 1; i >= 0; i--) { #ifndef BN_LLONG + /* + * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so + * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are + * safe and will not overflow + */ ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; #else diff --git a/crypto/openssl/crypto/bn/bntest.c b/crypto/openssl/crypto/bn/bntest.c index 1e35988..a327b1a 100644 --- a/crypto/openssl/crypto/bn/bntest.c +++ b/crypto/openssl/crypto/bn/bntest.c @@ -514,7 +514,7 @@ static void print_word(BIO *bp, BN_ULONG w) int test_div_word(BIO *bp) { BIGNUM a, b; - BN_ULONG r, s; + BN_ULONG r, rmod, s; int i; BN_init(&a); @@ -528,8 +528,14 @@ int test_div_word(BIO *bp) s = b.d[0]; BN_copy(&b, &a); + rmod = BN_mod_word(&b, s); r = BN_div_word(&b, s); + if (rmod != r) { + fprintf(stderr, "Mod (word) test failed!\n"); + return 0; + } + if (bp != NULL) { if (!results) { BN_print(bp, &a); diff --git a/crypto/openssl/crypto/cms/cms_enc.c b/crypto/openssl/crypto/cms/cms_enc.c index b14b4b6..90b1fcc 100644 --- a/crypto/openssl/crypto/cms/cms_enc.c +++ b/crypto/openssl/crypto/cms/cms_enc.c @@ -119,7 +119,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { - if (RAND_pseudo_bytes(iv, ivlen) <= 0) + if (RAND_bytes(iv, ivlen) <= 0) goto err; piv = iv; } @@ -179,10 +179,9 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } - - if (piv) { + if (enc) { calg->parameter = ASN1_TYPE_new(); - if (!calg->parameter) { + if (calg->parameter == NULL) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } @@ -191,6 +190,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } + /* If parameter type not set omit parameter */ + if (calg->parameter->type == V_ASN1_UNDEF) { + ASN1_TYPE_free(calg->parameter); + calg->parameter = NULL; + } } ok = 1; diff --git a/crypto/openssl/crypto/cms/cms_ess.c b/crypto/openssl/crypto/cms/cms_ess.c index 8631a2e..8212560 100644 --- a/crypto/openssl/crypto/cms/cms_ess.c +++ b/crypto/openssl/crypto/cms/cms_ess.c @@ -107,8 +107,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, else { if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) goto merr; - if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) - <= 0) + if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) goto err; } diff --git a/crypto/openssl/crypto/cms/cms_lib.c b/crypto/openssl/crypto/cms/cms_lib.c index d6cb60d..6d27c49 100644 --- a/crypto/openssl/crypto/cms/cms_lib.c +++ b/crypto/openssl/crypto/cms/cms_lib.c @@ -413,6 +413,8 @@ static STACK_OF(CMS_CertificateChoices) return &cms->d.signedData->certificates; case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; return &cms->d.envelopedData->originatorInfo->certificates; default: @@ -488,6 +490,8 @@ static STACK_OF(CMS_RevocationInfoChoice) return &cms->d.signedData->crls; case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; return &cms->d.envelopedData->originatorInfo->crls; default: diff --git a/crypto/openssl/crypto/cms/cms_pwri.c b/crypto/openssl/crypto/cms/cms_pwri.c index b91c016..5c817ca 100644 --- a/crypto/openssl/crypto/cms/cms_pwri.c +++ b/crypto/openssl/crypto/cms/cms_pwri.c @@ -134,7 +134,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ivlen = EVP_CIPHER_CTX_iv_length(&ctx); if (ivlen > 0) { - if (RAND_pseudo_bytes(iv, ivlen) <= 0) + if (RAND_bytes(iv, ivlen) <= 0) goto err; if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); @@ -301,7 +301,7 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, memcpy(out + 4, in, inlen); /* Add random padding to end */ if (olen > inlen + 4 - && RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen) < 0) + && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) return 0; /* Encrypt twice */ EVP_EncryptUpdate(ctx, out, &dummy, out, olen); diff --git a/crypto/openssl/crypto/comp/comp.h b/crypto/openssl/crypto/comp/comp.h index 60a0734..df599ba 100644 --- a/crypto/openssl/crypto/comp/comp.h +++ b/crypto/openssl/crypto/comp/comp.h @@ -14,7 +14,7 @@ extern "C" { typedef struct comp_ctx_st COMP_CTX; -typedef struct comp_method_st { +struct comp_method_st { int type; /* NID for compression library */ const char *name; /* A text string to identify the library */ int (*init) (COMP_CTX *ctx); @@ -30,7 +30,7 @@ typedef struct comp_method_st { */ long (*ctrl) (void); long (*callback_ctrl) (void); -} COMP_METHOD; +}; struct comp_ctx_st { COMP_METHOD *meth; diff --git a/crypto/openssl/crypto/conf/conf_def.h b/crypto/openssl/crypto/conf/conf_def.h index 7d897b89..48b3442 100644 --- a/crypto/openssl/crypto/conf/conf_def.h +++ b/crypto/openssl/crypto/conf/conf_def.h @@ -81,34 +81,34 @@ #define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) #ifndef CHARSET_EBCDIC -# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) -# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) -# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) -# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) -# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) -# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) -# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) # define IS_ALPHA_NUMERIC_PUNCT(c,a) \ (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) -# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) -# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) -#else /* CHARSET_EBCDIC */ +#else /*CHARSET_EBCDIC*/ -# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) -# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) -# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) -# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) -# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) -# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) -# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) +# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) # define IS_ALPHA_NUMERIC_PUNCT(c,a) \ (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) -# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) -# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) -#endif /* CHARSET_EBCDIC */ +# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) +#endif /*CHARSET_EBCDIC*/ static unsigned short CONF_type_default[256] = { 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, diff --git a/crypto/openssl/crypto/conf/conf_mod.c b/crypto/openssl/crypto/conf/conf_mod.c index 9acfca4..e0c9a67 100644 --- a/crypto/openssl/crypto/conf/conf_mod.c +++ b/crypto/openssl/crypto/conf/conf_mod.c @@ -288,6 +288,10 @@ static CONF_MODULE *module_add(DSO *dso, const char *name, tmod->dso = dso; tmod->name = BUF_strdup(name); + if (tmod->name == NULL) { + OPENSSL_free(tmod); + return NULL; + } tmod->init = ifunc; tmod->finish = ffunc; tmod->links = 0; diff --git a/crypto/openssl/crypto/conf/keysets.pl b/crypto/openssl/crypto/conf/keysets.pl index 50ed67f..5c9b2aa 100644 --- a/crypto/openssl/crypto/conf/keysets.pl +++ b/crypto/openssl/crypto/conf/keysets.pl @@ -59,21 +59,21 @@ print <<"EOF"; * This package is an SSL implementation written * by Eric Young (eay\@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh\@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -88,10 +88,10 @@ print <<"EOF"; * Eric Young (eay\@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh\@cryptsoft.com)" - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -103,83 +103,85 @@ print <<"EOF"; * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ -/* THIS FILE WAS AUTOMAGICALLY GENERATED! - Please modify and use keysets.pl to regenerate it. */ - -#define CONF_NUMBER $NUMBER -#define CONF_UPPER $UPPER -#define CONF_LOWER $LOWER -#define CONF_UNDER $UNDER -#define CONF_PUNCTUATION $PUNCTUATION -#define CONF_WS $WS -#define CONF_ESC $ESC -#define CONF_QUOTE $QUOTE -#define CONF_DQUOTE $DQUOTE -#define CONF_COMMENT $COMMENT -#define CONF_FCOMMENT $FCOMMENT -#define CONF_EOF $EOF -#define CONF_HIGHBIT $HIGHBIT -#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) -#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +/* + * THIS FILE WAS AUTOMAGICALLY GENERATED! Please modify and use keysets.pl to + * regenerate it. + */ + +#define CONF_NUMBER $NUMBER +#define CONF_UPPER $UPPER +#define CONF_LOWER $LOWER +#define CONF_UNDER $UNDER +#define CONF_PUNCTUATION $PUNCTUATION +#define CONF_WS $WS +#define CONF_ESC $ESC +#define CONF_QUOTE $QUOTE +#define CONF_DQUOTE $DQUOTE +#define CONF_COMMENT $COMMENT +#define CONF_FCOMMENT $FCOMMENT +#define CONF_EOF $EOF +#define CONF_HIGHBIT $HIGHBIT +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) #define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \\ - CONF_PUNCTUATION) + CONF_PUNCTUATION) -#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) #ifndef CHARSET_EBCDIC -#define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) -#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) -#define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) -#define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) -#define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) -#define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) -#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) -#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ - (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -#define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) -#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) -#define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) +# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) #else /*CHARSET_EBCDIC*/ -#define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) -#define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) -#define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) -#define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) -#define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) -#define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) -#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) -#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ - (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -#define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) -#define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) -#define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) +# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ + (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) #endif /*CHARSET_EBCDIC*/ EOF -print "static unsigned short CONF_type_default[256]={"; +print "static unsigned short CONF_type_default[256] = {"; for ($i=0; $i<256; $i++) { - print "\n\t" if ($i % 8) == 0; - printf "0x%04X,",$V_def[$i]; + print "\n " if ($i % 8) == 0; + printf " 0x%04X,",$V_def[$i]; } -print "\n\t};\n\n"; +print "\n};\n\n"; -print "static unsigned short CONF_type_win32[256]={"; +print "static unsigned short CONF_type_win32[256] = {"; for ($i=0; $i<256; $i++) { - print "\n\t" if ($i % 8) == 0; - printf "0x%04X,",$V_w32[$i]; + print "\n " if ($i % 8) == 0; + printf " 0x%04X,",$V_w32[$i]; } -print "\n\t};\n\n"; +print "\n};\n"; diff --git a/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl b/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl index 1dc6024..5f3a511 100755 --- a/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl +++ b/crypto/openssl/crypto/des/asm/dest4-sparcv9.pl @@ -96,7 +96,7 @@ $code.=<<___; des_t4_cbc_encrypt: cmp $len, 0 be,pn $::size_t_cc, .Lcbc_abort - nop + srln $len, 0, $len ! needed on v8+, "nop" on v9 ld [$ivec + 0], %f0 ! load ivec ld [$ivec + 4], %f1 @@ -197,7 +197,7 @@ des_t4_cbc_encrypt: des_t4_cbc_decrypt: cmp $len, 0 be,pn $::size_t_cc, .Lcbc_abort - nop + srln $len, 0, $len ! needed on v8+, "nop" on v9 ld [$ivec + 0], %f2 ! load ivec ld [$ivec + 4], %f3 @@ -305,7 +305,7 @@ $code.=<<___; des_t4_ede3_cbc_encrypt: cmp $len, 0 be,pn $::size_t_cc, .Lcbc_abort - nop + srln $len, 0, $len ! needed on v8+, "nop" on v9 ld [$ivec + 0], %f0 ! load ivec ld [$ivec + 4], %f1 @@ -457,7 +457,7 @@ des_t4_ede3_cbc_encrypt: des_t4_ede3_cbc_decrypt: cmp $len, 0 be,pn $::size_t_cc, .Lcbc_abort - nop + srln $len, 0, $len ! needed on v8+, "nop" on v9 ld [$ivec + 0], %f2 ! load ivec ld [$ivec + 4], %f3 diff --git a/crypto/openssl/crypto/des/des.c b/crypto/openssl/crypto/des/des.c index 586aed7..d737438 100644 --- a/crypto/openssl/crypto/des/des.c +++ b/crypto/openssl/crypto/des/des.c @@ -456,7 +456,7 @@ void doencryption(void) len = l - rem; if (feof(DES_IN)) { for (i = 7 - rem; i > 0; i--) { - if (RAND_pseudo_bytes(buf + l++, 1) < 0) + if (RAND_bytes(buf + l++, 1) <= 0) goto problems; } buf[l++] = rem; diff --git a/crypto/openssl/crypto/des/enc_writ.c b/crypto/openssl/crypto/des/enc_writ.c index bfaabde..c2aaa8e 100644 --- a/crypto/openssl/crypto/des/enc_writ.c +++ b/crypto/openssl/crypto/des/enc_writ.c @@ -135,7 +135,7 @@ int DES_enc_write(int fd, const void *_buf, int len, if (len < 8) { cp = shortbuf; memcpy(shortbuf, buf, len); - if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) { + if (RAND_bytes(shortbuf + len, 8 - len) <= 0) { return -1; } rnum = 8; diff --git a/crypto/openssl/crypto/dh/dh_ameth.c b/crypto/openssl/crypto/dh/dh_ameth.c index ac72468..4558283 100644 --- a/crypto/openssl/crypto/dh/dh_ameth.c +++ b/crypto/openssl/crypto/dh/dh_ameth.c @@ -519,7 +519,7 @@ static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) static int dh_missing_parameters(const EVP_PKEY *a) { - if (!a->pkey.dh->p || !a->pkey.dh->g) + if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL) return 1; return 0; } diff --git a/crypto/openssl/crypto/dsa/dsa_ameth.c b/crypto/openssl/crypto/dsa/dsa_ameth.c index cc83d6e..c4fa105 100644 --- a/crypto/openssl/crypto/dsa/dsa_ameth.c +++ b/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -350,7 +350,7 @@ static int dsa_missing_parameters(const EVP_PKEY *pkey) { DSA *dsa; dsa = pkey->pkey.dsa; - if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) + if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) return 1; return 0; } diff --git a/crypto/openssl/crypto/dsa/dsa_gen.c b/crypto/openssl/crypto/dsa/dsa_gen.c index 15f3bb4..1fce0f8 100644 --- a/crypto/openssl/crypto/dsa/dsa_gen.c +++ b/crypto/openssl/crypto/dsa/dsa_gen.c @@ -185,6 +185,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); + if (test == NULL) + goto err; + if (!BN_lshift(test, BN_value_one(), bits - 1)) goto err; @@ -197,7 +200,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, goto err; if (!seed_len || !seed_in) { - if (RAND_pseudo_bytes(seed, qsize) < 0) + if (RAND_bytes(seed, qsize) <= 0) goto err; seed_is_random = 1; } else { @@ -491,7 +494,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, goto err; if (!seed_in) { - if (RAND_pseudo_bytes(seed, seed_len) < 0) + if (RAND_bytes(seed, seed_len) <= 0) goto err; } /* step 2 */ diff --git a/crypto/openssl/crypto/dsa/dsa_ossl.c b/crypto/openssl/crypto/dsa/dsa_ossl.c index efc4f1b..58013a4 100644 --- a/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -247,11 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, do if (!BN_rand_range(&k, dsa->q)) goto err; - while (BN_is_zero(&k)) ; + while (BN_is_zero(&k)); + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { BN_set_flags(&k, BN_FLG_CONSTTIME); } + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, CRYPTO_LOCK_DSA, dsa->p, ctx)) @@ -264,6 +266,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if (!BN_copy(&kq, &k)) goto err; + BN_set_flags(&kq, BN_FLG_CONSTTIME); + /* * We do not want timing information to leak the length of k, so we * compute g^k using an equivalent exponent of fixed length. (This @@ -282,6 +286,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, } else { K = &k; } + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p); if (!BN_mod(r, r, dsa->q, ctx)) diff --git a/crypto/openssl/crypto/ec/Makefile b/crypto/openssl/crypto/ec/Makefile index 8949145..6628390 100644 --- a/crypto/openssl/crypto/ec/Makefile +++ b/crypto/openssl/crypto/ec/Makefile @@ -131,7 +131,7 @@ ec_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h ec_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h ec_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h ec_ameth.o: ../../include/openssl/x509_vfy.h ../asn1/asn1_locl.h ../cryptlib.h -ec_ameth.o: ec_ameth.c +ec_ameth.o: ec_ameth.c ec_lcl.h ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h diff --git a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl index 7140860..7948bf7 100755 --- a/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/openssl/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -128,6 +128,7 @@ ecp_nistz256_mul_by_2: push %r13 mov 8*0($a_ptr), $a0 + xor $t4,$t4 mov 8*1($a_ptr), $a1 add $a0, $a0 # a0:a3+a0:a3 mov 8*2($a_ptr), $a2 @@ -138,7 +139,7 @@ ecp_nistz256_mul_by_2: adc $a2, $a2 adc $a3, $a3 mov $a1, $t1 - sbb $t4, $t4 + adc \$0, $t4 sub 8*0($a_ptr), $a0 mov $a2, $t2 @@ -146,14 +147,14 @@ ecp_nistz256_mul_by_2: sbb 8*2($a_ptr), $a2 mov $a3, $t3 sbb 8*3($a_ptr), $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -250,12 +251,12 @@ ecp_nistz256_mul_by_3: sbb \$0, $a2 mov $a3, $t3 sbb .Lpoly+8*3(%rip), $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 - cmovz $t2, $a2 - cmovz $t3, $a3 + cmovc $t0, $a0 + cmovc $t1, $a1 + cmovc $t2, $a2 + cmovc $t3, $a3 xor $t4, $t4 add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3] @@ -272,14 +273,14 @@ ecp_nistz256_mul_by_3: sbb \$0, $a2 mov $a3, $t3 sbb .Lpoly+8*3(%rip), $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -318,14 +319,14 @@ ecp_nistz256_add: sbb 8*2($a_ptr), $a2 mov $a3, $t3 sbb 8*3($a_ptr), $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -1840,13 +1841,14 @@ $code.=<<___; .type __ecp_nistz256_add_toq,\@abi-omnipotent .align 32 __ecp_nistz256_add_toq: + xor $t4,$t4 add 8*0($b_ptr), $a0 adc 8*1($b_ptr), $a1 mov $a0, $t0 adc 8*2($b_ptr), $a2 adc 8*3($b_ptr), $a3 mov $a1, $t1 - sbb $t4, $t4 + adc \$0, $t4 sub \$-1, $a0 mov $a2, $t2 @@ -1854,14 +1856,14 @@ __ecp_nistz256_add_toq: sbb \$0, $a2 mov $a3, $t3 sbb $poly3, $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -1929,13 +1931,14 @@ __ecp_nistz256_subq: .type __ecp_nistz256_mul_by_2q,\@abi-omnipotent .align 32 __ecp_nistz256_mul_by_2q: + xor $t4, $t4 add $a0, $a0 # a0:a3+a0:a3 adc $a1, $a1 mov $a0, $t0 adc $a2, $a2 adc $a3, $a3 mov $a1, $t1 - sbb $t4, $t4 + adc \$0, $t4 sub \$-1, $a0 mov $a2, $t2 @@ -1943,14 +1946,14 @@ __ecp_nistz256_mul_by_2q: sbb \$0, $a2 mov $a3, $t3 sbb $poly3, $a3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $a0 - cmovz $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovz $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovz $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -2241,16 +2244,14 @@ $code.=<<___; mov $b_org, $a_ptr # reassign movdqa %xmm0, $in1_x(%rsp) movdqa %xmm1, $in1_x+0x10(%rsp) - por %xmm0, %xmm1 movdqa %xmm2, $in1_y(%rsp) movdqa %xmm3, $in1_y+0x10(%rsp) - por %xmm2, %xmm3 movdqa %xmm4, $in1_z(%rsp) movdqa %xmm5, $in1_z+0x10(%rsp) - por %xmm1, %xmm3 + por %xmm4, %xmm5 movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$b_ptr - pshufd \$0xb1, %xmm3, %xmm5 + pshufd \$0xb1, %xmm5, %xmm3 movdqu 0x10($a_ptr), %xmm1 movdqu 0x20($a_ptr), %xmm2 por %xmm3, %xmm5 @@ -2262,14 +2263,14 @@ $code.=<<___; movdqa %xmm0, $in2_x(%rsp) pshufd \$0x1e, %xmm5, %xmm4 movdqa %xmm1, $in2_x+0x10(%rsp) - por %xmm0, %xmm1 - movq $r_ptr, %xmm0 # save $r_ptr + movdqu 0x40($a_ptr),%xmm0 # in2_z again + movdqu 0x50($a_ptr),%xmm1 movdqa %xmm2, $in2_y(%rsp) movdqa %xmm3, $in2_y+0x10(%rsp) - por %xmm2, %xmm3 por %xmm4, %xmm5 pxor %xmm4, %xmm4 - por %xmm1, %xmm3 + por %xmm0, %xmm1 + movq $r_ptr, %xmm0 # save $r_ptr lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid mov $src0, $in2_z+8*0(%rsp) # make in2_z copy @@ -2280,8 +2281,8 @@ $code.=<<___; call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z2sqr, in2_z); pcmpeqd %xmm4, %xmm5 - pshufd \$0xb1, %xmm3, %xmm4 - por %xmm3, %xmm4 + pshufd \$0xb1, %xmm1, %xmm4 + por %xmm1, %xmm4 pshufd \$0, %xmm5, %xmm5 # in1infty pshufd \$0x1e, %xmm4, %xmm3 por %xmm3, %xmm4 @@ -2405,6 +2406,7 @@ $code.=<<___; #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2 #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2); + xor $t4, $t4 add $acc0, $acc0 # a0:a3+a0:a3 lea $Rsqr(%rsp), $a_ptr adc $acc1, $acc1 @@ -2412,7 +2414,7 @@ $code.=<<___; adc $acc2, $acc2 adc $acc3, $acc3 mov $acc1, $t1 - sbb $t4, $t4 + adc \$0, $t4 sub \$-1, $acc0 mov $acc2, $t2 @@ -2420,15 +2422,15 @@ $code.=<<___; sbb \$0, $acc2 mov $acc3, $t3 sbb $poly3, $acc3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $acc0 + cmovc $t0, $acc0 mov 8*0($a_ptr), $t0 - cmovz $t1, $acc1 + cmovc $t1, $acc1 mov 8*1($a_ptr), $t1 - cmovz $t2, $acc2 + cmovc $t2, $acc2 mov 8*2($a_ptr), $t2 - cmovz $t3, $acc3 + cmovc $t3, $acc3 mov 8*3($a_ptr), $t3 call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr); @@ -2612,16 +2614,14 @@ $code.=<<___; mov 0x40+8*3($a_ptr), $acc0 movdqa %xmm0, $in1_x(%rsp) movdqa %xmm1, $in1_x+0x10(%rsp) - por %xmm0, %xmm1 movdqa %xmm2, $in1_y(%rsp) movdqa %xmm3, $in1_y+0x10(%rsp) - por %xmm2, %xmm3 movdqa %xmm4, $in1_z(%rsp) movdqa %xmm5, $in1_z+0x10(%rsp) - por %xmm1, %xmm3 + por %xmm4, %xmm5 movdqu 0x00($b_ptr), %xmm0 # copy *(P256_POINT_AFFINE *)$b_ptr - pshufd \$0xb1, %xmm3, %xmm5 + pshufd \$0xb1, %xmm5, %xmm3 movdqu 0x10($b_ptr), %xmm1 movdqu 0x20($b_ptr), %xmm2 por %xmm3, %xmm5 @@ -2710,6 +2710,7 @@ $code.=<<___; #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2 #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2); + xor $t4, $t4 add $acc0, $acc0 # a0:a3+a0:a3 lea $Rsqr(%rsp), $a_ptr adc $acc1, $acc1 @@ -2717,7 +2718,7 @@ $code.=<<___; adc $acc2, $acc2 adc $acc3, $acc3 mov $acc1, $t1 - sbb $t4, $t4 + adc \$0, $t4 sub \$-1, $acc0 mov $acc2, $t2 @@ -2725,15 +2726,15 @@ $code.=<<___; sbb \$0, $acc2 mov $acc3, $t3 sbb $poly3, $acc3 - test $t4, $t4 + sbb \$0, $t4 - cmovz $t0, $acc0 + cmovc $t0, $acc0 mov 8*0($a_ptr), $t0 - cmovz $t1, $acc1 + cmovc $t1, $acc1 mov 8*1($a_ptr), $t1 - cmovz $t2, $acc2 + cmovc $t2, $acc2 mov 8*2($a_ptr), $t2 - cmovz $t3, $acc3 + cmovc $t3, $acc3 mov 8*3($a_ptr), $t3 call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr); @@ -2885,14 +2886,14 @@ __ecp_nistz256_add_tox: sbb \$0, $a2 mov $a3, $t3 sbb $poly3, $a3 + sbb \$0, $t4 - bt \$0, $t4 - cmovnc $t0, $a0 - cmovnc $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovnc $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovnc $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) @@ -2980,14 +2981,14 @@ __ecp_nistz256_mul_by_2x: sbb \$0, $a2 mov $a3, $t3 sbb $poly3, $a3 + sbb \$0, $t4 - bt \$0, $t4 - cmovnc $t0, $a0 - cmovnc $t1, $a1 + cmovc $t0, $a0 + cmovc $t1, $a1 mov $a0, 8*0($r_ptr) - cmovnc $t2, $a2 + cmovc $t2, $a2 mov $a1, 8*1($r_ptr) - cmovnc $t3, $a3 + cmovc $t3, $a3 mov $a2, 8*2($r_ptr) mov $a3, 8*3($r_ptr) diff --git a/crypto/openssl/crypto/ec/ec_ameth.c b/crypto/openssl/crypto/ec/ec_ameth.c index 83e208c..d089af7 100644 --- a/crypto/openssl/crypto/ec/ec_ameth.c +++ b/crypto/openssl/crypto/ec/ec_ameth.c @@ -66,9 +66,12 @@ #endif #include <openssl/asn1t.h> #include "asn1_locl.h" +#include "ec_lcl.h" +#ifndef OPENSSL_NO_CMS static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); +#endif static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) { @@ -221,6 +224,8 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); + if (group == NULL || pa == NULL || pb == NULL) + return -2; r = EC_POINT_cmp(group, pa, pb, NULL); if (r == 0) return 1; @@ -299,15 +304,13 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { - EC_KEY *ec_key; + EC_KEY ec_key = *(pkey->pkey.ec); unsigned char *ep, *p; int eplen, ptype; void *pval; - unsigned int tmp_flags, old_flags; - - ec_key = pkey->pkey.ec; + unsigned int old_flags; - if (!eckey_param2type(&ptype, &pval, ec_key)) { + if (!eckey_param2type(&ptype, &pval, &ec_key)) { ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); return 0; } @@ -318,30 +321,25 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) * do not include the parameters in the SEC1 private key see PKCS#11 * 12.11 */ - old_flags = EC_KEY_get_enc_flags(ec_key); - tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; - EC_KEY_set_enc_flags(ec_key, tmp_flags); - eplen = i2d_ECPrivateKey(ec_key, NULL); + old_flags = EC_KEY_get_enc_flags(&ec_key); + EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); + + eplen = i2d_ECPrivateKey(&ec_key, NULL); if (!eplen) { - EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } ep = (unsigned char *)OPENSSL_malloc(eplen); if (!ep) { - EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } p = ep; - if (!i2d_ECPrivateKey(ec_key, &p)) { - EC_KEY_set_enc_flags(ec_key, old_flags); + if (!i2d_ECPrivateKey(&ec_key, &p)) { OPENSSL_free(ep); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } - /* restore old encoding flags */ - EC_KEY_set_enc_flags(ec_key, old_flags); if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, ptype, pval, ep, eplen)) @@ -378,7 +376,7 @@ static int ec_bits(const EVP_PKEY *pkey) static int ec_missing_parameters(const EVP_PKEY *pkey) { - if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) return 1; return 0; } @@ -398,6 +396,8 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); + if (group_a == NULL || group_b == NULL) + return -2; if (EC_GROUP_cmp(group_a, group_b, NULL)) return 0; else diff --git a/crypto/openssl/crypto/ec/ec_key.c b/crypto/openssl/crypto/ec/ec_key.c index bc94ab5..456080e 100644 --- a/crypto/openssl/crypto/ec/ec_key.c +++ b/crypto/openssl/crypto/ec/ec_key.c @@ -377,9 +377,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, return 0; } ctx = BN_CTX_new(); - if (!ctx) - goto err; - + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); point = EC_POINT_new(key->group); if (!point) @@ -432,10 +432,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, ok = 1; err: - if (ctx) - BN_CTX_free(ctx); - if (point) - EC_POINT_free(point); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); return ok; } diff --git a/crypto/openssl/crypto/ec/ecp_nistz256.c b/crypto/openssl/crypto/ec/ecp_nistz256.c index ca44d0a..99b8d61 100644 --- a/crypto/openssl/crypto/ec/ecp_nistz256.c +++ b/crypto/openssl/crypto/ec/ecp_nistz256.c @@ -82,19 +82,36 @@ typedef struct ec_pre_comp_st { } EC_PRE_COMP; /* Functions implemented in assembly */ +/* + * Most of below mentioned functions *preserve* the property of inputs + * being fully reduced, i.e. being in [0, modulus) range. Simply put if + * inputs are fully reduced, then output is too. Note that reverse is + * not true, in sense that given partially reduced inputs output can be + * either, not unlikely reduced. And "most" in first sentence refers to + * the fact that given the calculations flow one can tolerate that + * addition, 1st function below, produces partially reduced result *if* + * multiplications by 2 and 3, which customarily use addition, fully + * reduce it. This effectively gives two options: a) addition produces + * fully reduced result [as long as inputs are, just like remaining + * functions]; b) addition is allowed to produce partially reduced + * result, but multiplications by 2 and 3 perform additional reduction + * step. Choice between the two can be platform-specific, but it was a) + * in all cases so far... + */ +/* Modular add: res = a+b mod P */ +void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); /* Modular mul by 2: res = 2*a mod P */ void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); -/* Modular div by 2: res = a/2 mod P */ -void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS]); /* Modular mul by 3: res = 3*a mod P */ void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); -/* Modular add: res = a+b mod P */ -void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], - const BN_ULONG a[P256_LIMBS], - const BN_ULONG b[P256_LIMBS]); + +/* Modular div by 2: res = a/2 mod P */ +void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS]); /* Modular sub: res = a-b mod P */ void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS], @@ -205,21 +222,29 @@ static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS], return is_zero(res); } -static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) +static BN_ULONG is_one(const BIGNUM *z) { - BN_ULONG res; - - res = a[0] ^ ONE[0]; - res |= a[1] ^ ONE[1]; - res |= a[2] ^ ONE[2]; - res |= a[3] ^ ONE[3]; - if (P256_LIMBS == 8) { - res |= a[4] ^ ONE[4]; - res |= a[5] ^ ONE[5]; - res |= a[6] ^ ONE[6]; + BN_ULONG res = 0; + BN_ULONG *a = z->d; + + if (z->top == (P256_LIMBS - P256_LIMBS / 8)) { + res = a[0] ^ ONE[0]; + res |= a[1] ^ ONE[1]; + res |= a[2] ^ ONE[2]; + res |= a[3] ^ ONE[3]; + if (P256_LIMBS == 8) { + res |= a[4] ^ ONE[4]; + res |= a[5] ^ ONE[5]; + res |= a[6] ^ ONE[6]; + /* + * no check for a[7] (being zero) on 32-bit platforms, + * because value of "one" takes only 7 limbs. + */ + } + res = is_zero(res); } - return is_zero(res); + return res; } static int ecp_nistz256_set_words(BIGNUM *a, BN_ULONG words[P256_LIMBS]) @@ -315,19 +340,16 @@ static void ecp_nistz256_point_add(P256_POINT *r, const BN_ULONG *in2_y = b->Y; const BN_ULONG *in2_z = b->Z; - /* We encode infinity as (0,0), which is not on the curve, - * so it is OK. */ - in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] | - in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]); + /* + * Infinity in encoded as (,,0) + */ + in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]); if (P256_LIMBS == 8) - in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] | - in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]); + in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]); - in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] | - in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]); + in2infty = (in2_z[0] | in2_z[1] | in2_z[2] | in2_z[3]); if (P256_LIMBS == 8) - in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] | - in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]); + in2infty |= (in2_z[4] | in2_z[5] | in2_z[6] | in2_z[7]); in1infty = is_zero(in1infty); in2infty = is_zero(in2infty); @@ -416,15 +438,16 @@ static void ecp_nistz256_point_add_affine(P256_POINT *r, const BN_ULONG *in2_y = b->Y; /* - * In affine representation we encode infty as (0,0), which is not on the - * curve, so it is OK + * Infinity in encoded as (,,0) */ - in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] | - in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]); + in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]); if (P256_LIMBS == 8) - in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] | - in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]); + in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]); + /* + * In affine representation we encode infinity as (0,0), which is + * not on the curve, so it is OK + */ in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] | in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]); if (P256_LIMBS == 8) @@ -741,9 +764,8 @@ static int ecp_nistz256_is_affine_G(const EC_POINT *generator) { return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) && - (generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) && is_equal(generator->X.d, def_xG) && - is_equal(generator->Y.d, def_yG) && is_one(generator->Z.d); + is_equal(generator->Y.d, def_yG) && is_one(&generator->Z); } static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) @@ -1249,6 +1271,8 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, } else #endif { + BN_ULONG infty; + /* First window */ wvalue = (p_str[0] << 1) & mask; index += window_size; @@ -1260,7 +1284,30 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, ecp_nistz256_neg(p.p.Z, p.p.Y); copy_conditional(p.p.Y, p.p.Z, wvalue & 1); - memcpy(p.p.Z, ONE, sizeof(ONE)); + /* + * Since affine infinity is encoded as (0,0) and + * Jacobian ias (,,0), we need to harmonize them + * by assigning "one" or zero to Z. + */ + infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] | + p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]); + if (P256_LIMBS == 8) + infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] | + p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]); + + infty = 0 - is_zero(infty); + infty = ~infty; + + p.p.Z[0] = ONE[0] & infty; + p.p.Z[1] = ONE[1] & infty; + p.p.Z[2] = ONE[2] & infty; + p.p.Z[3] = ONE[3] & infty; + if (P256_LIMBS == 8) { + p.p.Z[4] = ONE[4] & infty; + p.p.Z[5] = ONE[5] & infty; + p.p.Z[6] = ONE[6] & infty; + p.p.Z[7] = ONE[7] & infty; + } for (i = 1; i < 37; i++) { unsigned int off = (index - 1) / 8; @@ -1331,7 +1378,7 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group, !ecp_nistz256_set_words(&r->Z, p.p.Z)) { goto err; } - r->Z_is_one = is_one(p.p.Z) & 1; + r->Z_is_one = is_one(&r->Z) & 1; ret = 1; diff --git a/crypto/openssl/crypto/engine/eng_cryptodev.c b/crypto/openssl/crypto/engine/eng_cryptodev.c index 8fb9c33..65a74df 100644 --- a/crypto/openssl/crypto/engine/eng_cryptodev.c +++ b/crypto/openssl/crypto/engine/eng_cryptodev.c @@ -26,6 +26,7 @@ * */ +#include <string.h> #include <openssl/objects.h> #include <openssl/engine.h> #include <openssl/evp.h> @@ -934,11 +935,15 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) return (0); } + dstate->mac_len = fstate->mac_len; if (fstate->mac_len != 0) { if (fstate->mac_data != NULL) { dstate->mac_data = OPENSSL_malloc(fstate->mac_len); + if (dstate->ac_data == NULL) { + printf("cryptodev_digest_init: malloc failed\n"); + return 0; + } memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); - dstate->mac_len = fstate->mac_len; } } @@ -1064,8 +1069,7 @@ static void zapparams(struct crypt_kop *kop) int i; for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { - if (kop->crk_param[i].crp_p) - free(kop->crk_param[i].crp_p); + OPENSSL_free(kop->crk_param[i].crp_p); kop->crk_param[i].crp_p = NULL; kop->crk_param[i].crp_nbits = 0; } @@ -1078,16 +1082,25 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, int fd, ret = -1; if ((fd = get_asym_dev_crypto()) < 0) - return (ret); + return ret; if (r) { - kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); + kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_malloc(rlen); + if (kop->crk_param[kop->crk_iparams].crp_p == NULL) + return ret; + memset(kop->crk_param[kop->crk_iparams].crp_p, 0, (size_t)rlen); kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; kop->crk_oparams++; } if (s) { - kop->crk_param[kop->crk_iparams + 1].crp_p = - calloc(slen, sizeof(char)); + kop->crk_param[kop->crk_iparams + 1].crp_p = OPENSSL_malloc(slen); + /* No need to free the kop->crk_iparams parameter if it was allocated, + * callers of this routine have to free allocated parameters through + * zapparams both in case of success and failure + */ + if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL) + return ret; + memset(kop->crk_param[kop->crk_iparams + 1].crp_p, 0, (size_t)slen); kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; kop->crk_oparams++; } @@ -1100,7 +1113,7 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, ret = 0; } - return (ret); + return ret; } static int diff --git a/crypto/openssl/crypto/evp/bio_enc.c b/crypto/openssl/crypto/evp/bio_enc.c index 363e024..0806f23 100644 --- a/crypto/openssl/crypto/evp/bio_enc.c +++ b/crypto/openssl/crypto/evp/bio_enc.c @@ -201,9 +201,14 @@ static int enc_read(BIO *b, char *out, int outl) break; } } else { - EVP_CipherUpdate(&(ctx->cipher), - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)&(ctx->buf[BUF_OFFSET]), i); + if (!EVP_CipherUpdate(&ctx->cipher, + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)&(ctx->buf[BUF_OFFSET]), + i)) { + BIO_clear_retry_flags(b); + ctx->ok = 0; + return 0; + } ctx->cont = 1; /* * Note: it is possible for EVP_CipherUpdate to decrypt zero @@ -260,9 +265,13 @@ static int enc_write(BIO *b, const char *in, int inl) ctx->buf_off = 0; while (inl > 0) { n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl; - EVP_CipherUpdate(&(ctx->cipher), - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)in, n); + if (!EVP_CipherUpdate(&ctx->cipher, + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n)) { + BIO_clear_retry_flags(b); + ctx->ok = 0; + return 0; + } inl -= n; in += n; diff --git a/crypto/openssl/crypto/evp/bio_ok.c b/crypto/openssl/crypto/evp/bio_ok.c index 5c32e35..16e151f 100644 --- a/crypto/openssl/crypto/evp/bio_ok.c +++ b/crypto/openssl/crypto/evp/bio_ok.c @@ -491,7 +491,7 @@ static int sig_out(BIO *b) * FIXME: there's absolutely no guarantee this makes any sense at all, * particularly now EVP_MD_CTX has been restructured. */ - if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0) + if (RAND_bytes(md->md_data, md->digest->md_size) <= 0) goto berr; memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size); longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); diff --git a/crypto/openssl/crypto/evp/c_all.c b/crypto/openssl/crypto/evp/c_all.c index a3ed00d..719e34d 100644 --- a/crypto/openssl/crypto/evp/c_all.c +++ b/crypto/openssl/crypto/evp/c_all.c @@ -82,9 +82,4 @@ void OPENSSL_add_all_algorithms_noconf(void) OPENSSL_cpuid_setup(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); -#ifndef OPENSSL_NO_ENGINE -# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) - ENGINE_setup_bsd_cryptodev(); -# endif -#endif } diff --git a/crypto/openssl/crypto/evp/digest.c b/crypto/openssl/crypto/evp/digest.c index 5b642b2..4db1796 100644 --- a/crypto/openssl/crypto/evp/digest.c +++ b/crypto/openssl/crypto/evp/digest.c @@ -253,10 +253,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { #ifdef OPENSSL_FIPS - return FIPS_digestupdate(ctx, data, count); -#else - return ctx->update(ctx, data, count); + if (FIPS_mode()) + return FIPS_digestupdate(ctx, data, count); #endif + return ctx->update(ctx, data, count); } /* The caller can assume that this removes any secret data from the context */ @@ -271,10 +271,11 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) /* The caller can assume that this removes any secret data from the context */ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { -#ifdef OPENSSL_FIPS - return FIPS_digestfinal(ctx, md, size); -#else int ret; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_digestfinal(ctx, md, size); +#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret = ctx->digest->final(ctx, md); @@ -284,9 +285,8 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) ctx->digest->cleanup(ctx); EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); } - memset(ctx->md_data, 0, ctx->digest->ctx_size); + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); return ret; -#endif } int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) diff --git a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c index 2da1117..5e92855 100644 --- a/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c +++ b/crypto/openssl/crypto/evp/e_rc4_hmac_md5.c @@ -99,7 +99,7 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, return 1; } -# if !defined(OPENSSL_NO_ASM) && ( \ +# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) || \ defined(__INTEL__) ) && \ @@ -254,6 +254,8 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, MD5_Init(&key->tail); MD5_Update(&key->tail, hmac_key, sizeof(hmac_key)); + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + return 1; } case EVP_CTRL_AEAD_TLS1_AAD: diff --git a/crypto/openssl/crypto/evp/e_seed.c b/crypto/openssl/crypto/evp/e_seed.c index 7249d1b..3d01eac 100644 --- a/crypto/openssl/crypto/evp/e_seed.c +++ b/crypto/openssl/crypto/evp/e_seed.c @@ -70,7 +70,8 @@ typedef struct { } EVP_SEED_KEY; IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, - 16, 16, 16, 128, 0, seed_init_key, 0, 0, 0, 0) + 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1, + seed_init_key, 0, 0, 0, 0) static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff --git a/crypto/openssl/crypto/evp/evp_enc.c b/crypto/openssl/crypto/evp/evp_enc.c index 7d7be24..0e40f09 100644 --- a/crypto/openssl/crypto/evp/evp_enc.c +++ b/crypto/openssl/crypto/evp/evp_enc.c @@ -170,7 +170,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, #ifdef OPENSSL_FIPS if (FIPS_mode()) { - const EVP_CIPHER *fcipher; + const EVP_CIPHER *fcipher = NULL; if (cipher) fcipher = evp_get_fips_cipher(cipher); if (fcipher) diff --git a/crypto/openssl/crypto/evp/evp_test.c b/crypto/openssl/crypto/evp/evp_test.c index d7441ec..9879642 100644 --- a/crypto/openssl/crypto/evp/evp_test.c +++ b/crypto/openssl/crypto/evp/evp_test.c @@ -76,6 +76,7 @@ static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) static int convert(unsigned char *s) { unsigned char *d; + int digits = 0; for (d = s; *s; s += 2, ++d) { unsigned int n; @@ -86,8 +87,9 @@ static int convert(unsigned char *s) } sscanf((char *)s, "%2x", &n); *d = (unsigned char)n; + digits++; } - return s - d; + return digits; } static char *sstrsep(char **string, const char *delim) diff --git a/crypto/openssl/crypto/evp/openbsd_hw.c b/crypto/openssl/crypto/evp/openbsd_hw.c index 75d12e2..07decf2 100644 --- a/crypto/openssl/crypto/evp/openbsd_hw.c +++ b/crypto/openssl/crypto/evp/openbsd_hw.c @@ -133,6 +133,10 @@ static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher, return 0; CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY); + if (CDATA(ctx)->key == NULL { + err("CDATA(ctx)->key memory allocation failed"); + return 0; + } assert(ctx->cipher->iv_len <= MAX_HW_IV); @@ -186,6 +190,11 @@ static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (((unsigned long)in & 3) || cinl != inl) { cin = OPENSSL_malloc(cinl); + if (cin == NULL) { + err("cin - memory allocation failed"); + abort(); + return 0; + } memcpy(cin, in, inl); cryp.src = cin; } @@ -334,6 +343,11 @@ static int do_digest(int ses, unsigned char *md, const void *data, int len) char *dcopy; dcopy = OPENSSL_malloc(len); + if (dcopy == NULL) { + err("dcopy - memory allocation failed"); + abort(); + return 0; + } memcpy(dcopy, data, len); cryp.src = dcopy; cryp.dst = cryp.src; // FIXME!!! @@ -364,6 +378,10 @@ static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, return do_digest(md_data->sess.ses, md_data->md, data, len); md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); + if (md_data->data == NULL) { + err("DEV_CRYPTO_MD5_UPDATE: unable to allocate memory"); + abort(); + } memcpy(md_data->data + md_data->len, data, len); md_data->len += len; @@ -397,6 +415,10 @@ static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) assert(from->digest->flags & EVP_MD_FLAG_ONESHOT); to_md->data = OPENSSL_malloc(from_md->len); + if (to_md->data == NULL) { + err("DEV_CRYPTO_MD5_COPY: unable to allocate memory"); + abort(); + } memcpy(to_md->data, from_md->data, from_md->len); return 1; diff --git a/crypto/openssl/crypto/evp/p_lib.c b/crypto/openssl/crypto/evp/p_lib.c index c017124..545d04f 100644 --- a/crypto/openssl/crypto/evp/p_lib.c +++ b/crypto/openssl/crypto/evp/p_lib.c @@ -130,6 +130,14 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS); goto err; } + + if (!EVP_PKEY_missing_parameters(to)) { + if (EVP_PKEY_cmp_parameters(to, from) == 1) + return 1; + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS); + return 0; + } + if (from->ameth && from->ameth->param_copy) return from->ameth->param_copy(to, from); err: diff --git a/crypto/openssl/crypto/evp/pmeth_gn.c b/crypto/openssl/crypto/evp/pmeth_gn.c index 6435f1b..6a4d357 100644 --- a/crypto/openssl/crypto/evp/pmeth_gn.c +++ b/crypto/openssl/crypto/evp/pmeth_gn.c @@ -149,8 +149,10 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) if (!ppkey) return -1; - if (!*ppkey) + if (*ppkey == NULL) *ppkey = EVP_PKEY_new(); + if (*ppkey == NULL) + return -1; ret = ctx->pmeth->keygen(ctx, *ppkey); if (ret <= 0) { diff --git a/crypto/openssl/crypto/evp/pmeth_lib.c b/crypto/openssl/crypto/evp/pmeth_lib.c index 9f81d10..9668b3a 100644 --- a/crypto/openssl/crypto/evp/pmeth_lib.c +++ b/crypto/openssl/crypto/evp/pmeth_lib.c @@ -91,7 +91,9 @@ static const EVP_PKEY_METHOD *standard_methods[] = { &ec_pkey_meth, #endif &hmac_pkey_meth, +#ifndef OPENSSL_NO_CMAC &cmac_pkey_meth, +#endif #ifndef OPENSSL_NO_DH &dhx_pkey_meth #endif diff --git a/crypto/openssl/crypto/hmac/hmac.c b/crypto/openssl/crypto/hmac/hmac.c index 51a0a3e..213504e 100644 --- a/crypto/openssl/crypto/hmac/hmac.c +++ b/crypto/openssl/crypto/hmac/hmac.c @@ -234,7 +234,7 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx) EVP_MD_CTX_cleanup(&ctx->i_ctx); EVP_MD_CTX_cleanup(&ctx->o_ctx); EVP_MD_CTX_cleanup(&ctx->md_ctx); - memset(ctx, 0, sizeof *ctx); + OPENSSL_cleanse(ctx, sizeof *ctx); } unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, diff --git a/crypto/openssl/crypto/jpake/jpake.c b/crypto/openssl/crypto/jpake/jpake.c index ebc0975..2ba75f0 100644 --- a/crypto/openssl/crypto/jpake/jpake.c +++ b/crypto/openssl/crypto/jpake/jpake.c @@ -116,6 +116,8 @@ JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, const BIGNUM *secret) { JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + if (ctx == NULL) + return NULL; JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret); @@ -151,6 +153,8 @@ static void hashbn(SHA_CTX *sha, const BIGNUM *bn) size_t l = BN_num_bytes(bn); unsigned char *bin = OPENSSL_malloc(l); + if (bin == NULL) + return; hashlength(sha, l); BN_bn2bin(bn, bin); SHA1_Update(sha, bin, l); diff --git a/crypto/openssl/crypto/lhash/lhash.c b/crypto/openssl/crypto/lhash/lhash.c index 53c5c13..f20353a 100644 --- a/crypto/openssl/crypto/lhash/lhash.c +++ b/crypto/openssl/crypto/lhash/lhash.c @@ -335,8 +335,8 @@ static void expand(_LHASH *lh) n = (LHASH_NODE **)OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); if (n == NULL) { -/* fputs("realloc error in lhash",stderr); */ lh->error++; + lh->num_nodes--; lh->p = 0; return; } diff --git a/crypto/openssl/crypto/md2/md2_dgst.c b/crypto/openssl/crypto/md2/md2_dgst.c index 9cd79f8..7f5d9ba 100644 --- a/crypto/openssl/crypto/md2/md2_dgst.c +++ b/crypto/openssl/crypto/md2/md2_dgst.c @@ -219,6 +219,6 @@ int MD2_Final(unsigned char *md, MD2_CTX *c) for (i = 0; i < 16; i++) md[i] = (UCHAR) (p1[i] & 0xff); - memset((char *)&c, 0, sizeof(c)); + OPENSSL_cleanse(c, sizeof(*c)); return 1; } diff --git a/crypto/openssl/crypto/md32_common.h b/crypto/openssl/crypto/md32_common.h index 96828d2..b5a04bf 100644 --- a/crypto/openssl/crypto/md32_common.h +++ b/crypto/openssl/crypto/md32_common.h @@ -109,6 +109,8 @@ * <appro@fy.chalmers.se> */ +#include <openssl/crypto.h> + #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) # error "DATA_ORDER must be defined!" #endif @@ -329,6 +331,12 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) data += n; len -= n; c->num = 0; + /* + * We use memset rather than OPENSSL_cleanse() here deliberately. + * Using OPENSSL_cleanse() here could be a performance issue. It + * will get properly cleansed on finalisation so this isn't a + * security problem. + */ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ } else { memcpy(p + n, data, len); @@ -384,7 +392,7 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c) p -= HASH_CBLOCK; HASH_BLOCK_DATA_ORDER(c, p, 1); c->num = 0; - memset(p, 0, HASH_CBLOCK); + OPENSSL_cleanse(p, HASH_CBLOCK); #ifndef HASH_MAKE_STRING # error "HASH_MAKE_STRING must be defined!" diff --git a/crypto/openssl/crypto/mdc2/mdc2dgst.c b/crypto/openssl/crypto/mdc2/mdc2dgst.c index 6615cf8..2dce493 100644 --- a/crypto/openssl/crypto/mdc2/mdc2dgst.c +++ b/crypto/openssl/crypto/mdc2/mdc2dgst.c @@ -91,7 +91,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) i = c->num; if (i != 0) { - if (i + len < MDC2_BLOCK) { + if (len < MDC2_BLOCK - i) { /* partial block */ memcpy(&(c->data[i]), in, len); c->num += (int)len; diff --git a/crypto/openssl/crypto/mem.c b/crypto/openssl/crypto/mem.c index fdad49b..06c3960 100644 --- a/crypto/openssl/crypto/mem.c +++ b/crypto/openssl/crypto/mem.c @@ -82,6 +82,14 @@ static void *default_malloc_ex(size_t num, const char *file, int line) static void *(*malloc_ex_func) (size_t, const char *file, int line) = default_malloc_ex; +#ifdef OPENSSL_SYS_VMS +# if __INITIAL_POINTER_SIZE == 64 +# define realloc _realloc64 +# elif __INITIAL_POINTER_SIZE == 32 +# define realloc _realloc32 +# endif +#endif + static void *(*realloc_func) (void *, size_t) = realloc; static void *default_realloc_ex(void *str, size_t num, const char *file, int line) @@ -92,7 +100,11 @@ static void *default_realloc_ex(void *str, size_t num, static void *(*realloc_ex_func) (void *, size_t, const char *file, int line) = default_realloc_ex; -static void (*free_func) (void *) = free; +#ifdef OPENSSL_SYS_VMS + static void (*free_func) (__void_ptr64) = free; +#else + static void (*free_func) (void *) = free; +#endif static void *(*malloc_locked_func) (size_t) = malloc; static void *default_malloc_locked_ex(size_t num, const char *file, int line) @@ -103,7 +115,11 @@ static void *default_malloc_locked_ex(size_t num, const char *file, int line) static void *(*malloc_locked_ex_func) (size_t, const char *file, int line) = default_malloc_locked_ex; -static void (*free_locked_func) (void *) = free; +#ifdef OPENSSL_SYS_VMS + static void (*free_locked_func) (__void_ptr64) = free; +#else + static void (*free_locked_func) (void *) = free; +#endif /* may be changed as long as 'allow_customize_debug' is set */ /* XXX use correct function pointer types */ @@ -298,18 +314,6 @@ void *CRYPTO_malloc_locked(int num, const char *file, int line) if (malloc_debug_func != NULL) malloc_debug_func(ret, num, file, line, 1); -#ifndef OPENSSL_CPUID_OBJ - /* - * Create a dependency on the value of 'cleanse_ctr' so our memory - * sanitisation function can't be optimised out. NB: We only do this for - * >2Kb so the overhead doesn't bother us. - */ - if (ret && (num > 2048)) { - extern unsigned char cleanse_ctr; - ((unsigned char *)ret)[0] = cleanse_ctr; - } -#endif - return ret; } @@ -346,18 +350,6 @@ void *CRYPTO_malloc(int num, const char *file, int line) if (malloc_debug_func != NULL) malloc_debug_func(ret, num, file, line, 1); -#ifndef OPENSSL_CPUID_OBJ - /* - * Create a dependency on the value of 'cleanse_ctr' so our memory - * sanitisation function can't be optimised out. NB: We only do this for - * >2Kb so the overhead doesn't bother us. - */ - if (ret && (num > 2048)) { - extern unsigned char cleanse_ctr; - ((unsigned char *)ret)[0] = cleanse_ctr; - } -#endif - return ret; } diff --git a/crypto/openssl/crypto/mem_clr.c b/crypto/openssl/crypto/mem_clr.c index ab85344..579e9d1 100644 --- a/crypto/openssl/crypto/mem_clr.c +++ b/crypto/openssl/crypto/mem_clr.c @@ -60,22 +60,16 @@ #include <string.h> #include <openssl/crypto.h> -unsigned char cleanse_ctr = 0; +/* + * Pointer to memset is volatile so that compiler must de-reference + * the pointer and can't assume that it points to any function in + * particular (such as memset, which it then might further "optimize") + */ +typedef void *(*memset_t)(void *,int,size_t); + +static volatile memset_t memset_func = memset; void OPENSSL_cleanse(void *ptr, size_t len) { - unsigned char *p = ptr; - size_t loop = len, ctr = cleanse_ctr; - - if (ptr == NULL) - return; - - while (loop--) { - *(p++) = (unsigned char)ctr; - ctr += (17 + ((size_t)p & 0xF)); - } - p = memchr(ptr, (unsigned char)ctr, len); - if (p) - ctr += (63 + (size_t)p); - cleanse_ctr = (unsigned char)ctr; + memset_func(ptr, 0, len); } diff --git a/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl b/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl index 5bc2870..b129ba7 100755 --- a/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl +++ b/crypto/openssl/crypto/modes/asm/ghash-sparcv9.pl @@ -445,6 +445,8 @@ gcm_gmult_vis3: .align 32 gcm_ghash_vis3: save %sp,-$frame,%sp + nop + srln $len,0,$len ! needed on v8+, "nop" on v9 ldx [$Xip+8],$C2 ! load Xi ldx [$Xip+0],$C3 diff --git a/crypto/openssl/crypto/o_init.c b/crypto/openssl/crypto/o_init.c index 2088388..185841e 100644 --- a/crypto/openssl/crypto/o_init.c +++ b/crypto/openssl/crypto/o_init.c @@ -73,6 +73,9 @@ void OPENSSL_init(void) done = 1; #ifdef OPENSSL_FIPS FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); +# ifndef OPENSSL_NO_DEPRECATED + FIPS_crypto_set_id_callback(CRYPTO_thread_id); +# endif FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); RAND_init_fips(); diff --git a/crypto/openssl/crypto/o_time.c b/crypto/openssl/crypto/o_time.c index 635dae1..b99e599 100644 --- a/crypto/openssl/crypto/o_time.c +++ b/crypto/openssl/crypto/o_time.c @@ -78,7 +78,28 @@ # include <descrip.h> # include <stdlib.h> # endif /* ndef VMS_GMTIME_OK */ -#endif + + +/* + * Needed to pick up the correct definitions and declarations in some of the + * DEC C Header Files (*.H). + */ +# define __NEW_STARLET 1 + +# if (defined(__alpha) || defined(__ia64)) +# include <iledef.h> +# else + +/* VAX */ +typedef struct _ile3 { /* Copied from ILEDEF.H for Alpha */ +# pragma __nomember_alignment + unsigned short int ile3$w_length; /* Length of buffer in bytes */ + unsigned short int ile3$w_code; /* Item code value */ + void *ile3$ps_bufaddr; /* Buffer address */ + unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */ +} ILE3; +# endif /* alpha || ia64 */ +#endif /* OPENSSL_SYS_VMS */ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) { @@ -105,26 +126,42 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL"); char logvalue[256]; unsigned int reslen = 0; - struct { - short buflen; - short code; - void *bufaddr; - unsigned int *reslen; - } itemlist[] = { - { - 0, LNM$_STRING, 0, 0 - }, - { - 0, 0, 0, 0 - }, - }; +# if __INITIAL_POINTER_SIZE == 64 + ILEB_64 itemlist[2], *pitem; +# else + ILE3 itemlist[2], *pitem; +# endif int status; time_t t; + + /* + * Setup an itemlist for the call to $TRNLNM - Translate Logical Name. + */ + pitem = itemlist; + +# if __INITIAL_POINTER_SIZE == 64 + pitem->ileb_64$w_mbo = 1; + pitem->ileb_64$w_code = LNM$_STRING; + pitem->ileb_64$l_mbmo = -1; + pitem->ileb_64$q_length = sizeof (logvalue); + pitem->ileb_64$pq_bufaddr = logvalue; + pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen; + pitem++; + /* Last item of the item list is null terminated */ + pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0; +# else + pitem->ile3$w_length = sizeof (logvalue); + pitem->ile3$w_code = LNM$_STRING; + pitem->ile3$ps_bufaddr = logvalue; + pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen; + pitem++; + /* Last item of the item list is null terminated */ + pitem->ile3$w_length = pitem->ile3$w_code = 0; +# endif + + /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ - itemlist[0].buflen = sizeof(logvalue); - itemlist[0].bufaddr = logvalue; - itemlist[0].reslen = &reslen; status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); if (!(status & 1)) return NULL; @@ -132,7 +169,7 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) t = *timer; -/* The following is extracted from the DEC C header time.h */ + /* The following is extracted from the DEC C header time.h */ /* ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime ** have two implementations. One implementation is provided diff --git a/crypto/openssl/crypto/objects/o_names.c b/crypto/openssl/crypto/objects/o_names.c index 2485992..f106905 100644 --- a/crypto/openssl/crypto/objects/o_names.c +++ b/crypto/openssl/crypto/objects/o_names.c @@ -191,7 +191,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data) onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME)); if (onp == NULL) { /* ERROR */ - return (0); + return 0; } onp->name = name; @@ -216,10 +216,11 @@ int OBJ_NAME_add(const char *name, int type, const char *data) } else { if (lh_OBJ_NAME_error(names_lh)) { /* ERROR */ - return (0); + OPENSSL_free(onp); + return 0; } } - return (1); + return 1; } int OBJ_NAME_remove(const char *name, int type) diff --git a/crypto/openssl/crypto/ocsp/ocsp_cl.c b/crypto/openssl/crypto/ocsp/ocsp_cl.c index b3612c8..fca7db0 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_cl.c +++ b/crypto/openssl/crypto/ocsp/ocsp_cl.c @@ -93,8 +93,10 @@ OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) if (one->reqCert) OCSP_CERTID_free(one->reqCert); one->reqCert = cid; - if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) + if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) { + one->reqCert = NULL; /* do not free on error */ goto err; + } return one; err: OCSP_ONEREQ_free(one); diff --git a/crypto/openssl/crypto/ocsp/ocsp_ext.c b/crypto/openssl/crypto/ocsp/ocsp_ext.c index c19648c..55af31b 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_ext.c +++ b/crypto/openssl/crypto/ocsp/ocsp_ext.c @@ -361,7 +361,7 @@ static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); if (val) memcpy(tmpval, val, len); - else if (RAND_pseudo_bytes(tmpval, len) < 0) + else if (RAND_bytes(tmpval, len) <= 0) goto err; if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, &os, 0, X509V3_ADD_REPLACE)) diff --git a/crypto/openssl/crypto/ocsp/ocsp_lib.c b/crypto/openssl/crypto/ocsp/ocsp_lib.c index cabf539..ff781e5 100644 --- a/crypto/openssl/crypto/ocsp/ocsp_lib.c +++ b/crypto/openssl/crypto/ocsp/ocsp_lib.c @@ -271,12 +271,18 @@ int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, err: if (buf) OPENSSL_free(buf); - if (*ppath) + if (*ppath) { OPENSSL_free(*ppath); - if (*pport) + *ppath = NULL; + } + if (*pport) { OPENSSL_free(*pport); - if (*phost) + *pport = NULL; + } + if (*phost) { OPENSSL_free(*phost); + *phost = NULL; + } return 0; } diff --git a/crypto/openssl/crypto/opensslv.h b/crypto/openssl/crypto/opensslv.h index 1a67712..fdc3116 100644 --- a/crypto/openssl/crypto/opensslv.h +++ b/crypto/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x1000208fL +# define OPENSSL_VERSION_NUMBER 0x1000209fL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h-fips 3 May 2016" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2i-fips 22 Sep 2016" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h-freebsd 3 May 2016" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2i-freebsd 22 Sep 2016" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/crypto/openssl/crypto/ossl_typ.h b/crypto/openssl/crypto/ossl_typ.h index 9144ea2..364d262 100644 --- a/crypto/openssl/crypto/ossl_typ.h +++ b/crypto/openssl/crypto/ossl_typ.h @@ -178,6 +178,8 @@ typedef struct engine_st ENGINE; typedef struct ssl_st SSL; typedef struct ssl_ctx_st SSL_CTX; +typedef struct comp_method_st COMP_METHOD; + typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; diff --git a/crypto/openssl/crypto/pem/pem.h b/crypto/openssl/crypto/pem/pem.h index d3b23fc..aac72fb 100644 --- a/crypto/openssl/crypto/pem/pem.h +++ b/crypto/openssl/crypto/pem/pem.h @@ -531,6 +531,7 @@ int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, * The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ + void ERR_load_PEM_strings(void); /* Error codes for the PEM functions. */ @@ -592,6 +593,7 @@ void ERR_load_PEM_strings(void); # define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 # define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 # define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_HEADER_TOO_LONG 128 # define PEM_R_INCONSISTENT_HEADER 121 # define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 # define PEM_R_KEYBLOB_TOO_SHORT 123 @@ -609,7 +611,7 @@ void ERR_load_PEM_strings(void); # define PEM_R_UNSUPPORTED_ENCRYPTION 114 # define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif #endif diff --git a/crypto/openssl/crypto/pem/pem_err.c b/crypto/openssl/crypto/pem/pem_err.c index e1f4fdb..4e5f8e9 100644 --- a/crypto/openssl/crypto/pem/pem_err.c +++ b/crypto/openssl/crypto/pem/pem_err.c @@ -1,6 +1,6 @@ /* crypto/pem/pem_err.c */ /* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -132,6 +132,7 @@ static ERR_STRING_DATA PEM_str_reasons[] = { "expecting private key blob"}, {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), "expecting public key blob"}, + {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"}, {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"}, {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), "keyblob header parse error"}, diff --git a/crypto/openssl/crypto/pem/pem_lib.c b/crypto/openssl/crypto/pem/pem_lib.c index fe881d6..c82b3c0 100644 --- a/crypto/openssl/crypto/pem/pem_lib.c +++ b/crypto/openssl/crypto/pem/pem_lib.c @@ -105,17 +105,23 @@ int PEM_def_callback(char *buf, int num, int w, void *key) prompt = "Enter PEM pass phrase:"; for (;;) { - i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w); + /* + * We assume that w == 0 means decryption, + * while w == 1 means encryption + */ + int min_len = w ? MIN_LENGTH : 0; + + i = EVP_read_pw_string_min(buf, min_len, num, prompt, w); if (i != 0) { PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD); memset(buf, 0, (unsigned int)num); return (-1); } j = strlen(buf); - if (j < MIN_LENGTH) { + if (min_len && j < min_len) { fprintf(stderr, "phrase is too short, needs to be at least %d chars\n", - MIN_LENGTH); + min_len); } else break; } @@ -387,7 +393,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, } RAND_add(data, i, 0); /* put in the RSA key. */ OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); - if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) /* Generate a salt */ + if (RAND_bytes(iv, enc->iv_len) <= 0) /* Generate a salt */ goto err; /* * The 'iv' is used as the iv and as a salt. It is NOT taken from diff --git a/crypto/openssl/crypto/pem/pvkfmt.c b/crypto/openssl/crypto/pem/pvkfmt.c index 61864468..1ce5a1e 100644 --- a/crypto/openssl/crypto/pem/pvkfmt.c +++ b/crypto/openssl/crypto/pem/pvkfmt.c @@ -127,6 +127,9 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) # define MS_KEYTYPE_KEYX 0x1 # define MS_KEYTYPE_SIGN 0x2 +/* Maximum length of a blob after header */ +# define BLOB_MAX_LENGTH 102400 + /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ # define MS_PVKMAGIC 0xb0b5f11eL /* Salt length for PVK files */ @@ -272,6 +275,10 @@ static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) return NULL; length = blob_length(bitlen, isdss, ispub); + if (length > BLOB_MAX_LENGTH) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); + return NULL; + } buf = OPENSSL_malloc(length); if (!buf) { PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); diff --git a/crypto/openssl/crypto/perlasm/sparcv9_modes.pl b/crypto/openssl/crypto/perlasm/sparcv9_modes.pl index eb267a5..ac8da32 100755 --- a/crypto/openssl/crypto/perlasm/sparcv9_modes.pl +++ b/crypto/openssl/crypto/perlasm/sparcv9_modes.pl @@ -37,6 +37,7 @@ ${alg}${bits}_t4_cbc_encrypt: save %sp, -$::frame, %sp cmp $len, 0 be,pn $::size_t_cc, .L${bits}_cbc_enc_abort + srln $len, 0, $len ! needed on v8+, "nop" on v9 sub $inp, $out, $blk_init ! $inp!=$out ___ $::code.=<<___ if (!$::evp); @@ -254,6 +255,7 @@ ${alg}${bits}_t4_cbc_decrypt: save %sp, -$::frame, %sp cmp $len, 0 be,pn $::size_t_cc, .L${bits}_cbc_dec_abort + srln $len, 0, $len ! needed on v8+, "nop" on v9 sub $inp, $out, $blk_init ! $inp!=$out ___ $::code.=<<___ if (!$::evp); @@ -613,6 +615,7 @@ $::code.=<<___; .align 32 ${alg}${bits}_t4_ctr32_encrypt: save %sp, -$::frame, %sp + srln $len, 0, $len ! needed on v8+, "nop" on v9 prefetch [$inp], 20 prefetch [$inp + 63], 20 @@ -916,6 +919,7 @@ $::code.=<<___; .align 32 ${alg}${bits}_t4_xts_${dir}crypt: save %sp, -$::frame-16, %sp + srln $len, 0, $len ! needed on v8+, "nop" on v9 mov $ivec, %o0 add %fp, $::bias-16, %o1 diff --git a/crypto/openssl/crypto/pkcs12/p12_mutl.c b/crypto/openssl/crypto/pkcs12/p12_mutl.c index a927782..cbf34da 100644 --- a/crypto/openssl/crypto/pkcs12/p12_mutl.c +++ b/crypto/openssl/crypto/pkcs12/p12_mutl.c @@ -179,7 +179,7 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, } p12->mac->salt->length = saltlen; if (!salt) { - if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0) + if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0) return 0; } else memcpy(p12->mac->salt->data, salt, saltlen); diff --git a/crypto/openssl/crypto/pkcs12/p12_npas.c b/crypto/openssl/crypto/pkcs12/p12_npas.c index a89b61a..9e8ebb2 100644 --- a/crypto/openssl/crypto/pkcs12/p12_npas.c +++ b/crypto/openssl/crypto/pkcs12/p12_npas.c @@ -66,17 +66,18 @@ /* PKCS#12 password change routine */ -static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass); -static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, - char *newpass); -static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass); +static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass); +static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, + const char *newpass); static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); /* * Change the password on a PKCS#12 structure. */ -int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) { /* Check for NULL PKCS12 structure */ @@ -103,20 +104,21 @@ int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) /* Parse the outer PKCS#12 structure */ -static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) +static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) { - STACK_OF(PKCS7) *asafes, *newsafes; - STACK_OF(PKCS12_SAFEBAG) *bags; + STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; PKCS7 *p7, *p7new; - ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; + ASN1_OCTET_STRING *p12_data_tmp = NULL; unsigned char mac[EVP_MAX_MD_SIZE]; unsigned int maclen; + int rv = 0; - if (!(asafes = PKCS12_unpack_authsafes(p12))) - return 0; - if (!(newsafes = sk_PKCS7_new_null())) - return 0; + if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) + goto err; + if ((newsafes = sk_PKCS7_new_null()) == NULL) + goto err; for (i = 0; i < sk_PKCS7_num(asafes); i++) { p7 = sk_PKCS7_value(asafes, i); bagnid = OBJ_obj2nid(p7->type); @@ -125,67 +127,57 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) } else if (bagnid == NID_pkcs7_encrypted) { bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); if (!alg_get(p7->d.encrypted->enc_data->algorithm, - &pbe_nid, &pbe_iter, &pbe_saltlen)) { - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - } - } else + &pbe_nid, &pbe_iter, &pbe_saltlen)) + goto err; + } else { continue; - if (!bags) { - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 0; - } - if (!newpass_bags(bags, oldpass, newpass)) { - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 0; } + if (bags == NULL) + goto err; + if (!newpass_bags(bags, oldpass, newpass)) + goto err; /* Repack bag in same form with new password */ if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags); else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, pbe_saltlen, pbe_iter, bags); + if (!p7new || !sk_PKCS7_push(newsafes, p7new)) + goto err; sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - if (!p7new) { - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 0; - } - sk_PKCS7_push(newsafes, p7new); + bags = NULL; } - sk_PKCS7_pop_free(asafes, PKCS7_free); /* Repack safe: save old safe in case of error */ p12_data_tmp = p12->authsafes->d.data; - if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) - goto saferr; + if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) + goto err; if (!PKCS12_pack_authsafes(p12, newsafes)) - goto saferr; - + goto err; if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) - goto saferr; - if (!(macnew = ASN1_OCTET_STRING_new())) - goto saferr; - if (!ASN1_OCTET_STRING_set(macnew, mac, maclen)) - goto saferr; - ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); - p12->mac->dinfo->digest = macnew; - ASN1_OCTET_STRING_free(p12_data_tmp); - - return 1; - - saferr: - /* Restore old safe */ - ASN1_OCTET_STRING_free(p12->authsafes->d.data); - ASN1_OCTET_STRING_free(macnew); - p12->authsafes->d.data = p12_data_tmp; - return 0; - + goto err; + if (!ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen)) + goto err; + + rv = 1; + +err: + /* Restore old safe if necessary */ + if (rv == 1) { + ASN1_OCTET_STRING_free(p12_data_tmp); + } else if (p12_data_tmp != NULL) { + ASN1_OCTET_STRING_free(p12->authsafes->d.data); + p12->authsafes->d.data = p12_data_tmp; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + sk_PKCS7_pop_free(newsafes, PKCS7_free); + return rv; } -static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, - char *newpass) +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { @@ -197,7 +189,8 @@ static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, /* Change password of safebag: only needs handle shrouded keybags */ -static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) +static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, + const char *newpass) { PKCS8_PRIV_KEY_INFO *p8; X509_SIG *p8new; @@ -210,8 +203,10 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) return 0; if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen)) return 0; - if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, - p8_iter, p8))) + p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, + p8_iter, p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (p8new == NULL) return 0; X509_SIG_free(bag->value.shkeybag); bag->value.shkeybag = p8new; diff --git a/crypto/openssl/crypto/pkcs12/p12_utl.c b/crypto/openssl/crypto/pkcs12/p12_utl.c index a0b992e..e466f76 100644 --- a/crypto/openssl/crypto/pkcs12/p12_utl.c +++ b/crypto/openssl/crypto/pkcs12/p12_utl.c @@ -91,6 +91,10 @@ char *OPENSSL_uni2asc(unsigned char *uni, int unilen) { int asclen, i; char *asctmp; + + /* string must contain an even number of bytes */ + if (unilen & 1) + return NULL; asclen = unilen / 2; /* If no terminating zero allow for one */ if (!unilen || uni[unilen - 1]) diff --git a/crypto/openssl/crypto/pkcs12/pkcs12.h b/crypto/openssl/crypto/pkcs12/pkcs12.h index a39adf5..21f1f62 100644 --- a/crypto/openssl/crypto/pkcs12/pkcs12.h +++ b/crypto/openssl/crypto/pkcs12/pkcs12.h @@ -270,7 +270,7 @@ int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); -int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass); +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); /* BEGIN ERROR CODES */ /* diff --git a/crypto/openssl/crypto/pkcs7/pk7_doit.c b/crypto/openssl/crypto/pkcs7/pk7_doit.c index 946aaa6..6cf8253 100644 --- a/crypto/openssl/crypto/pkcs7/pk7_doit.c +++ b/crypto/openssl/crypto/pkcs7/pk7_doit.c @@ -340,7 +340,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) - if (RAND_pseudo_bytes(iv, ivlen) <= 0) + if (RAND_bytes(iv, ivlen) <= 0) goto err; if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) goto err; @@ -642,6 +642,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } else { # if 0 bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; /* * We need to set this so that when we have read all the data, the * encrypt BIO, if present, will read EOF and encode the last few diff --git a/crypto/openssl/crypto/rand/md_rand.c b/crypto/openssl/crypto/rand/md_rand.c index 5c13d57..bd76e23 100644 --- a/crypto/openssl/crypto/rand/md_rand.c +++ b/crypto/openssl/crypto/rand/md_rand.c @@ -136,7 +136,7 @@ /* #define PREDICT 1 */ #define STATE_SIZE 1023 -static int state_num = 0, state_index = 0; +static size_t state_num = 0, state_index = 0; static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH]; static unsigned char md[MD_DIGEST_LENGTH]; static long md_count[2] = { 0, 0 }; @@ -336,8 +336,8 @@ static void ssleay_rand_seed(const void *buf, int num) int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) { static volatile int stirred_pool = 0; - int i, j, k, st_num, st_idx; - int num_ceil; + int i, j, k; + size_t num_ceil, st_idx, st_num; int ok; long md_c[2]; unsigned char local_md[MD_DIGEST_LENGTH]; diff --git a/crypto/openssl/crypto/rand/rand_unix.c b/crypto/openssl/crypto/rand/rand_unix.c index bc3f809..f51b52f 100644 --- a/crypto/openssl/crypto/rand/rand_unix.c +++ b/crypto/openssl/crypto/rand/rand_unix.c @@ -235,7 +235,7 @@ int RAND_poll(void) rnd >>= 8; } RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); - memset(buf, 0, sizeof(buf)); + OPENSSL_cleanse(buf, sizeof(buf)); return 1; } diff --git a/crypto/openssl/crypto/rand/randfile.c b/crypto/openssl/crypto/rand/randfile.c index 9537c56..728fd0a 100644 --- a/crypto/openssl/crypto/rand/randfile.c +++ b/crypto/openssl/crypto/rand/randfile.c @@ -56,11 +56,6 @@ * [including the GNU Public Licence.] */ -/* We need to define this to get macros like S_IFBLK and S_IFCHR */ -#if !defined(OPENSSL_SYS_VXWORKS) -# define _XOPEN_SOURCE 500 -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -80,6 +75,29 @@ #ifndef OPENSSL_NO_POSIX_IO # include <sys/stat.h> # include <fcntl.h> +/* + * Following should not be needed, and we could have been stricter + * and demand S_IS*. But some systems just don't comply... Formally + * below macros are "anatomically incorrect", because normally they + * would look like ((m) & MASK == TYPE), but since MASK availability + * is as questionable, we settle for this poor-man fallback... + */ +# if !defined(S_ISBLK) +# if defined(_S_IFBLK) +# define S_ISBLK(m) ((m) & _S_IFBLK) +# elif defined(S_IFBLK) +# define S_ISBLK(m) ((m) & S_IFBLK) +# elif defined(_WIN32) +# define S_ISBLK(m) 0 /* no concept of block devices on Windows */ +# endif +# endif +# if !defined(S_ISCHR) +# if defined(_S_IFCHR) +# define S_ISCHR(m) ((m) & _S_IFCHR) +# elif defined(S_IFCHR) +# define S_ISCHR(m) ((m) & S_IFCHR) +# endif +# endif #endif #ifdef _WIN32 @@ -93,7 +111,7 @@ #define BUFSIZE 1024 #define RAND_DATA 1024 -#ifdef OPENSSL_SYS_VMS +#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) /* * This declaration is a nasty hack to get around vms' extension to fopen for * passing in sharing options being disabled by our /STANDARD=ANSI89 @@ -122,7 +140,24 @@ int RAND_load_file(const char *file, long bytes) struct stat sb; #endif int i, ret = 0, n; +/* + * If setvbuf() is to be called, then the FILE pointer + * to it must be 32 bit. +*/ + +#if !defined OPENSSL_NO_SETVBUF_IONBF && defined(OPENSSL_SYS_VMS) && defined(__VMS_VER) && (__VMS_VER >= 70000000) + /* For 64-bit-->32 bit API Support*/ +#if __INITIAL_POINTER_SIZE == 64 +#pragma __required_pointer_size __save +#pragma __required_pointer_size 32 +#endif + FILE *in; /* setvbuf() requires 32-bit pointers */ +#if __INITIAL_POINTER_SIZE == 64 +#pragma __required_pointer_size __restore +#endif +#else FILE *in; +#endif /* OPENSSL_SYS_VMS */ if (file == NULL) return (0); @@ -151,8 +186,8 @@ int RAND_load_file(const char *file, long bytes) #endif if (in == NULL) goto err; -#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO) - if (sb.st_mode & (S_IFBLK | S_IFCHR)) { +#if defined(S_ISBLK) && defined(S_ISCHR) && !defined(OPENSSL_NO_POSIX_IO) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { /* * this file is a device. we don't want read an infinite number of * bytes from a random device, nor do we want to use buffered I/O @@ -231,7 +266,7 @@ int RAND_write_file(const char *file) } #endif -#ifdef OPENSSL_SYS_VMS +#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) /* * VMS NOTE: Prior versions of this routine created a _new_ version of * the rand file for each call into this routine, then deleted all diff --git a/crypto/openssl/crypto/rsa/rsa_ameth.c b/crypto/openssl/crypto/rsa/rsa_ameth.c index 4e06218..951e1d5 100644 --- a/crypto/openssl/crypto/rsa/rsa_ameth.c +++ b/crypto/openssl/crypto/rsa/rsa_ameth.c @@ -68,10 +68,12 @@ #endif #include "asn1_locl.h" +#ifndef OPENSSL_NO_CMS static int rsa_cms_sign(CMS_SignerInfo *si); static int rsa_cms_verify(CMS_SignerInfo *si); static int rsa_cms_decrypt(CMS_RecipientInfo *ri); static int rsa_cms_encrypt(CMS_RecipientInfo *ri); +#endif static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { @@ -665,6 +667,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, return rv; } +#ifndef OPENSSL_NO_CMS static int rsa_cms_verify(CMS_SignerInfo *si) { int nid, nid2; @@ -683,6 +686,7 @@ static int rsa_cms_verify(CMS_SignerInfo *si) } return 0; } +#endif /* * Customised RSA item verification routine. This is called when a signature @@ -705,6 +709,7 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return -1; } +#ifndef OPENSSL_NO_CMS static int rsa_cms_sign(CMS_SignerInfo *si) { int pad_mode = RSA_PKCS1_PADDING; @@ -729,6 +734,7 @@ static int rsa_cms_sign(CMS_SignerInfo *si) X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); return 1; } +#endif static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, @@ -785,6 +791,7 @@ static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, return pss; } +#ifndef OPENSSL_NO_CMS static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; @@ -920,6 +927,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) ASN1_STRING_free(os); return rv; } +#endif const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { { diff --git a/crypto/openssl/crypto/rsa/rsa_chk.c b/crypto/openssl/crypto/rsa/rsa_chk.c index 607faa0..475dfc5 100644 --- a/crypto/openssl/crypto/rsa/rsa_chk.c +++ b/crypto/openssl/crypto/rsa/rsa_chk.c @@ -56,7 +56,6 @@ int RSA_check_key(const RSA *key) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; - int r; int ret = 1; if (!key->p || !key->q || !key->n || !key->e || !key->d) { @@ -70,75 +69,68 @@ int RSA_check_key(const RSA *key) l = BN_new(); m = BN_new(); ctx = BN_CTX_new(); - if (i == NULL || j == NULL || k == NULL || l == NULL || - m == NULL || ctx == NULL) { + if (i == NULL || j == NULL || k == NULL || l == NULL + || m == NULL || ctx == NULL) { ret = -1; RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); goto err; } + if (BN_is_one(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); + } + if (!BN_is_odd(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); + } + /* p prime? */ - r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL); - if (r != 1) { - ret = r; - if (r != 0) - goto err; + if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL) != 1) { + ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); } /* q prime? */ - r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL); - if (r != 1) { - ret = r; - if (r != 0) - goto err; + if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL) != 1) { + ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); } /* n = p*q? */ - r = BN_mul(i, key->p, key->q, ctx); - if (!r) { + if (!BN_mul(i, key->p, key->q, ctx)) { ret = -1; goto err; } - if (BN_cmp(i, key->n) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod lcm(p-1,q-1)? */ - - r = BN_sub(i, key->p, BN_value_one()); - if (!r) { + if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } - r = BN_sub(j, key->q, BN_value_one()); - if (!r) { + if (!BN_sub(j, key->q, BN_value_one())) { ret = -1; goto err; } /* now compute k = lcm(i,j) */ - r = BN_mul(l, i, j, ctx); - if (!r) { + if (!BN_mul(l, i, j, ctx)) { ret = -1; goto err; } - r = BN_gcd(m, i, j, ctx); - if (!r) { + if (!BN_gcd(m, i, j, ctx)) { ret = -1; goto err; } - r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */ - if (!r) { + if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ ret = -1; goto err; } - - r = BN_mod_mul(i, key->d, key->e, k, ctx); - if (!r) { + if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { ret = -1; goto err; } @@ -150,36 +142,28 @@ int RSA_check_key(const RSA *key) if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { /* dmp1 = d mod (p-1)? */ - r = BN_sub(i, key->p, BN_value_one()); - if (!r) { + if (!BN_sub(i, key->p, BN_value_one())) { ret = -1; goto err; } - - r = BN_mod(j, key->d, i, ctx); - if (!r) { + if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } - if (BN_cmp(j, key->dmp1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ - r = BN_sub(i, key->q, BN_value_one()); - if (!r) { + if (!BN_sub(i, key->q, BN_value_one())) { ret = -1; goto err; } - - r = BN_mod(j, key->d, i, ctx); - if (!r) { + if (!BN_mod(j, key->d, i, ctx)) { ret = -1; goto err; } - if (BN_cmp(j, key->dmq1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); @@ -190,7 +174,6 @@ int RSA_check_key(const RSA *key) ret = -1; goto err; } - if (BN_cmp(i, key->iqmp) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); @@ -198,17 +181,11 @@ int RSA_check_key(const RSA *key) } err: - if (i != NULL) - BN_free(i); - if (j != NULL) - BN_free(j); - if (k != NULL) - BN_free(k); - if (l != NULL) - BN_free(l); - if (m != NULL) - BN_free(m); - if (ctx != NULL) - BN_CTX_free(ctx); - return (ret); + BN_free(i); + BN_free(j); + BN_free(k); + BN_free(l); + BN_free(m); + BN_CTX_free(ctx); + return ret; } diff --git a/crypto/openssl/crypto/rsa/rsa_lib.c b/crypto/openssl/crypto/rsa/rsa_lib.c index a6805de..6ea6b40 100644 --- a/crypto/openssl/crypto/rsa/rsa_lib.c +++ b/crypto/openssl/crypto/rsa/rsa_lib.c @@ -143,6 +143,7 @@ RSA *RSA_new_method(ENGINE *engine) RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); return NULL; } + memset(ret,0,sizeof(RSA)); ret->meth = RSA_get_default_method(); #ifndef OPENSSL_NO_ENGINE diff --git a/crypto/openssl/crypto/rsa/rsa_pmeth.c b/crypto/openssl/crypto/rsa/rsa_pmeth.c index 2036355..94db87a 100644 --- a/crypto/openssl/crypto/rsa/rsa_pmeth.c +++ b/crypto/openssl/crypto/rsa/rsa_pmeth.c @@ -545,8 +545,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: - if (!p2) + if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); return -2; + } BN_free(rctx->pub_exp); rctx->pub_exp = p2; return 1; diff --git a/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl b/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl index 5f375fc..752138b 100755 --- a/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/openssl/crypto/sha/asm/sha1-x86_64.pl @@ -372,9 +372,9 @@ $code.=<<___; .align 16 .Loop_shaext: dec $num - lea 0x40($inp),%rax # next input block + lea 0x40($inp),%r8 # next input block paddd @MSG[0],$E - cmovne %rax,$inp + cmovne %r8,$inp movdqa $ABCD,$ABCD_SAVE # offload $ABCD ___ for($i=0;$i<20-4;$i+=2) { diff --git a/crypto/openssl/crypto/sparccpuid.S b/crypto/openssl/crypto/sparccpuid.S index 7b12ec2..51ba441 100644 --- a/crypto/openssl/crypto/sparccpuid.S +++ b/crypto/openssl/crypto/sparccpuid.S @@ -429,6 +429,7 @@ OPENSSL_cleanse: .size OPENSSL_cleanse,.-OPENSSL_cleanse .global _sparcv9_vis1_instrument_bus +.weak _sparcv9_vis1_instrument_bus .align 8 _sparcv9_vis1_instrument_bus: mov %o1,%o3 ! save cnt @@ -467,6 +468,7 @@ _sparcv9_vis1_instrument_bus: .size _sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus .global _sparcv9_vis1_instrument_bus2 +.weak _sparcv9_vis1_instrument_bus2 .align 8 _sparcv9_vis1_instrument_bus2: mov %o1,%o3 ! save cnt diff --git a/crypto/openssl/crypto/srp/srp_lib.c b/crypto/openssl/crypto/srp/srp_lib.c index e9a2e05..6df3b1c 100644 --- a/crypto/openssl/crypto/srp/srp_lib.c +++ b/crypto/openssl/crypto/srp/srp_lib.c @@ -159,8 +159,7 @@ BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) return NULL; - if ((bn_ctx = BN_CTX_new()) == NULL || - (tmp = BN_new()) == NULL || (S = BN_new()) == NULL) + if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL) goto err; /* S = (A*v**u) ** b */ @@ -169,8 +168,12 @@ BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, goto err; if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx)) goto err; - if (!BN_mod_exp(S, tmp, b, N, bn_ctx)) - goto err; + + S = BN_new(); + if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) { + BN_free(S); + S = NULL; + } err: BN_CTX_free(bn_ctx); BN_clear_free(tmp); @@ -267,7 +270,7 @@ BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, if ((tmp = BN_new()) == NULL || (tmp2 = BN_new()) == NULL || - (tmp3 = BN_new()) == NULL || (K = BN_new()) == NULL) + (tmp3 = BN_new()) == NULL) goto err; if (!BN_mod_exp(tmp, g, x, N, bn_ctx)) @@ -279,12 +282,15 @@ BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) goto err; - if (!BN_mod_mul(tmp3, u, x, N, bn_ctx)) + if (!BN_mul(tmp3, u, x, bn_ctx)) goto err; - if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx)) - goto err; - if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) + if (!BN_add(tmp2, a, tmp3)) goto err; + K = BN_new(); + if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) { + BN_free(K); + K = NULL; + } err: BN_CTX_free(bn_ctx); diff --git a/crypto/openssl/crypto/srp/srp_vfy.c b/crypto/openssl/crypto/srp/srp_vfy.c index 26ad3e0..a8ec52a 100644 --- a/crypto/openssl/crypto/srp/srp_vfy.c +++ b/crypto/openssl/crypto/srp/srp_vfy.c @@ -80,7 +80,7 @@ static char b64table[] = /* * Convert a base64 string into raw byte array representation. */ -static int t_fromb64(unsigned char *a, const char *src) +static int t_fromb64(unsigned char *a, size_t alen, const char *src) { char *loc; int i, j; @@ -89,6 +89,9 @@ static int t_fromb64(unsigned char *a, const char *src) while (*src && (*src == ' ' || *src == '\t' || *src == '\n')) ++src; size = strlen(src); + if (alen > INT_MAX || size > (int)alen) + return -1; + i = 0; while (i < size) { loc = strchr(b64table, src[i]); @@ -231,13 +234,25 @@ static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, unsigned char tmp[MAX_LEN]; int len; - if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) + vinfo->v = NULL; + vinfo->s = NULL; + + len = t_fromb64(tmp, sizeof(tmp), v); + if (len < 0) return 0; - len = t_fromb64(tmp, v); if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL))) return 0; - len = t_fromb64(tmp, s); - return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL); + len = t_fromb64(tmp, sizeof(tmp), s); + if (len < 0) + goto err; + vinfo->s = BN_bin2bn(tmp, len, NULL); + if (vinfo->s == NULL) + goto err; + return 1; + err: + BN_free(vinfo->v); + vinfo->v = NULL; + return 0; } static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) @@ -307,10 +322,13 @@ static SRP_gN_cache *SRP_gN_new_init(const char *ch) if (newgN == NULL) return NULL; + len = t_fromb64(tmp, sizeof(tmp), ch); + if (len < 0) + goto err; + if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) goto err; - len = t_fromb64(tmp, ch); if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) return newgN; @@ -544,7 +562,7 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) if (!SRP_user_pwd_set_ids(user, username, NULL)) goto err; - if (RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH) < 0) + if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0) goto err; EVP_MD_CTX_init(&ctxt); EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); @@ -580,10 +598,10 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, goto err; if (N) { - if (!(len = t_fromb64(tmp, N))) + if (!(len = t_fromb64(tmp, sizeof(tmp), N))) goto err; N_bn = BN_bin2bn(tmp, len, NULL); - if (!(len = t_fromb64(tmp, g))) + if (!(len = t_fromb64(tmp, sizeof(tmp), g))) goto err; g_bn = BN_bin2bn(tmp, len, NULL); defgNid = "*"; @@ -597,12 +615,12 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, } if (*salt == NULL) { - if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0) + if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) goto err; s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); } else { - if (!(len = t_fromb64(tmp2, *salt))) + if (!(len = t_fromb64(tmp2, sizeof(tmp2), *salt))) goto err; s = BN_bin2bn(tmp2, len, NULL); } @@ -635,7 +653,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, BN_free(N_bn); BN_free(g_bn); } - OPENSSL_cleanse(vf, vfsize); + if (vf != NULL) + OPENSSL_cleanse(vf, vfsize); OPENSSL_free(vf); BN_clear_free(s); BN_clear_free(v); @@ -670,7 +689,7 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, srp_bn_print(g); if (*salt == NULL) { - if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0) + if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) goto err; salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); diff --git a/crypto/openssl/crypto/ts/ts.h b/crypto/openssl/crypto/ts/ts.h index 16eccbb..2daa1b2 100644 --- a/crypto/openssl/crypto/ts/ts.h +++ b/crypto/openssl/crypto/ts/ts.h @@ -565,6 +565,9 @@ int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, /* At most we accept usec precision. */ # define TS_MAX_CLOCK_PRECISION_DIGITS 6 +/* Maximum status message length */ +# define TS_MAX_STATUS_LENGTH (1024 * 1024) + /* No flags are set by default. */ void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); diff --git a/crypto/openssl/crypto/ts/ts_lib.c b/crypto/openssl/crypto/ts/ts_lib.c index c51538a..e0f1063 100644 --- a/crypto/openssl/crypto/ts/ts_lib.c +++ b/crypto/openssl/crypto/ts/ts_lib.c @@ -90,9 +90,8 @@ int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) { char obj_txt[128]; - int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); - BIO_write(bio, obj_txt, len); - BIO_write(bio, "\n", 1); + OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); + BIO_printf(bio, "%s\n", obj_txt); return 1; } diff --git a/crypto/openssl/crypto/ts/ts_rsp_verify.c b/crypto/openssl/crypto/ts/ts_rsp_verify.c index 29aa5a4..7918236 100644 --- a/crypto/openssl/crypto/ts/ts_rsp_verify.c +++ b/crypto/openssl/crypto/ts/ts_rsp_verify.c @@ -434,51 +434,58 @@ static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, unsigned char *imprint = NULL; unsigned imprint_len = 0; int ret = 0; + int flags = ctx->flags; + + /* Some options require us to also check the signature */ + if (((flags & TS_VFY_SIGNER) && tsa_name != NULL) + || (flags & TS_VFY_TSA_NAME)) { + flags |= TS_VFY_SIGNATURE; + } /* Verify the signature. */ - if ((ctx->flags & TS_VFY_SIGNATURE) + if ((flags & TS_VFY_SIGNATURE) && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) goto err; /* Check version number of response. */ - if ((ctx->flags & TS_VFY_VERSION) + if ((flags & TS_VFY_VERSION) && TS_TST_INFO_get_version(tst_info) != 1) { TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); goto err; } /* Check policies. */ - if ((ctx->flags & TS_VFY_POLICY) + if ((flags & TS_VFY_POLICY) && !TS_check_policy(ctx->policy, tst_info)) goto err; /* Check message imprints. */ - if ((ctx->flags & TS_VFY_IMPRINT) + if ((flags & TS_VFY_IMPRINT) && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, tst_info)) goto err; /* Compute and check message imprints. */ - if ((ctx->flags & TS_VFY_DATA) + if ((flags & TS_VFY_DATA) && (!TS_compute_imprint(ctx->data, tst_info, &md_alg, &imprint, &imprint_len) || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) goto err; /* Check nonces. */ - if ((ctx->flags & TS_VFY_NONCE) + if ((flags & TS_VFY_NONCE) && !TS_check_nonces(ctx->nonce, tst_info)) goto err; /* Check whether TSA name and signer certificate match. */ - if ((ctx->flags & TS_VFY_SIGNER) + if ((flags & TS_VFY_SIGNER) && tsa_name && !TS_check_signer_name(tsa_name, signer)) { TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); goto err; } /* Check whether the TSA is the expected one. */ - if ((ctx->flags & TS_VFY_TSA_NAME) + if ((flags & TS_VFY_TSA_NAME) && !TS_check_signer_name(ctx->tsa_name, signer)) { TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); goto err; @@ -548,13 +555,15 @@ static int TS_check_status_info(TS_RESP *response) static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) { int i; - unsigned int length = 0; + int length = 0; char *result = NULL; char *p; /* Determine length first. */ for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1) + return NULL; length += ASN1_STRING_length(current); length += 1; /* separator character */ } diff --git a/crypto/openssl/crypto/ui/ui_lib.c b/crypto/openssl/crypto/ui/ui_lib.c index 2f58035..d25b4f3 100644 --- a/crypto/openssl/crypto/ui/ui_lib.c +++ b/crypto/openssl/crypto/ui/ui_lib.c @@ -413,6 +413,8 @@ char *UI_construct_prompt(UI *ui, const char *object_desc, len += sizeof(prompt3) - 1; prompt = (char *)OPENSSL_malloc(len + 1); + if (prompt == NULL) + return NULL; BUF_strlcpy(prompt, prompt1, len + 1); BUF_strlcat(prompt, object_desc, len + 1); if (object_name) { diff --git a/crypto/openssl/crypto/whrlpool/wp_dgst.c b/crypto/openssl/crypto/whrlpool/wp_dgst.c index e33bb4f..807d1c4 100644 --- a/crypto/openssl/crypto/whrlpool/wp_dgst.c +++ b/crypto/openssl/crypto/whrlpool/wp_dgst.c @@ -51,6 +51,7 @@ * input. This is done for perfomance. */ +#include <openssl/crypto.h> #include "wp_locl.h" #include <openssl/crypto.h> #include <string.h> @@ -237,7 +238,7 @@ int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) if (md) { memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); - memset(c, 0, sizeof(*c)); + OPENSSL_cleanse(c, sizeof(*c)); return (1); } return (0); diff --git a/crypto/openssl/crypto/x509/by_dir.c b/crypto/openssl/crypto/x509/by_dir.c index 9ee8f8d..bbc3189 100644 --- a/crypto/openssl/crypto/x509/by_dir.c +++ b/crypto/openssl/crypto/x509/by_dir.c @@ -401,6 +401,10 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, } if (!hent) { hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + goto finish; + } hent->hash = h; hent->suffix = k; if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { diff --git a/crypto/openssl/crypto/x509/x509.h b/crypto/openssl/crypto/x509/x509.h index fc613ce..6fa28eb 100644 --- a/crypto/openssl/crypto/x509/x509.h +++ b/crypto/openssl/crypto/x509/x509.h @@ -1234,6 +1234,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp); * The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ + void ERR_load_X509_strings(void); /* Error codes for the X509 functions. */ @@ -1241,6 +1242,7 @@ void ERR_load_X509_strings(void); /* Function codes. */ # define X509_F_ADD_CERT_DIR 100 # define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_NAME_CONSTRAINTS 106 # define X509_F_CHECK_POLICY 145 # define X509_F_DIR_CTRL 102 # define X509_F_GET_CERT_BY_SUBJECT 103 @@ -1322,7 +1324,7 @@ void ERR_load_X509_strings(void); # define X509_R_WRONG_LOOKUP_TYPE 112 # define X509_R_WRONG_TYPE 122 -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif #endif diff --git a/crypto/openssl/crypto/x509/x509_att.c b/crypto/openssl/crypto/x509/x509_att.c index bd59281..2501075 100644 --- a/crypto/openssl/crypto/x509/x509_att.c +++ b/crypto/openssl/crypto/x509/x509_att.c @@ -296,7 +296,7 @@ int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len) { - ASN1_TYPE *ttmp; + ASN1_TYPE *ttmp = NULL; ASN1_STRING *stmp = NULL; int atype = 0; if (!attr) @@ -324,20 +324,26 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, * least one value but some types use and zero length SET and require * this. */ - if (attrtype == 0) + if (attrtype == 0) { + ASN1_STRING_free(stmp); return 1; + } if (!(ttmp = ASN1_TYPE_new())) goto err; if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { if (!ASN1_TYPE_set1(ttmp, attrtype, data)) goto err; - } else + } else { ASN1_TYPE_set(ttmp, atype, stmp); + stmp = NULL; + } if (!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err; return 1; err: X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); return 0; } diff --git a/crypto/openssl/crypto/x509/x509_err.c b/crypto/openssl/crypto/x509/x509_err.c index 1e779fe..a2a8e1b 100644 --- a/crypto/openssl/crypto/x509/x509_err.c +++ b/crypto/openssl/crypto/x509/x509_err.c @@ -1,6 +1,6 @@ /* crypto/x509/x509_err.c */ /* ==================================================================== - * Copyright (c) 1999-2012 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -72,6 +72,7 @@ static ERR_STRING_DATA X509_str_functs[] = { {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, + {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"}, {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, diff --git a/crypto/openssl/crypto/x509/x509_obj.c b/crypto/openssl/crypto/x509/x509_obj.c index 3de3ac7..0a839f3 100644 --- a/crypto/openssl/crypto/x509/x509_obj.c +++ b/crypto/openssl/crypto/x509/x509_obj.c @@ -129,7 +129,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) type == V_ASN1_VISIBLESTRING || type == V_ASN1_PRINTABLESTRING || type == V_ASN1_TELETEXSTRING || - type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) { + type == V_ASN1_IA5STRING) { if (num > (int)sizeof(ebcdic_buf)) num = sizeof(ebcdic_buf); ascii2ebcdic(ebcdic_buf, q, num); diff --git a/crypto/openssl/crypto/x509/x509_r2x.c b/crypto/openssl/crypto/x509/x509_r2x.c index 0ff439c..2879569 100644 --- a/crypto/openssl/crypto/x509/x509_r2x.c +++ b/crypto/openssl/crypto/x509/x509_r2x.c @@ -70,10 +70,12 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) X509 *ret = NULL; X509_CINF *xi = NULL; X509_NAME *xn; + EVP_PKEY *pubkey = NULL; + int res; if ((ret = X509_new()) == NULL) { X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); - goto err; + return NULL; } /* duplicate the request */ @@ -89,9 +91,9 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) } xn = X509_REQ_get_subject_name(r); - if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0) + if (X509_set_subject_name(ret, xn) == 0) goto err; - if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0) + if (X509_set_issuer_name(ret, xn) == 0) goto err; if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) @@ -100,9 +102,11 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) NULL) goto err; - X509_set_pubkey(ret, X509_REQ_get_pubkey(r)); + pubkey = X509_REQ_get_pubkey(r); + res = X509_set_pubkey(ret, pubkey); + EVP_PKEY_free(pubkey); - if (!X509_sign(ret, pkey, EVP_md5())) + if (!res || !X509_sign(ret, pkey, EVP_md5())) goto err; if (0) { err: diff --git a/crypto/openssl/crypto/x509/x509_txt.c b/crypto/openssl/crypto/x509/x509_txt.c index 3d46d3f..35db095 100644 --- a/crypto/openssl/crypto/x509/x509_txt.c +++ b/crypto/openssl/crypto/x509/x509_txt.c @@ -204,6 +204,13 @@ const char *X509_verify_cert_error_string(long n) case X509_V_ERR_IP_ADDRESS_MISMATCH: return ("IP address mismatch"); + case X509_V_ERR_INVALID_CALL: + return ("Invalid certificate verification context"); + case X509_V_ERR_STORE_LOOKUP: + return ("Issuer certificate lookup error"); + case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: + return ("proxy subject name violation"); + default: BIO_snprintf(buf, sizeof buf, "error number %ld", n); return (buf); diff --git a/crypto/openssl/crypto/x509/x509_vfy.c b/crypto/openssl/crypto/x509/x509_vfy.c index 4d34dba..8334b3f 100644 --- a/crypto/openssl/crypto/x509/x509_vfy.c +++ b/crypto/openssl/crypto/x509/x509_vfy.c @@ -199,6 +199,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (ctx->cert == NULL) { X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ctx->error = X509_V_ERR_INVALID_CALL; return -1; } if (ctx->chain != NULL) { @@ -207,6 +208,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) * cannot do another one. */ X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; return -1; } @@ -219,6 +221,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (((ctx->chain = sk_X509_new_null()) == NULL) || (!sk_X509_push(ctx->chain, ctx->cert))) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; ok = -1; goto err; } @@ -229,6 +232,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; ok = -1; goto err; } @@ -253,8 +257,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx) */ if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; goto err; + } /* * If successful for now free up cert so it will be picked up * again later. @@ -271,6 +277,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (xtmp != NULL) { if (!sk_X509_push(ctx->chain, xtmp)) { X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; ok = -1; goto err; } @@ -352,14 +359,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx) break; ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; goto err; + } if (ok == 0) break; x = xtmp; if (!sk_X509_push(ctx->chain, x)) { X509_free(xtmp); X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; ok = -1; goto err; } @@ -386,8 +396,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx) while (j-- > 1) { xtmp2 = sk_X509_value(ctx->chain, j - 1); ok = ctx->get_issuer(&xtmp, ctx, xtmp2); - if (ok < 0) + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; goto err; + } /* Check if we found an alternate chain */ if (ok > 0) { /* @@ -515,6 +527,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx) sk_X509_free(sktmp); if (chain_ss != NULL) X509_free(chain_ss); + + /* Safety net, error returns must set ctx->error */ + if (ok <= 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; return ok; } @@ -697,13 +713,27 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) * the next certificate must be a CA certificate. */ if (x->ex_flags & EXFLAG_PROXY) { - if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) { - ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; + /* + * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint + * is less than max_path_length, the former should be copied to + * the latter, and 4.1.4 (a) stipulates that max_path_length + * should be verified to be larger than zero and decrement it. + * + * Because we're checking the certs in the reverse order, we start + * with verifying that proxy_path_length isn't larger than pcPLC, + * and copy the latter to the former if it is, and finally, + * increment proxy_path_length. + */ + if (x->ex_pcpathlen != -1) { + if (proxy_path_length > x->ex_pcpathlen) { + ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + proxy_path_length = x->ex_pcpathlen; } proxy_path_length++; must_be_ca = 0; @@ -726,6 +756,81 @@ static int check_name_constraints(X509_STORE_CTX *ctx) /* Ignore self issued certs unless last in chain */ if (i && (x->ex_flags & EXFLAG_SI)) continue; + + /* + * Proxy certificates policy has an extra constraint, where the + * certificate subject MUST be the issuer with a single CN entry + * added. + * (RFC 3820: 3.4, 4.1.3 (a)(4)) + */ + if (x->ex_flags & EXFLAG_PROXY) { + X509_NAME *tmpsubject = X509_get_subject_name(x); + X509_NAME *tmpissuer = X509_get_issuer_name(x); + X509_NAME_ENTRY *tmpentry = NULL; + int last_object_nid = 0; + int err = X509_V_OK; + int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1; + + /* Check that there are at least two RDNs */ + if (last_object_loc < 1) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that there is exactly one more RDN in subject as + * there is in issuer. + */ + if (X509_NAME_entry_count(tmpsubject) + != X509_NAME_entry_count(tmpissuer) + 1) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that the last subject component isn't part of a + * multivalued RDN + */ + if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set + == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that the last subject RDN is a commonName, and that + * all the previous RDNs match the issuer exactly + */ + tmpsubject = X509_NAME_dup(tmpsubject); + if (tmpsubject == NULL) { + X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + + tmpentry = + X509_NAME_delete_entry(tmpsubject, last_object_loc); + last_object_nid = + OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); + + if (last_object_nid != NID_commonName + || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + } + + X509_NAME_ENTRY_free(tmpentry); + X509_NAME_free(tmpsubject); + + proxy_name_done: + if (err != X509_V_OK) { + ctx->error = err; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + /* * Check against constraints for all certificates higher in chain * including trust anchor. Trust anchor not strictly speaking needed @@ -736,12 +841,19 @@ static int check_name_constraints(X509_STORE_CTX *ctx) NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; if (nc) { rv = NAME_CONSTRAINTS_check(x, nc); - if (rv != X509_V_OK) { + switch (rv) { + case X509_V_OK: + continue; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: ctx->error = rv; ctx->error_depth = i; ctx->current_cert = x; if (!ctx->verify_cb(0, ctx)) return 0; + break; } } } @@ -880,6 +992,8 @@ static int check_cert(X509_STORE_CTX *ctx) ctx->current_issuer = NULL; ctx->current_crl_score = 0; ctx->current_reasons = 0; + if (x->ex_flags & EXFLAG_PROXY) + return 1; while (ctx->current_reasons != CRLDP_ALL_REASONS) { last_reasons = ctx->current_reasons; /* Try to retrieve relevant CRL */ @@ -1010,13 +1124,25 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, crl = sk_X509_CRL_value(crls, i); reasons = *preasons; crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); - - if (crl_score > best_score) { - best_crl = crl; - best_crl_issuer = crl_issuer; - best_score = crl_score; - best_reasons = reasons; + if (crl_score < best_score) + continue; + /* If current CRL is equivalent use it if it is newer */ + if (crl_score == best_score) { + int day, sec; + if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl), + X509_CRL_get_lastUpdate(crl)) == 0) + continue; + /* + * ASN1_TIME_diff never returns inconsistent signs for |day| + * and |sec|. + */ + if (day <= 0 && sec <= 0) + continue; } + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; } if (best_crl) { @@ -1630,6 +1756,7 @@ static int check_policy(X509_STORE_CTX *ctx) ctx->param->policies, ctx->param->flags); if (ret == 0) { X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; return 0; } /* Invalid or inconsistent extensions */ @@ -1658,7 +1785,12 @@ static int check_policy(X509_STORE_CTX *ctx) if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { ctx->current_cert = NULL; - ctx->error = X509_V_OK; + /* + * Verification errors need to be "sticky", a callback may have allowed + * an SSL handshake to continue despite an error, and we must then + * remain in an error state. Therefore, we MUST NOT clear earlier + * verification errors by setting the error to X509_V_OK. + */ if (!ctx->verify_cb(2, ctx)) return 0; } diff --git a/crypto/openssl/crypto/x509/x509_vfy.h b/crypto/openssl/crypto/x509/x509_vfy.h index 2663e1c..5062682 100644 --- a/crypto/openssl/crypto/x509/x509_vfy.h +++ b/crypto/openssl/crypto/x509/x509_vfy.h @@ -368,6 +368,7 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); # define X509_V_ERR_PERMITTED_VIOLATION 47 # define X509_V_ERR_EXCLUDED_VIOLATION 48 # define X509_V_ERR_SUBTREE_MINMAX 49 +# define X509_V_ERR_APPLICATION_VERIFICATION 50 # define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 # define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 # define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 @@ -386,8 +387,12 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); # define X509_V_ERR_EMAIL_MISMATCH 63 # define X509_V_ERR_IP_ADDRESS_MISMATCH 64 -/* The application is not happy */ -# define X509_V_ERR_APPLICATION_VERIFICATION 50 +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 65 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 66 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67 /* Certificate verify flags */ diff --git a/crypto/openssl/crypto/x509/x509spki.c b/crypto/openssl/crypto/x509/x509spki.c index 2df84ea..5ae5d30 100644 --- a/crypto/openssl/crypto/x509/x509spki.c +++ b/crypto/openssl/crypto/x509/x509spki.c @@ -112,6 +112,8 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) der_spki = OPENSSL_malloc(der_len); b64_str = OPENSSL_malloc(der_len * 2); if (!der_spki || !b64_str) { + OPENSSL_free(der_spki); + OPENSSL_free(b64_str); X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); return NULL; } diff --git a/crypto/openssl/crypto/x509v3/v3_addr.c b/crypto/openssl/crypto/x509v3/v3_addr.c index 94cfed0..1290dec 100644 --- a/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/crypto/openssl/crypto/x509v3/v3_addr.c @@ -1211,6 +1211,11 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) /* * Core code for RFC 3779 2.3 path validation. + * + * Returns 1 for success, 0 on error. + * + * When returning 0, ctx->error MUST be set to an appropriate value other than + * X509_V_OK. */ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, @@ -1245,6 +1250,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; ret = 0; goto done; } diff --git a/crypto/openssl/crypto/x509v3/v3_alt.c b/crypto/openssl/crypto/x509v3/v3_alt.c index 22ec202..7f1e71d 100644 --- a/crypto/openssl/crypto/x509v3/v3_alt.c +++ b/crypto/openssl/crypto/x509v3/v3_alt.c @@ -573,6 +573,8 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) return 0; objlen = p - value; objtmp = OPENSSL_malloc(objlen + 1); + if (objtmp == NULL) + return 0; strncpy(objtmp, value, objlen); objtmp[objlen] = 0; gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); diff --git a/crypto/openssl/crypto/x509v3/v3_conf.c b/crypto/openssl/crypto/x509v3/v3_conf.c index eeff8bd..c1b4c1a 100644 --- a/crypto/openssl/crypto/x509v3/v3_conf.c +++ b/crypto/openssl/crypto/x509v3/v3_conf.c @@ -135,11 +135,13 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, nval = NCONF_get_section(conf, value + 1); else nval = X509V3_parse_list(value); - if (sk_CONF_VALUE_num(nval) <= 0) { + if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_INVALID_EXTENSION_STRING); ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value); + if (*value != '@') + sk_CONF_VALUE_free(nval); return NULL; } ext_struc = method->v2i(method, ctx, nval); diff --git a/crypto/openssl/doc/apps/cms.pod b/crypto/openssl/doc/apps/cms.pod index 4eaedbc..ac69804 100644 --- a/crypto/openssl/doc/apps/cms.pod +++ b/crypto/openssl/doc/apps/cms.pod @@ -86,6 +86,9 @@ encrypt mail for the given recipient certificates. Input file is the message to be encrypted. The output file is the encrypted mail in MIME format. The actual CMS type is <B>EnvelopedData<B>. +Note that no revocation check is done for the recipient cert, so if that +key has been compromised, others may be able to decrypt the text. + =item B<-decrypt> decrypt mail using the supplied certificate and private key. Expects an diff --git a/crypto/openssl/doc/apps/s_client.pod b/crypto/openssl/doc/apps/s_client.pod index 618df96..29675dd 100644 --- a/crypto/openssl/doc/apps/s_client.pod +++ b/crypto/openssl/doc/apps/s_client.pod @@ -53,6 +53,7 @@ B<openssl> B<s_client> [B<-rand file(s)>] [B<-serverinfo types>] [B<-status>] +[B<-alpn protocols>] [B<-nextprotoneg protocols>] =head1 DESCRIPTION @@ -277,9 +278,13 @@ file. sends a certificate status request to the server (OCSP stapling). The server response (if any) is printed out. -=item B<-nextprotoneg protocols> +=item B<-alpn protocols>, B<-nextprotoneg protocols> -enable Next Protocol Negotiation TLS extension and provide a list of +these flags enable the +Enable the Application-Layer Protocol Negotiation or Next Protocol +Negotiation extension, respectively. ALPN is the IETF standard and +replaces NPN. +The B<protocols> list is a comma-separated protocol names that the client should advertise support for. The list should contain most wanted protocols first. Protocol names are printable ASCII strings, for example "http/1.1" or diff --git a/crypto/openssl/doc/apps/s_server.pod b/crypto/openssl/doc/apps/s_server.pod index 6f4acb7..fa17488 100644 --- a/crypto/openssl/doc/apps/s_server.pod +++ b/crypto/openssl/doc/apps/s_server.pod @@ -62,6 +62,7 @@ B<openssl> B<s_server> [B<-status_verbose>] [B<-status_timeout nsec>] [B<-status_url url>] +[B<-alpn protocols>] [B<-nextprotoneg protocols>] =head1 DESCRIPTION @@ -327,9 +328,13 @@ sets a fallback responder URL to use if no responder URL is present in the server certificate. Without this option an error is returned if the server certificate does not contain a responder address. -=item B<-nextprotoneg protocols> +=item B<-alpn protocols>, B<-nextprotoneg protocols> -enable Next Protocol Negotiation TLS extension and provide a +these flags enable the +Enable the Application-Layer Protocol Negotiation or Next Protocol +Negotiation extension, respectively. ALPN is the IETF standard and +replaces NPN. +The B<protocols> list is a comma-separated list of supported protocol names. The list should contain most wanted protocols first. Protocol names are printable ASCII strings, for example "http/1.1" or diff --git a/crypto/openssl/doc/apps/smime.pod b/crypto/openssl/doc/apps/smime.pod index d5618c8..04a83ca 100644 --- a/crypto/openssl/doc/apps/smime.pod +++ b/crypto/openssl/doc/apps/smime.pod @@ -53,6 +53,9 @@ The meaning of the other options varies according to the operation type. encrypt mail for the given recipient certificates. Input file is the message to be encrypted. The output file is the encrypted mail in MIME format. +Note that no revocation check is done for the recipient cert, so if that +key has been compromised, others may be able to decrypt the text. + =item B<-decrypt> decrypt mail using the supplied certificate and private key. Expects an diff --git a/crypto/openssl/doc/apps/verify.pod b/crypto/openssl/doc/apps/verify.pod index bffa6c0..b376732 100644 --- a/crypto/openssl/doc/apps/verify.pod +++ b/crypto/openssl/doc/apps/verify.pod @@ -27,6 +27,7 @@ B<openssl> B<verify> [B<-use_deltas>] [B<-policy_print>] [B<-no_alt_chains>] +[B<-allow_proxy_certs>] [B<-untrusted file>] [B<-help>] [B<-issuer_checks>] @@ -139,6 +140,10 @@ be found that is trusted. With this option that behaviour is suppressed so that only the first chain found is ever used. Using this option will force the behaviour to match that of previous OpenSSL versions. +=item B<-allow_proxy_certs> + +Allow the verification of proxy certificates. + =item B<-trusted file> A file of additional trusted certificates. The file should contain multiple diff --git a/crypto/openssl/doc/apps/x509.pod b/crypto/openssl/doc/apps/x509.pod index f72e978..10e49e5 100644 --- a/crypto/openssl/doc/apps/x509.pod +++ b/crypto/openssl/doc/apps/x509.pod @@ -642,8 +642,8 @@ hex dump unsupported extensions. =item B<ca_default> -the value used by the B<ca> utility, equivalent to B<no_issuer>, B<no_pubkey>, B<no_header>, -B<no_version>, B<no_sigdump> and B<no_signame>. +the value used by the B<ca> utility, equivalent to B<no_issuer>, B<no_pubkey>, +B<no_header>, and B<no_version>. =back diff --git a/crypto/openssl/doc/apps/x509v3_config.pod b/crypto/openssl/doc/apps/x509v3_config.pod index c82cea1..fb5f79c 100644 --- a/crypto/openssl/doc/apps/x509v3_config.pod +++ b/crypto/openssl/doc/apps/x509v3_config.pod @@ -104,7 +104,7 @@ Examples: This extensions consists of a list of usages indicating purposes for which the certificate public key can be used for, -These can either be object short names of the dotted numerical form of OIDs. +These can either be object short names or the dotted numerical form of OIDs. While any OID can be used only certain values make sense. In particular the following PKIX, NS and MS values are meaningful: diff --git a/crypto/openssl/doc/crypto/BIO_s_bio.pod b/crypto/openssl/doc/crypto/BIO_s_bio.pod index 8d0a55a..9fe88b2 100644 --- a/crypto/openssl/doc/crypto/BIO_s_bio.pod +++ b/crypto/openssl/doc/crypto/BIO_s_bio.pod @@ -120,6 +120,9 @@ the application then waits for data to be available on the underlying transport before flushing the write buffer it will never succeed because the request was never sent! +BIO_eof() is true if no data is in the peer BIO and the peer BIO has been +shutdown. + =head1 RETURN VALUES BIO_new_bio_pair() returns 1 on success, with the new BIOs available in diff --git a/crypto/openssl/doc/crypto/BN_bn2bin.pod b/crypto/openssl/doc/crypto/BN_bn2bin.pod index a4b17ca..3bed47f 100644 --- a/crypto/openssl/doc/crypto/BN_bn2bin.pod +++ b/crypto/openssl/doc/crypto/BN_bn2bin.pod @@ -42,7 +42,9 @@ BN_hex2bn() converts the string B<str> containing a hexadecimal number to a B<BIGNUM> and stores it in **B<bn>. If *B<bn> is NULL, a new B<BIGNUM> is created. If B<bn> is NULL, it only computes the number's length in hexadecimal digits. If the string starts with '-', the -number is negative. BN_dec2bn() is the same using the decimal system. +number is negative. +A "negative zero" is converted to zero. +BN_dec2bn() is the same using the decimal system. BN_print() and BN_print_fp() write the hexadecimal encoding of B<a>, with a leading '-' for negative numbers, to the B<BIO> or B<FILE> diff --git a/crypto/openssl/doc/crypto/BN_rand.pod b/crypto/openssl/doc/crypto/BN_rand.pod index e8cbf65..a1513a9 100644 --- a/crypto/openssl/doc/crypto/BN_rand.pod +++ b/crypto/openssl/doc/crypto/BN_rand.pod @@ -19,7 +19,11 @@ BN_rand, BN_pseudo_rand, BN_rand_range, BN_pseudo_rand_range - generate pseudo-r =head1 DESCRIPTION BN_rand() generates a cryptographically strong pseudo-random number of -B<bits> in length and stores it in B<rnd>. If B<top> is -1, the +B<bits> in length and stores it in B<rnd>. +If B<bits> is less than zero, or too small to +accomodate the requirements specified by the B<top> and B<bottom> +parameters, an error is returned. +If B<top> is -1, the most significant bit of the random number can be zero. If B<top> is 0, it is set to 1, and if B<top> is 1, the two most significant bits of the number will be set to 1, so that the product of two such random diff --git a/crypto/openssl/doc/crypto/EVP_EncryptInit.pod b/crypto/openssl/doc/crypto/EVP_EncryptInit.pod index 9696fd8..9facf51 100644 --- a/crypto/openssl/doc/crypto/EVP_EncryptInit.pod +++ b/crypto/openssl/doc/crypto/EVP_EncryptInit.pod @@ -165,10 +165,11 @@ similar way to EVP_EncryptInit_ex(), EVP_DecryptInit_ex and EVP_CipherInit_ex() except the B<ctx> parameter does not need to be initialized and they always use the default cipher implementation. -EVP_EncryptFinal(), EVP_DecryptFinal() and EVP_CipherFinal() behave in a -similar way to EVP_EncryptFinal_ex(), EVP_DecryptFinal_ex() and -EVP_CipherFinal_ex() except B<ctx> is automatically cleaned up -after the call. +EVP_EncryptFinal(), EVP_DecryptFinal() and EVP_CipherFinal() are +identical to EVP_EncryptFinal_ex(), EVP_DecryptFinal_ex() and +EVP_CipherFinal_ex(). In previous releases they also cleaned up +the B<ctx>, but this is no longer done and EVP_CIPHER_CTX_clean() +must be called to free any context resources. EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj() return an EVP_CIPHER structure when passed a cipher name, a NID or an diff --git a/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod b/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod index 0ff027c..f8e7ff1 100644 --- a/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod +++ b/crypto/openssl/doc/crypto/EVP_PKEY_cmp.pod @@ -21,7 +21,9 @@ parameters of B<pkey> are missing and 0 if they are present or the algorithm doesn't use parameters. The function EVP_PKEY_copy_parameters() copies the parameters from key -B<from> to key B<to>. +B<from> to key B<to>. An error is returned if the parameters are missing in +B<from> or present in both B<from> and B<to> and mismatch. If the parameters +in B<from> and B<to> are both present and match this function has no effect. The function EVP_PKEY_cmp_parameters() compares the parameters of keys B<a> and B<b>. diff --git a/crypto/openssl/doc/crypto/OBJ_nid2obj.pod b/crypto/openssl/doc/crypto/OBJ_nid2obj.pod index 1e45dd4..b8d2896 100644 --- a/crypto/openssl/doc/crypto/OBJ_nid2obj.pod +++ b/crypto/openssl/doc/crypto/OBJ_nid2obj.pod @@ -33,6 +33,12 @@ functions The ASN1 object utility functions process ASN1_OBJECT structures which are a representation of the ASN1 OBJECT IDENTIFIER (OID) type. +For convenience, OIDs are usually represented in source code as numeric +identifiers, or B<NID>s. OpenSSL has an internal table of OIDs that +are generated when the library is built, and their corresponding NIDs +are available as defined constants. For the functions below, application +code should treat all returned values -- OIDs, NIDs, or names -- as +constants. OBJ_nid2obj(), OBJ_nid2ln() and OBJ_nid2sn() convert the NID B<n> to an ASN1_OBJECT structure, its long name and its short name respectively, @@ -96,6 +102,16 @@ Objects do not need to be in the internal tables to be processed, the functions OBJ_txt2obj() and OBJ_obj2txt() can process the numerical form of an OID. +Some objects are used to represent algorithms which do not have a +corresponding ASN.1 OBJECT IDENTIFIER encoding (for example no OID currently +exists for a particular algorithm). As a result they B<cannot> be encoded or +decoded as part of ASN.1 structures. Applications can determine if there +is a corresponding OBJECT IDENTIFIER by checking OBJ_length() is not zero. + +These functions cannot return B<const> because an B<ASN1_OBJECT> can +represent both an internal, constant, OID and a dynamically-created one. +The latter cannot be constant because it needs to be freed after use. + =head1 EXAMPLES Create an object for B<commonName>: @@ -106,12 +122,13 @@ Create an object for B<commonName>: Check if an object is B<commonName> if (OBJ_obj2nid(obj) == NID_commonName) - /* Do something */ + /* Do something */ Create a new NID and initialize an object from it: int new_nid; ASN1_OBJECT *obj; + new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier"); obj = OBJ_nid2obj(new_nid); @@ -133,6 +150,8 @@ than enough to handle any OID encountered in practice. OBJ_nid2obj() returns an B<ASN1_OBJECT> structure or B<NULL> is an error occurred. +It returns a pointer to an internal table and does not +allocate memory; ASN1_OBJECT_free() will have no effect. OBJ_nid2ln() and OBJ_nid2sn() returns a valid string or B<NULL> on error. diff --git a/crypto/openssl/doc/crypto/OPENSSL_config.pod b/crypto/openssl/doc/crypto/OPENSSL_config.pod index 2d25b26..4e71365 100644 --- a/crypto/openssl/doc/crypto/OPENSSL_config.pod +++ b/crypto/openssl/doc/crypto/OPENSSL_config.pod @@ -8,15 +8,14 @@ OPENSSL_config, OPENSSL_no_config - simple OpenSSL configuration functions #include <openssl/conf.h> - void OPENSSL_config(const char *config_name); + void OPENSSL_config(const char *appname); void OPENSSL_no_config(void); =head1 DESCRIPTION -OPENSSL_config() configures OpenSSL using the standard B<openssl.cnf> -configuration file name using B<config_name>. If B<config_name> is NULL then -the file specified in the environment variable B<OPENSSL_CONF> will be used, -and if that is not set then a system default location is used. +OPENSSL_config() configures OpenSSL using the standard B<openssl.cnf> and +reads from the application section B<appname>. If B<appname> is NULL then +the default section, B<openssl_conf>, will be used. Errors are silently ignored. Multiple calls have no effect. diff --git a/crypto/openssl/doc/crypto/OPENSSL_ia32cap.pod b/crypto/openssl/doc/crypto/OPENSSL_ia32cap.pod index 90156d2..5bcb82e 100644 --- a/crypto/openssl/doc/crypto/OPENSSL_ia32cap.pod +++ b/crypto/openssl/doc/crypto/OPENSSL_ia32cap.pod @@ -6,7 +6,7 @@ OPENSSL_ia32cap, OPENSSL_ia32cap_loc - the IA-32 processor capabilities vector =head1 SYNOPSIS - unsigned int *OPENSSL_ia32cap_loc(void); + unsigned long *OPENSSL_ia32cap_loc(void); #define OPENSSL_ia32cap ((OPENSSL_ia32cap_loc())[0]) =head1 DESCRIPTION diff --git a/crypto/openssl/doc/crypto/X509_verify_cert.pod b/crypto/openssl/doc/crypto/X509_verify_cert.pod index a22e441..4689e3a 100644 --- a/crypto/openssl/doc/crypto/X509_verify_cert.pod +++ b/crypto/openssl/doc/crypto/X509_verify_cert.pod @@ -31,12 +31,13 @@ Applications rarely call this function directly but it is used by OpenSSL internally for certificate validation, in both the S/MIME and SSL/TLS code. -The negative return value from X509_verify_cert() can only occur if no -certificate is set in B<ctx> (due to a programming error); if X509_verify_cert() -twice without reinitialising B<ctx> in between; or if a retry -operation is requested during internal lookups (which never happens with -standard lookup methods). It is however recommended that application check -for <= 0 return value on error. +A negative return value from X509_verify_cert() can occur if it is invoked +incorrectly, such as with no certificate set in B<ctx>, or when it is called +twice in succession without reinitialising B<ctx> for the second call. +A negative return value can also happen due to internal resource problems or if +a retry operation is requested during internal lookups (which never happens +with standard lookup methods). +Applications must check for <= 0 return value on error. =head1 BUGS diff --git a/crypto/openssl/doc/crypto/d2i_PrivateKey.pod b/crypto/openssl/doc/crypto/d2i_PrivateKey.pod new file mode 100644 index 0000000..e06ab6c --- /dev/null +++ b/crypto/openssl/doc/crypto/d2i_PrivateKey.pod @@ -0,0 +1,59 @@ +=pod + +=head1 NAME + +d2i_Private_key, d2i_AutoPrivateKey, i2d_PrivateKey - decode and encode +functions for reading and saving EVP_PKEY structures. + +=head1 SYNOPSIS + + #include <openssl/evp.h> + + EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); + EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); + int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +=head1 DESCRIPTION + +d2i_PrivateKey() decodes a private key using algorithm B<type>. It attempts to +use any key specific format or PKCS#8 unencrypted PrivateKeyInfo format. The +B<type> parameter should be a public key algorithm constant such as +B<EVP_PKEY_RSA>. An error occurs if the decoded key does not match B<type>. + +d2i_AutoPrivateKey() is similar to d2i_PrivateKey() except it attempts to +automatically detect the private key format. + +i2d_PrivateKey() encodes B<key>. It uses a key specific format or, if none is +defined for that key type, PKCS#8 unencrypted PrivateKeyInfo format. + +These functions are similar to the d2i_X509() functions, and you should refer to +that page for a detailed description (see L<d2i_X509(3)>). + +=head1 NOTES + +All these functions use DER format and unencrypted keys. Applications wishing +to encrypt or decrypt private keys should use other functions such as +d2i_PKC8PrivateKey() instead. + +If the B<*a> is not NULL when calling d2i_PrivateKey() or d2i_AutoPrivateKey() +(i.e. an existing structure is being reused) and the key format is PKCS#8 +then B<*a> will be freed and replaced on a successful call. + +=head1 RETURN VALUES + +d2i_PrivateKey() and d2i_AutoPrivateKey() return a valid B<EVP_KEY> structure +or B<NULL> if an error occurs. The error code can be obtained by calling +L<ERR_get_error(3)>. + +i2d_PrivateKey() returns the number of bytes successfully encoded or a +negative value if an error occurs. The error code can be obtained by calling +L<ERR_get_error(3)>. + +=head1 SEE ALSO + +L<crypto(3)>, +L<d2i_PKCS8PrivateKey(3)> + +=cut diff --git a/crypto/openssl/doc/crypto/d2i_X509.pod b/crypto/openssl/doc/crypto/d2i_X509.pod index 5b7c16f..2743bc7 100644 --- a/crypto/openssl/doc/crypto/d2i_X509.pod +++ b/crypto/openssl/doc/crypto/d2i_X509.pod @@ -9,8 +9,10 @@ i2d_X509_fp - X509 encode and decode functions #include <openssl/x509.h> - X509 *d2i_X509(X509 **px, const unsigned char **in, int len); + X509 *d2i_X509(X509 **px, const unsigned char **in, long len); + X509 *d2i_X509_AUX(X509 **px, const unsigned char **in, long len); int i2d_X509(X509 *x, unsigned char **out); + int i2d_X509_AUX(X509 *x, unsigned char **out); X509 *d2i_X509_bio(BIO *bp, X509 **x); X509 *d2i_X509_fp(FILE *fp, X509 **x); @@ -37,6 +39,11 @@ below, and the discussion in the RETURN VALUES section). If the call is successful B<*in> is incremented to the byte following the parsed data. +d2i_X509_AUX() is similar to d2i_X509() but the input is expected to consist of +an X509 certificate followed by auxiliary trust information. +This is used by the PEM routines to read "TRUSTED CERTIFICATE" objects. +This function should not be called on untrusted input. + i2d_X509() encodes the structure pointed to by B<x> into DER format. If B<out> is not B<NULL> is writes the DER encoded data to the buffer at B<*out>, and increments it to point after the data just written. @@ -48,6 +55,11 @@ allocated for a buffer and the encoded data written to it. In this case B<*out> is not incremented and it points to the start of the data just written. +i2d_X509_AUX() is similar to i2d_X509(), but the encoded output contains both +the certificate and any auxiliary trust information. +This is used by the PEM routines to write "TRUSTED CERTIFICATE" objects. +Note, this is a non-standard OpenSSL-specific data format. + d2i_X509_bio() is similar to d2i_X509() except it attempts to parse data from BIO B<bp>. diff --git a/crypto/openssl/doc/crypto/hmac.pod b/crypto/openssl/doc/crypto/hmac.pod index 58a57f4..2c8f20a 100644 --- a/crypto/openssl/doc/crypto/hmac.pod +++ b/crypto/openssl/doc/crypto/hmac.pod @@ -60,13 +60,17 @@ function B<evp_md> and the key B<key> which is B<key_len> bytes long. It is deprecated and only included for backward compatibility with OpenSSL 0.9.6b. -HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use -the function B<evp_md> and key B<key>. Either can be NULL, in which -case the existing one will be reused. HMAC_CTX_init() must have been -called before the first use of an B<HMAC_CTX> in this -function. B<N.B. HMAC_Init() had this undocumented behaviour in -previous versions of OpenSSL - failure to switch to HMAC_Init_ex() in -programs that expect it will cause them to stop working>. +HMAC_Init_ex() initializes or reuses a B<HMAC_CTX> structure to use the hash +function B<evp_md> and key B<key>. If both are NULL (or B<evp_md> is the same +as the previous digest used by B<ctx> and B<key> is NULL) the existing key is +reused. B<ctx> must have been created with HMAC_CTX_new() before the first use +of an B<HMAC_CTX> in this function. B<N.B. HMAC_Init() had this undocumented +behaviour in previous versions of OpenSSL - failure to switch to HMAC_Init_ex() +in programs that expect it will cause them to stop working>. + +B<NB: if HMAC_Init_ex() is called with B<key> NULL and B<evp_md> is not the +same as the previous digest used by B<ctx> then an error is returned +because reuse of an existing key with a different digest is not supported.> HMAC_Update() can be called repeatedly with chunks of the message to be authenticated (B<len> bytes at B<data>). diff --git a/crypto/openssl/doc/crypto/rand.pod b/crypto/openssl/doc/crypto/rand.pod index d102df2..b754854 100644 --- a/crypto/openssl/doc/crypto/rand.pod +++ b/crypto/openssl/doc/crypto/rand.pod @@ -14,7 +14,7 @@ rand - pseudo-random number generator int RAND_pseudo_bytes(unsigned char *buf, int num); void RAND_seed(const void *buf, int num); - void RAND_add(const void *buf, int num, int entropy); + void RAND_add(const void *buf, int num, double entropy); int RAND_status(void); int RAND_load_file(const char *file, long max_bytes); diff --git a/crypto/openssl/doc/crypto/ui.pod b/crypto/openssl/doc/crypto/ui.pod index 04f8e9c..2e94d8c 100644 --- a/crypto/openssl/doc/crypto/ui.pod +++ b/crypto/openssl/doc/crypto/ui.pod @@ -109,12 +109,12 @@ that's connected to it, like duplicated input strings, results and others. UI_add_input_string() and UI_add_verify_string() add a prompt to the UI, as well as flags and a result buffer and the desired minimum and maximum -sizes of the result. The given information is used to prompt for -information, for example a password, and to verify a password (i.e. having -the user enter it twice and check that the same string was entered twice). -UI_add_verify_string() takes and extra argument that should be a pointer -to the result buffer of the input string that it's supposed to verify, or -verification will fail. +sizes of the result, not counting the final NUL character. The given +information is used to prompt for information, for example a password, +and to verify a password (i.e. having the user enter it twice and check +that the same string was entered twice). UI_add_verify_string() takes +and extra argument that should be a pointer to the result buffer of the +input string that it's supposed to verify, or verification will fail. UI_add_input_boolean() adds a prompt to the UI that's supposed to be answered in a boolean way, with a single character for yes and a different character diff --git a/crypto/openssl/engines/ccgost/gost2001.c b/crypto/openssl/engines/ccgost/gost2001.c index 9536295..881d0d3 100644 --- a/crypto/openssl/engines/ccgost/gost2001.c +++ b/crypto/openssl/engines/ccgost/gost2001.c @@ -434,8 +434,16 @@ int gost2001_compute_public(EC_KEY *ec) int gost2001_keygen(EC_KEY *ec) { BIGNUM *order = BN_new(), *d = BN_new(); - const EC_GROUP *group = EC_KEY_get0_group(ec); + const EC_GROUP *group = NULL; + + if (order == NULL || d == NULL) { + GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_MALLOC_FAILURE); + BN_free(d); + BN_free(order); + return 0; + } + group = EC_KEY_get0_group(ec); if(!group || !EC_GROUP_get_order(group, order, NULL)) { GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); BN_free(d); diff --git a/crypto/openssl/engines/ccgost/gost2001_keyx.c b/crypto/openssl/engines/ccgost/gost2001_keyx.c index db1bdc1..ac7862e 100644 --- a/crypto/openssl/engines/ccgost/gost2001_keyx.c +++ b/crypto/openssl/engines/ccgost/gost2001_keyx.c @@ -147,6 +147,8 @@ int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, key_is_ephemeral = 1; if (out) { sec_key = EVP_PKEY_new(); + if (sec_key == NULL) + goto err; EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); EVP_PKEY_copy_parameters(sec_key, pubk); if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) { diff --git a/crypto/openssl/engines/ccgost/gost94_keyx.c b/crypto/openssl/engines/ccgost/gost94_keyx.c index ce57f17..3532bff 100644 --- a/crypto/openssl/engines/ccgost/gost94_keyx.c +++ b/crypto/openssl/engines/ccgost/gost94_keyx.c @@ -126,6 +126,8 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, key_is_ephemeral = 1; if (out) { mykey = EVP_PKEY_new(); + if (!mykey) + goto memerr; EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk), DSA_new()); EVP_PKEY_copy_parameters(mykey, pubk); if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) { diff --git a/crypto/openssl/engines/ccgost/gost_ameth.c b/crypto/openssl/engines/ccgost/gost_ameth.c index b7c5354..8283f19 100644 --- a/crypto/openssl/engines/ccgost/gost_ameth.c +++ b/crypto/openssl/engines/ccgost/gost_ameth.c @@ -617,6 +617,10 @@ static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) return 0; } databuf = OPENSSL_malloc(octet->length); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); + return 0; + } for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { databuf[j] = octet->data[i]; } @@ -646,6 +650,8 @@ static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) } data_len = BN_num_bytes(dsa->pub_key); databuf = OPENSSL_malloc(data_len); + if (databuf == NULL) + return 0; BN_bn2bin(dsa->pub_key, databuf); octet = ASN1_OCTET_STRING_new(); ASN1_STRING_set(octet, NULL, data_len); @@ -686,6 +692,10 @@ static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) return 0; } databuf = OPENSSL_malloc(octet->length); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { databuf[j] = octet->data[i]; } @@ -760,6 +770,10 @@ static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) data_len = 2 * BN_num_bytes(order); BN_free(order); databuf = OPENSSL_malloc(data_len); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } memset(databuf, 0, data_len); store_bignum(X, databuf + data_len / 2, data_len / 2); diff --git a/crypto/openssl/engines/ccgost/gost_pmeth.c b/crypto/openssl/engines/ccgost/gost_pmeth.c index 4a79a85..6968292 100644 --- a/crypto/openssl/engines/ccgost/gost_pmeth.c +++ b/crypto/openssl/engines/ccgost/gost_pmeth.c @@ -107,6 +107,8 @@ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_SET_IV: pctx->shared_ukm = OPENSSL_malloc((int)p1); + if (pctx->shared_ukm == NULL) + return 0; memcpy(pctx->shared_ukm, p2, (int)p1); return 1; case EVP_PKEY_CTRL_PEER_KEY: @@ -533,6 +535,8 @@ static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return 0; } keydata = OPENSSL_malloc(32); + if (keydata == NULL) + return 0; memcpy(keydata, data->key, 32); EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); return 1; diff --git a/crypto/openssl/engines/e_4758cca.c b/crypto/openssl/engines/e_4758cca.c index 5f77198..60ba4ab 100644 --- a/crypto/openssl/engines/e_4758cca.c +++ b/crypto/openssl/engines/e_4758cca.c @@ -463,6 +463,10 @@ static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, (*(long *)keyToken) = keyTokenLength; rtmp = RSA_new_method(e); + if (rtmp == NULL) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); @@ -535,6 +539,10 @@ static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, (*(long *)keyToken) = keyTokenLength; rtmp = RSA_new_method(e); + if (rtmp == NULL) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); + goto err; + } RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); diff --git a/crypto/openssl/engines/e_aep.c b/crypto/openssl/engines/e_aep.c index 9bfda76..4e97d29 100644 --- a/crypto/openssl/engines/e_aep.c +++ b/crypto/openssl/engines/e_aep.c @@ -1137,7 +1137,8 @@ static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize, /* * Expand the result bn so that it can hold our big num. Size is in bits */ - bn_expand(bn, (int)(BigNumSize << 3)); + if (bn_expand(bn, (int)(BigNumSize << 3)) == NULL) + return AEP_R_HOST_MEMORY; # ifdef SIXTY_FOUR_BIT_LONG bn->top = BigNumSize >> 3; diff --git a/crypto/openssl/engines/e_capi.c b/crypto/openssl/engines/e_capi.c index 6e52463..8c08872 100644 --- a/crypto/openssl/engines/e_capi.c +++ b/crypto/openssl/engines/e_capi.c @@ -1106,6 +1106,10 @@ static int capi_get_provname(CAPI_CTX * ctx, LPSTR * pname, DWORD * ptype, name = alloca(len); else name = OPENSSL_malloc(len); + if (name == NULL) { + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, ERR_R_MALLOC_FAILURE); + return 0; + } if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { err = GetLastError(); if (err == ERROR_NO_MORE_ITEMS) @@ -1286,6 +1290,10 @@ char *capi_cert_get_fname(CAPI_CTX * ctx, PCCERT_CONTEXT cert) (cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) return NULL; wfname = OPENSSL_malloc(dlen); + if (wfname == NULL) { + CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, ERR_R_MALLOC_FAILURE); + return NULL; + } if (CertGetCertificateContextProperty (cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) { char *fname = wide_to_asc(wfname); @@ -1436,6 +1444,11 @@ static CAPI_KEY *capi_get_key(CAPI_CTX * ctx, const TCHAR *contname, CAPI_KEY *key; DWORD dwFlags = 0; key = OPENSSL_malloc(sizeof(CAPI_KEY)); + if (key == NULL) { + CAPIerr(CAPI_F_CAPI_GET_KEY, ERR_R_MALLOC_FAILURE); + capi_addlasterror(); + goto err; + } if (sizeof(TCHAR) == sizeof(char)) CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", contname, provname, ptype); diff --git a/crypto/openssl/engines/e_chil.c b/crypto/openssl/engines/e_chil.c index 5dfab51..d5e4cb6 100644 --- a/crypto/openssl/engines/e_chil.c +++ b/crypto/openssl/engines/e_chil.c @@ -810,9 +810,17 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, # endif # ifndef OPENSSL_NO_RSA rtmp = RSA_new_method(eng); + if (rtmp == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); rtmp->e = BN_new(); rtmp->n = BN_new(); + if (rtmp->e == NULL || rtmp->n == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } rtmp->flags |= RSA_FLAG_EXT_PKEY; MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); @@ -823,8 +831,14 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, goto err; } - bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)); - bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)); + if (bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)) == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)) == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); @@ -923,7 +937,10 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, goto err; } /* Prepare the params */ - bn_expand2(r, m->top); /* Check for error !! */ + if (bn_expand2(r, m->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } BN2MPI(m_a, a); BN2MPI(m_p, p); BN2MPI(m_n, m); @@ -989,7 +1006,10 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, } /* Prepare the params */ - bn_expand2(r, rsa->n->top); /* Check for error !! */ + if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } BN2MPI(m_a, I); MPI2BN(r, m_r); @@ -1026,7 +1046,10 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, } /* Prepare the params */ - bn_expand2(r, rsa->n->top); /* Check for error !! */ + if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } BN2MPI(m_a, I); BN2MPI(m_p, rsa->p); BN2MPI(m_q, rsa->q); @@ -1272,7 +1295,7 @@ static int hwcrhk_insert_card(const char *prompt_info, ui = UI_new_method(ui_method); if (ui) { - char answer; + char answer = '\0'; char buf[BUFSIZ]; /* * Despite what the documentation says wrong_info can be an empty diff --git a/crypto/openssl/ssl/Makefile b/crypto/openssl/ssl/Makefile index b6dee5b..dd12962 100644 --- a/crypto/openssl/ssl/Makefile +++ b/crypto/openssl/ssl/Makefile @@ -15,7 +15,7 @@ KRB5_INCLUDES= CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile README ssl-lib.com install.com -TEST=ssltest.c heartbeat_test.c clienthellotest.c sslv2conftest.c +TEST=ssltest.c heartbeat_test.c clienthellotest.c sslv2conftest.c dtlstest.c bad_dtls_test.c APPS= LIB=$(TOP)/libssl.a diff --git a/crypto/openssl/ssl/bad_dtls_test.c b/crypto/openssl/ssl/bad_dtls_test.c new file mode 100644 index 0000000..d42817fc --- /dev/null +++ b/crypto/openssl/ssl/bad_dtls_test.c @@ -0,0 +1,923 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Unit test for Cisco DTLS1_BAD_VER session resume, as used by + * AnyConnect VPN protocol. + * + * This is designed to exercise the code paths in + * http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/dtls.c + * which have frequently been affected by regressions in DTLS1_BAD_VER + * support. + * + * Note that unlike other SSL tests, we don't test against our own SSL + * server method. Firstly because we don't have one; we *only* support + * DTLS1_BAD_VER as a client. And secondly because even if that were + * fixed up it's the wrong thing to test against — because if changes + * are made in generic DTLS code which don't take DTLS1_BAD_VER into + * account, there's plenty of scope for making those changes such that + * they break *both* the client and the server in the same way. + * + * So we handle the server side manually. In a session resume there isn't + * much to be done anyway. + */ +#include <string.h> + +/* On Windows this will include <winsock2.h> and thus it needs to be + * included *before* anything that includes <windows.h>. Ick. */ +#include "e_os.h" /* for 'inline' */ + +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/evp.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/rand.h> + +/* PACKET functions lifted from OpenSSL 1.1's ssl/packet_locl.h */ +typedef struct { + /* Pointer to where we are currently reading from */ + const unsigned char *curr; + /* Number of bytes remaining */ + size_t remaining; +} PACKET; + +/* Internal unchecked shorthand; don't use outside this file. */ +static inline void packet_forward(PACKET *pkt, size_t len) +{ + pkt->curr += len; + pkt->remaining -= len; +} + +/* + * Returns the number of bytes remaining to be read in the PACKET + */ +static inline size_t PACKET_remaining(const PACKET *pkt) +{ + return pkt->remaining; +} + +/* + * Initialise a PACKET with |len| bytes held in |buf|. This does not make a + * copy of the data so |buf| must be present for the whole time that the PACKET + * is being used. + */ +static inline int PACKET_buf_init(PACKET *pkt, + const unsigned char *buf, + size_t len) +{ + /* Sanity check for negative values. */ + if (len > (size_t)65536) + return 0; + + pkt->curr = buf; + pkt->remaining = len; + return 1; +} + +/* + * Returns 1 if the packet has length |num| and its contents equal the |num| + * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal). + * If lengths are equal, performs the comparison in constant time. + */ +static inline int PACKET_equal(const PACKET *pkt, const void *ptr, + size_t num) +{ + if (PACKET_remaining(pkt) != num) + return 0; + return CRYPTO_memcmp(pkt->curr, ptr, num) == 0; +} + +/* + * Peek ahead at 2 bytes in network order from |pkt| and store the value in + * |*data| + */ +static inline int PACKET_peek_net_2(const PACKET *pkt, + unsigned int *data) +{ + if (PACKET_remaining(pkt) < 2) + return 0; + + *data = ((unsigned int)(*pkt->curr)) << 8; + *data |= *(pkt->curr + 1); + + return 1; +} + +/* Equivalent of n2s */ +/* Get 2 bytes in network order from |pkt| and store the value in |*data| */ +static inline int PACKET_get_net_2(PACKET *pkt, + unsigned int *data) +{ + if (!PACKET_peek_net_2(pkt, data)) + return 0; + + packet_forward(pkt, 2); + + return 1; +} + +/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */ +static inline int PACKET_peek_1(const PACKET *pkt, + unsigned int *data) +{ + if (!PACKET_remaining(pkt)) + return 0; + + *data = *pkt->curr; + + return 1; +} + +/* Get 1 byte from |pkt| and store the value in |*data| */ +static inline int PACKET_get_1(PACKET *pkt, unsigned int *data) +{ + if (!PACKET_peek_1(pkt, data)) + return 0; + + packet_forward(pkt, 1); + + return 1; +} + +/* + * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in + * |*data|. This just points at the underlying buffer that |pkt| is using. The + * caller should not free this data directly (it will be freed when the + * underlying buffer gets freed + */ +static inline int PACKET_peek_bytes(const PACKET *pkt, + const unsigned char **data, + size_t len) +{ + if (PACKET_remaining(pkt) < len) + return 0; + + *data = pkt->curr; + + return 1; +} + +/* + * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This + * just points at the underlying buffer that |pkt| is using. The caller should + * not free this data directly (it will be freed when the underlying buffer gets + * freed + */ +static inline int PACKET_get_bytes(PACKET *pkt, + const unsigned char **data, + size_t len) +{ + if (!PACKET_peek_bytes(pkt, data, len)) + return 0; + + packet_forward(pkt, len); + + return 1; +} + +/* Peek ahead at |len| bytes from |pkt| and copy them to |data| */ +static inline int PACKET_peek_copy_bytes(const PACKET *pkt, + unsigned char *data, + size_t len) +{ + if (PACKET_remaining(pkt) < len) + return 0; + + memcpy(data, pkt->curr, len); + + return 1; +} + +/* + * Read |len| bytes from |pkt| and copy them to |data|. + * The caller is responsible for ensuring that |data| can hold |len| bytes. + */ +static inline int PACKET_copy_bytes(PACKET *pkt, + unsigned char *data, + size_t len) +{ + if (!PACKET_peek_copy_bytes(pkt, data, len)) + return 0; + + packet_forward(pkt, len); + + return 1; +} + + +/* Move the current reading position forward |len| bytes */ +static inline int PACKET_forward(PACKET *pkt, size_t len) +{ + if (PACKET_remaining(pkt) < len) + return 0; + + packet_forward(pkt, len); + + return 1; +} + +/* + * Reads a variable-length vector prefixed with a one-byte length, and stores + * the contents in |subpkt|. |pkt| can equal |subpkt|. + * Data is not copied: the |subpkt| packet will share its underlying buffer with + * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. + * Upon failure, the original |pkt| and |subpkt| are not modified. + */ +static inline int PACKET_get_length_prefixed_1(PACKET *pkt, + PACKET *subpkt) +{ + unsigned int length; + const unsigned char *data; + PACKET tmp = *pkt; + if (!PACKET_get_1(&tmp, &length) || + !PACKET_get_bytes(&tmp, &data, (size_t)length)) { + return 0; + } + + *pkt = tmp; + subpkt->curr = data; + subpkt->remaining = length; + + return 1; +} + +#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0])) + +/* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */ +#define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH) + +static unsigned char client_random[SSL3_RANDOM_SIZE]; +static unsigned char server_random[SSL3_RANDOM_SIZE]; + +/* These are all generated locally, sized purely according to our own whim */ +static unsigned char session_id[32]; +static unsigned char master_secret[48]; +static unsigned char cookie[20]; + +/* We've hard-coded the cipher suite; we know it's 104 bytes */ +static unsigned char key_block[104]; +#define mac_key (key_block + 20) +#define dec_key (key_block + 40) +#define enc_key (key_block + 56) + +static EVP_MD_CTX handshake_md5; +static EVP_MD_CTX handshake_sha1; + +/* PRF lifted from ssl/t1_enc.c since we can't easily use it directly */ +static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, + int sec_len, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + unsigned char *out, int olen) +{ + int chunk; + size_t j; + EVP_MD_CTX ctx, ctx_tmp, ctx_init; + EVP_PKEY *prf_mac_key; + unsigned char A1[EVP_MAX_MD_SIZE]; + size_t A1_len; + int ret = 0; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_init(&ctx_tmp); + EVP_MD_CTX_init(&ctx_init); + EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + prf_mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + if (!prf_mac_key) + goto err; + if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, prf_mac_key)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + + for (;;) { + /* Reinit mac contexts */ + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) + goto err; + if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + + if (olen > chunk) { + if (!EVP_DigestSignFinal(&ctx, out, &j)) + goto err; + out += j; + olen -= j; + /* calc the next A1 value */ + if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) + goto err; + } else { /* last one */ + + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + memcpy(out, A1, olen); + break; + } + } + ret = 1; + err: + EVP_PKEY_free(prf_mac_key); + EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_cleanup(&ctx_tmp); + EVP_MD_CTX_cleanup(&ctx_init); + OPENSSL_cleanse(A1, sizeof(A1)); + return ret; +} + +/* seed1 through seed5 are virtually concatenated */ +static int do_PRF(const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + unsigned char *out, int olen) +{ + unsigned char out2[104]; + int i, len; + + if (olen > (int)sizeof(out2)) + return 0; + + len = sizeof(master_secret) / 2; + + if (!tls1_P_hash(EVP_md5(), master_secret, len, + seed1, seed1_len, seed2, seed2_len, seed3, + seed3_len, out, olen)) + return 0; + + if (!tls1_P_hash(EVP_sha1(), master_secret + len, len, + seed1, seed1_len, seed2, seed2_len, seed3, + seed3_len, out2, olen)) + return 0; + + for (i = 0; i < olen; i++) { + out[i] ^= out2[i]; + } + + return 1; +} + +static SSL_SESSION *client_session(void) +{ + static unsigned char session_asn1[] = { + 0x30, 0x5F, /* SEQUENCE, length 0x5F */ + 0x02, 0x01, 0x01, /* INTEGER, SSL_SESSION_ASN1_VERSION */ + 0x02, 0x02, 0x01, 0x00, /* INTEGER, DTLS1_BAD_VER */ + 0x04, 0x02, 0x00, 0x2F, /* OCTET_STRING, AES128-SHA */ + 0x04, 0x20, /* OCTET_STRING, session id */ +#define SS_SESSID_OFS 15 /* Session ID goes here */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x30, /* OCTET_STRING, master secret */ +#define SS_SECRET_OFS 49 /* Master secret goes here */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + const unsigned char *p = session_asn1; + + /* Copy the randomly-generated fields into the above ASN1 */ + memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id)); + memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret)); + + return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1)); +} + +/* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */ +static int validate_client_hello(BIO *wbio) +{ + PACKET pkt, pkt2; + long len; + unsigned char *data; + int cookie_found = 0; + unsigned int u; + + len = BIO_get_mem_data(wbio, (char **)&data); + if (!PACKET_buf_init(&pkt, data, len)) + return 0; + + /* Check record header type */ + if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE) + return 0; + /* Version */ + if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER) + return 0; + /* Skip the rest of the record header */ + if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3)) + return 0; + + /* Check it's a ClientHello */ + if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO) + return 0; + /* Skip the rest of the handshake message header */ + if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1)) + return 0; + + /* Check client version */ + if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER) + return 0; + + /* Store random */ + if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE)) + return 0; + + /* Check session id length and content */ + if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) || + !PACKET_equal(&pkt2, session_id, sizeof(session_id))) + return 0; + + /* Check cookie */ + if (!PACKET_get_length_prefixed_1(&pkt, &pkt2)) + return 0; + if (PACKET_remaining(&pkt2)) { + if (!PACKET_equal(&pkt2, cookie, sizeof(cookie))) + return 0; + cookie_found = 1; + } + + /* Skip ciphers */ + if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u)) + return 0; + + /* Skip compression */ + if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u)) + return 0; + + /* Skip extensions */ + if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u)) + return 0; + + /* Now we are at the end */ + if (PACKET_remaining(&pkt)) + return 0; + + /* Update handshake MAC for second ClientHello (with cookie) */ + if (cookie_found && (!EVP_DigestUpdate(&handshake_md5, data + MAC_OFFSET, + len - MAC_OFFSET) || + !EVP_DigestUpdate(&handshake_sha1, data + MAC_OFFSET, + len - MAC_OFFSET))) + printf("EVP_DigestUpdate() failed\n"); + + (void)BIO_reset(wbio); + + return 1 + cookie_found; +} + +static int send_hello_verify(BIO *rbio) +{ + static unsigned char hello_verify[] = { + 0x16, /* Handshake */ + 0x01, 0x00, /* DTLS1_BAD_VER */ + 0x00, 0x00, /* Epoch 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */ + 0x00, 0x23, /* Length */ + 0x03, /* Hello Verify */ + 0x00, 0x00, 0x17, /* Length */ + 0x00, 0x00, /* Seq# 0 */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x17, /* Fragment length */ + 0x01, 0x00, /* DTLS1_BAD_VER */ + 0x14, /* Cookie length */ +#define HV_COOKIE_OFS 28 /* Cookie goes here */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie)); + + BIO_write(rbio, hello_verify, sizeof(hello_verify)); + + return 1; +} + +static int send_server_hello(BIO *rbio) +{ + static unsigned char server_hello[] = { + 0x16, /* Handshake */ + 0x01, 0x00, /* DTLS1_BAD_VER */ + 0x00, 0x00, /* Epoch 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */ + 0x00, 0x52, /* Length */ + 0x02, /* Server Hello */ + 0x00, 0x00, 0x46, /* Length */ + 0x00, 0x01, /* Seq# */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x46, /* Fragment length */ + 0x01, 0x00, /* DTLS1_BAD_VER */ +#define SH_RANDOM_OFS 27 /* Server random goes here */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, /* Session ID length */ +#define SH_SESSID_OFS 60 /* Session ID goes here */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2f, /* Cipher suite AES128-SHA */ + 0x00, /* Compression null */ + }; + static unsigned char change_cipher_spec[] = { + 0x14, /* Change Cipher Spec */ + 0x01, 0x00, /* DTLS1_BAD_VER */ + 0x00, 0x00, /* Epoch 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */ + 0x00, 0x03, /* Length */ + 0x01, 0x00, 0x02, /* Message */ + }; + + memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random)); + memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id)); + + if (!EVP_DigestUpdate(&handshake_md5, server_hello + MAC_OFFSET, + sizeof(server_hello) - MAC_OFFSET) || + !EVP_DigestUpdate(&handshake_sha1, server_hello + MAC_OFFSET, + sizeof(server_hello) - MAC_OFFSET)) + printf("EVP_DigestUpdate() failed\n"); + + BIO_write(rbio, server_hello, sizeof(server_hello)); + BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec)); + + return 1; +} + +/* Create header, HMAC, pad, encrypt and send a record */ +static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr, + const void *msg, size_t len) +{ + /* Note that the order of the record header fields on the wire, + * and in the HMAC, is different. So we just keep them in separate + * variables and handle them individually. */ + static unsigned char epoch[2] = { 0x00, 0x01 }; + static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */ + unsigned char lenbytes[2]; + HMAC_CTX ctx; + EVP_CIPHER_CTX enc_ctx; + unsigned char iv[16]; + unsigned char pad; + unsigned char *enc; + +#ifdef SIXTY_FOUR_BIT_LONG + seq[0] = (seqnr >> 40) & 0xff; + seq[1] = (seqnr >> 32) & 0xff; +#endif + seq[2] = (seqnr >> 24) & 0xff; + seq[3] = (seqnr >> 16) & 0xff; + seq[4] = (seqnr >> 8) & 0xff; + seq[5] = seqnr & 0xff; + + pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16); + enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad); + if (enc == NULL) + return 0; + + /* Copy record to encryption buffer */ + memcpy(enc, msg, len); + + /* Append HMAC to data */ + HMAC_Init(&ctx, mac_key, 20, EVP_sha1()); + HMAC_Update(&ctx, epoch, 2); + HMAC_Update(&ctx, seq, 6); + HMAC_Update(&ctx, &type, 1); + HMAC_Update(&ctx, ver, 2); /* Version */ + lenbytes[0] = len >> 8; + lenbytes[1] = len & 0xff; + HMAC_Update(&ctx, lenbytes, 2); /* Length */ + HMAC_Update(&ctx, enc, len); /* Finally the data itself */ + HMAC_Final(&ctx, enc + len, NULL); + HMAC_CTX_cleanup(&ctx); + + /* Append padding bytes */ + len += SHA_DIGEST_LENGTH; + do { + enc[len++] = pad; + } while (len % 16); + + /* Generate IV, and encrypt */ + RAND_bytes(iv, sizeof(iv)); + EVP_CIPHER_CTX_init(&enc_ctx); + EVP_CipherInit_ex(&enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1); + EVP_Cipher(&enc_ctx, enc, enc, len); + EVP_CIPHER_CTX_cleanup(&enc_ctx); + + /* Finally write header (from fragmented variables), IV and encrypted record */ + BIO_write(rbio, &type, 1); + BIO_write(rbio, ver, 2); + BIO_write(rbio, epoch, 2); + BIO_write(rbio, seq, 6); + lenbytes[0] = (len + sizeof(iv)) >> 8; + lenbytes[1] = (len + sizeof(iv)) & 0xff; + BIO_write(rbio, lenbytes, 2); + + BIO_write(rbio, iv, sizeof(iv)); + BIO_write(rbio, enc, len); + + OPENSSL_free(enc); + return 1; +} + +static int send_finished(SSL *s, BIO *rbio) +{ + static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH + + TLS1_FINISH_MAC_LENGTH] = { + 0x14, /* Finished */ + 0x00, 0x00, 0x0c, /* Length */ + 0x00, 0x03, /* Seq# 3 */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x0c, /* Fragment length */ + /* Finished MAC (12 bytes) */ + }; + unsigned char handshake_hash[EVP_MAX_MD_SIZE * 2]; + + /* Derive key material */ + do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, + server_random, SSL3_RANDOM_SIZE, + client_random, SSL3_RANDOM_SIZE, + key_block, sizeof(key_block)); + + /* Generate Finished MAC */ + if (!EVP_DigestFinal_ex(&handshake_md5, handshake_hash, NULL) || + !EVP_DigestFinal_ex(&handshake_sha1, handshake_hash + EVP_MD_CTX_size(&handshake_md5), NULL)) + printf("EVP_DigestFinal_ex() failed\n"); + + do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + handshake_hash, EVP_MD_CTX_size(&handshake_md5) + EVP_MD_CTX_size(&handshake_sha1), + NULL, 0, + finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH); + + return send_record(rbio, SSL3_RT_HANDSHAKE, 0, + finished_msg, sizeof(finished_msg)); +} + +static int validate_ccs(BIO *wbio) +{ + PACKET pkt; + long len; + unsigned char *data; + unsigned int u; + + len = BIO_get_mem_data(wbio, (char **)&data); + if (!PACKET_buf_init(&pkt, data, len)) + return 0; + + /* Check record header type */ + if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC) + return 0; + /* Version */ + if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER) + return 0; + /* Skip the rest of the record header */ + if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3)) + return 0; + + /* Check ChangeCipherSpec message */ + if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS) + return 0; + /* A DTLS1_BAD_VER ChangeCipherSpec also contains the + * handshake sequence number (which is 2 here) */ + if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002) + return 0; + + /* Now check the Finished packet */ + if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE) + return 0; + if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER) + return 0; + + /* Check epoch is now 1 */ + if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001) + return 0; + + /* That'll do for now. If OpenSSL accepted *our* Finished packet + * then it's evidently remembered that DTLS1_BAD_VER doesn't + * include the handshake header in the MAC. There's not a lot of + * point in implementing decryption here, just to check that it + * continues to get it right for one more packet. */ + + return 1; +} + +#define NODROP(x) { x##UL, 0 } +#define DROP(x) { x##UL, 1 } + +static struct { + unsigned long seq; + int drop; +} tests[] = { + NODROP(1), NODROP(3), NODROP(2), + NODROP(0x1234), NODROP(0x1230), NODROP(0x1235), + NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000), + DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1), + NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010), + NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012), + NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001), + NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff), + NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000) + /* The last test should be NODROP, because a DROP wouldn't get tested. */ +}; + +int main(int argc, char *argv[]) +{ + SSL_SESSION *sess; + SSL_CTX *ctx; + SSL *con; + BIO *rbio; + BIO *wbio; + BIO *err; + int testresult = 0; + int ret; + int i; + + SSL_library_init(); + SSL_load_error_strings(); + + err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + RAND_bytes(session_id, sizeof(session_id)); + RAND_bytes(master_secret, sizeof(master_secret)); + RAND_bytes(cookie, sizeof(cookie)); + RAND_bytes(server_random + 4, sizeof(server_random) - 4); + time((void *)server_random); + + sess = client_session(); + if (sess == NULL) { + printf("Failed to generate SSL_SESSION\n"); + goto end; + } + + if (!EVP_DigestInit_ex(&handshake_md5, EVP_md5(), NULL) || + !EVP_DigestInit_ex(&handshake_sha1, EVP_sha1(), NULL)) { + printf("Failed to initialise handshake_md\n"); + goto end; + } + + ctx = SSL_CTX_new(DTLSv1_client_method()); + if (ctx == NULL) { + printf("Failed to allocate SSL_CTX\n"); + goto end_md; + } + SSL_CTX_set_options(ctx, SSL_OP_CISCO_ANYCONNECT); + + if (!SSL_CTX_set_cipher_list(ctx, "AES128-SHA")) { + printf("SSL_CTX_set_cipher_list() failed\n"); + goto end_ctx; + } + + con = SSL_new(ctx); + if (!SSL_set_session(con, sess)) { + printf("SSL_set_session() failed\n"); + goto end_con; + } + SSL_SESSION_free(sess); + + rbio = BIO_new(BIO_s_mem()); + wbio = BIO_new(BIO_s_mem()); + + BIO_set_nbio(rbio, 1); + BIO_set_nbio(wbio, 1); + + SSL_set_bio(con, rbio, wbio); + SSL_set_connect_state(con); + + /* Send initial ClientHello */ + ret = SSL_do_handshake(con); + if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) { + printf("Unexpected handshake result at initial call!\n"); + goto end_con; + } + + if (validate_client_hello(wbio) != 1) { + printf("Initial ClientHello failed validation\n"); + goto end_con; + } + if (send_hello_verify(rbio) != 1) { + printf("Failed to send HelloVerify\n"); + goto end_con; + } + ret = SSL_do_handshake(con); + if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) { + printf("Unexpected handshake result after HelloVerify!\n"); + goto end_con; + } + if (validate_client_hello(wbio) != 2) { + printf("Second ClientHello failed validation\n"); + goto end_con; + } + if (send_server_hello(rbio) != 1) { + printf("Failed to send ServerHello\n"); + goto end_con; + } + ret = SSL_do_handshake(con); + if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) { + printf("Unexpected handshake result after ServerHello!\n"); + goto end_con; + } + if (send_finished(con, rbio) != 1) { + printf("Failed to send Finished\n"); + goto end_con; + } + ret = SSL_do_handshake(con); + if (ret < 1) { + printf("Handshake not successful after Finished!\n"); + goto end_con; + } + if (validate_ccs(wbio) != 1) { + printf("Failed to validate client CCS/Finished\n"); + goto end_con; + } + + /* While we're here and crafting packets by hand, we might as well do a + bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS + specific but useful anyway for the general case. It's been broken + before, and in fact was broken even for a basic 0, 2, 1 test case + when this test was first added.... */ + for (i = 0; i < (int)OSSL_NELEM(tests); i++) { + unsigned long recv_buf[2]; + + if (send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq, + &tests[i].seq, sizeof(unsigned long)) != 1) { + printf("Failed to send data seq #0x%lx (%d)\n", + tests[i].seq, i); + goto end_con; + } + + if (tests[i].drop) + continue; + + ret = SSL_read(con, recv_buf, 2 * sizeof(unsigned long)); + if (ret != sizeof(unsigned long)) { + printf("SSL_read failed or wrong size on seq#0x%lx (%d)\n", + tests[i].seq, i); + goto end_con; + } + if (recv_buf[0] != tests[i].seq) { + printf("Wrong data packet received (0x%lx not 0x%lx) at packet %d\n", + recv_buf[0], tests[i].seq, i); + goto end_con; + } + } + if (tests[i-1].drop) { + printf("Error: last test cannot be DROP()\n"); + goto end_con; + } + testresult=1; + + end_con: + SSL_free(con); + end_ctx: + SSL_CTX_free(ctx); + end_md: + EVP_MD_CTX_cleanup(&handshake_md5); + EVP_MD_CTX_cleanup(&handshake_sha1); + end: + ERR_print_errors_fp(stderr); + + if (!testresult) { + printf("Cisco BadDTLS test: FAILED\n"); + } + + ERR_free_strings(); + ERR_remove_thread_state(NULL); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + CRYPTO_mem_leaks(err); + BIO_free(err); + + return testresult?0:1; +} diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c index 5d26c94..9bc6153 100644 --- a/crypto/openssl/ssl/d1_both.c +++ b/crypto/openssl/ssl/d1_both.c @@ -581,9 +581,12 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, /* * msg_len is limited to 2^24, but is effectively checked against max * above + * + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 */ if (!BUF_MEM_grow_clean - (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { + (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); return SSL_AD_INTERNAL_ERROR; } @@ -618,11 +621,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) int al; *ok = 0; - item = pqueue_peek(s->d1->buffered_messages); - if (item == NULL) - return 0; + do { + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + if (frag->msg_header.seq < s->d1->handshake_read_seq) { + /* This is a stale message that has been buffered so clear it */ + pqueue_pop(s->d1->buffered_messages); + dtls1_hm_fragment_free(frag); + pitem_free(item); + item = NULL; + frag = NULL; + } + } while (item == NULL); - frag = (hm_fragment *)item->data; /* Don't return if reassembly still in progress */ if (frag->reassembly != NULL) @@ -1211,7 +1226,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, unsigned long header_length; unsigned char seq64be[8]; struct dtls1_retransmit_state saved_state; - unsigned char save_write_sequence[8]; + unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0}; /*- OPENSSL_assert(s->init_num == 0); @@ -1296,18 +1311,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, return ret; } -/* call this function when the buffered messages are no longer needed */ -void dtls1_clear_record_buffer(SSL *s) -{ - pitem *item; - - for (item = pqueue_pop(s->d1->sent_messages); - item != NULL; item = pqueue_pop(s->d1->sent_messages)) { - dtls1_hm_fragment_free((hm_fragment *)item->data); - pitem_free(item); - } -} - unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, unsigned long len, unsigned long frag_off, @@ -1469,7 +1472,7 @@ int dtls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -1546,6 +1549,8 @@ int dtls1_heartbeat(SSL *s) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + goto err; p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; @@ -1554,11 +1559,11 @@ int dtls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) + if (RAND_bytes(p, 16) <= 0) goto err; p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) + if (RAND_bytes(p, padding) <= 0) goto err; ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c index 3ddfa7b..7e2f5c2 100644 --- a/crypto/openssl/ssl/d1_clnt.c +++ b/crypto/openssl/ssl/d1_clnt.c @@ -769,6 +769,7 @@ int dtls1_connect(SSL *s) /* done with handshaking */ s->d1->handshake_read_seq = 0; s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); goto end; /* break; */ diff --git a/crypto/openssl/ssl/d1_lib.c b/crypto/openssl/ssl/d1_lib.c index ee78921..debd4fd 100644 --- a/crypto/openssl/ssl/d1_lib.c +++ b/crypto/openssl/ssl/d1_lib.c @@ -170,7 +170,6 @@ int dtls1_new(SSL *s) static void dtls1_clear_queues(SSL *s) { pitem *item = NULL; - hm_fragment *frag = NULL; DTLS1_RECORD_DATA *rdata; while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { @@ -191,28 +190,44 @@ static void dtls1_clear_queues(SSL *s) pitem_free(item); } + while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + dtls1_clear_received_buffer(s); + dtls1_clear_sent_buffer(s); +} + +void dtls1_clear_received_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } +} + +void dtls1_clear_sent_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } - - while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } } + void dtls1_free(SSL *s) { ssl3_free(s); @@ -456,7 +471,7 @@ void dtls1_stop_timer(SSL *s) 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); + dtls1_clear_sent_buffer(s); } int dtls1_check_timeout_num(SSL *s) diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c index fe30ec7..7a02459 100644 --- a/crypto/openssl/ssl/d1_pkt.c +++ b/crypto/openssl/ssl/d1_pkt.c @@ -125,7 +125,7 @@ /* mod 128 saturating subtract of two 64-bit values in big-endian order */ static int satsub64be(const unsigned char *v1, const unsigned char *v2) { - int ret, sat, brw, i; + int ret, i; if (sizeof(long) == 8) do { @@ -157,28 +157,51 @@ static int satsub64be(const unsigned char *v1, const unsigned char *v2) return (int)l; } while (0); - ret = (int)v1[7] - (int)v2[7]; - sat = 0; - brw = ret >> 8; /* brw is either 0 or -1 */ - if (ret & 0x80) { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= ~brw; - brw >>= 8; - } - } else { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= brw; - brw >>= 8; + ret = 0; + for (i=0; i<7; i++) { + if (v1[i] > v2[i]) { + /* v1 is larger... but by how much? */ + if (v1[i] != v2[i] + 1) + return 128; + while (++i <= 6) { + if (v1[i] != 0x00 || v2[i] != 0xff) + return 128; /* too much */ + } + /* We checked all the way to the penultimate byte, + * so despite higher bytes changing we actually + * know that it only changed from (e.g.) + * ... (xx) ff ff ff ?? + * to ... (xx+1) 00 00 00 ?? + * so we add a 'bias' of 256 for the carry that + * happened, and will eventually return + * 256 + v1[7] - v2[7]. */ + ret = 256; + break; + } else if (v2[i] > v1[i]) { + /* v2 is larger... but by how much? */ + if (v2[i] != v1[i] + 1) + return -128; + while (++i <= 6) { + if (v2[i] != 0x00 || v1[i] != 0xff) + return -128; /* too much */ + } + /* Similar to the case above, we know it changed + * from ... (xx) 00 00 00 ?? + * to ... (xx-1) ff ff ff ?? + * so we add a 'bias' of -256 for the borrow, + * to return -256 + v1[7] - v2[7]. */ + ret = -256; } } - brw <<= 8; /* brw is either 0 or -256 */ - if (sat & 0xff) - return brw | 0x80; + ret += (int)v1[7] - (int)v2[7]; + + if (ret > 128) + return 128; + else if (ret < -128) + return -128; else - return brw + (ret & 0xFF); + return ret; } static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, @@ -194,7 +217,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, #endif static int dtls1_buffer_record(SSL *s, record_pqueue *q, unsigned char *priority); -static int dtls1_process_record(SSL *s); +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); /* copy buffered record into SSL structure */ static int dtls1_copy_record(SSL *s, pitem *item) @@ -319,21 +342,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) static int dtls1_process_buffered_records(SSL *s) { pitem *item; + SSL3_BUFFER *rb; + SSL3_RECORD *rr; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + int replayok = 1; item = pqueue_peek(s->d1->unprocessed_rcds.q); if (item) { /* Check if epoch is current. */ if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) - return (1); /* Nothing to do. */ + return 1; /* Nothing to do. */ + + rr = &s->s3->rrec; + rb = &s->s3->rbuf; + + if (rb->left > 0) { + /* + * We've still got data from the current packet to read. There could + * be a record from the new epoch in it - so don't overwrite it + * with the unprocessed records yet (we'll do it when we've + * finished reading the current packet). + */ + return 1; + } + /* Process all the records. */ while (pqueue_peek(s->d1->unprocessed_rcds.q)) { dtls1_get_unprocessed_record(s); - if (!dtls1_process_record(s)) - return (0); + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) { + /* + * Should not happen. This will only ever be NULL when the + * current record is from a different epoch. But that cannot + * be the case because we already checked the epoch above + */ + SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, + ERR_R_INTERNAL_ERROR); + return 0; + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) +#endif + { + /* + * Check whether this is a repeat, or aged record. We did this + * check once already when we first received the record - but + * we might have updated the window since then due to + * records we subsequently processed. + */ + replayok = dtls1_record_replay_check(s, bitmap); + } + + if (!replayok || !dtls1_process_record(s, bitmap)) { + /* dump this record */ + rr->length = 0; + s->packet_length = 0; + continue; + } + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), s->s3->rrec.seq_num) < 0) - return -1; + return 0; } } @@ -344,7 +416,7 @@ static int dtls1_process_buffered_records(SSL *s) s->d1->processed_rcds.epoch = s->d1->r_epoch; s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; - return (1); + return 1; } #if 0 @@ -391,7 +463,7 @@ static int dtls1_get_buffered_record(SSL *s) #endif -static int dtls1_process_record(SSL *s) +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) { int i, al; int enc_err; @@ -551,6 +623,10 @@ static int dtls1_process_record(SSL *s) /* we have pulled in a full packet so zero things */ s->packet_length = 0; + + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + return (1); f_err: @@ -581,11 +657,12 @@ int dtls1_get_record(SSL *s) rr = &(s->s3->rrec); + again: /* * The epoch may have changed. If so, process all the pending records. * This is a non-blocking operation. */ - if (dtls1_process_buffered_records(s) < 0) + if (!dtls1_process_buffered_records(s)) return -1; /* if we're renegotiating, then there may be buffered records */ @@ -593,7 +670,6 @@ int dtls1_get_record(SSL *s) return 1; /* get something from the wire */ - again: /* check if we have the header */ if ((s->rstate != SSL_ST_READ_BODY) || (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { @@ -721,20 +797,17 @@ int dtls1_get_record(SSL *s) if (dtls1_buffer_record (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) return -1; - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); } rr->length = 0; s->packet_length = 0; goto again; } - if (!dtls1_process_record(s)) { + if (!dtls1_process_record(s, bitmap)) { rr->length = 0; s->packet_length = 0; /* dump this record */ goto again; /* get another record */ } - dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ return (1); @@ -878,6 +951,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto start; } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1144,6 +1224,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { #ifndef OPENSSL_NO_SCTP /* @@ -1201,7 +1289,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -1830,8 +1918,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, if (rr->epoch == s->d1->r_epoch) return &s->d1->bitmap; - /* Only HM and ALERT messages can be from the next epoch */ + /* + * Only HM and ALERT messages can be from the next epoch and only if we + * have already processed all of the unprocessed records from the last + * epoch + */ else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && + s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { *is_next_epoch = 1; return &s->d1->next_bitmap; @@ -1910,6 +2003,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) s->d1->r_epoch++; memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + + /* + * We must not use any buffered messages received from the previous + * epoch + */ + dtls1_clear_received_buffer(s); } else { seq = s->s3->write_sequence; memcpy(s->d1->last_write_sequence, seq, diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c index e677d88..bc875b5 100644 --- a/crypto/openssl/ssl/d1_srvr.c +++ b/crypto/openssl/ssl/d1_srvr.c @@ -313,7 +313,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_HELLO_REQ_B: s->shutdown = 0; - dtls1_clear_record_buffer(s); + dtls1_clear_sent_buffer(s); dtls1_start_timer(s); ret = ssl3_send_hello_request(s); if (ret <= 0) @@ -894,6 +894,7 @@ int dtls1_accept(SSL *s) /* next message is server hello */ s->d1->handshake_write_seq = 0; s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); goto end; /* break; */ diff --git a/crypto/openssl/ssl/dtlstest.c b/crypto/openssl/ssl/dtlstest.c new file mode 100644 index 0000000..78ebc67 --- /dev/null +++ b/crypto/openssl/ssl/dtlstest.c @@ -0,0 +1,147 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/ssl.h> +#include <openssl/err.h> + +#include "ssltestlib.h" +#include "testutil.h" + +static char *cert = NULL; +static char *privkey = NULL; + +#define NUM_TESTS 2 + + +#define DUMMY_CERT_STATUS_LEN 12 + +unsigned char certstatus[] = { + SSL3_RT_HANDSHAKE, /* Content type */ + 0xfe, 0xfd, /* Record version */ + 0, 1, /* Epoch */ + 0, 0, 0, 0, 0, 0x0f, /* Record sequence number */ + 0, DTLS1_HM_HEADER_LENGTH + DUMMY_CERT_STATUS_LEN - 2, + SSL3_MT_CERTIFICATE_STATUS, /* Cert Status handshake message type */ + 0, 0, DUMMY_CERT_STATUS_LEN, /* Message len */ + 0, 5, /* Message sequence */ + 0, 0, 0, /* Fragment offset */ + 0, 0, DUMMY_CERT_STATUS_LEN - 2, /* Fragment len */ + 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80 /* Dummy data */ +}; + +#define RECORD_SEQUENCE 10 + +static int test_dtls_unprocessed(int testidx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl1 = NULL, *clientssl1 = NULL; + BIO *c_to_s_fbio, *c_to_s_mempacket; + int testresult = 0; + + printf("Starting Test %d\n", testidx); + + if (!create_ssl_ctx_pair(DTLS_server_method(), DTLS_client_method(), &sctx, + &cctx, cert, privkey)) { + printf("Unable to create SSL_CTX pair\n"); + return 0; + } + + if (!SSL_CTX_set_ecdh_auto(sctx, 1)) { + printf("Failed configuring auto ECDH\n"); + } + + if (!SSL_CTX_set_cipher_list(cctx, "AES128-SHA")) { + printf("Failed setting cipher list\n"); + } + + c_to_s_fbio = BIO_new(bio_f_tls_dump_filter()); + if (c_to_s_fbio == NULL) { + printf("Failed to create filter BIO\n"); + goto end; + } + + /* BIO is freed by create_ssl_connection on error */ + if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, + c_to_s_fbio)) { + printf("Unable to create SSL objects\n"); + ERR_print_errors_fp(stdout); + goto end; + } + + if (testidx == 1) + certstatus[RECORD_SEQUENCE] = 0xff; + + /* + * Inject a dummy record from the next epoch. In test 0, this should never + * get used because the message sequence number is too big. In test 1 we set + * the record sequence number to be way off in the future. This should not + * have an impact on the record replay protection because the record should + * be dropped before it is marked as arrivedg + */ + c_to_s_mempacket = SSL_get_wbio(clientssl1); + c_to_s_mempacket = BIO_next(c_to_s_mempacket); + mempacket_test_inject(c_to_s_mempacket, (char *)certstatus, + sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ); + + if (!create_ssl_connection(serverssl1, clientssl1)) { + printf("Unable to create SSL connection\n"); + ERR_print_errors_fp(stdout); + goto end; + } + + testresult = 1; + end: + SSL_free(serverssl1); + SSL_free(clientssl1); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +int main(int argc, char *argv[]) +{ + BIO *err = NULL; + int testresult = 0; + + if (argc != 3) { + printf("Invalid argument count\n"); + return 1; + } + + cert = argv[1]; + privkey = argv[2]; + + err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + + SSL_library_init(); + SSL_load_error_strings(); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + if (!test_dtls_unprocessed(0) || !test_dtls_unprocessed(1)) + testresult = 1; + + ERR_free_strings(); + ERR_remove_thread_state(NULL); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + CRYPTO_mem_leaks(err); + BIO_free(err); + + if (!testresult) + printf("PASS\n"); + + return testresult; +} diff --git a/crypto/openssl/ssl/s23_clnt.c b/crypto/openssl/ssl/s23_clnt.c index f782010..6850dc0 100644 --- a/crypto/openssl/ssl/s23_clnt.c +++ b/crypto/openssl/ssl/s23_clnt.c @@ -289,9 +289,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) unsigned long Time = (unsigned long)time(NULL); unsigned char *p = result; l2n(Time, p); - return RAND_pseudo_bytes(p, len - 4); + return RAND_bytes(p, len - 4); } else - return RAND_pseudo_bytes(result, len); + return RAND_bytes(result, len); } static int ssl23_client_hello(SSL *s) @@ -466,8 +466,8 @@ static int ssl23_client_hello(SSL *s) i = ch_len; s2n(i, d); memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); - if (RAND_pseudo_bytes - (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0) + if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) + <= 0) return -1; memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); diff --git a/crypto/openssl/ssl/s2_clnt.c b/crypto/openssl/ssl/s2_clnt.c index 69da6b1..20de1a8 100644 --- a/crypto/openssl/ssl/s2_clnt.c +++ b/crypto/openssl/ssl/s2_clnt.c @@ -581,7 +581,7 @@ static int client_hello(SSL *s) /* * challenge id data */ - if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) return -1; memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); d += SSL2_CHALLENGE_LENGTH; @@ -629,7 +629,7 @@ static int client_master_key(SSL *s) return -1; } if (i > 0) - if (RAND_pseudo_bytes(sess->key_arg, i) <= 0) + if (RAND_bytes(sess->key_arg, i) <= 0) return -1; /* make a master key */ diff --git a/crypto/openssl/ssl/s2_srvr.c b/crypto/openssl/ssl/s2_srvr.c index 07e9df8..d3b243c 100644 --- a/crypto/openssl/ssl/s2_srvr.c +++ b/crypto/openssl/ssl/s2_srvr.c @@ -526,11 +526,8 @@ static int get_client_master_key(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - (int)num_encrypted_key_bytes) <= 0) + if (RAND_bytes(rand_premaster_secret, + (int)num_encrypted_key_bytes) <= 0) return 0; i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, @@ -822,8 +819,7 @@ static int server_hello(SSL *s) /* make and send conn_id */ s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; - if (RAND_pseudo_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= - 0) + if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) return -1; memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); d += SSL2_CONNECTION_ID_LENGTH; @@ -962,7 +958,7 @@ static int request_certificate(SSL *s) p = (unsigned char *)s->init_buf->data; *(p++) = SSL2_MT_REQUEST_CERTIFICATE; *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; - if (RAND_pseudo_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) return -1; memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); diff --git a/crypto/openssl/ssl/s3_both.c b/crypto/openssl/ssl/s3_both.c index 09d0661..054ded1 100644 --- a/crypto/openssl/ssl/s3_both.c +++ b/crypto/openssl/ssl/s3_both.c @@ -356,21 +356,22 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } *ok = 1; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = (int)s->s3->tmp.message_size; return s->init_num; } p = (unsigned char *)s->init_buf->data; - if (s->state == st1) { /* s->init_num < 4 */ + if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ int skip_message; do { - while (s->init_num < 4) { + while (s->init_num < SSL3_HM_HEADER_LENGTH) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - 4 - s->init_num, 0); + SSL3_HM_HEADER_LENGTH - + s->init_num, 0); if (i <= 0) { s->rwstate = SSL_READING; *ok = 0; @@ -394,12 +395,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, 4, s, s->msg_callback_arg); + p, SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); } } while (skip_message); - /* s->init_num == 4 */ + /* s->init_num == SSL3_HM_HEADER_LENGTH */ if ((mt >= 0) && (*p != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; @@ -415,19 +417,20 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) { + /* + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 + */ + if (l + && !BUF_MEM_grow_clean(s->init_buf, + (int)l + SSL3_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_size = l; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = 0; } @@ -456,10 +459,12 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) #endif /* Feed this message into MAC computation. */ - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH); if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + 4, s, s->msg_callback_arg); + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); *ok = 1; return s->init_num; f_err: @@ -535,6 +540,9 @@ int ssl_verify_alarm_type(long type) case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_CERT_REJECTED: + case X509_V_ERR_HOSTNAME_MISMATCH: + case X509_V_ERR_EMAIL_MISMATCH: + case X509_V_ERR_IP_ADDRESS_MISMATCH: al = SSL_AD_BAD_CERTIFICATE; break; case X509_V_ERR_CERT_SIGNATURE_FAILURE: @@ -548,7 +556,10 @@ int ssl_verify_alarm_type(long type) case X509_V_ERR_CERT_REVOKED: al = SSL_AD_CERTIFICATE_REVOKED; break; + case X509_V_ERR_UNSPECIFIED: case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: al = SSL_AD_INTERNAL_ERROR; break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c index 19dc864..2185347 100644 --- a/crypto/openssl/ssl/s3_clnt.c +++ b/crypto/openssl/ssl/s3_clnt.c @@ -1216,6 +1216,12 @@ int ssl3_get_server_certificate(SSL *s) goto f_err; } for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } n2l3(p, l); if ((l + nc + 3) > llen) { al = SSL_AD_DECODE_ERROR; @@ -2111,6 +2117,10 @@ int ssl3_get_certificate_request(SSL *s) if (ctype_num > SSL3_CT_NUMBER) { /* If we exceed static buffer copy all to cert structure */ s->cert->ctypes = OPENSSL_malloc(ctype_num); + if (s->cert->ctypes == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } memcpy(s->cert->ctypes, p, ctype_num); s->cert->ctype_num = (size_t)ctype_num; ctype_num = SSL3_CT_NUMBER; @@ -2167,6 +2177,11 @@ int ssl3_get_certificate_request(SSL *s) } for (nc = 0; nc < llen;) { + if (nc + 2 > llen) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); + goto err; + } n2s(p, l); if ((l + nc + 2) > llen) { if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) @@ -2999,19 +3014,6 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } /* - * If we have client certificate, use its secret as peer key - */ - if (s->s3->tmp.cert_req && s->cert->key->privatekey) { - if (EVP_PKEY_derive_set_peer - (pkey_ctx, s->cert->key->privatekey) <= 0) { - /* - * If there was an error - just ignore it. Ephemeral key - * * would be used - */ - ERR_clear_error(); - } - } - /* * Compute shared IV and store it in algorithm-specific context * data */ @@ -3057,12 +3059,6 @@ int ssl3_send_client_key_exchange(SSL *s) n = msglen + 2; } memcpy(p, tmp, msglen); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { - /* Set flag "skip certificate verify" */ - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } EVP_PKEY_CTX_free(pkey_ctx); s->session->master_key_length = s->method->ssl3_enc->generate_master_secret(s, diff --git a/crypto/openssl/ssl/s3_enc.c b/crypto/openssl/ssl/s3_enc.c index 47a0ec9..fbc954d 100644 --- a/crypto/openssl/ssl/s3_enc.c +++ b/crypto/openssl/ssl/s3_enc.c @@ -607,6 +607,10 @@ int ssl3_digest_cached_records(SSL *s) ssl3_free_digest_list(s); s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + if (s->s3->handshake_dgst == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); if (hdatalen <= 0) { @@ -624,8 +628,12 @@ int ssl3_digest_cached_records(SSL *s) EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } #endif - EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL); - EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen); + if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL) + || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, + hdatalen)) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); + return 0; + } } else { s->s3->handshake_dgst[i] = NULL; } diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c index 872e636..0385e03 100644 --- a/crypto/openssl/ssl/s3_lib.c +++ b/crypto/openssl/ssl/s3_lib.c @@ -329,7 +329,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -382,7 +382,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -434,7 +434,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -487,7 +487,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -539,7 +539,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -625,7 +625,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -712,7 +712,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -778,7 +778,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_MD5, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -1728,7 +1728,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2120,7 +2120,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2200,7 +2200,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2280,7 +2280,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2360,7 +2360,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2440,7 +2440,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2490,7 +2490,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2506,7 +2506,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2522,7 +2522,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -4528,7 +4528,10 @@ int ssl3_renegotiate_check(SSL *s) */ long ssl_get_algorithm2(SSL *s) { - long alg2 = s->s3->tmp.new_cipher->algorithm2; + long alg2; + if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) + return -1; + alg2 = s->s3->tmp.new_cipher->algorithm2; if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index 3798902..be37ef0 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -1229,6 +1229,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return (ret); } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1443,6 +1450,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { s->shutdown |= SSL_RECEIVED_SHUTDOWN; return (0); @@ -1473,7 +1488,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -1698,7 +1713,7 @@ int ssl3_send_alert(SSL *s, int level, int desc) return -1; /* If a fatal one, remove from cache */ if ((level == 2) && (s->session != NULL)) - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); s->s3->alert_dispatch = 1; s->s3->send_alert[0] = level; diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c index ab28702..01ccd5d 100644 --- a/crypto/openssl/ssl/s3_srvr.c +++ b/crypto/openssl/ssl/s3_srvr.c @@ -980,7 +980,8 @@ int ssl3_get_client_hello(SSL *s) session_length = *(p + SSL3_RANDOM_SIZE); - if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { + if (SSL3_RANDOM_SIZE + session_length + 1 + >= (unsigned int)((d + n) - p)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -998,7 +999,7 @@ int ssl3_get_client_hello(SSL *s) /* get the session-id */ j = *(p++); - if (p + j > d + n) { + if ((d + n) - p < j) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1054,14 +1055,14 @@ int ssl3_get_client_hello(SSL *s) if (SSL_IS_DTLS(s)) { /* cookie stuff */ - if (p + 1 > d + n) { + if ((d + n) - p < 1) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; } cookie_len = *(p++); - if (p + cookie_len > d + n) { + if ((unsigned int)((d + n ) - p) < cookie_len) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1131,7 +1132,7 @@ int ssl3_get_client_hello(SSL *s) } } - if (p + 2 > d + n) { + if ((d + n ) - p < 2) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1145,7 +1146,7 @@ int ssl3_get_client_hello(SSL *s) } /* i bytes of cipher data + 1 byte for compression length later */ - if ((p + i + 1) > (d + n)) { + if ((d + n) - p < i + 1) { /* not enough data */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); @@ -1211,7 +1212,7 @@ int ssl3_get_client_hello(SSL *s) /* compression */ i = *(p++); - if ((p + i) > (d + n)) { + if ((d + n) - p < i) { /* not enough data */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); @@ -1872,6 +1873,11 @@ int ssl3_send_server_key_exchange(SSL *s) goto f_err; } kn = EVP_PKEY_size(pkey); + /* Allow space for signature algorithm */ + if (SSL_USE_SIGALGS(s)) + kn += 2; + /* Allow space for signature length */ + kn += 2; } else { pkey = NULL; kn = 0; @@ -2229,11 +2235,8 @@ int ssl3_get_client_key_exchange(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) + if (RAND_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) goto err; decrypt_len = RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); @@ -2323,7 +2326,8 @@ int ssl3_get_client_key_exchange(SSL *s) if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - goto err; + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; } else { p -= 2; i = (int)n; @@ -2376,9 +2380,10 @@ int ssl3_get_client_key_exchange(SSL *s) i = DH_compute_key(p, pub, dh_srvr); if (i <= 0) { + al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); BN_clear_free(pub); - goto err; + goto f_err; } DH_free(s->s3->tmp.dh); @@ -2676,12 +2681,14 @@ int ssl3_get_client_key_exchange(SSL *s) i = *p; p += 1; if (n != 1 + i) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; } if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; } /* * p is pointing to somewhere in the buffer currently, so set it @@ -3213,6 +3220,12 @@ int ssl3_get_client_certificate(SSL *s) goto f_err; } for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } n2l3(p, l); if ((l + nc + 3) > llen) { al = SSL_AD_DECODE_ERROR; @@ -3497,37 +3510,34 @@ int ssl3_send_cert_status(SSL *s) { if (s->state == SSL3_ST_SW_CERT_STATUS_A) { unsigned char *p; + size_t msglen; + /*- * Grow buffer if need be: the length calculation is as - * follows 1 (message type) + 3 (message length) + + * follows handshake_header_length + * 1 (ocsp response type) + 3 (ocsp response length) * + (ocsp response) */ - if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) { + msglen = 4 + s->tlsext_ocsp_resplen; + if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) { s->state = SSL_ST_ERR; return -1; } - p = (unsigned char *)s->init_buf->data; + p = ssl_handshake_start(s); - /* do the header */ - *(p++) = SSL3_MT_CERTIFICATE_STATUS; - /* message length */ - l2n3(s->tlsext_ocsp_resplen + 4, p); /* status type */ *(p++) = s->tlsext_status_type; /* length of OCSP response */ l2n3(s->tlsext_ocsp_resplen, p); /* actual response */ memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); - /* number of bytes to write */ - s->init_num = 8 + s->tlsext_ocsp_resplen; - s->state = SSL3_ST_SW_CERT_STATUS_B; - s->init_off = 0; + + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen); } /* SSL3_ST_SW_CERT_STATUS_B */ - return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + return (ssl_do_write(s)); } # ifndef OPENSSL_NO_NEXTPROTONEG diff --git a/crypto/openssl/ssl/ssl.h b/crypto/openssl/ssl/ssl.h index 5ef56fa..90aeb0c 100644 --- a/crypto/openssl/ssl/ssl.h +++ b/crypto/openssl/ssl/ssl.h @@ -2532,7 +2532,6 @@ void SSL_set_tmp_ecdh_callback(SSL *ssl, int keylength)); # endif -# ifndef OPENSSL_NO_COMP const COMP_METHOD *SSL_get_current_compression(SSL *s); const COMP_METHOD *SSL_get_current_expansion(SSL *s); const char *SSL_COMP_get_name(const COMP_METHOD *comp); @@ -2541,13 +2540,6 @@ STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) *meths); void SSL_COMP_free_compression_methods(void); int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); -# else -const void *SSL_get_current_compression(SSL *s); -const void *SSL_get_current_expansion(SSL *s); -const char *SSL_COMP_get_name(const void *comp); -void *SSL_COMP_get_compression_methods(void); -int SSL_COMP_add_compression_method(int id, void *cm); -# endif const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); @@ -2623,6 +2615,7 @@ void ERR_load_SSL_strings(void); # define SSL_F_DTLS1_HEARTBEAT 305 # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 # define SSL_F_DTLS1_PROCESS_RECORD 257 # define SSL_F_DTLS1_READ_BYTES 258 @@ -3114,6 +3107,7 @@ void ERR_load_SSL_strings(void); # define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 # define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 # define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 # define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 # define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 # define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 diff --git a/crypto/openssl/ssl/ssl_asn1.c b/crypto/openssl/ssl/ssl_asn1.c index 35cc27c..499f0e8 100644 --- a/crypto/openssl/ssl/ssl_asn1.c +++ b/crypto/openssl/ssl/ssl_asn1.c @@ -527,6 +527,9 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (os.length > SSL_MAX_SID_CTX_LENGTH) { c.error = SSL_R_BAD_LENGTH; c.line = __LINE__; + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; goto err; } else { ret->sid_ctx_length = os.length; diff --git a/crypto/openssl/ssl/ssl_ciph.c b/crypto/openssl/ssl/ssl_ciph.c index 302464e..2ad8f43 100644 --- a/crypto/openssl/ssl/ssl_ciph.c +++ b/crypto/openssl/ssl/ssl_ciph.c @@ -1932,17 +1932,27 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) } #ifdef OPENSSL_NO_COMP -void *SSL_COMP_get_compression_methods(void) +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) { return NULL; } -int SSL_COMP_add_compression_method(int id, void *cm) +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths) +{ + return NULL; +} + +void SSL_COMP_free_compression_methods(void) +{ +} + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; } -const char *SSL_COMP_get_name(const void *comp) +const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; } @@ -1996,6 +2006,11 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) MemCheck_off(); comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp == NULL) { + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + return 1; + } comp->id = id; comp->method = cm; load_builtin_compressions(); diff --git a/crypto/openssl/ssl/ssl_err.c b/crypto/openssl/ssl/ssl_err.c index 704088d..79aaf1a 100644 --- a/crypto/openssl/ssl/ssl_err.c +++ b/crypto/openssl/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"}, {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), + "DTLS1_PROCESS_BUFFERED_RECORDS"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c index fd94325..42b980a 100644 --- a/crypto/openssl/ssl/ssl_lib.c +++ b/crypto/openssl/ssl/ssl_lib.c @@ -1828,7 +1828,7 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *p, size_t plen, int use_context) { - if (s->version < TLS1_VERSION) + if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, @@ -2000,7 +2000,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_servername_callback = 0; ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ - if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; @@ -3050,12 +3050,12 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) } #ifdef OPENSSL_NO_COMP -const void *SSL_get_current_compression(SSL *s) +const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; } -const void *SSL_get_current_expansion(SSL *s) +const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; } diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h index 747e718..6df725f 100644 --- a/crypto/openssl/ssl/ssl_locl.h +++ b/crypto/openssl/ssl/ssl_locl.h @@ -491,6 +491,12 @@ # define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) +/* + * Determine if a client should send signature algorithms extension: + * as with TLS1.2 cipher we can't rely on method flags. + */ +# define SSL_CLIENT_USE_SIGALGS(s) \ + SSL_CLIENT_USE_TLS1_2_CIPHERS(s) /* Mostly for SSLv3 */ # define SSL_PKEY_RSA_ENC 0 @@ -585,6 +591,8 @@ typedef struct { */ # define SSL_EXT_FLAG_SENT 0x2 +# define MAX_WARN_ALERT_COUNT 5 + typedef struct { custom_ext_method *meths; size_t meths_count; @@ -692,6 +700,8 @@ typedef struct cert_st { unsigned char *alpn_proposed; /* server */ unsigned int alpn_proposed_len; int alpn_sent; /* client */ + /* Count of the number of consecutive warning alerts received */ + unsigned int alert_count; } CERT; typedef struct sess_cert_st { @@ -1242,7 +1252,8 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, int *found); int dtls1_get_queue_priority(unsigned short seq, int is_ccs); int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_record_buffer(SSL *s); +void dtls1_clear_received_buffer(SSL *s); +void dtls1_clear_sent_buffer(SSL *s); void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr); void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); diff --git a/crypto/openssl/ssl/ssl_rsa.c b/crypto/openssl/ssl/ssl_rsa.c index 8202247..f679801 100644 --- a/crypto/openssl/ssl/ssl_rsa.c +++ b/crypto/openssl/ssl/ssl_rsa.c @@ -912,6 +912,8 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo, int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length) { + unsigned char *new_serverinfo; + if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -928,12 +930,13 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR); return 0; } - ctx->cert->key->serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, - serverinfo_length); - if (ctx->cert->key->serverinfo == NULL) { + new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, + serverinfo_length); + if (new_serverinfo == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); return 0; } + ctx->cert->key->serverinfo = new_serverinfo; memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); ctx->cert->key->serverinfo_length = serverinfo_length; diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c index b182998..ed9855f 100644 --- a/crypto/openssl/ssl/ssl_sess.c +++ b/crypto/openssl/ssl/ssl_sess.c @@ -382,7 +382,7 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id, { unsigned int retry = 0; do - if (RAND_pseudo_bytes(id, *id_len) <= 0) + if (RAND_bytes(id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -573,7 +573,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, int r; #endif - if (session_id + len > limit) { + if (limit - session_id < len) { fatal = 1; goto err; } @@ -919,6 +919,10 @@ int SSL_set_session(SSL *s, SSL_SESSION *session) session->krb5_client_princ_len > 0) { s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); + if (s->kssl_ctx->client_princ == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); + return 0; + } memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, session->krb5_client_princ_len); s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; @@ -1123,7 +1127,7 @@ int ssl_clear_bad_session(SSL *s) if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && !(SSL_in_init(s) || SSL_in_before(s))) { - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (1); } else return (0); diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c index 1db84ad..890e476 100644 --- a/crypto/openssl/ssl/ssltest.c +++ b/crypto/openssl/ssl/ssltest.c @@ -3141,9 +3141,12 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, static int do_test_cipherlist(void) { +#if !defined(OPENSSL_NO_SSL2) || !defined(OPENSSL_NO_SSL3) || \ + !defined(OPENSSL_NO_TLS1) int i = 0; const SSL_METHOD *meth; const SSL_CIPHER *ci, *tci = NULL; +#endif #ifndef OPENSSL_NO_SSL2 fprintf(stderr, "testing SSLv2 cipher list order: "); diff --git a/crypto/openssl/ssl/sslv2conftest.c b/crypto/openssl/ssl/sslv2conftest.c index 1fd748b..2aed995 100644 --- a/crypto/openssl/ssl/sslv2conftest.c +++ b/crypto/openssl/ssl/sslv2conftest.c @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) { BIO *err; int testresult = 0; - int currtest; + int currtest = 0; SSL_library_init(); SSL_load_error_strings(); diff --git a/crypto/openssl/ssl/t1_enc.c b/crypto/openssl/ssl/t1_enc.c index 514fcb3..b6d1ee9 100644 --- a/crypto/openssl/ssl/t1_enc.c +++ b/crypto/openssl/ssl/t1_enc.c @@ -673,7 +673,6 @@ int tls1_setup_key_block(SSL *s) if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - OPENSSL_free(p1); goto err; } #ifdef TLS_DEBUG diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c index dd5bd00..7831046 100644 --- a/crypto/openssl/ssl/t1_lib.c +++ b/crypto/openssl/ssl/t1_lib.c @@ -1429,7 +1429,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, } skip_ext: - if (SSL_USE_SIGALGS(s)) { + if (SSL_CLIENT_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; salglen = tls12_get_psigalgs(s, &salg); @@ -1867,11 +1867,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, 0x02, 0x03, /* SHA-1/ECDSA */ }; - if (data >= (limit - 2)) + if (limit - data <= 2) return; data += 2; - if (data > (limit - 4)) + if (limit - data < 4) return; n2s(data, type); n2s(data, size); @@ -1879,7 +1879,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, if (type != TLSEXT_TYPE_server_name) return; - if (data + size > limit) + if (limit - data < size) return; data += size; @@ -1887,7 +1887,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const size_t len1 = sizeof(kSafariExtensionsBlock); const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); - if (data + len1 + len2 != limit) + if (limit - data != (int)(len1 + len2)) return; if (memcmp(data, kSafariExtensionsBlock, len1) != 0) return; @@ -1896,7 +1896,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, } else { const size_t len = sizeof(kSafariExtensionsBlock); - if (data + len != limit) + if (limit - data != (int)(len)) return; if (memcmp(data, kSafariExtensionsBlock, len) != 0) return; @@ -2053,19 +2053,19 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, if (data == limit) goto ri_check; - if (data > (limit - 2)) + if (limit - data < 2) goto err; n2s(data, len); - if (data + len != limit) + if (limit - data != len) goto err; - while (data <= (limit - 4)) { + while (limit - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > (limit)) + if (limit - data < size) goto err; # if 0 fprintf(stderr, "Received extension type %d size %d\n", type, size); @@ -2316,6 +2316,23 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, size -= 2; if (dsize > size) goto err; + + /* + * We remove any OCSP_RESPIDs from a previous handshake + * to prevent unbounded memory growth - CVE-2016-6304 + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, + OCSP_RESPID_free); + if (dsize > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + s->tlsext_ocsp_ids = NULL; + } + while (dsize > 0) { OCSP_RESPID *id; int idsize; @@ -2335,13 +2352,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, OCSP_RESPID_free(id); goto err; } - if (!s->tlsext_ocsp_ids - && !(s->tlsext_ocsp_ids = - sk_OCSP_RESPID_new_null())) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; @@ -2472,18 +2482,18 @@ static int ssl_scan_clienthello_custom_tlsext(SSL *s, if (s->hit || s->cert->srv_ext.meths_count == 0) return 1; - if (data >= limit - 2) + if (limit - data <= 2) return 1; n2s(data, len); - if (data > limit - len) + if (limit - data < len) return 1; - while (data <= limit - 4) { + while (limit - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > limit) + if (limit - data < size) return 1; if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) return 0; @@ -2569,20 +2579,20 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, SSL_TLSEXT_HB_DONT_SEND_REQUESTS); # endif - if (data >= (d + n - 2)) + if ((d + n) - data <= 2) goto ri_check; n2s(data, length); - if (data + length != d + n) { + if ((d + n) - data != length) { *al = SSL_AD_DECODE_ERROR; return 0; } - while (data <= (d + n - 4)) { + while ((d + n) - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > (d + n)) + if ((d + n) - data < size) goto ri_check; if (s->tlsext_debug_cb) @@ -2712,6 +2722,11 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, *al = TLS1_AD_INTERNAL_ERROR; return 0; } + /* + * Could be non-NULL if server has sent multiple NPN extensions in + * a single Serverhello + */ + OPENSSL_free(s->next_proto_negotiated); s->next_proto_negotiated = OPENSSL_malloc(selected_len); if (!s->next_proto_negotiated) { *al = TLS1_AD_INTERNAL_ERROR; @@ -3307,29 +3322,33 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, /* Skip past DTLS cookie */ if (SSL_IS_DTLS(s)) { i = *(p++); - p += i; - if (p >= limit) + + if (limit - p <= i) return -1; + + p += i; } /* Skip past cipher list */ n2s(p, i); - p += i; - if (p >= limit) + if (limit - p <= i) return -1; + p += i; + /* Skip past compression algorithm list */ i = *(p++); - p += i; - if (p > limit) + if (limit - p < i) return -1; + p += i; + /* Now at start of extensions */ - if ((p + 2) >= limit) + if (limit - p <= 2) return 0; n2s(p, i); - while ((p + 4) <= limit) { + while (limit - p >= 4) { unsigned short type, size; n2s(p, type); n2s(p, size); - if (p + size > limit) + if (limit - p < size) return 0; if (type == TLSEXT_TYPE_session_ticket) { int r; @@ -3397,9 +3416,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, HMAC_CTX hctx; EVP_CIPHER_CTX ctx; SSL_CTX *tctx = s->initial_ctx; - /* Need at least keyname + iv + some encrypted data */ - if (eticklen < 48) - return 2; + /* Initialize session ticket encryption and HMAC contexts */ HMAC_CTX_init(&hctx); EVP_CIPHER_CTX_init(&ctx); @@ -3433,6 +3450,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (mlen < 0) { goto err; } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ + if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { + HMAC_CTX_cleanup(&hctx); + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + eticklen -= mlen; /* Check HMAC of encrypted ticket */ if (HMAC_Update(&hctx, etick, eticklen) <= 0 @@ -3902,7 +3926,7 @@ int tls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -3980,6 +4004,8 @@ int tls1_heartbeat(SSL *s) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + return -1; p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; @@ -3988,13 +4014,13 @@ int tls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) { + if (RAND_bytes(p, 16) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) { + if (RAND_bytes(p, padding) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } diff --git a/crypto/openssl/util/mk1mf.pl b/crypto/openssl/util/mk1mf.pl index 128a405..7a3ae11 100755 --- a/crypto/openssl/util/mk1mf.pl +++ b/crypto/openssl/util/mk1mf.pl @@ -277,6 +277,7 @@ $cflags.=" -DOPENSSL_NO_SOCK" if $no_sock; $cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2; $cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3; $cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext; +$cflags.=" -DOPENSSL_NO_TLS1" if $no_tls1; $cflags.=" -DOPENSSL_NO_SRP" if $no_srp; $cflags.=" -DOPENSSL_NO_CMS" if $no_cms; $cflags.=" -DOPENSSL_NO_ERR" if $no_err; @@ -692,8 +693,8 @@ $rules.=&do_copy_rule("\$(INCL_D)",$header,""); $defs.=&do_defs("EXHEADER",$exheader,"\$(INCO_D)",""); $rules.=&do_copy_rule("\$(INCO_D)",$exheader,""); -$defs.=&do_defs("T_OBJ",$test,"\$(OBJ_D)",$obj); -$rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)"); +$defs.=&do_defs("T_OBJ","$test test${o}ssltestlib","\$(OBJ_D)",$obj); +$rules.=&do_compile_rule("\$(OBJ_D)","$test test${o}ssltestlib","\$(APP_CFLAGS)"); $defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj); $rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)'); @@ -764,6 +765,7 @@ foreach (split(/\s+/,$test)) { $t=&bname($_); $tt="\$(OBJ_D)${o}$t${obj}"; + $tt.=" \$(OBJ_D)${o}ssltestlib${obj}" if $t eq "dtlstest"; $rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)"); } @@ -1204,6 +1206,7 @@ sub read_options "no-ssl3" => \$no_ssl3, "no-ssl3-method" => 0, "no-tlsext" => \$no_tlsext, + "no-tls1" => \$no_tls1, "no-srp" => \$no_srp, "no-cms" => \$no_cms, "no-jpake" => \$no_jpake, diff --git a/crypto/openssl/util/mkerr.pl b/crypto/openssl/util/mkerr.pl index 09ebebe..c197f3a 100644 --- a/crypto/openssl/util/mkerr.pl +++ b/crypto/openssl/util/mkerr.pl @@ -158,8 +158,8 @@ close IN; while (($hdr, $lib) = each %libinc) { next if($hdr eq "NONE"); - print STDERR "Scanning header file $hdr\n" if $debug; - my $line = "", $def= "", $linenr = 0, $gotfile = 0; + print STDERR "Scanning header file $hdr\n" if $debug; + my $line = "", $def= "", $linenr = 0, $gotfile = 0, $cpp = 0; if (open(IN, "<$hdr")) { $gotfile = 1; while(<IN>) { @@ -382,14 +382,21 @@ foreach $lib (keys %csrc) # Rewrite the header file + $cpp = 0; + $cplusplus = 0; if (open(IN, "<$hfile")) { # Copy across the old file while(<IN>) { + $cplusplus = $cpp if /^#.*ifdef.*cplusplus/; + $cpp++ if /^#\s*if/; + $cpp-- if /^#\s*endif/; push @out, $_; last if (/BEGIN ERROR CODES/); } close IN; } else { + $cpp = 1; + $cplusplus = 1; push @out, "/* ====================================================================\n", " * Copyright (c) 2001-$year The OpenSSL Project. All rights reserved.\n", @@ -446,11 +453,11 @@ foreach $lib (keys %csrc) " */\n", "\n", "#ifndef HEADER_${lib}_ERR_H\n", -"#define HEADER_${lib}_ERR_H\n", +"# define HEADER_${lib}_ERR_H\n", "\n", -"#ifdef __cplusplus\n", +"# ifdef __cplusplus\n", "extern \"C\" {\n", -"#endif\n", +"# endif\n", "\n", "/* BEGIN ERROR CODES */\n"; } @@ -463,6 +470,7 @@ foreach $lib (keys %csrc) * 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. */ + EOF if($static) { print OUT <<"EOF"; @@ -523,11 +531,17 @@ EOF } print OUT <<"EOF"; -#ifdef __cplusplus -} -#endif -#endif EOF + do { + if ($cplusplus == $cpp) { + print OUT "#", " "x$cpp, "ifdef __cplusplus\n"; + print OUT "}\n"; + print OUT "#", " "x$cpp, "endif\n"; + } + if ($cpp-- > 0) { + print OUT "#", " "x$cpp, "endif\n"; + } + } while ($cpp); close OUT; # Rewrite the C source file containing the error details. @@ -559,8 +573,9 @@ EOF my $hincf; if($static) { - $hfile =~ /([^\/]+)$/; - $hincf = "<${hprefix}$1>"; + $hincf = $hfile; + $hincf =~ s|.*/||g; + $hincf = "<${hprefix}${hincf}>"; } else { $hincf = "\"$hfile\""; } @@ -665,7 +680,7 @@ EOF $fn = $ftrans{$fn}; } # print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n"; - if(length($i) + length($fn) > 58) { + if(length($i) + length($fn) > 57) { print OUT " {ERR_FUNC($i),\n \"$fn\"},\n"; } else { print OUT " {ERR_FUNC($i), \"$fn\"},\n"; @@ -688,7 +703,7 @@ EOF $rn = $1; $rn =~ tr/_[A-Z]/ [a-z]/; } - if(length($i) + length($rn) > 56) { + if(length($i) + length($rn) > 55) { print OUT " {${rstr},\n \"$rn\"},\n"; } else { print OUT " {${rstr}, \"$rn\"},\n"; diff --git a/crypto/openssl/util/ssleay.num b/crypto/openssl/util/ssleay.num index 5760bc4..e3fdaf2 100644 --- a/crypto/openssl/util/ssleay.num +++ b/crypto/openssl/util/ssleay.num @@ -164,7 +164,7 @@ SSL_CTX_get_cert_store 180 EXIST::FUNCTION: SSL_CTX_set_cert_store 181 EXIST::FUNCTION: SSL_want 182 EXIST::FUNCTION: SSL_library_init 183 EXIST::FUNCTION: -SSL_COMP_add_compression_method 184 EXIST::FUNCTION:COMP +SSL_COMP_add_compression_method 184 EXIST::FUNCTION: SSL_add_file_cert_subjects_to_stack 185 EXIST:!VMS:FUNCTION:STDIO SSL_add_file_cert_subjs_to_stk 185 EXIST:VMS:FUNCTION:STDIO SSL_set_tmp_rsa_callback 186 EXIST::FUNCTION:RSA @@ -219,13 +219,13 @@ SSL_set_msg_callback 267 EXIST::FUNCTION: DTLSv1_client_method 268 EXIST::FUNCTION: SSL_CTX_set_tmp_ecdh_callback 269 EXIST::FUNCTION:ECDH SSL_set_tmp_ecdh_callback 270 EXIST::FUNCTION:ECDH -SSL_COMP_get_name 271 EXIST::FUNCTION:COMP -SSL_get_current_compression 272 EXIST::FUNCTION:COMP +SSL_COMP_get_name 271 EXIST::FUNCTION: +SSL_get_current_compression 272 EXIST::FUNCTION: DTLSv1_method 273 EXIST::FUNCTION: -SSL_get_current_expansion 274 EXIST::FUNCTION:COMP +SSL_get_current_expansion 274 EXIST::FUNCTION: DTLSv1_server_method 275 EXIST::FUNCTION: -SSL_COMP_get_compression_methods 276 EXIST:!VMS:FUNCTION:COMP -SSL_COMP_get_compress_methods 276 EXIST:VMS:FUNCTION:COMP +SSL_COMP_get_compression_methods 276 EXIST:!VMS:FUNCTION: +SSL_COMP_get_compress_methods 276 EXIST:VMS:FUNCTION: SSL_SESSION_get_id 277 EXIST::FUNCTION: SSL_CTX_sess_set_new_cb 278 EXIST::FUNCTION: SSL_CTX_sess_get_get_cb 279 EXIST::FUNCTION: @@ -332,8 +332,8 @@ SSL_set_alpn_protos 370 EXIST::FUNCTION: SSL_CTX_set_srv_supp_data 371 NOEXIST::FUNCTION: SSL_CONF_cmd_argv 372 EXIST::FUNCTION: DTLSv1_2_server_method 373 EXIST::FUNCTION: -SSL_COMP_set0_compression_methods 374 EXIST:!VMS:FUNCTION:COMP -SSL_COMP_set0_compress_methods 374 EXIST:VMS:FUNCTION:COMP +SSL_COMP_set0_compression_methods 374 EXIST:!VMS:FUNCTION: +SSL_COMP_set0_compress_methods 374 EXIST:VMS:FUNCTION: SSL_CTX_set_cert_cb 375 EXIST::FUNCTION: SSL_CTX_add_client_custom_ext 376 EXIST::FUNCTION:TLSEXT SSL_is_server 377 EXIST::FUNCTION: @@ -365,6 +365,6 @@ SSL_CTX_set_cli_supp_data 403 NOEXIST::FUNCTION: DTLSv1_2_method 404 EXIST::FUNCTION: DTLS_server_method 405 EXIST::FUNCTION: SSL_CTX_use_serverinfo_file 406 EXIST::FUNCTION:STDIO,TLSEXT -SSL_COMP_free_compression_methods 407 EXIST:!VMS:FUNCTION:COMP -SSL_COMP_free_compress_methods 407 EXIST:VMS:FUNCTION:COMP +SSL_COMP_free_compression_methods 407 EXIST:!VMS:FUNCTION: +SSL_COMP_free_compress_methods 407 EXIST:VMS:FUNCTION: SSL_extension_supported 409 EXIST::FUNCTION:TLSEXT |