diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..027980b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/openssl-fips-0.9.8e-usa.tar.bz2 diff --git a/.openssl098e.metadata b/.openssl098e.metadata new file mode 100644 index 0000000..5cbc049 --- /dev/null +++ b/.openssl098e.metadata @@ -0,0 +1 @@ +eb8c4675f69f19440b49033b93e11e0fa8977aa8 SOURCES/openssl-fips-0.9.8e-usa.tar.bz2 diff --git a/SOURCES/README.FIPS b/SOURCES/README.FIPS new file mode 100644 index 0000000..b99b437 --- /dev/null +++ b/SOURCES/README.FIPS @@ -0,0 +1,108 @@ +User guide for the FIPS Red Hat Enterprise Linux - OpenSSL Module +================================================================= + +This package contains libraries which comprise the FIPS 140-2 +Red Hat Enterprise Linux - OPENSSL Module. + +The module files +================ +/lib[64]/libcrypto.so.0.9.8e +/lib[64]/libssl.so.0.9.8e +/lib[64]/.libcrypto.so.0.9.8e.hmac +/lib[64]/.libssl.so.0.9.8e.hmac + +Dependencies +============ + +The approved mode of operation requires kernel with /dev/urandom RNG running +with properties as defined in the security policy of the module. This is +provided by kernel packages with validated Red Hat Enterprise Linux - IPSec +Crytographic Module. + +Installation +============ + +The RPM package of the module can be installed by standard tools recommended +for installation of RPM packages on the Red Hat Enterprise Linux system (yum, +rpm, RHN remote management tool). + +For proper operation of the in-module integrity verification the prelink has to +be disabled. This can be done with setting PRELINKING=no in the +/etc/sysconfig/prelink configuration file. If the libraries were already +prelinked the prelink should be undone on all the system files with the +'prelink -u -a' command. + +Usage and API +============= + +The module respects kernel command line FIPS setting. If the kernel command +line contains option fips=1 the module will initialize in the FIPS approved +mode of operation automatically. To allow for the automatic initialization the +application using the module has to call one of the following API calls: + +- void OPENSSL_init(void) - this will do only a basic initialization of the +library and does initialization of the FIPS approved mode without setting up +EVP API with supported algorithms. + +- void OPENSSL_add_all_algorithms(void) - this API function calls +OPENSSL_init() implicitly and also adds all approved algorithms to the EVP API +in the approved mode + +- void SSL_library_init(void) - it calls OPENSSL_init() implicitly and also +adds algorithms which are necessary for TLS protocol support and initializes +the SSL library. + +To explicitely put the library to the approved mode the application can call +the following function: + +- int FIPS_mode_set(int on) - if called with 1 as a parameter it will switch +the library from the non-approved to the approved mode. If any of the selftests +and integrity verification tests fail, the library is put into the error state +and 0 is returned. If they succeed the return value is 1. + +To query the module whether it is in the approved mode or not: + +- int FIPS_mode(void) - returns 1 if the module is in the approved mode, +0 otherwise. + +To query whether the module is in the error state: + +- int FIPS_selftest_failed(void) - returns 1 if the module is in the error +state, 0 otherwise. + +To zeroize the FIPS RNG key and internal state the application calls: + +- void RAND_cleanup(void) + +Possible error states of the OpenSSL FIPS module +================================================ + +The effects of self-test failures in the OpenSSL module differ depending +on the type of self-test that failed.   +The FIPS_mode_set() function verifies the integrity of the runtime executable +using a HMAC SHA-256 digest, which is computed at build time. If this computed +HMAC SHA-256 digest matches the stored, known digest, then the power-up +self-test (consisting of the algorithm-specific Pairwise Consistency and Known +Answer tests) is performed. + +Non-fatal self-test errors transition the module into an error state. The +application must be restarted to recover from these errors. The non-fatal +self-test errors are: +FIPS_R_FINGERPRINT_DOES_NOT_MATCH - the integrity verification check failed +FIPS_R_FIPS_SELFTEST_FAILED - a known answer test failed +FIPS_R_PAIRWISE_TEST_FAILED – a pairwise consistency test during DSA or RSA + key generation failed +FIPS_R_FIPS_MODE_ALREADY_SET - the application tries to initialize the FIPS + approved mode when it is already initialized +These errors are reported through the regular ERR interface of the OpenSSL +library and can be queried by functions such as ERR_get_error(). See the +OpenSSL manual page for the function description. + +A fatal error occurs only when the module is already in the error state +(a self test has failed) and the application calls a crypto function of +the module that cannot return an error in normal circumstances (void return +functions). The error message: 'FATAL FIPS SELFTEST FAILURE' is printed to +stderr and the application is terminated with the abort() call. +The only way to recover from a fatal error is to restart the application. +If failures persist, you must reinstall the Module. If you downloaded the +software, verify the package hash to confirm a proper download. diff --git a/SOURCES/hobble-openssl b/SOURCES/hobble-openssl new file mode 100755 index 0000000..de0490f --- /dev/null +++ b/SOURCES/hobble-openssl @@ -0,0 +1,45 @@ +#!/bin/sh + +# Quit out if anything fails. +set -e + +# Clean out patent-or-otherwise-encumbered code. +# MDC-2: 4,908,861 13/03/2007 +# IDEA: 5,214,703 25/05/2010 +# RC5: 5,724,428 03/03/2015 +# EC: ????????? ??/??/2015 + +# Remove assembler portions of IDEA, MDC2, and RC5. +(find crypto/{idea,mdc2,rc5}/asm -type f | xargs -r rm -fv) + +# IDEA, MDC2, RC5, EC. +for a in idea mdc2 rc5 ec ecdh ecdsa; do + for c in `find crypto/$a -name "*.c" -a \! -name "*test*" -type f` ; do + echo Destroying $c + > $c + done +done + +for c in `find crypto/evp -name "*_rc5.c" -o -name "*_idea.c" -o -name "*_mdc2.c" -o -name "*_ecdsa.c"`; do + echo Destroying $c + > $c +done + +for h in `find crypto ssl apps test -name "*.h"` ; do + echo Removing IDEA, MDC2, RC5, and EC references from $h + cat $h | \ + awk 'BEGIN {ech=1;} \ + /^#[ \t]*ifndef.*NO_IDEA/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_MDC2/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_RC5/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_EC/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_ECDH/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_ECDSA/ {ech--; next;} \ + /^#[ \t]*if/ {if(ech < 1) ech--;} \ + {if(ech>0) {;print $0};} \ + /^#[ \t]*endif/ {if(ech < 1) ech++;}' > $h.hobbled && \ + mv $h.hobbled $h +done + +# Make the makefiles happy. +touch crypto/rc5/asm/rc5-586.pl diff --git a/SOURCES/openssl-0.9.6-x509.patch b/SOURCES/openssl-0.9.6-x509.patch new file mode 100644 index 0000000..7b3f49f --- /dev/null +++ b/SOURCES/openssl-0.9.6-x509.patch @@ -0,0 +1,29 @@ +Do not treat duplicate certs as an error. + +--- openssl-0.9.6/crypto/x509/by_file.c Wed Sep 27 15:09:05 2000 ++++ openssl-0.9.6/crypto/x509/by_file.c Wed Sep 27 14:21:20 2000 +@@ -163,8 +163,12 @@ + } + } + i=X509_STORE_add_cert(ctx->store_ctx,x); +- if (!i) goto err; +- count++; ++ /* ignore any problems with current certificate ++ and continue with the next one */ ++ if (i) ++ count++; ++ else ++ ERR_clear_error(); + X509_free(x); + x=NULL; + } +@@ -179,7 +183,8 @@ + goto err; + } + i=X509_STORE_add_cert(ctx->store_ctx,x); +- if (!i) goto err; ++ if (!i) ++ ERR_clear_error(); + ret=i; + } + else diff --git a/SOURCES/openssl-0.9.7-beta5-version-add-engines.patch b/SOURCES/openssl-0.9.7-beta5-version-add-engines.patch new file mode 100644 index 0000000..24889b1 --- /dev/null +++ b/SOURCES/openssl-0.9.7-beta5-version-add-engines.patch @@ -0,0 +1,49 @@ +List the compiled-in hardware support when passed the -a flag. + +--- openssl-0.9.7-beta5/apps/version.c 2002-12-03 11:34:28.000000000 -0500 ++++ openssl-0.9.7-beta5/apps/version.c 2002-12-11 19:29:10.000000000 -0500 +@@ -130,6 +130,7 @@ + #ifndef OPENSSL_NO_BF + # include + #endif ++#include + + #undef PROG + #define PROG version_main +@@ -139,7 +140,7 @@ + int MAIN(int argc, char **argv) + { + int i,ret=0; +- int cflags=0,version=0,date=0,options=0,platform=0,dir=0; ++ int cflags=0,version=0,date=0,options=0,platform=0,dir=0,engines=0; + + apps_startup(); + +@@ -163,7 +164,7 @@ + else if (strcmp(argv[i],"-d") == 0) + dir=1; + else if (strcmp(argv[i],"-a") == 0) +- date=version=cflags=options=platform=dir=1; ++ date=version=cflags=options=platform=dir=engines=1; + else + { + BIO_printf(bio_err,"usage:version -[avbofp]\n"); +@@ -198,6 +199,18 @@ + } + if (cflags) printf("%s\n",SSLeay_version(SSLEAY_CFLAGS)); + if (dir) printf("%s\n",SSLeay_version(SSLEAY_DIR)); ++ if (engines) ++ { ++ ENGINE *e; ++ printf("engines: "); ++ e = ENGINE_get_first(); ++ while (e) ++ { ++ printf("%s ", ENGINE_get_id(e)); ++ e = ENGINE_get_next(e); ++ } ++ printf("\n"); ++ } + end: + apps_shutdown(); + OPENSSL_EXIT(ret); diff --git a/SOURCES/openssl-0.9.8a-defaults.patch b/SOURCES/openssl-0.9.8a-defaults.patch new file mode 100644 index 0000000..5a4db7b --- /dev/null +++ b/SOURCES/openssl-0.9.8a-defaults.patch @@ -0,0 +1,50 @@ +--- openssl-0.9.8a/apps/openssl.cnf.defaults 2005-09-16 14:20:24.000000000 +0200 ++++ openssl-0.9.8a/apps/openssl.cnf 2005-11-04 11:00:37.000000000 +0100 +@@ -99,6 +99,7 @@ + #################################################################### + [ req ] + default_bits = 1024 ++default_md = sha1 + default_keyfile = privkey.pem + distinguished_name = req_distinguished_name + attributes = req_attributes +@@ -116,23 +117,26 @@ + # MASK:XXXX a literal mask value. + # WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings + # so use this option with caution! +-string_mask = nombstr ++# we use PrintableString+UTF8String mask so if pure ASCII texts are used ++# the resulting certificates are compatible with Netscape ++string_mask = MASK:0x2002 + + # req_extensions = v3_req # The extensions to add to a certificate request + + [ req_distinguished_name ] + countryName = Country Name (2 letter code) +-countryName_default = AU ++countryName_default = GB + countryName_min = 2 + countryName_max = 2 + + stateOrProvinceName = State or Province Name (full name) +-stateOrProvinceName_default = Some-State ++stateOrProvinceName_default = Berkshire + + localityName = Locality Name (eg, city) ++localityName_default = Newbury + + 0.organizationName = Organization Name (eg, company) +-0.organizationName_default = Internet Widgits Pty Ltd ++0.organizationName_default = My Company Ltd + + # we can do this but it is not needed normally :-) + #1.organizationName = Second Organization Name (eg, company) +@@ -141,7 +145,7 @@ + organizationalUnitName = Organizational Unit Name (eg, section) + #organizationalUnitName_default = + +-commonName = Common Name (eg, YOUR name) ++commonName = Common Name (eg, your name or your server\'s hostname) + commonName_max = 64 + + emailAddress = Email Address diff --git a/SOURCES/openssl-0.9.8a-link-krb5.patch b/SOURCES/openssl-0.9.8a-link-krb5.patch new file mode 100644 index 0000000..f34b1e5 --- /dev/null +++ b/SOURCES/openssl-0.9.8a-link-krb5.patch @@ -0,0 +1,11 @@ +--- openssl-0.9.8a/Makefile.org.link-krb5 2005-07-05 07:14:21.000000000 +0200 ++++ openssl-0.9.8a/Makefile.org 2005-11-07 18:00:08.000000000 +0100 +@@ -266,7 +266,7 @@ + + do_$(SHLIB_TARGET): + @ set -e; libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \ +- if [ "${SHLIBDIRS}" = "ssl" -a -n "$(LIBKRB5)" ]; then \ ++ if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \ + libs="$(LIBKRB5) $$libs"; \ + fi; \ + $(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \ diff --git a/SOURCES/openssl-0.9.8a-no-rpath.patch b/SOURCES/openssl-0.9.8a-no-rpath.patch new file mode 100644 index 0000000..8f8fb91 --- /dev/null +++ b/SOURCES/openssl-0.9.8a-no-rpath.patch @@ -0,0 +1,11 @@ +--- openssl-0.9.8a/Makefile.shared.no-rpath 2005-06-23 22:47:54.000000000 +0200 ++++ openssl-0.9.8a/Makefile.shared 2005-11-16 22:35:37.000000000 +0100 +@@ -153,7 +153,7 @@ + NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ + SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" + +-DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)" ++DO_GNU_APP=LDFLAGS="$(CFLAGS)" + + #This is rather special. It's a special target with which one can link + #applications without bothering with any features that have anything to diff --git a/SOURCES/openssl-0.9.8a-reuse-cipher-change.patch b/SOURCES/openssl-0.9.8a-reuse-cipher-change.patch new file mode 100644 index 0000000..666688b --- /dev/null +++ b/SOURCES/openssl-0.9.8a-reuse-cipher-change.patch @@ -0,0 +1,20 @@ +--- openssl-0.9.8a/ssl/ssl.h.cipher-change 2005-11-22 16:36:22.000000000 +0100 ++++ openssl-0.9.8a/ssl/ssl.h 2005-12-15 11:28:05.000000000 +0100 +@@ -477,7 +477,7 @@ + + #define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L + #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +-#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L ++#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L /* can break some security expectations */ + #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L + #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L + #define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */ +@@ -494,7 +494,7 @@ + + /* SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. */ +-#define SSL_OP_ALL 0x00000FFFL ++#define SSL_OP_ALL 0x00000FF7L /* without SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG */ + + /* DTLS options */ + #define SSL_OP_NO_QUERY_MTU 0x00001000L diff --git a/SOURCES/openssl-0.9.8b-aliasing-bug.patch b/SOURCES/openssl-0.9.8b-aliasing-bug.patch new file mode 100644 index 0000000..8d3b36a --- /dev/null +++ b/SOURCES/openssl-0.9.8b-aliasing-bug.patch @@ -0,0 +1,24 @@ + +This patch fixes a violation of the C aliasing rules that can cause +miscompilation with some compiler versions. + +--- openssl-0.9.8b/crypto/dso/dso_dlfcn.c.orig 2006-10-30 18:21:35.000000000 +0100 ++++ openssl-0.9.8b/crypto/dso/dso_dlfcn.c 2006-10-30 18:21:37.000000000 +0100 +@@ -237,7 +237,7 @@ static void *dlfcn_bind_var(DSO *dso, co + static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) + { + void *ptr; +- DSO_FUNC_TYPE sym, *tsym = &sym; ++ DSO_FUNC_TYPE sym; + + if((dso == NULL) || (symname == NULL)) + { +@@ -255,7 +255,7 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO + DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); + return(NULL); + } +- *(void **)(tsym) = dlsym(ptr, symname); ++ sym = dlsym(ptr, symname); + if(sym == NULL) + { + DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); diff --git a/SOURCES/openssl-0.9.8b-cve-2007-5135.patch b/SOURCES/openssl-0.9.8b-cve-2007-5135.patch new file mode 100644 index 0000000..49e2fff --- /dev/null +++ b/SOURCES/openssl-0.9.8b-cve-2007-5135.patch @@ -0,0 +1,45 @@ +Possible one byte buffer overflow in SSL_get_shared_ciphers. +CVE-2007-5135 +diff -up openssl-0.9.8b/ssl/ssl_lib.c.orig openssl-0.9.8b/ssl/ssl_lib.c +--- openssl-0.9.8b/ssl/ssl_lib.c.orig 2007-10-08 10:20:42.000000000 +0200 ++++ openssl-0.9.8b/ssl/ssl_lib.c 2007-10-08 17:32:29.000000000 +0200 +@@ -1201,7 +1201,6 @@ int SSL_set_cipher_list(SSL *s,const cha + char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) + { + char *p; +- const char *cp; + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *c; + int i; +@@ -1214,20 +1213,21 @@ char *SSL_get_shared_ciphers(const SSL * + sk=s->session->ciphers; + for (i=0; iname; *cp; ) ++ n=strlen(c->name); ++ if (n+1 > len) + { +- if (len-- <= 0) +- { +- *p='\0'; +- return(buf); +- } +- else +- *(p++)= *(cp++); ++ if (p != buf) ++ --p; ++ *p='\0'; ++ return buf; + } ++ strcpy(p,c->name); ++ p+=n; + *(p++)=':'; ++ len-=n+1; + } + p[-1]='\0'; + return(buf); diff --git a/SOURCES/openssl-0.9.8b-ipv6-apps.patch b/SOURCES/openssl-0.9.8b-ipv6-apps.patch new file mode 100644 index 0000000..87718f0 --- /dev/null +++ b/SOURCES/openssl-0.9.8b-ipv6-apps.patch @@ -0,0 +1,510 @@ +diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_apps.h openssl-0.9.8b/apps/s_apps.h +--- openssl-0.9.8b.orig/apps/s_apps.h 2006-07-11 16:14:29.000000000 +0200 ++++ openssl-0.9.8b/apps/s_apps.h 2006-07-13 08:44:29.000000000 +0200 +@@ -148,7 +148,7 @@ + #define PORT_STR "4433" + #define PROTOCOL "tcp" + +-int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); ++int do_server(char *port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); + #ifdef HEADER_X509_H + int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); + #endif +@@ -156,10 +156,9 @@ + int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); + int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); + #endif +-int init_client(int *sock, char *server, int port, int type); ++int init_client(int *sock, char *server, char *port, int type); + int should_retry(int i); +-int extract_port(char *str, short *port_ptr); +-int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p); ++int extract_host_port(char *str,char **host_ptr,char **port_ptr); + + long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, + int argi, long argl, long ret); +diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_client.c openssl-0.9.8b/apps/s_client.c +--- openssl-0.9.8b.orig/apps/s_client.c 2005-11-25 14:46:41.000000000 +0100 ++++ openssl-0.9.8b/apps/s_client.c 2006-07-13 08:44:29.000000000 +0200 +@@ -246,7 +246,7 @@ + int cbuf_len,cbuf_off; + int sbuf_len,sbuf_off; + fd_set readfds,writefds; +- short port=PORT; ++ char *port_str = PORT_STR; + int full_log=1; + char *host=SSL_HOST_NAME; + char *cert_file=NULL,*key_file=NULL; +@@ -330,13 +330,12 @@ + else if (strcmp(*argv,"-port") == 0) + { + if (--argc < 1) goto bad; +- port=atoi(*(++argv)); +- if (port == 0) goto bad; ++ port_str= *(++argv); + } + else if (strcmp(*argv,"-connect") == 0) + { + if (--argc < 1) goto bad; +- if (!extract_host_port(*(++argv),&host,NULL,&port)) ++ if (!extract_host_port(*(++argv),&host,&port_str)) + goto bad; + } + else if (strcmp(*argv,"-verify") == 0) +@@ -619,7 +618,7 @@ + + re_start: + +- if (init_client(&s,host,port,sock_type) == 0) ++ if (init_client(&s,host,port_str,sock_type) == 0) + { + BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); + SHUTDOWN(s); +diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_server.c openssl-0.9.8b/apps/s_server.c +--- openssl-0.9.8b.orig/apps/s_server.c 2005-09-02 14:27:02.000000000 +0200 ++++ openssl-0.9.8b/apps/s_server.c 2006-07-13 08:44:29.000000000 +0200 +@@ -532,7 +532,7 @@ + { + X509_STORE *store = NULL; + int vflags = 0; +- short port=PORT; ++ char *port_str = PORT_STR; + char *CApath=NULL,*CAfile=NULL; + unsigned char *context = NULL; + char *dhfile = NULL; +@@ -597,8 +597,7 @@ + (strcmp(*argv,"-accept") == 0)) + { + if (--argc < 1) goto bad; +- if (!extract_port(*(++argv),&port)) +- goto bad; ++ port_str= *(++argv); + } + else if (strcmp(*argv,"-verify") == 0) + { +@@ -1086,9 +1085,9 @@ + + BIO_printf(bio_s_out,"ACCEPT\n"); + if (www) +- do_server(port,sock_type,&accept_socket,www_body, context); ++ do_server(port_str,sock_type,&accept_socket,www_body, context); + else +- do_server(port,sock_type,&accept_socket,sv_body, context); ++ do_server(port_str,sock_type,&accept_socket,sv_body, context); + print_stats(bio_s_out,ctx); + ret=0; + end: +diff --exclude-from=exclude-diff-openssl-0.9.8b -bru openssl-0.9.8b.orig/apps/s_socket.c openssl-0.9.8b/apps/s_socket.c +--- openssl-0.9.8b.orig/apps/s_socket.c 2005-06-13 05:21:00.000000000 +0200 ++++ openssl-0.9.8b/apps/s_socket.c 2006-07-13 08:44:29.000000000 +0200 +@@ -96,9 +96,7 @@ + static void ssl_sock_cleanup(void); + #endif + static int ssl_sock_init(void); +-static int init_client_ip(int *sock,unsigned char ip[4], int port, int type); +-static int init_server(int *sock, int port, int type); +-static int init_server_long(int *sock, int port,char *ip, int type); ++static int init_server(int *sock, char *port, int type); + static int do_accept(int acc_sock, int *sock, char **host); + static int host_ip(char *str, unsigned char ip[4]); + +@@ -228,60 +226,69 @@ + return(1); + } + +-int init_client(int *sock, char *host, int port, int type) ++int init_client(int *sock, char *host, char *port, int type) + { +- unsigned char ip[4]; +- short p=0; +- +- if (!host_ip(host,&(ip[0]))) +- { +- return(0); +- } +- if (p != 0) port=p; +- return(init_client_ip(sock,ip,port,type)); +- } +- +-static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) +- { +- unsigned long addr; +- struct sockaddr_in them; +- int s,i; ++ struct addrinfo *res, *res0, hints; ++ char * failed_call = NULL; ++ int s; ++ int e; + + if (!ssl_sock_init()) return(0); + +- memset((char *)&them,0,sizeof(them)); +- them.sin_family=AF_INET; +- them.sin_port=htons((unsigned short)port); +- addr=(unsigned long) +- ((unsigned long)ip[0]<<24L)| +- ((unsigned long)ip[1]<<16L)| +- ((unsigned long)ip[2]<< 8L)| +- ((unsigned long)ip[3]); +- them.sin_addr.s_addr=htonl(addr); +- +- if (type == SOCK_STREAM) +- s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); +- else /* ( type == SOCK_DGRAM) */ +- s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); +- +- if (s == INVALID_SOCKET) { perror("socket"); return(0); } ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_socktype = type; ++ hints.ai_flags = AI_ADDRCONFIG; ++ ++ e = getaddrinfo(host, port, &hints, &res); ++ if (e) ++ { ++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); ++ if (e == EAI_SYSTEM) ++ perror("getaddrinfo"); ++ return (0); ++ } + ++ res0 = res; ++ while (res) ++ { ++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); ++ if (s == INVALID_SOCKET) ++ { ++ failed_call = "socket"; ++ goto nextres; ++ } + #ifndef OPENSSL_SYS_MPE + if (type == SOCK_STREAM) + { +- i=0; +- i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); +- if (i < 0) { perror("keepalive"); return(0); } ++ int i=0; ++ i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE, ++ (char *)&i,sizeof(i)); ++ if (i < 0) { ++ failed_call = "keepalive"; ++ goto nextres; ++ } + } + #endif +- +- if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1) +- { close(s); perror("connect"); return(0); } ++ if (connect(s,(struct sockaddr *)res->ai_addr, ++ res->ai_addrlen) == 0) ++ { ++ freeaddrinfo(res0); + *sock=s; + return(1); + } ++ failed_call = "socket"; ++nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; ++ } ++ freeaddrinfo(res0); ++ ++ perror(failed_call); ++ return(0); ++ } + +-int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) ++int do_server(char *port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) + { + int sock; + char *name = NULL; +@@ -319,33 +326,38 @@ + } + } + +-static int init_server_long(int *sock, int port, char *ip, int type) ++static int init_server(int *sock, char *port, int type) + { +- int ret=0; +- struct sockaddr_in server; +- int s= -1,i; ++ struct addrinfo *res, *res0, hints; ++ char * failed_call = NULL; ++ char port_name[8]; ++ int s; ++ int e; + + if (!ssl_sock_init()) return(0); + +- memset((char *)&server,0,sizeof(server)); +- server.sin_family=AF_INET; +- server.sin_port=htons((unsigned short)port); +- if (ip == NULL) +- server.sin_addr.s_addr=INADDR_ANY; +- else +-/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ +-#ifndef BIT_FIELD_LIMITS +- memcpy(&server.sin_addr.s_addr,ip,4); +-#else +- memcpy(&server.sin_addr,ip,4); +-#endif +- +- if (type == SOCK_STREAM) +- s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); +- else /* type == SOCK_DGRAM */ +- s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP); ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_socktype = type; ++ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; ++ ++ e = getaddrinfo(NULL, port, &hints, &res); ++ if (e) ++ { ++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); ++ if (e == EAI_SYSTEM) ++ perror("getaddrinfo"); ++ return (0); ++ } + +- if (s == INVALID_SOCKET) goto err; ++ res0 = res; ++ while (res) ++ { ++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); ++ if (s == INVALID_SOCKET) ++ { ++ failed_call = "socket"; ++ goto nextres; ++ } + #if defined SOL_SOCKET && defined SO_REUSEADDR + { + int j = 1; +@@ -353,36 +365,39 @@ + (void *) &j, sizeof j); + } + #endif +- if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) ++ ++ if (bind(s,(struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) + { +-#ifndef OPENSSL_SYS_WINDOWS +- perror("bind"); +-#endif +- goto err; ++ failed_call = "bind"; ++ goto nextres; + } +- /* Make it 128 for linux */ +- if (type==SOCK_STREAM && listen(s,128) == -1) goto err; +- i=0; +- *sock=s; +- ret=1; +-err: +- if ((ret == 0) && (s != -1)) ++ if (type==SOCK_STREAM && listen(s,128) == -1) + { +- SHUTDOWN(s); ++ failed_call = "listen"; ++ goto nextres; + } +- return(ret); ++ ++ *sock=s; ++ return(1); ++ ++nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; + } ++ freeaddrinfo(res0); + +-static int init_server(int *sock, int port, int type) +- { +- return(init_server_long(sock, port, NULL, type)); ++ if (s == INVALID_SOCKET) { perror("socket"); return(0); } ++ ++ perror(failed_call); ++ return(0); + } + + static int do_accept(int acc_sock, int *sock, char **host) + { +- int ret,i; +- struct hostent *h1,*h2; +- static struct sockaddr_in from; ++ static struct sockaddr_storage from; ++ char buffer[NI_MAXHOST]; ++ int ret; + int len; + /* struct linger ling; */ + +@@ -427,137 +442,62 @@ + if (i < 0) { perror("keepalive"); return(0); } + */ + +- if (host == NULL) goto end; +-#ifndef BIT_FIELD_LIMITS +- /* I should use WSAAsyncGetHostByName() under windows */ +- h1=gethostbyaddr((char *)&from.sin_addr.s_addr, +- sizeof(from.sin_addr.s_addr),AF_INET); +-#else +- h1=gethostbyaddr((char *)&from.sin_addr, +- sizeof(struct in_addr),AF_INET); +-#endif +- if (h1 == NULL) ++ if (host == NULL) + { +- BIO_printf(bio_err,"bad gethostbyaddr\n"); +- *host=NULL; +- /* return(0); */ +- } +- else +- { +- if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL) +- { +- perror("OPENSSL_malloc"); +- return(0); ++ *sock=ret; ++ return(1); + } +- BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1); + +- h2=GetHostByName(*host); +- if (h2 == NULL) ++ if (getnameinfo((struct sockaddr *)&from, sizeof(from), ++ buffer, sizeof(buffer), ++ NULL, 0, 0)) + { +- BIO_printf(bio_err,"gethostbyname failure\n"); ++ BIO_printf(bio_err,"getnameinfo failed\n"); ++ *host=NULL; *sock=ret; ++ return(1); +- return(0); + } +- i=0; +- if (h2->h_addrtype != AF_INET) ++ else + { +- BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); ++ if ((*host=(char *)OPENSSL_malloc(strlen(buffer)+1)) == NULL) ++ { ++ perror("OPENSSL_malloc"); + return(0); + } +- } +-end: ++ strcpy(*host, buffer); + *sock=ret; + return(1); + } ++ } + +-int extract_host_port(char *str, char **host_ptr, unsigned char *ip, +- short *port_ptr) ++int extract_host_port(char *str, char **host_ptr, ++ char **port_ptr) + { +- char *h,*p; ++ char *h,*p,*x; + +- h=str; +- p=strchr(str,':'); ++ x=h=str; ++ if (*h == '[') ++ { ++ h++; ++ p=strchr(h,']'); + if (p == NULL) + { +- BIO_printf(bio_err,"no port defined\n"); ++ BIO_printf(bio_err,"no ending bracket for IPv6 address\n"); + return(0); + } + *(p++)='\0'; +- +- if ((ip != NULL) && !host_ip(str,ip)) +- goto err; +- if (host_ptr != NULL) *host_ptr=h; +- +- if (!extract_port(p,port_ptr)) +- goto err; +- return(1); +-err: +- return(0); ++ x = p; + } +- +-static int host_ip(char *str, unsigned char ip[4]) +- { +- unsigned int in[4]; +- int i; +- +- if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4) +- { +- for (i=0; i<4; i++) +- if (in[i] > 255) +- { +- BIO_printf(bio_err,"invalid IP address\n"); +- goto err; +- } +- ip[0]=in[0]; +- ip[1]=in[1]; +- ip[2]=in[2]; +- ip[3]=in[3]; +- } +- else +- { /* do a gethostbyname */ +- struct hostent *he; +- +- if (!ssl_sock_init()) return(0); +- +- he=GetHostByName(str); +- if (he == NULL) +- { +- BIO_printf(bio_err,"gethostbyname failure\n"); +- goto err; +- } +- /* cast to short because of win16 winsock definition */ +- if ((short)he->h_addrtype != AF_INET) ++ p=strchr(x,':'); ++ if (p == NULL) + { +- BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); +- return(0); +- } +- ip[0]=he->h_addr_list[0][0]; +- ip[1]=he->h_addr_list[0][1]; +- ip[2]=he->h_addr_list[0][2]; +- ip[3]=he->h_addr_list[0][3]; +- } +- return(1); +-err: ++ BIO_printf(bio_err,"no port defined\n"); + return(0); + } ++ *(p++)='\0'; + +-int extract_port(char *str, short *port_ptr) +- { +- int i; +- struct servent *s; ++ if (host_ptr != NULL) *host_ptr=h; ++ if (port_ptr != NULL) *port_ptr=p; + +- i=atoi(str); +- if (i != 0) +- *port_ptr=(unsigned short)i; +- else +- { +- s=getservbyname(str,"tcp"); +- if (s == NULL) +- { +- BIO_printf(bio_err,"getservbyname failure for %s\n",str); +- return(0); +- } +- *port_ptr=ntohs((unsigned short)s->s_port); +- } + return(1); + } + diff --git a/SOURCES/openssl-0.9.8b-soversion.patch b/SOURCES/openssl-0.9.8b-soversion.patch new file mode 100644 index 0000000..25c4899 --- /dev/null +++ b/SOURCES/openssl-0.9.8b-soversion.patch @@ -0,0 +1,47 @@ +Define and use a soname -- because we have to care about binary +compatibility, we have to increment the soname in order to allow +this version to co-exist with another versions and have everything +work right. + +--- openssl-0.9.8b/Makefile.org.soversion 2006-05-11 11:53:26.000000000 +0200 ++++ openssl-0.9.8b/Makefile.org 2006-05-11 12:14:05.000000000 +0200 +@@ -10,6 +10,7 @@ + SHLIB_MAJOR= + SHLIB_MINOR= + SHLIB_EXT= ++SHLIB_SONAMEVER=6 + PLATFORM=dist + OPTIONS= + CONFIGURE_ARGS= +@@ -277,10 +278,9 @@ + link-shared: + @ set -e; for i in ${SHLIBDIRS}; do \ + $(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \ +- LIBNAME=$$i LIBVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR} \ ++ LIBNAME=$$i LIBVERSION=${SHLIB_SONAMEVER} \ + LIBCOMPATVERSIONS=";${SHLIB_VERSION_HISTORY}" \ + symlink.$(SHLIB_TARGET); \ +- libs="$$libs -l$$i"; \ + done + + build-shared: do_$(SHLIB_TARGET) link-shared +@@ -291,7 +291,7 @@ + libs="$(LIBKRB5) $$libs"; \ + fi; \ + $(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \ +- LIBNAME=$$i LIBVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR} \ ++ LIBNAME=$$i LIBVERSION=${SHLIB_SONAMEVER} \ + LIBCOMPATVERSIONS=";${SHLIB_VERSION_HISTORY}" \ + LIBDEPS="$$libs $(EX_LIBS)" \ + link_a.$(SHLIB_TARGET); \ +--- openssl-0.9.8b/Configure.soversion 2006-05-11 11:53:26.000000000 +0200 ++++ openssl-0.9.8b/Configure 2006-05-11 11:53:26.000000000 +0200 +@@ -1327,7 +1327,7 @@ + elsif ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*\.[^\.]*$/) + { + my $sotmp = $1; +- s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_MAJOR) .s$sotmp/; ++ s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_SONAMEVER) .s$sotmp/; + } + elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.[^\.]*\.dylib$/) + { diff --git a/SOURCES/openssl-0.9.8b-x509-name-cmp.patch b/SOURCES/openssl-0.9.8b-x509-name-cmp.patch new file mode 100644 index 0000000..c7e8848 --- /dev/null +++ b/SOURCES/openssl-0.9.8b-x509-name-cmp.patch @@ -0,0 +1,18 @@ +--- openssl-0.9.8b/crypto/x509/x509_cmp.c.name-cmp 2004-12-01 02:45:30.000000000 +0100 ++++ openssl-0.9.8b/crypto/x509/x509_cmp.c 2006-11-30 23:37:26.000000000 +0100 +@@ -282,14 +282,7 @@ + nb=sk_X509_NAME_ENTRY_value(b->entries,i); + j=na->value->type-nb->value->type; + if (j) +- { +- nabit = ASN1_tag2bit(na->value->type); +- nbbit = ASN1_tag2bit(nb->value->type); +- if (!(nabit & STR_TYPE_CMP) || +- !(nbbit & STR_TYPE_CMP)) +- return j; +- j = asn1_string_memcmp(na->value, nb->value); +- } ++ return j; + else if (na->value->type == V_ASN1_PRINTABLESTRING) + j=nocase_spacenorm_cmp(na->value, nb->value); + else if (na->value->type == V_ASN1_IA5STRING diff --git a/SOURCES/openssl-fips-0.9.8e-abi.patch b/SOURCES/openssl-fips-0.9.8e-abi.patch new file mode 100644 index 0000000..0cf4fd7 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-abi.patch @@ -0,0 +1,404 @@ +diff -up openssl-fips-0.9.8e/crypto/crypto.h.abi openssl-fips-0.9.8e/crypto/crypto.h +--- openssl-fips-0.9.8e/crypto/crypto.h.abi 2008-09-04 12:38:01.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/crypto.h 2008-09-04 13:00:39.000000000 +0200 +@@ -343,7 +343,18 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + + /* Set standard debugging functions (not done by default + * unless CRYPTO_MDEBUG is defined) */ ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + void CRYPTO_malloc_debug_init(void); ++#else ++#define CRYPTO_malloc_debug_init() do {\ ++ CRYPTO_set_mem_debug_functions(\ ++ CRYPTO_dbg_malloc,\ ++ CRYPTO_dbg_realloc,\ ++ CRYPTO_dbg_free,\ ++ CRYPTO_dbg_set_options,\ ++ CRYPTO_dbg_get_options);\ ++ } while(0) ++#endif + + int CRYPTO_mem_ctrl(int mode); + int CRYPTO_is_mem_check_on(void); +diff -up openssl-fips-0.9.8e/crypto/rsa/rsa.h.abi openssl-fips-0.9.8e/crypto/rsa/rsa.h +--- openssl-fips-0.9.8e/crypto/rsa/rsa.h.abi 2008-09-04 12:38:01.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/rsa/rsa.h 2008-09-04 12:38:02.000000000 +0200 +@@ -226,7 +226,6 @@ struct rsa_st + * operations and results in faster RSA + * private key operations. + */ +-#ifndef OPENSSL_NO_DEPRECATED + #define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/ + /* new with 0.9.7h; the built-in RSA + * implementation now uses constant time +@@ -235,7 +234,6 @@ struct rsa_st + * faster variable sliding window method to + * be used for all exponents. + */ +-#endif + + + #define RSA_PKCS1_PADDING 1 +diff -up openssl-fips-0.9.8e/crypto/evp/e_des3.c.abi openssl-fips-0.9.8e/crypto/evp/e_des3.c +--- openssl-fips-0.9.8e/crypto/evp/e_des3.c.abi 2007-07-01 19:58:14.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/e_des3.c 2008-09-04 12:38:02.000000000 +0200 +@@ -87,6 +87,7 @@ typedef struct + static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++ /* FIPS selftest embedded in the loop macro */ + BLOCK_CIPHER_ecb_loop() + DES_ecb3_encrypt((const_DES_cblock *)(in + i), + (DES_cblock *)(out + i), +@@ -99,6 +100,9 @@ static int des_ede_ecb_cipher(EVP_CIPHER + static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num); +@@ -108,6 +112,9 @@ static int des_ede_ofb_cipher(EVP_CIPHER + static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + #ifdef KSSL_DEBUG + { + int i; +@@ -128,6 +135,9 @@ static int des_ede_cbc_cipher(EVP_CIPHER + static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); +@@ -142,6 +152,9 @@ static int des_ede3_cfb1_cipher(EVP_CIPH + unsigned int n; + unsigned char c[1],d[1]; + ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + for(n=0 ; n < inl ; ++n) + { + c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; +@@ -157,6 +170,9 @@ static int des_ede3_cfb1_cipher(EVP_CIPH + static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + DES_ede3_cfb_encrypt(in,out,8,inl, + &data(ctx)->ks1,&data(ctx)->ks2,&data(ctx)->ks3, + (DES_cblock *)ctx->iv,ctx->encrypt); +diff -up openssl-fips-0.9.8e/crypto/evp/evp_locl.h.abi openssl-fips-0.9.8e/crypto/evp/evp_locl.h +--- openssl-fips-0.9.8e/crypto/evp/evp_locl.h.abi 2008-09-04 12:38:02.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/evp_locl.h 2008-09-04 12:38:02.000000000 +0200 +@@ -60,8 +60,10 @@ + + /* Wrapper functions for each cipher mode */ + ++#ifdef OPENSSL_FIPS + #define BLOCK_CIPHER_ecb_loop() \ + unsigned int i, bl; \ ++ FIPS_selftest_check(); \ + bl = ctx->cipher->block_size;\ + if(inl < bl) return 1;\ + inl -= bl; \ +@@ -78,6 +80,7 @@ static int cname##_ecb_cipher(EVP_CIPHER + #define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ + static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ + {\ ++ FIPS_selftest_check(); \ + cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + return 1;\ + } +@@ -85,6 +88,7 @@ static int cname##_ofb_cipher(EVP_CIPHER + #define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ + static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ + {\ ++ FIPS_selftest_check(); \ + cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + return 1;\ + } +@@ -92,9 +96,47 @@ static int cname##_cbc_cipher(EVP_CIPHER + #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ + static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ + {\ ++ FIPS_selftest_check(); \ + cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + return 1;\ + } ++#else ++#define BLOCK_CIPHER_ecb_loop() \ ++ unsigned int i, bl; \ ++ bl = ctx->cipher->block_size;\ ++ if(inl < bl) return 1;\ ++ inl -= bl; \ ++ for(i=0; i <= inl; i+=bl) ++ ++#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ ++static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ ++{\ ++ BLOCK_CIPHER_ecb_loop() \ ++ cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ ++ return 1;\ ++} ++ ++#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ ++static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ ++{\ ++ cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ ++ return 1;\ ++} ++ ++#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ ++static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ ++{\ ++ cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ ++ return 1;\ ++} ++ ++#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ ++static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ ++{\ ++ cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ ++ return 1;\ ++} ++#endif + + #define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \ + BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ +diff -up openssl-fips-0.9.8e/crypto/evp/enc_min.c.abi openssl-fips-0.9.8e/crypto/evp/enc_min.c +--- openssl-fips-0.9.8e/crypto/evp/enc_min.c.abi 2007-08-19 14:49:07.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/enc_min.c 2008-09-04 12:38:02.000000000 +0200 +@@ -347,9 +347,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT + + int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) + { +-#ifdef OPENSSL_FIPS +- FIPS_selftest_check(); +-#endif + return ctx->cipher->do_cipher(ctx,out,in,inl); + } + +diff -up openssl-fips-0.9.8e/crypto/evp/evp.h.abi openssl-fips-0.9.8e/crypto/evp/evp.h +--- openssl-fips-0.9.8e/crypto/evp/evp.h.abi 2008-09-04 12:38:02.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/evp.h 2008-09-04 13:00:16.000000000 +0200 +@@ -448,6 +448,7 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_ + #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) + #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + /* Macros to reduce FIPS dependencies: do NOT use in applications */ + #define M_EVP_MD_size(e) ((e)->md_size) + #define M_EVP_MD_block_size(e) ((e)->block_size) +@@ -490,6 +491,38 @@ void EVP_CIPHER_CTX_set_app_data(EVP_CIP + #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) + unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); + #define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) ++#else ++#define EVP_MD_type(e) ((e)->type) ++#define EVP_MD_nid(e) EVP_MD_type(e) ++#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) ++#define EVP_MD_pkey_type(e) ((e)->pkey_type) ++#define EVP_MD_size(e) ((e)->md_size) ++#define EVP_MD_block_size(e) ((e)->block_size) ++ ++#define EVP_MD_CTX_md(e) ((e)->digest) ++#define EVP_MD_CTX_size(e) EVP_MD_size((e)->digest) ++#define EVP_MD_CTX_block_size(e) EVP_MD_block_size((e)->digest) ++#define EVP_MD_CTX_type(e) EVP_MD_type((e)->digest) ++ ++#define EVP_CIPHER_nid(e) ((e)->nid) ++#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) ++#define EVP_CIPHER_block_size(e) ((e)->block_size) ++#define EVP_CIPHER_key_length(e) ((e)->key_len) ++#define EVP_CIPHER_iv_length(e) ((e)->iv_len) ++#define EVP_CIPHER_flags(e) ((e)->flags) ++#define EVP_CIPHER_mode(e) (((e)->flags) & EVP_CIPH_MODE) ++ ++#define EVP_CIPHER_CTX_cipher(e) ((e)->cipher) ++#define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid) ++#define EVP_CIPHER_CTX_block_size(e) ((e)->cipher->block_size) ++#define EVP_CIPHER_CTX_key_length(e) ((e)->key_len) ++#define EVP_CIPHER_CTX_iv_length(e) ((e)->cipher->iv_len) ++#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) ++#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d)) ++#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) ++#define EVP_CIPHER_CTX_flags(e) ((e)->cipher->flags) ++#define EVP_CIPHER_CTX_mode(e) ((e)->cipher->flags & EVP_CIPH_MODE) ++#endif + + #define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) + #define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) +@@ -514,10 +547,14 @@ void BIO_set_md(BIO *,const EVP_MD *md); + #define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) + #define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, + const unsigned char *in, + unsigned int inl); ++#else ++#define EVP_Cipher(c,o,i,l) (c)->cipher->do_cipher((c),(o),(i),(l)) ++#endif + + #define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +@@ -533,9 +570,15 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); + EVP_MD_CTX *EVP_MD_CTX_create(void); + void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); + int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in); ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); + void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); + int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags); ++#else ++#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) ++#define EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs)) ++#define EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs)) ++#endif + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); + int EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d, + size_t cnt); +diff -up openssl-fips-0.9.8e/crypto/bio/bio.h.abi openssl-fips-0.9.8e/crypto/bio/bio.h +--- openssl-fips-0.9.8e/crypto/bio/bio.h.abi 2008-09-04 12:38:02.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/bio/bio.h 2008-09-04 13:00:32.000000000 +0200 +@@ -198,6 +198,7 @@ extern "C" { + + typedef struct bio_st BIO; + ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + void BIO_set_flags(BIO *b, int flags); + int BIO_test_flags(const BIO *b, int flags); + void BIO_clear_flags(BIO *b, int flags); +@@ -222,6 +223,30 @@ void BIO_clear_flags(BIO *b, int flags); + #define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) + #define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) + #define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) ++#else ++#define BIO_set_flags(b,f) ((b)->flags|=(f)) ++#define BIO_get_flags(b) ((b)->flags) ++#define BIO_set_retry_special(b) \ ++ ((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) ++#define BIO_set_retry_read(b) \ ++ ((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) ++#define BIO_set_retry_write(b) \ ++ ((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) ++ ++/* These are normally used internally in BIOs */ ++#define BIO_clear_flags(b,f) ((b)->flags&= ~(f)) ++#define BIO_clear_retry_flags(b) \ ++ ((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) ++#define BIO_get_retry_flags(b) \ ++ ((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) ++ ++/* These should be used by the application to tell why we should retry */ ++#define BIO_should_read(a) ((a)->flags & BIO_FLAGS_READ) ++#define BIO_should_write(a) ((a)->flags & BIO_FLAGS_WRITE) ++#define BIO_should_io_special(a) ((a)->flags & BIO_FLAGS_IO_SPECIAL) ++#define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS) ++#define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY) ++#endif + + /* The next three are used in conjunction with the + * BIO_should_io_special() condition. After this returns true, +@@ -250,6 +275,7 @@ void BIO_clear_flags(BIO *b, int flags); + #define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) + #define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long); + void BIO_set_callback(BIO *b, + long (*callback)(struct bio_st *,int,const char *,int, long,long)); +@@ -258,6 +284,14 @@ void BIO_set_callback_arg(BIO *b, char * + + const char * BIO_method_name(const BIO *b); + int BIO_method_type(const BIO *b); ++#else ++#define BIO_set_callback(b,cb) ((b)->callback=(cb)) ++#define BIO_set_callback_arg(b,arg) ((b)->cb_arg=(char *)(arg)) ++#define BIO_get_callback_arg(b) ((b)->cb_arg) ++#define BIO_get_callback(b) ((b)->callback) ++#define BIO_method_name(b) ((b)->method->name) ++#define BIO_method_type(b) ((b)->method->type) ++#endif + + typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); + +diff -up openssl-fips-0.9.8e/crypto/bn/bn.h.abi openssl-fips-0.9.8e/crypto/bn/bn.h +--- openssl-fips-0.9.8e/crypto/bn/bn.h.abi 2008-09-04 12:38:02.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/bn/bn.h 2008-09-04 12:38:02.000000000 +0200 +@@ -251,11 +251,9 @@ extern "C" { + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ + +-#ifndef OPENSSL_NO_DEPRECATED + #define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */ + /* avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ +-#endif + + #ifndef OPENSSL_NO_DEPRECATED + #define BN_FLG_FREE 0x8000 /* used for debuging */ +diff -up openssl-fips-0.9.8e/crypto/opensslv.h.abi openssl-fips-0.9.8e/crypto/opensslv.h +--- openssl-fips-0.9.8e/crypto/opensslv.h.abi 2008-09-04 12:38:01.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/opensslv.h 2008-09-04 12:38:02.000000000 +0200 +@@ -25,11 +25,11 @@ + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +-#define OPENSSL_VERSION_NUMBER 0x00908060L ++#define OPENSSL_VERSION_NUMBER 0x0090802fL + #ifdef OPENSSL_FIPS +-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8f-fips-dev xx XXXX xxxx" ++#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008" + #else +-#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8f-dev xx XXXX xxxx" ++#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8e-rhel5 01 Jul 2008" + #endif + #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +diff -up openssl-fips-0.9.8e/ssl/ssl.h.abi openssl-fips-0.9.8e/ssl/ssl.h +--- openssl-fips-0.9.8e/ssl/ssl.h.abi 2008-09-04 12:38:02.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl.h 2008-09-04 13:02:38.000000000 +0200 +@@ -789,6 +789,7 @@ struct ssl_ctx_st + #define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + ++#ifdef OPENSSL_USE_NEW_FUNCTIONS + void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess)); + int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess); + void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess)); +@@ -801,6 +802,20 @@ void SSL_CTX_set_client_cert_cb(SSL_CTX + int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey); + void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)); + void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)); ++#else ++#define SSL_CTX_sess_set_new_cb(ctx,cb) ((ctx)->new_session_cb=(cb)) ++#define SSL_CTX_sess_get_new_cb(ctx) ((ctx)->new_session_cb) ++#define SSL_CTX_sess_set_remove_cb(ctx,cb) ((ctx)->remove_session_cb=(cb)) ++#define SSL_CTX_sess_get_remove_cb(ctx) ((ctx)->remove_session_cb) ++#define SSL_CTX_sess_set_get_cb(ctx,cb) ((ctx)->get_session_cb=(cb)) ++#define SSL_CTX_sess_get_get_cb(ctx) ((ctx)->get_session_cb) ++#define SSL_CTX_set_info_callback(ctx,cb) ((ctx)->info_callback=(cb)) ++#define SSL_CTX_get_info_callback(ctx) ((ctx)->info_callback) ++#define SSL_CTX_set_client_cert_cb(ctx,cb) ((ctx)->client_cert_cb=(cb)) ++#define SSL_CTX_get_client_cert_cb(ctx) ((ctx)->client_cert_cb) ++#define SSL_CTX_set_cookie_generate_cb(ctx,cb) ((ctx)->app_gen_cookie_cb=(cb)) ++#define SSL_CTX_set_cookie_verify_cb(ctx,cb) ((ctx)->app_verify_cookie_cb=(cb)) ++#endif + + #define SSL_NOTHING 1 + #define SSL_WRITING 2 diff --git a/SOURCES/openssl-fips-0.9.8e-aescfb.patch b/SOURCES/openssl-fips-0.9.8e-aescfb.patch new file mode 100644 index 0000000..01388ce --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-aescfb.patch @@ -0,0 +1,65 @@ +Add flag EVP_CIPH_FLAG_LENGTH_BITS to indicate that input buffer length +is in bits not bytes. The Monte Carlo FIPS140-2 CFB1 tests require this. +[Steve Henson] + +openssl/crypto/evp/evp.h 1.112.2.4.2.8 -> 1.112.2.4.2.9 + +--- openssl/crypto/evp/evp.h 2007/12/14 01:15:44 1.112.2.4.2.8 ++++ openssl/crypto/evp/evp.h 2007/12/26 19:04:57 1.112.2.4.2.9 +@@ -378,6 +378,8 @@ + #define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 + /* Allow use default ASN1 get/set iv */ + #define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 ++/* Buffer length in bits not bytes: CFB1 mode only */ ++#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 + + /* ctrl() values */ + +@@ -470,6 +472,7 @@ + #define M_EVP_MD_CTX_type(e) M_EVP_MD_type(M_EVP_MD_CTX_md(e)) + #define M_EVP_MD_CTX_md(e) ((e)->digest) + ++#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) + + int EVP_MD_type(const EVP_MD *md); + #define EVP_MD_nid(e) EVP_MD_type(e) + +openssl/crypto/evp/evp_locl.h 1.10.2.1.2.3 -> 1.10.2.1.2.4 + +--- openssl/crypto/evp/evp_locl.h 2007/07/08 19:20:48 1.10.2.1.2.3 ++++ openssl/crypto/evp/evp_locl.h 2007/12/26 19:04:57 1.10.2.1.2.4 +@@ -92,7 +92,7 @@ + #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ + static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ + {\ +- cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ ++ cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + return 1;\ + } + + +openssl/fips/aes/fips_aesavs.c 1.1.4.3 -> 1.1.4.4 + +--- openssl/fips/aes/fips_aesavs.c 2007/09/21 18:00:23 1.1.4.3 ++++ openssl/fips/aes/fips_aesavs.c 2007/12/26 19:04:58 1.1.4.4 +@@ -212,6 +212,8 @@ + } + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; ++ if(!strcasecmp(amode,"CFB1")) ++ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + if (dir) + EVP_Cipher(ctx, ciphertext, plaintext, len); + else +@@ -377,9 +379,11 @@ + case CFB1: + if(j == 0) + { ++#if 0 + /* compensate for wrong endianness of input file */ + if(i == 0) + ptext[0][0]<<=7; ++#endif + ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, + ptext[j], ctext[j], len); + } diff --git a/SOURCES/openssl-fips-0.9.8e-algo-doc.patch b/SOURCES/openssl-fips-0.9.8e-algo-doc.patch new file mode 100644 index 0000000..061ddd7 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-algo-doc.patch @@ -0,0 +1,113 @@ +diff -up openssl-fips-0.9.8e/doc/crypto/EVP_DigestInit.pod.algo-doc openssl-fips-0.9.8e/doc/crypto/EVP_DigestInit.pod +--- openssl-fips-0.9.8e/doc/crypto/EVP_DigestInit.pod.algo-doc 2004-05-20 23:39:50.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/crypto/EVP_DigestInit.pod 2009-06-29 18:20:10.000000000 +0200 +@@ -6,7 +6,8 @@ EVP_MD_CTX_init, EVP_MD_CTX_create, EVP_ + EVP_DigestFinal_ex, EVP_MD_CTX_cleanup, EVP_MD_CTX_destroy, EVP_MAX_MD_SIZE, + EVP_MD_CTX_copy_ex, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size, + EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type, +-EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_dss, EVP_dss1, EVP_mdc2, ++EVP_md_null, EVP_md2, EVP_md5, EVP_sha, EVP_sha1, EVP_sha224, ++EVP_sha256, EVP_sha384, EVP_sha512, EVP_dss, EVP_dss1, EVP_mdc2, + EVP_ripemd160, EVP_get_digestbyname, EVP_get_digestbynid, EVP_get_digestbyobj - + EVP digest routines + +@@ -51,6 +52,10 @@ EVP digest routines + const EVP_MD *EVP_md5(void); + const EVP_MD *EVP_sha(void); + const EVP_MD *EVP_sha1(void); ++ const EVP_MD *EVP_sha224(void); ++ const EVP_MD *EVP_sha256(void); ++ const EVP_MD *EVP_sha384(void); ++ const EVP_MD *EVP_sha512(void); + const EVP_MD *EVP_dss(void); + const EVP_MD *EVP_dss1(void); + const EVP_MD *EVP_mdc2(void); +@@ -70,7 +75,7 @@ EVP_MD_CTX_create() allocates, initializ + + EVP_DigestInit_ex() sets up digest context B to use a digest + B from ENGINE B. B must be initialized before calling this +-function. B will typically be supplied by a functionsuch as EVP_sha1(). ++function. B will typically be supplied by a function such as EVP_sha1(). + If B is NULL then the default implementation of digest B is used. + + EVP_DigestUpdate() hashes B bytes of data at B into the +@@ -127,9 +132,11 @@ with this digest. For example EVP_sha1() + return B. This "link" between digests and signature + algorithms may not be retained in future versions of OpenSSL. + +-EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_mdc2() and EVP_ripemd160() +-return B structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 digest +-algorithms respectively. The associated signature algorithm is RSA in each case. ++EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_sha224(), EVP_sha256(), ++EVP_sha384(), EVP_sha512(), EVP_mdc2() and EVP_ripemd160() ++return B structures for the MD2, MD5, SHA, SHA1, SHA224, SHA256, SHA384, ++SHA512, MDC2 and RIPEMD160 digest algorithms respectively. The associated ++signature algorithm is RSA in each case. + + EVP_dss() and EVP_dss1() return B structures for SHA and SHA1 digest + algorithms but using DSS (DSA) for the signature algorithm. +@@ -156,7 +163,8 @@ EVP_MD_size(), EVP_MD_block_size(), EVP_ + EVP_MD_CTX_block_size() and EVP_MD_block_size() return the digest or block + size in bytes. + +-EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(), ++EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), ++EVP_sha224(), EVP_sha256(), EVP_sha384(), EVP_sha512(), EVP_dss(), + EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the + corresponding EVP_MD structures. + +diff -up openssl-fips-0.9.8e/doc/crypto/EVP_EncryptInit.pod.algo-doc openssl-fips-0.9.8e/doc/crypto/EVP_EncryptInit.pod +--- openssl-fips-0.9.8e/doc/crypto/EVP_EncryptInit.pod.algo-doc 2005-04-15 18:01:35.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/crypto/EVP_EncryptInit.pod 2009-06-29 18:28:46.000000000 +0200 +@@ -91,6 +91,32 @@ EVP_CIPHER_CTX_set_padding - EVP cipher + int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + ++ const EVP_CIPHER *EVP_des_ede3(void); ++ const EVP_CIPHER *EVP_des_ede3_ecb(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb64(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb1(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb8(void); ++ const EVP_CIPHER *EVP_des_ede3_ofb(void); ++ const EVP_CIPHER *EVP_des_ede3_cbc(void); ++ const EVP_CIPHER *EVP_aes_128_ecb(void); ++ const EVP_CIPHER *EVP_aes_128_cbc(void); ++ const EVP_CIPHER *EVP_aes_128_cfb1(void); ++ const EVP_CIPHER *EVP_aes_128_cfb8(void); ++ const EVP_CIPHER *EVP_aes_128_cfb128(void); ++ const EVP_CIPHER *EVP_aes_128_ofb(void); ++ const EVP_CIPHER *EVP_aes_192_ecb(void); ++ const EVP_CIPHER *EVP_aes_192_cbc(void); ++ const EVP_CIPHER *EVP_aes_192_cfb1(void); ++ const EVP_CIPHER *EVP_aes_192_cfb8(void); ++ const EVP_CIPHER *EVP_aes_192_cfb128(void); ++ const EVP_CIPHER *EVP_aes_192_ofb(void); ++ const EVP_CIPHER *EVP_aes_256_ecb(void); ++ const EVP_CIPHER *EVP_aes_256_cbc(void); ++ const EVP_CIPHER *EVP_aes_256_cfb1(void); ++ const EVP_CIPHER *EVP_aes_256_cfb8(void); ++ const EVP_CIPHER *EVP_aes_256_cfb128(void); ++ const EVP_CIPHER *EVP_aes_256_ofb(void); ++ + =head1 DESCRIPTION + + The EVP cipher routines are a high level interface to certain +@@ -297,6 +323,18 @@ Three key triple DES in CBC, ECB, CFB an + + DESX algorithm in CBC mode. + ++=item EVP_aes_128_cbc(void), EVP_aes_128_ecb(), EVP_aes_128_ofb(void), EVP_aes_128_cfb1(void), EVP_aes_128_cfb8(void), EVP_aes_128_cfb128(void) ++ ++AES with 128 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ ++=item EVP_aes_192_cbc(void), EVP_aes_192_ecb(), EVP_aes_192_ofb(void), EVP_aes_192_cfb1(void), EVP_aes_192_cfb8(void), EVP_aes_192_cfb128(void) ++ ++AES with 192 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ ++=item EVP_aes_256_cbc(void), EVP_aes_256_ecb(), EVP_aes_256_ofb(void), EVP_aes_256_cfb1(void), EVP_aes_256_cfb8(void), EVP_aes_256_cfb128(void) ++ ++AES with 256 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ + =item EVP_rc4(void) + + RC4 stream cipher. This is a variable key length cipher with default key length 128 bits. diff --git a/SOURCES/openssl-fips-0.9.8e-apps-dgst.patch b/SOURCES/openssl-fips-0.9.8e-apps-dgst.patch new file mode 100644 index 0000000..b00212a --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-apps-dgst.patch @@ -0,0 +1,101 @@ +diff -up openssl-fips-0.9.8e/apps/ca.c.dgst openssl-fips-0.9.8e/apps/ca.c +--- openssl-fips-0.9.8e/apps/ca.c.dgst 2006-11-27 14:36:52.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/ca.c 2011-04-04 14:36:24.000000000 +0200 +@@ -158,7 +158,7 @@ static const char *ca_usage[]={ + " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n", + " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n", + " -days arg - number of days to certify the certificate for\n", +-" -md arg - md to use, one of md2, md5, sha or sha1\n", ++" -md arg - md to use, see openssl dgst -h for list\n", + " -policy arg - The CA 'policy' to support\n", + " -keyfile arg - private key file\n", + " -keyform arg - private key file format (PEM or ENGINE)\n", +diff -up openssl-fips-0.9.8e/apps/dgst.c.dgst openssl-fips-0.9.8e/apps/dgst.c +--- openssl-fips-0.9.8e/apps/dgst.c.dgst 2007-09-19 02:02:10.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/dgst.c 2011-04-04 14:41:31.000000000 +0200 +@@ -280,10 +280,14 @@ ERR_load_crypto_strings(); + LN_sha512,LN_sha512); + #endif + #endif ++#ifndef OPENSSL_NO_MDC2 + BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", + LN_mdc2,LN_mdc2); ++#endif ++#ifndef OPENSSL_NO_RIPEMD + BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", + LN_ripemd160,LN_ripemd160); ++#endif + err=1; + goto end; + } +diff -up openssl-fips-0.9.8e/apps/enc.c.dgst openssl-fips-0.9.8e/apps/enc.c +--- openssl-fips-0.9.8e/apps/enc.c.dgst 2007-03-22 01:37:43.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/enc.c 2011-04-04 14:39:17.000000000 +0200 +@@ -285,7 +285,7 @@ bad: + BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k"); + BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); + BIO_printf(bio_err,"%-14s the next argument is the md to use to create a key\n","-md"); +- BIO_printf(bio_err,"%-14s from a passphrase. One of md2, md5, sha or sha1\n",""); ++ BIO_printf(bio_err,"%-14s from a passphrase. See openssl dgst -h for list.\n",""); + BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); + BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); + BIO_printf(bio_err,"%-14s buffer size\n","-bufsize "); +diff -up openssl-fips-0.9.8e/apps/req.c.dgst openssl-fips-0.9.8e/apps/req.c +--- openssl-fips-0.9.8e/apps/req.c.dgst 2005-07-16 13:13:03.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/req.c 2011-04-04 14:40:46.000000000 +0200 +@@ -523,7 +523,7 @@ bad: + #ifndef OPENSSL_NO_ECDSA + BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); + #endif +- BIO_printf(bio_err," -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n"); ++ BIO_printf(bio_err," -[digest] Digest to sign with (see openssl dgst -h for list)\n"); + BIO_printf(bio_err," -config file request template file.\n"); + BIO_printf(bio_err," -subj arg set or modify request subject\n"); + BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n"); +diff -up openssl-fips-0.9.8e/apps/x509.c.dgst openssl-fips-0.9.8e/apps/x509.c +--- openssl-fips-0.9.8e/apps/x509.c.dgst 2011-04-04 14:18:34.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/x509.c 2011-04-04 14:35:05.000000000 +0200 +@@ -134,7 +134,7 @@ static const char *x509_usage[]={ + " -set_serial - serial number to use\n", + " -text - print the certificate in text form\n", + " -C - print out C code forms\n", +-" -md2/-md5/-sha1/-mdc2 - digest to use\n", ++" - - digest to use, see openssl dgst -h output for list\n", + " -extfile - configuration file with X509V3 extensions to add\n", + " -extensions - section from config file with X509V3 extensions to add\n", + " -clrext - delete extensions before signing and input certificate\n", +diff -up openssl-fips-0.9.8e/doc/apps/ca.pod.dgst openssl-fips-0.9.8e/doc/apps/ca.pod +--- openssl-fips-0.9.8e/doc/apps/ca.pod.dgst 2005-07-15 11:50:38.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/apps/ca.pod 2011-04-04 15:03:07.000000000 +0200 +@@ -160,7 +160,8 @@ the number of days to certify the certif + =item B<-md alg> + + the message digest to use. Possible values include md5, sha1 and mdc2. +-This option also applies to CRLs. ++For full list of digests see openssl dgst -h output. This option also ++applies to CRLs. + + =item B<-policy arg> + +diff -up openssl-fips-0.9.8e/doc/apps/req.pod.dgst openssl-fips-0.9.8e/doc/apps/req.pod +--- openssl-fips-0.9.8e/doc/apps/req.pod.dgst 2005-07-15 11:50:38.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/apps/req.pod 2011-04-04 15:05:22.000000000 +0200 +@@ -160,6 +160,7 @@ will not be encrypted. + this specifies the message digest to sign the request with. This + overrides the digest algorithm specified in the configuration file. + This option is ignored for DSA requests: they always use SHA1. ++For full list of possible digests see openssl dgst -h output. + + =item B<-config filename> + +diff -up openssl-fips-0.9.8e/doc/apps/x509.pod.dgst openssl-fips-0.9.8e/doc/apps/x509.pod +--- openssl-fips-0.9.8e/doc/apps/x509.pod.dgst 2007-02-03 11:27:31.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/apps/x509.pod 2011-04-04 15:06:14.000000000 +0200 +@@ -100,6 +100,7 @@ the digest to use. This affects any sign + digest, such as the B<-fingerprint>, B<-signkey> and B<-CA> options. If not + specified then SHA1 is used. If the key being used to sign with is a DSA key + then this option has no effect: SHA1 is always used with DSA keys. ++For full list of digests see openssl dgst -h output. + + =item B<-engine id> + diff --git a/SOURCES/openssl-fips-0.9.8e-apps-yesno.patch b/SOURCES/openssl-fips-0.9.8e-apps-yesno.patch new file mode 100644 index 0000000..8268db0 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-apps-yesno.patch @@ -0,0 +1,14 @@ +Index: openssl/apps/apps.c +RCS File: /v/openssl/cvs/openssl/apps/apps.c,v +rcsdiff -q -kk '-r1.91.2.3' '-r1.91.2.4' -u '/v/openssl/cvs/openssl/apps/apps.c,v' 2>/dev/null +--- openssl/apps/apps.c 2005/07/16 11:13:02 1.91.2.3 ++++ openssl/apps/apps.c 2008/04/17 14:15:29 1.91.2.4 +@@ -2010,7 +2010,7 @@ + case 'y': /* yes */ + case 'Y': /* YES */ + case '1': /* 1 */ +- ret = 0; ++ ret = 1; + break; + default: + ret = def; diff --git a/SOURCES/openssl-fips-0.9.8e-asm-sign.patch b/SOURCES/openssl-fips-0.9.8e-asm-sign.patch new file mode 100644 index 0000000..d3d9f4a --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-asm-sign.patch @@ -0,0 +1,14 @@ +diff -up openssl-fips-0.9.8e/crypto/perlasm/x86_64-xlate.pl.sign openssl-fips-0.9.8e/crypto/perlasm/x86_64-xlate.pl +--- openssl-fips-0.9.8e/crypto/perlasm/x86_64-xlate.pl.sign 2010-04-16 18:52:58.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/perlasm/x86_64-xlate.pl 2010-04-16 18:53:11.000000000 +0200 +@@ -186,8 +186,10 @@ my $current_function; + if (!$masm) { + # Solaris /usr/ccs/bin/as can't handle multiplications + # in $self->{label} ++ use integer; + $self->{label} =~ s/(?{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; ++ $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg; + + if (defined($self->{index})) { + sprintf "%s(%%%s,%%%s,%d)", diff --git a/SOURCES/openssl-fips-0.9.8e-bad-mime.patch b/SOURCES/openssl-fips-0.9.8e-bad-mime.patch new file mode 100644 index 0000000..22f5e89 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-bad-mime.patch @@ -0,0 +1,14 @@ +diff -up openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c.bad-mime openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c +--- openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c.bad-mime 2007-06-22 14:17:50.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c 2009-04-15 14:58:36.000000000 +0200 +@@ -689,6 +689,10 @@ static int mime_hdr_addparam(MIME_HEADER + static int mime_hdr_cmp(const MIME_HEADER * const *a, + const MIME_HEADER * const *b) + { ++ if ((*a)->name == NULL || (*b)->name == NULL) ++ return (*a)->name - (*b)->name < 0 ? -1 : ++ (*a)->name - (*b)->name > 0 ? 1 : 0; ++ + return(strcmp((*a)->name, (*b)->name)); + } + diff --git a/SOURCES/openssl-fips-0.9.8e-bn-fixes.patch b/SOURCES/openssl-fips-0.9.8e-bn-fixes.patch new file mode 100644 index 0000000..81e651e --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-bn-fixes.patch @@ -0,0 +1,220 @@ +Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() +to get the expected BN_FLG_CONSTTIME behavior. +[Bodo Moeller (Google)] + +openssl/crypto/bn/bn_mont.c 1.36.2.8 -> 1.36.2.9 + +--- openssl/crypto/bn/bn_mont.c 2007/11/11 20:43:23 1.36.2.8 ++++ openssl/crypto/bn/bn_mont.c 2008/02/27 06:01:59 1.36.2.9 +@@ -413,6 +413,8 @@ + + buf[0]=mod->d[0]; /* tmod = N mod word size */ + buf[1]=0; ++ ++ BN_init(&tmod); + tmod.d=buf; + tmod.top = buf[0] != 0 ? 1 : 0; + tmod.dmax=2; + +openssl/crypto/rsa/rsa_eay.c 1.46.2.8 -> 1.46.2.9 + +--- openssl/crypto/rsa/rsa_eay.c 2007/03/28 00:14:21 1.46.2.8 ++++ openssl/crypto/rsa/rsa_eay.c 2008/02/27 06:02:00 1.46.2.9 +@@ -151,13 +151,13 @@ + } + + /* Usage example; +- * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); ++ * MONT_HELPER(rsa->_method_mod_p, bn_ctx, rsa->p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + */ +-#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ +- if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ +- !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \ ++#define MONT_HELPER(method_mod, ctx, m, pre_cond, err_instr) \ ++ if ((pre_cond) && ((method_mod) == NULL) && \ ++ !BN_MONT_CTX_set_locked(&(method_mod), \ + CRYPTO_LOCK_RSA, \ +- (rsa)->m, (ctx))) \ ++ (m), (ctx))) \ + err_instr + + static int RSA_eay_public_encrypt(int flen, const unsigned char *from, +@@ -227,13 +227,13 @@ + if (BN_bin2bn(buf,num,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) +- { ++ { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + +- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); ++ MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; +@@ -436,9 +436,9 @@ + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else +- d = rsa->d; ++ d= rsa->d; + +- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); ++ MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) goto err; +@@ -559,7 +559,7 @@ + else + d = rsa->d; + +- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); ++ MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) + goto err; +@@ -669,7 +669,7 @@ + goto err; + } + +- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); ++ MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; +@@ -717,7 +717,6 @@ + BIGNUM *r1,*m1,*vrfy; + BIGNUM local_dmp1,local_dmq1,local_c,local_r1; + BIGNUM *dmp1,*dmq1,*c,*pr1; +- int bn_flags; + int ret=0; + + BN_CTX_start(ctx); +@@ -725,31 +724,34 @@ + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + +- /* Make sure mod_inverse in montgomerey intialization use correct +- * BN_FLG_CONSTTIME flag. +- */ +- bn_flags = rsa->p->flags; +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) +- { +- rsa->p->flags |= BN_FLG_CONSTTIME; +- } +- MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); +- /* We restore bn_flags back */ +- rsa->p->flags = bn_flags; ++ { ++ BIGNUM local_p, local_q; ++ BIGNUM *p = NULL, *q = NULL; + +- /* Make sure mod_inverse in montgomerey intialization use correct +- * BN_FLG_CONSTTIME flag. +- */ +- bn_flags = rsa->q->flags; +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) +- { +- rsa->q->flags |= BN_FLG_CONSTTIME; +- } +- MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); +- /* We restore bn_flags back */ +- rsa->q->flags = bn_flags; ++ /* Make sure BN_mod_inverse in Montgomery intialization uses the ++ * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) ++ */ ++ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) ++ { ++ BN_init(&local_p); ++ p = &local_p; ++ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); ++ ++ BN_init(&local_q); ++ q = &local_q; ++ BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); ++ } ++ else ++ { ++ p = rsa->p; ++ q = rsa->q; ++ } ++ ++ MONT_HELPER(rsa->_method_mod_p, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); ++ MONT_HELPER(rsa->_method_mod_q, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); ++ } + +- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); ++ MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + +Fix DH with certain moduli. + +openssl/crypto/bn/bn_mul.c 1.36.4.1 -> 1.36.4.2 + +--- openssl/crypto/bn/bn_mul.c 2007/07/08 18:55:51 1.36.4.1 ++++ openssl/crypto/bn/bn_mul.c 2007/11/03 20:10:10 1.36.4.2 +@@ -389,6 +389,7 @@ + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) + * a[1]*b[1] + */ ++/* dnX may not be positive, but n2/2+dnX has to be */ + void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + int dna, int dnb, BN_ULONG *t) + { +@@ -398,7 +399,7 @@ + BN_ULONG ln,lo,*p; + + # ifdef BN_COUNT +- fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2); ++ fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb); + # endif + # ifdef BN_MUL_COMBA + # if 0 +@@ -545,6 +546,7 @@ + + /* n+tn is the word length + * t needs to be n*4 is size, as does r */ ++/* tnX may not be negative but less than n */ + void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, + int tna, int tnb, BN_ULONG *t) + { +@@ -553,8 +555,8 @@ + BN_ULONG ln,lo,*p; + + # ifdef BN_COUNT +- fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n", +- tna, n, tnb, n); ++ fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n", ++ n, tna, n, tnb); + # endif + if (n < 8) + { +@@ -655,16 +657,19 @@ + for (;;) + { + i/=2; +- if (i <= tna && tna == tnb) ++ /* these simplified conditions work ++ * exclusively because difference ++ * between tna and tnb is 1 or 0 */ ++ if (i < tna || i < tnb) + { +- bn_mul_recursive(&(r[n2]), ++ bn_mul_part_recursive(&(r[n2]), + &(a[n]),&(b[n]), + i,tna-i,tnb-i,p); + break; + } +- else if (i < tna || i < tnb) ++ else if (i == tna || i == tnb) + { +- bn_mul_part_recursive(&(r[n2]), ++ bn_mul_recursive(&(r[n2]), + &(a[n]),&(b[n]), + i,tna-i,tnb-i,p); + break; diff --git a/SOURCES/openssl-fips-0.9.8e-casts.patch b/SOURCES/openssl-fips-0.9.8e-casts.patch new file mode 100644 index 0000000..fa5dd01 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-casts.patch @@ -0,0 +1,488 @@ +diff -up openssl-fips-0.9.8e/apps/pkcs12.c.casts openssl-fips-0.9.8e/apps/pkcs12.c +--- openssl-fips-0.9.8e/apps/pkcs12.c.casts 2007-04-24 13:30:31.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/pkcs12.c 2010-04-16 16:02:13.000000000 +0200 +@@ -484,7 +484,7 @@ int MAIN(int argc, char **argv) + X509_keyid_set1(ucert, NULL, 0); + X509_alias_set1(ucert, NULL, 0); + /* Remove from list */ +- sk_X509_delete(certs, i); ++ (void)sk_X509_delete(certs, i); + break; + } + } +diff -up openssl-fips-0.9.8e/crypto/asn1/asn1.h.casts openssl-fips-0.9.8e/crypto/asn1/asn1.h +--- openssl-fips-0.9.8e/crypto/asn1/asn1.h.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/asn1/asn1.h 2010-04-16 16:02:13.000000000 +0200 +@@ -322,6 +322,17 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; + #define I2D_OF(type) int (*)(type *,unsigned char **) + #define I2D_OF_const(type) int (*)(const type *,unsigned char **) + ++#define CHECKED_D2I_OF(type, d2i) \ ++ ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) ++#define CHECKED_I2D_OF(type, i2d) \ ++ ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) ++#define CHECKED_NEW_OF(type, xnew) \ ++ ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) ++#define CHECKED_PTR_OF(type, p) \ ++ ((void*) (1 ? p : (type*)0)) ++#define CHECKED_PPTR_OF(type, p) \ ++ ((void**) (1 ? p : (type**)0)) ++ + #define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) + #define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) + #define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) +@@ -902,23 +913,41 @@ int ASN1_object_size(int constructed, in + + /* Used to implement other functions */ + void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); ++ + #define ASN1_dup_of(type,i2d,d2i,x) \ +- ((type *(*)(I2D_OF(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x) ++ ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ ++ CHECKED_D2I_OF(type, d2i), \ ++ CHECKED_PTR_OF(type, x))) ++ + #define ASN1_dup_of_const(type,i2d,d2i,x) \ +- ((type *(*)(I2D_OF_const(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x) ++ ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ ++ CHECKED_D2I_OF(type, d2i), \ ++ CHECKED_PTR_OF(const type, x))) + + void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + + #ifndef OPENSSL_NO_FP_API + void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); ++ + #define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ +- ((type *(*)(type *(*)(void),D2I_OF(type),FILE *,type **))openssl_fcast(ASN1_d2i_fp))(xnew,d2i,in,x) ++ ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ ++ CHECKED_D2I_OF(type, d2i), \ ++ in, \ ++ CHECKED_PPTR_OF(type, x))) ++ + void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); + int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x); ++ + #define ASN1_i2d_fp_of(type,i2d,out,x) \ +- ((int (*)(I2D_OF(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x) ++ (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ ++ out, \ ++ CHECKED_PTR_OF(type, x))) ++ + #define ASN1_i2d_fp_of_const(type,i2d,out,x) \ +- ((int (*)(I2D_OF_const(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x) ++ (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ ++ out, \ ++ CHECKED_PTR_OF(const type, x))) ++ + int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); + int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); + #endif +@@ -927,14 +956,26 @@ int ASN1_STRING_to_UTF8(unsigned char ** + + #ifndef OPENSSL_NO_BIO + void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); ++ + #define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ +- ((type *(*)(type *(*)(void),D2I_OF(type),BIO *,type **))openssl_fcast(ASN1_d2i_bio))(xnew,d2i,in,x) ++ ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ ++ CHECKED_D2I_OF(type, d2i), \ ++ in, \ ++ CHECKED_PPTR_OF(type, x))) ++ + void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); + int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x); ++ + #define ASN1_i2d_bio_of(type,i2d,out,x) \ +- ((int (*)(I2D_OF(type),BIO *,type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x) ++ (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ ++ out, \ ++ CHECKED_PTR_OF(type, x))) ++ + #define ASN1_i2d_bio_of_const(type,i2d,out,x) \ +- ((int (*)(I2D_OF_const(type),BIO *,const type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x) ++ (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ ++ out, \ ++ CHECKED_PTR_OF(const type, x))) ++ + int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); + int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a); + int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a); +@@ -977,8 +1018,12 @@ void *ASN1_unpack_string(ASN1_STRING *oc + void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); + ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); ++ + #define ASN1_pack_string_of(type,obj,i2d,oct) \ +- ((ASN1_STRING *(*)(type *,I2D_OF(type),ASN1_OCTET_STRING **))openssl_fcast(ASN1_pack_string))(obj,i2d,oct) ++ (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ ++ CHECKED_I2D_OF(type, i2d), \ ++ oct)) ++ + ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); + + void ASN1_STRING_set_default_mask(unsigned long mask); +diff -up openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c.casts openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c +--- openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c 2010-04-16 16:02:13.000000000 +0200 +@@ -130,7 +130,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **p + ASN1_VALUE *ptmpval = NULL; + if (!pval) + pval = &ptmpval; +- asn1_tlc_clear(&c); ++ c.valid = 0; + if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + return *pval; + return NULL; +@@ -140,7 +140,7 @@ int ASN1_template_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, const ASN1_TEMPLATE *tt) + { + ASN1_TLC c; +- asn1_tlc_clear(&c); ++ c.valid = 0; + return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); + } + +diff -up openssl-fips-0.9.8e/crypto/asn1/tasn_enc.c.casts openssl-fips-0.9.8e/crypto/asn1/tasn_enc.c +--- openssl-fips-0.9.8e/crypto/asn1/tasn_enc.c.casts 2006-01-19 18:17:33.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/asn1/tasn_enc.c 2010-04-16 16:02:13.000000000 +0200 +@@ -494,7 +494,7 @@ static int asn1_set_seq_out(STACK_OF(ASN + { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); + i++, tder++) +- sk_ASN1_VALUE_set(sk, i, tder->field); ++ (void)sk_ASN1_VALUE_set(sk, i, tder->field); + } + OPENSSL_free(derlst); + OPENSSL_free(tmpdat); +diff -up openssl-fips-0.9.8e/crypto/asn1/x_crl.c.casts openssl-fips-0.9.8e/crypto/asn1/x_crl.c +--- openssl-fips-0.9.8e/crypto/asn1/x_crl.c.casts 2004-12-09 14:35:05.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/asn1/x_crl.c 2010-04-16 16:02:13.000000000 +0200 +@@ -84,7 +84,7 @@ static int crl_inf_cb(int operation, ASN + * would affect the output of X509_CRL_print(). + */ + case ASN1_OP_D2I_POST: +- sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); ++ (void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp); + break; + } + return 1; +diff -up openssl-fips-0.9.8e/crypto/conf/conf_api.c.casts openssl-fips-0.9.8e/crypto/conf/conf_api.c +--- openssl-fips-0.9.8e/crypto/conf/conf_api.c.casts 2002-01-18 17:50:42.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/conf/conf_api.c 2010-04-16 16:02:13.000000000 +0200 +@@ -121,7 +121,7 @@ int _CONF_add_string(CONF *conf, CONF_VA + v = (CONF_VALUE *)lh_insert(conf->data, value); + if (v != NULL) + { +- sk_CONF_VALUE_delete_ptr(ts,v); ++ (void)sk_CONF_VALUE_delete_ptr(ts,v); + OPENSSL_free(v->name); + OPENSSL_free(v->value); + OPENSSL_free(v); +diff -up openssl-fips-0.9.8e/crypto/conf/conf_mod.c.casts openssl-fips-0.9.8e/crypto/conf/conf_mod.c +--- openssl-fips-0.9.8e/crypto/conf/conf_mod.c.casts 2007-04-09 13:47:59.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/conf/conf_mod.c 2010-04-16 16:02:13.000000000 +0200 +@@ -432,7 +432,7 @@ void CONF_modules_unload(int all) + if (((md->links > 0) || !md->dso) && !all) + continue; + /* Since we're working in reverse this is OK */ +- sk_CONF_MODULE_delete(supported_modules, i); ++ (void)sk_CONF_MODULE_delete(supported_modules, i); + module_free(md); + } + if (sk_CONF_MODULE_num(supported_modules) == 0) +diff -up openssl-fips-0.9.8e/crypto/engine/eng_table.c.casts openssl-fips-0.9.8e/crypto/engine/eng_table.c +--- openssl-fips-0.9.8e/crypto/engine/eng_table.c.casts 2004-06-19 05:58:42.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/engine/eng_table.c 2010-04-16 16:02:13.000000000 +0200 +@@ -147,7 +147,7 @@ int engine_table_register(ENGINE_TABLE * + lh_insert(&(*table)->piles, fnd); + } + /* A registration shouldn't add duplciate entries */ +- sk_ENGINE_delete_ptr(fnd->sk, e); ++ (void)sk_ENGINE_delete_ptr(fnd->sk, e); + /* if 'setdefault', this ENGINE goes to the head of the list */ + if(!sk_ENGINE_push(fnd->sk, e)) + goto end; +@@ -178,7 +178,7 @@ static void int_unregister_cb(ENGINE_PIL + /* Iterate the 'c->sk' stack removing any occurance of 'e' */ + while((n = sk_ENGINE_find(pile->sk, e)) >= 0) + { +- sk_ENGINE_delete(pile->sk, n); ++ (void)sk_ENGINE_delete(pile->sk, n); + /* "touch" this ENGINE_CIPHER */ + pile->uptodate = 1; + } +diff -up openssl-fips-0.9.8e/crypto/ex_data.c.casts openssl-fips-0.9.8e/crypto/ex_data.c +--- openssl-fips-0.9.8e/crypto/ex_data.c.casts 2004-04-19 20:09:22.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/ex_data.c 2010-04-16 16:02:13.000000000 +0200 +@@ -354,7 +354,7 @@ static int def_add_index(EX_CLASS_ITEM * + } + } + toret = item->meth_num++; +- sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); ++ (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); + err: + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +diff -up openssl-fips-0.9.8e/crypto/ocsp/ocsp.h.casts openssl-fips-0.9.8e/crypto/ocsp/ocsp.h +--- openssl-fips-0.9.8e/crypto/ocsp/ocsp.h.casts 2010-04-16 11:00:43.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/ocsp/ocsp.h 2010-04-16 16:02:13.000000000 +0200 +@@ -469,7 +469,7 @@ int OCSP_basic_sign(OCSP_BASICRESP *brsp + ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, + void *data, STACK_OF(ASN1_OBJECT) *sk); + #define ASN1_STRING_encode_of(type,s,i2d,data,sk) \ +-((ASN1_STRING *(*)(ASN1_STRING *,I2D_OF(type),type *,STACK_OF(ASN1_OBJECT) *))openssl_fcast(ASN1_STRING_encode))(s,i2d,data,sk) ++ ASN1_STRING_encode(s, CHECKED_I2D_OF(type, i2d), data, sk) + + X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); + +diff -up openssl-fips-0.9.8e/crypto/pem/pem.h.casts openssl-fips-0.9.8e/crypto/pem/pem.h +--- openssl-fips-0.9.8e/crypto/pem/pem.h.casts 2010-04-16 11:00:43.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/pem/pem.h 2010-04-16 16:02:13.000000000 +0200 +@@ -220,19 +220,28 @@ typedef struct pem_ctx_st + #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ + { \ +-return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \ ++ return (type*)PEM_ASN1_read(CHECKED_D2I_OF(type, d2i_##asn1), \ ++ str, fp, \ ++ CHECKED_PPTR_OF(type, x), \ ++ cb, u); \ + } + + #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ + int PEM_write_##name(FILE *fp, type *x) \ + { \ +-return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \ ++ return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ ++ str, fp, \ ++ CHECKED_PTR_OF(type, x), \ ++ NULL, NULL, 0, NULL, NULL); \ + } + + #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ + int PEM_write_##name(FILE *fp, const type *x) \ + { \ +-return(((int (*)(I2D_OF_const(type),const char *,FILE *, const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \ ++ return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ ++ str, fp, \ ++ CHECKED_PTR_OF(const type, x), \ ++ NULL, NULL, 0, NULL, NULL); \ + } + + #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +@@ -240,7 +249,10 @@ int PEM_write_##name(FILE *fp, type *x, + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ +- return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \ ++ return PEM_ASN1_write(CHECKED_I2D_OF(type, i2d_##asn1), \ ++ str, fp, \ ++ CHECKED_PTR_OF(type, x), \ ++ enc, kstr, klen, cb, u); \ + } + + #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +@@ -248,7 +260,10 @@ int PEM_write_##name(FILE *fp, type *x, + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ +- return(((int (*)(I2D_OF_const(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \ ++ return PEM_ASN1_write(CHECKED_I2D_OF(const type, i2d_##asn1), \ ++ str, fp, \ ++ CHECKED_PTR_OF(const type, x), \ ++ enc, kstr, klen, cb, u); \ + } + + #endif +@@ -256,33 +271,48 @@ int PEM_write_##name(FILE *fp, type *x, + #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ + { \ +-return(((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i_##asn1, str,bp,x,cb,u)); \ ++ return (type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i_##asn1), \ ++ str, bp, \ ++ CHECKED_PPTR_OF(type, x), \ ++ cb, u); \ + } + + #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + int PEM_write_bio_##name(BIO *bp, type *x) \ + { \ +-return(((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \ ++ return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ ++ str, bp, \ ++ CHECKED_PTR_OF(type, x), \ ++ NULL, NULL, 0, NULL, NULL); \ + } + + #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + int PEM_write_bio_##name(BIO *bp, const type *x) \ + { \ +-return(((int (*)(I2D_OF_const(type),const char *,BIO *,const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \ ++ return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ ++ str, bp, \ ++ CHECKED_PTR_OF(const type, x), \ ++ NULL, NULL, 0, NULL, NULL); \ + } + + #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ +- return(((int (*)(I2D_OF(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \ ++ return PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d_##asn1), \ ++ str, bp, \ ++ CHECKED_PTR_OF(type, x), \ ++ enc, kstr, klen, cb, u); \ + } + + #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ +- return(((int (*)(I2D_OF_const(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \ ++ return PEM_ASN1_write_bio(CHECKED_I2D_OF(const type, i2d_##asn1), \ ++ str, bp, \ ++ CHECKED_PTR_OF(const type, x), \ ++ enc, kstr, klen, cb, u); \ + } + + #define IMPLEMENT_PEM_write(name, type, str, asn1) \ +@@ -545,13 +575,22 @@ int PEM_bytes_read_bio(unsigned char **p + pem_password_cb *cb, void *u); + void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, + void **x, pem_password_cb *cb, void *u); ++ + #define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \ +-((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i,name,bp,x,cb,u) ++ ((type*)PEM_ASN1_read_bio(CHECKED_D2I_OF(type, d2i), \ ++ name, bp, \ ++ CHECKED_PPTR_OF(type, x), \ ++ cb, u)) ++ + int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x, + const EVP_CIPHER *enc,unsigned char *kstr,int klen, + pem_password_cb *cb, void *u); ++ + #define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \ +- ((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d,name,bp,x,enc,kstr,klen,cb,u) ++ (PEM_ASN1_write_bio(CHECKED_I2D_OF(type, i2d), \ ++ name, bp, \ ++ CHECKED_PTR_OF(type, x), \ ++ enc, kstr, klen, cb, u)) + + STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); + int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, +diff -up openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c.casts openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c +--- openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c.casts 2006-11-27 14:36:54.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c 2010-04-16 16:02:13.000000000 +0200 +@@ -345,7 +345,7 @@ static int tree_prune(X509_POLICY_TREE * + { + node->parent->nchild--; + OPENSSL_free(node); +- sk_X509_POLICY_NODE_delete(curr->nodes, i); ++ (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); + } + } + +@@ -358,7 +358,7 @@ static int tree_prune(X509_POLICY_TREE * + { + node->parent->nchild--; + OPENSSL_free(node); +- sk_X509_POLICY_NODE_delete(curr->nodes, i); ++ (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); + } + } + if (curr->anyPolicy && !curr->anyPolicy->nchild) +diff -up openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.casts openssl-fips-0.9.8e/crypto/x509/x509_vfy.c +--- openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/x509_vfy.c 2010-04-16 16:02:13.000000000 +0200 +@@ -164,7 +164,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx + goto end; + } + CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); +- sk_X509_delete_ptr(sktmp,xtmp); ++ (void)sk_X509_delete_ptr(sktmp,xtmp); + ctx->last_untrusted++; + x=xtmp; + num++; +@@ -214,7 +214,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx + */ + X509_free(x); + x = xtmp; +- sk_X509_set(ctx->chain, i - 1, x); ++ (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted=0; + } + } +diff -up openssl-fips-0.9.8e/crypto/x509/x509_vpm.c.casts openssl-fips-0.9.8e/crypto/x509/x509_vpm.c +--- openssl-fips-0.9.8e/crypto/x509/x509_vpm.c.casts 2006-05-03 15:16:02.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/x509_vpm.c 2010-04-16 16:02:13.000000000 +0200 +@@ -385,7 +385,7 @@ int X509_VERIFY_PARAM_add0_table(X509_VE + { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); +- sk_X509_VERIFY_PARAM_delete(param_table, idx); ++ (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) +diff -up openssl-fips-0.9.8e/engines/e_ubsec.c.casts openssl-fips-0.9.8e/engines/e_ubsec.c +--- openssl-fips-0.9.8e/engines/e_ubsec.c.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/engines/e_ubsec.c 2010-04-16 16:02:13.000000000 +0200 +@@ -822,11 +822,11 @@ static int ubsec_dsa_verify(const unsign + int v_len, d_len; + int to_return = 0; + int fd; +- BIGNUM v; ++ BIGNUM v, *pv = &v; + + BN_init(&v); + +- if(!bn_wexpand(&v, dsa->p->top)) { ++ if(!bn_wexpand(pv, dsa->p->top)) { + UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } +diff -up openssl-fips-0.9.8e/ssl/ssl_cert.c.casts openssl-fips-0.9.8e/ssl/ssl_cert.c +--- openssl-fips-0.9.8e/ssl/ssl_cert.c.casts 2006-06-14 10:51:41.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl_cert.c 2010-04-16 16:02:13.000000000 +0200 +@@ -762,7 +762,7 @@ err: + if(x != NULL) + X509_free(x); + +- sk_X509_NAME_set_cmp_func(stack,oldcmp); ++ (void)sk_X509_NAME_set_cmp_func(stack,oldcmp); + + return ret; + } +diff -up openssl-fips-0.9.8e/ssl/s2_clnt.c.casts openssl-fips-0.9.8e/ssl/s2_clnt.c +--- openssl-fips-0.9.8e/ssl/s2_clnt.c.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_clnt.c 2010-04-16 16:02:13.000000000 +0200 +@@ -466,11 +466,11 @@ static int get_server_hello(SSL *s) + return(-1); + } + +- sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp); ++ (void)sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp); + + /* get the array of ciphers we will accept */ + cl=SSL_get_ciphers(s); +- sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp); ++ (void)sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp); + + /* + * If server preference flag set, choose the first +diff -up openssl-fips-0.9.8e/ssl/s2_srvr.c.casts openssl-fips-0.9.8e/ssl/s2_srvr.c +--- openssl-fips-0.9.8e/ssl/s2_srvr.c.casts 2010-04-16 11:00:44.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_srvr.c 2010-04-16 16:02:13.000000000 +0200 +@@ -657,7 +657,7 @@ static int get_client_hello(SSL *s) + { + if (sk_SSL_CIPHER_find(allow,sk_SSL_CIPHER_value(prio,z)) < 0) + { +- sk_SSL_CIPHER_delete(prio,z); ++ (void)sk_SSL_CIPHER_delete(prio,z); + z--; + } + } diff --git a/SOURCES/openssl-fips-0.9.8e-chil-fixes.patch b/SOURCES/openssl-fips-0.9.8e-chil-fixes.patch new file mode 100644 index 0000000..ede8909 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-chil-fixes.patch @@ -0,0 +1,148 @@ +diff -up openssl-fips-0.9.8e/engines/e_chil.c.chil openssl-fips-0.9.8e/engines/e_chil.c +--- openssl-fips-0.9.8e/engines/e_chil.c.chil 2005-07-16 13:13:08.000000000 +0200 ++++ openssl-fips-0.9.8e/engines/e_chil.c 2011-04-04 16:35:45.000000000 +0200 +@@ -116,6 +116,7 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, + /* This function is aliased to mod_exp (with the mont stuff dropped). */ + static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); ++static int hwcrhk_rsa_finish(RSA *rsa); + #endif + + #ifndef OPENSSL_NO_DH +@@ -135,10 +136,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENG + UI_METHOD *ui_method, void *callback_data); + static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +-#ifndef OPENSSL_NO_RSA +-static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, +- int ind,long argl, void *argp); +-#endif + + /* Interaction stuff */ + static int hwcrhk_insert_card(const char *prompt_info, +@@ -193,7 +190,7 @@ static RSA_METHOD hwcrhk_rsa = + hwcrhk_rsa_mod_exp, + hwcrhk_mod_exp_mont, + NULL, +- NULL, ++ hwcrhk_rsa_finish, + 0, + NULL, + NULL, +@@ -589,12 +586,6 @@ static int hwcrhk_init(ENGINE *e) + hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; + hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; + } +- else if (CRYPTO_get_locking_callback() != NULL) +- { +- HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_LOCKING_MISSING); +- ERR_add_error_data(1,"You HAVE to add dynamic locking callbacks via CRYPTO_set_dynlock_{create,lock,destroy}_callback()"); +- goto err; +- } + } + + /* Try and get a context - if not, we may have a DSO but no +@@ -609,7 +600,7 @@ static int hwcrhk_init(ENGINE *e) + if (hndidx_rsa == -1) + hndidx_rsa = RSA_get_ex_new_index(0, + "nFast HWCryptoHook RSA key handle", +- NULL, NULL, hwcrhk_ex_free); ++ NULL, NULL, NULL); + #endif + return 1; + err: +@@ -853,8 +844,6 @@ static EVP_PKEY *hwcrhk_load_privkey(ENG + + return res; + err: +- if (res) +- EVP_PKEY_free(res); + #ifndef OPENSSL_NO_RSA + if (rtmp) + RSA_free(rtmp); +@@ -1087,6 +1076,21 @@ static int hwcrhk_mod_exp_mont(BIGNUM *r + { + return hwcrhk_mod_exp(r, a, p, m, ctx); + } ++ ++static int hwcrhk_rsa_finish(RSA *rsa) ++ { ++ HWCryptoHook_RSAKeyHandle *hptr; ++ ++ hptr = RSA_get_ex_data(rsa, hndidx_rsa); ++ if (hptr) ++ { ++ p_hwcrhk_RSAUnloadKey(*hptr, NULL); ++ OPENSSL_free(hptr); ++ RSA_set_ex_data(rsa, hndidx_rsa, NULL); ++ } ++ return 1; ++ } ++ + #endif + + #ifndef OPENSSL_NO_DH +@@ -1145,34 +1149,6 @@ static int hwcrhk_rand_status(void) + return 1; + } + +-/* This cleans up an RSA KM key, called when ex_data is freed */ +-#ifndef OPENSSL_NO_RSA +-static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, +- int ind,long argl, void *argp) +-{ +- char tempbuf[1024]; +- HWCryptoHook_ErrMsgBuf rmsg; +-#ifndef OPENSSL_NO_RSA +- HWCryptoHook_RSAKeyHandle *hptr; +-#endif +-#if !defined(OPENSSL_NO_RSA) +- int ret; +-#endif +- +- rmsg.buf = tempbuf; +- rmsg.size = sizeof(tempbuf); +- +-#ifndef OPENSSL_NO_RSA +- hptr = (HWCryptoHook_RSAKeyHandle *) item; +- if(hptr) +- { +- ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); +- OPENSSL_free(hptr); +- } +-#endif +-} +-#endif +- + /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model + * these just wrap the POSIX functions and add some logging. + */ +@@ -1210,6 +1186,11 @@ static int hwcrhk_get_pass(const char *p + pem_password_cb *callback = NULL; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; ++ /* Despite what the documentation says prompt_info can be ++ * an empty string. ++ */ ++ if (prompt_info && !*prompt_info) ++ prompt_info = NULL; + + if (cactx) + { +@@ -1311,10 +1292,14 @@ static int hwcrhk_insert_card(const char + { + char answer; + char buf[BUFSIZ]; +- +- if (wrong_info) ++ /* Despite what the documentation says wrong_info can be ++ * an empty string. ++ */ ++ if (wrong_info && *wrong_info) + BIO_snprintf(buf, sizeof(buf)-1, + "Current card: \"%s\"\n", wrong_info); ++ else ++ buf[0] = 0; + ok = UI_dup_info_string(ui, buf); + if (ok >= 0 && prompt_info) + { diff --git a/SOURCES/openssl-fips-0.9.8e-ciph-sort.patch b/SOURCES/openssl-fips-0.9.8e-ciph-sort.patch new file mode 100644 index 0000000..d36f2fb --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-ciph-sort.patch @@ -0,0 +1,11 @@ +diff -up openssl-fips-0.9.8e/ssl/ssl_ciph.c.sort openssl-fips-0.9.8e/ssl/ssl_ciph.c +--- openssl-fips-0.9.8e/ssl/ssl_ciph.c.sort 2010-12-07 17:45:32.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_ciph.c 2011-04-04 14:00:56.000000000 +0200 +@@ -1087,6 +1087,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ + sk_SSL_CIPHER_free(*cipher_list_by_id); + *cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); ++ sk_SSL_CIPHER_sort(*cipher_list_by_id); + + return(cipherstack); + } diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2008-5077.patch b/SOURCES/openssl-fips-0.9.8e-cve-2008-5077.patch new file mode 100644 index 0000000..2d33e45 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2008-5077.patch @@ -0,0 +1,140 @@ +diff -up openssl-fips-0.9.8e/apps/speed.c.verifysig openssl-fips-0.9.8e/apps/speed.c +--- openssl-fips-0.9.8e/apps/speed.c.verifysig 2007-05-21 14:40:06.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/speed.c 2008-12-16 16:44:22.000000000 +0100 +@@ -2132,7 +2132,7 @@ int MAIN(int argc, char **argv) + { + ret=RSA_verify(NID_md5_sha1, buf,36, buf2, + rsa_num, rsa_key[j]); +- if (ret == 0) ++ if (ret <= 0) + { + BIO_printf(bio_err, + "RSA verify failure\n"); +diff -up openssl-fips-0.9.8e/apps/verify.c.verifysig openssl-fips-0.9.8e/apps/verify.c +--- openssl-fips-0.9.8e/apps/verify.c.verifysig 2004-11-29 12:28:07.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/verify.c 2008-12-16 16:44:22.000000000 +0100 +@@ -266,7 +266,7 @@ static int check(X509_STORE *ctx, char * + + ret=0; + end: +- if (i) ++ if (i > 0) + { + fprintf(stdout,"OK\n"); + ret=1; +@@ -367,4 +367,3 @@ static int MS_CALLBACK cb(int ok, X509_S + ERR_clear_error(); + return(ok); + } +- +diff -up openssl-fips-0.9.8e/apps/spkac.c.verifysig openssl-fips-0.9.8e/apps/spkac.c +--- openssl-fips-0.9.8e/apps/spkac.c.verifysig 2005-04-05 21:11:18.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/spkac.c 2008-12-16 16:44:22.000000000 +0100 +@@ -285,7 +285,7 @@ bad: + pkey = NETSCAPE_SPKI_get_pubkey(spki); + if(verify) { + i = NETSCAPE_SPKI_verify(spki, pkey); +- if(i) BIO_printf(bio_err, "Signature OK\n"); ++ if (i > 0) BIO_printf(bio_err, "Signature OK\n"); + else { + BIO_printf(bio_err, "Signature Failure\n"); + ERR_print_errors(bio_err); +diff -up openssl-fips-0.9.8e/apps/x509.c.verifysig openssl-fips-0.9.8e/apps/x509.c +--- openssl-fips-0.9.8e/apps/x509.c.verifysig 2005-07-16 13:13:03.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/x509.c 2008-12-16 16:44:22.000000000 +0100 +@@ -1144,7 +1144,7 @@ static int x509_certify(X509_STORE *ctx, + /* NOTE: this certificate can/should be self signed, unless it was + * a certificate request in which case it is not. */ + X509_STORE_CTX_set_cert(&xsc,x); +- if (!reqfile && !X509_verify_cert(&xsc)) ++ if (!reqfile && X509_verify_cert(&xsc) <= 0) + goto end; + + if (!X509_check_private_key(xca,pkey)) +diff -up openssl-fips-0.9.8e/ssl/s2_clnt.c.verifysig openssl-fips-0.9.8e/ssl/s2_clnt.c +--- openssl-fips-0.9.8e/ssl/s2_clnt.c.verifysig 2006-09-28 13:29:03.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_clnt.c 2008-12-16 16:44:50.000000000 +0100 +@@ -1044,7 +1044,7 @@ int ssl2_set_certificate(SSL *s, int typ + + i=ssl_verify_cert_chain(s,sk); + +- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i)) ++ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) + { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); + goto err; +diff -up openssl-fips-0.9.8e/ssl/s2_srvr.c.verifysig openssl-fips-0.9.8e/ssl/s2_srvr.c +--- openssl-fips-0.9.8e/ssl/s2_srvr.c.verifysig 2005-12-05 18:32:20.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s2_srvr.c 2008-12-16 16:47:28.000000000 +0100 +@@ -1054,7 +1054,7 @@ static int request_certificate(SSL *s) + + i=ssl_verify_cert_chain(s,sk); + +- if (i) /* we like the packet, now check the chksum */ ++ if (i > 0) /* we like the packet, now check the chksum */ + { + EVP_MD_CTX ctx; + EVP_PKEY *pkey=NULL; +@@ -1083,7 +1083,7 @@ static int request_certificate(SSL *s) + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&ctx); + +- if (i) ++ if (i > 0) + { + if (s->session->peer != NULL) + X509_free(s->session->peer); +diff -up openssl-fips-0.9.8e/ssl/s3_clnt.c.verifysig openssl-fips-0.9.8e/ssl/s3_clnt.c +--- openssl-fips-0.9.8e/ssl/s3_clnt.c.verifysig 2008-10-31 09:18:53.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_clnt.c 2008-12-16 16:44:50.000000000 +0100 +@@ -886,7 +886,7 @@ int ssl3_get_server_certificate(SSL *s) + } + + i=ssl_verify_cert_chain(s,sk); +- if ((s->verify_mode != SSL_VERIFY_NONE) && (!i) ++ if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) + #ifndef OPENSSL_NO_KRB5 + && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) + != (SSL_aKRB5|SSL_kKRB5) +@@ -1373,7 +1373,7 @@ int ssl3_get_key_exchange(SSL *s) + EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx,param,param_len); +- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) ++ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0) + { + /* bad signature */ + al=SSL_AD_DECRYPT_ERROR; +@@ -1391,7 +1391,7 @@ int ssl3_get_key_exchange(SSL *s) + EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); + EVP_VerifyUpdate(&md_ctx,param,param_len); +- if (!EVP_VerifyFinal(&md_ctx,p,(int)n,pkey)) ++ if (EVP_VerifyFinal(&md_ctx,p,(int)n,pkey) <= 0) + { + /* bad signature */ + al=SSL_AD_DECRYPT_ERROR; +diff -up openssl-fips-0.9.8e/ssl/ssltest.c.verifysig openssl-fips-0.9.8e/ssl/ssltest.c +--- openssl-fips-0.9.8e/ssl/ssltest.c.verifysig 2007-08-21 17:26:51.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssltest.c 2008-12-16 16:44:50.000000000 +0100 +@@ -2093,7 +2093,7 @@ static int MS_CALLBACK app_verify_callba + + if (cb_arg->proxy_auth) + { +- if (ok) ++ if (ok > 0) + { + const char *cond_end = NULL; + +diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.verifysig openssl-fips-0.9.8e/ssl/s3_srvr.c +--- openssl-fips-0.9.8e/ssl/s3_srvr.c.verifysig 2008-10-31 09:18:53.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_srvr.c 2008-12-16 16:44:50.000000000 +0100 +@@ -2484,7 +2484,7 @@ int ssl3_get_client_certificate(SSL *s) + else + { + i=ssl_verify_cert_chain(s,sk); +- if (!i) ++ if (i <= 0) + { + al=ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2009-0590.patch b/SOURCES/openssl-fips-0.9.8e-cve-2009-0590.patch new file mode 100644 index 0000000..b030d87 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2009-0590.patch @@ -0,0 +1,60 @@ +diff -up openssl-fips-0.9.8e/crypto/asn1/asn1_err.c.bad-string openssl-fips-0.9.8e/crypto/asn1/asn1_err.c +--- openssl-fips-0.9.8e/crypto/asn1/asn1_err.c.bad-string 2006-11-21 21:14:36.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/asn1/asn1_err.c 2009-04-15 16:31:18.000000000 +0200 +@@ -188,6 +188,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ + {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"}, + {ERR_REASON(ASN1_R_BAD_PASSWORD_READ) ,"bad password read"}, + {ERR_REASON(ASN1_R_BAD_TAG) ,"bad tag"}, ++{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"}, + {ERR_REASON(ASN1_R_BN_LIB) ,"bn lib"}, + {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"}, + {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"}, +@@ -267,6 +268,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"}, + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"}, + {ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"}, ++{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"}, + {ERR_REASON(ASN1_R_UNKNOWN_FORMAT) ,"unknown format"}, + {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"}, + {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"}, +diff -up openssl-fips-0.9.8e/crypto/asn1/asn1.h.bad-string openssl-fips-0.9.8e/crypto/asn1/asn1.h +--- openssl-fips-0.9.8e/crypto/asn1/asn1.h.bad-string 2009-04-15 13:48:50.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/asn1/asn1.h 2009-04-15 16:31:18.000000000 +0200 +@@ -1134,6 +1134,7 @@ void ERR_load_ASN1_strings(void); + #define ASN1_R_BAD_OBJECT_HEADER 102 + #define ASN1_R_BAD_PASSWORD_READ 103 + #define ASN1_R_BAD_TAG 104 ++#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 210 + #define ASN1_R_BN_LIB 105 + #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 + #define ASN1_R_BUFFER_TOO_SMALL 107 +@@ -1213,6 +1214,7 @@ void ERR_load_ASN1_strings(void); + #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 + #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 + #define ASN1_R_UNEXPECTED_EOC 159 ++#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 211 + #define ASN1_R_UNKNOWN_FORMAT 160 + #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 + #define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +diff -up openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c.bad-string openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c +--- openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c.bad-string 2007-01-23 18:54:22.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/asn1/tasn_dec.c 2009-04-15 16:31:18.000000000 +0200 +@@ -1012,6 +1012,18 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const + case V_ASN1_SET: + case V_ASN1_SEQUENCE: + default: ++ if (utype == V_ASN1_BMPSTRING && (len & 1)) ++ { ++ ASN1err(ASN1_F_ASN1_EX_C2I, ++ ASN1_R_BMPSTRING_IS_WRONG_LENGTH); ++ goto err; ++ } ++ if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) ++ { ++ ASN1err(ASN1_F_ASN1_EX_C2I, ++ ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); ++ goto err; ++ } + /* All based on ASN1_STRING and handled the same */ + if (!*pval) + { diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2009-2409.patch b/SOURCES/openssl-fips-0.9.8e-cve-2009-2409.patch new file mode 100644 index 0000000..40fac2f --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2009-2409.patch @@ -0,0 +1,59 @@ +Skip signature validation on selfsigned certificates and +drop MD2 algorithm from the list of algorithms added to +EVP tables by default. (CVE-2009-2409) +diff -up openssl-fips-0.9.8e/crypto/evp/c_alld.c.nomd2 openssl-fips-0.9.8e/crypto/evp/c_alld.c +--- openssl-fips-0.9.8e/crypto/evp/c_alld.c.nomd2 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/c_alld.c 2010-01-14 09:24:00.000000000 +0100 +@@ -69,9 +69,6 @@ void OpenSSL_add_all_digests(void) + if (!FIPS_mode()) + { + #endif +-#ifndef OPENSSL_NO_MD2 +- EVP_add_digest(EVP_md2()); +-#endif + #ifndef OPENSSL_NO_MD4 + EVP_add_digest(EVP_md4()); + #endif +diff -up openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.nomd2 openssl-fips-0.9.8e/crypto/x509/x509_vfy.c +--- openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.nomd2 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/x509_vfy.c 2010-01-14 09:22:49.000000000 +0100 +@@ -1013,7 +1013,11 @@ static int internal_verify(X509_STORE_CT + while (n >= 0) + { + ctx->error_depth=n; +- if (!xs->valid) ++ ++ /* Skip signature check for self signed certificates. It ++ * doesn't add any security and just wastes time. ++ */ ++ if (!xs->valid && xs != xi) + { + if ((pkey=X509_get_pubkey(xi)) == NULL) + { +@@ -1023,13 +1027,6 @@ static int internal_verify(X509_STORE_CT + if (!ok) goto end; + } + else if (X509_verify(xs,pkey) <= 0) +- /* XXX For the final trusted self-signed cert, +- * this is a waste of time. That check should +- * optional so that e.g. 'openssl x509' can be +- * used to detect invalid self-signatures, but +- * we don't verify again and again in SSL +- * handshakes and the like once the cert has +- * been declared trusted. */ + { + ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert=xs; +diff -up openssl-fips-0.9.8e/ssl/ssl_algs.c.nomd2 openssl-fips-0.9.8e/ssl/ssl_algs.c +--- openssl-fips-0.9.8e/ssl/ssl_algs.c.nomd2 2009-04-15 14:09:42.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl_algs.c 2010-01-14 09:23:10.000000000 +0100 +@@ -94,9 +94,6 @@ int SSL_library_init(void) + EVP_add_cipher(EVP_seed_cbc()); + #endif + +-#ifndef OPENSSL_NO_MD2 +- EVP_add_digest(EVP_md2()); +-#endif + #ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5,"ssl2-md5"); diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2009-3245.patch b/SOURCES/openssl-fips-0.9.8e-cve-2009-3245.patch new file mode 100644 index 0000000..e977aa8 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2009-3245.patch @@ -0,0 +1,57 @@ +diff -up openssl-fips-0.9.8e/crypto/bn/bn_gf2m.c.wexpand openssl-fips-0.9.8e/crypto/bn/bn_gf2m.c +--- openssl-fips-0.9.8e/crypto/bn/bn_gf2m.c.wexpand 2006-02-08 20:16:11.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/bn/bn_gf2m.c 2010-03-12 13:28:55.000000000 +0100 +@@ -294,7 +294,8 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM + if (a->top < b->top) { at = b; bt = a; } + else { at = a; bt = b; } + +- bn_wexpand(r, at->top); ++ if(bn_wexpand(r, at->top) == NULL) ++ return 0; + + for (i = 0; i < bt->top; i++) + { +diff -up openssl-fips-0.9.8e/crypto/bn/bn_mul.c.wexpand openssl-fips-0.9.8e/crypto/bn/bn_mul.c +--- openssl-fips-0.9.8e/crypto/bn/bn_mul.c.wexpand 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/bn/bn_mul.c 2010-03-12 13:27:24.000000000 +0100 +@@ -1030,15 +1030,15 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, c + t = BN_CTX_get(ctx); + if (al > j || bl > j) + { +- bn_wexpand(t,k*4); +- bn_wexpand(rr,k*4); ++ if (bn_wexpand(t,k*4) == NULL) goto err; ++ if (bn_wexpand(rr,k*4) == NULL) goto err; + bn_mul_part_recursive(rr->d,a->d,b->d, + j,al-j,bl-j,t->d); + } + else /* al <= j || bl <= j */ + { +- bn_wexpand(t,k*2); +- bn_wexpand(rr,k*2); ++ if (bn_wexpand(t,k*2) == NULL) goto err; ++ if (bn_wexpand(rr,k*2) == NULL) goto err; + bn_mul_recursive(rr->d,a->d,b->d, + j,al-j,bl-j,t->d); + } +diff -up openssl-fips-0.9.8e/engines/e_ubsec.c.wexpand openssl-fips-0.9.8e/engines/e_ubsec.c +--- openssl-fips-0.9.8e/engines/e_ubsec.c.wexpand 2005-07-16 13:13:08.000000000 +0200 ++++ openssl-fips-0.9.8e/engines/e_ubsec.c 2010-03-12 13:30:07.000000000 +0100 +@@ -934,7 +934,7 @@ static int ubsec_dh_generate_key(DH *dh) + priv_key = BN_new(); + if (priv_key == NULL) goto err; + priv_key_len = BN_num_bits(dh->p); +- bn_wexpand(priv_key, dh->p->top); ++ if (bn_wexpand(priv_key, dh->p->top) == NULL) goto err; + do + if (!BN_rand_range(priv_key, dh->p)) goto err; + while (BN_is_zero(priv_key)); +@@ -949,7 +949,7 @@ static int ubsec_dh_generate_key(DH *dh) + { + pub_key = BN_new(); + pub_key_len = BN_num_bits(dh->p); +- bn_wexpand(pub_key, dh->p->top); ++ if(bn_wexpand(pub_key, dh->p->top) == NULL) goto err; + if(pub_key == NULL) goto err; + } + else diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2009-3555.patch b/SOURCES/openssl-fips-0.9.8e-cve-2009-3555.patch new file mode 100644 index 0000000..bb1f22c --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2009-3555.patch @@ -0,0 +1,1502 @@ +diff -up openssl-fips-0.9.8e/apps/s_client.c.reneg openssl-fips-0.9.8e/apps/s_client.c +--- openssl-fips-0.9.8e/apps/s_client.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/s_client.c 2010-02-18 15:58:31.000000000 +0100 +@@ -231,7 +231,7 @@ static void sc_usage(void) + BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n"); + #endif + BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); +- ++ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); + } + + enum +@@ -247,7 +247,7 @@ int MAIN(int, char **); + + int MAIN(int argc, char **argv) + { +- int off=0; ++ int off=0, clr = 0; + SSL *con=NULL,*con2=NULL; + X509_STORE *store = NULL; + int s,k,width,state=0; +@@ -461,6 +461,12 @@ int MAIN(int argc, char **argv) + off|=SSL_OP_NO_SSLv2; + else if (strcmp(*argv,"-serverpref") == 0) + off|=SSL_OP_CIPHER_SERVER_PREFERENCE; ++ else if (strcmp(*argv,"-legacy_renegotiation") == 0) ++ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; ++ else if (strcmp(*argv,"-legacy_server_connect") == 0) ++ { off|=SSL_OP_LEGACY_SERVER_CONNECT; } ++ else if (strcmp(*argv,"-no_legacy_server_connect") == 0) ++ { clr|=SSL_OP_LEGACY_SERVER_CONNECT; } + else if (strcmp(*argv,"-cipher") == 0) + { + if (--argc < 1) goto bad; +@@ -589,6 +595,9 @@ bad: + SSL_CTX_set_options(ctx,SSL_OP_ALL|off); + else + SSL_CTX_set_options(ctx,off); ++ ++ if (clr) ++ SSL_CTX_clear_options(ctx, clr); + /* DTLS: partial reads end up discarding unread UDP bytes :-( + * Setting read ahead solves this problem. + */ +@@ -1290,6 +1299,8 @@ static void print_stuff(BIO *bio, SSL *s + EVP_PKEY_bits(pktmp)); + EVP_PKEY_free(pktmp); + } ++ BIO_printf(bio, "Secure Renegotiation IS%s supported\n", ++ SSL_get_secure_renegotiation_support(s) ? "" : " NOT"); + #ifndef OPENSSL_NO_COMP + comp=SSL_get_current_compression(s); + expansion=SSL_get_current_expansion(s); +diff -up openssl-fips-0.9.8e/apps/s_server.c.reneg openssl-fips-0.9.8e/apps/s_server.c +--- openssl-fips-0.9.8e/apps/s_server.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/s_server.c 2010-02-18 15:58:31.000000000 +0100 +@@ -371,6 +371,7 @@ static void sv_usage(void) + #endif + BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); + BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); ++ BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); + } + + static int local_argc=0; +@@ -700,6 +701,8 @@ int MAIN(int argc, char *argv[]) + } + else if (strcmp(*argv,"-serverpref") == 0) + { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } ++ else if (strcmp(*argv,"-legacy_renegotiation") == 0) ++ off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; + else if (strcmp(*argv,"-cipher") == 0) + { + if (--argc < 1) goto bad; +@@ -1534,6 +1537,8 @@ static int init_ssl_connection(SSL *con) + con->kssl_ctx->client_princ); + } + #endif /* OPENSSL_NO_KRB5 */ ++ BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", ++ SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); + return(1); + } + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.reneg openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.reneg 2005-10-11 12:16:09.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod 2010-02-18 16:10:52.000000000 +0100 +@@ -2,7 +2,7 @@ + + =head1 NAME + +-SSL_CTX_set_options, SSL_set_options, SSL_CTX_get_options, SSL_get_options - manipulate SSL engine options ++SSL_CTX_set_options, SSL_set_options, SSL_CTX_clear_options, SSL_clear_options, SSL_CTX_get_options, SSL_get_options, SSL_get_secure_renegotiation_support - manipulate SSL options + + =head1 SYNOPSIS + +@@ -11,26 +11,41 @@ SSL_CTX_set_options, SSL_set_options, SS + long SSL_CTX_set_options(SSL_CTX *ctx, long options); + long SSL_set_options(SSL *ssl, long options); + ++ long SSL_CTX_clear_options(SSL_CTX *ctx, long options); ++ long SSL_clear_options(SSL *ssl, long options); ++ + long SSL_CTX_get_options(SSL_CTX *ctx); + long SSL_get_options(SSL *ssl); + ++ long SSL_get_secure_renegotiation_support(SSL *ssl); ++ + =head1 DESCRIPTION + ++Note: all these functions are implemented using macros. ++ + SSL_CTX_set_options() adds the options set via bitmask in B to B. + Options already set before are not cleared! + + SSL_set_options() adds the options set via bitmask in B to B. + Options already set before are not cleared! + ++SSL_CTX_clear_options() clears the options set via bitmask in B ++to B. ++ ++SSL_clear_options() clears the options set via bitmask in B to B. ++ + SSL_CTX_get_options() returns the options set for B. + + SSL_get_options() returns the options set for B. + ++SSL_get_secure_renegotiation_support() indicates whether the peer supports ++secure renegotiation. ++ + =head1 NOTES + + The behaviour of the SSL library can be changed by setting several options. + The options are coded as bitmasks and can be combined by a logical B +-operation (|). Options can only be added but can never be reset. ++operation (|). + + SSL_CTX_set_options() and SSL_set_options() affect the (external) + protocol behaviour of the SSL library. The (internal) behaviour of +@@ -199,17 +214,109 @@ Do not use the TLSv1 protocol. + + When performing renegotiation as a server, always start a new session + (i.e., session resumption requests are only accepted in the initial +-handshake). This option is not needed for clients. ++handshake). This option is not needed for clients. ++ ++=item SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION ++ ++Allow legacy insecure renegotiation between OpenSSL and unpatched clients or ++servers. See the B section for more details. ++ ++=item SSL_OP_LEGACY_SERVER_CONNECT ++ ++Allow legacy insecure renegotiation between OpenSSL and unpatched servers ++B: this option is currently set by default. See the ++B section for more details. + + =back + ++=head1 SECURE RENEGOTIATION ++ ++OpenSSL 0.9.8m and later always attempts to use secure renegotiation as ++described in RFC5746. This counters the prefix attack described in ++CVE-2009-3555 and elsewhere. ++ ++The deprecated and highly broken SSLv2 protocol does not support ++renegotiation at all: its use is B discouraged. ++ ++This attack has far reaching consequences which application writers should be ++aware of. In the description below an implementation supporting secure ++renegotiation is referred to as I. A server not supporting secure ++renegotiation is referred to as I. ++ ++The following sections describe the operations permitted by OpenSSL's secure ++renegotiation implementation. ++ ++=head2 Patched client and server ++ ++Connections and renegotiation are always permitted by OpenSSL implementations. ++ ++=head2 Unpatched client and patched OpenSSL server ++ ++The initial connection suceeds but client renegotiation is denied by the ++server with a B warning alert if TLS v1.0 is used or a fatal ++B alert in SSL v3.0. ++ ++If the patched OpenSSL server attempts to renegotiate a fatal ++B alert is sent. This is because the server code may be ++unaware of the unpatched nature of the client. ++ ++If the option B is set then ++renegotiation B succeeds. ++ ++B a bug in OpenSSL clients earlier than 0.9.8m (all of which are ++unpatched) will result in the connection hanging if it receives a ++B alert. OpenSSL versions 0.9.8m and later will regard ++a B alert as fatal and respond with a fatal ++B alert. This is because the OpenSSL API currently has ++no provision to indicate to an application that a renegotiation attempt ++was refused. ++ ++=head2 Patched OpenSSL client and unpatched server. ++ ++If the option B or ++B is set then initial connections ++and renegotiation between patched OpenSSL clients and unpatched servers ++succeeds. If neither option is set then initial connections to unpatched ++servers will fail. ++ ++The option B is currently set by default even ++though it has security implications: otherwise it would be impossible to ++connect to unpatched servers (i.e. all of them initially) and this is clearly ++not acceptable. Renegotiation is permitted because this does not add any ++additional security issues: during an attack clients do not see any ++renegotiations anyway. ++ ++As more servers become patched the option B will ++B be set by default in a future version of OpenSSL. ++ ++OpenSSL client applications wishing to ensure they can connect to unpatched ++servers should always B B ++ ++OpenSSL client applications that want to ensure they can B connect to ++unpatched servers (and thus avoid any security issues) should always B ++B using SSL_CTX_clear_options() or ++SSL_clear_options(). ++ ++The difference between the B and ++B options is that ++B enables initial connections and secure ++renegotiation between OpenSSL clients and unpatched servers B, while ++B allows initial connections ++and renegotiation between OpenSSL and unpatched clients or servers. ++ + =head1 RETURN VALUES + + SSL_CTX_set_options() and SSL_set_options() return the new options bitmask + after adding B. + ++SSL_CTX_clear_options() and SSL_clear_options() return the new options bitmask ++after clearing B. ++ + SSL_CTX_get_options() and SSL_get_options() return the current bitmask. + ++SSL_get_secure_renegotiation_support() returns 1 is the peer supports ++secure renegotiation and 0 if it does not. ++ + =head1 SEE ALSO + + L, L, L, +@@ -232,4 +339,11 @@ Versions up to OpenSSL 0.9.6c do not inc + can be disabled with this option (in OpenSSL 0.9.6d, it was always + enabled). + ++SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL ++0.9.8m. ++ ++B, B ++and the function SSL_get_secure_renegotiation_support() were first added in ++OpenSSL 0.9.8m. ++ + =cut +diff -up openssl-fips-0.9.8e/ssl/d1_both.c.reneg openssl-fips-0.9.8e/ssl/d1_both.c +--- openssl-fips-0.9.8e/ssl/d1_both.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_both.c 2010-02-18 15:58:31.000000000 +0100 +@@ -750,6 +750,24 @@ int dtls1_send_finished(SSL *s, int a, i + p+=i; + l=i; + ++ /* Copy the finished so we can use it for ++ * renegotiation checks ++ */ ++ if(s->type == SSL_ST_CONNECT) ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_client_finished, ++ s->s3->tmp.finish_md, i); ++ s->s3->previous_client_finished_len=i; ++ } ++ else ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_server_finished, ++ s->s3->tmp.finish_md, i); ++ s->s3->previous_server_finished_len=i; ++ } ++ + #ifdef OPENSSL_SYS_WIN16 + /* MSVC 1.5 does not clear the top bytes of the word unless + * I do this. +diff -up openssl-fips-0.9.8e/ssl/d1_clnt.c.reneg openssl-fips-0.9.8e/ssl/d1_clnt.c +--- openssl-fips-0.9.8e/ssl/d1_clnt.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_clnt.c 2010-02-18 15:58:31.000000000 +0100 +@@ -621,7 +621,13 @@ int dtls1_client_hello(SSL *s) + *(p++)=comp->id; + } + *(p++)=0; /* Add the NULL method */ +- ++ ++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) ++ { ++ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ + l=(p-d); + d=buf; + +diff -up openssl-fips-0.9.8e/ssl/d1_srvr.c.reneg openssl-fips-0.9.8e/ssl/d1_srvr.c +--- openssl-fips-0.9.8e/ssl/d1_srvr.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_srvr.c 2010-02-18 15:58:31.000000000 +0100 +@@ -267,7 +267,6 @@ int dtls1_accept(SSL *s) + s->shutdown=0; + ret=ssl3_get_client_hello(s); + if (ret <= 0) goto end; +- s->new_session = 2; + + if ( s->d1->send_cookie) + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; +@@ -293,6 +292,7 @@ int dtls1_accept(SSL *s) + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: ++ s->new_session = 2; + ret=dtls1_send_server_hello(s); + if (ret <= 0) goto end; + +@@ -713,6 +713,8 @@ int dtls1_send_server_hello(SSL *s) + p+=sl; + + /* put the cipher */ ++ if (s->s3->tmp.new_cipher == NULL) ++ return -1; + i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p); + p+=i; + +@@ -726,13 +728,21 @@ int dtls1_send_server_hello(SSL *s) + *(p++)=s->s3->tmp.new_compression->id; + #endif + ++#ifndef OPENSSL_NO_TLSEXT ++ if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) ++ { ++ SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); ++ return -1; ++ } ++#endif ++ + /* do the header */ + l=(p-d); + d=buf; + + d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); + +- s->state=SSL3_ST_CW_CLNT_HELLO_B; ++ s->state=SSL3_ST_SW_SRVR_HELLO_B; + /* number of bytes to write */ + s->init_num=p-buf; + s->init_off=0; +@@ -741,7 +751,7 @@ int dtls1_send_server_hello(SSL *s) + dtls1_buffer_message(s, 0); + } + +- /* SSL3_ST_CW_CLNT_HELLO_B */ ++ /* SSL3_ST_SW_SRVR_HELLO_B */ + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); + } + +@@ -765,7 +775,7 @@ int dtls1_send_server_done(SSL *s) + dtls1_buffer_message(s, 0); + } + +- /* SSL3_ST_CW_CLNT_HELLO_B */ ++ /* SSL3_ST_SW_SRVR_DONE_B */ + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); + } + +diff -up openssl-fips-0.9.8e/ssl/Makefile.reneg openssl-fips-0.9.8e/ssl/Makefile +--- openssl-fips-0.9.8e/ssl/Makefile.reneg 2007-08-01 13:33:16.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/Makefile 2010-02-18 15:58:31.000000000 +0100 +@@ -30,7 +30,7 @@ LIBSRC= \ + ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ + ssl_ciph.c ssl_stat.c ssl_rsa.c \ + ssl_asn1.c ssl_txt.c ssl_algs.c \ +- bio_ssl.c ssl_err.c kssl.c ++ bio_ssl.c ssl_err.c kssl.c t1_reneg.c + LIBOBJ= \ + s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ + s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ +@@ -41,7 +41,7 @@ LIBOBJ= \ + ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ + ssl_ciph.o ssl_stat.o ssl_rsa.o \ + ssl_asn1.o ssl_txt.o ssl_algs.o \ +- bio_ssl.o ssl_err.o kssl.o ++ bio_ssl.o ssl_err.o kssl.o t1_reneg.o + + SRC= $(LIBSRC) + +diff -up openssl-fips-0.9.8e/ssl/ssl_err.c.reneg openssl-fips-0.9.8e/ssl/ssl_err.c +--- openssl-fips-0.9.8e/ssl/ssl_err.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_err.c 2010-02-18 15:58:31.000000000 +0100 +@@ -168,8 +168,12 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"}, ++{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"}, ++{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), "SSL_add_dir_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), "SSL_add_file_cert_subjects_to_stack"}, ++{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"}, ++{ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), "SSL_ADD_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"}, + {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"}, +@@ -208,6 +212,10 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, + {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, + {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, ++{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"}, ++{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), "SSL_PARSE_CLIENTHELLO_TLSEXT"}, ++{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"}, ++{ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), "SSL_PARSE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, + {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, + {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, +@@ -371,6 +379,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"}, + {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"}, + {ERR_REASON(SSL_R_NO_PUBLICKEY) ,"no publickey"}, ++{ERR_REASON(SSL_R_NO_RENEGOTIATION) ,"no renegotiation"}, + {ERR_REASON(SSL_R_NO_SHARED_CIPHER) ,"no shared cipher"}, + {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) ,"no verify callback"}, + {ERR_REASON(SSL_R_NULL_SSL_CTX) ,"null ssl ctx"}, +@@ -378,6 +387,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),"old session cipher not returned"}, + {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),"only tls allowed in fips mode"}, + {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG),"packet length too long"}, ++{ERR_REASON(SSL_R_PARSE_TLSEXT) ,"parse tlsext"}, + {ERR_REASON(SSL_R_PATH_TOO_LONG) ,"path too long"}, + {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),"peer did not return a certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR) ,"peer error"}, +@@ -397,10 +407,14 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH),"record length mismatch"}, + {ERR_REASON(SSL_R_RECORD_TOO_LARGE) ,"record too large"}, + {ERR_REASON(SSL_R_RECORD_TOO_SMALL) ,"record too small"}, ++{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG),"renegotiate ext too long"}, ++{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),"renegotiation encoding err"}, ++{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH),"renegotiation mismatch"}, + {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING),"required cipher missing"}, + {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),"reuse cert length not zero"}, + {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO),"reuse cert type not zero"}, + {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),"reuse cipher list not zero"}, ++{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"}, + {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, + {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, + {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, +@@ -466,6 +480,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),"unknown remote error type"}, + {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) ,"unknown ssl version"}, + {ERR_REASON(SSL_R_UNKNOWN_STATE) ,"unknown state"}, ++{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),"unsafe legacy renegotiation disabled"}, + {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, + {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, + {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),"unsupported elliptic curve"}, +diff -up openssl-fips-0.9.8e/ssl/ssl.h.reneg openssl-fips-0.9.8e/ssl/ssl.h +--- openssl-fips-0.9.8e/ssl/ssl.h.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl.h 2010-02-18 15:58:31.000000000 +0100 +@@ -480,6 +480,8 @@ typedef struct ssl_session_st + + #define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L + #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L ++/* Allow initial connection to servers that don't support RI */ ++#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L + #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L /* can break some security expectations */ + #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L + #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L +@@ -506,6 +508,8 @@ typedef struct ssl_session_st + + /* As server, disallow session resumption on renegotiation */ + #define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L ++/* Permit unsafe legacy renegotiation */ ++#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L + /* If set, always create a new key when using tmp_ecdh parameters */ + #define SSL_OP_SINGLE_ECDH_USE 0x00080000L + /* If set, always create a new key when using tmp_dh parameters */ +@@ -554,17 +558,25 @@ typedef struct ssl_session_st + + #define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) ++#define SSL_CTX_clear_options(ctx,op) \ ++ SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) + #define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) + #define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) ++#define SSL_clear_options(ssl,op) \ ++ SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) + #define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + + #define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) ++#define SSL_CTX_clear_mode(ctx,op) \ ++ SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) + #define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) ++#define SSL_clear_mode(ssl,op) \ ++ SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) + #define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) + #define SSL_get_mode(ssl) \ +@@ -572,6 +584,8 @@ typedef struct ssl_session_st + #define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) + ++#define SSL_get_secure_renegotiation_support(ssl) \ ++ SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + + void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); + void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); +@@ -1189,6 +1203,10 @@ size_t SSL_get_peer_finished(const SSL * + #define SSL_CTRL_GET_MAX_CERT_LIST 50 + #define SSL_CTRL_SET_MAX_CERT_LIST 51 + ++#define SSL_CTRL_GET_RI_SUPPORT 76 ++#define SSL_CTRL_CLEAR_OPTIONS 77 ++#define SSL_CTRL_CLEAR_MODE 78 ++ + #define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) + #define SSL_num_renegotiations(ssl) \ +@@ -1650,8 +1668,12 @@ void ERR_load_SSL_strings(void); + #define SSL_F_SSL3_SETUP_KEY_BLOCK 157 + #define SSL_F_SSL3_WRITE_BYTES 158 + #define SSL_F_SSL3_WRITE_PENDING 159 ++#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 285 ++#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 272 + #define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 + #define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 ++#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 286 ++#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 273 + #define SSL_F_SSL_BAD_METHOD 160 + #define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 + #define SSL_F_SSL_CERT_DUP 221 +@@ -1690,6 +1712,10 @@ void ERR_load_SSL_strings(void); + #define SSL_F_SSL_INIT_WBIO_BUFFER 184 + #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 + #define SSL_F_SSL_NEW 186 ++#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 287 ++#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 290 ++#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 289 ++#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 291 + #define SSL_F_SSL_PEEK 270 + #define SSL_F_SSL_READ 223 + #define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +@@ -1850,6 +1876,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 + #define SSL_R_NO_PROTOCOLS_AVAILABLE 191 + #define SSL_R_NO_PUBLICKEY 192 ++#define SSL_R_NO_RENEGOTIATION 319 + #define SSL_R_NO_SHARED_CIPHER 193 + #define SSL_R_NO_VERIFY_CALLBACK 194 + #define SSL_R_NULL_SSL_CTX 195 +@@ -1857,6 +1884,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 + #define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 + #define SSL_R_PACKET_LENGTH_TOO_LONG 198 ++#define SSL_R_PARSE_TLSEXT 223 + #define SSL_R_PATH_TOO_LONG 270 + #define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 + #define SSL_R_PEER_ERROR 200 +@@ -1876,10 +1904,14 @@ void ERR_load_SSL_strings(void); + #define SSL_R_RECORD_LENGTH_MISMATCH 213 + #define SSL_R_RECORD_TOO_LARGE 214 + #define SSL_R_RECORD_TOO_SMALL 298 ++#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 320 ++#define SSL_R_RENEGOTIATION_ENCODING_ERR 321 ++#define SSL_R_RENEGOTIATION_MISMATCH 322 + #define SSL_R_REQUIRED_CIPHER_MISSING 215 + #define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 + #define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 + #define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 ++#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 324 + #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 + #define SSL_R_SHORT_READ 219 + #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +@@ -1945,6 +1977,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 + #define SSL_R_UNKNOWN_SSL_VERSION 254 + #define SSL_R_UNKNOWN_STATE 255 ++#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 323 + #define SSL_R_UNSUPPORTED_CIPHER 256 + #define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 + #define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +diff -up openssl-fips-0.9.8e/ssl/ssl_lib.c.reneg openssl-fips-0.9.8e/ssl/ssl_lib.c +--- openssl-fips-0.9.8e/ssl/ssl_lib.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_lib.c 2010-02-18 16:10:30.000000000 +0100 +@@ -958,8 +958,12 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v + + case SSL_CTRL_OPTIONS: + return(s->options|=larg); ++ case SSL_CTRL_CLEAR_OPTIONS: ++ return(s->options&=~larg); + case SSL_CTRL_MODE: + return(s->mode|=larg); ++ case SSL_CTRL_CLEAR_MODE: ++ return(s->mode &=~larg); + case SSL_CTRL_GET_MAX_CERT_LIST: + return(s->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: +@@ -973,6 +977,10 @@ long SSL_ctrl(SSL *s,int cmd,long larg,v + return larg; + } + return 0; ++ case SSL_CTRL_GET_RI_SUPPORT: ++ if (s->s3) ++ return s->s3->send_connection_binding; ++ else return 0; + default: + return(s->method->ssl_ctrl(s,cmd,larg,parg)); + } +@@ -1059,8 +1067,12 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,l + return(ctx->stats.sess_cache_full); + case SSL_CTRL_OPTIONS: + return(ctx->options|=larg); ++ case SSL_CTRL_CLEAR_OPTIONS: ++ return(ctx->options&=~larg); + case SSL_CTRL_MODE: + return(ctx->mode|=larg); ++ case SSL_CTRL_CLEAR_MODE: ++ return(ctx->mode&=~larg); + default: + return(ctx->method->ssl_ctx_ctrl(ctx,cmd,larg,parg)); + } +@@ -1257,6 +1269,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC + j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); + p+=j; + } ++ /* If p == q, no ciphers and caller indicates an error. Otherwise ++ * add SCSV if not renegotiating. ++ */ ++ if (p != q && !s->new_session) ++ { ++ static SSL_CIPHER scsv = ++ { ++ 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, ++ }; ++ j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p); ++ p+=j; ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "SCSV sent by client\n"); ++#endif ++ } ++ + return(p-q); + } + +@@ -1266,6 +1294,8 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int i,n; ++ if (s->s3) ++ s->s3->send_connection_binding = 0; + + n=ssl_put_cipher_by_char(s,NULL,NULL); + if ((num%n) != 0) +@@ -1283,6 +1313,26 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe + + for (i=0; is3 && (n != 3 || !p[0]) && ++ (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && ++ (p[n-1] == (SSL3_CK_SCSV & 0xff))) ++ { ++ /* SCSV fatal if renegotiating */ ++ if (s->new_session) ++ { ++ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); ++ goto err; ++ } ++ s->s3->send_connection_binding = 1; ++ p += n; ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "SCSV received by server\n"); ++#endif ++ continue; ++ } ++ + c=ssl_get_cipher_by_char(s,p); + p+=n; + if (c != NULL) +@@ -1461,6 +1511,11 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) + ret->extra_certs=NULL; + ret->comp_methods=SSL_COMP_get_compression_methods(); + ++ /* Default is to connect to non-RI servers. When RI is more widely ++ * deployed might change this. ++ */ ++ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; ++ + return(ret); + err: + SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); +diff -up openssl-fips-0.9.8e/ssl/ssl_locl.h.reneg openssl-fips-0.9.8e/ssl/ssl_locl.h +--- openssl-fips-0.9.8e/ssl/ssl_locl.h.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_locl.h 2010-02-18 15:58:31.000000000 +0100 +@@ -934,5 +934,17 @@ int check_srvr_ecc_cert_and_alg(X509 *x, + + SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); + ++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); ++unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); ++int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); ++int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); ++int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, ++ int maxlen); ++int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, ++ int *al); ++int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, ++ int maxlen); ++int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, ++ int *al); + + #endif +diff -up openssl-fips-0.9.8e/ssl/ssl3.h.reneg openssl-fips-0.9.8e/ssl/ssl3.h +--- openssl-fips-0.9.8e/ssl/ssl3.h.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl3.h 2010-02-18 15:58:31.000000000 +0100 +@@ -129,6 +129,9 @@ + extern "C" { + #endif + ++/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ ++#define SSL3_CK_SCSV 0x030000FF ++ + #define SSL3_CK_RSA_NULL_MD5 0x03000001 + #define SSL3_CK_RSA_NULL_SHA 0x03000002 + #define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +@@ -437,6 +440,12 @@ typedef struct ssl3_state_st + int cert_request; + } tmp; + ++ /* Connection binding to prevent renegotiation attacks */ ++ unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; ++ unsigned char previous_client_finished_len; ++ unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; ++ unsigned char previous_server_finished_len; ++ int send_connection_binding; /* TODOEKR */ + } SSL3_STATE; + + +diff -up openssl-fips-0.9.8e/ssl/s23_clnt.c.reneg openssl-fips-0.9.8e/ssl/s23_clnt.c +--- openssl-fips-0.9.8e/ssl/s23_clnt.c.reneg 2007-03-22 01:39:13.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s23_clnt.c 2010-02-18 16:07:51.000000000 +0100 +@@ -368,6 +368,11 @@ static int ssl23_client_hello(SSL *s) + *(p++)=comp->id; + } + *(p++)=0; /* Add the NULL method */ ++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) ++ { ++ SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); ++ return -1; ++ } + + l = p-d; + *p = 42; +diff -up openssl-fips-0.9.8e/ssl/s3_both.c.reneg openssl-fips-0.9.8e/ssl/s3_both.c +--- openssl-fips-0.9.8e/ssl/s3_both.c.reneg 2005-04-26 18:02:39.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/s3_both.c 2010-02-18 15:58:31.000000000 +0100 +@@ -168,6 +168,23 @@ int ssl3_send_finished(SSL *s, int a, in + p+=i; + l=i; + ++ /* Copy the finished so we can use it for ++ renegotiation checks */ ++ if(s->type == SSL_ST_CONNECT) ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_client_finished, ++ s->s3->tmp.finish_md, i); ++ s->s3->previous_client_finished_len=i; ++ } ++ else ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_server_finished, ++ s->s3->tmp.finish_md, i); ++ s->s3->previous_server_finished_len=i; ++ } ++ + #ifdef OPENSSL_SYS_WIN16 + /* MSVC 1.5 does not clear the top bytes of the word unless + * I do this. +@@ -232,6 +249,23 @@ int ssl3_get_finished(SSL *s, int a, int + goto f_err; + } + ++ /* Copy the finished so we can use it for ++ renegotiation checks */ ++ if(s->type == SSL_ST_ACCEPT) ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_client_finished, ++ s->s3->tmp.peer_finish_md, i); ++ s->s3->previous_client_finished_len=i; ++ } ++ else ++ { ++ OPENSSL_assert(i <= EVP_MAX_MD_SIZE); ++ memcpy(s->s3->previous_server_finished, ++ s->s3->tmp.peer_finish_md, i); ++ s->s3->previous_server_finished_len=i; ++ } ++ + return(1); + f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); +diff -up openssl-fips-0.9.8e/ssl/s3_clnt.c.reneg openssl-fips-0.9.8e/ssl/s3_clnt.c +--- openssl-fips-0.9.8e/ssl/s3_clnt.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_clnt.c 2010-02-18 15:58:31.000000000 +0100 +@@ -601,7 +601,11 @@ int ssl3_client_hello(SSL *s) + } + #endif + *(p++)=0; /* Add the NULL method */ +- ++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) ++ { ++ SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); ++ goto err; ++ } + l=(p-d); + d=buf; + *(d++)=SSL3_MT_CLIENT_HELLO; +@@ -635,7 +639,7 @@ int ssl3_get_server_hello(SSL *s) + SSL3_ST_CR_SRVR_HELLO_A, + SSL3_ST_CR_SRVR_HELLO_B, + -1, +- 300, /* ?? */ ++ 1000, /* ?? */ + &ok); + + if (!ok) return((int)n); +@@ -785,6 +789,17 @@ int ssl3_get_server_hello(SSL *s) + s->s3->tmp.new_compression=comp; + } + #endif ++ /* TLS extensions - we parse renegotiate extension only */ ++ if (s->version >= SSL3_VERSION) ++ { ++ if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al)) ++ { ++ /* 'al' set by ssl_parse_serverhello_tlsext */ ++ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_PARSE_TLSEXT); ++ goto f_err; ++ } ++ } ++ + + if (p != (d+n)) + { +diff -up openssl-fips-0.9.8e/ssl/s3_pkt.c.reneg openssl-fips-0.9.8e/ssl/s3_pkt.c +--- openssl-fips-0.9.8e/ssl/s3_pkt.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_pkt.c 2010-02-18 15:58:31.000000000 +0100 +@@ -1013,7 +1013,25 @@ start: + * now try again to obtain the (application) data we were asked for */ + goto start; + } +- ++ /* If we are a server and get a client hello when renegotiation isn't ++ * allowed send back a no renegotiation alert and carry on. ++ * WARNING: experimental code, needs reviewing (steve) ++ */ ++ if (s->server && ++ SSL_is_init_finished(s) && ++ !s->s3->send_connection_binding && ++ (s->version > SSL3_VERSION) && ++ (s->s3->handshake_fragment_len >= 4) && ++ (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && ++ (s->session != NULL) && (s->session->cipher != NULL) && ++ !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) ++ ++ { ++ /*s->s3->handshake_fragment_len = 0;*/ ++ rr->length = 0; ++ ssl3_send_alert(s,SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); ++ goto start; ++ } + if (s->s3->alert_fragment_len >= 2) + { + int alert_level = s->s3->alert_fragment[0]; +@@ -1043,6 +1061,21 @@ start: + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return(0); + } ++ /* This is a warning but we receive it if we requested ++ * renegotiation and the peer denied it. Terminate with ++ * a fatal alert because if application tried to ++ * renegotiatie it presumably had a good reason and ++ * expects it to succeed. ++ * ++ * In future we might have a renegotiation where we ++ * don't care if the peer refused it where we carry on. ++ */ ++ else if (alert_descr == SSL_AD_NO_RENEGOTIATION) ++ { ++ al = SSL_AD_HANDSHAKE_FAILURE; ++ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION); ++ goto f_err; ++ } + } + else if (alert_level == 2) /* fatal */ + { +diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.reneg openssl-fips-0.9.8e/ssl/s3_srvr.c +--- openssl-fips-0.9.8e/ssl/s3_srvr.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_srvr.c 2010-02-18 15:58:31.000000000 +0100 +@@ -248,6 +248,18 @@ int ssl3_accept(SSL *s) + s->state=SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } ++ else if (!s->s3->send_connection_binding && ++ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) ++ { ++ /* Server attempting to renegotiate with ++ * client that doesn't support secure ++ * renegotiation. ++ */ ++ SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); ++ ret = -1; ++ goto end; ++ } + else + { + /* s->state == SSL_ST_RENEGOTIATE, +@@ -898,6 +910,16 @@ int ssl3_get_client_hello(SSL *s) + goto f_err; + } + ++ /* TLS extensions - just parsing the renegotiation extension */ ++ if (s->version >= SSL3_VERSION) ++ { ++ if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al)) ++ { ++ /* 'al' set by ssl_parse_clienthello_tlsext */ ++ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT); ++ goto f_err; ++ } ++ } + /* Worst case, we will use the NULL compression, but if we have other + * options, we will now look for them. We have i-1 compression + * algorithms from the client, starting at q. */ +@@ -1089,20 +1111,24 @@ int ssl3_send_server_hello(SSL *s) + else + *(p++)=s->s3->tmp.new_compression->id; + #endif +- ++ if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) ++ { ++ SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); ++ return -1; ++ } + /* do the header */ + l=(p-d); + d=buf; + *(d++)=SSL3_MT_SERVER_HELLO; + l2n3(l,d); + +- s->state=SSL3_ST_CW_CLNT_HELLO_B; ++ s->state=SSL3_ST_SW_SRVR_HELLO_B; + /* number of bytes to write */ + s->init_num=p-buf; + s->init_off=0; + } + +- /* SSL3_ST_CW_CLNT_HELLO_B */ ++ /* SSL3_ST_SW_SRVR_HELLO_B */ + return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + } + +@@ -1126,7 +1152,7 @@ int ssl3_send_server_done(SSL *s) + s->init_off=0; + } + +- /* SSL3_ST_CW_CLNT_HELLO_B */ ++ /* SSL3_ST_SW_SRVR_DONE_B */ + return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); + } + +diff -up openssl-fips-0.9.8e/ssl/tls1.h.reneg openssl-fips-0.9.8e/ssl/tls1.h +--- openssl-fips-0.9.8e/ssl/tls1.h.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/tls1.h 2010-02-18 15:58:31.000000000 +0100 +@@ -97,6 +97,9 @@ extern "C" { + #define TLS1_AD_USER_CANCELLED 90 + #define TLS1_AD_NO_RENEGOTIATION 100 + ++/* Temporary extension type */ ++#define TLSEXT_TYPE_renegotiate 0xff01 ++ + /* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt + * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see + * s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably +diff -up openssl-fips-0.9.8e/ssl/t1_lib.c.reneg openssl-fips-0.9.8e/ssl/t1_lib.c +--- openssl-fips-0.9.8e/ssl/t1_lib.c.reneg 2007-01-21 17:07:25.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/t1_lib.c 2010-02-18 16:10:05.000000000 +0100 +@@ -117,3 +117,202 @@ long tls1_callback_ctrl(SSL *s, int cmd, + return(0); + } + #endif ++ ++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) ++ { ++ int extdatalen=0; ++ unsigned char *ret = p; ++ ++ /* don't add extensions for SSLv3 unless doing secure renegotiation */ ++ if (s->client_version == SSL3_VERSION ++ && !s->s3->send_connection_binding) ++ return p; ++ ++ ret+=2; ++ ++ if (ret>=limit) return NULL; /* this really never occurs, but ... */ ++ ++ /* Add RI if renegotiating */ ++ if (s->new_session) ++ { ++ int el; ++ ++ if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) ++ { ++ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); ++ return NULL; ++ } ++ ++ if((limit - p - 4 - el) < 0) return NULL; ++ ++ s2n(TLSEXT_TYPE_renegotiate,ret); ++ s2n(el,ret); ++ ++ if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) ++ { ++ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); ++ return NULL; ++ } ++ ++ ret += el; ++ } ++ ++ if ((extdatalen = ret-p-2)== 0) ++ return p; ++ ++ s2n(extdatalen,p); ++ return ret; ++ } ++ ++unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) ++ { ++ int extdatalen=0; ++ unsigned char *ret = p; ++ ++ /* don't add extensions for SSLv3, unless doing secure renegotiation */ ++ if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) ++ return p; ++ ++ ret+=2; ++ if (ret>=limit) return NULL; /* this really never occurs, but ... */ ++ ++ if(s->s3->send_connection_binding) ++ { ++ int el; ++ ++ if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) ++ { ++ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); ++ return NULL; ++ } ++ ++ if((limit - p - 4 - el) < 0) return NULL; ++ ++ s2n(TLSEXT_TYPE_renegotiate,ret); ++ s2n(el,ret); ++ ++ if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) ++ { ++ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); ++ return NULL; ++ } ++ ++ ret += el; ++ } ++ ++ if ((extdatalen = ret-p-2)== 0) ++ return p; ++ ++ s2n(extdatalen,p); ++ return ret; ++ } ++ ++int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) ++ { ++ unsigned short type; ++ unsigned short size; ++ unsigned short len; ++ unsigned char *data = *p; ++ int renegotiate_seen = 0; ++ ++ if (data >= (d+n-2)) ++ goto ri_check; ++ ++ n2s(data,len); ++ ++ if (data > (d+n-len)) ++ goto ri_check; ++ ++ while (data <= (d+n-4)) ++ { ++ n2s(data,type); ++ n2s(data,size); ++ ++ if (data+size > (d+n)) ++ goto ri_check; ++ ++ if (type == TLSEXT_TYPE_renegotiate) ++ { ++ if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) ++ return 0; ++ renegotiate_seen = 1; ++ } ++ ++ data+=size; ++ } ++ *p = data; ++ ++ ri_check: ++ ++ /* Need RI if renegotiating */ ++ ++ if (!renegotiate_seen && s->new_session && ++ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) ++ { ++ *al = SSL_AD_HANDSHAKE_FAILURE; ++ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, ++ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); ++ return 0; ++ } ++ ++ return 1; ++ } ++ ++int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) ++ { ++ unsigned short type; ++ unsigned short size; ++ unsigned short len; ++ unsigned char *data = *p; ++ int renegotiate_seen = 0; ++ ++ if (data >= (d+n-2)) ++ goto ri_check; ++ ++ n2s(data,len); ++ ++ while(data <= (d+n-4)) ++ { ++ n2s(data,type); ++ n2s(data,size); ++ ++ if (data+size > (d+n)) ++ goto ri_check; ++ if (type == TLSEXT_TYPE_renegotiate) ++ { ++ if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) ++ return 0; ++ renegotiate_seen = 1; ++ } ++ data+=size; ++ } ++ ++ if (data != d+n) ++ { ++ *al = SSL_AD_DECODE_ERROR; ++ return 0; ++ } ++ ++ *p = data; ++ ++ ri_check: ++ ++ /* Determine if we need to see RI. Strictly speaking if we want to ++ * avoid an attack we should *always* see RI even on initial server ++ * hello because the client doesn't see any renegotiation during an ++ * attack. However this would mean we could not connect to any server ++ * which doesn't support RI so for the immediate future tolerate RI ++ * absence on initial connect only. ++ */ ++ if (!renegotiate_seen ++ && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) ++ && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) ++ { ++ *al = SSL_AD_HANDSHAKE_FAILURE; ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, ++ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); ++ return 0; ++ } ++ ++ return 1; ++ } +diff -up openssl-fips-0.9.8e/ssl/t1_reneg.c.reneg openssl-fips-0.9.8e/ssl/t1_reneg.c +--- openssl-fips-0.9.8e/ssl/t1_reneg.c.reneg 2010-02-18 15:58:31.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/t1_reneg.c 2010-02-18 15:58:31.000000000 +0100 +@@ -0,0 +1,292 @@ ++/* ssl/t1_reneg.c */ ++/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * 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: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * 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 ++ * 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 ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * 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.] ++ */ ++/* ==================================================================== ++ * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++#include ++#include ++#include "ssl_locl.h" ++ ++/* Add the client's renegotiation binding */ ++int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, ++ int maxlen) ++ { ++ if(p) ++ { ++ if((s->s3->previous_client_finished_len+1) > maxlen) ++ { ++ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG); ++ return 0; ++ } ++ ++ /* Length byte */ ++ *p = s->s3->previous_client_finished_len; ++ p++; ++ ++ memcpy(p, s->s3->previous_client_finished, ++ s->s3->previous_client_finished_len); ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "%s RI extension sent by client\n", ++ s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); ++#endif ++ } ++ ++ *len=s->s3->previous_client_finished_len + 1; ++ ++ ++ return 1; ++ } ++ ++/* Parse the client's renegotiation binding and abort if it's not ++ right */ ++int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, ++ int *al) ++ { ++ int ilen; ++ ++ /* Parse the length byte */ ++ if(len < 1) ++ { ++ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); ++ *al=SSL_AD_ILLEGAL_PARAMETER; ++ return 0; ++ } ++ ilen = *d; ++ d++; ++ ++ /* Consistency check */ ++ if((ilen+1) != len) ++ { ++ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); ++ *al=SSL_AD_ILLEGAL_PARAMETER; ++ return 0; ++ } ++ ++ /* Check that the extension matches */ ++ if(ilen != s->s3->previous_client_finished_len) ++ { ++ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); ++ *al=SSL_AD_HANDSHAKE_FAILURE; ++ return 0; ++ } ++ ++ if(memcmp(d, s->s3->previous_client_finished, ++ s->s3->previous_client_finished_len)) ++ { ++ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); ++ *al=SSL_AD_HANDSHAKE_FAILURE; ++ return 0; ++ } ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "%s RI extension received by server\n", ++ ilen ? "Non-empty" : "Empty"); ++#endif ++ ++ s->s3->send_connection_binding=1; ++ ++ return 1; ++ } ++ ++/* Add the server's renegotiation binding */ ++int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, ++ int maxlen) ++ { ++ if(p) ++ { ++ if((s->s3->previous_client_finished_len + ++ s->s3->previous_server_finished_len + 1) > maxlen) ++ { ++ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATE_EXT_TOO_LONG); ++ return 0; ++ } ++ ++ /* Length byte */ ++ *p = s->s3->previous_client_finished_len + s->s3->previous_server_finished_len; ++ p++; ++ ++ memcpy(p, s->s3->previous_client_finished, ++ s->s3->previous_client_finished_len); ++ p += s->s3->previous_client_finished_len; ++ ++ memcpy(p, s->s3->previous_server_finished, ++ s->s3->previous_server_finished_len); ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "%s RI extension sent by server\n", ++ s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); ++#endif ++ } ++ ++ *len=s->s3->previous_client_finished_len ++ + s->s3->previous_server_finished_len + 1; ++ ++ return 1; ++ } ++ ++/* Parse the server's renegotiation binding and abort if it's not ++ right */ ++int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, ++ int *al) ++ { ++ int expected_len=s->s3->previous_client_finished_len ++ + s->s3->previous_server_finished_len; ++ int ilen; ++ ++ /* Check for logic errors */ ++ OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); ++ OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); ++ ++ /* Parse the length byte */ ++ if(len < 1) ++ { ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); ++ *al=SSL_AD_ILLEGAL_PARAMETER; ++ return 0; ++ } ++ ilen = *d; ++ d++; ++ ++ /* Consistency check */ ++ if(ilen+1 != len) ++ { ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_ENCODING_ERR); ++ *al=SSL_AD_ILLEGAL_PARAMETER; ++ return 0; ++ } ++ ++ /* Check that the extension matches */ ++ if(ilen != expected_len) ++ { ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); ++ *al=SSL_AD_HANDSHAKE_FAILURE; ++ return 0; ++ } ++ ++ if(memcmp(d, s->s3->previous_client_finished, ++ s->s3->previous_client_finished_len)) ++ { ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); ++ *al=SSL_AD_HANDSHAKE_FAILURE; ++ return 0; ++ } ++ d += s->s3->previous_client_finished_len; ++ ++ if(memcmp(d, s->s3->previous_server_finished, ++ s->s3->previous_server_finished_len)) ++ { ++ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH); ++ *al=SSL_AD_ILLEGAL_PARAMETER; ++ return 0; ++ } ++#ifdef OPENSSL_RI_DEBUG ++ fprintf(stderr, "%s RI extension received by client\n", ++ ilen ? "Non-empty" : "Empty"); ++#endif ++ s->s3->send_connection_binding=1; ++ ++ return 1; ++ } diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2009-4355.patch b/SOURCES/openssl-fips-0.9.8e-cve-2009-4355.patch new file mode 100644 index 0000000..41537e9 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2009-4355.patch @@ -0,0 +1,48 @@ +Modify compression code so it frees up structures without using the +ex_data callbacks. This works around a problem where some applications +call CRYPTO_free_all_ex_data() before application exit (e.g. when +restarting) then use compression (e.g. SSL with compression) later. +This results in significant per-connection memory leaks and +has caused some security issues including CVE-2008-1678 and +CVE-2009-4355. [Steve Henson] +diff -up openssl-fips-0.9.8e/crypto/comp/c_zlib.c.compleak openssl-fips-0.9.8e/crypto/comp/c_zlib.c +--- openssl-fips-0.9.8e/crypto/comp/c_zlib.c.compleak 2007-02-14 22:50:26.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/comp/c_zlib.c 2010-01-14 09:32:46.000000000 +0100 +@@ -133,15 +133,6 @@ struct zlib_state + + static int zlib_stateful_ex_idx = -1; + +-static void zlib_stateful_free_ex_data(void *obj, void *item, +- CRYPTO_EX_DATA *ad, int ind,long argl, void *argp) +- { +- struct zlib_state *state = (struct zlib_state *)item; +- inflateEnd(&state->istream); +- deflateEnd(&state->ostream); +- OPENSSL_free(state); +- } +- + static int zlib_stateful_init(COMP_CTX *ctx) + { + int err; +@@ -185,6 +176,12 @@ static int zlib_stateful_init(COMP_CTX * + + static void zlib_stateful_finish(COMP_CTX *ctx) + { ++ struct zlib_state *state = ++ (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, ++ zlib_stateful_ex_idx); ++ inflateEnd(&state->istream); ++ deflateEnd(&state->ostream); ++ OPENSSL_free(state); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data); + } + +@@ -396,7 +393,7 @@ COMP_METHOD *COMP_zlib(void) + if (zlib_stateful_ex_idx == -1) + zlib_stateful_ex_idx = + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, +- 0,NULL,NULL,NULL,zlib_stateful_free_ex_data); ++ 0,NULL,NULL,NULL,NULL); + CRYPTO_w_unlock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + goto err; diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2010-0433.patch b/SOURCES/openssl-fips-0.9.8e-cve-2010-0433.patch new file mode 100644 index 0000000..a91f119 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2010-0433.patch @@ -0,0 +1,12 @@ +diff -up openssl-fips-0.9.8e/ssl/kssl.c.nullprinc openssl-fips-0.9.8e/ssl/kssl.c +--- openssl-fips-0.9.8e/ssl/kssl.c.nullprinc 2010-03-04 11:33:16.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/kssl.c 2010-03-04 11:33:54.000000000 +0100 +@@ -1806,6 +1806,8 @@ kssl_ctx_show(KSSL_CTX *kssl_ctx) + krb5rc = krb5_sname_to_principal(krb5context, NULL, + kssl_ctx->service_name ? kssl_ctx->service_name: KRB5SVC, + KRB5_NT_SRV_HST, &princ); ++ if (krb5rc) ++ goto exit; + + krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, + princ, diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2010-4180.patch b/SOURCES/openssl-fips-0.9.8e-cve-2010-4180.patch new file mode 100644 index 0000000..c331e5b --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2010-4180.patch @@ -0,0 +1,71 @@ +*) Disable code workaround for ancient and obsolete Netscape browsers +and servers: an attacker can use it in a ciphersuite downgrade attack. +Thanks to Martin Rex for discovering this bug. CVE-2010-4180 +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.disable-nsbug openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod.disable-nsbug 2010-12-07 17:45:32.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_options.pod 2010-12-07 17:45:33.000000000 +0100 +@@ -78,18 +78,7 @@ this breaks this server so 16 bytes is t + + =item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + +-ssl3.netscape.com:443, first a connection is established with RC4-MD5. +-If it is then resumed, we end up using DES-CBC3-SHA. It should be +-RC4-MD5 according to 7.6.1.3, 'cipher_suite'. +- +-Netscape-Enterprise/2.01 (https://merchant.netscape.com) has this bug. +-It only really shows up when connecting via SSLv2/v3 then reconnecting +-via SSLv3. The cipher list changes.... +- +-NEW INFORMATION. Try connecting with a cipher list of just +-DES-CBC-SHA:RC4-MD5. For some weird reason, each new connection uses +-RC4-MD5, but a re-connect tries to use DES-CBC-SHA. So netscape, when +-doing a re-connect, always takes the first cipher in the cipher list. ++This option has no effect anymore. + + =item SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG + +diff -up openssl-fips-0.9.8e/ssl/ssl.h.disable-nsbug openssl-fips-0.9.8e/ssl/ssl.h +--- openssl-fips-0.9.8e/ssl/ssl.h.disable-nsbug 2010-12-07 17:45:32.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl.h 2010-12-07 17:45:33.000000000 +0100 +@@ -482,7 +482,7 @@ typedef struct ssl_session_st + #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L + /* Allow initial connection to servers that don't support RI */ + #define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +-#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L /* can break some security expectations */ ++#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L /* no effect anymore */ + #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L + #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L + #define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */ +diff -up openssl-fips-0.9.8e/ssl/s3_clnt.c.disable-nsbug openssl-fips-0.9.8e/ssl/s3_clnt.c +--- openssl-fips-0.9.8e/ssl/s3_clnt.c.disable-nsbug 2010-12-07 17:45:32.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_clnt.c 2010-12-07 17:45:33.000000000 +0100 +@@ -752,8 +752,11 @@ int ssl3_get_server_hello(SSL *s) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) + { ++/* Workaround is now obsolete */ ++#if 0 + if (!(s->options & + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) ++#endif + { + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); +diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.disable-nsbug openssl-fips-0.9.8e/ssl/s3_srvr.c +--- openssl-fips-0.9.8e/ssl/s3_srvr.c.disable-nsbug 2010-12-07 17:46:11.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_srvr.c 2010-12-07 17:46:15.000000000 +0100 +@@ -870,12 +870,14 @@ int ssl3_get_client_hello(SSL *s) + } + if (j == 0) + { ++#if 0 + if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) + { + /* Very bad for multi-threading.... */ + s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0); + } + else ++#endif + { + /* we need to have the cipher in the cipher + * list if we are asked to reuse it */ diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2011-4109.patch b/SOURCES/openssl-fips-0.9.8e-cve-2011-4109.patch new file mode 100644 index 0000000..fd2f8c7 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2011-4109.patch @@ -0,0 +1,59 @@ +diff -up openssl-fips-0.9.8e/CHANGES.doublefree openssl-fips-0.9.8e/CHANGES +diff -up openssl-fips-0.9.8e/crypto/x509v3/pcy_map.c.doublefree openssl-fips-0.9.8e/crypto/x509v3/pcy_map.c +--- openssl-fips-0.9.8e/crypto/x509v3/pcy_map.c.doublefree 2004-03-25 14:45:58.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/x509v3/pcy_map.c 2012-01-16 10:37:18.480935735 +0100 +@@ -70,8 +70,6 @@ static int ref_cmp(const X509_POLICY_REF + + static void policy_map_free(X509_POLICY_REF *map) + { +- if (map->subjectDomainPolicy) +- ASN1_OBJECT_free(map->subjectDomainPolicy); + OPENSSL_free(map); + } + +@@ -95,6 +93,7 @@ int policy_cache_set_mapping(X509 *x, PO + { + POLICY_MAPPING *map; + X509_POLICY_REF *ref = NULL; ++ ASN1_OBJECT *subjectDomainPolicyRef; + X509_POLICY_DATA *data; + X509_POLICY_CACHE *cache = x->policy_cache; + int i; +@@ -153,13 +152,16 @@ int policy_cache_set_mapping(X509 *x, PO + if (!sk_ASN1_OBJECT_push(data->expected_policy_set, + map->subjectDomainPolicy)) + goto bad_mapping; ++ /* map->subjectDomainPolicy will be freed when ++ * cache->data is freed. Set it to NULL to avoid double-free. */ ++ subjectDomainPolicyRef = map->subjectDomainPolicy; ++ map->subjectDomainPolicy = NULL; + + ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); + if (!ref) + goto bad_mapping; + +- ref->subjectDomainPolicy = map->subjectDomainPolicy; +- map->subjectDomainPolicy = NULL; ++ ref->subjectDomainPolicy = subjectDomainPolicyRef; + ref->data = data; + + if (!sk_X509_POLICY_REF_push(cache->maps, ref)) +diff -up openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c.doublefree openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c +--- openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c.doublefree 2006-11-27 14:36:54.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/x509v3/pcy_tree.c 2012-01-16 10:37:18.481935777 +0100 +@@ -610,6 +610,10 @@ int X509_policy_check(X509_POLICY_TREE * + case 2: + return 1; + ++ /* Some internal error */ ++ case -1: ++ return -1; ++ + /* Some internal error */ + case 0: + return 0; +@@ -689,4 +693,3 @@ int X509_policy_check(X509_POLICY_TREE * + return 0; + + } +- diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2011-4576.patch b/SOURCES/openssl-fips-0.9.8e-cve-2011-4576.patch new file mode 100644 index 0000000..ee406c3 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2011-4576.patch @@ -0,0 +1,14 @@ +diff -up openssl-fips-0.9.8e/CHANGES.padding openssl-fips-0.9.8e/CHANGES +diff -up openssl-fips-0.9.8e/ssl/s3_enc.c.padding openssl-fips-0.9.8e/ssl/s3_enc.c +--- openssl-fips-0.9.8e/ssl/s3_enc.c.padding 2007-03-22 01:39:14.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_enc.c 2012-01-16 10:40:02.146294455 +0100 +@@ -480,6 +480,9 @@ int ssl3_enc(SSL *s, int send) + + /* we need to add 'i-1' padding bytes */ + l+=i; ++ /* the last of these zero bytes will be overwritten ++ * with the padding length. */ ++ memset(&rec->input[rec->length], 0, i); + rec->length+=i; + rec->input[l-1]=(i-1); + } diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2011-4619.patch b/SOURCES/openssl-fips-0.9.8e-cve-2011-4619.patch new file mode 100644 index 0000000..be97e8e --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2011-4619.patch @@ -0,0 +1,92 @@ +diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.sgc-dos openssl-fips-0.9.8e/ssl/s3_srvr.c +--- openssl-fips-0.9.8e/ssl/s3_srvr.c.sgc-dos 2012-03-19 17:42:34.490429863 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_srvr.c 2012-03-19 17:44:42.928114348 +0100 +@@ -236,6 +236,7 @@ int ssl3_accept(SSL *s) + } + + s->init_num=0; ++ s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; + + if (s->state != SSL_ST_RENEGOTIATE) + { +@@ -655,6 +656,13 @@ int ssl3_check_client_hello(SSL *s) + s->s3->tmp.reuse_message = 1; + if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) + { ++ /* We only allow the client to restart the handshake once per ++ * negotiation. */ ++ if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) ++ { ++ SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); ++ return -1; ++ } + /* Throw away what we have done so far in the current handshake, + * which will now be aborted. (A full SSL_clear would be too much.) + * I hope that tmp.dh is the only thing that may need to be cleared +@@ -666,6 +674,7 @@ int ssl3_check_client_hello(SSL *s) + s->s3->tmp.dh = NULL; + } + #endif ++ s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE; + return 2; + } + return 1; +diff -up openssl-fips-0.9.8e/ssl/ssl3.h.sgc-dos openssl-fips-0.9.8e/ssl/ssl3.h +--- openssl-fips-0.9.8e/ssl/ssl3.h.sgc-dos 2012-03-19 17:42:34.465429341 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl3.h 2012-03-19 17:42:34.532430741 +0100 +@@ -333,6 +333,17 @@ typedef struct ssl3_buffer_st + #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 + #define SSL3_FLAGS_POP_BUFFER 0x0004 + #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 ++ ++/* SSL3_FLAGS_SGC_RESTART_DONE is set when we ++ * restart a handshake because of MS SGC and so prevents us ++ * from restarting the handshake in a loop. It's reset on a ++ * renegotiation, so effectively limits the client to one restart ++ * per negotiation. This limits the possibility of a DDoS ++ * attack where the client handshakes in a loop using SGC to ++ * restart. Servers which permit renegotiation can still be ++ * effected, but we can't prevent that. ++ */ ++#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 + + typedef struct ssl3_state_st + { +diff -up openssl-fips-0.9.8e/ssl/ssl_err.c.sgc-dos openssl-fips-0.9.8e/ssl/ssl_err.c +--- openssl-fips-0.9.8e/ssl/ssl_err.c.sgc-dos 2012-03-19 17:42:34.462429280 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_err.c 2012-03-19 17:42:34.532430741 +0100 +@@ -134,6 +134,7 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, ++{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, + {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, +@@ -361,6 +362,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) ,"missing tmp rsa pkey"}, + {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"}, ++{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"}, + {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"}, + {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"}, +diff -up openssl-fips-0.9.8e/ssl/ssl.h.sgc-dos openssl-fips-0.9.8e/ssl/ssl.h +--- openssl-fips-0.9.8e/ssl/ssl.h.sgc-dos 2012-03-19 17:42:34.488429820 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl.h 2012-03-19 17:42:34.533430762 +0100 +@@ -1634,6 +1634,7 @@ void ERR_load_SSL_strings(void); + #define SSL_F_SSL3_CALLBACK_CTRL 233 + #define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 + #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 ++#define SSL_F_SSL3_CHECK_CLIENT_HELLO 293 + #define SSL_F_SSL3_CLIENT_HELLO 131 + #define SSL_F_SSL3_CONNECT 132 + #define SSL_F_SSL3_CTRL 213 +@@ -1858,6 +1859,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_MISSING_TMP_RSA_KEY 172 + #define SSL_R_MISSING_TMP_RSA_PKEY 173 + #define SSL_R_MISSING_VERIFY_MESSAGE 174 ++#define SSL_R_MULTIPLE_SGC_RESTARTS 325 + #define SSL_R_NON_SSLV2_INITIAL_PACKET 175 + #define SSL_R_NO_CERTIFICATES_RETURNED 176 + #define SSL_R_NO_CERTIFICATE_ASSIGNED 177 diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2012-0884.patch b/SOURCES/openssl-fips-0.9.8e-cve-2012-0884.patch new file mode 100644 index 0000000..5af6d45 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2012-0884.patch @@ -0,0 +1,128 @@ +Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness +in PKCS7 code. When RSA decryption fails use a random key for +content decryption and always return the same error. +diff -up openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c.pk7-mma openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c +--- openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c.pk7-mma 2007-02-03 10:51:58.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/pkcs7/pk7_doit.c 2012-03-19 17:51:35.879037258 +0100 +@@ -423,6 +423,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + int max; + X509_OBJECT ret; + #endif ++ unsigned char *tkey = NULL; ++ int tkeylen; + int jj; + + if ((etmp=BIO_new(BIO_f_cipher())) == NULL) +@@ -464,36 +466,42 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + + if (pcert == NULL) + { ++ /* Temporary storage in case EVP_PKEY_decrypt ++ * overwrites output buffer on error. ++ */ ++ unsigned char *tmp2; ++ tmp2 = OPENSSL_malloc(jj); ++ if (!tmp2) ++ goto err; ++ jj = -1; ++ /* Always attempt to decrypt all cases to avoid ++ * leaking timing information about a successful ++ * decrypt. ++ */ + for (i=0; ienc_key), + M_ASN1_STRING_length(ri->enc_key), + pkey); +- if (jj > 0) +- break; ++ if (tret > 0) ++ { ++ memcpy(tmp, tmp2, tret); ++ OPENSSL_cleanse(tmp2, tret); ++ jj = tret; ++ } + ERR_clear_error(); +- ri = NULL; +- } +- if (ri == NULL) +- { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- PKCS7_R_NO_RECIPIENT_MATCHES_KEY); +- goto err; + } ++ OPENSSL_free(tmp2); + } + else + { + jj=EVP_PKEY_decrypt(tmp, + M_ASN1_STRING_data(ri->enc_key), + M_ASN1_STRING_length(ri->enc_key), pkey); +- if (jj <= 0) +- { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- ERR_R_EVP_LIB); +- goto err; +- } ++ ERR_clear_error(); + } + + evp_ctx=NULL; +@@ -502,24 +510,49 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + goto err; + if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) + goto err; ++ /* Generate random key to counter MMA */ ++ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); ++ tkey = OPENSSL_malloc(tkeylen); ++ if (!tkey) ++ goto err; ++ if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) ++ goto err; ++ /* If we have no key use random key */ ++ if (jj <= 0) ++ { ++ OPENSSL_free(tmp); ++ jj = tkeylen; ++ tmp = tkey; ++ tkey = NULL; ++ } + +- if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { ++ if (jj != tkeylen) { + /* Some S/MIME clients don't use the same key + * and effective key length. The key length is + * determined by the size of the decrypted RSA key. + */ + if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) + { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); +- goto err; ++ /* As MMA defence use random key instead */ ++ OPENSSL_cleanse(tmp, jj); ++ OPENSSL_free(tmp); ++ jj = tkeylen; ++ tmp = tkey; ++ tkey = NULL; + } + } ++ ERR_clear_error(); + if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) + goto err; + + OPENSSL_cleanse(tmp,jj); + ++ if (tkey) ++ { ++ OPENSSL_cleanse(tkey, tkeylen); ++ OPENSSL_free(tkey); ++ } ++ + if (out == NULL) + out=etmp; + else diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2012-1165.patch b/SOURCES/openssl-fips-0.9.8e-cve-2012-1165.patch new file mode 100644 index 0000000..369ea56 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2012-1165.patch @@ -0,0 +1,24 @@ +diff -up openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c.bad-mime2 openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c +--- openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c.bad-mime2 2012-03-19 17:42:34.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/pkcs7/pk7_mime.c 2012-03-19 18:07:00.357352534 +0100 +@@ -689,9 +689,8 @@ static int mime_hdr_addparam(MIME_HEADER + static int mime_hdr_cmp(const MIME_HEADER * const *a, + const MIME_HEADER * const *b) + { +- if ((*a)->name == NULL || (*b)->name == NULL) +- return (*a)->name - (*b)->name < 0 ? -1 : +- (*a)->name - (*b)->name > 0 ? 1 : 0; ++ if (!(*a)->name || !(*b)->name) ++ return !!(*a)->name - !!(*b)->name; + + return(strcmp((*a)->name, (*b)->name)); + } +@@ -699,6 +698,8 @@ static int mime_hdr_cmp(const MIME_HEADE + static int mime_param_cmp(const MIME_PARAM * const *a, + const MIME_PARAM * const *b) + { ++ if (!(*a)->param_name || !(*b)->param_name) ++ return !!(*a)->param_name - !!(*b)->param_name; + return(strcmp((*a)->param_name, (*b)->param_name)); + } + diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2012-2110.patch b/SOURCES/openssl-fips-0.9.8e-cve-2012-2110.patch new file mode 100644 index 0000000..9e04e48 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2012-2110.patch @@ -0,0 +1,203 @@ +diff -up openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c.biobuf openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c +--- openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c.biobuf 2005-05-09 02:27:32.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c 2012-04-23 15:07:40.813957295 +0200 +@@ -57,6 +57,7 @@ + */ + + #include ++#include + #include "cryptlib.h" + #include + #include +@@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BU + BUF_MEM *b; + unsigned char *p; + int i; +- int ret=-1; + ASN1_const_CTX c; +- int want=HEADER_SIZE; ++ size_t want=HEADER_SIZE; + int eos=0; +-#if defined(__GNUC__) && defined(__ia64) +- /* pathetic compiler bug in all known versions as of Nov. 2002 */ +- long off=0; +-#else +- int off=0; +-#endif +- int len=0; ++ size_t off=0; ++ size_t len=0; + + b=BUF_MEM_new(); + if (b == NULL) +@@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BU + { + want-=(len-off); + +- if (!BUF_MEM_grow_clean(b,len+want)) ++ if (len + want < len || !BUF_MEM_grow_clean(b,len+want)) + { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); + goto err; +@@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BU + goto err; + } + if (i > 0) ++ { ++ if (len+i < len) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); ++ goto err; ++ } + len+=i; ++ } + } + /* else data already loaded */ + +@@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BU + { + /* no data body so go round again */ + eos++; ++ if (eos < 0) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG); ++ goto err; ++ } + want=HEADER_SIZE; + } + else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) +@@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BU + else + { + /* suck in c.slen bytes of data */ +- want=(int)c.slen; ++ want=c.slen; + if (want > (len-off)) + { + want-=(len-off); ++ if (want > INT_MAX /* BIO_read takes an int length */ || ++ len+want < len) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); ++ goto err; ++ } + if (!BUF_MEM_grow_clean(b,len+want)) + { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); +@@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BU + ASN1_R_NOT_ENOUGH_DATA); + goto err; + } ++ /* This can't overflow because ++ * |len+want| didn't overflow. */ + len+=i; +- want -= i; ++ want-=i; + } + } +- off+=(int)c.slen; ++ if (off + c.slen < off) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); ++ goto err; ++ } ++ off+=c.slen; + if (eos <= 0) + { + break; +@@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BU + } + } + ++ if (off > INT_MAX) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); ++ goto err; ++ } ++ + *pb = b; + return off; + err: + if (b != NULL) BUF_MEM_free(b); +- return(ret); ++ return -1; + } +diff -up openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf openssl-fips-0.9.8e/crypto/buffer/buffer.c +--- openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf 2007-03-22 01:37:55.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/buffer/buffer.c 2012-04-23 16:01:56.083684024 +0200 +@@ -60,6 +60,11 @@ + #include "cryptlib.h" + #include + ++/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That ++ * function is applied in several functions in this file and this limit ensures ++ * that the result fits in an int. */ ++#define LIMIT_BEFORE_EXPANSION 0x5ffffffc ++ + BUF_MEM *BUF_MEM_new(void) + { + BUF_MEM *ret; +@@ -94,6 +99,11 @@ int BUF_MEM_grow(BUF_MEM *str, int len) + char *ret; + unsigned int n; + ++ if (len < 0) ++ { ++ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + if (str->length >= len) + { + str->length=len; +@@ -105,6 +115,12 @@ int BUF_MEM_grow(BUF_MEM *str, int len) + str->length=len; + return(len); + } ++ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ ++ if (len > LIMIT_BEFORE_EXPANSION) ++ { ++ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + n=(len+3)/3*4; + if (str->data == NULL) + ret=OPENSSL_malloc(n); +@@ -130,6 +146,11 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int + char *ret; + unsigned int n; + ++ if (len < 0) ++ { ++ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + if (str->length >= len) + { + memset(&str->data[len],0,str->length-len); +@@ -142,6 +163,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int + str->length=len; + return(len); + } ++ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ ++ if (len > LIMIT_BEFORE_EXPANSION) ++ { ++ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + n=(len+3)/3*4; + if (str->data == NULL) + ret=OPENSSL_malloc(n); +diff -up openssl-fips-0.9.8e/crypto/mem.c.biobuf openssl-fips-0.9.8e/crypto/mem.c +--- openssl-fips-0.9.8e/crypto/mem.c.biobuf 2007-03-22 01:37:46.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/mem.c 2012-04-23 15:07:40.814957317 +0200 +@@ -372,6 +372,10 @@ void *CRYPTO_realloc_clean(void *str, in + + if (num <= 0) return NULL; + ++ /* We don't support shrinking the buffer. Note the memcpy that copies ++ * |old_len| bytes to the new buffer, below. */ ++ if (num < old_len) return NULL; ++ + if (realloc_debug_func != NULL) + realloc_debug_func(str, NULL, num, file, line, 0); + ret=malloc_ex_func(num,file,line); diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2012-2333.patch b/SOURCES/openssl-fips-0.9.8e-cve-2012-2333.patch new file mode 100644 index 0000000..2dcb491 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2012-2333.patch @@ -0,0 +1,17 @@ +Sanity check record length before skipping explicit IV in DTLS +to fix DoS attack. +Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic +fuzzing as a service testing platform. +(CVE-2012-2333) +diff -up openssl-fips-0.9.8e/ssl/d1_enc.c.reclen openssl-fips-0.9.8e/ssl/d1_enc.c +--- openssl-fips-0.9.8e/ssl/d1_enc.c.reclen 2006-02-08 20:16:32.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_enc.c 2012-05-15 12:14:25.510013029 +0200 +@@ -252,7 +252,7 @@ int dtls1_enc(SSL *s, int send) + } + /* TLS 1.0 does not bound the number of padding bytes by the block size. + * All of them must have value 'padding_length'. */ +- if (i > (int)rec->length) ++ if (i + bs > (int)rec->length) + { + /* Incorrect padding. SSLerr() and ssl3_alert are done + * by caller: we don't want to reveal whether this is diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2013-0166.patch b/SOURCES/openssl-fips-0.9.8e-cve-2013-0166.patch new file mode 100644 index 0000000..d33b4f4 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2013-0166.patch @@ -0,0 +1,36 @@ +diff -up openssl-fips-0.9.8e/CHANGES.ocsp-dos openssl-fips-0.9.8e/CHANGES +diff -up openssl-fips-0.9.8e/crypto/asn1/a_verify.c.ocsp-dos openssl-fips-0.9.8e/crypto/asn1/a_verify.c +--- openssl-fips-0.9.8e/crypto/asn1/a_verify.c.ocsp-dos 2005-05-09 02:27:32.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/asn1/a_verify.c 2013-02-25 11:34:37.011201995 +0100 +@@ -133,6 +133,12 @@ int ASN1_item_verify(const ASN1_ITEM *it + unsigned char *buf_in=NULL; + int ret= -1,i,inl; + ++ if (!pkey) ++ { ++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); ++ return -1; ++ } ++ + EVP_MD_CTX_init(&ctx); + i=OBJ_obj2nid(a->algorithm); + type=EVP_get_digestbyname(OBJ_nid2sn(i)); +diff -up openssl-fips-0.9.8e/crypto/ocsp/ocsp_vfy.c.ocsp-dos openssl-fips-0.9.8e/crypto/ocsp/ocsp_vfy.c +--- openssl-fips-0.9.8e/crypto/ocsp/ocsp_vfy.c.ocsp-dos 2006-11-13 14:23:05.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/ocsp/ocsp_vfy.c 2013-02-25 11:34:38.363204929 +0100 +@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs + { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); +- ret = OCSP_BASICRESP_verify(bs, skey, 0); +- EVP_PKEY_free(skey); +- if(ret <= 0) ++ if (skey) ++ { ++ ret = OCSP_BASICRESP_verify(bs, skey, 0); ++ EVP_PKEY_free(skey); ++ } ++ if(!skey || ret <= 0) + { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); + goto end; diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2013-0169.patch b/SOURCES/openssl-fips-0.9.8e-cve-2013-0169.patch new file mode 100644 index 0000000..9c82343 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2013-0169.patch @@ -0,0 +1,1753 @@ +diff -up openssl-fips-0.9.8e/crypto/cryptlib.c.lucky13 openssl-fips-0.9.8e/crypto/cryptlib.c +--- openssl-fips-0.9.8e/crypto/cryptlib.c.lucky13 2007-07-26 18:46:54.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/cryptlib.c 2013-02-25 14:56:11.392381859 +0100 +@@ -543,3 +543,16 @@ void OpenSSLDie(const char *file,int lin + } + + void *OPENSSL_stderr(void) { return stderr; } ++ ++int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) ++ { ++ size_t i; ++ const unsigned char *a = in_a; ++ const unsigned char *b = in_b; ++ unsigned char x = 0; ++ ++ for (i = 0; i < len; i++) ++ x |= a[i] ^ b[i]; ++ ++ return x; ++ } +diff -up openssl-fips-0.9.8e/crypto/crypto.h.lucky13 openssl-fips-0.9.8e/crypto/crypto.h +--- openssl-fips-0.9.8e/crypto/crypto.h.lucky13 2013-02-25 14:56:11.049380949 +0100 ++++ openssl-fips-0.9.8e/crypto/crypto.h 2013-02-25 14:56:11.393381862 +0100 +@@ -592,6 +592,13 @@ unsigned long *OPENSSL_ia32cap_loc(void) + + #endif /* def OPENSSL_FIPS */ + ++/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It ++ * takes an amount of time dependent on |len|, but independent of the contents ++ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a ++ * defined order as the return value when a != b is undefined, other than to be ++ * non-zero. */ ++int CRYPTO_memcmp(const void *a, const void *b, size_t len); ++ + /* BEGIN ERROR CODES */ + /* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. +diff -up openssl-fips-0.9.8e/crypto/rsa/rsa_oaep.c.lucky13 openssl-fips-0.9.8e/crypto/rsa/rsa_oaep.c +--- openssl-fips-0.9.8e/crypto/rsa/rsa_oaep.c.lucky13 2007-03-22 01:38:34.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/rsa/rsa_oaep.c 2013-02-25 14:56:11.394381865 +0100 +@@ -136,7 +136,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigne + + EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL); + +- if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) ++ if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) + goto decoding_err; + else + { +diff -up openssl-fips-0.9.8e/ssl/d1_enc.c.lucky13 openssl-fips-0.9.8e/ssl/d1_enc.c +--- openssl-fips-0.9.8e/ssl/d1_enc.c.lucky13 2013-02-25 14:56:11.374381809 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_enc.c 2013-02-25 14:56:11.395381868 +0100 +@@ -122,18 +122,30 @@ + #include + + ++/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, ++ * an internal error occured. */ + int dtls1_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i,ii,j,k,n=0; ++ int bs,i,j,k,mac_size=0; + const EVP_CIPHER *enc; + + if (send) + { +- if (s->write_hash != NULL) +- n=EVP_MD_size(s->write_hash); ++ if (s->write_hash) ++ { ++ mac_size=EVP_MD_size(s->write_hash); ++ if (mac_size < 0) ++ return -1; ++ } + ds=s->enc_write_ctx; + rec= &(s->s3->wrec); + if (s->enc_write_ctx == NULL) +@@ -147,15 +159,18 @@ int dtls1_enc(SSL *s, int send) + __FILE__, __LINE__); + else if ( EVP_CIPHER_block_size(ds->cipher) > 1) + { +- if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))) ++ if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) <= 0) + return -1; + } + } + } + else + { +- if (s->read_hash != NULL) +- n=EVP_MD_size(s->read_hash); ++ if (s->read_hash) ++ { ++ mac_size=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(mac_size >= 0); ++ } + ds=s->enc_read_ctx; + rec= &(s->s3->rrec); + if (s->enc_read_ctx == NULL) +@@ -219,11 +234,7 @@ int dtls1_enc(SSL *s, int send) + if (!send) + { + if (l == 0 || l%bs != 0) +- { +- SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); +- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; +- } + } + + EVP_Cipher(ds,rec->data,rec->input,l); +@@ -238,43 +249,7 @@ int dtls1_enc(SSL *s, int send) + #endif /* KSSL_DEBUG */ + + if ((bs != 1) && !send) +- { +- ii=i=rec->data[l-1]; /* padding_length */ +- i++; +- if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) +- { +- /* First packet is even in size, so check */ +- if ((memcmp(s->s3->read_sequence, +- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) +- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; +- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) +- i--; +- } +- /* TLS 1.0 does not bound the number of padding bytes by the block size. +- * All of them must have value 'padding_length'. */ +- if (i + bs > (int)rec->length) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) +- */ +- return -1; +- } +- for (j=(int)(l-i); j<(int)l; j++) +- { +- if (rec->data[j] != ii) +- { +- /* Incorrect padding */ +- return -1; +- } +- } +- rec->length-=i; +- +- rec->data += bs; /* skip the implicit IV */ +- rec->input += bs; +- rec->length -= bs; +- } ++ return tls1_cbc_remove_padding(s, rec, bs, mac_size); + } + return(1); + } +diff -up openssl-fips-0.9.8e/ssl/d1_pkt.c.lucky13 openssl-fips-0.9.8e/ssl/d1_pkt.c +--- openssl-fips-0.9.8e/ssl/d1_pkt.c.lucky13 2013-02-25 14:56:11.278381571 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_pkt.c 2013-02-25 14:56:11.400381882 +0100 +@@ -328,16 +328,12 @@ dtls1_get_buffered_record(SSL *s) + static int + dtls1_process_record(SSL *s) + { +- int al; +- int clear=0; +- int enc_err; ++ int i,al; ++ int enc_err; + SSL_SESSION *sess; +- SSL3_RECORD *rr; +- unsigned int mac_size; ++ SSL3_RECORD *rr; ++ unsigned int mac_size, orig_len; + unsigned char md[EVP_MAX_MD_SIZE]; +- int decryption_failed_or_bad_record_mac = 0; +- unsigned char *mac = NULL; +- + + rr= &(s->s3->rrec); + sess = s->session; +@@ -369,12 +365,16 @@ dtls1_process_record(SSL *s) + rr->data=rr->input; + + enc_err = s->method->ssl3_enc->enc(s,0); +- if (enc_err <= 0) ++ /* enc_err is: ++ * 0: (in non-constant time) if the record is publically invalid. ++ * 1: if the padding is valid ++ * -1: if the padding is invalid */ ++ if (enc_err == 0) + { +- /* To minimize information leaked via timing, we will always +- * perform all computations before discarding the message. +- */ +- decryption_failed_or_bad_record_mac = 1; ++ /* For DTLS we simply ignore bad packets. */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto err; + } + + #ifdef TLS_DEBUG +@@ -384,41 +384,62 @@ printf("\n"); + #endif + + /* r->length is now the compressed data plus mac */ +-if ( (sess == NULL) || +- (s->enc_read_ctx == NULL) || +- (s->read_hash == NULL)) +- clear=1; +- +- if (!clear) ++ if ((sess != NULL) && ++ (s->enc_read_ctx != NULL) && ++ (s->read_hash != NULL)) + { ++ /* s->read_hash != NULL => mac_size != -1 */ ++ unsigned char *mac = NULL; ++ unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + +- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) ++ /* kludge: *_cbc_remove_padding passes padding length in rr->type */ ++ orig_len = rr->length+((unsigned int)rr->type>>8); ++ ++ /* orig_len is the length of the record before any padding was ++ * removed. This is public information, as is the MAC in use, ++ * therefore we can safely process the record in a different ++ * amount of time if it's too short to possibly contain a MAC. ++ */ ++ if (orig_len < mac_size || ++ /* CBC records must have a padding length byte too. */ ++ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ orig_len < mac_size+1)) + { +-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ +- al=SSL_AD_RECORD_OVERFLOW; +- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); ++ al=SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); + goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +-#endif + } +- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ +- if (rr->length >= mac_size) ++ ++ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) + { ++ /* We update the length so that the TLS header bytes ++ * can be constructed correctly but we need to extract ++ * the MAC in constant time from within the record, ++ * without leaking the contents of the padding bytes. ++ * */ ++ mac = mac_tmp; ++ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; +- mac = &rr->data[rr->length]; + } + else +- rr->length = 0; +- s->method->ssl3_enc->mac(s,md,0); +- if (mac == NULL || memcmp(md, mac, mac_size) != 0) + { +- decryption_failed_or_bad_record_mac = 1; ++ /* In this case there's no padding, so |orig_len| ++ * equals |rec->length| and we checked that there's ++ * enough bytes for |mac_size| above. */ ++ rr->length -= mac_size; ++ mac = &rr->data[rr->length]; + } ++ ++ i=s->method->ssl3_enc->mac(s,md,0 /* not send */); ++ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) ++ enc_err = -1; ++ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) ++ enc_err = -1; + } + +- if (decryption_failed_or_bad_record_mac) ++ if (enc_err < 0) + { + /* decryption failed, silently discard message */ + rr->length = 0; +diff -up openssl-fips-0.9.8e/ssl/Makefile.lucky13 openssl-fips-0.9.8e/ssl/Makefile +--- openssl-fips-0.9.8e/ssl/Makefile.lucky13 2013-02-25 14:56:11.212381386 +0100 ++++ openssl-fips-0.9.8e/ssl/Makefile 2013-02-25 14:56:11.404381893 +0100 +@@ -22,7 +22,7 @@ LIB=$(TOP)/libssl.a + SHARED_LIB= libssl$(SHLIB_EXT) + LIBSRC= \ + s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ +- s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ ++ s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \ + s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ + t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ + d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ +@@ -33,7 +33,7 @@ LIBSRC= \ + bio_ssl.c ssl_err.c kssl.c t1_reneg.c + LIBOBJ= \ + s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ +- s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ ++ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \ + s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ + t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ + d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ +diff -up openssl-fips-0.9.8e/ssl/s2_clnt.c.lucky13 openssl-fips-0.9.8e/ssl/s2_clnt.c +--- openssl-fips-0.9.8e/ssl/s2_clnt.c.lucky13 2013-02-25 14:56:11.097381084 +0100 ++++ openssl-fips-0.9.8e/ssl/s2_clnt.c 2013-02-25 14:56:11.404381893 +0100 +@@ -935,7 +935,7 @@ static int get_server_verify(SSL *s) + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ + p += 1; + +- if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) ++ if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) + { + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); +diff -up openssl-fips-0.9.8e/ssl/s2_pkt.c.lucky13 openssl-fips-0.9.8e/ssl/s2_pkt.c +--- openssl-fips-0.9.8e/ssl/s2_pkt.c.lucky13 2003-12-27 17:10:30.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s2_pkt.c 2013-02-25 14:56:11.405381896 +0100 +@@ -267,8 +267,7 @@ static int ssl2_read_internal(SSL *s, vo + s->s2->ract_data_length-=mac_size; + ssl2_mac(s,mac,0); + s->s2->ract_data_length-=s->s2->padding; +- if ( (memcmp(mac,s->s2->mac_data, +- (unsigned int)mac_size) != 0) || ++ if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) || + (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) + { + SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); +diff -up openssl-fips-0.9.8e/ssl/s3_both.c.lucky13 openssl-fips-0.9.8e/ssl/s3_both.c +--- openssl-fips-0.9.8e/ssl/s3_both.c.lucky13 2013-02-25 14:56:11.221381411 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_both.c 2013-02-25 14:56:11.406381899 +0100 +@@ -242,7 +242,7 @@ int ssl3_get_finished(SSL *s, int a, int + goto f_err; + } + +- if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) ++ if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) + { + al=SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); +diff -up openssl-fips-0.9.8e/ssl/s3_cbc.c.lucky13 openssl-fips-0.9.8e/ssl/s3_cbc.c +--- openssl-fips-0.9.8e/ssl/s3_cbc.c.lucky13 2013-02-25 14:56:11.407381902 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_cbc.c 2013-02-25 14:56:11.407381902 +0100 +@@ -0,0 +1,783 @@ ++/* ssl/s3_cbc.c */ ++/* ==================================================================== ++ * Copyright (c) 2012 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include "ssl_locl.h" ++ ++#include ++#include ++ ++/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length ++ * field. (SHA-384/512 have 128-bit length.) */ ++#define MAX_HASH_BIT_COUNT_BYTES 16 ++ ++/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. ++ * Currently SHA-384/512 has a 128-byte block size and that's the largest ++ * supported by TLS.) */ ++#define MAX_HASH_BLOCK_SIZE 128 ++ ++/* Some utility functions are needed: ++ * ++ * These macros return the given value with the MSB copied to all the other ++ * bits. They use the fact that arithmetic shift shifts-in the sign bit. ++ * However, this is not ensured by the C standard so you may need to replace ++ * them with something else on odd CPUs. */ ++#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) ++#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) ++ ++/* constant_time_lt returns 0xff if a=b and 0x00 otherwise. */ ++static unsigned constant_time_ge(unsigned a, unsigned b) ++ { ++ a -= b; ++ return DUPLICATE_MSB_TO_ALL(~a); ++ } ++ ++/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */ ++static unsigned char constant_time_eq_8(unsigned a, unsigned b) ++ { ++ unsigned c = a ^ b; ++ c--; ++ return DUPLICATE_MSB_TO_ALL_8(c); ++ } ++ ++/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC ++ * record in |rec| by updating |rec->length| in constant time. ++ * ++ * block_size: the block size of the cipher used to encrypt the record. ++ * returns: ++ * 0: (in non-constant time) if the record is publicly invalid. ++ * 1: if the padding was valid ++ * -1: otherwise. */ ++int ssl3_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size) ++ { ++ unsigned padding_length, good; ++ const unsigned overhead = 1 /* padding length byte */ + mac_size; ++ ++ /* These lengths are all public so we can test them in non-constant ++ * time. */ ++ if (overhead > rec->length) ++ return 0; ++ ++ padding_length = rec->data[rec->length-1]; ++ good = constant_time_ge(rec->length, padding_length+overhead); ++ /* SSLv3 requires that the padding is minimal. */ ++ good &= constant_time_ge(block_size, padding_length+1); ++ padding_length = good & (padding_length+1); ++ rec->length -= padding_length; ++ rec->type |= padding_length<<8; /* kludge: pass padding length */ ++ return (int)((good & 1) | (~good & -1)); ++} ++ ++/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC ++ * record in |rec| in constant time and returns 1 if the padding is valid and ++ * -1 otherwise. It also removes any explicit IV from the start of the record ++ * without leaking any timing about whether there was enough space after the ++ * padding was removed. ++ * ++ * block_size: the block size of the cipher used to encrypt the record. ++ * returns: ++ * 0: (in non-constant time) if the record is publicly invalid. ++ * 1: if the padding was valid ++ * -1: otherwise. */ ++int tls1_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size) ++ { ++ unsigned padding_length, good, to_check, i; ++ const unsigned overhead = 1 /* padding length byte */ + mac_size; ++ /* Check if version requires explicit IV */ ++ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) ++ { ++ /* These lengths are all public so we can test them in ++ * non-constant time. ++ */ ++ if (overhead + block_size > rec->length) ++ return 0; ++ /* We can now safely skip explicit IV */ ++ rec->data += block_size; ++ rec->input += block_size; ++ rec->length -= block_size; ++ } ++ else if (overhead > rec->length) ++ return 0; ++ ++ padding_length = rec->data[rec->length-1]; ++ ++ /* NB: if compression is in operation the first packet may not be of ++ * even length so the padding bug check cannot be performed. This bug ++ * workaround has been around since SSLeay so hopefully it is either ++ * fixed now or no buggy implementation supports compression [steve] ++ */ ++ if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) ++ { ++ /* First packet is even in size, so check */ ++ if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && ++ !(padding_length & 1)) ++ { ++ s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; ++ } ++ if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && ++ padding_length > 0) ++ { ++ padding_length--; ++ } ++ } ++ ++ good = constant_time_ge(rec->length, overhead+padding_length); ++ /* The padding consists of a length byte at the end of the record and ++ * then that many bytes of padding, all with the same value as the ++ * length byte. Thus, with the length byte included, there are i+1 ++ * bytes of padding. ++ * ++ * We can't check just |padding_length+1| bytes because that leaks ++ * decrypted information. Therefore we always have to check the maximum ++ * amount of padding possible. (Again, the length of the record is ++ * public information so we can use it.) */ ++ to_check = 255; /* maximum amount of padding. */ ++ if (to_check > rec->length-1) ++ to_check = rec->length-1; ++ ++ for (i = 0; i < to_check; i++) ++ { ++ unsigned char mask = constant_time_ge(padding_length, i); ++ unsigned char b = rec->data[rec->length-1-i]; ++ /* The final |padding_length+1| bytes should all have the value ++ * |padding_length|. Therefore the XOR should be zero. */ ++ good &= ~(mask&(padding_length ^ b)); ++ } ++ ++ /* If any of the final |padding_length+1| bytes had the wrong value, ++ * one or more of the lower eight bits of |good| will be cleared. We ++ * AND the bottom 8 bits together and duplicate the result to all the ++ * bits. */ ++ good &= good >> 4; ++ good &= good >> 2; ++ good &= good >> 1; ++ good <<= sizeof(good)*8-1; ++ good = DUPLICATE_MSB_TO_ALL(good); ++ ++ padding_length = good & (padding_length+1); ++ rec->length -= padding_length; ++ rec->type |= padding_length<<8; /* kludge: pass padding length */ ++ ++ return (int)((good & 1) | (~good & -1)); ++ } ++ ++/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in ++ * constant time (independent of the concrete value of rec->length, which may ++ * vary within a 256-byte window). ++ * ++ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to ++ * this function. ++ * ++ * On entry: ++ * rec->orig_len >= md_size ++ * md_size <= EVP_MAX_MD_SIZE ++ * ++ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with ++ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into ++ * a single or pair of cache-lines, then the variable memory accesses don't ++ * actually affect the timing. CPUs with smaller cache-lines [if any] are ++ * not multi-core and are not considered vulnerable to cache-timing attacks. ++ */ ++#define CBC_MAC_ROTATE_IN_PLACE ++ ++void ssl3_cbc_copy_mac(unsigned char* out, ++ const SSL3_RECORD *rec, ++ unsigned md_size,unsigned orig_len) ++ { ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE]; ++ unsigned char *rotated_mac; ++#else ++ unsigned char rotated_mac[EVP_MAX_MD_SIZE]; ++#endif ++ ++ /* mac_end is the index of |rec->data| just after the end of the MAC. */ ++ unsigned mac_end = rec->length; ++ unsigned mac_start = mac_end - md_size; ++ /* scan_start contains the number of bytes that we can ignore because ++ * the MAC's position can only vary by 255 bytes. */ ++ unsigned scan_start = 0; ++ unsigned i, j; ++ unsigned div_spoiler; ++ unsigned rotate_offset; ++ ++ OPENSSL_assert(orig_len >= md_size); ++ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); ++ ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63); ++#endif ++ ++ /* This information is public so it's safe to branch based on it. */ ++ if (orig_len > md_size + 255 + 1) ++ scan_start = orig_len - (md_size + 255 + 1); ++ /* div_spoiler contains a multiple of md_size that is used to cause the ++ * modulo operation to be constant time. Without this, the time varies ++ * based on the amount of padding when running on Intel chips at least. ++ * ++ * The aim of right-shifting md_size is so that the compiler doesn't ++ * figure out that it can remove div_spoiler as that would require it ++ * to prove that md_size is always even, which I hope is beyond it. */ ++ div_spoiler = md_size >> 1; ++ div_spoiler <<= (sizeof(div_spoiler)-1)*8; ++ rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; ++ ++ memset(rotated_mac, 0, md_size); ++ for (i = scan_start, j = 0; i < orig_len; i++) ++ { ++ unsigned char mac_started = constant_time_ge(i, mac_start); ++ unsigned char mac_ended = constant_time_ge(i, mac_end); ++ unsigned char b = rec->data[i]; ++ rotated_mac[j++] |= b & mac_started & ~mac_ended; ++ j &= constant_time_lt(j,md_size); ++ } ++ ++ /* Now rotate the MAC */ ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ j = 0; ++ for (i = 0; i < md_size; i++) ++ { ++ /* in case cache-line is 32 bytes, touch second line */ ++ ((volatile unsigned char *)rotated_mac)[rotate_offset^32]; ++ out[j++] = rotated_mac[rotate_offset++]; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ } ++#else ++ memset(out, 0, md_size); ++ rotate_offset = md_size - rotate_offset; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ for (i = 0; i < md_size; i++) ++ { ++ for (j = 0; j < md_size; j++) ++ out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); ++ rotate_offset++; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ } ++#endif ++ } ++ ++/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in ++ * little-endian order. The value of p is advanced by four. */ ++#define u32toLE(n, p) \ ++ (*((p)++)=(unsigned char)(n), \ ++ *((p)++)=(unsigned char)(n>>8), \ ++ *((p)++)=(unsigned char)(n>>16), \ ++ *((p)++)=(unsigned char)(n>>24)) ++ ++/* These functions serialize the state of a hash and thus perform the standard ++ * "final" operation without adding the padding and length that such a function ++ * typically does. */ ++static void tls1_md5_final_raw(void* ctx, unsigned char *md_out) ++ { ++ MD5_CTX *md5 = ctx; ++ u32toLE(md5->A, md_out); ++ u32toLE(md5->B, md_out); ++ u32toLE(md5->C, md_out); ++ u32toLE(md5->D, md_out); ++ } ++ ++static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA_CTX *sha1 = ctx; ++ l2n(sha1->h0, md_out); ++ l2n(sha1->h1, md_out); ++ l2n(sha1->h2, md_out); ++ l2n(sha1->h3, md_out); ++ l2n(sha1->h4, md_out); ++ } ++#define LARGEST_DIGEST_CTX SHA_CTX ++ ++#ifndef OPENSSL_NO_SHA256 ++static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA256_CTX *sha256 = ctx; ++ unsigned i; ++ ++ for (i = 0; i < 8; i++) ++ { ++ l2n(sha256->h[i], md_out); ++ } ++ } ++#undef LARGEST_DIGEST_CTX ++#define LARGEST_DIGEST_CTX SHA256_CTX ++#endif ++ ++#ifndef OPENSSL_NO_SHA512 ++static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA512_CTX *sha512 = ctx; ++ unsigned i; ++ ++ for (i = 0; i < 8; i++) ++ { ++ l2n8(sha512->h[i], md_out); ++ } ++ } ++#undef LARGEST_DIGEST_CTX ++#define LARGEST_DIGEST_CTX SHA512_CTX ++#endif ++ ++/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function ++ * which ssl3_cbc_digest_record supports. */ ++char ssl3_cbc_record_digest_supported(const EVP_MD *digest) ++ { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) ++ return 0; ++#endif ++ switch (EVP_MD_type(digest)) ++ { ++ case NID_md5: ++ case NID_sha1: ++#ifndef OPENSSL_NO_SHA256 ++ case NID_sha224: ++ case NID_sha256: ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ case NID_sha384: ++ case NID_sha512: ++#endif ++ return 1; ++ default: ++ return 0; ++ } ++ } ++ ++/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS ++ * record. ++ * ++ * ctx: the EVP_MD_CTX from which we take the hash function. ++ * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. ++ * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. ++ * md_out_size: if non-NULL, the number of output bytes is written here. ++ * header: the 13-byte, TLS record header. ++ * data: the record data itself, less any preceeding explicit IV. ++ * data_plus_mac_size: the secret, reported length of the data and MAC ++ * once the padding has been removed. ++ * data_plus_mac_plus_padding_size: the public length of the whole ++ * record, including padding. ++ * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. ++ * ++ * On entry: by virtue of having been through one of the remove_padding ++ * functions, above, we know that data_plus_mac_size is large enough to contain ++ * a padding byte and MAC. (If the padding was invalid, it might contain the ++ * padding too. ) */ ++void ssl3_cbc_digest_record( ++ const EVP_MD *digest, ++ unsigned char* md_out, ++ size_t* md_out_size, ++ const unsigned char header[13], ++ const unsigned char *data, ++ size_t data_plus_mac_size, ++ size_t data_plus_mac_plus_padding_size, ++ const unsigned char *mac_secret, ++ unsigned mac_secret_length, ++ char is_sslv3) ++ { ++ union { double align; ++ unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; ++ void (*md_final_raw)(void *ctx, unsigned char *md_out); ++ void (*md_transform)(void *ctx, const unsigned char *block); ++ unsigned md_size, md_block_size = 64; ++ unsigned sslv3_pad_length = 40, header_length, variance_blocks, ++ len, max_mac_bytes, num_blocks, ++ num_starting_blocks, k, mac_end_offset, c, index_a, index_b; ++ unsigned int bits; /* at most 18 bits */ ++ unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; ++ /* hmac_pad is the masked HMAC key. */ ++ unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; ++ unsigned char first_block[MAX_HASH_BLOCK_SIZE]; ++ unsigned char mac_out[EVP_MAX_MD_SIZE]; ++ unsigned i, j, md_out_size_u; ++ EVP_MD_CTX md_ctx; ++ /* mdLengthSize is the number of bytes in the length field that terminates ++ * the hash. */ ++ unsigned md_length_size = 8; ++ char length_is_big_endian = 1; ++ ++ /* This is a, hopefully redundant, check that allows us to forget about ++ * many possible overflows later in this function. */ ++ OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); ++ ++ switch (EVP_MD_type(digest)) ++ { ++ case NID_md5: ++ MD5_Init((MD5_CTX*)md_state.c); ++ md_final_raw = tls1_md5_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; ++ md_size = 16; ++ sslv3_pad_length = 48; ++ length_is_big_endian = 0; ++ break; ++ case NID_sha1: ++ SHA1_Init((SHA_CTX*)md_state.c); ++ md_final_raw = tls1_sha1_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; ++ md_size = 20; ++ break; ++#ifndef OPENSSL_NO_SHA256 ++ case NID_sha224: ++ SHA224_Init((SHA256_CTX*)md_state.c); ++ md_final_raw = tls1_sha256_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; ++ md_size = 224/8; ++ break; ++ case NID_sha256: ++ SHA256_Init((SHA256_CTX*)md_state.c); ++ md_final_raw = tls1_sha256_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; ++ md_size = 32; ++ break; ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ case NID_sha384: ++ SHA384_Init((SHA512_CTX*)md_state.c); ++ md_final_raw = tls1_sha512_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; ++ md_size = 384/8; ++ md_block_size = 128; ++ md_length_size = 16; ++ break; ++ case NID_sha512: ++ SHA512_Init((SHA512_CTX*)md_state.c); ++ md_final_raw = tls1_sha512_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; ++ md_size = 64; ++ md_block_size = 128; ++ md_length_size = 16; ++ break; ++#endif ++ default: ++ /* ssl3_cbc_record_digest_supported should have been ++ * called first to check that the hash function is ++ * supported. */ ++ OPENSSL_assert(0); ++ if (md_out_size) ++ *md_out_size = -1; ++ return; ++ } ++ ++ OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); ++ OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); ++ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); ++ ++ header_length = 13; ++ if (is_sslv3) ++ { ++ header_length = ++ mac_secret_length + ++ sslv3_pad_length + ++ 8 /* sequence number */ + ++ 1 /* record type */ + ++ 2 /* record length */; ++ } ++ ++ /* variance_blocks is the number of blocks of the hash that we have to ++ * calculate in constant time because they could be altered by the ++ * padding value. ++ * ++ * In SSLv3, the padding must be minimal so the end of the plaintext ++ * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that ++ * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash ++ * termination (0x80 + 64-bit length) don't fit in the final block, we ++ * say that the final two blocks can vary based on the padding. ++ * ++ * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not ++ * required to be minimal. Therefore we say that the final six blocks ++ * can vary based on the padding. ++ * ++ * Later in the function, if the message is short and there obviously ++ * cannot be this many blocks then variance_blocks can be reduced. */ ++ variance_blocks = is_sslv3 ? 2 : 6; ++ /* From now on we're dealing with the MAC, which conceptually has 13 ++ * bytes of `header' before the start of the data (TLS) or 71/75 bytes ++ * (SSLv3) */ ++ len = data_plus_mac_plus_padding_size + header_length; ++ /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including ++ * |header|, assuming that there's no padding. */ ++ max_mac_bytes = len - md_size - 1; ++ /* num_blocks is the maximum number of hash blocks. */ ++ num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; ++ /* In order to calculate the MAC in constant time we have to handle ++ * the final blocks specially because the padding value could cause the ++ * end to appear somewhere in the final |variance_blocks| blocks and we ++ * can't leak where. However, |num_starting_blocks| worth of data can ++ * be hashed right away because no padding value can affect whether ++ * they are plaintext. */ ++ num_starting_blocks = 0; ++ /* k is the starting byte offset into the conceptual header||data where ++ * we start processing. */ ++ k = 0; ++ /* mac_end_offset is the index just past the end of the data to be ++ * MACed. */ ++ mac_end_offset = data_plus_mac_size + header_length - md_size; ++ /* c is the index of the 0x80 byte in the final hash block that ++ * contains application data. */ ++ c = mac_end_offset % md_block_size; ++ /* index_a is the hash block number that contains the 0x80 terminating ++ * value. */ ++ index_a = mac_end_offset / md_block_size; ++ /* index_b is the hash block number that contains the 64-bit hash ++ * length, in bits. */ ++ index_b = (mac_end_offset + md_length_size) / md_block_size; ++ /* bits is the hash-length in bits. It includes the additional hash ++ * block for the masked HMAC key, or whole of |header| in the case of ++ * SSLv3. */ ++ ++ /* For SSLv3, if we're going to have any starting blocks then we need ++ * at least two because the header is larger than a single block. */ ++ if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) ++ { ++ num_starting_blocks = num_blocks - variance_blocks; ++ k = md_block_size*num_starting_blocks; ++ } ++ ++ bits = 8*mac_end_offset; ++ if (!is_sslv3) ++ { ++ /* Compute the initial HMAC block. For SSLv3, the padding and ++ * secret bytes are included in |header| because they take more ++ * than a single block. */ ++ bits += 8*md_block_size; ++ memset(hmac_pad, 0, md_block_size); ++ OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); ++ memcpy(hmac_pad, mac_secret, mac_secret_length); ++ for (i = 0; i < md_block_size; i++) ++ hmac_pad[i] ^= 0x36; ++ ++ md_transform(md_state.c, hmac_pad); ++ } ++ ++ if (length_is_big_endian) ++ { ++ memset(length_bytes,0,md_length_size-4); ++ length_bytes[md_length_size-4] = (unsigned char)(bits>>24); ++ length_bytes[md_length_size-3] = (unsigned char)(bits>>16); ++ length_bytes[md_length_size-2] = (unsigned char)(bits>>8); ++ length_bytes[md_length_size-1] = (unsigned char)bits; ++ } ++ else ++ { ++ memset(length_bytes,0,md_length_size); ++ length_bytes[md_length_size-5] = (unsigned char)(bits>>24); ++ length_bytes[md_length_size-6] = (unsigned char)(bits>>16); ++ length_bytes[md_length_size-7] = (unsigned char)(bits>>8); ++ length_bytes[md_length_size-8] = (unsigned char)bits; ++ } ++ ++ if (k > 0) ++ { ++ if (is_sslv3) ++ { ++ /* The SSLv3 header is larger than a single block. ++ * overhang is the number of bytes beyond a single ++ * block that the header consumes: either 7 bytes ++ * (SHA1) or 11 bytes (MD5). */ ++ unsigned overhang = header_length-md_block_size; ++ md_transform(md_state.c, header); ++ memcpy(first_block, header + md_block_size, overhang); ++ memcpy(first_block + overhang, data, md_block_size-overhang); ++ md_transform(md_state.c, first_block); ++ for (i = 1; i < k/md_block_size - 1; i++) ++ md_transform(md_state.c, data + md_block_size*i - overhang); ++ } ++ else ++ { ++ /* k is a multiple of md_block_size. */ ++ memcpy(first_block, header, 13); ++ memcpy(first_block+13, data, md_block_size-13); ++ md_transform(md_state.c, first_block); ++ for (i = 1; i < k/md_block_size; i++) ++ md_transform(md_state.c, data + md_block_size*i - 13); ++ } ++ } ++ ++ memset(mac_out, 0, sizeof(mac_out)); ++ ++ /* We now process the final hash blocks. For each block, we construct ++ * it in constant time. If the |i==index_a| then we'll include the 0x80 ++ * bytes and zero pad etc. For each block we selectively copy it, in ++ * constant time, to |mac_out|. */ ++ for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++) ++ { ++ unsigned char block[MAX_HASH_BLOCK_SIZE]; ++ unsigned char is_block_a = constant_time_eq_8(i, index_a); ++ unsigned char is_block_b = constant_time_eq_8(i, index_b); ++ for (j = 0; j < md_block_size; j++) ++ { ++ unsigned char b = 0, is_past_c, is_past_cp1; ++ if (k < header_length) ++ b = header[k]; ++ else if (k < data_plus_mac_plus_padding_size + header_length) ++ b = data[k-header_length]; ++ k++; ++ ++ is_past_c = is_block_a & constant_time_ge(j, c); ++ is_past_cp1 = is_block_a & constant_time_ge(j, c+1); ++ /* If this is the block containing the end of the ++ * application data, and we are at the offset for the ++ * 0x80 value, then overwrite b with 0x80. */ ++ b = (b&~is_past_c) | (0x80&is_past_c); ++ /* If this the the block containing the end of the ++ * application data and we're past the 0x80 value then ++ * just write zero. */ ++ b = b&~is_past_cp1; ++ /* If this is index_b (the final block), but not ++ * index_a (the end of the data), then the 64-bit ++ * length didn't fit into index_a and we're having to ++ * add an extra block of zeros. */ ++ b &= ~is_block_b | is_block_a; ++ ++ /* The final bytes of one of the blocks contains the ++ * length. */ ++ if (j >= md_block_size - md_length_size) ++ { ++ /* If this is index_b, write a length byte. */ ++ b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]); ++ } ++ block[j] = b; ++ } ++ ++ md_transform(md_state.c, block); ++ md_final_raw(md_state.c, block); ++ /* If this is index_b, copy the hash value to |mac_out|. */ ++ for (j = 0; j < md_size; j++) ++ mac_out[j] |= block[j]&is_block_b; ++ } ++ ++ EVP_MD_CTX_init(&md_ctx); ++ EVP_DigestInit_ex(&md_ctx, digest, NULL /* engine */); ++ if (is_sslv3) ++ { ++ /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ ++ memset(hmac_pad, 0x5c, sslv3_pad_length); ++ ++ EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); ++ EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); ++ EVP_DigestUpdate(&md_ctx, mac_out, md_size); ++ } ++ else ++ { ++ /* Complete the HMAC in the standard manner. */ ++ for (i = 0; i < md_block_size; i++) ++ hmac_pad[i] ^= 0x6a; ++ ++ EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); ++ EVP_DigestUpdate(&md_ctx, mac_out, md_size); ++ } ++ EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); ++ if (md_out_size) ++ *md_out_size = md_out_size_u; ++ EVP_MD_CTX_cleanup(&md_ctx); ++ } ++ ++#ifdef OPENSSL_FIPS ++ ++/* Due to the need to use EVP in FIPS mode we can't reimplement digests but ++ * we can ensure the number of blocks processed is equal for all cases ++ * by digesting additional data. ++ */ ++ ++void tls_fips_digest_extra( ++ const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, ++ const unsigned char *data, size_t data_len, size_t orig_len) ++ { ++ size_t block_size, digest_pad, blocks_data, blocks_orig; ++ if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) ++ return; ++ block_size = EVP_MD_block_size(hash); ++ /* We are in FIPS mode if we get this far so we know we have only SHA* ++ * digests and TLS to deal with. ++ * Minimum digest padding length is 17 for SHA384/SHA512 and 9 ++ * otherwise. ++ * Additional header is 13 bytes. To get the number of digest blocks ++ * processed round up the amount of data plus padding to the nearest ++ * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. ++ * So we have: ++ * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size ++ * equivalently: ++ * blocks = (payload_len + digest_pad + 12)/block_size + 1 ++ * HMAC adds a constant overhead. ++ * We're ultimately only interested in differences so this becomes ++ * blocks = (payload_len + 29)/128 ++ * for SHA384/SHA512 and ++ * blocks = (payload_len + 21)/64 ++ * otherwise. ++ */ ++ digest_pad = block_size == 64 ? 21 : 29; ++ blocks_orig = (orig_len + digest_pad)/block_size; ++ blocks_data = (data_len + digest_pad)/block_size; ++ /* MAC enough blocks to make up the difference between the original ++ * and actual lengths plus one extra block to ensure this is never a ++ * no op. The "data" pointer should always have enough space to ++ * perform this operation as it is large enough for a maximum ++ * length TLS buffer. ++ */ ++ HMAC_Update(hctx, data, ++ (blocks_orig - blocks_data + 1) * block_size); ++ } ++#endif +diff -up openssl-fips-0.9.8e/ssl/s3_enc.c.lucky13 openssl-fips-0.9.8e/ssl/s3_enc.c +--- openssl-fips-0.9.8e/ssl/s3_enc.c.lucky13 2013-02-25 14:56:11.285381591 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_enc.c 2013-02-25 14:56:11.407381902 +0100 +@@ -434,12 +434,21 @@ void ssl3_cleanup_key_block(SSL *s) + s->s3->tmp.key_block_length=0; + } + ++/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding is invalid or, if sending, an internal error ++ * occured. ++ */ + int ssl3_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i; ++ int bs,i,mac_size=0; + const EVP_CIPHER *enc; + + if (send) +@@ -490,32 +499,17 @@ int ssl3_enc(SSL *s, int send) + if (!send) + { + if (l == 0 || l%bs != 0) +- { +- SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); +- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; +- } + /* otherwise, rec->length >= bs */ + } + + EVP_Cipher(ds,rec->data,rec->input,l); + ++ if (s->read_hash != NULL) ++ mac_size = EVP_MD_size(s->read_hash); ++ + if ((bs != 1) && !send) +- { +- i=rec->data[l-1]+1; +- /* SSL 3.0 bounds the number of padding bytes by the block size; +- * padding bytes (except the last one) are arbitrary */ +- if (i > bs) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ +- return -1; +- } +- /* now i <= bs <= rec->length */ +- rec->length-=i; +- } ++ return ssl3_cbc_remove_padding(s, rec, bs, mac_size); + } + return(1); + } +@@ -592,7 +586,7 @@ int ssl3_mac(SSL *ssl, unsigned char *md + EVP_MD_CTX md_ctx; + const EVP_MD *hash; + unsigned char *p,rec_char; +- unsigned int md_size; ++ size_t md_size, orig_len; + int npad; + + if (send) +@@ -613,28 +607,72 @@ int ssl3_mac(SSL *ssl, unsigned char *md + md_size=EVP_MD_size(hash); + npad=(48/md_size)*md_size; + +- /* Chop the digest off the end :-) */ +- EVP_MD_CTX_init(&md_ctx); +- +- EVP_DigestInit_ex( &md_ctx,hash, NULL); +- EVP_DigestUpdate(&md_ctx,mac_sec,md_size); +- EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); +- EVP_DigestUpdate(&md_ctx,seq,8); +- rec_char=rec->type; +- EVP_DigestUpdate(&md_ctx,&rec_char,1); +- p=md; +- s2n(rec->length,p); +- EVP_DigestUpdate(&md_ctx,md,2); +- EVP_DigestUpdate(&md_ctx,rec->input,rec->length); +- EVP_DigestFinal_ex( &md_ctx,md,NULL); +- +- EVP_DigestInit_ex( &md_ctx,hash, NULL); +- EVP_DigestUpdate(&md_ctx,mac_sec,md_size); +- EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); +- EVP_DigestUpdate(&md_ctx,md,md_size); +- EVP_DigestFinal_ex( &md_ctx,md,&md_size); ++ /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */ ++ orig_len = rec->length+md_size+((unsigned int)rec->type>>8); ++ rec->type &= 0xff; ++ ++ if (!send && ++ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ ssl3_cbc_record_digest_supported(hash)) ++ { ++ /* This is a CBC-encrypted record. We must avoid leaking any ++ * timing-side channel information about how many blocks of ++ * data we are hashing because that gives an attacker a ++ * timing-oracle. */ ++ ++ /* npad is, at most, 48 bytes and that's with MD5: ++ * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. ++ * ++ * With SHA-1 (the largest hash speced for SSLv3) the hash size ++ * goes up 4, but npad goes down by 8, resulting in a smaller ++ * total size. */ ++ unsigned char header[75]; ++ unsigned j = 0; ++ memcpy(header+j, mac_sec, md_size); ++ j += md_size; ++ memcpy(header+j, ssl3_pad_1, npad); ++ j += npad; ++ memcpy(header+j, seq, 8); ++ j += 8; ++ header[j++] = rec->type; ++ header[j++] = rec->length >> 8; ++ header[j++] = rec->length & 0xff; ++ ++ ssl3_cbc_digest_record( ++ hash, ++ md, &md_size, ++ header, rec->input, ++ rec->length + md_size, orig_len, ++ mac_sec, md_size, ++ 1 /* is SSLv3 */); ++ } ++ else ++ { ++ unsigned int md_size_u; ++ /* Chop the digest off the end :-) */ ++ EVP_MD_CTX_init(&md_ctx); ++ ++ EVP_DigestInit_ex( &md_ctx,hash, NULL); ++ EVP_DigestUpdate(&md_ctx,mac_sec,md_size); ++ EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); ++ EVP_DigestUpdate(&md_ctx,seq,8); ++ rec_char=rec->type; ++ EVP_DigestUpdate(&md_ctx,&rec_char,1); ++ p=md; ++ s2n(rec->length,p); ++ EVP_DigestUpdate(&md_ctx,md,2); ++ EVP_DigestUpdate(&md_ctx,rec->input,rec->length); ++ EVP_DigestFinal_ex( &md_ctx,md,NULL); ++ ++ EVP_DigestInit_ex( &md_ctx,hash, NULL); ++ EVP_DigestUpdate(&md_ctx,mac_sec,md_size); ++ EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); ++ EVP_DigestUpdate(&md_ctx,md,md_size); ++ EVP_DigestFinal_ex( &md_ctx,md,&md_size_u); ++ md_size = md_size_u; + +- EVP_MD_CTX_cleanup(&md_ctx); ++ EVP_MD_CTX_cleanup(&md_ctx); ++ } + + ssl3_record_sequence_update(seq); + return(md_size); +diff -up openssl-fips-0.9.8e/ssl/s3_pkt.c.lucky13 openssl-fips-0.9.8e/ssl/s3_pkt.c +--- openssl-fips-0.9.8e/ssl/s3_pkt.c.lucky13 2013-02-25 14:56:11.225381423 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_pkt.c 2013-02-25 14:56:11.408381905 +0100 +@@ -237,11 +237,8 @@ static int ssl3_get_record(SSL *s) + unsigned char *p; + unsigned char md[EVP_MAX_MD_SIZE]; + short version; +- unsigned int mac_size; +- int clear=0; ++ unsigned mac_size, orig_len; + size_t extra; +- int decryption_failed_or_bad_record_mac = 0; +- unsigned char *mac = NULL; + + rr= &(s->s3->rrec); + sess=s->session; +@@ -347,17 +344,15 @@ again: + rr->data=rr->input; + + enc_err = s->method->ssl3_enc->enc(s,0); +- if (enc_err <= 0) ++ /* enc_err is: ++ * 0: (in non-constant time) if the record is publically invalid. ++ * 1: if the padding is valid ++ * -1: if the padding is invalid */ ++ if (enc_err == 0) + { +- if (enc_err == 0) +- /* SSLerr() and ssl3_send_alert() have been called */ +- goto err; +- +- /* Otherwise enc_err == -1, which indicates bad padding +- * (rec->length has not been changed in this case). +- * To minimize information leaked via timing, we will perform +- * the MAC computation anyway. */ +- decryption_failed_or_bad_record_mac = 1; ++ al=SSL_AD_DECRYPTION_FAILED; ++ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); ++ goto f_err; + } + + #ifdef TLS_DEBUG +@@ -367,51 +362,62 @@ printf("\n"); + #endif + + /* r->length is now the compressed data plus mac */ +- if ( (sess == NULL) || +- (s->enc_read_ctx == NULL) || +- (s->read_hash == NULL)) +- clear=1; +- +- if (!clear) +- { ++ if ((sess != NULL) && ++ (s->enc_read_ctx != NULL) && ++ (s->read_hash != NULL)) ++ { ++ /* s->read_hash != NULL => mac_size != -1 */ ++ unsigned char *mac = NULL; ++ unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + +- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) ++ /* kludge: *_cbc_remove_padding passes padding length in rr->type */ ++ orig_len = rr->length+((unsigned int)rr->type>>8); ++ ++ /* orig_len is the length of the record before any padding was ++ * removed. This is public information, as is the MAC in use, ++ * therefore we can safely process the record in a different ++ * amount of time if it's too short to possibly contain a MAC. ++ */ ++ if (orig_len < mac_size || ++ /* CBC records must have a padding length byte too. */ ++ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ orig_len < mac_size+1)) + { +-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ +- al=SSL_AD_RECORD_OVERFLOW; +- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); ++ al=SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); + goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +-#endif + } +- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ +- if (rr->length >= mac_size) ++ ++ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) + { ++ /* We update the length so that the TLS header bytes ++ * can be constructed correctly but we need to extract ++ * the MAC in constant time from within the record, ++ * without leaking the contents of the padding bytes. ++ * */ ++ mac = mac_tmp; ++ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; +- mac = &rr->data[rr->length]; + } + else + { +- /* record (minus padding) is too short to contain a MAC */ +-#if 0 /* OK only for stream ciphers */ +- al=SSL_AD_DECODE_ERROR; +- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); +- goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +- rr->length = 0; +-#endif +- } +- i=s->method->ssl3_enc->mac(s,md,0); +- if (mac == NULL || memcmp(md, mac, mac_size) != 0) +- { +- decryption_failed_or_bad_record_mac = 1; ++ /* In this case there's no padding, so |orig_len| ++ * equals |rec->length| and we checked that there's ++ * enough bytes for |mac_size| above. */ ++ rr->length -= mac_size; ++ mac = &rr->data[rr->length]; + } ++ ++ i=s->method->ssl3_enc->mac(s,md,0 /* not send */); ++ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) ++ enc_err = -1; ++ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) ++ enc_err = -1; + } + +- if (decryption_failed_or_bad_record_mac) ++ if (enc_err < 0) + { + /* A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption +diff -up openssl-fips-0.9.8e/ssl/ssl_locl.h.lucky13 openssl-fips-0.9.8e/ssl/ssl_locl.h +--- openssl-fips-0.9.8e/ssl/ssl_locl.h.lucky13 2013-02-25 14:56:11.219381406 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_locl.h 2013-02-25 14:57:27.348538698 +0100 +@@ -133,6 +133,7 @@ + #ifndef OPENSSL_NO_DSA + #include + #endif ++#include + #include + #include + #include +@@ -187,6 +188,15 @@ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + ++#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>48)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>40)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>32)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>24)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ ++ *((c)++)=(unsigned char)(((l) )&0xff)) ++ + #define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ + l|=((BN_ULLONG)(*((c)++)))<<32, \ + l|=((BN_ULLONG)(*((c)++)))<<24, \ +@@ -946,5 +956,33 @@ int ssl_add_clienthello_renegotiate_ext( + int maxlen); + int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); ++/* s3_cbc.c */ ++void ssl3_cbc_copy_mac(unsigned char* out, ++ const SSL3_RECORD *rec, ++ unsigned md_size,unsigned orig_len); ++int ssl3_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size); ++int tls1_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size); ++char ssl3_cbc_record_digest_supported(const EVP_MD *hash); ++void ssl3_cbc_digest_record( ++ const EVP_MD *hash, ++ unsigned char* md_out, ++ size_t* md_out_size, ++ const unsigned char header[13], ++ const unsigned char *data, ++ size_t data_plus_mac_size, ++ size_t data_plus_mac_plus_padding_size, ++ const unsigned char *mac_secret, ++ unsigned mac_secret_length, ++ char is_sslv3); ++ ++void tls_fips_digest_extra( ++ const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, ++ const unsigned char *data, size_t data_len, size_t orig_len); + + #endif +diff -up openssl-fips-0.9.8e/ssl/t1_enc.c.lucky13 openssl-fips-0.9.8e/ssl/t1_enc.c +--- openssl-fips-0.9.8e/ssl/t1_enc.c.lucky13 2013-02-25 14:56:11.027380889 +0100 ++++ openssl-fips-0.9.8e/ssl/t1_enc.c 2013-02-25 15:30:15.511540650 +0100 +@@ -523,18 +523,25 @@ err: + return(0); + } + ++/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, ++ * an internal error occured. ++ */ + int tls1_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i,ii,j,k,n=0; ++ int bs,i,j,k,pad=0,ret,mac_size=0; + const EVP_CIPHER *enc; + + if (send) + { +- if (s->write_hash != NULL) +- n=EVP_MD_size(s->write_hash); + ds=s->enc_write_ctx; + rec= &(s->s3->wrec); + if (s->enc_write_ctx == NULL) +@@ -544,8 +551,6 @@ int tls1_enc(SSL *s, int send) + } + else + { +- if (s->read_hash != NULL) +- n=EVP_MD_size(s->read_hash); + ds=s->enc_read_ctx; + rec= &(s->s3->rrec); + if (s->enc_read_ctx == NULL) +@@ -558,11 +563,11 @@ int tls1_enc(SSL *s, int send) + printf("tls1_enc(%d)\n", send); + #endif /* KSSL_DEBUG */ + +- if ((s->session == NULL) || (ds == NULL) || +- (enc == NULL)) ++ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) + { + memmove(rec->data,rec->input,rec->length); + rec->input=rec->data; ++ ret = 1; + } + else + { +@@ -609,11 +614,7 @@ int tls1_enc(SSL *s, int send) + if (!send) + { + if (l == 0 || l%bs != 0) +- { +- SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); +- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; +- } + } + + EVP_Cipher(ds,rec->data,rec->input,l); +@@ -627,49 +628,15 @@ int tls1_enc(SSL *s, int send) + } + #endif /* KSSL_DEBUG */ + ++ ret = 1; ++ if (s->read_hash != NULL) ++ mac_size = EVP_MD_size(s->read_hash); + if ((bs != 1) && !send) +- { +- ii=i=rec->data[l-1]; /* padding_length */ +- i++; +- /* NB: if compression is in operation the first packet +- * may not be of even length so the padding bug check +- * cannot be performed. This bug workaround has been +- * around since SSLeay so hopefully it is either fixed +- * now or no buggy implementation supports compression +- * [steve] +- */ +- if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) +- && !s->expand) +- { +- /* First packet is even in size, so check */ +- if ((memcmp(s->s3->read_sequence, +- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) +- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; +- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) +- i--; +- } +- /* TLS 1.0 does not bound the number of padding bytes by the block size. +- * All of them must have value 'padding_length'. */ +- if (i > (int)rec->length) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ +- return -1; +- } +- for (j=(int)(l-i); j<(int)l; j++) +- { +- if (rec->data[j] != ii) +- { +- /* Incorrect padding */ +- return -1; +- } +- } +- rec->length-=i; +- } ++ ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); ++ if (pad && !send) ++ rec->length -= pad; + } +- return(1); ++ return ret; + } + + int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out) +@@ -717,10 +684,10 @@ int tls1_mac(SSL *ssl, unsigned char *md + SSL3_RECORD *rec; + unsigned char *mac_sec,*seq; + const EVP_MD *hash; +- unsigned int md_size; ++ size_t md_size, orig_len; + int i; + HMAC_CTX hmac; +- unsigned char buf[5]; ++ unsigned char header[13]; + + if (send) + { +@@ -739,20 +706,6 @@ int tls1_mac(SSL *ssl, unsigned char *md + + md_size=EVP_MD_size(hash); + +- buf[0]=rec->type; +- if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) +- { +- buf[1]=TLS1_VERSION_MAJOR; +- buf[2]=TLS1_VERSION_MINOR; +- } +- else { +- buf[1]=(unsigned char)(ssl->version>>8); +- buf[2]=(unsigned char)(ssl->version); +- } +- +- buf[3]=rec->length>>8; +- buf[4]=rec->length&0xff; +- + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + HMAC_CTX_init(&hmac); + HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); +@@ -764,16 +717,57 @@ int tls1_mac(SSL *ssl, unsigned char *md + s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); + memcpy (p,&seq[2],6); + +- HMAC_Update(&hmac,dtlsseq,8); ++ memcpy(header, dtlsseq, 8); + } + else +- HMAC_Update(&hmac,seq,8); ++ memcpy(header, seq, 8); + +- HMAC_Update(&hmac,buf,5); +- HMAC_Update(&hmac,rec->input,rec->length); +- HMAC_Final(&hmac,md,&md_size); +- HMAC_CTX_cleanup(&hmac); ++ /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ ++ orig_len = rec->length+md_size+((unsigned int)rec->type>>8); ++ rec->type &= 0xff; ++ ++ header[8]=rec->type; ++ header[9]=(unsigned char)(ssl->version>>8); ++ header[10]=(unsigned char)(ssl->version); ++ header[11]=(rec->length)>>8; ++ header[12]=(rec->length)&0xff; ++ ++ if (!send && ++ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ ssl3_cbc_record_digest_supported(hash)) ++ { ++ /* This is a CBC-encrypted record. We must avoid leaking any ++ * timing-side channel information about how many blocks of ++ * data we are hashing because that gives an attacker a ++ * timing-oracle. */ ++ ssl3_cbc_digest_record( ++ hash, ++ md, &md_size, ++ header, rec->input, ++ rec->length + md_size, orig_len, ++ ssl->s3->read_mac_secret, ++ EVP_MD_size(ssl->read_hash), ++ 0 /* not SSLv3 */); ++ } ++ else ++ { ++ unsigned mds; + ++ HMAC_Update(&hmac,header,sizeof(header)); ++ HMAC_Update(&hmac,rec->input,rec->length); ++ HMAC_Final(&hmac,md,&mds); ++ md_size = mds; ++#ifdef OPENSSL_FIPS ++ if (!send && FIPS_mode()) ++ tls_fips_digest_extra( ++ ssl->enc_read_ctx, ++ hash, ++ &hmac, rec->input, ++ rec->length, orig_len); ++#endif ++ } ++ ++ HMAC_CTX_cleanup(&hmac); + #ifdef TLS_DEBUG + printf("sec="); + {unsigned int z; for (z=0; zs3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) goto end; +@@ -706,6 +707,7 @@ int ssl3_get_server_hello(SSL *s) + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->hit=1; + } + else /* a miss or crap from the other end */ +diff -up openssl-fips-0.9.8e/ssl/s3_pkt.c.keying-mitm openssl-fips-0.9.8e/ssl/s3_pkt.c +--- openssl-fips-0.9.8e/ssl/s3_pkt.c.keying-mitm 2014-06-02 15:45:18.375350271 +0200 ++++ openssl-fips-0.9.8e/ssl/s3_pkt.c 2014-06-02 15:49:35.037283962 +0200 +@@ -1133,6 +1133,15 @@ start: + goto f_err; + } + ++ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) ++ { ++ al=SSL_AD_UNEXPECTED_MESSAGE; ++ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY); ++ goto f_err; ++ } ++ ++ s->s3->flags &= ~SSL3_FLAGS_CCS_OK; ++ + rr->length=0; + + if (s->msg_callback) +@@ -1264,7 +1273,7 @@ int ssl3_do_change_cipher_spec(SSL *s) + + if (s->s3->tmp.key_block == NULL) + { +- if (s->session == NULL) ++ if (s->session == NULL || s->session->master_key_length == 0) + { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); +diff -up openssl-fips-0.9.8e/ssl/s3_srvr.c.keying-mitm openssl-fips-0.9.8e/ssl/s3_srvr.c +--- openssl-fips-0.9.8e/ssl/s3_srvr.c.keying-mitm 2014-06-02 15:45:18.362349971 +0200 ++++ openssl-fips-0.9.8e/ssl/s3_srvr.c 2014-06-02 15:49:35.037283962 +0200 +@@ -492,6 +492,7 @@ int ssl3_accept(SSL *s) + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* we should decide if we expected this one */ + ret=ssl3_get_cert_verify(s); + if (ret <= 0) goto end; +@@ -502,6 +503,7 @@ int ssl3_accept(SSL *s) + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) goto end; diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2015-0293.patch b/SOURCES/openssl-fips-0.9.8e-cve-2015-0293.patch new file mode 100644 index 0000000..3e9cfd6 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2015-0293.patch @@ -0,0 +1,112 @@ +diff -up openssl-fips-0.9.8e/ssl/s2_lib.c.ssl2-assert openssl-fips-0.9.8e/ssl/s2_lib.c +--- openssl-fips-0.9.8e/ssl/s2_lib.c.ssl2-assert 2015-04-01 12:41:28.023403066 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_lib.c 2015-04-02 15:29:37.468346462 +0200 +@@ -410,7 +410,7 @@ int ssl2_generate_key_material(SSL *s) + + OPENSSL_assert(s->session->master_key_length >= 0 + && s->session->master_key_length +- < (int)sizeof(s->session->master_key)); ++ <= (int)sizeof(s->session->master_key)); + EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length); + EVP_DigestUpdate(&ctx,&c,1); + c++; +diff -up openssl-fips-0.9.8e/ssl/s2_srvr.c.ssl2-assert openssl-fips-0.9.8e/ssl/s2_srvr.c +--- openssl-fips-0.9.8e/ssl/s2_srvr.c.ssl2-assert 2015-04-01 12:41:27.950401420 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_srvr.c 2015-04-02 15:33:51.109049368 +0200 +@@ -363,7 +363,8 @@ end: + + static int get_client_master_key(SSL *s) + { +- int is_export,i,n,keya,ek; ++ int is_export,i,n,keya; ++ unsigned int ek; + unsigned long len; + unsigned char *p; + SSL_CIPHER *cp; +@@ -445,9 +446,6 @@ static int get_client_master_key(SSL *s) + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY); + return(-1); + } +- i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc, +- &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]), +- (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); + + is_export=SSL_C_IS_EXPORT(s->session->cipher); + +@@ -466,21 +464,61 @@ static int get_client_master_key(SSL *s) + else + ek=5; + ++ /* ++ * The format of the CLIENT-MASTER-KEY message is ++ * 1 byte message type ++ * 3 bytes cipher ++ * 2-byte clear key length (stored in s->s2->tmp.clear) ++ * 2-byte encrypted key length (stored in s->s2->tmp.enc) ++ * 2-byte key args length (IV etc) ++ * clear key ++ * encrypted key ++ * key args ++ * ++ * If the cipher is an export cipher, then the encrypted key bytes ++ * are a fixed portion of the total key (5 or 8 bytes). The size of ++ * this portion is in |ek|. If the cipher is not an export cipher, ++ * then the entire key material is encrypted (i.e., clear key length ++ * must be zero). ++ */ ++ if ((!is_export && s->s2->tmp.clear != 0) || ++ (is_export && s->s2->tmp.clear + ek != (unsigned int)EVP_CIPHER_key_length(c))) ++ { ++ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); ++ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); ++ return -1; ++ } ++ /* ++ * The encrypted blob must decrypt to the encrypted portion of the key. ++ * Decryption can't be expanding, so if we don't have enough encrypted ++ * bytes to fit the key in the buffer, stop now. ++ */ ++ if ((is_export && s->s2->tmp.enc < ek) || ++ (!is_export && s->s2->tmp.enc < (unsigned int)EVP_CIPHER_key_length(c))) ++ { ++ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); ++ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); ++ return -1; ++ } ++ ++ i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, ++ &(p[s->s2->tmp.clear]), ++ &(p[s->s2->tmp.clear]), ++ (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : RSA_PKCS1_PADDING); ++ + /* bad decrypt */ + #if 1 + /* If a bad decrypt, continue with protocol but with a + * random master secret (Bleichenbacher attack) */ +- if ((i < 0) || +- ((!is_export && (i != EVP_CIPHER_key_length(c))) +- || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i != +- (unsigned int)EVP_CIPHER_key_length(c)))))) ++ if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c)) ++ || (is_export && i != (int)ek))) + { + ERR_clear_error(); + if (is_export) + i=ek; + else + i=EVP_CIPHER_key_length(c); +- if (RAND_pseudo_bytes(p,i) <= 0) ++ if (RAND_pseudo_bytes(&p[s->s2->tmp.clear],i) <= 0) + return 0; + } + #else +@@ -504,7 +542,8 @@ static int get_client_master_key(SSL *s) + } + #endif + +- if (is_export) i+=s->s2->tmp.clear; ++ if (is_export) ++ i = EVP_CIPHER_key_length(c); + + if (i > SSL_MAX_MASTER_KEY_LENGTH) + { diff --git a/SOURCES/openssl-fips-0.9.8e-cve-2015-3197.patch b/SOURCES/openssl-fips-0.9.8e-cve-2015-3197.patch new file mode 100644 index 0000000..028bde3 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-cve-2015-3197.patch @@ -0,0 +1,42 @@ +diff -up openssl-fips-0.9.8e/ssl/s2_srvr.c.ssl2-ciphers openssl-fips-0.9.8e/ssl/s2_srvr.c +--- openssl-fips-0.9.8e/ssl/s2_srvr.c.ssl2-ciphers 2015-04-02 15:33:51.109049368 +0200 ++++ openssl-fips-0.9.8e/ssl/s2_srvr.c 2016-02-18 19:15:21.164380375 +0100 +@@ -393,7 +393,7 @@ static int get_client_master_key(SSL *s) + } + + cp=ssl2_get_cipher_by_char(p); +- if (cp == NULL) ++ if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) + { + ssl2_return_error(s,SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); +@@ -692,9 +692,13 @@ static int get_client_hello(SSL *s) + prio = cs; + allow = cl; + } ++ ++ /* Generate list of SSLv2 ciphers shared between client and server */ + for (z=0; zalgorithms & SSL_SSLV2) == 0 || ++ sk_SSL_CIPHER_find(allow,cp) < 0) + { + (void)sk_SSL_CIPHER_delete(prio,z); + z--; +@@ -705,6 +709,14 @@ static int get_client_hello(SSL *s) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = prio; + } ++ ++ /* Make sure we have at least one cipher in common */ ++ if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) ++ { ++ ssl2_return_error(s, SSL2_PE_NO_CIPHER); ++ SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); ++ return -1; ++ } + /* s->session->ciphers should now have a list of + * ciphers that are on both the client and server. + * This list is ordered by the order the client sent diff --git a/SOURCES/openssl-fips-0.9.8e-default-paths.patch b/SOURCES/openssl-fips-0.9.8e-default-paths.patch new file mode 100644 index 0000000..5b54071 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-default-paths.patch @@ -0,0 +1,63 @@ +diff -up openssl-fips-0.9.8e/apps/s_client.c.default-paths openssl-fips-0.9.8e/apps/s_client.c +--- openssl-fips-0.9.8e/apps/s_client.c.default-paths 2008-09-06 12:17:46.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/s_client.c 2008-09-06 12:17:46.000000000 +0200 +@@ -610,12 +610,13 @@ bad: + if (!set_cert_key_stuff(ctx,cert,key)) + goto end; + +- if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx))) ++ if (!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ++ { ++ ERR_print_errors(bio_err); ++ } ++ if (!SSL_CTX_set_default_verify_paths(ctx)) + { +- /* BIO_printf(bio_err,"error setting default verify locations\n"); */ + ERR_print_errors(bio_err); +- /* goto end; */ + } + + store = SSL_CTX_get_cert_store(ctx); +diff -up openssl-fips-0.9.8e/apps/s_server.c.default-paths openssl-fips-0.9.8e/apps/s_server.c +--- openssl-fips-0.9.8e/apps/s_server.c.default-paths 2008-09-06 12:17:46.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/s_server.c 2008-09-06 12:17:46.000000000 +0200 +@@ -956,12 +956,13 @@ bad: + } + #endif + +- if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx))) ++ if (!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ++ { ++ ERR_print_errors(bio_err); ++ } ++ if (!SSL_CTX_set_default_verify_paths(ctx)) + { +- /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ + ERR_print_errors(bio_err); +- /* goto end; */ + } + store = SSL_CTX_get_cert_store(ctx); + X509_STORE_set_flags(store, vflags); +diff -up openssl-fips-0.9.8e/apps/s_time.c.default-paths openssl-fips-0.9.8e/apps/s_time.c +--- openssl-fips-0.9.8e/apps/s_time.c.default-paths 2003-12-27 15:40:17.000000000 +0100 ++++ openssl-fips-0.9.8e/apps/s_time.c 2008-09-06 12:17:46.000000000 +0200 +@@ -476,12 +476,13 @@ int MAIN(int argc, char **argv) + + SSL_load_error_strings(); + +- if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) || +- (!SSL_CTX_set_default_verify_paths(tm_ctx))) ++ if (!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ++ { ++ ERR_print_errors(bio_err); ++ } ++ if (!SSL_CTX_set_default_verify_paths(tm_ctx)) + { +- /* BIO_printf(bio_err,"error setting default verify locations\n"); */ + ERR_print_errors(bio_err); +- /* goto end; */ + } + + if (tm_cipher == NULL) diff --git a/SOURCES/openssl-fips-0.9.8e-dh-check.patch b/SOURCES/openssl-fips-0.9.8e-dh-check.patch new file mode 100644 index 0000000..3dc1eb7 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-dh-check.patch @@ -0,0 +1,38 @@ +diff -up openssl-fips-0.9.8e/fips/dh/fips_dh_key.c.dh-check openssl-fips-0.9.8e/fips/dh/fips_dh_key.c +--- openssl-fips-0.9.8e/fips/dh/fips_dh_key.c.dh-check 2007-08-21 16:44:13.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/dh/fips_dh_key.c 2011-05-04 12:30:34.000000000 +0200 +@@ -189,6 +189,7 @@ static int compute_key(unsigned char *ke + BN_MONT_CTX *mont=NULL; + BIGNUM *tmp; + int ret= -1; ++ int check_result; + + ctx = BN_CTX_new(); + if (ctx == NULL) goto err; +@@ -227,6 +228,12 @@ static int compute_key(unsigned char *ke + goto err; + } + ++ if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) ++ { ++ DHerr(DH_F_COMPUTE_KEY,DH_R_INVALID_PUBKEY); ++ goto err; ++ } ++ + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) + { + DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB); +@@ -235,8 +242,11 @@ static int compute_key(unsigned char *ke + + ret=BN_bn2bin(tmp,key); + err: +- BN_CTX_end(ctx); +- BN_CTX_free(ctx); ++ if (ctx != NULL) ++ { ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ } + return(ret); + } + diff --git a/SOURCES/openssl-fips-0.9.8e-disable-sslv2.patch b/SOURCES/openssl-fips-0.9.8e-disable-sslv2.patch new file mode 100644 index 0000000..f724578 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-disable-sslv2.patch @@ -0,0 +1,83 @@ +diff -up openssl-fips-0.9.8e/doc/apps/ciphers.pod.disable-sslv2 openssl-fips-0.9.8e/doc/apps/ciphers.pod +--- openssl-fips-0.9.8e/doc/apps/ciphers.pod.disable-sslv2 2007-04-25 15:15:50.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/apps/ciphers.pod 2016-02-24 15:49:57.949108087 +0100 +@@ -383,11 +383,11 @@ Note: these ciphers can also be used in + =head2 SSL v2.0 cipher suites. + + SSL_CK_RC4_128_WITH_MD5 RC4-MD5 +- SSL_CK_RC4_128_EXPORT40_WITH_MD5 EXP-RC4-MD5 +- SSL_CK_RC2_128_CBC_WITH_MD5 RC2-MD5 +- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 EXP-RC2-MD5 ++ SSL_CK_RC4_128_EXPORT40_WITH_MD5 Not implemented. ++ SSL_CK_RC2_128_CBC_WITH_MD5 RC2-CBC-MD5 ++ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 Not implemented. + SSL_CK_IDEA_128_CBC_WITH_MD5 IDEA-CBC-MD5 +- SSL_CK_DES_64_CBC_WITH_MD5 DES-CBC-MD5 ++ SSL_CK_DES_64_CBC_WITH_MD5 Not implemented. + SSL_CK_DES_192_EDE3_CBC_WITH_MD5 DES-CBC3-MD5 + + =head1 NOTES +diff -up openssl-fips-0.9.8e/ssl/ssl_lib.c.disable-sslv2 openssl-fips-0.9.8e/ssl/ssl_lib.c +--- openssl-fips-0.9.8e/ssl/ssl_lib.c.disable-sslv2 2016-02-24 15:49:57.927107582 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_lib.c 2016-02-24 15:49:57.948108064 +0100 +@@ -1548,6 +1548,8 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + ++ ret->options |= SSL_OP_NO_SSLv2; ++ + return(ret); + err: + SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); +diff -up openssl-fips-0.9.8e/ssl/s2_lib.c.disable-sslv2 openssl-fips-0.9.8e/ssl/s2_lib.c +--- openssl-fips-0.9.8e/ssl/s2_lib.c.disable-sslv2 2016-02-24 15:49:57.949108087 +0100 ++++ openssl-fips-0.9.8e/ssl/s2_lib.c 2016-02-24 15:52:27.697544452 +0100 +@@ -97,6 +97,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, ++#if 0 + /* RC4_128_EXPORT40_WITH_MD5 */ + { + 1, +@@ -110,6 +111,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, ++#endif + /* RC2_128_CBC_WITH_MD5 */ + { + 1, +@@ -123,6 +125,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, ++#if 0 + /* RC2_128_CBC_EXPORT40_WITH_MD5 */ + { + 1, +@@ -136,7 +139,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, +-/* IDEA_128_CBC_WITH_MD5 */ ++#endif + #ifndef OPENSSL_NO_IDEA + { + 1, +@@ -151,6 +154,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_STRENGTHS, + }, + #endif ++#if 0 + /* DES_64_CBC_WITH_MD5 */ + { + 1, +@@ -164,6 +168,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[] + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, ++#endif + /* DES_192_EDE3_CBC_WITH_MD5 */ + { + 1, diff --git a/SOURCES/openssl-fips-0.9.8e-dtls-dos.patch b/SOURCES/openssl-fips-0.9.8e-dtls-dos.patch new file mode 100644 index 0000000..41d015f --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-dtls-dos.patch @@ -0,0 +1,172 @@ +Fixes CVE-2009-1377 CVE-2009-1378 CVE-2009-1379 CVE-2009-1386 CVE-2009-1387 +DoS vulnerabilities in the DTLS implementation. +diff -up openssl-fips-0.9.8e/crypto/pqueue/pqueue.c.dtls-dos openssl-fips-0.9.8e/crypto/pqueue/pqueue.c +--- openssl-fips-0.9.8e/crypto/pqueue/pqueue.c.dtls-dos 2005-06-28 14:53:33.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/pqueue/pqueue.c 2009-05-21 14:41:48.000000000 +0200 +@@ -234,3 +234,17 @@ pqueue_next(pitem **item) + + return ret; + } ++ ++int ++pqueue_size(pqueue_s *pq) ++{ ++ pitem *item = pq->items; ++ int count = 0; ++ ++ while(item != NULL) ++ { ++ count++; ++ item = item->next; ++ } ++ return count; ++} +diff -up openssl-fips-0.9.8e/crypto/pqueue/pqueue.h.dtls-dos openssl-fips-0.9.8e/crypto/pqueue/pqueue.h +--- openssl-fips-0.9.8e/crypto/pqueue/pqueue.h.dtls-dos 2009-04-15 13:48:50.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/pqueue/pqueue.h 2009-05-21 14:41:48.000000000 +0200 +@@ -91,5 +91,6 @@ pitem *pqueue_iterator(pqueue pq); + pitem *pqueue_next(piterator *iter); + + void pqueue_print(pqueue pq); ++int pqueue_size(pqueue pq); + + #endif /* ! HEADER_PQUEUE_H */ +diff -up openssl-fips-0.9.8e/ssl/d1_both.c.dtls-dos openssl-fips-0.9.8e/ssl/d1_both.c +--- openssl-fips-0.9.8e/ssl/d1_both.c.dtls-dos 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/d1_both.c 2009-06-02 15:07:31.000000000 +0200 +@@ -519,6 +519,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, + + if ( s->d1->handshake_read_seq == frag->msg_header.seq) + { ++ unsigned long frag_len = frag->msg_header.frag_len; + pqueue_pop(s->d1->buffered_messages); + + al=dtls1_preprocess_fragment(s,&frag->msg_header,max); +@@ -536,7 +537,7 @@ dtls1_retrieve_buffered_fragment(SSL *s, + if (al==0) + { + *ok = 1; +- return frag->msg_header.frag_len; ++ return frag_len; + } + + ssl3_send_alert(s,SSL3_AL_FATAL,al); +@@ -561,7 +562,16 @@ dtls1_process_out_of_seq_message(SSL *s, + if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) + goto err; + +- if (msg_hdr->seq <= s->d1->handshake_read_seq) ++ /* Try to find item in queue, to prevent duplicate entries */ ++ pq_64bit_init(&seq64); ++ pq_64bit_assign_word(&seq64, msg_hdr->seq); ++ item = pqueue_find(s->d1->buffered_messages, seq64); ++ pq_64bit_free(&seq64); ++ ++ /* Discard the message if sequence number was already there, is ++ * too far in the future or the fragment is already in the queue */ ++ if (msg_hdr->seq <= s->d1->handshake_read_seq || ++ msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL) + { + unsigned char devnull [256]; + +@@ -575,30 +585,31 @@ dtls1_process_out_of_seq_message(SSL *s, + } + } + +- frag = dtls1_hm_fragment_new(frag_len); +- if ( frag == NULL) +- goto err; ++ if (frag_len) ++ { ++ frag = dtls1_hm_fragment_new(frag_len); ++ if ( frag == NULL) ++ goto err; + +- memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); ++ memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + +- if (frag_len) +- { +- /* read the body of the fragment (header has already been read */ ++ /* read the body of the fragment (header has already been read) */ + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, + frag->fragment,frag_len,0); +- if (i<=0 || i!=frag_len) ++ if (i<=0 || (unsigned long)i!=frag_len) + goto err; +- } + +- pq_64bit_init(&seq64); +- pq_64bit_assign_word(&seq64, msg_hdr->seq); ++ pq_64bit_init(&seq64); ++ pq_64bit_assign_word(&seq64, msg_hdr->seq); + +- item = pitem_new(seq64, frag); +- pq_64bit_free(&seq64); +- if ( item == NULL) +- goto err; ++ item = pitem_new(seq64, frag); ++ pq_64bit_free(&seq64); ++ if ( item == NULL) ++ goto err; ++ ++ pqueue_insert(s->d1->buffered_messages, item); ++ } + +- pqueue_insert(s->d1->buffered_messages, item); + return DTLS1_HM_FRAGMENT_RETRY; + + err: +diff -up openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-dos openssl-fips-0.9.8e/ssl/d1_pkt.c +--- openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-dos 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/d1_pkt.c 2009-05-21 14:41:48.000000000 +0200 +@@ -167,6 +167,10 @@ dtls1_buffer_record(SSL *s, record_pqueu + DTLS1_RECORD_DATA *rdata; + pitem *item; + ++ /* Limit the size of the queue to prevent DOS attacks */ ++ if (pqueue_size(queue->q) >= 100) ++ return 0; ++ + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) +diff -up openssl-fips-0.9.8e/ssl/s3_pkt.c.dtls-dos openssl-fips-0.9.8e/ssl/s3_pkt.c +--- openssl-fips-0.9.8e/ssl/s3_pkt.c.dtls-dos 2006-11-29 15:45:14.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s3_pkt.c 2009-06-02 14:57:16.000000000 +0200 +@@ -1225,6 +1225,13 @@ int ssl3_do_change_cipher_spec(SSL *s) + + if (s->s3->tmp.key_block == NULL) + { ++ if (s->session == NULL) ++ { ++ /* might happen if dtls1_read_bytes() calls this */ ++ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); ++ return (0); ++ } ++ + s->session->cipher=s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) return(0); + } +diff -up openssl-fips-0.9.8e/ssl/ssl_err.c.dtls-dos openssl-fips-0.9.8e/ssl/ssl_err.c +--- openssl-fips-0.9.8e/ssl/ssl_err.c.dtls-dos 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl_err.c 2009-06-02 14:57:16.000000000 +0200 +@@ -138,6 +138,7 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, + {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, ++{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), "SSL3_DO_CHANGE_CIPHER_SPEC"}, + {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"}, +diff -up openssl-fips-0.9.8e/ssl/ssl.h.dtls-dos openssl-fips-0.9.8e/ssl/ssl.h +--- openssl-fips-0.9.8e/ssl/ssl.h.dtls-dos 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl.h 2009-06-02 14:57:16.000000000 +0200 +@@ -1620,6 +1620,7 @@ void ERR_load_SSL_strings(void); + #define SSL_F_SSL3_CONNECT 132 + #define SSL_F_SSL3_CTRL 213 + #define SSL_F_SSL3_CTX_CTRL 133 ++#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 + #define SSL_F_SSL3_ENC 134 + #define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 + #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 diff --git a/SOURCES/openssl-fips-0.9.8e-dtls-fixes.patch b/SOURCES/openssl-fips-0.9.8e-dtls-fixes.patch new file mode 100644 index 0000000..9509fad --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-dtls-fixes.patch @@ -0,0 +1,1326 @@ +diff -up openssl-fips-0.9.8f-dev/ssl/dtls1.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/dtls1.h +--- openssl-fips-0.9.8f-dev/ssl/dtls1.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/ssl/dtls1.h 2008-07-15 21:01:29.000000000 +0200 +@@ -67,9 +67,8 @@ + extern "C" { + #endif + +-#define DTLS1_VERSION 0x0100 +-#define DTLS1_VERSION_MAJOR 0x01 +-#define DTLS1_VERSION_MINOR 0x00 ++#define DTLS1_VERSION 0xFEFF ++#define DTLS1_BAD_VER 0x0100 + + #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 + +@@ -83,7 +82,7 @@ extern "C" { + #define DTLS1_HM_BAD_FRAGMENT -2 + #define DTLS1_HM_FRAGMENT_RETRY -3 + +-#define DTLS1_CCS_HEADER_LENGTH 3 ++#define DTLS1_CCS_HEADER_LENGTH 1 + + #define DTLS1_AL_HEADER_LENGTH 7 + +diff -up openssl-fips-0.9.8f-dev/ssl/d1_lib.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_lib.c +--- openssl-fips-0.9.8f-dev/ssl/d1_lib.c.dtls-fixes 2007-01-21 17:07:25.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/d1_lib.c 2008-07-15 21:01:29.000000000 +0200 +@@ -188,3 +188,23 @@ void dtls1_clear(SSL *s) + ssl3_clear(s); + s->version=DTLS1_VERSION; + } ++ ++/* ++ * As it's impossible to use stream ciphers in "datagram" mode, this ++ * simple filter is designed to disengage them in DTLS. Unfortunately ++ * there is no universal way to identify stream SSL_CIPHER, so we have ++ * to explicitly list their SSL_* codes. Currently RC4 is the only one ++ * available, but if new ones emerge, they will have to be added... ++ */ ++SSL_CIPHER *dtls1_get_cipher(unsigned int u) ++ { ++ SSL_CIPHER *ciph = ssl3_get_cipher(u); ++ ++ if (ciph != NULL) ++ { ++ if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) ++ return NULL; ++ } ++ ++ return ciph; ++ } +diff -up openssl-fips-0.9.8f-dev/ssl/d1_srvr.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_srvr.c +--- openssl-fips-0.9.8f-dev/ssl/d1_srvr.c.dtls-fixes 2007-09-19 02:02:49.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/ssl/d1_srvr.c 2008-07-15 21:01:29.000000000 +0200 +@@ -285,6 +285,10 @@ int dtls1_accept(SSL *s) + s->d1->send_cookie = 0; + s->state=SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; ++ ++ /* HelloVerifyRequests resets Finished MAC */ ++ if (s->client_version != DTLS1_BAD_VER) ++ ssl3_init_finished_mac(s); + break; + + case SSL3_ST_SW_SRVR_HELLO_A: +@@ -620,10 +624,13 @@ int dtls1_send_hello_verify_request(SSL + buf = (unsigned char *)s->init_buf->data; + + msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); +- *(p++) = s->version >> 8; +- *(p++) = s->version & 0xFF; ++ if (s->client_version == DTLS1_BAD_VER) ++ *(p++) = DTLS1_BAD_VER>>8, ++ *(p++) = DTLS1_BAD_VER&0xff; ++ else ++ *(p++) = s->version >> 8, ++ *(p++) = s->version & 0xFF; + +- *(p++) = (unsigned char) s->d1->cookie_len; + if ( s->ctx->app_gen_cookie_cb != NULL && + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) +@@ -634,6 +641,7 @@ int dtls1_send_hello_verify_request(SSL + /* else the cookie is assumed to have + * been initialized by the application */ + ++ *(p++) = (unsigned char) s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + msg_len = p - msg; +@@ -672,8 +680,12 @@ int dtls1_send_server_hello(SSL *s) + /* Do the message type and length last */ + d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); + +- *(p++)=s->version>>8; +- *(p++)=s->version&0xff; ++ if (s->client_version == DTLS1_BAD_VER) ++ *(p++)=DTLS1_BAD_VER>>8, ++ *(p++)=DTLS1_BAD_VER&0xff; ++ else ++ *(p++)=s->version>>8, ++ *(p++)=s->version&0xff; + + /* Random stuff */ + memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); +diff -up openssl-fips-0.9.8f-dev/ssl/s3_srvr.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/s3_srvr.c +--- openssl-fips-0.9.8f-dev/ssl/s3_srvr.c.dtls-fixes 2007-03-22 01:39:14.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/s3_srvr.c 2008-07-15 21:01:29.000000000 +0200 +@@ -699,7 +699,8 @@ int ssl3_get_client_hello(SSL *s) + s->client_version=(((int)p[0])<<8)|(int)p[1]; + p+=2; + +- if (s->client_version < s->version) ++ if ((s->version == DTLS1_VERSION && s->client_version > s->version) || ++ (s->version != DTLS1_VERSION && s->client_version < s->version)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); + if ((s->client_version>>8) == SSL3_VERSION_MAJOR) +@@ -750,7 +751,7 @@ int ssl3_get_client_hello(SSL *s) + + p+=j; + +- if (SSL_version(s) == DTLS1_VERSION) ++ if (s->version == DTLS1_VERSION) + { + /* cookie stuff */ + cookie_len = *(p++); +@@ -1713,8 +1714,9 @@ int ssl3_get_client_key_exchange(SSL *s) + rsa=pkey->pkey.rsa; + } + +- /* TLS */ +- if (s->version > SSL3_VERSION) ++ /* TLS and [incidentally] DTLS, including pre-0.9.8f */ ++ if (s->version > SSL3_VERSION && ++ s->client_version != DTLS1_BAD_VER) + { + n2s(p,i); + if (n != i+2) +diff -up openssl-fips-0.9.8f-dev/ssl/ssl_locl.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl_locl.h +--- openssl-fips-0.9.8f-dev/ssl/ssl_locl.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/ssl/ssl_locl.h 2008-07-15 21:01:29.000000000 +0200 +@@ -680,7 +680,7 @@ SSL_METHOD *func_name(void) \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ +- ssl3_get_cipher, \ ++ dtls1_get_cipher, \ + s_get_meth, \ + dtls1_default_timeout, \ + &DTLSv1_enc_data, \ +@@ -845,6 +845,8 @@ void dtls1_get_message_header(unsigned c + void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); + void dtls1_reset_seq_numbers(SSL *s, int rw); + long dtls1_default_timeout(void); ++SSL_CIPHER *dtls1_get_cipher(unsigned int u); ++ + + + /* some client-only functions */ +diff -up openssl-fips-0.9.8f-dev/ssl/t1_enc.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/t1_enc.c +--- openssl-fips-0.9.8f-dev/ssl/t1_enc.c.dtls-fixes 2007-03-22 01:39:15.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/t1_enc.c 2008-07-15 21:01:29.000000000 +0200 +@@ -740,15 +740,35 @@ int tls1_mac(SSL *ssl, unsigned char *md + md_size=EVP_MD_size(hash); + + buf[0]=rec->type; +- buf[1]=TLS1_VERSION_MAJOR; +- buf[2]=TLS1_VERSION_MINOR; ++ if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) ++ { ++ buf[1]=TLS1_VERSION_MAJOR; ++ buf[2]=TLS1_VERSION_MINOR; ++ } ++ else { ++ buf[1]=(unsigned char)(ssl->version>>8); ++ buf[2]=(unsigned char)(ssl->version); ++ } ++ + buf[3]=rec->length>>8; + buf[4]=rec->length&0xff; + + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + HMAC_CTX_init(&hmac); + HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); +- HMAC_Update(&hmac,seq,8); ++ ++ if (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER) ++ { ++ unsigned char dtlsseq[8],*p=dtlsseq; ++ ++ s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); ++ memcpy (p,&seq[2],6); ++ ++ HMAC_Update(&hmac,dtlsseq,8); ++ } ++ else ++ HMAC_Update(&hmac,seq,8); ++ + HMAC_Update(&hmac,buf,5); + HMAC_Update(&hmac,rec->input,rec->length); + HMAC_Final(&hmac,md,&md_size); +@@ -765,8 +785,8 @@ printf("rec="); + {unsigned int z; for (z=0; zlength; z++) printf("%02X ",buf[z]); printf("\n"); } + #endif + +- if ( SSL_version(ssl) != DTLS1_VERSION) +- { ++ if ( SSL_version(ssl) != DTLS1_VERSION) ++ { + for (i=7; i>=0; i--) + { + ++seq[i]; +diff -up openssl-fips-0.9.8f-dev/ssl/ssl.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl.h +--- openssl-fips-0.9.8f-dev/ssl/ssl.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/ssl/ssl.h 2008-07-15 21:01:29.000000000 +0200 +@@ -1554,6 +1554,7 @@ void ERR_load_SSL_strings(void); + #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 + #define SSL_F_DTLS1_GET_RECORD 254 + #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 ++#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277 + #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 + #define SSL_F_DTLS1_PROCESS_RECORD 257 + #define SSL_F_DTLS1_READ_BYTES 258 +diff -up openssl-fips-0.9.8f-dev/ssl/d1_pkt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_pkt.c +--- openssl-fips-0.9.8f-dev/ssl/d1_pkt.c.dtls-fixes 2006-11-29 15:45:13.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/d1_pkt.c 2008-07-15 21:01:29.000000000 +0200 +@@ -120,6 +120,7 @@ + #include + #include + #include ++#include + + static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek); +@@ -486,9 +487,9 @@ int dtls1_get_record(SSL *s) + SSL3_RECORD *rr; + SSL_SESSION *sess; + unsigned char *p; +- short version; ++ unsigned short version; + DTLS1_BITMAP *bitmap; +- unsigned int is_next_epoch; ++ unsigned int is_next_epoch; + + rr= &(s->s3->rrec); + sess=s->session; +@@ -524,7 +525,7 @@ again: + ssl_minor= *(p++); + version=(ssl_major<<8)|ssl_minor; + +- /* sequence number is 64 bits, with top 2 bytes = epoch */ ++ /* sequence number is 64 bits, with top 2 bytes = epoch */ + n2s(p,rr->epoch); + + memcpy(&(s->s3->read_sequence[2]), p, 6); +@@ -535,7 +536,7 @@ again: + /* Lets check version */ + if (!s->first_packet) + { +- if (version != s->version) ++ if (version != s->version && version != DTLS1_BAD_VER) + { + SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); + /* Send back error using their +@@ -546,7 +547,8 @@ again: + } + } + +- if ((version & 0xff00) != (DTLS1_VERSION & 0xff00)) ++ if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && ++ (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) + { + SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); + goto err; +@@ -559,6 +561,7 @@ again: + goto f_err; + } + ++ s->client_version = version; + /* now s->rstate == SSL_ST_READ_BODY */ + } + +@@ -973,47 +976,40 @@ start: + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) +- { +- struct ccs_header_st ccs_hdr; ++ { ++ struct ccs_header_st ccs_hdr; + + dtls1_get_ccs_header(rr->data, &ccs_hdr); + +- if ( ccs_hdr.seq == s->d1->handshake_read_seq) ++ /* 'Change Cipher Spec' is just a single byte, so we know ++ * exactly what the record payload has to look like */ ++ /* XDTLS: check that epoch is consistent */ ++ if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) || ++ (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) || ++ (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) + { +- /* 'Change Cipher Spec' is just a single byte, so we know +- * exactly what the record payload has to look like */ +- /* XDTLS: check that epoch is consistent */ +- if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) || +- (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) +- { +- i=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); +- goto err; +- } +- +- rr->length=0; +- +- if (s->msg_callback) +- s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, +- rr->data, 1, s, s->msg_callback_arg); +- +- s->s3->change_cipher_spec=1; +- if (!ssl3_do_change_cipher_spec(s)) +- goto err; +- +- /* do this whenever CCS is processed */ +- dtls1_reset_seq_numbers(s, SSL3_CC_READ); +- +- /* handshake read seq is reset upon handshake completion */ +- s->d1->handshake_read_seq++; +- +- goto start; +- } +- else +- { +- rr->length = 0; +- goto start; ++ i=SSL_AD_ILLEGAL_PARAMETER; ++ SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); ++ goto err; + } ++ ++ rr->length=0; ++ ++ if (s->msg_callback) ++ s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, ++ rr->data, 1, s, s->msg_callback_arg); ++ ++ s->s3->change_cipher_spec=1; ++ if (!ssl3_do_change_cipher_spec(s)) ++ goto err; ++ ++ /* do this whenever CCS is processed */ ++ dtls1_reset_seq_numbers(s, SSL3_CC_READ); ++ ++ if (s->client_version == DTLS1_BAD_VER) ++ s->d1->handshake_read_seq++; ++ ++ goto start; + } + + /* Unexpected handshake message (Client Hello, or protocol violation) */ +@@ -1341,8 +1337,12 @@ int do_dtls1_write(SSL *s, int type, con + *(p++)=type&0xff; + wr->type=type; + +- *(p++)=(s->version>>8); +- *(p++)=s->version&0xff; ++ if (s->client_version == DTLS1_BAD_VER) ++ *(p++) = DTLS1_BAD_VER>>8, ++ *(p++) = DTLS1_BAD_VER&0xff; ++ else ++ *(p++)=(s->version>>8), ++ *(p++)=s->version&0xff; + + /* field where we are to write out packet epoch, seq num and len */ + pseq=p; +@@ -1397,8 +1397,14 @@ int do_dtls1_write(SSL *s, int type, con + + + /* ssl3_enc can only have an error on read */ +- wr->length += bs; /* bs != 0 in case of CBC. The enc fn provides +- * the randomness */ ++ if (bs) /* bs != 0 in case of CBC */ ++ { ++ RAND_pseudo_bytes(p,bs); ++ /* master IV and last CBC residue stand for ++ * the rest of randomness */ ++ wr->length += bs; ++ } ++ + s->method->ssl3_enc->enc(s,1); + + /* record length after mac and block padding */ +diff -up openssl-fips-0.9.8f-dev/ssl/ssl_err.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl_err.c +--- openssl-fips-0.9.8f-dev/ssl/ssl_err.c.dtls-fixes 2006-11-21 21:14:46.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/ssl_err.c 2008-07-15 21:01:29.000000000 +0200 +@@ -87,6 +87,7 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"}, + {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_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"}, +diff -up openssl-fips-0.9.8f-dev/ssl/s3_clnt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/s3_clnt.c +--- openssl-fips-0.9.8f-dev/ssl/s3_clnt.c.dtls-fixes 2007-03-22 01:39:14.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/s3_clnt.c 2008-07-15 21:08:43.000000000 +0200 +@@ -1847,6 +1847,13 @@ int ssl3_send_client_key_exchange(SSL *s + { + DH *dh_srvr,*dh_clnt; + ++ if (s->session->sess_cert == NULL) ++ { ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); ++ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); ++ goto err; ++ } ++ + if (s->session->sess_cert->peer_dh_tmp != NULL) + dh_srvr=s->session->sess_cert->peer_dh_tmp; + else +diff -up openssl-fips-0.9.8f-dev/ssl/d1_both.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_both.c +--- openssl-fips-0.9.8f-dev/ssl/d1_both.c.dtls-fixes 2007-06-22 14:17:52.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/ssl/d1_both.c 2008-07-15 21:01:29.000000000 +0200 +@@ -138,38 +138,40 @@ static void dtls1_set_message_header_int + unsigned long frag_len); + static int dtls1_retransmit_buffered_messages(SSL *s); + static long dtls1_get_message_fragment(SSL *s, int st1, int stn, +- long max, int *ok); +-static void dtls1_process_handshake_fragment(SSL *s, int frag_len); ++ long max, int *ok); + + static hm_fragment * + dtls1_hm_fragment_new(unsigned long frag_len) +- { +- hm_fragment *frag = NULL; +- unsigned char *buf = NULL; ++ { ++ hm_fragment *frag = NULL; ++ unsigned char *buf = NULL; + +- frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); +- if ( frag == NULL) +- return NULL; ++ frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); ++ if ( frag == NULL) ++ return NULL; + +- buf = (unsigned char *)OPENSSL_malloc(frag_len +- + DTLS1_HM_HEADER_LENGTH); +- if ( buf == NULL) +- { +- OPENSSL_free(frag); +- return NULL; +- } +- +- frag->fragment = buf; ++ if (frag_len) ++ { ++ buf = (unsigned char *)OPENSSL_malloc(frag_len); ++ if ( buf == NULL) ++ { ++ OPENSSL_free(frag); ++ return NULL; ++ } ++ } + +- return frag; +- } ++ /* zero length fragment gets zero frag->fragment */ ++ frag->fragment = buf; ++ ++ return frag; ++ } + + static void + dtls1_hm_fragment_free(hm_fragment *frag) +- { +- OPENSSL_free(frag->fragment); +- OPENSSL_free(frag); +- } ++ { ++ if (frag->fragment) OPENSSL_free(frag->fragment); ++ OPENSSL_free(frag); ++ } + + /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ + int dtls1_do_write(SSL *s, int type) +@@ -180,7 +182,7 @@ int dtls1_do_write(SSL *s, int type) + + /* AHA! Figure out the MTU, and stick to the right size */ + if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) +- { ++ { + s->d1->mtu = + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + +@@ -207,7 +209,7 @@ int dtls1_do_write(SSL *s, int type) + mtu = curr_mtu; + else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0) + return ret; +- ++ + if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu) + { + ret = BIO_flush(SSL_get_wbio(s)); +@@ -254,11 +256,11 @@ int dtls1_do_write(SSL *s, int type) + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; + +- /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ ++ /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ + if ( len <= DTLS1_HM_HEADER_LENGTH) + len += DTLS1_HM_HEADER_LENGTH; + } +- ++ + dtls1_fix_message_header(s, frag_off, + len - DTLS1_HM_HEADER_LENGTH); + +@@ -286,18 +288,40 @@ int dtls1_do_write(SSL *s, int type) + } + else + { +- ++ + /* bad if this assert fails, only part of the handshake + * message got sent. but why would this happen? */ +- OPENSSL_assert(len == (unsigned int)ret); +- ++ OPENSSL_assert(len == (unsigned int)ret); ++ + if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting) ++ { + /* should not be done for 'Hello Request's, but in that case + * we'll ignore the result anyway */ +- ssl3_finish_mac(s, +- (unsigned char *)&s->init_buf->data[s->init_off + +- DTLS1_HM_HEADER_LENGTH], ret - DTLS1_HM_HEADER_LENGTH); +- ++ unsigned char *p = &s->init_buf->data[s->init_off]; ++ const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; ++ int len; ++ ++ if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) ++ { ++ /* reconstruct message header is if it ++ * is being sent in single fragment */ ++ *p++ = msg_hdr->type; ++ l2n3(msg_hdr->msg_len,p); ++ s2n (msg_hdr->seq,p); ++ l2n3(0,p); ++ l2n3(msg_hdr->msg_len,p); ++ p -= DTLS1_HM_HEADER_LENGTH; ++ len = ret; ++ } ++ else ++ { ++ p += DTLS1_HM_HEADER_LENGTH; ++ len = ret - DTLS1_HM_HEADER_LENGTH; ++ } ++ ++ ssl3_finish_mac(s, p, len); ++ } ++ + if (ret == s->init_num) + { + if (s->msg_callback) +@@ -307,7 +331,7 @@ int dtls1_do_write(SSL *s, int type) + + s->init_off = 0; /* done writing this message */ + s->init_num = 0; +- ++ + return(1); + } + s->init_off+=ret; +@@ -327,6 +351,7 @@ int dtls1_do_write(SSL *s, int type) + long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) + { + int i, al; ++ struct hm_header_st *msg_hdr; + + /* s3->tmp is used to store messages that are unexpected, caused + * by the absence of an optional handshake message */ +@@ -344,25 +369,56 @@ long dtls1_get_message(SSL *s, int st1, + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } +- ++ ++ msg_hdr = &s->d1->r_msg_hdr; + do + { +- if ( s->d1->r_msg_hdr.frag_off == 0) ++ if ( msg_hdr->frag_off == 0) + { + /* s->d1->r_message_header.msg_len = 0; */ +- memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st)); ++ memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + } + + i = dtls1_get_message_fragment(s, st1, stn, max, ok); + if ( i == DTLS1_HM_BAD_FRAGMENT || +- i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ ++ i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ + continue; + else if ( i <= 0 && !*ok) + return i; + +- if (s->d1->r_msg_hdr.msg_len == (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH) ++ /* Note that s->init_sum is used as a counter summing ++ * up fragments' lengths: as soon as they sum up to ++ * handshake packet length, we assume we have got all ++ * the fragments. Overlapping fragments would cause ++ * premature termination, so we don't expect overlaps. ++ * Well, handling overlaps would require something more ++ * drastic. Indeed, as it is now there is no way to ++ * tell if out-of-order fragment from the middle was ++ * the last. '>=' is the best/least we can do to control ++ * the potential damage caused by malformed overlaps. */ ++ if ((unsigned int)s->init_num >= msg_hdr->msg_len) + { +- memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st)); ++ unsigned char *p = s->init_buf->data; ++ unsigned long msg_len = msg_hdr->msg_len; ++ ++ /* reconstruct message header as if it was ++ * sent in single fragment */ ++ *(p++) = msg_hdr->type; ++ l2n3(msg_len,p); ++ s2n (msg_hdr->seq,p); ++ l2n3(0,p); ++ l2n3(msg_len,p); ++ if (s->client_version != DTLS1_BAD_VER) ++ p -= DTLS1_HM_HEADER_LENGTH, ++ msg_len += DTLS1_HM_HEADER_LENGTH; ++ ++ ssl3_finish_mac(s, p, msg_len); ++ if (s->msg_callback) ++ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, ++ p, msg_len, ++ s, s->msg_callback_arg); ++ ++ memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + s->d1->handshake_read_seq++; + /* we just read a handshake message from the other side: +@@ -379,11 +435,11 @@ long dtls1_get_message(SSL *s, int st1, + * first data segment, but is there a better way? */ + dtls1_clear_record_buffer(s); + +- s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; +- return s->init_num - DTLS1_HM_HEADER_LENGTH; ++ s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; ++ return s->init_num; + } + else +- s->d1->r_msg_hdr.frag_off = i; ++ msg_hdr->frag_off = i; + } while(1) ; + + f_err: +@@ -393,161 +449,183 @@ f_err: + } + + +-static int +-dtls1_retrieve_buffered_fragment(SSL *s, unsigned long *copied) +- { +- /* (0) check whether the desired fragment is available +- * if so: +- * (1) copy over the fragment to s->init_buf->data[] +- * (2) update s->init_num +- */ +- pitem *item; +- hm_fragment *frag; +- unsigned long overlap; +- unsigned char *p; +- +- item = pqueue_peek(s->d1->buffered_messages); +- if ( item == NULL) +- return 0; ++static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max) ++ { ++ size_t frag_off,frag_len,msg_len; + +- frag = (hm_fragment *)item->data; +- +- if ( s->d1->handshake_read_seq == frag->msg_header.seq && +- frag->msg_header.frag_off <= (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH) +- { +- pqueue_pop(s->d1->buffered_messages); +- overlap = s->init_num - DTLS1_HM_HEADER_LENGTH +- - frag->msg_header.frag_off; +- +- p = frag->fragment; +- +- memcpy(&s->init_buf->data[s->init_num], +- p + DTLS1_HM_HEADER_LENGTH + overlap, +- frag->msg_header.frag_len - overlap); +- +- OPENSSL_free(frag->fragment); +- OPENSSL_free(frag); +- pitem_free(item); ++ msg_len = msg_hdr->msg_len; ++ frag_off = msg_hdr->frag_off; ++ frag_len = msg_hdr->frag_len; + +- *copied = frag->msg_header.frag_len - overlap; +- return *copied; +- } +- else +- return 0; +- } ++ /* sanity checking */ ++ if ( (frag_off+frag_len) > msg_len) ++ { ++ SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); ++ return SSL_AD_ILLEGAL_PARAMETER; ++ } + ++ if ( (frag_off+frag_len) > (unsigned long)max) ++ { ++ SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); ++ return SSL_AD_ILLEGAL_PARAMETER; ++ } + +-static int +-dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr) +-{ +- hm_fragment *frag = NULL; +- pitem *item = NULL; +- PQ_64BIT seq64; ++ if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ ++ { ++ /* msg_len is limited to 2^24, but is effectively checked ++ * against max above */ ++ if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) ++ { ++ SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); ++ return SSL_AD_INTERNAL_ERROR; ++ } + +- frag = dtls1_hm_fragment_new(msg_hdr->frag_len); +- if ( frag == NULL) +- goto err; ++ s->s3->tmp.message_size = msg_len; ++ s->d1->r_msg_hdr.msg_len = msg_len; ++ s->s3->tmp.message_type = msg_hdr->type; ++ s->d1->r_msg_hdr.type = msg_hdr->type; ++ s->d1->r_msg_hdr.seq = msg_hdr->seq; ++ } ++ else if (msg_len != s->d1->r_msg_hdr.msg_len) ++ { ++ /* They must be playing with us! BTW, failure to enforce ++ * upper limit would open possibility for buffer overrun. */ ++ SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); ++ return SSL_AD_ILLEGAL_PARAMETER; ++ } + +- memcpy(frag->fragment, &(s->init_buf->data[s->init_num]), +- msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH); ++ return 0; /* no error */ ++ } + +- memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + +- pq_64bit_init(&seq64); +- pq_64bit_assign_word(&seq64, msg_hdr->seq); ++static int ++dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) ++ { ++ /* (0) check whether the desired fragment is available ++ * if so: ++ * (1) copy over the fragment to s->init_buf->data[] ++ * (2) update s->init_num ++ */ ++ pitem *item; ++ hm_fragment *frag; ++ int al; + +- item = pitem_new(seq64, frag); +- if ( item == NULL) +- goto err; ++ *ok = 0; ++ item = pqueue_peek(s->d1->buffered_messages); ++ if ( item == NULL) ++ return 0; + +- pq_64bit_free(&seq64); ++ frag = (hm_fragment *)item->data; + +- pqueue_insert(s->d1->buffered_messages, item); +- return 1; ++ if ( s->d1->handshake_read_seq == frag->msg_header.seq) ++ { ++ pqueue_pop(s->d1->buffered_messages); + +-err: +- if ( frag != NULL) dtls1_hm_fragment_free(frag); +- if ( item != NULL) OPENSSL_free(item); +- return 0; +-} ++ al=dtls1_preprocess_fragment(s,&frag->msg_header,max); + ++ if (al==0) /* no alert */ ++ { ++ unsigned char *p = s->init_buf->data+DTLS1_HM_HEADER_LENGTH; ++ memcpy(&p[frag->msg_header.frag_off], ++ frag->fragment,frag->msg_header.frag_len); ++ } + +-static void +-dtls1_process_handshake_fragment(SSL *s, int frag_len) +- { +- unsigned char *p; ++ dtls1_hm_fragment_free(frag); ++ pitem_free(item); + +- p = (unsigned char *)s->init_buf->data; ++ if (al==0) ++ { ++ *ok = 1; ++ return frag->msg_header.frag_len; ++ } + +- ssl3_finish_mac(s, &p[s->init_num - frag_len], frag_len); +- } ++ ssl3_send_alert(s,SSL3_AL_FATAL,al); ++ s->init_num = 0; ++ *ok = 0; ++ return -1; ++ } ++ else ++ return 0; ++ } + + + static int +-dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st *msg_hdr, int *ok) +- { +- int i; +- unsigned char *p; +- +- /* make sure there's enough room to read this fragment */ +- if ( (int)msg_hdr->frag_len && !BUF_MEM_grow_clean(s->init_buf, +- (int)msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH + s->init_num)) +- { +- SSLerr(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE,ERR_R_BUF_LIB); +- goto err; +- } ++dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) ++{ ++ int i=-1; ++ hm_fragment *frag = NULL; ++ pitem *item = NULL; ++ PQ_64BIT seq64; ++ unsigned long frag_len = msg_hdr->frag_len; + +- p = (unsigned char *)s->init_buf->data; ++ if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) ++ goto err; + +- /* read the body of the fragment (header has already been read */ +- if ( msg_hdr->frag_len > 0) ++ if (msg_hdr->seq <= s->d1->handshake_read_seq) + { +- i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, +- &p[s->init_num], +- msg_hdr->frag_len,0); +- if (i <= 0) ++ unsigned char devnull [256]; ++ ++ while (frag_len) + { +- *ok = 0; +- return i; ++ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, ++ devnull, ++ frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); ++ if (i<=0) goto err; ++ frag_len -= i; + } + } + +- if ( msg_hdr->seq > s->d1->handshake_read_seq) +- dtls1_buffer_handshake_fragment(s, msg_hdr); +- else +- OPENSSL_assert(msg_hdr->seq < s->d1->handshake_read_seq); ++ frag = dtls1_hm_fragment_new(frag_len); ++ if ( frag == NULL) ++ goto err; ++ ++ memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); ++ ++ if (frag_len) ++ { ++ /* read the body of the fragment (header has already been read */ ++ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, ++ frag->fragment,frag_len,0); ++ if (i<=0 || i!=frag_len) ++ goto err; ++ } ++ ++ pq_64bit_init(&seq64); ++ pq_64bit_assign_word(&seq64, msg_hdr->seq); ++ ++ item = pitem_new(seq64, frag); ++ pq_64bit_free(&seq64); ++ if ( item == NULL) ++ goto err; ++ ++ pqueue_insert(s->d1->buffered_messages, item); ++ return DTLS1_HM_FRAGMENT_RETRY; + +- return DTLS1_HM_FRAGMENT_RETRY; + err: +- *ok = 0; +- return -1; +- } ++ if ( frag != NULL) dtls1_hm_fragment_free(frag); ++ if ( item != NULL) OPENSSL_free(item); ++ *ok = 0; ++ return i; ++ } + + + static long + dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) + { +- unsigned char *p; ++ unsigned char wire[DTLS1_HM_HEADER_LENGTH]; + unsigned long l, frag_off, frag_len; + int i,al; + struct hm_header_st msg_hdr; +- unsigned long overlap; +- +- /* see if we have the required fragment already */ +- if (dtls1_retrieve_buffered_fragment(s, &l)) +- { +- /* compute MAC, remove fragment headers */ +- dtls1_process_handshake_fragment(s, l); +- s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; +- s->state = stn; +- return 1; +- } + +- /* get a handshake fragment from the record layer */ +- p = (unsigned char *)s->init_buf->data; ++ /* see if we have the required fragment already */ ++ if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) ++ { ++ if (*ok) s->init_num += frag_len; ++ return frag_len; ++ } + +- /* read handshake message header */ +- i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num], ++ /* read handshake message header */ ++ i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire, + DTLS1_HM_HEADER_LENGTH, 0); + if (i <= 0) /* nbio, or an error */ + { +@@ -555,130 +633,61 @@ dtls1_get_message_fragment(SSL *s, int s + *ok = 0; + return i; + } +- + OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); + +- p += s->init_num; +- /* parse the message fragment header */ +- +- dtls1_get_message_header(p, &msg_hdr); ++ /* parse the message fragment header */ ++ dtls1_get_message_header(wire, &msg_hdr); + +- /* +- * if this is a future (or stale) message it gets buffered +- * (or dropped)--no further processing at this time +- */ +- if ( msg_hdr.seq != s->d1->handshake_read_seq) +- return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); ++ /* ++ * if this is a future (or stale) message it gets buffered ++ * (or dropped)--no further processing at this time ++ */ ++ if ( msg_hdr.seq != s->d1->handshake_read_seq) ++ return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + +- l = msg_hdr.msg_len; +- frag_off = msg_hdr.frag_off; ++ l = msg_hdr.msg_len; ++ frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + +- /* sanity checking */ +- if ( frag_off + frag_len > l) +- { +- al=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); +- goto f_err; +- } +- + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && +- p[0] == SSL3_MT_HELLO_REQUEST) +- { +- /* The server may always send 'Hello Request' messages -- +- * we are doing a handshake anyway now, so ignore them +- * if their format is correct. Does not count for +- * 'Finished' MAC. */ +- if (p[1] == 0 && p[2] == 0 &&p[3] == 0) +- { +- if (s->msg_callback) +- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, +- p, DTLS1_HM_HEADER_LENGTH, s, +- s->msg_callback_arg); +- +- s->init_num = 0; +- return dtls1_get_message_fragment(s, st1, stn, +- max, ok); +- } +- else /* Incorrectly formated Hello request */ +- { +- al=SSL_AD_UNEXPECTED_MESSAGE; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); +- goto f_err; +- } +- } +- +- /* XDTLS: do a sanity check on the fragment */ +- +- s->init_num += i; +- +- if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ ++ wire[0] == SSL3_MT_HELLO_REQUEST) + { +- /* BUF_MEM_grow takes an 'int' parameter */ +- if (l > (INT_MAX-DTLS1_HM_HEADER_LENGTH)) ++ /* The server may always send 'Hello Request' messages -- ++ * we are doing a handshake anyway now, so ignore them ++ * if their format is correct. Does not count for ++ * 'Finished' MAC. */ ++ if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) + { +- al=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); +- goto f_err; +- } +- if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l +- + DTLS1_HM_HEADER_LENGTH)) +- { +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB); +- goto err; ++ if (s->msg_callback) ++ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, ++ wire, DTLS1_HM_HEADER_LENGTH, s, ++ s->msg_callback_arg); ++ ++ s->init_num = 0; ++ return dtls1_get_message_fragment(s, st1, stn, ++ max, ok); + } +- /* Only do this test when we're reading the expected message. +- * Stale messages will be dropped and future messages will be buffered */ +- if ( l > (unsigned long)max) ++ else /* Incorrectly formated Hello request */ + { +- al=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); ++ al=SSL_AD_UNEXPECTED_MESSAGE; ++ SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } +- +- s->s3->tmp.message_size=l; + } + +- if ( frag_len > (unsigned long)max) +- { +- al=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); +- goto f_err; +- } +- if ( frag_len + s->init_num > (INT_MAX - DTLS1_HM_HEADER_LENGTH)) +- { +- al=SSL_AD_ILLEGAL_PARAMETER; +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); +- goto f_err; +- } +- +- if ( frag_len & !BUF_MEM_grow_clean(s->init_buf, (int)frag_len +- + DTLS1_HM_HEADER_LENGTH + s->init_num)) +- { +- SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB); +- goto err; +- } +- +- if ( s->d1->r_msg_hdr.frag_off == 0) +- { +- s->s3->tmp.message_type = msg_hdr.type; +- s->d1->r_msg_hdr.type = msg_hdr.type; +- s->d1->r_msg_hdr.msg_len = l; +- /* s->d1->r_msg_hdr.seq = seq_num; */ +- } ++ if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) ++ goto f_err; + + /* XDTLS: ressurect this when restart is in place */ + s->state=stn; +- +- /* next state (stn) */ +- p = (unsigned char *)s->init_buf->data; + + if ( frag_len > 0) + { ++ unsigned char *p=s->init_buf->data+DTLS1_HM_HEADER_LENGTH; ++ + i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, +- &p[s->init_num], +- frag_len,0); +- /* XDTLS: fix this--message fragments cannot span multiple packets */ ++ &p[frag_off],frag_len,0); ++ /* XDTLS: fix this--message fragments cannot span multiple packets */ + if (i <= 0) + { + s->rwstate=SSL_READING; +@@ -689,70 +698,23 @@ dtls1_get_message_fragment(SSL *s, int s + else + i = 0; + +- /* XDTLS: an incorrectly formatted fragment should cause the +- * handshake to fail */ ++ /* XDTLS: an incorrectly formatted fragment should cause the ++ * handshake to fail */ + OPENSSL_assert(i == (int)frag_len); + +-#if 0 +- /* Successfully read a fragment. +- * It may be (1) out of order, or +- * (2) it's a repeat, in which case we dump it +- * (3) the one we are expecting next (maybe with overlap) +- * If it is next one, it may overlap with previously read bytes +- */ ++ *ok = 1; + +- /* case (1): buffer the future fragment +- * (we can treat fragments from a future message the same +- * as future fragments from the message being currently read, since +- * they are sematically simply out of order. +- */ +- if ( msg_hdr.seq > s->d1->handshake_read_seq || +- frag_off > s->init_num - DTLS1_HM_HEADER_LENGTH) +- { +- dtls1_buffer_handshake_fragment(s, &msg_hdr); +- return DTLS1_HM_FRAGMENT_RETRY; +- } +- +- /* case (2): drop the entire fragment, and try again */ +- if ( msg_hdr.seq < s->d1->handshake_read_seq || +- frag_off + frag_len < s->init_num - DTLS1_HM_HEADER_LENGTH) +- { +- s->init_num -= DTLS1_HM_HEADER_LENGTH; +- return DTLS1_HM_FRAGMENT_RETRY; +- } +-#endif +- +- /* case (3): received a immediately useful fragment. Determine the +- * possible overlap and copy the fragment. +- */ +- overlap = (s->init_num - DTLS1_HM_HEADER_LENGTH) - frag_off; +- +- /* retain the header for the first fragment */ +- if ( s->init_num > DTLS1_HM_HEADER_LENGTH) +- { +- memmove(&(s->init_buf->data[s->init_num]), +- &(s->init_buf->data[s->init_num + DTLS1_HM_HEADER_LENGTH + overlap]), +- frag_len - overlap); +- +- s->init_num += frag_len - overlap; +- } +- else +- s->init_num += frag_len; +- +- dtls1_process_handshake_fragment(s, frag_len - overlap); +- +- if (s->msg_callback) +- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, +- (size_t)s->init_num, s, +- s->msg_callback_arg); +- *ok=1; +- +- return s->init_num; ++ /* Note that s->init_num is *not* used as current offset in ++ * s->init_buf->data, but as a counter summing up fragments' ++ * lengths: as soon as they sum up to handshake packet ++ * length, we assume we have got all the fragments. */ ++ s->init_num += frag_len; ++ return frag_len; + + f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); +- s->init_num = 0; +-err: ++ s->init_num = 0; ++ + *ok=0; + return(-1); + } +@@ -790,7 +752,7 @@ int dtls1_send_finished(SSL *s, int a, i + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); +- ++ + s->state=b; + } + +@@ -815,10 +777,15 @@ int dtls1_send_change_cipher_spec(SSL *s + p=(unsigned char *)s->init_buf->data; + *p++=SSL3_MT_CCS; + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; +- s->d1->next_handshake_write_seq++; +- s2n(s->d1->handshake_write_seq,p); +- + s->init_num=DTLS1_CCS_HEADER_LENGTH; ++ ++ if (s->client_version == DTLS1_BAD_VER) ++ { ++ s->d1->next_handshake_write_seq++; ++ s2n(s->d1->handshake_write_seq,p); ++ s->init_num+=2; ++ } ++ + s->init_off=0; + + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, +@@ -1044,6 +1011,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) + pitem *item; + hm_fragment *frag; + PQ_64BIT seq64; ++ unsigned int epoch = s->d1->w_epoch; + + /* this function is called immediately after a message has + * been serialized */ +@@ -1056,7 +1024,8 @@ dtls1_buffer_message(SSL *s, int is_ccs) + if ( is_ccs) + { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + +- DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num); ++ DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); ++ epoch++; + } + else + { +@@ -1072,7 +1041,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) + frag->msg_header.is_ccs = is_ccs; + + pq_64bit_init(&seq64); +- pq_64bit_assign_word(&seq64, frag->msg_header.seq); ++ pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq); + + item = pitem_new(seq64, frag); + pq_64bit_free(&seq64); +@@ -1259,5 +1228,4 @@ dtls1_get_ccs_header(unsigned char *data + memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); + + ccs_hdr->type = *(data++); +- n2s(data, ccs_hdr->seq); + } +diff -up openssl-fips-0.9.8f-dev/ssl/d1_clnt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_clnt.c +--- openssl-fips-0.9.8f-dev/ssl/d1_clnt.c.dtls-fixes 2005-12-05 18:32:19.000000000 +0100 ++++ openssl-fips-0.9.8f-dev/ssl/d1_clnt.c 2008-07-15 21:01:29.000000000 +0200 +@@ -214,17 +214,21 @@ int dtls1_connect(SSL *s) + + /* don't push the buffering BIO quite yet */ + +- ssl3_init_finished_mac(s); +- + s->state=SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num=0; ++ /* mark client_random uninitialized */ ++ memset(s->s3->client_random,0,sizeof(s->s3->client_random)); + break; + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + + s->shutdown=0; ++ ++ /* every DTLS ClientHello resets Finished MAC */ ++ ssl3_init_finished_mac(s); ++ + ret=dtls1_client_hello(s); + if (ret <= 0) goto end; + +@@ -422,6 +426,9 @@ int dtls1_connect(SSL *s) + s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; + } + s->init_num=0; ++ /* mark client_random uninitialized */ ++ memset (s->s3->client_random,0,sizeof(s->s3->client_random)); ++ + break; + + case SSL3_ST_CR_FINISHED_A: +@@ -544,9 +551,15 @@ int dtls1_client_hello(SSL *s) + /* else use the pre-loaded session */ + + p=s->s3->client_random; +- Time=(unsigned long)time(NULL); /* Time */ +- l2n(Time,p); +- RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); ++ /* if client_random is initialized, reuse it, we are ++ * required to use same upon reply to HelloVerify */ ++ for (i=0;p[i]=='\0' && is3->client_random);i++) ; ++ if (i==sizeof(s->s3->client_random)) ++ { ++ Time=(unsigned long)time(NULL); /* Time */ ++ l2n(Time,p); ++ RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4); ++ } + + /* Do the message type and length last */ + d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); diff --git a/SOURCES/openssl-fips-0.9.8e-dtls-fixes2.patch b/SOURCES/openssl-fips-0.9.8e-dtls-fixes2.patch new file mode 100644 index 0000000..bbcd816 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-dtls-fixes2.patch @@ -0,0 +1,287 @@ +diff -up openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2 openssl-fips-0.9.8e/ssl/d1_pkt.c +--- openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2 2012-01-16 11:00:34.242797904 +0100 ++++ openssl-fips-0.9.8e/ssl/d1_pkt.c 2012-01-18 15:45:25.144865068 +0100 +@@ -134,7 +134,7 @@ static int dtls1_record_needs_buffering( + unsigned short *priority, unsigned long *offset); + #endif + static int dtls1_buffer_record(SSL *s, record_pqueue *q, +- PQ_64BIT priority); ++ PQ_64BIT *priority); + static int dtls1_process_record(SSL *s); + #if PQ_64BIT_IS_INTEGER + static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); +@@ -156,13 +156,16 @@ dtls1_copy_record(SSL *s, pitem *item) + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); ++ ++ /* Set proper sequence number for mac calculation */ ++ memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); + + return(1); + } + + + static int +-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority) ++dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority) + { + DTLS1_RECORD_DATA *rdata; + pitem *item; +@@ -172,7 +175,7 @@ dtls1_buffer_record(SSL *s, record_pqueu + return 0; + + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); +- item = pitem_new(priority, rdata); ++ item = pitem_new(*priority, rdata); + if (rdata == NULL || item == NULL) + { + if (rdata != NULL) OPENSSL_free(rdata); +@@ -253,9 +256,6 @@ dtls1_process_buffered_records(SSL *s) + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) + { +- DTLS1_RECORD_DATA *rdata; +- rdata = (DTLS1_RECORD_DATA *)item->data; +- + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) + return(1); /* Nothing to do. */ +@@ -267,7 +267,7 @@ dtls1_process_buffered_records(SSL *s) + if ( ! dtls1_process_record(s)) + return(0); + dtls1_buffer_record(s, &(s->d1->processed_rcds), +- s->s3->rrec.seq_num); ++ &s->s3->rrec.seq_num); + } + } + +@@ -328,13 +328,15 @@ dtls1_get_buffered_record(SSL *s) + static int + dtls1_process_record(SSL *s) + { +- int i,al; ++ int al; + int clear=0; + int enc_err; + SSL_SESSION *sess; + SSL3_RECORD *rr; + unsigned int mac_size; + unsigned char md[EVP_MAX_MD_SIZE]; ++ int decryption_failed_or_bad_record_mac = 0; ++ unsigned char *mac = NULL; + + + rr= &(s->s3->rrec); +@@ -369,12 +371,10 @@ dtls1_process_record(SSL *s) + enc_err = s->method->ssl3_enc->enc(s,0); + if (enc_err <= 0) + { +- if (enc_err == 0) +- /* SSLerr() and ssl3_send_alert() have been called */ +- goto err; +- +- /* otherwise enc_err == -1 */ +- goto decryption_failed_or_bad_record_mac; ++ /* To minimize information leaked via timing, we will always ++ * perform all computations before discarding the message. ++ */ ++ decryption_failed_or_bad_record_mac = 1; + } + + #ifdef TLS_DEBUG +@@ -400,28 +400,32 @@ if ( (sess == NULL) || + SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); + goto f_err; + #else +- goto decryption_failed_or_bad_record_mac; ++ decryption_failed_or_bad_record_mac = 1; + #endif + } + /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ +- if (rr->length < mac_size) ++ if (rr->length >= mac_size) + { +-#if 0 /* OK only for stream ciphers */ +- al=SSL_AD_DECODE_ERROR; +- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); +- goto f_err; +-#else +- goto decryption_failed_or_bad_record_mac; +-#endif ++ rr->length -= mac_size; ++ mac = &rr->data[rr->length]; + } +- rr->length-=mac_size; +- i=s->method->ssl3_enc->mac(s,md,0); +- if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) ++ else ++ rr->length = 0; ++ s->method->ssl3_enc->mac(s,md,0); ++ if (mac == NULL || memcmp(md, mac, mac_size) != 0) + { +- goto decryption_failed_or_bad_record_mac; ++ decryption_failed_or_bad_record_mac = 1; + } + } + ++ if (decryption_failed_or_bad_record_mac) ++ { ++ /* decryption failed, silently discard message */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto err; ++ } ++ + /* r->length is now just compressed */ + if (s->expand != NULL) + { +@@ -460,14 +464,6 @@ if ( (sess == NULL) || + dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ + return(1); + +-decryption_failed_or_bad_record_mac: +- /* Separate 'decryption_failed' alert was introduced with TLS 1.0, +- * SSL 3.0 only has 'bad_record_mac'. But unless a decryption +- * failure is directly visible from the ciphertext anyway, +- * we should not reveal which kind of error occured -- this +- * might become visible to an attacker (e.g. via logfile) */ +- al=SSL_AD_BAD_RECORD_MAC; +- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + err: +@@ -486,22 +482,19 @@ err: + /* used only by dtls1_read_bytes */ + int dtls1_get_record(SSL *s) + { +- int ssl_major,ssl_minor,al; ++ int ssl_major,ssl_minor; + int i,n; + SSL3_RECORD *rr; +- SSL_SESSION *sess; +- unsigned char *p; ++ unsigned char *p = NULL; + unsigned short version; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + + rr= &(s->s3->rrec); +- sess=s->session; + + /* The epoch may have changed. If so, process all the + * pending records. This is a non-blocking operation. */ +- if ( ! dtls1_process_buffered_records(s)) +- return 0; ++ dtls1_process_buffered_records(s); + + /* if we're renegotiating, then there may be buffered records */ + if (dtls1_get_processed_record(s)) +@@ -517,7 +510,12 @@ again: + /* read timeout is handled by dtls1_read_bytes */ + if (n <= 0) return(n); /* error or non-blocking */ + +- OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH); ++ /* this packet contained a partial record, dump it */ ++ if (s->packet_length != DTLS1_RT_HEADER_LENGTH) ++ { ++ s->packet_length = 0; ++ goto again; ++ } + + s->rstate=SSL_ST_READ_BODY; + +@@ -542,27 +540,28 @@ again: + { + if (version != s->version && version != DTLS1_BAD_VER) + { +- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); +- /* Send back error using their +- * version number :-) */ +- s->version=version; +- al=SSL_AD_PROTOCOL_VERSION; +- goto f_err; ++ /* unexpected version, silently discard */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto again; + } + } + + if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && + (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) + { +- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); +- goto err; ++ /* wrong version, silently discard record */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto again; + } + + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) + { +- al=SSL_AD_RECORD_OVERFLOW; +- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); +- goto f_err; ++ /* record too long, silently discard it */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto again; + } + + s->client_version = version; +@@ -581,6 +580,7 @@ again: + /* this packet contained a partial record, dump it */ + if ( n != i) + { ++ rr->length = 0; + s->packet_length = 0; + goto again; + } +@@ -594,6 +594,7 @@ again: + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if ( bitmap == NULL) + { ++ rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +@@ -601,6 +602,7 @@ again: + /* check whether this is a repeat, or aged record */ + if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) + { ++ rr->length = 0; + s->packet_length=0; /* dump this record */ + goto again; /* get another record */ + } +@@ -615,21 +617,22 @@ again: + if (is_next_epoch) + { + dtls1_record_bitmap_update(s, bitmap); +- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); ++ dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); ++ rr->length = 0; + s->packet_length = 0; + goto again; + } + +- if ( ! dtls1_process_record(s)) +- return(0); ++ if (!dtls1_process_record(s)) ++ { ++ rr->length = 0; ++ s->packet_length=0; /* dump this record */ ++ goto again; /* get another record */ ++ } + + dtls1_clear_timeouts(s); /* done waiting */ + return(1); + +-f_err: +- ssl3_send_alert(s,SSL3_AL_FATAL,al); +-err: +- return(0); + } + + /* Return up to 'len' payload bytes received in 'type' records. diff --git a/SOURCES/openssl-fips-0.9.8e-enginesdir.patch b/SOURCES/openssl-fips-0.9.8e-enginesdir.patch new file mode 100644 index 0000000..59b9839 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-enginesdir.patch @@ -0,0 +1,40 @@ +diff -up openssl-fips-0.9.8e/Configure.enginesdir openssl-fips-0.9.8e/Configure +--- openssl-fips-0.9.8e/Configure.enginesdir 2010-04-16 17:38:40.000000000 +0200 ++++ openssl-fips-0.9.8e/Configure 2010-04-16 17:38:40.000000000 +0200 +@@ -564,6 +564,7 @@ my $idx_arflags = $idx++; + + my $prefix=""; + my $openssldir=""; ++my $enginesdir=""; + my $exe_ext=""; + my $install_prefix=""; + my $fipslibdir="/usr/local/ssl/lib/fips-1.0/"; +@@ -778,6 +779,10 @@ PROCESS_ARGS: + { + $openssldir=$1; + } ++ elsif (/^--enginesdir=(.*)$/) ++ { ++ $enginesdir=$1; ++ } + elsif (/^--install.prefix=(.*)$/) + { + $install_prefix=$1; +@@ -1027,7 +1032,7 @@ chop $prefix if $prefix =~ /\/$/; + + $openssldir=$prefix . "/ssl" if $openssldir eq ""; + $openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^\/|^[a-zA-Z]:[\\\/])/; +- ++$enginesdir="$prefix/lib/engines" if $enginesdir eq ""; + + print "IsMK1MF=$IsMK1MF\n"; + +@@ -1571,7 +1576,7 @@ while () + if (/^#define\s+OPENSSLDIR/) + { print OUT "#define OPENSSLDIR \"$openssldir\"\n"; } + elsif (/^#define\s+ENGINESDIR/) +- { print OUT "#define ENGINESDIR \"$prefix/lib/engines\"\n"; } ++ { print OUT "#define ENGINESDIR \"$enginesdir\"\n"; } + elsif (/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/) + { printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n" + if $export_var_as_fn; diff --git a/SOURCES/openssl-fips-0.9.8e-env-zlib.patch b/SOURCES/openssl-fips-0.9.8e-env-zlib.patch new file mode 100644 index 0000000..9534a72 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-env-zlib.patch @@ -0,0 +1,66 @@ +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib 2003-11-29 11:33:25.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod 2013-07-17 12:30:39.390891366 +0200 +@@ -47,6 +47,13 @@ Once the identities of the compression m + been standardized, the compression API will most likely be changed. Using + it in the current state is not recommended. + ++It is also not recommended to use compression if data transfered contain ++untrusted parts that can be manipulated by an attacker as he could then ++get information about the encrypted data. See the CRIME attack. For ++that reason the default loading of the zlib compression method is ++disabled and enabled only if the environment variable B ++is present during the library initialization. ++ + =head1 RETURN VALUES + + SSL_COMP_add_compression_method() may return the following values: +diff -up openssl-fips-0.9.8e/README.env-zlib openssl-fips-0.9.8e/README +--- openssl-fips-0.9.8e/README.env-zlib 2007-03-22 01:37:41.000000000 +0100 ++++ openssl-fips-0.9.8e/README 2013-07-17 12:30:39.390891366 +0200 +@@ -8,8 +8,22 @@ + WARNING + ------- + +- This version of OpenSSL is an initial port of the FIPS 140-2 code to OpenSSL +- 0.9.8. See the file README.FIPS for brief usage details. ++ This version of OpenSSL is based on upstream openssl-fips-1.2.0 code ++ which is also undergoing FIPS validation. ++ ++ However this version contains a few differences from the upstream code ++ some of which are: ++ * The module respects the kernel FIPS flag /proc/sys/crypto/fips and ++ tries to initialize the FIPS mode if it is set to 1 aborting if the ++ FIPS mode could not be initialized. It is also possible to force the ++ OpenSSL library to FIPS mode especially for debugging purposes by ++ setting the environment variable OPENSSL_FORCE_FIPS_MODE. ++ * If the environment variable OPENSSL_DEFAULT_ZLIB is set the module ++ will automatically load the built in compression method ZLIB ++ when initialized. Applications can still explicitely ask for ZLIB ++ compression method with API calls. Otherwise the compression is not ++ loaded and used due to protocol vulnerability as described in the ++ CRIME attack. + + DESCRIPTION + ----------- +diff -up openssl-fips-0.9.8e/ssl/ssl_ciph.c.env-zlib openssl-fips-0.9.8e/ssl/ssl_ciph.c +--- openssl-fips-0.9.8e/ssl/ssl_ciph.c.env-zlib 2007-08-13 20:35:04.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl_ciph.c 2013-07-17 12:31:22.855061684 +0200 +@@ -113,6 +113,8 @@ + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -284,7 +286,7 @@ static void load_builtin_compressions(vo + + MemCheck_off(); + ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp); +- if (ssl_comp_methods != NULL) ++ if (ssl_comp_methods != NULL && secure_getenv("OPENSSL_DEFAULT_ZLIB") != NULL) + { + comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp != NULL) diff --git a/SOURCES/openssl-fips-0.9.8e-evp-nonfips.patch b/SOURCES/openssl-fips-0.9.8e-evp-nonfips.patch new file mode 100644 index 0000000..0870195 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-evp-nonfips.patch @@ -0,0 +1,154 @@ +diff -up openssl-fips-0.9.8e/crypto/engine/eng_all.c.nonfips openssl-fips-0.9.8e/crypto/engine/eng_all.c +--- openssl-fips-0.9.8e/crypto/engine/eng_all.c.nonfips 2009-04-15 14:26:12.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/engine/eng_all.c 2009-04-15 14:24:20.000000000 +0200 +@@ -58,9 +58,23 @@ + + #include "cryptlib.h" + #include "eng_int.h" ++#ifdef OPENSSL_FIPS ++#include ++#endif + + void ENGINE_load_builtin_engines(void) + { ++#ifdef OPENSSL_FIPS ++ OPENSSL_init(); ++ if (FIPS_mode()) { ++ /* We allow loading dynamic engine as a third party ++ engine might be FIPS validated. ++ User is disallowed to load non-validated engines ++ by security policy. */ ++ ENGINE_load_dynamic(); ++ return; ++ } ++#endif + /* There's no longer any need for an "openssl" ENGINE unless, one day, + * it is the *only* way for standard builtin implementations to be be + * accessed (ie. it would be possible to statically link binaries with +diff -up openssl-fips-0.9.8e/crypto/evp/c_allc.c.nonfips openssl-fips-0.9.8e/crypto/evp/c_allc.c +--- openssl-fips-0.9.8e/crypto/evp/c_allc.c.nonfips 2007-04-24 13:30:34.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/c_allc.c 2009-04-15 13:48:51.000000000 +0200 +@@ -65,6 +65,11 @@ + void OpenSSL_add_all_ciphers(void) + { + ++#ifdef OPENSSL_FIPS ++ OPENSSL_init(); ++ if(!FIPS_mode()) ++ { ++#endif + #ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cfb()); + EVP_add_cipher(EVP_des_cfb1()); +@@ -219,6 +224,63 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256"); + EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256"); + #endif ++#ifdef OPENSSL_FIPS ++ } ++ else ++ { ++#ifndef OPENSSL_NO_DES ++ EVP_add_cipher(EVP_des_ede_cfb()); ++ EVP_add_cipher(EVP_des_ede3_cfb()); ++ ++ EVP_add_cipher(EVP_des_ede_ofb()); ++ EVP_add_cipher(EVP_des_ede3_ofb()); ++ ++ EVP_add_cipher(EVP_des_ede_cbc()); ++ EVP_add_cipher(EVP_des_ede3_cbc()); ++ EVP_add_cipher_alias(SN_des_ede3_cbc,"DES3"); ++ EVP_add_cipher_alias(SN_des_ede3_cbc,"des3"); ++ ++ EVP_add_cipher(EVP_des_ede()); ++ EVP_add_cipher(EVP_des_ede3()); ++#endif ++ ++#ifndef OPENSSL_NO_AES ++ EVP_add_cipher(EVP_aes_128_ecb()); ++ EVP_add_cipher(EVP_aes_128_cbc()); ++ EVP_add_cipher(EVP_aes_128_cfb()); ++ EVP_add_cipher(EVP_aes_128_cfb1()); ++ EVP_add_cipher(EVP_aes_128_cfb8()); ++ EVP_add_cipher(EVP_aes_128_ofb()); ++#if 0 ++ EVP_add_cipher(EVP_aes_128_ctr()); ++#endif ++ EVP_add_cipher_alias(SN_aes_128_cbc,"AES128"); ++ EVP_add_cipher_alias(SN_aes_128_cbc,"aes128"); ++ EVP_add_cipher(EVP_aes_192_ecb()); ++ EVP_add_cipher(EVP_aes_192_cbc()); ++ EVP_add_cipher(EVP_aes_192_cfb()); ++ EVP_add_cipher(EVP_aes_192_cfb1()); ++ EVP_add_cipher(EVP_aes_192_cfb8()); ++ EVP_add_cipher(EVP_aes_192_ofb()); ++#if 0 ++ EVP_add_cipher(EVP_aes_192_ctr()); ++#endif ++ EVP_add_cipher_alias(SN_aes_192_cbc,"AES192"); ++ EVP_add_cipher_alias(SN_aes_192_cbc,"aes192"); ++ EVP_add_cipher(EVP_aes_256_ecb()); ++ EVP_add_cipher(EVP_aes_256_cbc()); ++ EVP_add_cipher(EVP_aes_256_cfb()); ++ EVP_add_cipher(EVP_aes_256_cfb1()); ++ EVP_add_cipher(EVP_aes_256_cfb8()); ++ EVP_add_cipher(EVP_aes_256_ofb()); ++#if 0 ++ EVP_add_cipher(EVP_aes_256_ctr()); ++#endif ++ EVP_add_cipher_alias(SN_aes_256_cbc,"AES256"); ++ EVP_add_cipher_alias(SN_aes_256_cbc,"aes256"); ++#endif ++ } ++#endif + + PKCS12_PBE_add(); + PKCS5_PBE_add(); +diff -up openssl-fips-0.9.8e/crypto/evp/c_alld.c.nonfips openssl-fips-0.9.8e/crypto/evp/c_alld.c +--- openssl-fips-0.9.8e/crypto/evp/c_alld.c.nonfips 2005-04-30 23:51:40.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/evp/c_alld.c 2009-04-15 13:48:51.000000000 +0200 +@@ -64,6 +64,11 @@ + + void OpenSSL_add_all_digests(void) + { ++#ifdef OPENSSL_FIPS ++ OPENSSL_init(); ++ if (!FIPS_mode()) ++ { ++#endif + #ifndef OPENSSL_NO_MD2 + EVP_add_digest(EVP_md2()); + #endif +@@ -111,4 +116,32 @@ void OpenSSL_add_all_digests(void) + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); + #endif ++#ifdef OPENSSL_FIPS ++ } ++ else ++ { ++#ifndef OPENSSL_NO_SHA ++ EVP_add_digest(EVP_sha1()); ++ EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); ++ EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); ++#ifndef OPENSSL_NO_DSA ++ EVP_add_digest(EVP_dss1()); ++ EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); ++ EVP_add_digest_alias(SN_dsaWithSHA1,"DSS1"); ++ EVP_add_digest_alias(SN_dsaWithSHA1,"dss1"); ++#endif ++#ifndef OPENSSL_NO_ECDSA ++ EVP_add_digest(EVP_ecdsa()); ++#endif ++#endif ++#ifndef OPENSSL_NO_SHA256 ++ EVP_add_digest(EVP_sha224()); ++ EVP_add_digest(EVP_sha256()); ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ EVP_add_digest(EVP_sha384()); ++ EVP_add_digest(EVP_sha512()); ++#endif ++ } ++#endif + } diff --git a/SOURCES/openssl-fips-0.9.8e-fipsmode.patch b/SOURCES/openssl-fips-0.9.8e-fipsmode.patch new file mode 100644 index 0000000..768c19c --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-fipsmode.patch @@ -0,0 +1,74 @@ +diff -up openssl-fips-0.9.8e/crypto/o_init.c.fipsmode openssl-fips-0.9.8e/crypto/o_init.c +--- openssl-fips-0.9.8e/crypto/o_init.c.fipsmode 2007-07-01 02:07:22.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/o_init.c 2009-04-15 13:48:51.000000000 +0200 +@@ -59,6 +59,45 @@ + #include + #include + ++#ifdef OPENSSL_FIPS ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" ++ ++static void init_fips_mode(void) ++ { ++ char buf[2] = "0"; ++ int fd; ++ ++ if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) ++ { ++ buf[0] = '1'; ++ } ++ else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) ++ { ++ while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); ++ close(fd); ++ } ++ /* Failure reading the fips mode switch file means just not ++ * switching into FIPS mode. We would break too many things ++ * otherwise. ++ */ ++ ++ if (buf[0] == '1') ++ { ++ FIPS_mode_set(1); ++ } ++ } ++#endif ++ + /* Perform any essential OpenSSL initialization operations. + * Currently only sets FIPS callbacks + */ +@@ -73,11 +112,10 @@ void OPENSSL_init(void) + #ifdef CRYPTO_MDEBUG + CRYPTO_malloc_debug_init(); + #endif +-#ifdef OPENSSL_ENGINE ++ init_fips_mode(); + int_EVP_MD_init_engine_callbacks(); + int_EVP_CIPHER_init_engine_callbacks(); + int_RAND_init_engine_callbacks(); +-#endif + done = 1; + } + #endif +diff -up openssl-fips-0.9.8e/ssl/ssl_algs.c.fipsmode openssl-fips-0.9.8e/ssl/ssl_algs.c +--- openssl-fips-0.9.8e/ssl/ssl_algs.c.fipsmode 2007-04-24 13:30:48.000000000 +0200 ++++ openssl-fips-0.9.8e/ssl/ssl_algs.c 2009-04-15 14:09:42.000000000 +0200 +@@ -64,6 +64,8 @@ + int SSL_library_init(void) + { + ++ OPENSSL_init(); ++ + #ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); diff --git a/SOURCES/openssl-fips-0.9.8e-ia64.patch b/SOURCES/openssl-fips-0.9.8e-ia64.patch new file mode 100644 index 0000000..d8c69cf --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-ia64.patch @@ -0,0 +1,19 @@ +diff -up openssl-fips-0.9.8e/crypto/bn/bn_lcl.h.ia64 openssl-fips-0.9.8e/crypto/bn/bn_lcl.h +--- openssl-fips-0.9.8e/crypto/bn/bn_lcl.h.ia64 2010-04-16 18:15:11.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/bn/bn_lcl.h 2010-04-16 18:15:11.000000000 +0200 +@@ -279,6 +279,15 @@ extern "C" { + # define BN_UMULT_HIGH(a,b) __umulh((a),(b)) + # define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high))) + # endif ++# elif defined(__ia64) && defined(SIXTY_FOUR_BIT_LONG) ++# if defined(__GNUC__) ++# define BN_UMULT_HIGH(a,b) ({ \ ++ register BN_ULONG ret; \ ++ asm ("xmpy.hu %0 = %1, %2" \ ++ : "=f"(ret) \ ++ : "f"(a), "f"(b)); \ ++ ret; }) ++# endif /* compiler */ + # endif /* cpu */ + #endif /* OPENSSL_NO_ASM */ + diff --git a/SOURCES/openssl-fips-0.9.8e-manfix.patch b/SOURCES/openssl-fips-0.9.8e-manfix.patch new file mode 100644 index 0000000..4cc47e4 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-manfix.patch @@ -0,0 +1,344 @@ +diff -up openssl-fips-0.9.8e/doc/apps/openssl.pod.manfix openssl-fips-0.9.8e/doc/apps/openssl.pod +--- openssl-fips-0.9.8e/doc/apps/openssl.pod.manfix 2007-09-19 02:02:45.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/apps/openssl.pod 2013-07-17 16:53:35.344845801 +0200 +@@ -125,7 +125,7 @@ Generation of RSA Parameters. + + Online Certificate Status Protocol utility. + +-=item L|passwd(1)> ++=item L|sslpasswd(1)> + + Generation of hashed passwords. + +@@ -137,7 +137,7 @@ PKCS#12 Data Management. + + PKCS#7 Data Management. + +-=item L|rand(1)> ++=item L|sslrand(1)> + + Generate pseudo-random bytes. + +@@ -341,9 +341,9 @@ L, L, L, L, + L, L, + L, L, L, +-L, ++L, + L, L, L, +-L, L, L, ++L, L, L, + L, L, + L, L, + L, L, +diff -up openssl-fips-0.9.8e/doc/apps/smime.pod.manfix openssl-fips-0.9.8e/doc/apps/smime.pod +--- openssl-fips-0.9.8e/doc/apps/smime.pod.manfix 2006-06-09 17:42:16.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/apps/smime.pod 2013-07-17 16:53:35.345845817 +0200 +@@ -265,28 +265,28 @@ encrypted data is used for other purpose + + =over 4 + +-=item 0 ++=item C<0> + + the operation was completely successfully. + +-=item 1 ++=item C<1> + + an error occurred parsing the command options. + +-=item 2 ++=item C<2> + + one of the input files could not be read. + +-=item 3 ++=item C<3> + + an error occurred creating the PKCS#7 file or when reading the MIME + message. + +-=item 4 ++=item C<4> + + an error occurred decrypting or verifying the message. + +-=item 5 ++=item C<5> + + the message was verified correctly but an error occurred writing out + the signers certificates. +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_accept.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_accept.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_accept.pod.manfix 2003-06-03 11:59:44.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_accept.pod 2013-07-17 16:57:03.617836245 +0200 +@@ -44,12 +44,12 @@ The following return values can occur: + + =over 4 + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_clear.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_clear.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_clear.pod.manfix 2002-02-27 09:08:57.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_clear.pod 2013-07-17 16:53:35.349845898 +0200 +@@ -50,12 +50,12 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The SSL_clear() operation could not be performed. Check the error stack to + find out the reason. + +-=item 1 ++=item C<1> + + The SSL_clear() operation was successful. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod.manfix 2013-07-17 12:30:39.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_COMP_add_compression_method.pod 2013-07-17 16:53:35.349845898 +0200 +@@ -60,11 +60,11 @@ SSL_COMP_add_compression_method() may re + + =over 4 + +-=item 0 ++=item C<0> + + The operation succeeded. + +-=item 1 ++=item C<1> + + The operation failed. Check the error queue to find out the reason. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_connect.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_connect.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_connect.pod.manfix 2003-06-03 11:59:44.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_connect.pod 2013-07-17 16:56:43.854426631 +0200 +@@ -41,12 +41,12 @@ The following return values can occur: + + =over 4 + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_add_session.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_CTX_add_session.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_add_session.pod.manfix 2002-10-29 01:33:01.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_add_session.pod 2013-07-17 16:53:35.353845983 +0200 +@@ -52,13 +52,13 @@ The following values are returned by all + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed. In case of the add operation, it was tried to add + the same (identical) session twice. In case of the remove operation, the + session was not found in the cache. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_load_verify_locations.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_CTX_load_verify_locations.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_load_verify_locations.pod.manfix 2001-09-07 08:13:39.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_load_verify_locations.pod 2013-07-17 16:53:35.354846005 +0200 +@@ -100,13 +100,13 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed because B and B are NULL or the + processing at one of the locations specified failed. Check the error + stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_client_CA_list.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_client_CA_list.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_client_CA_list.pod.manfix 2001-04-12 18:02:34.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_client_CA_list.pod 2013-07-17 16:54:37.273839574 +0200 +@@ -66,11 +66,11 @@ values: + + =over 4 + +-=item 1 ++=item C<1> + + The operation succeeded. + +-=item 0 ++=item C<0> + + A failure while manipulating the STACK_OF(X509_NAME) object occurred or + the X509_NAME could not be extracted from B. Check the error stack +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_session_id_context.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_session_id_context.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_session_id_context.pod.manfix 2004-06-14 15:27:28.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_session_id_context.pod 2013-07-17 16:53:35.358846090 +0200 +@@ -64,13 +64,13 @@ return the following values: + + =over 4 + +-=item 0 ++=item C<0> + + The length B of the session id context B exceeded + the maximum allowed length of B. The error + is logged to the error stack. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_ssl_version.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_ssl_version.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_ssl_version.pod.manfix 2001-03-08 18:24:01.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_CTX_set_ssl_version.pod 2013-07-17 16:53:35.360846132 +0200 +@@ -42,11 +42,11 @@ and SSL_set_ssl_method(): + + =over 4 + +-=item 0 ++=item C<0> + + The new choice failed, check the error stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_do_handshake.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_do_handshake.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_do_handshake.pod.manfix 2002-07-19 13:05:49.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_do_handshake.pod 2013-07-17 16:55:03.530386725 +0200 +@@ -45,12 +45,12 @@ The following return values can occur: + + =over 4 + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_read.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_read.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_read.pod.manfix 2001-09-13 15:21:38.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_read.pod 2013-07-17 16:53:45.846069565 +0200 +@@ -81,7 +81,7 @@ The following return values can occur: + The read operation was successful; the return value is the number of + bytes actually read from the TLS/SSL connection. + +-=item 0 ++=item C<0> + + The read operation was not successful. The reason may either be a clean + shutdown due to a "close notify" alert sent by the peer (in which case +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_session_reused.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_session_reused.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_session_reused.pod.manfix 2001-07-20 20:57:15.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_session_reused.pod 2013-07-17 16:53:45.848069608 +0200 +@@ -27,11 +27,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + A new session was negotiated. + +-=item 1 ++=item C<1> + + A session was reused. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_set_fd.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_set_fd.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_set_fd.pod.manfix 2000-09-16 18:00:38.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_set_fd.pod 2013-07-17 16:53:45.849069630 +0200 +@@ -35,11 +35,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed. Check the error stack to find out why. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_set_session.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_set_session.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_set_session.pod.manfix 2001-10-12 14:29:16.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_set_session.pod 2013-07-17 16:53:45.851069674 +0200 +@@ -37,11 +37,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed; check the error stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_shutdown.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_shutdown.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_shutdown.pod.manfix 2004-11-14 14:55:16.000000000 +0100 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_shutdown.pod 2013-07-17 16:56:04.569658682 +0200 +@@ -92,12 +92,12 @@ The following return values can occur: + + =over 4 + +-=item 1 ++=item C<1> + + The shutdown was successfully completed. The "close notify" alert was sent + and the peer's "close notify" alert was received. + +-=item 0 ++=item C<0> + + The shutdown is not yet finished. Call SSL_shutdown() for a second time, + if a bidirectional shutdown shall be performed. +diff -up openssl-fips-0.9.8e/doc/ssl/SSL_write.pod.manfix openssl-fips-0.9.8e/doc/ssl/SSL_write.pod +--- openssl-fips-0.9.8e/doc/ssl/SSL_write.pod.manfix 2002-07-19 13:53:54.000000000 +0200 ++++ openssl-fips-0.9.8e/doc/ssl/SSL_write.pod 2013-07-17 16:53:45.854069737 +0200 +@@ -79,7 +79,7 @@ The following return values can occur: + The write operation was successful, the return value is the number of + bytes actually written to the TLS/SSL connection. + +-=item 0 ++=item C<0> + + The write operation was not successful. Probably the underlying connection + was closed. Call SSL_get_error() with the return value B to find out, diff --git a/SOURCES/openssl-fips-0.9.8e-multi-crl.patch b/SOURCES/openssl-fips-0.9.8e-multi-crl.patch new file mode 100644 index 0000000..64e8579 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-multi-crl.patch @@ -0,0 +1,90 @@ +diff -up openssl-fips-0.9.8e/crypto/x509/x509_lu.c.multi-crl openssl-fips-0.9.8e/crypto/x509/x509_lu.c +--- openssl-fips-0.9.8e/crypto/x509/x509_lu.c.multi-crl 2005-05-11 05:45:35.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/x509_lu.c 2009-03-26 15:09:49.000000000 +0100 +@@ -453,19 +453,41 @@ X509_OBJECT *X509_OBJECT_retrieve_by_sub + return sk_X509_OBJECT_value(h, idx); + } + ++static int x509_crl_match(const X509_CRL *a, const X509_CRL *b) ++{ ++ if (a->signature == NULL || b->signature == NULL) ++ return a->signature != b->signature; ++ ++ if (a->signature->length != b->signature->length) ++ return 0; ++ ++ return memcmp(a->signature->data, b->signature->data, a->signature->length); ++} ++ + X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) + { + int idx, i; + X509_OBJECT *obj; + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) return NULL; +- if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); ++ if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) ++ return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) + { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) + return NULL; +- if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) ++ if (x->type == X509_LU_X509) ++ { ++ if (!X509_cmp(obj->data.x509, x->data.x509)) ++ return obj; ++ } ++ else if (x->type == X509_LU_CRL) ++ { ++ if (!x509_crl_match(obj->data.crl, x->data.crl)) ++ return obj; ++ } ++ else + return obj; + } + return NULL; +diff -up openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.multi-crl openssl-fips-0.9.8e/crypto/x509/x509_vfy.c +--- openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.multi-crl 2007-02-07 02:42:51.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/x509/x509_vfy.c 2009-03-26 15:00:05.000000000 +0100 +@@ -721,7 +721,38 @@ static int get_crl(X509_STORE_CTX *ctx, + return 0; + } + +- *pcrl = xobj.data.crl; ++ /* If CRL times not valid look through store */ ++ if (!check_crl_time(ctx, xobj.data.crl, 0)) ++ { ++ int idx, i; ++ X509_OBJECT *pobj; ++ X509_OBJECT_free_contents(&xobj); ++ idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, ++ X509_LU_CRL, nm); ++ if (idx == -1) ++ return 0; ++ *pcrl = NULL; ++ for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) ++ { ++ pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); ++ /* Check to see if it is a CRL and issuer matches */ ++ if (pobj->type != X509_LU_CRL) ++ break; ++ if (X509_NAME_cmp(nm, ++ X509_CRL_get_issuer(pobj->data.crl))) ++ break; ++ /* Set *pcrl because the CRL will either be valid or ++ * a "best fit" CRL. ++ */ ++ *pcrl = pobj->data.crl; ++ if (check_crl_time(ctx, *pcrl, 0)) ++ break; ++ } ++ if (*pcrl) ++ CRYPTO_add(&(*pcrl)->references, 1, CRYPTO_LOCK_X509); ++ } ++ else ++ *pcrl = xobj.data.crl; + if (crl) + X509_CRL_free(crl); + return 1; diff --git a/SOURCES/openssl-fips-0.9.8e-no-pairwise.patch b/SOURCES/openssl-fips-0.9.8e-no-pairwise.patch new file mode 100644 index 0000000..32c8811 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-no-pairwise.patch @@ -0,0 +1,26 @@ +Do not call pairwise tests in non-fips mode. +Some possible generated keys might be too small to pass. +diff -up openssl-fips-0.9.8e/fips/dsa/fips_dsa_key.c.no-pairwise openssl-fips-0.9.8e/fips/dsa/fips_dsa_key.c +--- openssl-fips-0.9.8e/fips/dsa/fips_dsa_key.c.no-pairwise 2007-09-12 19:46:04.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/dsa/fips_dsa_key.c 2009-04-15 11:21:07.000000000 +0200 +@@ -154,7 +154,7 @@ static int dsa_builtin_keygen(DSA *dsa) + dsa->pub_key=pub_key; + if (fips_dsa_pairwise_fail) + BN_add_word(dsa->pub_key, 1); +- if(!fips_check_dsa(dsa)) ++ if(FIPS_mode() && !fips_check_dsa(dsa)) + goto err; + ok=1; + +diff -up openssl-fips-0.9.8e/fips/rsa/fips_rsa_gen.c.no-pairwise openssl-fips-0.9.8e/fips/rsa/fips_rsa_gen.c +--- openssl-fips-0.9.8e/fips/rsa/fips_rsa_gen.c.no-pairwise 2007-09-12 19:46:07.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/rsa/fips_rsa_gen.c 2009-04-15 11:21:31.000000000 +0200 +@@ -288,7 +288,7 @@ static int rsa_builtin_keygen(RSA *rsa, + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + +- if(!fips_check_rsa(rsa)) ++ if(FIPS_mode() && !fips_check_rsa(rsa)) + goto err; + + ok=1; diff --git a/SOURCES/openssl-fips-0.9.8e-perlfind.patch b/SOURCES/openssl-fips-0.9.8e-perlfind.patch new file mode 100644 index 0000000..1211047 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-perlfind.patch @@ -0,0 +1,16 @@ +diff -up openssl-fips-0.9.8e/util/perlpath.pl.perlfind openssl-fips-0.9.8e/util/perlpath.pl +--- openssl-fips-0.9.8e/util/perlpath.pl.perlfind 2013-07-17 11:47:59.977820958 +0200 ++++ openssl-fips-0.9.8e/util/perlpath.pl 2013-07-17 12:12:37.997614805 +0200 +@@ -4,10 +4,10 @@ + # line in all scripts that rely on perl. + # + +-require "find.pl"; ++use File::Find; + + $#ARGV == 0 || print STDERR "usage: perlpath newpath (eg /usr/bin)\n"; +-&find("."); ++find(\&wanted, "."); + + sub wanted + { diff --git a/SOURCES/openssl-fips-0.9.8e-redhat.patch b/SOURCES/openssl-fips-0.9.8e-redhat.patch new file mode 100644 index 0000000..76196e9 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-redhat.patch @@ -0,0 +1,55 @@ +diff -up openssl-fips-0.9.8f-dev/Configure.redhat openssl-fips-0.9.8f-dev/Configure +--- openssl-fips-0.9.8f-dev/Configure.redhat 2007-09-19 02:01:58.000000000 +0200 ++++ openssl-fips-0.9.8f-dev/Configure 2008-07-15 19:09:47.000000000 +0200 +@@ -317,29 +317,28 @@ my %table=( + #### + # *-generic* is endian-neutral target, but ./config is free to + # throw in -D[BL]_ENDIAN, whichever appropriate... +-"linux-generic32","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-ppc", "gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-generic32","gcc:-DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-ppc", "gcc:-DB_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc32.o::::::::::dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + #### IA-32 targets... + "linux-ia32-icc", "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-aout", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}", ++"linux-elf", "gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-aout", "gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}", + #### +-"linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-ppc64", "gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-generic64","gcc:-DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-ppc64", "gcc:-DB_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc64.o::::::::::dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + "linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + "linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-x86_64", "gcc:-DL_ENDIAN -DTERMIO -Wall -DMD32_REG_T=int \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + #### SPARC Linux setups + # Ray Miller has patiently + # assisted with debugging of following two configs. +-"linux-sparcv8","gcc:-mv8 -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparcv8","gcc:-DB_ENDIAN -DTERMIO -Wall -DBN_DIV2W \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + # it's a real mess with -mcpu=ultrasparc option under Linux, but + # -Wa,-Av8plus should do the trick no matter what. +-"linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparcv9","gcc:-DB_ENDIAN -DTERMIO -Wall -Wa,-Av8plus -DBN_DIV2W \$(RPM_OPT_FLAGS)::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::sparcv8plus.o:des_enc-sparc.o fcrypt_b.o:::md5-sparcv8plus.o::::::dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + # GCC 3.1 is a requirement +-"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:ULTRASPARC:-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux64-sparcv9","gcc:-DB_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT:ULTRASPARC:-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::des_enc-sparc.o fcrypt_b.o:::md5-sparcv9.o::::::dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + #### Alpha Linux with GNU C and Compaq C setups + # Special notes: + # - linux-alpha+bwx-gcc is ment to be used from ./config only. If you +@@ -353,8 +352,8 @@ my %table=( + # + # + # +-"linux-alpha-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-alpha+bwx-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-alpha-gcc","gcc:-DL_ENDIAN -DTERMIO -mcpu=ev5 \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-alpha+bwx-gcc","gcc:-DL_ENDIAN -DTERMIO -mcpu=ev5 \$(RPM_OPT_FLAGS)::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + "linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${no_asm}", + "linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${no_asm}", + diff --git a/SOURCES/openssl-fips-0.9.8e-rng-seed.patch b/SOURCES/openssl-fips-0.9.8e-rng-seed.patch new file mode 100644 index 0000000..6fa8975 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-rng-seed.patch @@ -0,0 +1,76 @@ +Seed the FIPS rng directly from the kernel random device. +diff -up openssl-fips-0.9.8e/crypto/rand/rand_lcl.h.rng-seed openssl-fips-0.9.8e/crypto/rand/rand_lcl.h +--- openssl-fips-0.9.8e/crypto/rand/rand_lcl.h.rng-seed 2009-04-15 13:48:50.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/rand/rand_lcl.h 2009-04-15 13:48:51.000000000 +0200 +@@ -112,7 +112,7 @@ + #ifndef HEADER_RAND_LCL_H + #define HEADER_RAND_LCL_H + +-#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ ++#define ENTROPY_NEEDED 48 /* we need 48 bytes of randomness for FIPS rng */ + + + #if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) +diff -up openssl-fips-0.9.8e/fips/fips.c.rng-seed openssl-fips-0.9.8e/fips/fips.c +--- openssl-fips-0.9.8e/fips/fips.c.rng-seed 2009-04-15 13:48:51.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/fips.c 2009-04-15 13:48:51.000000000 +0200 +@@ -508,22 +508,22 @@ int FIPS_mode_set(int onoff) + goto end; + } + ++ /* now switch into FIPS mode */ ++ fips_set_rand_check(FIPS_rand_method()); ++ RAND_set_rand_method(FIPS_rand_method()); ++ + /* automagically seed PRNG if not already seeded */ + if(!FIPS_rand_status()) + { +- if(RAND_bytes(buf,sizeof buf) <= 0) ++ RAND_poll(); ++ if (!FIPS_rand_status()) + { + fips_selftest_fail = 1; + ret = 0; + goto end; + } +- FIPS_rand_set_key(buf,32); +- FIPS_rand_seed(buf+32,16); + } + +- /* now switch into FIPS mode */ +- fips_set_rand_check(FIPS_rand_method()); +- RAND_set_rand_method(FIPS_rand_method()); + if(FIPS_selftest()) + fips_set_mode(1); + else +diff -up openssl-fips-0.9.8e/fips/rand/fips_rand.c.rng-seed openssl-fips-0.9.8e/fips/rand/fips_rand.c +--- openssl-fips-0.9.8e/fips/rand/fips_rand.c.rng-seed 2007-09-12 19:46:05.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/rand/fips_rand.c 2009-06-29 18:34:00.000000000 +0200 +@@ -155,7 +155,18 @@ static int fips_set_prng_seed(FIPS_PRNG_ + { + int i; + if (!ctx->keyed) +- return 0; ++ { ++ FIPS_RAND_SIZE_T keylen = 16; ++ ++ if (seedlen - keylen < AES_BLOCK_LENGTH) ++ return 0; ++ if (seedlen - keylen - 8 >= AES_BLOCK_LENGTH) ++ keylen += 8; ++ if (seedlen - keylen - 8 >= AES_BLOCK_LENGTH) ++ keylen += 8; ++ seedlen -= keylen; ++ fips_set_prng_key(ctx, seed+seedlen, keylen); ++ } + /* In test mode seed is just supplied data */ + if (ctx->test_mode) + { +@@ -276,6 +287,7 @@ static int fips_rand(FIPS_PRNG_CTX *ctx, + unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH]; + unsigned char tmp[AES_BLOCK_LENGTH]; + int i; ++ FIPS_selftest_check(); + if (ctx->error) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR); diff --git a/SOURCES/openssl-fips-0.9.8e-secure-getenv.patch b/SOURCES/openssl-fips-0.9.8e-secure-getenv.patch new file mode 100644 index 0000000..4d76a89 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-secure-getenv.patch @@ -0,0 +1,193 @@ +diff -up openssl-fips-0.9.8e/crypto/conf/conf_api.c.secure-getenv openssl-fips-0.9.8e/crypto/conf/conf_api.c +--- openssl-fips-0.9.8e/crypto/conf/conf_api.c.secure-getenv 2013-07-17 11:38:28.172584638 +0200 ++++ openssl-fips-0.9.8e/crypto/conf/conf_api.c 2013-07-17 11:44:13.779925448 +0200 +@@ -62,6 +62,8 @@ + # undef NDEBUG /* avoid conflicting definitions */ + # define NDEBUG + #endif ++/* for secure_getenv */ ++#define _GNU_SOURCE + + #include + #include +@@ -145,7 +147,7 @@ char *_CONF_get_string(const CONF *conf, + if (v != NULL) return(v->value); + if (strcmp(section,"ENV") == 0) + { +- p=Getenv(name); ++ p=secure_getenv(name); + if (p != NULL) return(p); + } + } +@@ -158,7 +160,7 @@ char *_CONF_get_string(const CONF *conf, + return(NULL); + } + else +- return(Getenv(name)); ++ return(secure_getenv(name)); + } + + #if 0 /* There's no way to provide error checking with this function, so +diff -up openssl-fips-0.9.8e/crypto/conf/conf_mod.c.secure-getenv openssl-fips-0.9.8e/crypto/conf/conf_mod.c +--- openssl-fips-0.9.8e/crypto/conf/conf_mod.c.secure-getenv 2013-07-17 11:38:28.173584642 +0200 ++++ openssl-fips-0.9.8e/crypto/conf/conf_mod.c 2013-07-17 11:44:37.188017398 +0200 +@@ -56,6 +56,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -548,8 +550,8 @@ char *CONF_get1_default_config_file(void + char *file; + int len; + +- file = getenv("OPENSSL_CONF"); +- if (file) ++ file = secure_getenv("OPENSSL_CONF"); ++ if (file) + return BUF_strdup(file); + + len = strlen(X509_get_default_cert_area()); +diff -up openssl-fips-0.9.8e/crypto/engine/eng_list.c.secure-getenv openssl-fips-0.9.8e/crypto/engine/eng_list.c +--- openssl-fips-0.9.8e/crypto/engine/eng_list.c.secure-getenv 2005-08-06 12:34:35.000000000 +0200 ++++ openssl-fips-0.9.8e/crypto/engine/eng_list.c 2013-07-17 11:42:52.210608034 +0200 +@@ -61,6 +61,8 @@ + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include "eng_int.h" + + /* The linked-list of pointers to engine types. engine_list_head +@@ -398,9 +400,9 @@ ENGINE *ENGINE_by_id(const char *id) + if (strcmp(id, "dynamic")) + { + #ifdef OPENSSL_SYS_VMS +- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]"; ++ if(OPENSSL_issetugid() || (load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]"; + #else +- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR; ++ if((load_dir = secure_getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR; + #endif + iterator = ENGINE_by_id("dynamic"); + if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || +diff -up openssl-fips-0.9.8e/crypto/o_init.c.secure-getenv openssl-fips-0.9.8e/crypto/o_init.c +--- openssl-fips-0.9.8e/crypto/o_init.c.secure-getenv 2013-07-17 11:38:28.232584911 +0200 ++++ openssl-fips-0.9.8e/crypto/o_init.c 2013-07-17 11:41:57.060391907 +0200 +@@ -56,6 +56,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + +@@ -77,7 +79,7 @@ static void init_fips_mode(void) + char buf[2] = "0"; + int fd; + +- if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) ++ if (secure_getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) + { + buf[0] = '1'; + } +diff -up openssl-fips-0.9.8e/crypto/rand/randfile.c.secure-getenv openssl-fips-0.9.8e/crypto/rand/randfile.c +--- openssl-fips-0.9.8e/crypto/rand/randfile.c.secure-getenv 2007-03-02 18:44:55.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/rand/randfile.c 2013-07-17 11:43:29.891755269 +0200 +@@ -58,6 +58,8 @@ + + /* We need to define this to get macros like S_IFBLK and S_IFCHR */ + #define _XOPEN_SOURCE 500 ++/* for secure_getenv */ ++#define _GNU_SOURCE + + #include + #include +@@ -231,8 +233,7 @@ const char *RAND_file_name(char *buf, si + struct stat sb; + #endif + +- if (OPENSSL_issetugid() == 0) +- s=getenv("RANDFILE"); ++ s=secure_getenv("RANDFILE"); + if (s != NULL && *s && strlen(s) + 1 < size) + { + if (BUF_strlcpy(buf,s,size) >= size) +@@ -240,8 +241,7 @@ const char *RAND_file_name(char *buf, si + } + else + { +- if (OPENSSL_issetugid() == 0) +- s=getenv("HOME"); ++ s=secure_getenv("HOME"); + #ifdef DEFAULT_HOME + if (s == NULL) + { +diff -up openssl-fips-0.9.8e/crypto/x509/by_dir.c.secure-getenv openssl-fips-0.9.8e/crypto/x509/by_dir.c +--- openssl-fips-0.9.8e/crypto/x509/by_dir.c.secure-getenv 2007-02-18 18:23:20.000000000 +0100 ++++ openssl-fips-0.9.8e/crypto/x509/by_dir.c 2013-07-17 11:45:03.612126552 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -123,7 +125,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, in + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) + { +- dir=(char *)Getenv(X509_get_default_cert_dir_env()); ++ dir=(char *)secure_getenv(X509_get_default_cert_dir_env()); + if (dir) + ret=add_cert_dir(ld,dir,X509_FILETYPE_PEM); + else +diff -up openssl-fips-0.9.8e/crypto/x509/by_file.c.secure-getenv openssl-fips-0.9.8e/crypto/x509/by_file.c +--- openssl-fips-0.9.8e/crypto/x509/by_file.c.secure-getenv 2013-07-17 11:38:28.127584434 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/by_file.c 2013-07-17 11:45:22.708202388 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -100,7 +102,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) + { +- file = (char *)Getenv(X509_get_default_cert_file_env()); ++ file = (char *)secure_getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx,file, + X509_FILETYPE_PEM) != 0); +diff -up openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.secure-getenv openssl-fips-0.9.8e/crypto/x509/x509_vfy.c +--- openssl-fips-0.9.8e/crypto/x509/x509_vfy.c.secure-getenv 2013-07-17 11:38:28.396585612 +0200 ++++ openssl-fips-0.9.8e/crypto/x509/x509_vfy.c 2013-07-17 11:45:49.733310202 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -414,7 +416,7 @@ static int check_chain_extensions(X509_S + + /* A hack to keep people who don't want to modify their software + happy */ +- if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) ++ if (secure_getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + + /* Check all untrusted certificates */ diff --git a/SOURCES/openssl-fips-0.9.8e-sha2test.patch b/SOURCES/openssl-fips-0.9.8e-sha2test.patch new file mode 100644 index 0000000..aea31fe --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-sha2test.patch @@ -0,0 +1,85 @@ +diff -up openssl-fips-0.9.8e/fips/fips.c.sha2test openssl-fips-0.9.8e/fips/fips.c +--- openssl-fips-0.9.8e/fips/fips.c.sha2test 2011-04-04 16:40:28.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/fips.c 2011-10-18 16:30:21.000000000 +0200 +@@ -56,6 +56,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -161,6 +162,7 @@ int FIPS_selftest() + { + + return FIPS_selftest_sha1() ++ && FIPS_selftest_sha2() + && FIPS_selftest_hmac() + && FIPS_selftest_aes() + && FIPS_selftest_des() +@@ -401,6 +403,8 @@ FIPSCHECK_verify(const char *libname, co + return 0; + + hmacpath = make_hmac_path(path); ++ if (hmacpath == NULL) ++ return 0; + + hf = fopen(hmacpath, "r"); + if (hf == NULL) { +@@ -712,6 +716,45 @@ int fips_cipher_test(EVP_CIPHER_CTX *ctx + return 1; + } + ++static const unsigned char msg_sha256[] = { 0xfa, 0x48, 0x59, 0x2a, 0xe1, 0xae, 0x1f, 0x30, ++ 0xfc }; ++static const unsigned char dig_sha256[] = { 0xf7, 0x26, 0xd8, 0x98, 0x47, 0x91, 0x68, 0x5b, ++ 0x9e, 0x39, 0xb2, 0x58, 0xbb, 0x75, 0xbf, 0x01, ++ 0x17, 0x0c, 0x84, 0x00, 0x01, 0x7a, 0x94, 0x83, ++ 0xf3, 0x0b, 0x15, 0x84, 0x4b, 0x69, 0x88, 0x8a }; ++ ++static const unsigned char msg_sha512[] = { 0x37, 0xd1, 0x35, 0x9d, 0x18, 0x41, 0xe9, 0xb7, ++ 0x6d, 0x9a, 0x13, 0xda, 0x5f, 0xf3, 0xbd }; ++static const unsigned char dig_sha512[] = { 0x11, 0x13, 0xc4, 0x19, 0xed, 0x2b, 0x1d, 0x16, ++ 0x11, 0xeb, 0x9b, 0xbe, 0xf0, 0x7f, 0xcf, 0x44, ++ 0x8b, 0xd7, 0x57, 0xbd, 0x8d, 0xa9, 0x25, 0xb0, ++ 0x47, 0x25, 0xd6, 0x6c, 0x9a, 0x54, 0x7f, 0x8f, ++ 0x0b, 0x53, 0x1a, 0x10, 0x68, 0x32, 0x03, 0x38, ++ 0x82, 0xc4, 0x87, 0xc4, 0xea, 0x0e, 0xd1, 0x04, ++ 0xa9, 0x98, 0xc1, 0x05, 0xa3, 0xf3, 0xf8, 0xb1, ++ 0xaf, 0xbc, 0xd9, 0x78, 0x7e, 0xee, 0x3d, 0x43 }; ++ ++int FIPS_selftest_sha2(void) ++ { ++ unsigned char md[SHA512_DIGEST_LENGTH]; ++ ++ EVP_Digest(msg_sha256, sizeof(msg_sha256), md, NULL, EVP_sha256(), NULL); ++ if(memcmp(dig_sha256, md, sizeof(dig_sha256))) ++ { ++ FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ EVP_Digest(msg_sha512, sizeof(msg_sha512), md, NULL, EVP_sha512(), NULL); ++ if(memcmp(dig_sha512, md, sizeof(dig_sha512))) ++ { ++ FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ return 1; ++ } ++ + #if 0 + /* The purpose of this is to ensure the error code exists and the function + * name is to keep the error checking script quiet +diff -up openssl-fips-0.9.8e/fips/fips.h.sha2test openssl-fips-0.9.8e/fips/fips.h +--- openssl-fips-0.9.8e/fips/fips.h.sha2test 2007-09-12 19:46:03.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/fips.h 2011-09-26 10:43:08.000000000 +0200 +@@ -68,6 +68,7 @@ int FIPS_selftest_failed(void); + void FIPS_selftest_check(void); + void FIPS_corrupt_sha1(void); + int FIPS_selftest_sha1(void); ++int FIPS_selftest_sha2(void); + void FIPS_corrupt_aes(void); + int FIPS_selftest_aes(void); + void FIPS_corrupt_des(void); diff --git a/SOURCES/openssl-fips-0.9.8e-ssl-sha256.patch b/SOURCES/openssl-fips-0.9.8e-ssl-sha256.patch new file mode 100644 index 0000000..03508fc --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-ssl-sha256.patch @@ -0,0 +1,18 @@ +diff -up openssl-fips-0.9.8e/ssl/ssl_algs.c.sha256 openssl-fips-0.9.8e/ssl/ssl_algs.c +--- openssl-fips-0.9.8e/ssl/ssl_algs.c.sha256 2010-12-07 17:45:32.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/ssl_algs.c 2011-03-07 18:58:56.000000000 +0100 +@@ -104,6 +104,14 @@ int SSL_library_init(void) + EVP_add_digest_alias(SN_sha1,"ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption,SN_sha1WithRSA); + #endif ++#ifndef OPENSSL_NO_SHA256 ++ EVP_add_digest(EVP_sha224()); ++ EVP_add_digest(EVP_sha256()); ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ EVP_add_digest(EVP_sha384()); ++ EVP_add_digest(EVP_sha512()); ++#endif + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1,SN_dsaWithSHA1_2); diff --git a/SOURCES/openssl-fips-0.9.8e-tls-version.patch b/SOURCES/openssl-fips-0.9.8e-tls-version.patch new file mode 100644 index 0000000..1e5aa83 --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-tls-version.patch @@ -0,0 +1,26 @@ +diff -up openssl-fips-0.9.8e/ssl/s23_srvr.c.tlsver openssl-fips-0.9.8e/ssl/s23_srvr.c +--- openssl-fips-0.9.8e/ssl/s23_srvr.c.tlsver 2007-03-22 01:39:13.000000000 +0100 ++++ openssl-fips-0.9.8e/ssl/s23_srvr.c 2011-04-04 15:36:45.000000000 +0200 +@@ -315,7 +315,7 @@ int ssl23_get_client_hello(SSL *s) + (p[1] == SSL3_VERSION_MAJOR) && + (p[5] == SSL3_MT_CLIENT_HELLO) && + ((p[3] == 0 && p[4] < 5 /* silly record length? */) +- || (p[9] == p[1]))) ++ || (p[9] >= p[1]))) + { + /* + * SSLv3 or tls1 header +@@ -339,6 +339,13 @@ int ssl23_get_client_hello(SSL *s) + v[1] = TLS1_VERSION_MINOR; + #endif + } ++ /* if major version number > 3 set minor to a value ++ * which will use the highest version 3 we support. ++ * If TLS 2.0 ever appears we will need to revise ++ * this.... ++ */ ++ else if (p[9] > SSL3_VERSION_MAJOR) ++ v[1]=0xff; + else + v[1]=p[10]; /* minor version according to client_version */ + if (v[1] >= TLS1_VERSION_MINOR) diff --git a/SOURCES/openssl-fips-0.9.8e-use-fipscheck.patch b/SOURCES/openssl-fips-0.9.8e-use-fipscheck.patch new file mode 100644 index 0000000..f1aaaec --- /dev/null +++ b/SOURCES/openssl-fips-0.9.8e-use-fipscheck.patch @@ -0,0 +1,552 @@ +Do not create a fips canister but use a fipscheck equivalent method for +integrity verification of both libssl and libcrypto shared libraries. +diff -up openssl-fips-0.9.8e/apps/Makefile.use-fipscheck openssl-fips-0.9.8e/apps/Makefile +--- openssl-fips-0.9.8e/apps/Makefile.use-fipscheck 2007-08-15 15:35:29.000000000 +0200 ++++ openssl-fips-0.9.8e/apps/Makefile 2009-03-26 15:16:09.000000000 +0100 +@@ -152,8 +152,6 @@ $(EXE): progs.h $(E_OBJ) $(PROGRAM).o $( + $(RM) $(EXE) + shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \ + shlib_target="$(SHLIB_TARGET)"; \ +- elif [ -n "$(FIPSCANLIB)" ]; then \ +- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \ + fi; \ + LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \ + [ "x$(FIPSCANLIB)" = "xlibfips" ] && LIBRARIES="$$LIBRARIES -lfips"; \ +diff -up openssl-fips-0.9.8e/fips/fips.c.use-fipscheck openssl-fips-0.9.8e/fips/fips.c +--- openssl-fips-0.9.8e/fips/fips.c.use-fipscheck 2007-08-26 16:57:10.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/fips.c 2009-04-15 11:43:59.000000000 +0200 +@@ -47,6 +47,8 @@ + * + */ + ++#define _GNU_SOURCE ++ + #include + #include + #include +@@ -56,6 +58,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include "fips_locl.h" + + #ifdef OPENSSL_FIPS +@@ -163,6 +168,7 @@ int FIPS_selftest() + && FIPS_selftest_dsa(); + } + ++#if 0 + extern const void *FIPS_text_start(), *FIPS_text_end(); + extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[]; + unsigned char FIPS_signature [20] = { 0 }; +@@ -241,6 +247,206 @@ int FIPS_check_incore_fingerprint(void) + + return 1; + } ++#else ++/* we implement what libfipscheck does ourselves */ ++ ++static int ++get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) ++{ ++ Dl_info info; ++ void *dl, *sym; ++ int rv = -1; ++ ++ dl = dlopen(libname, RTLD_LAZY); ++ if (dl == NULL) { ++ return -1; ++ } ++ ++ sym = dlsym(dl, symbolname); ++ ++ if (sym != NULL && dladdr(sym, &info)) { ++ strncpy(path, info.dli_fname, pathlen-1); ++ path[pathlen-1] = '\0'; ++ rv = 0; ++ } ++ ++ dlclose(dl); ++ ++ return rv; ++} ++ ++static const char conv[] = "0123456789abcdef"; ++ ++static char * ++bin2hex(void *buf, size_t len) ++{ ++ char *hex, *p; ++ unsigned char *src = buf; ++ ++ hex = malloc(len * 2 + 1); ++ if (hex == NULL) ++ return NULL; ++ ++ p = hex; ++ ++ while (len > 0) { ++ unsigned c; ++ ++ c = *src; ++ src++; ++ ++ *p = conv[c >> 4]; ++ ++p; ++ *p = conv[c & 0x0f]; ++ ++p; ++ --len; ++ } ++ *p = '\0'; ++ return hex; ++} ++ ++#define HMAC_PREFIX "." ++#define HMAC_SUFFIX ".hmac" ++#define READ_BUFFER_LENGTH 16384 ++ ++static char * ++make_hmac_path(const char *origpath) ++{ ++ char *path, *p; ++ const char *fn; ++ ++ path = malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath)); ++ if(path == NULL) { ++ return NULL; ++ } ++ ++ fn = strrchr(origpath, '/'); ++ if (fn == NULL) { ++ fn = origpath; ++ } else { ++ ++fn; ++ } ++ ++ strncpy(path, origpath, fn-origpath); ++ p = path + (fn - origpath); ++ p = stpcpy(p, HMAC_PREFIX); ++ p = stpcpy(p, fn); ++ p = stpcpy(p, HMAC_SUFFIX); ++ ++ return path; ++} ++ ++static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP"; ++ ++static int ++compute_file_hmac(const char *path, void **buf, size_t *hmaclen) ++{ ++ FILE *f = NULL; ++ int rv = -1; ++ unsigned char rbuf[READ_BUFFER_LENGTH]; ++ size_t len; ++ unsigned int hlen; ++ HMAC_CTX c; ++ ++ HMAC_CTX_init(&c); ++ ++ f = fopen(path, "r"); ++ ++ if (f == NULL) { ++ goto end; ++ } ++ ++ HMAC_Init(&c, hmackey, sizeof(hmackey)-1, EVP_sha256()); ++ ++ while ((len=fread(rbuf, 1, sizeof(rbuf), f)) != 0) { ++ HMAC_Update(&c, rbuf, len); ++ } ++ ++ len = sizeof(rbuf); ++ /* reuse rbuf for hmac */ ++ HMAC_Final(&c, rbuf, &hlen); ++ ++ *buf = malloc(hlen); ++ if (*buf == NULL) { ++ goto end; ++ } ++ ++ *hmaclen = hlen; ++ ++ memcpy(*buf, rbuf, hlen); ++ ++ rv = 0; ++end: ++ HMAC_CTX_cleanup(&c); ++ ++ if (f) ++ fclose(f); ++ ++ return rv; ++} ++ ++static int ++FIPSCHECK_verify(const char *libname, const char *symbolname) ++{ ++ char path[PATH_MAX+1]; ++ int rv; ++ FILE *hf; ++ char *hmacpath, *p; ++ char *hmac = NULL; ++ size_t n; ++ ++ rv = get_library_path(libname, symbolname, path, sizeof(path)); ++ ++ if (rv < 0) ++ return 0; ++ ++ hmacpath = make_hmac_path(path); ++ ++ hf = fopen(hmacpath, "r"); ++ if (hf == NULL) { ++ free(hmacpath); ++ return 0; ++ } ++ ++ if (getline(&hmac, &n, hf) > 0) { ++ void *buf; ++ size_t hmaclen; ++ char *hex; ++ ++ if ((p=strchr(hmac, '\n')) != NULL) ++ *p = '\0'; ++ ++ if (compute_file_hmac(path, &buf, &hmaclen) < 0) { ++ rv = -4; ++ goto end; ++ } ++ ++ if ((hex=bin2hex(buf, hmaclen)) == NULL) { ++ free(buf); ++ rv = -5; ++ goto end; ++ } ++ ++ if (strcmp(hex, hmac) != 0) { ++ rv = -1; ++ } ++ free(buf); ++ free(hex); ++ } ++ ++end: ++ free(hmac); ++ free(hmacpath); ++ fclose(hf); ++ ++ if (rv < 0) ++ return 0; ++ ++ /* check successful */ ++ return 1; ++} ++ ++#endif + + int FIPS_mode_set(int onoff) + { +@@ -278,16 +484,17 @@ int FIPS_mode_set(int onoff) + } + #endif + +- if(fips_signature_witness() != FIPS_signature) ++ if(!FIPSCHECK_verify("libcrypto.so.0.9.8e","FIPS_mode_set")) + { +- FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE); ++ FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + +- if(!FIPS_check_incore_fingerprint()) ++ if(!FIPSCHECK_verify("libssl.so.0.9.8e","SSL_CTX_new")) + { ++ FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; +@@ -403,11 +610,13 @@ int fips_clear_owning_thread(void) + return ret; + } + ++#if 0 + unsigned char *fips_signature_witness(void) + { + extern unsigned char FIPS_signature[]; + return FIPS_signature; + } ++#endif + + /* Generalized public key test routine. Signs and verifies the data + * supplied in tbs using mesage digest md and setting option digest +diff -up openssl-fips-0.9.8e/fips/fips_locl.h.use-fipscheck openssl-fips-0.9.8e/fips/fips_locl.h +--- openssl-fips-0.9.8e/fips/fips_locl.h.use-fipscheck 2007-08-15 15:35:31.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/fips_locl.h 2009-03-26 15:15:39.000000000 +0100 +@@ -63,7 +63,9 @@ int fips_is_owning_thread(void); + int fips_set_owning_thread(void); + void fips_set_selftest_fail(void); + int fips_clear_owning_thread(void); ++#if 0 + unsigned char *fips_signature_witness(void); ++#endif + + #define FIPS_MAX_CIPHER_TEST_SIZE 16 + +diff -up openssl-fips-0.9.8e/fips/Makefile.use-fipscheck openssl-fips-0.9.8e/fips/Makefile +--- openssl-fips-0.9.8e/fips/Makefile.use-fipscheck 2007-08-15 15:35:30.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/Makefile 2009-04-15 11:41:25.000000000 +0200 +@@ -62,9 +62,9 @@ testapps: + + all: + @if [ -z "$(FIPSLIBDIR)" ]; then \ +- $(MAKE) -e subdirs lib fips_premain_dso$(EXE_EXT); \ ++ $(MAKE) -e subdirs lib; \ + else \ +- $(MAKE) -e lib fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT); \ ++ $(MAKE) -e lib; \ + fi + + # Idea behind fipscanister.o is to "seize" the sequestered code between +@@ -109,7 +109,6 @@ fipscanister.o: fips_start.o $(LIBOBJ) $ + HP-UX|OSF1|SunOS) set -x; /usr/ccs/bin/ld -r -o $@ $$objs ;; \ + *) set -x; $(CC) $$cflags -r -o $@ $$objs ;; \ + esac fi +- ./fips_standalone_sha1 fipscanister.o > fipscanister.o.sha1 + + # If another exception is immediately required, assign approprite + # site-specific ld command to FIPS_SITE_LD environment variable. +@@ -141,8 +140,24 @@ links: + lib: $(LIB) + @touch lib + +-$(LIB): $(FIPSLIBDIR)fipscanister.o +- $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o ++$(LIB): $(LIBOBJ) $(FIPS_OBJ_LISTS) ++ FIPS_ASM=""; \ ++ list="$(BN_ASM)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/bn/$$i" ; done; \ ++ list="$(AES_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/aes/$$i" ; done; \ ++ list="$(DES_ENC)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/des/$$i" ; done; \ ++ list="$(SHA1_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/sha/$$i" ; done; \ ++ if [ -n "$(CPUID_OBJ)" ]; then \ ++ CPUID=../crypto/$(CPUID_OBJ) ; \ ++ else \ ++ CPUID="" ; \ ++ fi ; \ ++ objs="$(LIBOBJ) $(FIPS_EX_OBJ) $$CPUID $$FIPS_ASM"; \ ++ for i in $(FIPS_OBJ_LISTS); do \ ++ dir=`dirname $$i`; script="s|^|$$dir/|;s| | $$dir/|g"; \ ++ objs="$$objs `sed "$$script" $$i`"; \ ++ done; \ ++ objs="$$objs" ; \ ++ $(AR) $(LIB) $$objs + $(RANLIB) $(LIB) || echo Never mind. + + $(FIPSCANLIB): $(FIPSCANLOC) +@@ -154,7 +169,7 @@ $(FIPSCANLIB): $(FIPSCANLOC) + $(RANLIB) ../$(FIPSCANLIB).a || echo Never mind. + @touch lib + +-shared: lib subdirs fips_premain_dso$(EXE_EXT) ++shared: lib subdirs + + libs: + @target=lib; $(RECURSIVE_MAKE) +@@ -178,10 +193,6 @@ install: + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + @target=install; $(RECURSIVE_MAKE) +- @cp -p -f fipscanister.o fipscanister.o.sha1 fips_premain.c \ +- fips_premain.c.sha1 \ +- $(INSTALL_PREFIX)$(INSTALLTOP)/lib/; \ +- chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/fips* + + lint: + @target=lint; $(RECURSIVE_MAKE) +diff -up openssl-fips-0.9.8e/fips/sha/fips_standalone_sha1.c.use-fipscheck openssl-fips-0.9.8e/fips/sha/fips_standalone_sha1.c +--- openssl-fips-0.9.8e/fips/sha/fips_standalone_sha1.c.use-fipscheck 2007-08-15 15:35:46.000000000 +0200 ++++ openssl-fips-0.9.8e/fips/sha/fips_standalone_sha1.c 2009-04-15 11:58:37.000000000 +0200 +@@ -62,20 +62,20 @@ void OPENSSL_cleanse(void *p,size_t len) + + #ifdef OPENSSL_FIPS + +-static void hmac_init(SHA_CTX *md_ctx,SHA_CTX *o_ctx, ++static void hmac_init(SHA256_CTX *md_ctx,SHA256_CTX *o_ctx, + const char *key) + { +- int len=strlen(key); ++ size_t len=strlen(key); + int i; + unsigned char keymd[HMAC_MAX_MD_CBLOCK]; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (len > SHA_CBLOCK) + { +- SHA1_Init(md_ctx); +- SHA1_Update(md_ctx,key,len); +- SHA1_Final(keymd,md_ctx); +- len=20; ++ SHA256_Init(md_ctx); ++ SHA256_Update(md_ctx,key,len); ++ SHA256_Final(keymd,md_ctx); ++ len=SHA256_DIGEST_LENGTH; + } + else + memcpy(keymd,key,len); +@@ -83,22 +83,22 @@ static void hmac_init(SHA_CTX *md_ctx,SH + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x36^keymd[i]; +- SHA1_Init(md_ctx); +- SHA1_Update(md_ctx,pad,SHA_CBLOCK); ++ SHA256_Init(md_ctx); ++ SHA256_Update(md_ctx,pad,SHA256_CBLOCK); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x5c^keymd[i]; +- SHA1_Init(o_ctx); +- SHA1_Update(o_ctx,pad,SHA_CBLOCK); ++ SHA256_Init(o_ctx); ++ SHA256_Update(o_ctx,pad,SHA256_CBLOCK); + } + +-static void hmac_final(unsigned char *md,SHA_CTX *md_ctx,SHA_CTX *o_ctx) ++static void hmac_final(unsigned char *md,SHA256_CTX *md_ctx,SHA256_CTX *o_ctx) + { +- unsigned char buf[20]; ++ unsigned char buf[SHA256_DIGEST_LENGTH]; + +- SHA1_Final(buf,md_ctx); +- SHA1_Update(o_ctx,buf,sizeof buf); +- SHA1_Final(md,o_ctx); ++ SHA256_Final(buf,md_ctx); ++ SHA256_Update(o_ctx,buf,sizeof buf); ++ SHA256_Final(md,o_ctx); + } + + #endif +@@ -106,7 +106,7 @@ static void hmac_final(unsigned char *md + int main(int argc,char **argv) + { + #ifdef OPENSSL_FIPS +- static char key[]="etaonrishdlcupfm"; ++ static char key[]="orboDeJITITejsirpADONivirpUkvarP"; + int n,binary=0; + + if(argc < 2) +@@ -125,8 +125,8 @@ int main(int argc,char **argv) + for(; n < argc ; ++n) + { + FILE *f=fopen(argv[n],"rb"); +- SHA_CTX md_ctx,o_ctx; +- unsigned char md[20]; ++ SHA256_CTX md_ctx,o_ctx; ++ unsigned char md[SHA256_DIGEST_LENGTH]; + int i; + + if(!f) +@@ -139,7 +139,7 @@ int main(int argc,char **argv) + for( ; ; ) + { + char buf[1024]; +- int l=fread(buf,1,sizeof buf,f); ++ size_t l=fread(buf,1,sizeof buf,f); + + if(l == 0) + { +@@ -151,18 +151,18 @@ int main(int argc,char **argv) + else + break; + } +- SHA1_Update(&md_ctx,buf,l); ++ SHA256_Update(&md_ctx,buf,l); + } + hmac_final(md,&md_ctx,&o_ctx); + + if (binary) + { +- fwrite(md,20,1,stdout); ++ fwrite(md,SHA256_DIGEST_LENGTH,1,stdout); + break; /* ... for single(!) file */ + } + +- printf("HMAC-SHA1(%s)= ",argv[n]); +- for(i=0 ; i < 20 ; ++i) ++/* printf("HMAC-SHA1(%s)= ",argv[n]); */ ++ for(i=0 ; i < SHA256_DIGEST_LENGTH ; ++i) + printf("%02x",md[i]); + printf("\n"); + } +diff -up openssl-fips-0.9.8e/fips/sha/Makefile.use-fipscheck openssl-fips-0.9.8e/fips/sha/Makefile +--- openssl-fips-0.9.8e/fips/sha/Makefile.use-fipscheck 2009-03-26 15:16:04.000000000 +0100 ++++ openssl-fips-0.9.8e/fips/sha/Makefile 2009-04-15 11:57:17.000000000 +0200 +@@ -47,7 +47,7 @@ lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + + ../fips_standalone_sha1$(EXE_EXT): fips_standalone_sha1.o +- FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha1dgst.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \ ++ FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha256.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \ + $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM + + files: +diff -up openssl-fips-0.9.8e/Makefile.org.use-fipscheck openssl-fips-0.9.8e/Makefile.org +--- openssl-fips-0.9.8e/Makefile.org.use-fipscheck 2009-03-26 15:15:39.000000000 +0100 ++++ openssl-fips-0.9.8e/Makefile.org 2009-03-26 15:15:39.000000000 +0100 +@@ -355,10 +355,6 @@ libcrypto$(SHLIB_EXT): libcrypto.a $(SHA + $(MAKE) SHLIBDIRS='crypto' SHLIBDEPS='-lfips' build-shared; \ + $(AR) libcrypto.a fips/fipscanister.o ; \ + else \ +- if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \ +- FIPSLD_CC=$(CC); CC=fips/fipsld; \ +- export CC FIPSLD_CC; \ +- fi; \ + $(MAKE) -e SHLIBDIRS='crypto' build-shared; \ + fi \ + else \ +@@ -379,9 +375,8 @@ libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT + fips/fipscanister.o: build_fips + libfips$(SHLIB_EXT): fips/fipscanister.o + @if [ "$(SHLIB_TARGET)" != "" ]; then \ +- FIPSLD_CC=$(CC); CC=fips/fipsld; export CC FIPSLD_CC; \ + $(MAKE) -f Makefile.shared -e $(BUILDENV) \ +- CC=$${CC} LIBNAME=fips THIS=$@ \ ++ CC=$(CC) LIBNAME=fips THIS=$@ \ + LIBEXTRAS=fips/fipscanister.o \ + LIBDEPS="$(EX_LIBS)" \ + LIBVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR} \ +@@ -467,7 +462,7 @@ openssl.pc: Makefile + echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \ + echo 'Version: '$(VERSION); \ + echo 'Requires: '; \ +- echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \ ++ echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)';\ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc + + Makefile: Makefile.org Configure config +diff -up openssl-fips-0.9.8e/test/Makefile.use-fipscheck openssl-fips-0.9.8e/test/Makefile +--- openssl-fips-0.9.8e/test/Makefile.use-fipscheck 2007-08-26 16:57:41.000000000 +0200 ++++ openssl-fips-0.9.8e/test/Makefile 2009-04-15 11:37:30.000000000 +0200 +@@ -395,8 +395,7 @@ FIPS_BUILD_CMD=shlib_target=; if [ -n "$ + if [ "$(FIPSCANLIB)" = "libfips" ]; then \ + LIBRARIES="-L$(TOP) -lfips"; \ + else \ +- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \ +- LIBRARIES="$${FIPSLIBDIR:-$(TOP)/fips/}fipscanister.o"; \ ++ LIBRARIES="$(LIBCRYPTO)"; \ + fi; \ + $(MAKE) -f $(TOP)/Makefile.shared -e \ + CC=$${CC} APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \ +@@ -407,9 +406,6 @@ FIPS_CRYPTO_BUILD_CMD=shlib_target=; if + shlib_target="$(SHLIB_TARGET)"; \ + fi; \ + LIBRARIES="$(LIBSSL) $(LIBCRYPTO) $(LIBKRB5)"; \ +- if [ -z "$(SHARED_LIBS)" ] ; then \ +- FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \ +- fi; \ + [ "$(FIPSCANLIB)" = "libfips" ] && LIBRARIES="$$LIBRARIES -lfips"; \ + $(MAKE) -f $(TOP)/Makefile.shared -e \ + CC=$${CC} APPNAME=$$target$(EXE_EXT) OBJECTS="$$target.o" \ diff --git a/SOURCES/openssl-thread-test.c b/SOURCES/openssl-thread-test.c new file mode 100644 index 0000000..3b90285 --- /dev/null +++ b/SOURCES/openssl-thread-test.c @@ -0,0 +1,400 @@ +/* Test program to verify that RSA signing is thread-safe in OpenSSL. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Just assume we want to do engine stuff if we're using 0.9.6b or + * higher. This assumption is only valid for versions bundled with RHL. */ +#if OPENSSL_VERSION_NUMBER >= 0x0090602fL +#include +#define USE_ENGINE +#endif + +#define MAX_THREAD_COUNT 10000 +#define ITERATION_COUNT 10 +#define MAIN_COUNT 100 + +/* OpenSSL requires us to provide thread ID and locking primitives. */ +pthread_mutex_t *mutex_locks = NULL; +static unsigned long +thread_id_cb(void) +{ + return (unsigned long) pthread_self(); +} +static void +lock_cb(int mode, int n, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&mutex_locks[n]); + } else { + pthread_mutex_unlock(&mutex_locks[n]); + } +} + +struct thread_args { + RSA *rsa; + int digest_type; + unsigned char *digest; + unsigned int digest_len; + unsigned char *signature; + unsigned int signature_len; + pthread_t main_thread; +}; + +static int print = 0; + +pthread_mutex_t sign_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_sign = 0; +static void SIGN_LOCK() {if (locked_sign) pthread_mutex_lock(&sign_lock);} +static void SIGN_UNLOCK() {if (locked_sign) pthread_mutex_unlock(&sign_lock);} + +pthread_mutex_t verify_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_verify = 0; +static void VERIFY_LOCK() {if (locked_verify) pthread_mutex_lock(&verify_lock);} +static void VERIFY_UNLOCK() {if (locked_verify) pthread_mutex_unlock(&verify_lock);} + +pthread_mutex_t failure_count_lock = PTHREAD_MUTEX_INITIALIZER; +long failure_count = 0; +static void +failure() +{ + pthread_mutex_lock(&failure_count_lock); + failure_count++; + pthread_mutex_unlock(&failure_count_lock); +} + +static void * +thread_main(void *argp) +{ + struct thread_args *args = argp; + unsigned char *signature; + unsigned int signature_len, signature_alloc_len; + int ret, i; + + signature_alloc_len = args->signature_len; + if (RSA_size(args->rsa) > signature_alloc_len) { + signature_alloc_len = RSA_size(args->rsa); + } + signature = malloc(signature_alloc_len); + if (signature == NULL) { + fprintf(stderr, "Skipping checks in thread %lu -- %s.\n", + (unsigned long) pthread_self(), strerror(errno)); + pthread_exit(0); + return NULL; + } + for (i = 0; i < ITERATION_COUNT; i++) { + signature_len = signature_alloc_len; + SIGN_LOCK(); + ret = RSA_check_key(args->rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + ret = RSA_sign(args->digest_type, + args->digest, + args->digest_len, + signature, &signature_len, + args->rsa); + SIGN_UNLOCK(); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + + VERIFY_LOCK(); + ret = RSA_verify(args->digest_type, + args->digest, + args->digest_len, + signature, signature_len, + args->rsa); + VERIFY_UNLOCK(); + if (ret != 1) { + fprintf(stderr, + "Signature from thread %lu(%d) fails " + "verification (passed in thread #%lu)!\n", + (long) pthread_self(), i, + (long) args->main_thread); + ERR_print_errors_fp(stdout); + failure(); + continue; + } + if (print) { + fprintf(stderr, ">%d\n", i); + } + } + free(signature); + + pthread_exit(0); + + return NULL; +} + +unsigned char * +xmemdup(unsigned char *s, size_t len) +{ + unsigned char *r; + r = malloc(len); + if (r == NULL) { + fprintf(stderr, "Out of memory.\n"); + ERR_print_errors_fp(stdout); + assert(r != NULL); + } + memcpy(r, s, len); + return r; +} + +int +main(int argc, char **argv) +{ + RSA *rsa; + MD5_CTX md5; + int fd, i; + pthread_t threads[MAX_THREAD_COUNT]; + int thread_count = 1000; + unsigned char *message, *digest; + unsigned int message_len, digest_len; + unsigned char *correct_signature; + unsigned int correct_siglen, ret; + struct thread_args master_args, *args; + int sync = 0, seed = 0; + int again = 1; +#ifdef USE_ENGINE + char *engine = NULL; + ENGINE *e = NULL; +#endif + + pthread_mutex_init(&failure_count_lock, NULL); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--seed") == 0) { + printf("Seeding PRNG.\n"); + seed++; + } else + if (strcmp(argv[i], "--sync") == 0) { + printf("Running synchronized.\n"); + sync++; + } else + if ((strcmp(argv[i], "--threads") == 0) && (i < argc - 1)) { + i++; + thread_count = atol(argv[i]); + if (thread_count > MAX_THREAD_COUNT) { + thread_count = MAX_THREAD_COUNT; + } + printf("Starting %d threads.\n", thread_count); + sync++; + } else + if (strcmp(argv[i], "--sign") == 0) { + printf("Locking signing.\n"); + locked_sign++; + } else + if (strcmp(argv[i], "--verify") == 0) { + printf("Locking verifies.\n"); + locked_verify++; + } else + if (strcmp(argv[i], "--print") == 0) { + printf("Tracing.\n"); + print++; +#ifdef USE_ENGINE + } else + if ((strcmp(argv[i], "--engine") == 0) && (i < argc - 1)) { + printf("Using engine \"%s\".\n", argv[i + 1]); + engine = argv[i + 1]; + i++; +#endif + } else { + printf("Bad argument: %s\n", argv[i]); + return 1; + } + } + + /* Get some random data to sign. */ + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Error opening /dev/urandom: %s\n", + strerror(errno)); + } + + if (print) { + fprintf(stderr, "Reading random data.\n"); + } + message = malloc(message_len = 9371); + read(fd, message, message_len); + close(fd); + + /* Initialize the SSL library and set up thread-safe locking. */ + ERR_load_crypto_strings(); + SSL_library_init(); + mutex_locks = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks()); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&mutex_locks[i], NULL); + } + CRYPTO_set_id_callback(thread_id_cb); + CRYPTO_set_locking_callback(lock_cb); + ERR_print_errors_fp(stdout); + + /* Seed the PRNG if we were asked to do so. */ + if (seed) { + if (print) { + fprintf(stderr, "Seeding PRNG.\n"); + } + RAND_add(message, message_len, message_len); + ERR_print_errors_fp(stdout); + } + + /* Turn on a hardware crypto device if asked to do so. */ +#ifdef USE_ENGINE + if (engine) { +#if OPENSSL_VERSION_NUMBER >= 0x0090700fL + ENGINE_load_builtin_engines(); +#endif + if (print) { + fprintf(stderr, "Initializing \"%s\" engine.\n", + engine); + } + e = ENGINE_by_id(engine); + ERR_print_errors_fp(stdout); + if (e) { + i = ENGINE_init(e); + ERR_print_errors_fp(stdout); + i = ENGINE_set_default_RSA(e); + ERR_print_errors_fp(stdout); + } + } +#endif + + /* Compute the digest for the signature. */ + if (print) { + fprintf(stderr, "Computing digest.\n"); + } + digest = malloc(digest_len = MD5_DIGEST_LENGTH); + MD5_Init(&md5); + MD5_Update(&md5, message, message_len); + MD5_Final(digest, &md5); + + /* Generate a signing key. */ + if (print) { + fprintf(stderr, "Generating key.\n"); + } + rsa = RSA_generate_key(4096, 3, NULL, NULL); + ERR_print_errors_fp(stdout); + if (rsa == NULL) { + _exit(1); + } + + /* Sign the data. */ + correct_siglen = RSA_size(rsa); + correct_signature = malloc(correct_siglen); + for (i = 0; i < MAIN_COUNT; i++) { + if (print) { + fprintf(stderr, "Signing data (%d).\n", i); + } + ret = RSA_check_key(rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + } + correct_siglen = RSA_size(rsa); + ret = RSA_sign(NID_md5, digest, digest_len, + correct_signature, &correct_siglen, + rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + _exit(2); + } + if (print) { + fprintf(stderr, "Verifying data (%d).\n", i); + } + ret = RSA_verify(NID_md5, digest, digest_len, + correct_signature, correct_siglen, + rsa); + if (ret != 1) { + _exit(2); + } + } + + /* Collect up the inforamtion which other threads will need for + * comparing their signature results with ours. */ + master_args.rsa = rsa; + master_args.digest_type = NID_md5; + master_args.digest = digest; + master_args.digest_len = digest_len; + master_args.signature = correct_signature; + master_args.signature_len = correct_siglen; + master_args.main_thread = pthread_self(); + + fprintf(stdout, "Performing %d signatures in each of %d threads " + "(%d, %d).\n", ITERATION_COUNT, thread_count, + digest_len, correct_siglen); + fflush(NULL); + + /* Start up all of the threads. */ + for (i = 0; i < thread_count; i++) { + args = malloc(sizeof(struct thread_args)); + args->rsa = RSAPrivateKey_dup(master_args.rsa); + args->digest_type = master_args.digest_type; + args->digest_len = master_args.digest_len; + args->digest = xmemdup(master_args.digest, args->digest_len); + args->signature_len = master_args.signature_len; + args->signature = xmemdup(master_args.signature, + args->signature_len); + args->main_thread = pthread_self(); + ret = pthread_create(&threads[i], NULL, thread_main, args); + while ((ret != 0) && (errno == EAGAIN)) { + ret = pthread_create(&threads[i], NULL, + thread_main, &args); + fprintf(stderr, "Thread limit hit at %d.\n", i); + } + if (ret != 0) { + fprintf(stderr, "Unable to create thread %d: %s.\n", + i, strerror(errno)); + threads[i] = -1; + } else { + if (sync) { + ret = pthread_join(threads[i], NULL); + assert(ret == 0); + } + if (print) { + fprintf(stderr, "%d\n", i); + } + } + } + + /* Wait for all threads to complete. So long as we can find an + * unjoined thread, keep joining threads. */ + do { + again = 0; + for (i = 0; i < thread_count; i++) { + /* If we have an unterminated thread, join it. */ + if (threads[i] != -1) { + again = 1; + if (print) { + fprintf(stderr, "Joining thread %d.\n", + i); + } + pthread_join(threads[i], NULL); + threads[i] = -1; + break; + } + } + } while (again == 1); + + fprintf(stderr, "%ld failures\n", failure_count); + + return (failure_count != 0); +} diff --git a/SOURCES/opensslconf-new-warning.h b/SOURCES/opensslconf-new-warning.h new file mode 100644 index 0000000..de091c8 --- /dev/null +++ b/SOURCES/opensslconf-new-warning.h @@ -0,0 +1,7 @@ +/* Prepended at openssl package build-time. Don't include this file directly, + * use instead. */ + +#ifndef openssl_opensslconf_multilib_redirection_h +#error "Don't include this file directly, use instead!" +#endif + diff --git a/SOURCES/opensslconf-new.h b/SOURCES/opensslconf-new.h new file mode 100644 index 0000000..bc8e30d --- /dev/null +++ b/SOURCES/opensslconf-new.h @@ -0,0 +1,30 @@ +/* This file is here to prevent a file conflict on multiarch systems. A + * conflict will frequently occur because arch-specific build-time + * configuration options are stored (and used, so they can't just be stripped + * out) in opensslconf.h. The original opensslconf.h has been renamed. + * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */ + +#ifdef openssl_opensslconf_multilib_redirection_h +#error "Do not define openssl_opensslconf_multilib_redirection_h!" +#endif +#define openssl_opensslconf_multilib_redirection_h + +#if defined(__i386__) +#include "opensslconf-i386.h" +#elif defined(__ia64__) +#include "opensslconf-ia64.h" +#elif defined(__powerpc64__) +#include "opensslconf-ppc64.h" +#elif defined(__powerpc__) +#include "opensslconf-ppc.h" +#elif defined(__s390x__) +#include "opensslconf-s390x.h" +#elif defined(__s390__) +#include "opensslconf-s390.h" +#elif defined(__x86_64__) +#include "opensslconf-x86_64.h" +#else +#error "This openssl-devel package does not work your architecture?" +#endif + +#undef openssl_opensslconf_multilib_redirection_h diff --git a/SPECS/openssl098e.spec b/SPECS/openssl098e.spec new file mode 100644 index 0000000..f90d6ac --- /dev/null +++ b/SPECS/openssl098e.spec @@ -0,0 +1,1104 @@ +# For the curious: +# 0.9.5a soversion = 0 +# 0.9.6 soversion = 1 +# 0.9.6a soversion = 2 +# 0.9.6c soversion = 3 +# 0.9.7a soversion = 4 +# 0.9.7ef soversion = 5 +# 0.9.8abe soversion = 6 +%define soversion 6 + +# Number of threads to spawn when testing some threading fixes. +%define thread_test_threads %{?threads:%{threads}}%{!?threads:1} + +# Arches on which we need to prevent arch conflicts on opensslconf.h, must +# also be handled in opensslconf-new.h. +%define multilib_arches %{ix86} ia64 ppc ppc64 s390 s390x x86_64 + +Summary: A compatibility version of a general cryptography and TLS library +Name: openssl098e +Version: 0.9.8e +Release: 29%{?dist}.3 +# The tarball is based on the openssl-fips-1.2.0-test.tar.gz tarball +Source: openssl-fips-%{version}-usa.tar.bz2 +Source1: hobble-openssl +Source8: openssl-thread-test.c +Source9: opensslconf-new.h +Source10: opensslconf-new-warning.h +Source11: README.FIPS +# Build changes +Patch0: openssl-fips-0.9.8e-redhat.patch +Patch1: openssl-0.9.8a-defaults.patch +Patch2: openssl-0.9.8a-link-krb5.patch +Patch3: openssl-0.9.8b-soversion.patch +Patch4: openssl-fips-0.9.8e-enginesdir.patch +Patch5: openssl-0.9.8a-no-rpath.patch +Patch6: openssl-fips-0.9.8e-perlfind.patch +Patch7: openssl-fips-0.9.8e-manfix.patch +# Functionality changes +Patch32: openssl-fips-0.9.8e-ia64.patch +Patch34: openssl-0.9.6-x509.patch +Patch35: openssl-0.9.7-beta5-version-add-engines.patch +Patch38: openssl-0.9.8a-reuse-cipher-change.patch +Patch39: openssl-0.9.8b-ipv6-apps.patch +Patch40: openssl-fips-0.9.8e-casts.patch +Patch41: openssl-fips-0.9.8e-asm-sign.patch +# Backported fixes including security fixes +Patch61: openssl-0.9.8b-aliasing-bug.patch +Patch62: openssl-0.9.8b-x509-name-cmp.patch +Patch64: openssl-fips-0.9.8e-dtls-fixes.patch +Patch65: openssl-0.9.8b-cve-2007-5135.patch +Patch67: openssl-fips-0.9.8e-aescfb.patch +Patch68: openssl-fips-0.9.8e-abi.patch +Patch69: openssl-fips-0.9.8e-fipsmode.patch +Patch70: openssl-fips-0.9.8e-bn-fixes.patch +Patch71: openssl-fips-0.9.8e-use-fipscheck.patch +Patch72: openssl-fips-0.9.8e-env-zlib.patch +Patch73: openssl-fips-0.9.8e-default-paths.patch +Patch74: openssl-fips-0.9.8e-evp-nonfips.patch +Patch75: openssl-fips-0.9.8e-cve-2008-5077.patch +Patch76: openssl-fips-0.9.8e-multi-crl.patch +Patch77: openssl-fips-0.9.8e-no-pairwise.patch +Patch78: openssl-fips-0.9.8e-rng-seed.patch +Patch79: openssl-fips-0.9.8e-bad-mime.patch +Patch80: openssl-fips-0.9.8e-cve-2009-0590.patch +Patch81: openssl-fips-0.9.8e-dtls-dos.patch +Patch82: openssl-fips-0.9.8e-algo-doc.patch +Patch83: openssl-fips-0.9.8e-cve-2009-2409.patch +Patch84: openssl-fips-0.9.8e-cve-2009-4355.patch +Patch85: openssl-fips-0.9.8e-cve-2009-3555.patch +Patch86: openssl-fips-0.9.8e-cve-2010-0433.patch +Patch87: openssl-fips-0.9.8e-cve-2009-3245.patch +Patch88: openssl-fips-0.9.8e-cve-2010-4180.patch +Patch89: openssl-fips-0.9.8e-ssl-sha256.patch +Patch90: openssl-fips-0.9.8e-ciph-sort.patch +Patch91: openssl-fips-0.9.8e-apps-dgst.patch +Patch92: openssl-fips-0.9.8e-tls-version.patch +Patch93: openssl-fips-0.9.8e-chil-fixes.patch +Patch94: openssl-fips-0.9.8e-dh-check.patch +Patch95: openssl-fips-0.9.8e-sha2test.patch +Patch96: openssl-fips-0.9.8e-apps-yesno.patch +Patch97: openssl-fips-0.9.8e-dtls-fixes2.patch +Patch98: openssl-fips-0.9.8e-cve-2011-4109.patch +Patch99: openssl-fips-0.9.8e-cve-2011-4576.patch +Patch100: openssl-fips-0.9.8e-cve-2011-4619.patch +Patch101: openssl-fips-0.9.8e-cve-2012-0884.patch +Patch102: openssl-fips-0.9.8e-cve-2012-1165.patch +Patch103: openssl-fips-0.9.8e-cve-2012-2110.patch +Patch104: openssl-fips-0.9.8e-cve-2012-2333.patch +Patch105: openssl-fips-0.9.8e-secure-getenv.patch +Patch106: openssl-fips-0.9.8e-cve-2013-0166.patch +Patch107: openssl-fips-0.9.8e-cve-2013-0169.patch +Patch108: openssl-fips-0.9.8e-cve-2014-0224.patch +Patch122: openssl-fips-0.9.8e-cve-2015-0293.patch +Patch128: openssl-fips-0.9.8e-cve-2015-3197.patch +Patch129: openssl-fips-0.9.8e-disable-sslv2.patch + +License: OpenSSL +Group: System Environment/Libraries +URL: http://www.openssl.org/ +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: mktemp, krb5-devel, perl, sed, zlib-devel, /usr/bin/cmp +BuildRequires: /usr/bin/rename +Requires: mktemp, ca-certificates >= 2008-5 + +# for compatibility with previous versions, not needed for (and doesn't build +# on) newly added platforms +ExcludeArch: aarch64 ppc64le + +%description +The OpenSSL toolkit provides support for secure communications between +machines. OpenSSL includes a certificate management tool and shared +libraries which provide various cryptographic algorithms and +protocols. This version of OpenSSL package is provided for compatibility +with the previous Red Hat Enterprise Linux release. + + +%prep +%setup -q -n openssl-fips-%{version} + +%{SOURCE1} > /dev/null +%patch0 -p1 -b .redhat +%patch1 -p1 -b .defaults +# Fix link line for libssl (bug #111154). +%patch2 -p1 -b .krb5 +%patch3 -p1 -b .soversion +%patch4 -p1 -b .enginesdir +%patch5 -p1 -b .no-rpath +%patch6 -p1 -b .perlfind +%patch7 -p1 -b .manfix + +%patch32 -p1 -b .ia64 +%patch34 -p1 -b .x509 +%patch35 -p1 -b .version-add-engines +%patch38 -p1 -b .cipher-change +%patch39 -p1 -b .ipv6-apps +%patch40 -p1 -b .casts +%patch41 -p1 -b .sign + +%patch61 -p1 -b .aliasing-bug +%patch62 -p1 -b .name-cmp +%patch64 -p1 -b .dtls-fixes +%patch65 -p1 -b .shciphers +%patch67 -p1 -b .aescfb +%patch68 -p1 -b .abi +%patch69 -p1 -b .fipsmode +%patch70 -p1 -b .bn-fixes +%patch71 -p1 -b .use-fipscheck +%patch72 -p1 -b .env-zlib +%patch73 -p1 -b .default-paths +%patch74 -p1 -b .nonfips +%patch75 -p1 -b .verifysig +%patch76 -p1 -b .multi-crl +%patch77 -p1 -b .no-pairwise +%patch78 -p1 -b .rng-seed +%patch79 -p1 -b .bad-mime +%patch80 -p1 -b .bad-string +%patch81 -p1 -b .dtls-dos +%patch82 -p1 -b .algo-doc +%patch83 -p1 -b .nomd2 +%patch84 -p1 -b .compleak +%patch85 -p1 -b .reneg +%patch86 -p1 -b .nullprinc +%patch87 -p1 -b .wexpand +%patch88 -p1 -b .disable-nsbug +%patch89 -p1 -b .sha256 +%patch90 -p1 -b .sort +%patch91 -p1 -b .dgst +%patch92 -p1 -b .tlsver +%patch93 -p1 -b .chil +%patch94 -p1 -b .dh-check +%patch95 -p1 -b .sha2test +%patch96 -p1 -b .yesno +%patch97 -p1 -b .dtls-fixes2 +%patch98 -p1 -b .doublefree +%patch99 -p1 -b .padding +%patch100 -p1 -b .sgc-dos +%patch101 -p1 -b .cms-mma +%patch102 -p1 -b .bad-mime2 +%patch103 -p1 -b .biobuf +%patch104 -p1 -b .reclen +%patch105 -p1 -b .secure-getenv +%patch106 -p1 -b .ocsp-dos +%patch107 -p1 -b .lucky13 +%patch108 -p1 -b .keying-mitm +%patch122 -p1 -b .ssl2-assert +%patch128 -p1 -b .ssl2-ciphers +%patch129 -p1 -b .disable-sslv2 + +# Modify the various perl scripts to reference perl in the right location. +perl util/perlpath.pl `dirname %{__perl}` + +# Generate a table with the compile settings for my perusal. +touch Makefile +make TABLE PERL=%{__perl} + +%build +# Figure out which flags we want to use. +# default +sslarch=%{_os}-%{_arch} +%ifarch %ix86 +sslarch=linux-elf +if ! echo %{_target} | grep -q i686 ; then + sslflags="no-asm 386" +fi +%endif +%ifarch sparc +sslarch=linux-sparcv9 +sslflags=no-asm +%endif +%ifarch alpha +sslarch=linux-alpha-gcc +%endif +%ifarch s390 +# The -fno-regmove is a workaround for bug #199604 +sslarch="linux-generic32 -DB_ENDIAN -DNO_ASM -march=z900 -fno-regmove" +%endif +%ifarch s390x +sslarch="linux-generic64 -DB_ENDIAN -DNO_ASM" +%endif +# ia64, x86_64, ppc, ppc64 are OK by default +# Configure the build tree. Override OpenSSL defaults with known-good defaults +# usable on all platforms. The Configure script already knows to use -fPIC and +# RPM_OPT_FLAGS, so we can skip specifiying them here. +./Configure \ + --prefix=/usr --openssldir=%{_sysconfdir}/pki/tls ${sslflags} \ + zlib no-idea no-mdc2 no-rc5 no-ec no-ecdh no-ecdsa \ + --with-krb5-flavor=MIT --enginesdir=%{_libdir}/openssl098e/engines \ + --with-krb5-dir=/usr shared \ + ${sslarch} fipscanisterbuild + +# Add -Wa,--noexecstack here so that libcrypto's assembler modules will be +# marked as not requiring an executable stack. +RPM_OPT_FLAGS="$RPM_OPT_FLAGS -Wa,--noexecstack -DOPENSSL_USE_NEW_FUNCTIONS -fno-strict-aliasing" +make depend +make all + +# Generate hashes for the included certs. +make rehash + +# Overwrite FIPS README +cp -f %{SOURCE11} . + +%check +# Verify that what was compiled actually works. +LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +export LD_LIBRARY_PATH +make -C test apps tests +%{__cc} -o openssl-thread-test \ + `krb5-config --cflags` \ + -I./include \ + $RPM_OPT_FLAGS \ + %{SOURCE8} \ + -L. \ + -lssl -lcrypto \ + `krb5-config --libs` \ + -lpthread -lz -ldl +./openssl-thread-test --threads %{thread_test_threads} + +# Add generation of HMAC checksum of the final stripped library +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + fips/fips_standalone_sha1 $RPM_BUILD_ROOT%{_libdir}/libcrypto.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{version}.hmac \ + ln -sf .libcrypto.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{soversion}.hmac \ + fips/fips_standalone_sha1 $RPM_BUILD_ROOT%{_libdir}/libssl.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{version}.hmac \ + ln -sf .libssl.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{soversion}.hmac \ +%{nil} + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +# Install OpenSSL. +install -d $RPM_BUILD_ROOT{%{_bindir},%{_includedir},%{_libdir},%{_mandir},%{_libdir}/openssl098e} +make INSTALL_PREFIX=$RPM_BUILD_ROOT install +make INSTALL_PREFIX=$RPM_BUILD_ROOT install_docs +# OpenSSL install doesn't use correct _libdir on 64 bit archs +[ "%{_libdir}" != /usr/lib ] && mv $RPM_BUILD_ROOT/usr/lib/lib*.so.%{soversion} $RPM_BUILD_ROOT%{_libdir}/ +mv $RPM_BUILD_ROOT/usr/lib/engines $RPM_BUILD_ROOT%{_libdir}/openssl098e +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/man +rm -f $RPM_BUILD_ROOT/usr/lib/*.{a,so} || : +rename so.%{soversion} so.%{version} $RPM_BUILD_ROOT%{_libdir}/*.so.%{soversion} +for lib in $RPM_BUILD_ROOT%{_libdir}/*.so.%{version} ; do + chmod 755 ${lib} + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/`basename ${lib} .%{version}`.%{soversion} +done + +# Delete man pages in the compat package +rm -rf $RPM_BUILD_ROOT%{_mandir} + +# Delete configuration files +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/pki + +# Remove devel stuff +rm -rf $RPM_BUILD_ROOT/usr/lib/pkgconfig +rm -rf $RPM_BUILD_ROOT/%{_includedir} + +# Remove binaries +rm -rf $RPM_BUILD_ROOT/%{_bindir} + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc FAQ LICENSE CHANGES NEWS INSTALL README +%doc README.FIPS + +%attr(0755,root,root) %{_libdir}/*.so.%{version} +%attr(0755,root,root) %{_libdir}/*.so.%{soversion} +%attr(0644,root,root) %{_libdir}/.libcrypto.so.*.hmac +%attr(0644,root,root) %{_libdir}/.libssl.so.*.hmac +%dir %{_libdir}/openssl098e +%attr(0755,root,root) %{_libdir}/openssl098e/engines + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%changelog +* Fri Mar 4 2016 Tomas Mraz 0.9.8e-29.3 +- fix CVE-2015-0293 - triggerable assert in SSLv2 server +- fix CVE-2015-3197 - SSLv2 ciphersuite enforcement +- disable SSLv2 in the generic TLS method + +* Tue Jun 3 2014 Tomas Mraz 0.9.8e-29.2 +- fix for CVE-2014-0224 - SSL/TLS MITM vulnerability + +* Fri Jan 24 2014 Daniel Mach - 0.9.8e-29 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 0.9.8e-28 +- Mass rebuild 2013-12-27 + +* Wed Jul 17 2013 Tomas Mraz 0.9.8e-27 +- fix for CVE-2013-0169 - SSL/TLS CBC timing attack (#907589) +- fix for CVE-2013-0166 - DoS in OCSP signatures checking (#908052) +- enable compression only if explicitly asked for or OPENSSL_DEFAULT_ZLIB + environment variable is set (fixes CVE-2012-4929 #857051) +- use secure_getenv() everywhere instead of getenv() (#839735) + +* Wed Jun 20 2012 Tomas Mraz 0.9.8e-26 +- merge fixes from the latest openssl-0.9.8e package + +* Fri Apr 20 2012 Tomas Mraz 0.9.8e-18 +- fix for CVE-2012-2110 - memory corruption in asn1_d2i_read_bio() (#814185) + +* Fri Apr 16 2010 Tomas Mraz 0.9.8e-17 +- create compat package + +* Fri Mar 12 2010 Tomas Mraz 0.9.8e-16 +- fix CVE-2009-3245 - add missing bn_wexpand return checks (#570924) + +* Thu Mar 4 2010 Tomas Mraz 0.9.8e-15 +- fix CVE-2010-0433 - do not pass NULL princ to krb5_kt_get_entry which + in the RHEL-5 and newer versions will crash in such case (#569774) + +* Thu Feb 18 2010 Tomas Mraz 0.9.8e-14 +- fix CVE-2009-3555 - support the safe renegotiation extension and + do not allow legacy renegotiation on the server by default (#533125) + +* Thu Jan 14 2010 Tomas Mraz 0.9.8e-13 +- fix CVE-2009-2409 - drop MD2 algorithm from EVP tables (#510197) +- fix CVE-2009-4355 - do not leak memory when CRYPTO_cleanup_all_ex_data() + is called prematurely by application (#546707) + +* Mon Jun 29 2009 Tomas Mraz 0.9.8e-12 +- abort if selftests failed and random number generator is polled +- mention EVP_aes and EVP_sha2xx routines in the manpages +- add README.FIPS + +* Thu May 21 2009 Tomas Mraz 0.9.8e-10 +- fix CVE-2009-1386 CVE-2009-1387 (DTLS DoS problems) + (#503685, #503688) + +* Thu May 21 2009 Tomas Mraz 0.9.8e-9 +- fix CVE-2009-1377 CVE-2009-1378 CVE-2009-1379 + (DTLS DoS problems) (#501253, #501254, #501572) + +* Wed Apr 15 2009 Tomas Mraz 0.9.8e-8 +- support multiple CRLs with same subject in a store (#457134) +- fix CVE-2009-0590 - reject incorrectly encoded ASN.1 strings (#492304) +- seed FIPS rng directly from kernel random device +- do not require fipscheck to build the package (#475798) +- call pairwise key tests in FIPS mode only (#479817) +- do not crash when parsing bad mime data (#472440) + +* Tue Dec 16 2008 Tomas Mraz 0.9.8e-7 +- fix CVE-2008-5077 - incorrect checks for malformed signatures (#476671) + +* Fri Oct 31 2008 Tomas Mraz 0.9.8e-6 +- allow lookup of algorithms in engine + +* Fri Oct 24 2008 Tomas Mraz 0.9.8e-5 +- implement the integrity checking inside libcrypto so OpenSSL + can be used in FIPS mode by the fipscheck library + +* Thu Oct 9 2008 Tomas Mraz 0.9.8e-4 +- FIPS mode kernel flag is /proc/sys/crypto/fips_enabled + +* Wed Sep 10 2008 Tomas Mraz 0.9.8e-3 +- disable strict aliasing + +* Tue Sep 9 2008 Tomas Mraz 0.9.8e-2 +- more changes for FIPS validation (#444800) +- correctly initialize default CA paths (#450987) +- allow disabling zlib support through environment (#442624) + +* Tue Jul 15 2008 Tomas Mraz 0.9.8e-1 +- rebase to version undergoing FIPS validation (#455634) + +* Tue Jan 15 2008 Tomas Mraz 0.9.8b-10 +- compile with -march=z900 on s390 for performance improvements (#250818) +- make ssl session ID matching strict (#233599) + +* Mon Oct 8 2007 Tomas Mraz 0.9.8b-9 +- fix CVE-2007-3108 - side channel attack on private keys (#250581) +- fix CVE-2007-5135 - off-by-one in SSL_get_shared_ciphers (#309881) +- fix CVE-2007-4995 - out of order DTLS fragments buffer overflow (#321221) + +* Thu Nov 30 2006 Tomas Mraz 0.9.8b-8.3 +- the previous change still didn't make X509_NAME_cmp transitive + +* Thu Nov 23 2006 Tomas Mraz 0.9.8b-8.2 +- make X509_NAME_cmp transitive otherwise certificate lookup + is broken (#216050) + +* Fri Nov 3 2006 Tomas Mraz 0.9.8b-8.1 +- aliasing bug in engine loading, patch by IBM (#213216) + +* Mon Oct 2 2006 Tomas Mraz 0.9.8b-8 +- CVE-2006-2940 fix was incorrect (#208744) + +* Mon Sep 25 2006 Tomas Mraz 0.9.8b-7 +- fix CVE-2006-2937 - mishandled error on ASN.1 parsing (#207276) +- fix CVE-2006-2940 - parasitic public keys DoS (#207274) +- fix CVE-2006-3738 - buffer overflow in SSL_get_shared_ciphers (#206940) +- fix CVE-2006-4343 - sslv2 client DoS (#206940) + +* Tue Sep 5 2006 Tomas Mraz 0.9.8b-6 +- fix CVE-2006-4339 - prevent attack on PKCS#1 v1.5 signatures (#205180) + +* Wed Aug 2 2006 Tomas Mraz - 0.9.8b-5 +- set buffering to none on stdio/stdout FILE when bufsize is set (#200580) + patch by IBM + +* Fri Jul 28 2006 Alexandre Oliva - 0.9.8b-4.1 +- rebuild with new binutils (#200330) + +* Fri Jul 21 2006 Tomas Mraz - 0.9.8b-4 +- add a temporary workaround for sha512 test failure on s390 (#199604) + +* Thu Jul 20 2006 Tomas Mraz +- add ipv6 support to s_client and s_server (by Jan Pazdziora) (#198737) +- add patches for BN threadsafety, AES cache collision attack hazard fix and + pkcs7 code memleak fix from upstream CVS + +* Wed Jul 12 2006 Jesse Keating - 0.9.8b-3.1 +- rebuild + +* Wed Jun 21 2006 Tomas Mraz - 0.9.8b-3 +- dropped libica and ica engine from build + +* Wed Jun 21 2006 Joe Orton +- update to new CA bundle from mozilla.org; adds CA certificates + from netlock.hu and startcom.org + +* Mon Jun 5 2006 Tomas Mraz - 0.9.8b-2 +- fixed a few rpmlint warnings +- better fix for #173399 from upstream +- upstream fix for pkcs12 + +* Thu May 11 2006 Tomas Mraz - 0.9.8b-1 +- upgrade to new version, stays ABI compatible +- there is no more linux/config.h (it was empty anyway) + +* Tue Apr 4 2006 Tomas Mraz - 0.9.8a-6 +- fix stale open handles in libica (#177155) +- fix build if 'rand' or 'passwd' in buildroot path (#178782) +- initialize VIA Padlock engine (#186857) + +* Fri Feb 10 2006 Jesse Keating - 0.9.8a-5.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 0.9.8a-5.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Dec 15 2005 Tomas Mraz 0.9.8a-5 +- don't include SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + in SSL_OP_ALL (#175779) + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Tue Nov 29 2005 Tomas Mraz 0.9.8a-4 +- fix build (-lcrypto was erroneusly dropped) of the updated libica +- updated ICA engine to 1.3.6-rc3 + +* Tue Nov 22 2005 Tomas Mraz 0.9.8a-3 +- disable builtin compression methods for now until they work + properly (#173399) + +* Wed Nov 16 2005 Tomas Mraz 0.9.8a-2 +- don't set -rpath for openssl binary + +* Tue Nov 8 2005 Tomas Mraz 0.9.8a-1 +- new upstream version +- patches partially renumbered + +* Fri Oct 21 2005 Tomas Mraz 0.9.7f-11 +- updated IBM ICA engine library and patch to latest upstream version + +* Wed Oct 12 2005 Tomas Mraz 0.9.7f-10 +- fix CAN-2005-2969 - remove SSL_OP_MSIE_SSLV2_RSA_PADDING which + disables the countermeasure against man in the middle attack in SSLv2 + (#169863) +- use sha1 as default for CA and cert requests - CAN-2005-2946 (#169803) + +* Tue Aug 23 2005 Tomas Mraz 0.9.7f-9 +- add *.so.soversion as symlinks in /lib (#165264) +- remove unpackaged symlinks (#159595) +- fixes from upstream (constant time fixes for DSA, + bn assembler div on ppc arch, initialize memory on realloc) + +* Thu Aug 11 2005 Phil Knirsch 0.9.7f-8 +- Updated ICA engine IBM patch to latest upstream version. + +* Thu May 19 2005 Tomas Mraz 0.9.7f-7 +- fix CAN-2005-0109 - use constant time/memory access mod_exp + so bits of private key aren't leaked by cache eviction (#157631) +- a few more fixes from upstream 0.9.7g + +* Wed Apr 27 2005 Tomas Mraz 0.9.7f-6 +- use poll instead of select in rand (#128285) +- fix Makefile.certificate to point to /etc/pki/tls +- change the default string mask in ASN1 to PrintableString+UTF8String + +* Mon Apr 25 2005 Joe Orton 0.9.7f-5 +- update to revision 1.37 of Mozilla CA bundle + +* Thu Apr 21 2005 Tomas Mraz 0.9.7f-4 +- move certificates to _sysconfdir/pki/tls (#143392) +- move CA directories to _sysconfdir/pki/CA +- patch the CA script and the default config so it points to the + CA directories + +* Fri Apr 1 2005 Tomas Mraz 0.9.7f-3 +- uninitialized variable mustn't be used as input in inline + assembly +- reenable the x86_64 assembly again + +* Thu Mar 31 2005 Tomas Mraz 0.9.7f-2 +- add back RC4_CHAR on ia64 and x86_64 so the ABI isn't broken +- disable broken bignum assembly on x86_64 + +* Wed Mar 30 2005 Tomas Mraz 0.9.7f-1 +- reenable optimizations on ppc64 and assembly code on ia64 +- upgrade to new upstream version (no soname bump needed) +- disable thread test - it was testing the backport of the + RSA blinding - no longer needed +- added support for changing serial number to + Makefile.certificate (#151188) +- make ca-bundle.crt a config file (#118903) + +* Tue Mar 1 2005 Tomas Mraz 0.9.7e-3 +- libcrypto shouldn't depend on libkrb5 (#135961) + +* Mon Feb 28 2005 Tomas Mraz 0.9.7e-2 +- rebuild + +* Mon Feb 28 2005 Tomas Mraz 0.9.7e-1 +- new upstream source, updated patches +- added patch so we are hopefully ABI compatible with upcoming + 0.9.7f + +* Thu Feb 10 2005 Tomas Mraz +- Support UTF-8 charset in the Makefile.certificate (#134944) +- Added cmp to BuildPrereq + +* Thu Jan 27 2005 Joe Orton 0.9.7a-46 +- generate new ca-bundle.crt from Mozilla certdata.txt (revision 1.32) + +* Thu Dec 23 2004 Phil Knirsch 0.9.7a-45 +- Fixed and updated libica-1.3.4-urandom.patch patch (#122967) + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-44 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-43 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-42 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-41 +- remove der_chop, as upstream cvs has done (CAN-2004-0975, #140040) + +* Tue Oct 05 2004 Phil Knirsch 0.9.7a-40 +- Include latest libica version with important bugfixes + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 14 2004 Phil Knirsch 0.9.7a-38 +- Updated ICA engine IBM patch to latest upstream version. + +* Mon Jun 7 2004 Nalin Dahyabhai 0.9.7a-37 +- build for linux-alpha-gcc instead of alpha-gcc on alpha (Jeff Garzik) + +* Tue May 25 2004 Nalin Dahyabhai 0.9.7a-36 +- handle %%{_arch}=i486/i586/i686/athlon cases in the intermediate + header (#124303) + +* Thu Mar 25 2004 Joe Orton 0.9.7a-35 +- add security fixes for CAN-2004-0079, CAN-2004-0112 + +* Tue Mar 16 2004 Phil Knirsch +- Fixed libica filespec. + +* Thu Mar 11 2004 Nalin Dahyabhai 0.9.7a-34 +- ppc/ppc64 define __powerpc__/__powerpc64__, not __ppc__/__ppc64__, fix + the intermediate header + +* Wed Mar 10 2004 Nalin Dahyabhai 0.9.7a-33 +- add an intermediate which points to the right + arch-specific opensslconf.h on multilib arches + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Thu Feb 26 2004 Phil Knirsch 0.9.7a-32 +- Updated libica to latest upstream version 1.3.5. + +* Tue Feb 17 2004 Phil Knirsch 0.9.7a-31 +- Update ICA crypto engine patch from IBM to latest version. + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Phil Knirsch 0.9.7a-29 +- rebuilt + +* Wed Feb 11 2004 Phil Knirsch 0.9.7a-28 +- Fixed libica build. + +* Wed Feb 4 2004 Nalin Dahyabhai +- add "-ldl" to link flags added for Linux-on-ARM (#99313) + +* Wed Feb 4 2004 Joe Orton 0.9.7a-27 +- updated ca-bundle.crt: removed expired GeoTrust roots, added + freessl.com root, removed trustcenter.de Class 0 root + +* Sun Nov 30 2003 Tim Waugh 0.9.7a-26 +- Fix link line for libssl (bug #111154). + +* Fri Oct 24 2003 Nalin Dahyabhai 0.9.7a-25 +- add dependency on zlib-devel for the -devel package, which depends on zlib + symbols because we enable zlib for libssl (#102962) + +* Fri Oct 24 2003 Phil Knirsch 0.9.7a-24 +- Use /dev/urandom instead of PRNG for libica. +- Apply libica-1.3.5 fix for /dev/urandom in icalinux.c +- Use latest ICA engine patch from IBM. + +* Sat Oct 4 2003 Nalin Dahyabhai 0.9.7a-22.1 +- rebuild + +* Wed Oct 1 2003 Nalin Dahyabhai 0.9.7a-22 +- rebuild (22 wasn't actually built, fun eh?) + +* Tue Sep 30 2003 Nalin Dahyabhai 0.9.7a-23 +- re-disable optimizations on ppc64 + +* Tue Sep 30 2003 Joe Orton +- add a_mbstr.c fix for 64-bit platforms from CVS + +* Tue Sep 30 2003 Nalin Dahyabhai 0.9.7a-22 +- add -Wa,--noexecstack to RPM_OPT_FLAGS so that assembled modules get tagged + as not needing executable stacks + +* Mon Sep 29 2003 Nalin Dahyabhai 0.9.7a-21 +- rebuild + +* Thu Sep 25 2003 Nalin Dahyabhai +- re-enable optimizations on ppc64 + +* Thu Sep 25 2003 Nalin Dahyabhai +- remove exclusivearch + +* Wed Sep 24 2003 Nalin Dahyabhai 0.9.7a-20 +- only parse a client cert if one was requested +- temporarily exclusivearch for %%{ix86} + +* Tue Sep 23 2003 Nalin Dahyabhai +- add security fixes for protocol parsing bugs (CAN-2003-0543, CAN-2003-0544) + and heap corruption (CAN-2003-0545) +- update RHNS-CA-CERT files +- ease back on the number of threads used in the threading test + +* Wed Sep 17 2003 Matt Wilson 0.9.7a-19 +- rebuild to fix gzipped file md5sums (#91211) + +* Mon Aug 25 2003 Phil Knirsch 0.9.7a-18 +- Updated libica to version 1.3.4. + +* Thu Jul 17 2003 Nalin Dahyabhai 0.9.7a-17 +- rebuild + +* Tue Jul 15 2003 Nalin Dahyabhai 0.9.7a-10.9 +- free the kssl_ctx structure when we free an SSL structure (#99066) + +* Fri Jul 11 2003 Nalin Dahyabhai 0.9.7a-16 +- rebuild + +* Thu Jul 10 2003 Nalin Dahyabhai 0.9.7a-15 +- lower thread test count on s390x + +* Tue Jul 8 2003 Nalin Dahyabhai 0.9.7a-14 +- rebuild + +* Thu Jun 26 2003 Nalin Dahyabhai 0.9.7a-13 +- disable assembly on arches where it seems to conflict with threading + +* Thu Jun 26 2003 Phil Knirsch 0.9.7a-12 +- Updated libica to latest upstream version 1.3.0 + +* Wed Jun 11 2003 Nalin Dahyabhai 0.9.7a-9.9 +- rebuild + +* Wed Jun 11 2003 Nalin Dahyabhai 0.9.7a-11 +- rebuild + +* Tue Jun 10 2003 Nalin Dahyabhai 0.9.7a-10 +- ubsec: don't stomp on output data which might also be input data + +* Tue Jun 10 2003 Nalin Dahyabhai 0.9.7a-9 +- temporarily disable optimizations on ppc64 + +* Mon Jun 9 2003 Nalin Dahyabhai +- backport fix for engine-used-for-everything from 0.9.7b +- backport fix for prng not being seeded causing problems, also from 0.9.7b +- add a check at build-time to ensure that RSA is thread-safe +- keep perlpath from stomping on the libica configure scripts + +* Fri Jun 6 2003 Nalin Dahyabhai +- thread-safety fix for RSA blinding + +* Wed Jun 04 2003 Elliot Lee 0.9.7a-8 +- rebuilt + +* Fri May 30 2003 Phil Knirsch 0.9.7a-7 +- Added libica-1.2 to openssl (featurerequest). + +* Wed Apr 16 2003 Nalin Dahyabhai 0.9.7a-6 +- fix building with incorrect flags on ppc64 + +* Wed Mar 19 2003 Nalin Dahyabhai 0.9.7a-5 +- add patch to harden against Klima-Pokorny-Rosa extension of Bleichenbacher's + attack (CAN-2003-0131) + +* Mon Mar 17 2003 Nalin Dahyabhai 0.9.7a-4 +- add patch to enable RSA blinding by default, closing a timing attack + (CAN-2003-0147) + +* Wed Mar 5 2003 Nalin Dahyabhai 0.9.7a-3 +- disable use of BN assembly module on x86_64, but continue to allow inline + assembly (#83403) + +* Thu Feb 27 2003 Nalin Dahyabhai 0.9.7a-2 +- disable EC algorithms + +* Wed Feb 19 2003 Nalin Dahyabhai 0.9.7a-1 +- update to 0.9.7a + +* Wed Feb 19 2003 Nalin Dahyabhai 0.9.7-8 +- add fix to guard against attempts to allocate negative amounts of memory +- add patch for CAN-2003-0078, fixing a timing attack + +* Thu Feb 13 2003 Elliot Lee 0.9.7-7 +- Add openssl-ppc64.patch + +* Mon Feb 10 2003 Nalin Dahyabhai 0.9.7-6 +- EVP_DecryptInit should call EVP_CipherInit() instead of EVP_CipherInit_ex(), + to get the right behavior when passed uninitialized context structures + (#83766) +- build with -mcpu=ev5 on alpha family (#83828) + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Fri Jan 17 2003 Phil Knirsch 0.9.7-4 +- Added IBM hw crypto support patch. + +* Wed Jan 15 2003 Nalin Dahyabhai +- add missing builddep on sed + +* Thu Jan 9 2003 Bill Nottingham 0.9.7-3 +- debloat +- fix broken manpage symlinks + +* Wed Jan 8 2003 Nalin Dahyabhai 0.9.7-2 +- fix double-free in 'openssl ca' + +* Fri Jan 3 2003 Nalin Dahyabhai 0.9.7-1 +- update to 0.9.7 final + +* Tue Dec 17 2002 Nalin Dahyabhai 0.9.7-0 +- update to 0.9.7 beta6 (DO NOT USE UNTIL UPDATED TO FINAL 0.9.7) + +* Wed Dec 11 2002 Nalin Dahyabhai +- update to 0.9.7 beta5 (DO NOT USE UNTIL UPDATED TO FINAL 0.9.7) + +* Tue Oct 22 2002 Nalin Dahyabhai 0.9.6b-30 +- add configuration stanza for x86_64 and use it on x86_64 +- build for linux-ppc on ppc +- start running the self-tests again + +* Wed Oct 02 2002 Elliot Lee 0.9.6b-29hammer.3 +- Merge fixes from previous hammer packages, including general x86-64 and + multilib + +* Tue Aug 6 2002 Nalin Dahyabhai 0.9.6b-29 +- rebuild + +* Thu Aug 1 2002 Nalin Dahyabhai 0.9.6b-28 +- update asn patch to fix accidental reversal of a logic check + +* Wed Jul 31 2002 Nalin Dahyabhai 0.9.6b-27 +- update asn patch to reduce chance that compiler optimization will remove + one of the added tests + +* Wed Jul 31 2002 Nalin Dahyabhai 0.9.6b-26 +- rebuild + +* Mon Jul 29 2002 Nalin Dahyabhai 0.9.6b-25 +- add patch to fix ASN.1 vulnerabilities + +* Thu Jul 25 2002 Nalin Dahyabhai 0.9.6b-24 +- add backport of Ben Laurie's patches for OpenSSL 0.9.6d + +* Wed Jul 17 2002 Nalin Dahyabhai 0.9.6b-23 +- own _datadir/ssl/misc + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Fri May 17 2002 Nalin Dahyabhai 0.9.6b-20 +- free ride through the build system (whee!) + +* Thu May 16 2002 Nalin Dahyabhai 0.9.6b-19 +- rebuild in new environment + +* Thu Apr 4 2002 Nalin Dahyabhai 0.9.6b-17, 0.9.6b-18 +- merge RHL-specific bits into stronghold package, rename + +* Tue Apr 02 2002 Gary Benson stronghold-0.9.6c-2 +- add support for Chrysalis Luna token + +* Tue Mar 26 2002 Gary Benson +- disable AEP random number generation, other AEP fixes + +* Fri Mar 15 2002 Nalin Dahyabhai 0.9.6b-15 +- only build subpackages on primary arches + +* Thu Mar 14 2002 Nalin Dahyabhai 0.9.6b-13 +- on ia32, only disable use of assembler on i386 +- enable assembly on ia64 + +* Mon Jan 7 2002 Florian La Roche 0.9.6b-11 +- fix sparcv9 entry + +* Mon Jan 7 2002 Gary Benson stronghold-0.9.6c-1 +- upgrade to 0.9.6c +- bump BuildArch to i686 and enable assembler on all platforms +- synchronise with shrimpy and rawhide +- bump soversion to 3 + +* Wed Oct 10 2001 Florian La Roche +- delete BN_LLONG for s390x, patch from Oliver Paukstadt + +* Mon Sep 17 2001 Nalin Dahyabhai 0.9.6b-9 +- update AEP driver patch + +* Mon Sep 10 2001 Nalin Dahyabhai +- adjust RNG disabling patch to match version of patch from Broadcom + +* Fri Sep 7 2001 Nalin Dahyabhai 0.9.6b-8 +- disable the RNG in the ubsec engine driver + +* Tue Aug 28 2001 Nalin Dahyabhai 0.9.6b-7 +- tweaks to the ubsec engine driver + +* Fri Aug 24 2001 Nalin Dahyabhai 0.9.6b-6 +- tweaks to the ubsec engine driver + +* Thu Aug 23 2001 Nalin Dahyabhai 0.9.6b-5 +- update ubsec engine driver from Broadcom + +* Fri Aug 10 2001 Nalin Dahyabhai 0.9.6b-4 +- move man pages back to %%{_mandir}/man?/foo.?ssl from + %%{_mandir}/man?ssl/foo.? +- add an [ engine ] section to the default configuration file + +* Thu Aug 9 2001 Nalin Dahyabhai +- add a patch for selecting a default engine in SSL_library_init() + +* Mon Jul 23 2001 Nalin Dahyabhai 0.9.6b-3 +- add patches for AEP hardware support +- add patch to keep trying when we fail to load a cert from a file and + there are more in the file +- add missing prototype for ENGINE_ubsec() in engine_int.h + +* Wed Jul 18 2001 Nalin Dahyabhai 0.9.6b-2 +- actually add hw_ubsec to the engine list + +* Tue Jul 17 2001 Nalin Dahyabhai +- add in the hw_ubsec driver from CVS + +* Wed Jul 11 2001 Nalin Dahyabhai 0.9.6b-1 +- update to 0.9.6b + +* Thu Jul 5 2001 Nalin Dahyabhai +- move .so symlinks back to %%{_libdir} + +* Tue Jul 3 2001 Nalin Dahyabhai +- move shared libraries to /lib (#38410) + +* Mon Jun 25 2001 Nalin Dahyabhai +- switch to engine code base + +* Mon Jun 18 2001 Nalin Dahyabhai +- add a script for creating dummy certificates +- move man pages from %%{_mandir}/man?/foo.?ssl to %%{_mandir}/man?ssl/foo.? + +* Thu Jun 07 2001 Florian La Roche +- add s390x support + +* Fri Jun 1 2001 Nalin Dahyabhai +- change two memcpy() calls to memmove() +- don't define L_ENDIAN on alpha + +* Wed May 23 2001 Joe Orton stronghold-0.9.6a-1 +- Add 'stronghold-' prefix to package names. +- Obsolete standard openssl packages. + +* Wed May 16 2001 Joe Orton +- Add BuildArch: i586 as per Nalin's advice. + +* Tue May 15 2001 Joe Orton +- Enable assembler on ix86 (using new .tar.bz2 which does + include the asm directories). + +* Tue May 15 2001 Nalin Dahyabhai +- make subpackages depend on the main package + +* Tue May 1 2001 Nalin Dahyabhai +- adjust the hobble script to not disturb symlinks in include/ (fix from + Joe Orton) + +* Thu Apr 26 2001 Nalin Dahyabhai +- drop the m2crypo patch we weren't using + +* Tue Apr 24 2001 Nalin Dahyabhai +- configure using "shared" as well + +* Sun Apr 8 2001 Nalin Dahyabhai +- update to 0.9.6a +- use the build-shared target to build shared libraries +- bump the soversion to 2 because we're no longer compatible with + our 0.9.5a packages or our 0.9.6 packages +- drop the patch for making rsatest a no-op when rsa null support is used +- put all man pages into
ssl instead of
+- break the m2crypto modules into a separate package + +* Tue Mar 13 2001 Nalin Dahyabhai +- use BN_LLONG on s390 + +* Mon Mar 12 2001 Nalin Dahyabhai +- fix the s390 changes for 0.9.6 (isn't supposed to be marked as 64-bit) + +* Sat Mar 3 2001 Nalin Dahyabhai +- move c_rehash to the perl subpackage, because it's a perl script now + +* Fri Mar 2 2001 Nalin Dahyabhai +- update to 0.9.6 +- enable MD2 +- use the libcrypto.so and libssl.so targets to build shared libs with +- bump the soversion to 1 because we're no longer compatible with any of + the various 0.9.5a packages circulating around, which provide lib*.so.0 + +* Wed Feb 28 2001 Florian La Roche +- change hobble-openssl for disabling MD2 again + +* Tue Feb 27 2001 Nalin Dahyabhai +- re-disable MD2 -- the EVP_MD_CTX structure would grow from 100 to 152 + bytes or so, causing EVP_DigestInit() to zero out stack variables in + apps built against a version of the library without it + +* Mon Feb 26 2001 Nalin Dahyabhai +- disable some inline assembly, which on x86 is Pentium-specific +- re-enable MD2 (see http://www.ietf.org/ietf/IPR/RSA-MD-all) + +* Thu Feb 08 2001 Florian La Roche +- fix s390 patch + +* Fri Dec 8 2000 Than Ngo +- added support s390 + +* Mon Nov 20 2000 Nalin Dahyabhai +- remove -Wa,* and -m* compiler flags from the default Configure file (#20656) +- add the CA.pl man page to the perl subpackage + +* Thu Nov 2 2000 Nalin Dahyabhai +- always build with -mcpu=ev5 on alpha + +* Tue Oct 31 2000 Nalin Dahyabhai +- add a symlink from cert.pem to ca-bundle.crt + +* Wed Oct 25 2000 Nalin Dahyabhai +- add a ca-bundle file for packages like Samba to reference for CA certificates + +* Tue Oct 24 2000 Nalin Dahyabhai +- remove libcrypto's crypt(), which doesn't handle md5crypt (#19295) + +* Mon Oct 2 2000 Nalin Dahyabhai +- add unzip as a buildprereq (#17662) +- update m2crypto to 0.05-snap4 + +* Tue Sep 26 2000 Bill Nottingham +- fix some issues in building when it's not installed + +* Wed Sep 6 2000 Nalin Dahyabhai +- make sure the headers we include are the ones we built with (aaaaarrgh!) + +* Fri Sep 1 2000 Nalin Dahyabhai +- add Richard Henderson's patch for BN on ia64 +- clean up the changelog + +* Tue Aug 29 2000 Nalin Dahyabhai +- fix the building of python modules without openssl-devel already installed + +* Wed Aug 23 2000 Nalin Dahyabhai +- byte-compile python extensions without the build-root +- adjust the makefile to not remove temporary files (like .key files when + building .csr files) by marking them as .PRECIOUS + +* Sat Aug 19 2000 Nalin Dahyabhai +- break out python extensions into a subpackage + +* Mon Jul 17 2000 Nalin Dahyabhai +- tweak the makefile some more + +* Tue Jul 11 2000 Nalin Dahyabhai +- disable MD2 support + +* Thu Jul 6 2000 Nalin Dahyabhai +- disable MDC2 support + +* Sun Jul 2 2000 Nalin Dahyabhai +- tweak the disabling of RC5, IDEA support +- tweak the makefile + +* Thu Jun 29 2000 Nalin Dahyabhai +- strip binaries and libraries +- rework certificate makefile to have the right parts for Apache + +* Wed Jun 28 2000 Nalin Dahyabhai +- use %%{_perl} instead of /usr/bin/perl +- disable alpha until it passes its own test suite + +* Fri Jun 9 2000 Nalin Dahyabhai +- move the passwd.1 man page out of the passwd package's way + +* Fri Jun 2 2000 Nalin Dahyabhai +- update to 0.9.5a, modified for U.S. +- add perl as a build-time requirement +- move certificate makefile to another package +- disable RC5, IDEA, RSA support +- remove optimizations for now + +* Wed Mar 1 2000 Florian La Roche +- Bero told me to move the Makefile into this package + +* Wed Mar 1 2000 Florian La Roche +- add lib*.so symlinks to link dynamically against shared libs + +* Tue Feb 29 2000 Florian La Roche +- update to 0.9.5 +- run ldconfig directly in post/postun +- add FAQ + +* Sat Dec 18 1999 Bernhard Rosenkrdnzer +- Fix build on non-x86 platforms + +* Fri Nov 12 1999 Bernhard Rosenkrdnzer +- move /usr/share/ssl/* from -devel to main package + +* Tue Oct 26 1999 Bernhard Rosenkrdnzer +- inital packaging +- changes from base: + - Move /usr/local/ssl to /usr/share/ssl for FHS compliance + - handle RPM_OPT_FLAGS