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
-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.
# 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).
$disabled{"tls1"} = "forced";
}
-if (defined($disabled{"tls1"}))
- {
- $disabled{"tlsext"} = "forced";
- }
-
if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
|| defined($disabled{"dh"}))
{
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
$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;
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";
}
If you link with static OpenSSL libraries [those built with ms/nt.mak],
then you're expected to additionally link your application with
- WS2_32.LIB, ADVAPI32.LIB, GDI32.LIB and USER32.LIB. Those developing
- non-interactive service applications might feel concerned about linking
- with the latter two, as they are justly associated with interactive
- desktop, which is not available to service processes. The toolkit is
- designed to detect in which context it's currently executed, GUI,
- console app or service, and act accordingly, namely whether or not to
- actually make GUI calls. Additionally those who wish to
- /DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and actually keep them
- off service process should consider implementing and exporting from
- .exe image in question own _OPENSSL_isservice not relying on USER32.DLL.
- E.g., on Windows Vista and later you could:
+ WS2_32.LIB, GDI32.LIB, ADVAPI32.LIB, CRYPT32.LIB and USER32.LIB. Those
+ developing non-interactive service applications might feel concerned about
+ linking with GDI32.LIB and USER32.LIB, as they are justly associated with
+ interactive desktop, which is not available to service processes. The toolkit
+ is designed to detect in which context it's currently executed, GUI, console
+ app or service, and act accordingly, namely whether or not to actually make
+ GUI calls. Additionally those who wish to /DELAYLOAD:GDI32.DLL and
+ /DELAYLOAD:USER32.DLL and actually keep them off service process should
+ consider implementing and exporting from .exe image in question own
+ _OPENSSL_isservice not relying on USER32.DLL. E.g., on Windows Vista and
+ later you could:
__declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void)
{ DWORD sess;
## Makefile for OpenSSL
##
-VERSION=1.0.2h
+VERSION=1.0.2i
MAJOR=1
MINOR=0.2
SHLIB_VERSION_NUMBER=1.0.0
ARFLAGS=
AR= ar $(ARFLAGS) r
RANLIB= /usr/bin/ranlib
+RC= windres
NM= nm
PERL= /usr/bin/perl
TAR= tar
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)' \
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'; \
## Makefile for OpenSSL
##
-VERSION=1.0.2h
+VERSION=1.0.2i
MAJOR=1
MINOR=0.2
SHLIB_VERSION_NUMBER=1.0.0
# PKCS1_CHECK - pkcs1 tests.
CC= gcc
-CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
+CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
DEPFLAG= -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
PEX_LIBS=
EX_LIBS= -ldl
ARFLAGS=
AR= ar $(ARFLAGS) r
RANLIB= /usr/bin/ranlib
+RC= windres
NM= nm
PERL= /usr/bin/perl
TAR= tar
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)' \
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'; \
ARFLAGS=
AR=ar $(ARFLAGS) r
RANLIB= ranlib
+RC= windres
NM= nm
PERL= perl
TAR= tar
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)' \
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'; \
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'; \
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)
- 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
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
}
}
}
-
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
}
}
}
-
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;
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;
#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)
{
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
#else
int raw_write_stdout(const void *buf, int siz)
{
- return write(fileno(stdout), buf, siz);
+ return write(fileno_stdout(), buf, siz);
}
#endif
# 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);
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';
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;
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");
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
"CIPHERS,NSEQ,PKCS12,PKCS8,PKEY,PKEYPARAM,PKEYUTL,"+ -
"SPKAC,SMIME,CMS,RAND,ENGINE,OCSP,PRIME,TS,SRP"
$!
-$ LIB_OPENSSL = LIB_OPENSSL+ ",VMS_DECC_INIT"
+$ LIB_OPENSSL = LIB_OPENSSL+ ",VMS_DECC_INIT,VMS_TERM_SOCK"
$!
$ TCPIP_PROGRAMS = ",,"
$ IF COMPILER .EQS. "VAXC" THEN -
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 */
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++)
EVP_PKEY *pkey;
PKCS8_PRIV_KEY_INFO *p8;
X509 *x509;
+ int ret = 0;
switch (M_PKCS12_bag_type(bag)) {
case NID_keyBag:
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;
}
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;
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;
return 1;
break;
}
- return 1;
+ return ret;
}
/* Given a single certificate return a verified chain or NULL if error */
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;
}
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;
}
}
- if (newreq || x509) {
+ if (newreq) {
if (pkey == NULL) {
BIO_printf(bio_err, "you need to specify a private key\n");
goto end;
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;
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,
}
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 */
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");
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");
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();
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;
}
#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) {
}
#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();
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;
#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);
/* 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;
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);
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
#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) {
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");
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");
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();
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;
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) {
}
#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();
}
#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;
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);
/*
/* 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))
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))
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");
{
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
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");
OPENSSL_EXIT(ret);
}
+#else
+static void *dummy = &dummy;
#endif
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--;
ret = -1;
}
- end:
+ usage:
if (ret == 1) {
BIO_printf(bio_err,
"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
X509_PURPOSE_get0_name(ptmp));
}
}
+ end:
if (vpm)
X509_VERIFY_PARAM_free(vpm);
if (cert_ctx != NULL)
--- /dev/null
+/*
+ * Copyright 2016 VMS Software, Inc. 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
+ */
+
+#ifdef __VMS
+# define OPENSSL_SYS_VMS
+# pragma message disable DOLLARID
+
+
+# include <openssl/opensslconf.h>
+
+# if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+/*
+ * On VMS, you need to define this to get the declaration of fileno(). The
+ * value 2 is to make sure no function defined in POSIX-2 is left undefined.
+ */
+# define _POSIX_C_SOURCE 2
+# endif
+
+# include <stdio.h>
+
+# undef _POSIX_C_SOURCE
+
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <inet.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <starlet.h>
+# include <iodef.h>
+# ifdef __alpha
+# include <iosbdef.h>
+# else
+typedef struct _iosb { /* Copied from IOSBDEF.H for Alpha */
+# pragma __nomember_alignment
+ __union {
+ __struct {
+ unsigned short int iosb$w_status; /* Final I/O status */
+ __union {
+ __struct { /* 16-bit byte count variant */
+ unsigned short int iosb$w_bcnt; /* 16-bit byte count */
+ __union {
+ unsigned int iosb$l_dev_depend; /* 32-bit device dependent info */
+ unsigned int iosb$l_pid; /* 32-bit pid */
+ } iosb$r_l;
+ } iosb$r_bcnt_16;
+ __struct { /* 32-bit byte count variant */
+ unsigned int iosb$l_bcnt; /* 32-bit byte count (unaligned) */
+ unsigned short int iosb$w_dev_depend_high; /* 16-bit device dependent info */
+ } iosb$r_bcnt_32;
+ } iosb$r_devdepend;
+ } iosb$r_io_64;
+ __struct {
+ __union {
+ unsigned int iosb$l_getxxi_status; /* Final GETxxI status */
+ unsigned int iosb$l_reg_status; /* Final $Registry status */
+ } iosb$r_l_status;
+ unsigned int iosb$l_reserved; /* Reserved field */
+ } iosb$r_get_64;
+ } iosb$r_io_get;
+} IOSB;
+
+# if !defined(__VAXC)
+# define iosb$w_status iosb$r_io_get.iosb$r_io_64.iosb$w_status
+# define iosb$w_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$w_bcnt
+# define iosb$r_l iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_16.iosb$r_l
+# define iosb$l_dev_depend iosb$r_l.iosb$l_dev_depend
+# define iosb$l_pid iosb$r_l.iosb$l_pid
+# define iosb$l_bcnt iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$l_bcnt
+# define iosb$w_dev_depend_high iosb$r_io_get.iosb$r_io_64.iosb$r_devdepend.iosb$r_bcnt_32.iosb$w_dev_depend_high
+# define iosb$l_getxxi_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_getxxi_status
+# define iosb$l_reg_status iosb$r_io_get.iosb$r_get_64.iosb$r_l_status.iosb$l_reg_status
+# endif /* #if !defined(__VAXC) */
+
+# endif /* End of IOSBDEF */
+
+# include <efndef.h>
+# include <stdlib.h>
+# include <ssdef.h>
+# include <time.h>
+# include <stdarg.h>
+# include <descrip.h>
+
+# include "vms_term_sock.h"
+
+# ifdef __alpha
+static struct _iosb TerminalDeviceIosb;
+# else
+IOSB TerminalDeviceIosb;
+# endif
+
+static char TerminalDeviceBuff[255 + 2];
+static int TerminalSocketPair[2] = {0, 0};
+static unsigned short TerminalDeviceChan = 0;
+
+static int CreateSocketPair (int, int, int, int *);
+static void SocketPairTimeoutAst (int);
+static int TerminalDeviceAst (int);
+static void LogMessage (char *, ...);
+
+/*
+** Socket Pair Timeout Value (must be 0-59 seconds)
+*/
+# define SOCKET_PAIR_TIMEOUT_VALUE 20
+
+/*
+** Socket Pair Timeout Block which is passed to timeout AST
+*/
+typedef struct _SocketPairTimeoutBlock {
+ unsigned short SockChan1;
+ unsigned short SockChan2;
+} SPTB;
+
+# ifdef TERM_SOCK_TEST
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+int main (int argc, char *argv[], char *envp[])
+{
+ char TermBuff[80];
+ int TermSock,
+ status,
+ len;
+
+ LogMessage ("Enter 'q' or 'Q' to quit ...");
+ while (strcasecmp (TermBuff, "Q")) {
+ /*
+ ** Create the terminal socket
+ */
+ status = TerminalSocket (TERM_SOCK_CREATE, &TermSock);
+ if (status != TERM_SOCK_SUCCESS)
+ exit (1);
+
+ /*
+ ** Process the terminal input
+ */
+ LogMessage ("Waiting on terminal I/O ...\n");
+ len = recv (TermSock, TermBuff, sizeof (TermBuff), 0) ;
+ TermBuff[len] = '\0';
+ LogMessage ("Received terminal I/O [%s]", TermBuff);
+
+ /*
+ ** Delete the terminal socket
+ */
+ status = TerminalSocket (TERM_SOCK_DELETE, &TermSock);
+ if (status != TERM_SOCK_SUCCESS)
+ exit (1);
+ }
+
+ return 1;
+
+}
+# endif
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+int TerminalSocket (int FunctionCode, int *ReturnSocket)
+{
+ int status;
+ $DESCRIPTOR (TerminalDeviceDesc, "SYS$COMMAND");
+
+ /*
+ ** Process the requested function code
+ */
+ switch (FunctionCode) {
+ case TERM_SOCK_CREATE:
+ /*
+ ** Create a socket pair
+ */
+ status = CreateSocketPair (AF_INET, SOCK_STREAM, 0, TerminalSocketPair);
+ if (status == -1) {
+ LogMessage ("TerminalSocket: CreateSocketPair () - %08X", status);
+ if (TerminalSocketPair[0])
+ close (TerminalSocketPair[0]);
+ if (TerminalSocketPair[1])
+ close (TerminalSocketPair[1]);
+ return (TERM_SOCK_FAILURE);
+ }
+
+ /*
+ ** Assign a channel to the terminal device
+ */
+ status = sys$assign (&TerminalDeviceDesc,
+ &TerminalDeviceChan,
+ 0, 0, 0);
+ if (! (status & 1)) {
+ LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status);
+ close (TerminalSocketPair[0]);
+ close (TerminalSocketPair[1]);
+ return (TERM_SOCK_FAILURE);
+ }
+
+ /*
+ ** Queue an async IO to the terminal device
+ */
+ status = sys$qio (EFN$C_ENF,
+ TerminalDeviceChan,
+ IO$_READVBLK,
+ &TerminalDeviceIosb,
+ TerminalDeviceAst,
+ 0,
+ TerminalDeviceBuff,
+ sizeof (TerminalDeviceBuff) - 2,
+ 0, 0, 0, 0);
+ if (! (status & 1)) {
+ LogMessage ("TerminalSocket: SYS$QIO () - %08X", status);
+ close (TerminalSocketPair[0]);
+ close (TerminalSocketPair[1]);
+ return (TERM_SOCK_FAILURE);
+ }
+
+ /*
+ ** Return the input side of the socket pair
+ */
+ *ReturnSocket = TerminalSocketPair[1];
+ break;
+
+ case TERM_SOCK_DELETE:
+ /*
+ ** Cancel any pending IO on the terminal channel
+ */
+ status = sys$cancel (TerminalDeviceChan);
+ if (! (status & 1)) {
+ LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status);
+ close (TerminalSocketPair[0]);
+ close (TerminalSocketPair[1]);
+ return (TERM_SOCK_FAILURE);
+ }
+
+ /*
+ ** Deassign the terminal channel
+ */
+ status = sys$dassgn (TerminalDeviceChan);
+ if (! (status & 1)) {
+ LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status);
+ close (TerminalSocketPair[0]);
+ close (TerminalSocketPair[1]);
+ return (TERM_SOCK_FAILURE);
+ }
+
+ /*
+ ** Close the terminal socket pair
+ */
+ close (TerminalSocketPair[0]);
+ close (TerminalSocketPair[1]);
+
+ /*
+ ** Return the initialized socket
+ */
+ *ReturnSocket = 0;
+ break;
+
+ default:
+ /*
+ ** Invalid function code
+ */
+ LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode);
+ return (TERM_SOCK_FAILURE);
+ break;
+ }
+
+ /*
+ ** Return success
+ */
+ return (TERM_SOCK_SUCCESS);
+
+}
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+static int CreateSocketPair (int SocketFamily,
+ int SocketType,
+ int SocketProtocol,
+ int *SocketPair)
+{
+ struct dsc$descriptor AscTimeDesc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
+ static const char* LocalHostAddr = {"127.0.0.1"};
+ unsigned short TcpAcceptChan = 0,
+ TcpDeviceChan = 0;
+ unsigned long BinTimeBuff[2];
+ struct sockaddr_in sin;
+ char AscTimeBuff[32];
+ short LocalHostPort;
+ int status;
+ unsigned int slen;
+
+# ifdef __alpha
+ struct _iosb iosb;
+# else
+ IOSB iosb;
+# endif
+
+ int SockDesc1 = 0,
+ SockDesc2 = 0;
+ SPTB sptb;
+ $DESCRIPTOR (TcpDeviceDesc, "TCPIP$DEVICE");
+
+ /*
+ ** Create a socket
+ */
+ SockDesc1 = socket (SocketFamily, SocketType, 0);
+ if (SockDesc1 < 0) {
+ LogMessage ("CreateSocketPair: socket () - %d", errno);
+ return (-1);
+ }
+
+ /*
+ ** Initialize the socket information
+ */
+ slen = sizeof (sin);
+ memset ((char *) &sin, 0, slen);
+ sin.sin_family = SocketFamily;
+ sin.sin_addr.s_addr = inet_addr (LocalHostAddr);
+ sin.sin_port = 0;
+
+ /*
+ ** Bind the socket to the local IP
+ */
+ status = bind (SockDesc1, (struct sockaddr *) &sin, slen);
+ if (status < 0) {
+ LogMessage ("CreateSocketPair: bind () - %d", errno);
+ close (SockDesc1);
+ return (-1);
+ }
+
+ /*
+ ** Get the socket name so we can save the port number
+ */
+ status = getsockname (SockDesc1, (struct sockaddr *) &sin, &slen);
+ if (status < 0) {
+ LogMessage ("CreateSocketPair: getsockname () - %d", errno);
+ close (SockDesc1);
+ return (-1);
+ } else
+ LocalHostPort = sin.sin_port;
+
+ /*
+ ** Setup a listen for the socket
+ */
+ listen (SockDesc1, 5);
+
+ /*
+ ** Get the binary (64-bit) time of the specified timeout value
+ */
+ sprintf (AscTimeBuff, "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE);
+ AscTimeDesc.dsc$w_length = strlen (AscTimeBuff);
+ AscTimeDesc.dsc$a_pointer = AscTimeBuff;
+ status = sys$bintim (&AscTimeDesc, BinTimeBuff);
+ if (! (status & 1)) {
+ LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status);
+ close (SockDesc1);
+ return (-1);
+ }
+
+ /*
+ ** Assign another channel to the TCP/IP device for the accept.
+ ** This is the channel that ends up being connected to.
+ */
+ status = sys$assign (&TcpDeviceDesc, &TcpDeviceChan, 0, 0, 0);
+ if (! (status & 1)) {
+ LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status);
+ close (SockDesc1);
+ return (-1);
+ }
+
+ /*
+ ** Get the channel of the first socket for the accept
+ */
+ TcpAcceptChan = decc$get_sdc (SockDesc1);
+
+ /*
+ ** Perform the accept using $QIO so we can do this asynchronously
+ */
+ status = sys$qio (EFN$C_ENF,
+ TcpAcceptChan,
+ IO$_ACCESS | IO$M_ACCEPT,
+ &iosb,
+ 0, 0, 0, 0, 0,
+ &TcpDeviceChan,
+ 0, 0);
+ if (! (status & 1)) {
+ LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status);
+ close (SockDesc1);
+ sys$dassgn (TcpDeviceChan);
+ return (-1);
+ }
+
+ /*
+ ** Create the second socket to do the connect
+ */
+ SockDesc2 = socket (SocketFamily, SocketType, 0);
+ if (SockDesc2 < 0) {
+ LogMessage ("CreateSocketPair: socket () - %d", errno);
+ sys$cancel (TcpAcceptChan);
+ close (SockDesc1);
+ sys$dassgn (TcpDeviceChan);
+ return (-1) ;
+ }
+
+ /*
+ ** Setup the Socket Pair Timeout Block
+ */
+ sptb.SockChan1 = TcpAcceptChan;
+ sptb.SockChan2 = decc$get_sdc (SockDesc2);
+
+ /*
+ ** Before we block on the connect, set a timer that can cancel I/O on our
+ ** two sockets if it never connects.
+ */
+ status = sys$setimr (EFN$C_ENF,
+ BinTimeBuff,
+ SocketPairTimeoutAst,
+ &sptb,
+ 0);
+ if (! (status & 1)) {
+ LogMessage ("CreateSocketPair: SYS$SETIMR () - %08X", status);
+ sys$cancel (TcpAcceptChan);
+ close (SockDesc1);
+ close (SockDesc2);
+ sys$dassgn (TcpDeviceChan);
+ return (-1);
+ }
+
+ /*
+ ** Now issue the connect
+ */
+ memset ((char *) &sin, 0, sizeof (sin)) ;
+ sin.sin_family = SocketFamily;
+ sin.sin_addr.s_addr = inet_addr (LocalHostAddr) ;
+ sin.sin_port = LocalHostPort ;
+
+ status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof (sin));
+ if (status < 0 ) {
+ LogMessage ("CreateSocketPair: connect () - %d", errno);
+ sys$cantim (&sptb, 0);
+ sys$cancel (TcpAcceptChan);
+ close (SockDesc1);
+ close (SockDesc2);
+ sys$dassgn (TcpDeviceChan);
+ return (-1);
+ }
+
+ /*
+ ** Wait for the asynch $QIO to finish. Note that if the I/O was aborted
+ ** (SS$_ABORT), then we probably canceled it from the AST routine - so log
+ ** a timeout.
+ */
+ status = sys$synch (EFN$C_ENF, &iosb);
+ if (! (iosb.iosb$w_status & 1)) {
+ if (iosb.iosb$w_status == SS$_ABORT)
+ LogMessage ("CreateSocketPair: SYS$QIO(iosb) timeout");
+ else {
+ LogMessage ("CreateSocketPair: SYS$QIO(iosb) - %d",
+ iosb.iosb$w_status);
+ sys$cantim (&sptb, 0);
+ }
+ close (SockDesc1);
+ close (SockDesc2);
+ sys$dassgn (TcpDeviceChan);
+ return (-1);
+ }
+
+ /*
+ ** Here we're successfully connected, so cancel the timer, convert the
+ ** I/O channel to a socket fd, close the listener socket and return the
+ ** connected pair.
+ */
+ sys$cantim (&sptb, 0);
+
+ close (SockDesc1) ;
+ SocketPair[0] = SockDesc2 ;
+ SocketPair[1] = socket_fd (TcpDeviceChan);
+
+ return (0) ;
+
+}
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+static void SocketPairTimeoutAst (int astparm)
+{
+ SPTB *sptb = (SPTB *) astparm;
+
+ sys$cancel (sptb->SockChan2); /* Cancel the connect() */
+ sys$cancel (sptb->SockChan1); /* Cancel the accept() */
+
+ return;
+
+}
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+static int TerminalDeviceAst (int astparm)
+{
+ int status;
+
+ /*
+ ** Terminate the terminal buffer
+ */
+ TerminalDeviceBuff[TerminalDeviceIosb.iosb$w_bcnt] = '\0';
+ strcat (TerminalDeviceBuff, "\n");
+
+ /*
+ ** Send the data read from the terminal device throught the socket pair
+ */
+ send (TerminalSocketPair[0], TerminalDeviceBuff,
+ TerminalDeviceIosb.iosb$w_bcnt + 1, 0);
+
+ /*
+ ** Queue another async IO to the terminal device
+ */
+ status = sys$qio (EFN$C_ENF,
+ TerminalDeviceChan,
+ IO$_READVBLK,
+ &TerminalDeviceIosb,
+ TerminalDeviceAst,
+ 0,
+ TerminalDeviceBuff,
+ sizeof (TerminalDeviceBuff) - 1,
+ 0, 0, 0, 0);
+
+ /*
+ ** Return status
+ */
+ return status;
+
+}
+\f
+/*----------------------------------------------------------------------------*/
+/* */
+/*----------------------------------------------------------------------------*/
+static void LogMessage (char *msg, ...)
+{
+ char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+ static unsigned int pid = 0;
+ va_list args;
+ time_t CurTime;
+ struct tm *LocTime;
+ char MsgBuff[256];
+
+ /*
+ ** Get the process pid
+ */
+ if (pid == 0)
+ pid = getpid ();
+
+ /*
+ ** Convert the current time into local time
+ */
+ CurTime = time (NULL);
+ LocTime = localtime (&CurTime);
+
+ /*
+ ** Format the message buffer
+ */
+ sprintf (MsgBuff, "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n",
+ LocTime->tm_mday, Month[LocTime->tm_mon],
+ (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min,
+ LocTime->tm_sec, pid, msg);
+
+ /*
+ ** Get any variable arguments and add them to the print of the message
+ ** buffer
+ */
+ va_start (args, msg);
+ vfprintf (stderr, MsgBuff, args);
+ va_end (args);
+
+ /*
+ ** Flush standard error output
+ */
+ fsync (fileno (stderr));
+
+ return;
+
+}
+#endif
--- /dev/null
+/*
+ * Copyright 2016 VMS Software, Inc. 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
+ */
+
+#ifndef TERM_SOCK_H
+# define TERM_SOCK_H
+
+/*
+** Terminal Socket Function Codes
+*/
+# define TERM_SOCK_CREATE 1
+# define TERM_SOCK_DELETE 2
+
+/*
+** Terminal Socket Status Codes
+*/
+# define TERM_SOCK_FAILURE 0
+# define TERM_SOCK_SUCCESS 1
+
+/*
+** Terminal Socket Prototype
+*/
+int TerminalSocket (int FunctionCode, int *ReturnSocket);
+
+#endif
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);
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);
/*
- * $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
/*
- * $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.
*
/*
- * $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
- * $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
/*
- * $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
- * $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
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
.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
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
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
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
.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
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
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
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
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
.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
#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.
*/
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;
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)
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;
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)
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
- ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
return (NULL);
}
* 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;
}
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;
}
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)
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
- if (pp == NULL)
+ if (pp == NULL || objsize == -1)
return objsize;
p = *pp;
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 (;;) {
*/
#include <stdio.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/asn1_mac.h>
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;
-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 */
}
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;
&eckey_asn1_meth,
#endif
&hmac_asn1_meth,
+#ifndef OPENSSL_NO_CMAC
&cmac_asn1_meth,
+#endif
#ifndef OPENSSL_NO_DH
&dhx_asn1_meth
#endif
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)
return (0);
}
if (c->inf == (1 | V_ASN1_CONSTRUCTED))
- c->slen = *length + *(c->pp) - c->p;
+ c->slen = *length;
c->eos = 0;
return (1);
}
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);
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;
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);
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;
}
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);
# 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");
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;
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;
err_sl:
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
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;
err_sl:
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
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;
err_sl:
ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
}
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;
}
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)) {
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;
}
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)
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)
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);
}
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? */
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;
#include <stddef.h>
#include <string.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
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);
/* 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... */
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);
} 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;
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);
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;
sfld = offset2ptr(*pval, adb->offset);
/* Check if NULL */
- if (!sfld) {
+ if (*sfld == NULL) {
if (!adb->null_tt)
goto err;
return adb->null_tt;
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,
bn_free,
0,
bn_c2i,
- bn_i2c
+ bn_i2c,
+ bn_print
};
ASN1_ITEM_start(BIGNUM)
}
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;
+}
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 */
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);
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;
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;
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);
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);
}
# 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) */
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;
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;
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);
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;
&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
# 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
&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!
\f
if($sse2) {
$acc0="mm0"; # mmx register bank layout
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;
.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
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";
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
.type bn_mul4x_mont,\@function,6
.align 16
bn_mul4x_mont:
+ mov ${num}d,${num}d
+ mov %rsp,%rax
.Lmul4x_enter:
___
$code.=<<___ if ($addx);
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
___
$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
.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
# 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
.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
##############################################################
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
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
.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
___
}
.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
___
.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
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)
___
.type bn_mul4x_mont_gather5,\@function,6
.align 32
bn_mul4x_mont_gather5:
+ .byte 0x67
+ mov %rsp,%rax
.Lmul4x_enter:
___
$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
# 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
.type bn_power5,\@function,6
.align 32
bn_power5:
+ mov %rsp,%rax
___
$code.=<<___ if ($addx);
mov OPENSSL_ia32cap_P+8(%rip),%r11d
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
# 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
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
# 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
.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
# 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
.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
# 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
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
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
.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
if (*(ftl--)) break; \
(a)->top = tmp_top; \
} \
+ if ((a)->top == 0) \
+ (a)->neg = 0; \
bn_pollute(a); \
}
({ asm volatile ( \
"divl %4" \
: "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
+ : "a"(n1), "d"(n0), "r"(d0) \
: "cc"); \
q; \
})
({ asm volatile ( \
"divq %4" \
: "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
+ : "a"(n1), "d"(n0), "r"(d0) \
: "cc"); \
q; \
})
{
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;
}
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;
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
*/
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;
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--;
}
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)
if (j == BN_DEC_NUM)
j = 0;
l = 0;
- while (*a) {
+ while (--i >= 0) {
l *= 10;
l += *a - '0';
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)
int BN_asc2bn(BIGNUM **bn, const char *a)
{
const char *p = a;
+
if (*p == '-')
p++;
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;
}
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;
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) {
}
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)
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
int test_div_word(BIO *bp)
{
BIGNUM a, b;
- BN_ULONG r, s;
+ BN_ULONG r, rmod, s;
int i;
BN_init(&a);
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);
/* 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;
}
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;
}
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;
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;
}
return &cms->d.signedData->certificates;
case NID_pkcs7_enveloped:
+ if (cms->d.envelopedData->originatorInfo == NULL)
+ return NULL;
return &cms->d.envelopedData->originatorInfo->certificates;
default:
return &cms->d.signedData->crls;
case NID_pkcs7_enveloped:
+ if (cms->d.envelopedData->originatorInfo == NULL)
+ return NULL;
return &cms->d.envelopedData->originatorInfo->crls;
default:
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);
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);
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);
*/
long (*ctrl) (void);
long (*callback_ctrl) (void);
-} COMP_METHOD;
+};
struct comp_ctx_st {
COMP_METHOD *meth;
#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,
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;
* 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:
* 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
* 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";
$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
THEN CC = "CC/DECC"
$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
- "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+ "''POINTER_SIZE' /NOLIST /PREFIX=ALL /EXTERN_MODEL=STRICT_REFDEF" + -
" /INCLUDE=(''CC_INCLUDES')"+ -
CCEXTRAFLAGS
$!
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
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
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
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
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;
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;
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;
}
{
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;
}
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;
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 {
goto err;
if (!seed_in) {
- if (RAND_pseudo_bytes(seed, seed_len) < 0)
+ if (RAND_bytes(seed, seed_len) <= 0)
goto err;
}
/* step 2 */
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))
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
} 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))
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
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
adc $a2, $a2
adc $a3, $a3
mov $a1, $t1
- sbb $t4, $t4
+ adc \$0, $t4
sub 8*0($a_ptr), $a0
mov $a2, $t2
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)
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]
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)
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)
.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
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)
.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
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)
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
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
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
#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
adc $acc2, $acc2
adc $acc3, $acc3
mov $acc1, $t1
- sbb $t4, $t4
+ adc \$0, $t4
sub \$-1, $acc0
mov $acc2, $t2
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);
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
#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
adc $acc2, $acc2
adc $acc3, $acc3
mov $acc1, $t1
- sbb $t4, $t4
+ adc \$0, $t4
sub \$-1, $acc0
mov $acc2, $t2
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);
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)
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)
#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)
{
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;
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;
}
* 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))
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;
}
{
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
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)
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;
}
} 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],
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])
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);
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)
{
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)
} else
#endif
{
+ BN_ULONG infty;
+
/* First window */
wvalue = (p_str[0] << 1) & mask;
index += window_size;
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;
!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;
*
*/
+#include <string.h>
#include <openssl/objects.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
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;
}
}
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;
}
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++;
}
ret = 0;
}
- return (ret);
+ return ret;
}
static int
L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c
L STORE crypto/store/store.h crypto/store/str_err.c
L TS crypto/ts/ts.h crypto/ts/ts_err.c
-L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c
+#L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c
L CMS crypto/cms/cms.h crypto/cms/cms_err.c
L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c
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
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;
* 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);
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
}
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 */
/* 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);
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)
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__) ) && \
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:
} 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)
#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)
static int convert(unsigned char *s)
{
unsigned char *d;
+ int digits = 0;
for (d = s; *s; s += 2, ++d) {
unsigned int n;
}
sscanf((char *)s, "%2x", &n);
*d = (unsigned char)n;
+ digits++;
}
- return s - d;
+ return digits;
}
static char *sstrsep(char **string, const char *delim)
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);
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;
}
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!!!
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;
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;
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:
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) {
&ec_pkey_meth,
#endif
&hmac_pkey_meth,
+#ifndef OPENSSL_NO_CMAC
&cmac_pkey_meth,
+#endif
#ifndef OPENSSL_NO_DH
&dhx_pkey_meth
#endif
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,
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);
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);
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;
}
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;
}
* <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
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);
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!"
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;
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)
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)
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 */
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;
}
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;
}
#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);
}
.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
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();
# 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)
{
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;
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
onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
if (onp == NULL) {
/* ERROR */
- return (0);
+ return 0;
}
onp->name = name;
} 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)
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);
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))
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;
}
* (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 3 May 2016"
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2i 22 Sep 2016"
# endif
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
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;
* 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. */
# 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
# define PEM_R_UNSUPPORTED_ENCRYPTION 114
# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
/* 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
"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"},
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;
}
}
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
# 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 */
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);
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);
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);
.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
.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
}
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);
/* 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 */
/* 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);
} 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++) {
/* 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;
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;
{
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])
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 */
/*
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;
} 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
/* #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 };
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];
rnd >>= 8;
}
RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
- memset(buf, 0, sizeof(buf));
+ OPENSSL_cleanse(buf, sizeof(buf));
return 1;
}
* Written by Richard Levitte <richard@levitte.org> for the OpenSSL project
* 2000.
*/
+/*
+ * Modified by VMS Software, Inc (2016)
+ * Eliminate looping through all processes (performance)
+ * Add additional randomizations using rand() function
+ */
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
*
#include "rand_lcl.h"
#if defined(OPENSSL_SYS_VMS)
-
# include <descrip.h>
# include <jpidef.h>
# include <ssdef.h>
# include <starlet.h>
+# include <efndef>
# ifdef __DECC
# pragma message disable DOLLARID
# endif
# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
static struct items_data_st {
- short length, code; /* length is amount of bytes */
+ short length, code; /* length is number of bytes */
} items_data[] = {
- {
- 4, JPI$_BUFIO
- },
- {
- 4, JPI$_CPUTIM
- },
- {
- 4, JPI$_DIRIO
- },
- {
- 8, JPI$_LOGINTIM
- },
- {
- 4, JPI$_PAGEFLTS
- },
- {
- 4, JPI$_PID
- },
- {
- 4, JPI$_WSSIZE
- },
- {
- 0, 0
- }
+ {4, JPI$_BUFIO},
+ {4, JPI$_CPUTIM},
+ {4, JPI$_DIRIO},
+ {4, JPI$_IMAGECOUNT},
+ {8, JPI$_LAST_LOGIN_I},
+ {8, JPI$_LOGINTIM},
+ {4, JPI$_PAGEFLTS},
+ {4, JPI$_PID},
+ {4, JPI$_PPGCNT},
+ {4, JPI$_WSPEAK},
+ {4, JPI$_FINALEXC},
+ {0, 0} /* zero terminated */
};
int RAND_poll(void)
{
- long pid, iosb[2];
- int status = 0;
+
+ /* determine the number of items in the JPI array */
+
+ struct items_data_st item_entry;
+ int item_entry_count = sizeof(items_data)/sizeof(item_entry);
+
+ /* Create the JPI itemlist array to hold item_data content */
+
struct {
short length, code;
- long *buffer;
+ int *buffer;
int *retlen;
- } item[32], *pitem;
- unsigned char data_buffer[256];
- short total_length = 0;
- struct items_data_st *pitems_data;
+ } item[item_entry_count], *pitem; /* number of entries in items_data */
+ struct items_data_st *pitems_data;
pitems_data = items_data;
pitem = item;
+ int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */
+ int iosb[2];
+ int sys_time[2];
+ int *ptr;
+ int i, j ;
+ int tmp_length = 0;
+ int total_length = 0;
+
+ /* Setup itemlist for GETJPI */
- /* Setup */
- while (pitems_data->length && (total_length + pitems_data->length <= 256)) {
+ while (pitems_data->length) {
pitem->length = pitems_data->length;
- pitem->code = pitems_data->code;
- pitem->buffer = (long *)&data_buffer[total_length];
+ pitem->code = pitems_data->code;
+ pitem->buffer = &data_buffer[total_length];
pitem->retlen = 0;
- total_length += pitems_data->length;
+ /* total_length is in longwords */
+ total_length += pitems_data->length/4;
pitems_data++;
pitem ++;
}
pitem->length = pitem->code = 0;
- /*
- * Scan through all the processes in the system and add entropy with
- * results from the processes that were possible to look at.
- * However, view the information as only half trustable.
- */
- pid = -1; /* search context */
- while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
- != SS$_NOMOREPROC) {
- if (status == SS$_NORMAL) {
- RAND_add((PTR_T) data_buffer, total_length, total_length / 2);
+ /* Fill data_buffer with various info bits from this process */
+ /* and twist that data to seed the SSL random number init */
+
+ if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) {
+ for (i = 0; i < total_length; i++) {
+ sys$gettim((struct _generic_64 *)&sys_time[0]);
+ srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i);
+
+ if (i == (total_length - 1)) { /* for JPI$_FINALEXC */
+ ptr = &data_buffer[i];
+ for (j = 0; j < 4; j++) {
+ data_buffer[i + j] = ptr[j];
+ /* OK to use rand() just to scramble the seed */
+ data_buffer[i + j] ^= (sys_time[0] ^ rand());
+ tmp_length++;
+ }
+ } else {
+ /* OK to use rand() just to scramble the seed */
+ data_buffer[i] ^= (sys_time[0] ^ rand());
+ }
}
+
+ total_length += (tmp_length - 1);
+
+ /* size of seed is total_length*4 bytes (64bytes) */
+ RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2);
+ } else {
+ return 0;
}
- sys$gettim(iosb);
- RAND_add((PTR_T) iosb, sizeof(iosb), sizeof(iosb) / 2);
+
return 1;
}
-
#endif
* [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>
#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
#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
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);
#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
}
#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
#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)
{
return rv;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_verify(CMS_SignerInfo *si)
{
int nid, nid2;
}
return 0;
}
+#endif
/*
* Customised RSA item verification routine. This is called when a signature
return -1;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_sign(CMS_SignerInfo *si)
{
int pad_mode = RSA_PKCS1_PADDING;
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,
return pss;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
{
EVP_PKEY_CTX *pkctx;
ASN1_STRING_free(os);
return rv;
}
+#endif
const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = {
{
{
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) {
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;
}
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);
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);
}
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;
}
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
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;
.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) {
.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
.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
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 */
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);
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))
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);
/*
* 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;
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]);
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)
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;
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);
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 = "*";
}
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);
}
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);
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);
/* 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);
{
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;
}
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;
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 */
}
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) {
* input. This is done for perfomance.
*/
+#include <openssl/crypto.h>
#include "wp_locl.h"
#include <openssl/crypto.h>
#include <string.h>
if (md) {
memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH);
- memset(c, 0, sizeof(*c));
+ OPENSSL_cleanse(c, sizeof(*c));
return (1);
}
return (0);
}
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)) {
* 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. */
/* 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
# define X509_R_WRONG_LOOKUP_TYPE 112
# define X509_R_WRONG_TYPE 122
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
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)
* 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;
}
/* 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
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"},
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);
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 */
}
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)
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:
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);
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) {
* 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;
}
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;
}
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;
}
*/
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.
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;
}
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;
}
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) {
/*
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;
}
* 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;
/* 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
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;
}
}
}
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 */
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) {
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 */
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;
}
# 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
# 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 */
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;
}
/*
* 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,
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;
}
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);
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);
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
[B<-rand file(s)>]
[B<-serverinfo types>]
[B<-status>]
+[B<-alpn protocols>]
[B<-nextprotoneg protocols>]
=head1 DESCRIPTION
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
[B<-status_verbose>]
[B<-status_timeout nsec>]
[B<-status_url url>]
+[B<-alpn protocols>]
[B<-nextprotoneg protocols>]
=head1 DESCRIPTION
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
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
[B<-use_deltas>]
[B<-policy_print>]
[B<-no_alt_chains>]
+[B<-allow_proxy_certs>]
[B<-untrusted file>]
[B<-help>]
[B<-issuer_checks>]
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
=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
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:
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
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>
=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
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
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>.
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,
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>:
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);
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.
#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.
=head1 SYNOPSIS
- unsigned int *OPENSSL_ia32cap_loc(void);
+ unsigned long *OPENSSL_ia32cap_loc(void);
#define OPENSSL_ia32cap ((OPENSSL_ia32cap_loc())[0])
=head1 DESCRIPTION
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
--- /dev/null
+=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
#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);
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.
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>.
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>).
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);
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
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);
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))) {
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))) {
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];
}
}
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);
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];
}
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);
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:
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;
(*(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);
(*(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);
/*
* 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;
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)
(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);
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);
# 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);
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);
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);
}
/* 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);
}
/* 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);
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
%define _unpackaged_files_terminate_build 0
+%define debug_package %{nil}
Release: 1
Summary: Secure Sockets Layer and cryptography libraries and tools
Name: openssl
-Version: 1.0.2h
+Version: 1.0.2i
Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
License: OpenSSL
Group: System Environment/Libraries
%build
-%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=/usr --openssldir=%{openssldir}
+%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=%{_exec_prefix} --openssldir=%{openssldir}
perl util/perlpath.pl /usr/bin/perl
%install
rm -rf $RPM_BUILD_ROOT
-make MANDIR=/usr/man MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
+make MANDIR=%{_mandir} MANSUFFIX=ssl INSTALL_PREFIX="$RPM_BUILD_ROOT" install
# Make backwards-compatibility symlink to ssleay
ln -sf /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay
%defattr(0644,root,root,0755)
%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
-%attr(0755,root,root) /usr/bin/*
-%attr(0755,root,root) /usr/lib/*.so*
+%attr(0755,root,root) %{_bindir}/*
+%attr(0755,root,root) %{_libdir}/*.so*
+%attr(0755,root,root) %{_libdir}/engines/*.so*
+%attr(0755,root,root) %{_libdir}/pkgconfig/*
%attr(0755,root,root) %{openssldir}/misc/*
-%attr(0644,root,root) /usr/man/man[157]/*
+%attr(0644,root,root) %{_mandir}/man[157]/*
%config %attr(0644,root,root) %{openssldir}/openssl.cnf
%dir %attr(0755,root,root) %{openssldir}/certs
%defattr(0644,root,root,0755)
%doc CHANGES CHANGES.SSLeay LICENSE NEWS README
-%attr(0644,root,root) /usr/lib/*.a
-%attr(0644,root,root) /usr/lib/pkgconfig/openssl.pc
-%attr(0644,root,root) /usr/include/openssl/*
-%attr(0644,root,root) /usr/man/man[3]/*
+%attr(0644,root,root) %{_libdir}/*.a
+%attr(0644,root,root) %{_libdir}/pkgconfig/openssl.pc
+%attr(0644,root,root) %{_includedir}/openssl/*
+%attr(0644,root,root) %{_mandir}/man[3]/*
%files doc
%defattr(0644,root,root,0755)
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
--- /dev/null
+/*
+ * 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;
+}
/*
* 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;
}
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)
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);
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,
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;
}
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ if (buf == NULL)
+ goto err;
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
/* 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);
/* done with handshaking */
s->d1->handshake_read_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
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) {
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);
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)
/* 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 {
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,
#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)
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;
}
}
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
#endif
-static int dtls1_process_record(SSL *s)
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
{
int i, al;
int enc_err;
/* 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:
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 */
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)) {
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);
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,
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
/*
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;
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;
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,
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)
/* 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; */
--- /dev/null
+/*
+ * 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;
+}
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)
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);
/*
* 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;
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 */
* 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,
/* 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;
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);
}
*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;
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;
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;
}
#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:
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:
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:
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;
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;
}
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))
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
*/
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,
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) {
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;
}
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,
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,
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,
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,
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,
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,
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,
SSL_3DES,
SSL_MD5,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
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,
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,
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,
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,
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,
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,
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
*/
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;
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,
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);
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;
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;
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;
/* 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;
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;
}
}
- 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;
}
/* 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);
/* 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);
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;
* 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);
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;
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);
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
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;
{
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
$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
THEN CC = "CC/DECC"
$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
- "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
+ "''POINTER_SIZE' /NOLIST /PREFIX=ALL /EXTERN_MODEL=STRICT_REFDEF" + -
" /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
$!
$! Define The Linker Options File Name.
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);
*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);
# 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
# 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
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;
}
#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;
}
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();
/* 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
{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"},
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,
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;
}
#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;
}
# 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
*/
# define SSL_EXT_FLAG_SENT 0x2
+# define MAX_WARN_ALERT_COUNT 5
+
typedef struct {
custom_ext_method *meths;
size_t meths_count;
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 {
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);
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;
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;
{
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)) ;
int r;
#endif
- if (session_id + len > limit) {
+ if (limit - session_id < len) {
fatal = 1;
goto err;
}
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';
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);
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: ");
{
BIO *err;
int testresult = 0;
- int currtest;
+ int currtest = 0;
SSL_library_init();
SSL_load_error_strings();
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
}
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);
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);
if (type != TLSEXT_TYPE_server_name)
return;
- if (data + size > limit)
+ if (limit - data < size)
return;
data += size;
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;
} else {
const size_t len = sizeof(kSafariExtensionsBlock);
- if (data + len != limit)
+ if (limit - data != (int)(len))
return;
if (memcmp(data, kSafariExtensionsBlock, len) != 0)
return;
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);
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;
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;
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;
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)
*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;
/* 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;
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);
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
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;
}
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ if (buf == NULL)
+ return -1;
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
/* 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;
}
CONSTTIMETEST= constant_time_test
VERIFYEXTRATEST= verify_extra_test
CLIENTHELLOTEST= clienthellotest
+BADDTLSTEST= bad_dtls_test
SSLV2CONFTEST = sslv2conftest
+DTLSTEST = dtlstest
TESTS= alltests
$(EVPTEST)$(EXE_EXT) $(EVPEXTRATEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT) \
$(ASN1TEST)$(EXE_EXT) $(V3NAMETEST)$(EXE_EXT) $(HEARTBEATTEST)$(EXE_EXT) \
$(CONSTTIMETEST)$(EXE_EXT) $(VERIFYEXTRATEST)$(EXE_EXT) \
- $(CLIENTHELLOTEST)$(EXE_EXT) $(SSLV2CONFTEST)$(EXE_EXT)
+ $(CLIENTHELLOTEST)$(EXE_EXT) $(SSLV2CONFTEST)$(EXE_EXT) $(DTLSTEST)$(EXE_EXT) \
+ $(BADDTLSTEST)$(EXE_EXT)
# $(METHTEST)$(EXE_EXT)
$(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o \
$(EVPTEST).o $(EVPEXTRATEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o $(V3NAMETEST).o \
$(HEARTBEATTEST).o $(CONSTTIMETEST).o $(VERIFYEXTRATEST).o \
- $(CLIENTHELLOTEST).o $(SSLV2CONFTEST).o
+ $(CLIENTHELLOTEST).o $(SSLV2CONFTEST).o $(DTLSTEST).o ssltestlib.o \
+ $(BADDTLSTEST).o
SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
$(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \
$(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c \
$(EVPTEST).c $(EVPEXTRATEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c \
$(V3NAMETEST).c $(HEARTBEATTEST).c $(CONSTTIMETEST).c $(VERIFYEXTRATEST).c \
- $(CLIENTHELLOTEST).c $(SSLV2CONFTEST).c
+ $(CLIENTHELLOTEST).c $(SSLV2CONFTEST).c $(DTLSTEST).c ssltestlib.c \
+ $(BADDTLSTEST).c
EXHEADER=
-HEADER= testutil.h $(EXHEADER)
+HEADER= testutil.h ssltestlib.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
test_jpake test_srp test_cms test_ocsp test_v3name test_heartbeat \
- test_constant_time test_verify_extra test_clienthello test_sslv2conftest
+ test_constant_time test_verify_extra test_clienthello test_sslv2conftest \
+ test_dtls test_bad_dtls
test_evp: $(EVPTEST)$(EXE_EXT) evptests.txt
../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
@echo $(START) $@
../util/shlib_wrap.sh ./$(CLIENTHELLOTEST)
+test_bad_dtls: $(BADDTLSTEST)$(EXE_EXT)
+ @echo $(START) $@
+ ../util/shlib_wrap.sh ./$(BADDTLSTEST)
+
test_sslv2conftest: $(SSLV2CONFTEST)$(EXE_EXT)
@echo $(START) $@
../util/shlib_wrap.sh ./$(SSLV2CONFTEST)
+test_dtls: $(DTLSTEST)$(EXE_EXT)
+ @echo $(START) $@
+ ../util/shlib_wrap.sh ./$(DTLSTEST) ../apps/server.pem ../apps/server.pem
+
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
fi; \
LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \
$(MAKE) -f $(TOP)/Makefile.shared -e \
- CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \
+ CC="$${CC}" APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o $$exobj" \
LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
link_app.$${shlib_target}
$(CLIENTHELLOTEST)$(EXE_EXT): $(CLIENTHELLOTEST).o
@target=$(CLIENTHELLOTEST) $(BUILD_CMD)
+$(BADDTLSTEST)$(EXE_EXT): $(BADDTLSTEST).o
+ @target=$(BADDTLSTEST) $(BUILD_CMD)
+
$(SSLV2CONFTEST)$(EXE_EXT): $(SSLV2CONFTEST).o
@target=$(SSLV2CONFTEST) $(BUILD_CMD)
+$(DTLSTEST)$(EXE_EXT): $(DTLSTEST).o ssltestlib.o $(DLIBSSL) $(DLIBCRYPTO)
+ @target=$(DTLSTEST); exobj=ssltestlib.o; $(BUILD_CMD)
+
#$(AESTEST).o: $(AESTEST).c
# $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
asn1test.o: ../include/openssl/sha.h ../include/openssl/stack.h
asn1test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
asn1test.o: ../include/openssl/x509_vfy.h asn1test.c
+bad_dtls_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+bad_dtls_test.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+bad_dtls_test.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+bad_dtls_test.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+bad_dtls_test.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+bad_dtls_test.o: ../include/openssl/err.h ../include/openssl/evp.h
+bad_dtls_test.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+bad_dtls_test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+bad_dtls_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+bad_dtls_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+bad_dtls_test.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+bad_dtls_test.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+bad_dtls_test.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+bad_dtls_test.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+bad_dtls_test.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+bad_dtls_test.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+bad_dtls_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+bad_dtls_test.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+bad_dtls_test.o: ../include/openssl/x509_vfy.h bad_dtls_test.c
bftest.o: ../e_os.h ../include/openssl/blowfish.h ../include/openssl/e_os2.h
bftest.o: ../include/openssl/opensslconf.h bftest.c
bntest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
dsatest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
dsatest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
dsatest.o: ../include/openssl/symhacks.h dsatest.c
+dtlstest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+dtlstest.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+dtlstest.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+dtlstest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+dtlstest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+dtlstest.o: ../include/openssl/err.h ../include/openssl/evp.h
+dtlstest.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+dtlstest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dtlstest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+dtlstest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dtlstest.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dtlstest.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+dtlstest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dtlstest.o: ../include/openssl/srtp.h ../include/openssl/ssl.h
+dtlstest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+dtlstest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+dtlstest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+dtlstest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h dtlstest.c
+dtlstest.o: ssltestlib.h testutil.h
ecdhtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ecdhtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
ecdhtest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
ssltest.o: ../include/openssl/x509v3.h ssltest.c
+ssltestlib.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+ssltestlib.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+ssltestlib.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
+ssltestlib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+ssltestlib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+ssltestlib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+ssltestlib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+ssltestlib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ssltestlib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssltestlib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssltestlib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssltestlib.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
+ssltestlib.o: ../include/openssl/sha.h ../include/openssl/srtp.h
+ssltestlib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssltestlib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssltestlib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssltestlib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssltestlib.o: ../include/openssl/x509_vfy.h ssltestlib.c ssltestlib.h
sslv2conftest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
sslv2conftest.o: ../include/openssl/buffer.h ../include/openssl/comp.h
sslv2conftest.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h
"MDC2TEST,RMDTEST,"+ -
"RANDTEST,DHTEST,ENGINETEST,"+ -
"BFTEST,CASTTEST,SSLTEST,EXPTEST,DSATEST,RSA_TEST,"+ -
- "EVP_TEST,IGETEST,JPAKETEST,SRPTEST,"+ -
+ "EVP_TEST,EVP_EXTRA_TEST,IGETEST,JPAKETEST,SRPTEST,"+ -
"ASN1TEST,V3NAMETEST,HEARTBEAT_TEST,"+ -
- "CONSTANT_TIME_TEST"
+ "CONSTANT_TIME_TEST,VERIFY_EXTRA_TEST,"+ -
+ "CLIENTHELLOTEST,SSLV2CONFTEST,DTLSTEST"
$! Should we add MTTEST,PQ_TEST,LH_TEST,DIVTEST,TABTEST as well?
$!
$! Additional directory information.
$ T_D_DSATEST := [-.crypto.dsa]
$ T_D_RSA_TEST := [-.crypto.rsa]
$ T_D_EVP_TEST := [-.crypto.evp]
+$ T_D_EVP_EXTRA_TEST := [-.crypto.evp]
$ T_D_IGETEST := [-.test]
$ T_D_JPAKETEST := [-.crypto.jpake]
$ T_D_SRPTEST := [-.crypto.srp]
$ T_D_ASN1TEST := [-.test]
$ T_D_HEARTBEAT_TEST := [-.ssl]
$ T_D_CONSTANT_TIME_TEST := [-.crypto]
+$ T_D_VERIFY_EXTRA_TEST := [-.crypto.x509]
+$ T_D_CLIENTHELLOTEST := [-.ssl]
+$ T_D_SSLV2CONFTEST := [-.ssl]
+$ T_D_DTLSTEST := [-.ssl]
+$
+$ EXOBJ_DTLSTEST := SSLTESTLIB
$!
$ TCPIP_PROGRAMS = ",,"
$ IF COMPILER .EQS. "VAXC" THEN -
$! Create The Object File Name.
$!
$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
+$ OBJECT_FILES = OBJECT_FILE
$!
$! Create The Executable File Name.
$!
$ EXE_FILE = EXE_DIR + FILE_NAME + ".EXE"
+$!
+$! Do the same for the possible extra unit
+$!
+$ IF F$TYPE(EXOBJ_'FILE_NAME') .NES. ""
+$ THEN
+$ EXOBJ_SOURCE_FILE = "SYS$DISK:" + EXOBJ_'FILE_NAME' + ".C"
+$ EXOBJ_OBJECT_FILE = OBJ_DIR + EXOBJ_'FILE_NAME' + ".OBJ"
+$ OBJECT_FILES = OBJECT_FILES + "," + EXOBJ_OBJECT_FILE
+$ ENDIF
+$!
$ ON WARNING THEN GOTO NEXT_FILE
$!
$! Check To See If The File We Want To Compile Actually Exists.
$!
$ ON ERROR THEN GOTO NEXT_FILE
$ CC /OBJECT='OBJECT_FILE' 'SOURCE_FILE'
+$ IF F$TYPE(EXOBJ_'FILE_NAME') .NES. ""
+$ THEN
+$ CC /OBJECT='EXOBJ_OBJECT_FILE' 'EXOBJ_SOURCE_FILE'
+$ ENDIF
$ ON WARNING THEN GOTO NEXT_FILE
$!
$! Check If What We Are About To Compile Works Without A TCP/IP Library.
$! Don't Link With The RSAREF Routines And TCP/IP Library.
$!
$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXECTABLE = 'EXE_FILE' -
- 'OBJECT_FILE', -
+ 'OBJECT_FILES', -
'SSL_LIB' /LIBRARY, -
'CRYPTO_LIB' /LIBRARY -
'TCPIP_LIB' -
$!
$! Set basic C compiler /INCLUDE directories.
$!
-$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO]"
+$ CC_INCLUDES = "SYS$DISK:[-],SYS$DISK:[-.CRYPTO],SYS$DISK:[-.TEST]"
$!
$! Check To See If P1 Is Blank.
$!
--- /dev/null
+/*
+ * 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 <string.h>
+#include <openssl/safestack.h>
+
+#include "ssltestlib.h"
+
+#define SSL_IS_DTLS(s) (s->method->version == DTLS_ANY_VERSION \
+ || s->method->version == DTLS1_2_VERSION \
+ || s->method->version == DTLS1_VERSION)
+
+static int tls_dump_new(BIO *bi);
+static int tls_dump_free(BIO *a);
+static int tls_dump_read(BIO *b, char *out, int outl);
+static int tls_dump_write(BIO *b, const char *in, int inl);
+static long tls_dump_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int tls_dump_gets(BIO *bp, char *buf, int size);
+static int tls_dump_puts(BIO *bp, const char *str);
+
+/* Choose a sufficiently large type likely to be unused for this custom BIO */
+# define BIO_TYPE_TLS_DUMP_FILTER (0x80 | BIO_TYPE_FILTER)
+
+# define BIO_TYPE_MEMPACKET_TEST 0x81
+
+static BIO_METHOD method_tls_dump = {
+ BIO_TYPE_TLS_DUMP_FILTER,
+ "TLS dump filter",
+ tls_dump_write,
+ tls_dump_read,
+ tls_dump_puts,
+ tls_dump_gets,
+ tls_dump_ctrl,
+ tls_dump_new,
+ tls_dump_free
+};
+
+BIO_METHOD *bio_f_tls_dump_filter(void)
+{
+ return &method_tls_dump;
+}
+
+static int tls_dump_new(BIO *bio)
+{
+ bio->init = 1;
+ return 1;
+}
+
+static int tls_dump_free(BIO *bio)
+{
+ bio->init = 0;
+
+ return 1;
+}
+
+static void copy_flags(BIO *bio)
+{
+ int flags;
+ BIO *next = BIO_next(bio);
+
+ flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
+ BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
+ BIO_set_flags(bio, flags);
+}
+
+#define RECORD_CONTENT_TYPE 0
+#define RECORD_VERSION_HI 1
+#define RECORD_VERSION_LO 2
+#define RECORD_EPOCH_HI 3
+#define RECORD_EPOCH_LO 4
+#define RECORD_SEQUENCE_START 5
+#define RECORD_SEQUENCE_END 10
+#define RECORD_LEN_HI 11
+#define RECORD_LEN_LO 12
+
+#define MSG_TYPE 0
+#define MSG_LEN_HI 1
+#define MSG_LEN_MID 2
+#define MSG_LEN_LO 3
+#define MSG_SEQ_HI 4
+#define MSG_SEQ_LO 5
+#define MSG_FRAG_OFF_HI 6
+#define MSG_FRAG_OFF_MID 7
+#define MSG_FRAG_OFF_LO 8
+#define MSG_FRAG_LEN_HI 9
+#define MSG_FRAG_LEN_MID 10
+#define MSG_FRAG_LEN_LO 11
+
+
+static void dump_data(const char *data, int len)
+{
+ int rem, i, content, reclen, msglen, fragoff, fraglen, epoch;
+ unsigned char *rec;
+
+ printf("---- START OF PACKET ----\n");
+
+ rem = len;
+ rec = (unsigned char *)data;
+
+ while (rem > 0) {
+ if (rem != len)
+ printf("*\n");
+ printf("*---- START OF RECORD ----\n");
+ if (rem < DTLS1_RT_HEADER_LENGTH) {
+ printf("*---- RECORD TRUNCATED ----\n");
+ break;
+ }
+ content = rec[RECORD_CONTENT_TYPE];
+ printf("** Record Content-type: %d\n", content);
+ printf("** Record Version: %02x%02x\n",
+ rec[RECORD_VERSION_HI], rec[RECORD_VERSION_LO]);
+ epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO];
+ printf("** Record Epoch: %d\n", epoch);
+ printf("** Record Sequence: ");
+ for (i = RECORD_SEQUENCE_START; i <= RECORD_SEQUENCE_END; i++)
+ printf("%02x", rec[i]);
+ reclen = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO];
+ printf("\n** Record Length: %d\n", reclen);
+
+ /* Now look at message */
+ rec += DTLS1_RT_HEADER_LENGTH;
+ rem -= DTLS1_RT_HEADER_LENGTH;
+ if (content == SSL3_RT_HANDSHAKE) {
+ printf("**---- START OF HANDSHAKE MESSAGE FRAGMENT ----\n");
+ if (epoch > 0) {
+ printf("**---- HANDSHAKE MESSAGE FRAGMENT ENCRYPTED ----\n");
+ } else if (rem < DTLS1_HM_HEADER_LENGTH
+ || reclen < DTLS1_HM_HEADER_LENGTH) {
+ printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
+ } else {
+ printf("*** Message Type: %d\n", rec[MSG_TYPE]);
+ msglen = (rec[MSG_LEN_HI] << 16) | (rec[MSG_LEN_MID] << 8)
+ | rec[MSG_LEN_LO];
+ printf("*** Message Length: %d\n", msglen);
+ printf("*** Message sequence: %d\n",
+ (rec[MSG_SEQ_HI] << 8) | rec[MSG_SEQ_LO]);
+ fragoff = (rec[MSG_FRAG_OFF_HI] << 16)
+ | (rec[MSG_FRAG_OFF_MID] << 8)
+ | rec[MSG_FRAG_OFF_LO];
+ printf("*** Message Fragment offset: %d\n", fragoff);
+ fraglen = (rec[MSG_FRAG_LEN_HI] << 16)
+ | (rec[MSG_FRAG_LEN_MID] << 8)
+ | rec[MSG_FRAG_LEN_LO];
+ printf("*** Message Fragment len: %d\n", fraglen);
+ if (fragoff + fraglen > msglen)
+ printf("***---- HANDSHAKE MESSAGE FRAGMENT INVALID ----\n");
+ else if(reclen < fraglen)
+ printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
+ else
+ printf("**---- END OF HANDSHAKE MESSAGE FRAGMENT ----\n");
+ }
+ }
+ if (rem < reclen) {
+ printf("*---- RECORD TRUNCATED ----\n");
+ rem = 0;
+ } else {
+ rec += reclen;
+ rem -= reclen;
+ printf("*---- END OF RECORD ----\n");
+ }
+ }
+ printf("---- END OF PACKET ----\n\n");
+ fflush(stdout);
+}
+
+static int tls_dump_read(BIO *bio, char *out, int outl)
+{
+ int ret;
+ BIO *next = BIO_next(bio);
+
+ ret = BIO_read(next, out, outl);
+ copy_flags(bio);
+
+ if (ret > 0) {
+ dump_data(out, ret);
+ }
+
+ return ret;
+}
+
+static int tls_dump_write(BIO *bio, const char *in, int inl)
+{
+ int ret;
+ BIO *next = BIO_next(bio);
+
+ ret = BIO_write(next, in, inl);
+ copy_flags(bio);
+
+ return ret;
+}
+
+static long tls_dump_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ long ret;
+ BIO *next = BIO_next(bio);
+
+ if (next == NULL)
+ return 0;
+
+ switch (cmd) {
+ case BIO_CTRL_DUP:
+ ret = 0L;
+ break;
+ default:
+ ret = BIO_ctrl(next, cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+static int tls_dump_gets(BIO *bio, char *buf, int size)
+{
+ /* We don't support this - not needed anyway */
+ return -1;
+}
+
+static int tls_dump_puts(BIO *bio, const char *str)
+{
+ return tls_dump_write(bio, str, strlen(str));
+}
+
+
+typedef struct mempacket_st {
+ unsigned char *data;
+ int len;
+ unsigned int num;
+ unsigned int type;
+} MEMPACKET;
+
+/*
+ * These defines would normally be auto-generated and in safestack.h...but this
+ * is just for tests so its probably not an appropriate place
+ */
+# define sk_MEMPACKET_new(cmp) SKM_sk_new(MEMPACKET, (cmp))
+# define sk_MEMPACKET_new_null() SKM_sk_new_null(MEMPACKET)
+# define sk_MEMPACKET_free(st) SKM_sk_free(MEMPACKET, (st))
+# define sk_MEMPACKET_num(st) SKM_sk_num(MEMPACKET, (st))
+# define sk_MEMPACKET_value(st, i) SKM_sk_value(MEMPACKET, (st), (i))
+# define sk_MEMPACKET_set(st, i, val) SKM_sk_set(MEMPACKET, (st), (i), (val))
+# define sk_MEMPACKET_zero(st) SKM_sk_zero(MEMPACKET, (st))
+# define sk_MEMPACKET_push(st, val) SKM_sk_push(MEMPACKET, (st), (val))
+# define sk_MEMPACKET_unshift(st, val) SKM_sk_unshift(MEMPACKET, (st), (val))
+# define sk_MEMPACKET_find(st, val) SKM_sk_find(MEMPACKET, (st), (val))
+# define sk_MEMPACKET_find_ex(st, val) SKM_sk_find_ex(MEMPACKET, (st), (val))
+# define sk_MEMPACKET_delete(st, i) SKM_sk_delete(MEMPACKET, (st), (i))
+# define sk_MEMPACKET_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEMPACKET, (st), (ptr))
+# define sk_MEMPACKET_insert(st, val, i) SKM_sk_insert(MEMPACKET, (st), (val), (i))
+# define sk_MEMPACKET_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEMPACKET, (st), (cmp))
+# define sk_MEMPACKET_dup(st) SKM_sk_dup(MEMPACKET, st)
+# define sk_MEMPACKET_pop_free(st, free_func) SKM_sk_pop_free(MEMPACKET, (st), (free_func))
+# define sk_MEMPACKET_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEMPACKET, (st), (copy_func), (free_func))
+# define sk_MEMPACKET_shift(st) SKM_sk_shift(MEMPACKET, (st))
+# define sk_MEMPACKET_pop(st) SKM_sk_pop(MEMPACKET, (st))
+# define sk_MEMPACKET_sort(st) SKM_sk_sort(MEMPACKET, (st))
+# define sk_MEMPACKET_is_sorted(st) SKM_sk_is_sorted(MEMPACKET, (st))
+
+static void mempacket_free(MEMPACKET *pkt)
+{
+ if (pkt->data != NULL)
+ OPENSSL_free(pkt->data);
+ OPENSSL_free(pkt);
+}
+
+typedef struct mempacket_test_ctx_st {
+ STACK_OF(MEMPACKET) *pkts;
+ unsigned int epoch;
+ unsigned int currrec;
+ unsigned int currpkt;
+ unsigned int lastpkt;
+ unsigned int noinject;
+} MEMPACKET_TEST_CTX;
+
+static int mempacket_test_new(BIO *bi);
+static int mempacket_test_free(BIO *a);
+static int mempacket_test_read(BIO *b, char *out, int outl);
+static int mempacket_test_write(BIO *b, const char *in, int inl);
+static long mempacket_test_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int mempacket_test_gets(BIO *bp, char *buf, int size);
+static int mempacket_test_puts(BIO *bp, const char *str);
+
+static BIO_METHOD method_mempacket_test = {
+ BIO_TYPE_MEMPACKET_TEST,
+ "Mem Packet Test",
+ mempacket_test_write,
+ mempacket_test_read,
+ mempacket_test_puts,
+ mempacket_test_gets,
+ mempacket_test_ctrl,
+ mempacket_test_new,
+ mempacket_test_free
+};
+
+BIO_METHOD *bio_s_mempacket_test(void)
+{
+ return &method_mempacket_test;
+}
+
+static int mempacket_test_new(BIO *bio)
+{
+ MEMPACKET_TEST_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return 0;
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->pkts = sk_MEMPACKET_new_null();
+ if (ctx->pkts == NULL) {
+ OPENSSL_free(ctx);
+ return 0;
+ }
+ bio->init = 1;
+ bio->ptr = ctx;
+ return 1;
+}
+
+static int mempacket_test_free(BIO *bio)
+{
+ MEMPACKET_TEST_CTX *ctx = bio->ptr;
+
+ sk_MEMPACKET_pop_free(ctx->pkts, mempacket_free);
+ OPENSSL_free(ctx);
+ bio->ptr = NULL;
+ bio->init = 0;
+
+ return 1;
+}
+
+/* Record Header values */
+#define EPOCH_HI 4
+#define EPOCH_LO 5
+#define RECORD_SEQUENCE 10
+#define RECORD_LEN_HI 11
+#define RECORD_LEN_LO 12
+
+#define STANDARD_PACKET 0
+
+static int mempacket_test_read(BIO *bio, char *out, int outl)
+{
+ MEMPACKET_TEST_CTX *ctx = bio->ptr;
+ MEMPACKET *thispkt;
+ unsigned char *rec;
+ int rem;
+ unsigned int seq, offset, len, epoch;
+
+ BIO_clear_retry_flags(bio);
+
+ thispkt = sk_MEMPACKET_value(ctx->pkts, 0);
+ if (thispkt == NULL || thispkt->num != ctx->currpkt) {
+ /* Probably run out of data */
+ BIO_set_retry_read(bio);
+ return -1;
+ }
+ (void)sk_MEMPACKET_shift(ctx->pkts);
+ ctx->currpkt++;
+
+ if (outl > thispkt->len)
+ outl = thispkt->len;
+
+ if (thispkt->type != INJECT_PACKET_IGNORE_REC_SEQ) {
+ /*
+ * Overwrite the record sequence number. We strictly number them in
+ * the order received. Since we are actually a reliable transport
+ * we know that there won't be any re-ordering. We overwrite to deal
+ * with any packets that have been injected
+ */
+ rem = thispkt->len;
+ rec = thispkt->data;
+ while (rem > 0) {
+ if (rem < DTLS1_RT_HEADER_LENGTH) {
+ return -1;
+ }
+ epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO];
+ if (epoch != ctx->epoch) {
+ ctx->epoch = epoch;
+ ctx->currrec = 0;
+ }
+ seq = ctx->currrec;
+ offset = 0;
+ do {
+ rec[RECORD_SEQUENCE - offset] = seq & 0xFF;
+ seq >>= 8;
+ offset++;
+ } while (seq > 0);
+ ctx->currrec++;
+
+ len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO])
+ + DTLS1_RT_HEADER_LENGTH;
+
+ rec += len;
+ rem -= len;
+ }
+ }
+
+ memcpy(out, thispkt->data, outl);
+
+ mempacket_free(thispkt);
+
+ return outl;
+}
+
+int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
+ int type)
+{
+ MEMPACKET_TEST_CTX *ctx = bio->ptr;
+ MEMPACKET *thispkt, *looppkt, *nextpkt;
+ int i;
+
+ if (ctx == NULL)
+ return -1;
+
+ /* We only allow injection before we've started writing any data */
+ if (pktnum >= 0) {
+ if (ctx->noinject)
+ return -1;
+ } else {
+ ctx->noinject = 1;
+ }
+
+ thispkt = OPENSSL_malloc(sizeof(MEMPACKET));
+ if (thispkt == NULL)
+ return -1;
+
+ thispkt->data = OPENSSL_malloc(inl);
+ if (thispkt->data == NULL) {
+ mempacket_free(thispkt);
+ return -1;
+ }
+
+ memcpy(thispkt->data, in, inl);
+ thispkt->len = inl;
+ thispkt->num = (pktnum >= 0) ? (unsigned int)pktnum : ctx->lastpkt;
+ thispkt->type = type;
+
+ for(i = 0; (looppkt = sk_MEMPACKET_value(ctx->pkts, i)) != NULL; i++) {
+ /* Check if we found the right place to insert this packet */
+ if (looppkt->num > thispkt->num) {
+ if (sk_MEMPACKET_insert(ctx->pkts, thispkt, i) == 0) {
+ mempacket_free(thispkt);
+ return -1;
+ }
+ /* If we're doing up front injection then we're done */
+ if (pktnum >= 0)
+ return inl;
+ /*
+ * We need to do some accounting on lastpkt. We increment it first,
+ * but it might now equal the value of injected packets, so we need
+ * to skip over those
+ */
+ ctx->lastpkt++;
+ do {
+ i++;
+ nextpkt = sk_MEMPACKET_value(ctx->pkts, i);
+ if (nextpkt != NULL && nextpkt->num == ctx->lastpkt)
+ ctx->lastpkt++;
+ else
+ return inl;
+ } while(1);
+ } else if(looppkt->num == thispkt->num) {
+ if (!ctx->noinject) {
+ /* We injected two packets with the same packet number! */
+ return -1;
+ }
+ ctx->lastpkt++;
+ thispkt->num++;
+ }
+ }
+ /*
+ * We didn't find any packets with a packet number equal to or greater than
+ * this one, so we just add it onto the end
+ */
+ if (!sk_MEMPACKET_push(ctx->pkts, thispkt)) {
+ mempacket_free(thispkt);
+ return -1;
+ }
+
+ if (pktnum < 0)
+ ctx->lastpkt++;
+
+ return inl;
+}
+
+static int mempacket_test_write(BIO *bio, const char *in, int inl)
+{
+ return mempacket_test_inject(bio, in, inl, -1, STANDARD_PACKET);
+}
+
+static long mempacket_test_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ long ret = 1;
+ MEMPACKET_TEST_CTX *ctx = bio->ptr;
+ MEMPACKET *thispkt;
+
+ switch (cmd) {
+ case BIO_CTRL_EOF:
+ ret = (long)(sk_MEMPACKET_num(ctx->pkts) == 0);
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = bio->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ bio->shutdown = (int)num;
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = 0L;
+ break;
+ case BIO_CTRL_PENDING:
+ thispkt = sk_MEMPACKET_value(ctx->pkts, 0);
+ if (thispkt == NULL)
+ ret = 0;
+ else
+ ret = thispkt->len;
+ break;
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ case BIO_CTRL_RESET:
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_PUSH:
+ case BIO_CTRL_POP:
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static int mempacket_test_gets(BIO *bio, char *buf, int size)
+{
+ /* We don't support this - not needed anyway */
+ return -1;
+}
+
+static int mempacket_test_puts(BIO *bio, const char *str)
+{
+ return mempacket_test_write(bio, str, strlen(str));
+}
+
+int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
+ SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
+ char *privkeyfile)
+{
+ SSL_CTX *serverctx = NULL;
+ SSL_CTX *clientctx = NULL;
+
+ serverctx = SSL_CTX_new(sm);
+ clientctx = SSL_CTX_new(cm);
+ if (serverctx == NULL || clientctx == NULL) {
+ printf("Failed to create SSL_CTX\n");
+ goto err;
+ }
+
+ if (SSL_CTX_use_certificate_file(serverctx, certfile,
+ SSL_FILETYPE_PEM) <= 0) {
+ printf("Failed to load server certificate\n");
+ goto err;
+ }
+ if (SSL_CTX_use_PrivateKey_file(serverctx, privkeyfile,
+ SSL_FILETYPE_PEM) <= 0) {
+ printf("Failed to load server private key\n");
+ }
+ if (SSL_CTX_check_private_key(serverctx) <= 0) {
+ printf("Failed to check private key\n");
+ goto err;
+ }
+
+ *sctx = serverctx;
+ *cctx = clientctx;
+
+ return 1;
+ err:
+ SSL_CTX_free(serverctx);
+ SSL_CTX_free(clientctx);
+ return 0;
+}
+
+#define MAXLOOPS 100000
+
+/*
+ * NOTE: Transfers control of the BIOs - this function will free them on error
+ */
+int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
+ SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio)
+{
+ SSL *serverssl, *clientssl;
+ BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
+
+ serverssl = SSL_new(serverctx);
+ clientssl = SSL_new(clientctx);
+
+ if (serverssl == NULL || clientssl == NULL) {
+ printf("Failed to create SSL object\n");
+ goto error;
+ }
+
+ if (SSL_IS_DTLS(clientssl)) {
+ s_to_c_bio = BIO_new(bio_s_mempacket_test());
+ c_to_s_bio = BIO_new(bio_s_mempacket_test());;
+ } else {
+ s_to_c_bio = BIO_new(BIO_s_mem());
+ c_to_s_bio = BIO_new(BIO_s_mem());
+ }
+ if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
+ printf("Failed to create mem BIOs\n");
+ goto error;
+ }
+
+ if (s_to_c_fbio != NULL)
+ s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio);
+ if (c_to_s_fbio != NULL)
+ c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio);
+ if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
+ printf("Failed to create chained BIOs\n");
+ goto error;
+ }
+
+ /* Set Non-blocking IO behaviour */
+ BIO_set_mem_eof_return(s_to_c_bio, -1);
+ BIO_set_mem_eof_return(c_to_s_bio, -1);
+
+ /* Up ref these as we are passing them to two SSL objects */
+ CRYPTO_add(&s_to_c_bio->references, 1, CRYPTO_LOCK_BIO);
+ CRYPTO_add(&c_to_s_bio->references, 1, CRYPTO_LOCK_BIO);
+
+ SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
+ SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
+
+ /* BIOs will now be freed when SSL objects are freed */
+ s_to_c_bio = c_to_s_bio = NULL;
+ s_to_c_fbio = c_to_s_fbio = NULL;
+
+ *sssl = serverssl;
+ *cssl = clientssl;
+
+ return 1;
+
+ error:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ BIO_free(s_to_c_bio);
+ BIO_free(c_to_s_bio);
+ BIO_free(s_to_c_fbio);
+ BIO_free(c_to_s_fbio);
+
+ return 0;
+}
+
+int create_ssl_connection(SSL *serverssl, SSL *clientssl)
+{
+ int retc = -1, rets = -1, err, abortctr = 0;
+
+ do {
+ err = SSL_ERROR_WANT_WRITE;
+ while (retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ retc = SSL_connect(clientssl);
+ if (retc <= 0)
+ err = SSL_get_error(clientssl, retc);
+ }
+
+ if (retc <= 0 && err != SSL_ERROR_WANT_READ) {
+ printf("SSL_connect() failed %d, %d\n", retc, err);
+ return 0;
+ }
+
+ err = SSL_ERROR_WANT_WRITE;
+ while (rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ rets = SSL_accept(serverssl);
+ if (rets <= 0)
+ err = SSL_get_error(serverssl, rets);
+ }
+
+ if (rets <= 0 && err != SSL_ERROR_WANT_READ) {
+ printf("SSL_accept() failed %d, %d\n", retc, err);
+ return 0;
+ }
+ if (++abortctr == MAXLOOPS) {
+ printf("No progress made\n");
+ return 0;
+ }
+ } while (retc <=0 || rets <= 0);
+
+ return 1;
+}
--- /dev/null
+/*
+ * 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
+ */
+
+#ifndef HEADER_SSLTESTLIB_H
+# define HEADER_SSLTESTLIB_H
+
+# include <openssl/ssl.h>
+
+int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
+ SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
+ char *privkeyfile);
+int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
+ SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio);
+int create_ssl_connection(SSL *serverssl, SSL *clientssl);
+
+/* Note: Not thread safe! */
+BIO_METHOD *bio_f_tls_dump_filter(void);
+void bio_f_tls_dump_filter_free(void);
+
+BIO_METHOD *bio_s_mempacket_test(void);
+void bio_s_mempacket_test_free(void);
+
+/* Packet types - value 0 is reserved */
+#define INJECT_PACKET 1
+#define INJECT_PACKET_IGNORE_REC_SEQ 2
+
+int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
+ int type);
+
+#endif /* HEADER_SSLTESTLIB_H */
test_rand,test_bn,test_ec,test_ecdsa,test_ecdh,-
test_enc,test_x509,test_rsa,test_crl,test_sid,-
test_gen,test_req,test_pkcs7,test_verify,test_dh,test_dsa,-
- test_ss,test_ca,test_engine,test_evp,test_ssl,test_tsa,test_ige,-
+ test_ss,test_ca,test_engine,test_evp,test_evp_extra,test_ssl,test_tsa,test_ige,-
test_jpake,test_srp,test_cms,test_ocsp,test_v3name,test_heartbeat,-
- test_constant_time
+ test_constant_time,test_verify_extra,test_clienthello,test_sslv2conftest,test_dtls
$ endif
$ tests = f$edit(tests,"COLLAPSE")
$
$ RSATEST := rsa_test
$ ENGINETEST := enginetest
$ EVPTEST := evp_test
+$ EVPEXTRATEST := evp_extra_test
$ IGETEST := igetest
$ JPAKETEST := jpaketest
$ SRPTEST := srptest
$ ASN1TEST := asn1test
$ HEARTBEATTEST := heartbeat_test
$ CONSTTIMETEST := constant_time_test
+$ VERIFYEXTRATEST := verify_extra_test
+$ CLIENTHELLOTEST := clienthellotest
+$ SSLV2CONFTEST := sslv2conftest
+$ DTLSTEST := dtlstest
$!
$ tests_i = 0
$ loop_tests:
$ test_evp:
$ mcr 'texe_dir''evptest' 'ROOT'.CRYPTO.EVP]evptests.txt
$ return
+$ test_evp_extra:
+$ mcr 'texe_dir''evpextratest'
+$ return
$ test_des:
$ mcr 'texe_dir''destest'
$ return
$ write sys$output "Test constant time utilities"
$ mcr 'texe_dir''consttimetest'
$ return
-$
+$ test_verify_extra:
+$ write sys$output "''START' test_verify_extra"
+$ mcr 'texe_dir''verifyextratest'
+$ return
+$ test_clienthello:
+$ write sys$output "''START' test_clienthello"
+$ mcr 'texe_dir''clienthellotest'
+$ return
+$ test_sslv2conftest:
+$ write sys$output "''START' test_sslv2conftest"
+$ mcr 'texe_dir''sslv2conftest'
+$ return
+$ test_dtls:
+$ write sys$output "''START' test_dtls"
+$ mcr 'texe_dir''dtlstest' 'ROOT'.APPS]server.pem 'ROOT'.APPS]server.pem
+$ return
$
$ exit:
$ on error then goto exit2 ! In case openssl.exe didn't build.
$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;
$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)');
{
$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)");
}
"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,
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>) {
# 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",
" */\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";
}
* 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";
}
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.
my $hincf;
if($static) {
- $hfile =~ /([^\/]+)$/;
- $hincf = "<${hprefix}$1>";
+ $hincf = $hfile;
+ $hincf =~ s|.*/||g;
+ $hincf = "<${hprefix}${hincf}>";
} else {
$hincf = "\"$hfile\"";
}
$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";
$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";
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
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:
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:
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