Import OpenSSL 1.0.1n.
authorSascha Wildner <saw@online.de>
Thu, 11 Jun 2015 19:03:27 +0000 (21:03 +0200)
committerSascha Wildner <saw@online.de>
Thu, 11 Jun 2015 19:03:27 +0000 (21:03 +0200)
Fixes CVE-2015-1788, CVE-2015-1789, CVE-2015-1790, CVE-2015-1791,
and CVE-2015-1792.

Rejects DH handshakes with parameters shorter than 768 bits.

118 files changed:
crypto/openssl/CHANGES
crypto/openssl/NEWS
crypto/openssl/README
crypto/openssl/apps/apps.c
crypto/openssl/apps/asn1pars.c
crypto/openssl/apps/ca.c
crypto/openssl/apps/cms.c
crypto/openssl/apps/dhparam.c
crypto/openssl/apps/enc.c
crypto/openssl/apps/gendh.c
crypto/openssl/apps/ocsp.c
crypto/openssl/apps/s_cb.c
crypto/openssl/apps/s_client.c
crypto/openssl/apps/s_server.c
crypto/openssl/apps/s_time.c
crypto/openssl/apps/smime.c
crypto/openssl/apps/srp.c
crypto/openssl/apps/verify.c
crypto/openssl/crypto/asn1/a_int.c
crypto/openssl/crypto/asn1/asn1_gen.c
crypto/openssl/crypto/asn1/asn_mime.c
crypto/openssl/crypto/asn1/bio_ndef.c
crypto/openssl/crypto/asn1/tasn_new.c
crypto/openssl/crypto/asn1/tasn_prn.c
crypto/openssl/crypto/asn1/x_x509.c
crypto/openssl/crypto/bio/b_print.c
crypto/openssl/crypto/bio/bf_nbio.c
crypto/openssl/crypto/bio/bio_lib.c
crypto/openssl/crypto/bio/bss_dgram.c
crypto/openssl/crypto/bn/bn.h
crypto/openssl/crypto/bn/bn_err.c
crypto/openssl/crypto/bn/bn_gf2m.c
crypto/openssl/crypto/bn/bn_lcl.h
crypto/openssl/crypto/bn/bn_print.c
crypto/openssl/crypto/bn/bn_rand.c
crypto/openssl/crypto/bn/bn_shift.c
crypto/openssl/crypto/buffer/buffer.c
crypto/openssl/crypto/cmac/cmac.c
crypto/openssl/crypto/cms/cms_pwri.c
crypto/openssl/crypto/cms/cms_smime.c
crypto/openssl/crypto/cryptlib.c
crypto/openssl/crypto/des/enc_writ.c
crypto/openssl/crypto/dh/dh_ameth.c
crypto/openssl/crypto/dsa/dsa_gen.c
crypto/openssl/crypto/dsa/dsa_ossl.c
crypto/openssl/crypto/dso/dso_lib.c
crypto/openssl/crypto/ec/ec2_oct.c
crypto/openssl/crypto/ec/ec_asn1.c
crypto/openssl/crypto/ec/ec_check.c
crypto/openssl/crypto/ec/ec_key.c
crypto/openssl/crypto/ec/ec_lcl.h
crypto/openssl/crypto/ec/ec_lib.c
crypto/openssl/crypto/ec/eck_prn.c
crypto/openssl/crypto/ec/ecp_oct.c
crypto/openssl/crypto/engine/eng_table.c
crypto/openssl/crypto/evp/bio_ok.c
crypto/openssl/crypto/evp/e_aes.c
crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
crypto/openssl/crypto/evp/e_rc4_hmac_md5.c
crypto/openssl/crypto/evp/encode.c
crypto/openssl/crypto/evp/evp.h
crypto/openssl/crypto/evp/p_seal.c
crypto/openssl/crypto/hmac/hmac.c
crypto/openssl/crypto/hmac/hmac.h
crypto/openssl/crypto/md32_common.h
crypto/openssl/crypto/mem.c
crypto/openssl/crypto/modes/gcm128.c
crypto/openssl/crypto/objects/o_names.c
crypto/openssl/crypto/objects/obj_dat.c
crypto/openssl/crypto/objects/objects.README
crypto/openssl/crypto/ocsp/ocsp_ext.c
crypto/openssl/crypto/ocsp/ocsp_vfy.c
crypto/openssl/crypto/opensslv.h
crypto/openssl/crypto/pem/pem_lib.c
crypto/openssl/crypto/pem/pem_pk8.c
crypto/openssl/crypto/pkcs12/p12_mutl.c
crypto/openssl/crypto/pkcs7/pk7_doit.c
crypto/openssl/crypto/rsa/rsa_pmeth.c
crypto/openssl/crypto/srp/srp_vfy.c
crypto/openssl/crypto/threads/th-lock.c
crypto/openssl/crypto/x509/x509_lu.c
crypto/openssl/crypto/x509/x509_vfy.c
crypto/openssl/crypto/x509/x509_vfy.h
crypto/openssl/crypto/x509/x509_vpm.c
crypto/openssl/crypto/x509/x509type.c
crypto/openssl/crypto/x509v3/v3_alt.c
crypto/openssl/crypto/x509v3/v3_cpols.c
crypto/openssl/crypto/x509v3/v3_utl.c
crypto/openssl/e_os2.h
crypto/openssl/engines/ccgost/e_gost_err.c
crypto/openssl/engines/ccgost/e_gost_err.h
crypto/openssl/engines/ccgost/gost2001.c
crypto/openssl/engines/ccgost/gost94_keyx.c
crypto/openssl/engines/ccgost/gost_ameth.c
crypto/openssl/engines/ccgost/gost_pmeth.c
crypto/openssl/engines/ccgost/gost_sign.c
crypto/openssl/engines/e_sureware.c
crypto/openssl/ssl/d1_both.c
crypto/openssl/ssl/d1_clnt.c
crypto/openssl/ssl/d1_lib.c
crypto/openssl/ssl/d1_pkt.c
crypto/openssl/ssl/d1_srvr.c
crypto/openssl/ssl/s2_pkt.c
crypto/openssl/ssl/s2_srvr.c
crypto/openssl/ssl/s3_both.c
crypto/openssl/ssl/s3_cbc.c
crypto/openssl/ssl/s3_clnt.c
crypto/openssl/ssl/s3_pkt.c
crypto/openssl/ssl/s3_srvr.c
crypto/openssl/ssl/ssl.h
crypto/openssl/ssl/ssl_err.c
crypto/openssl/ssl/ssl_lib.c
crypto/openssl/ssl/ssl_locl.h
crypto/openssl/ssl/ssl_sess.c
crypto/openssl/ssl/ssl_stat.c
crypto/openssl/ssl/t1_enc.c
crypto/openssl/ssl/t1_lib.c
crypto/openssl/ssl/tls_srp.c

index 74179ab..2565187 100644 (file)
@@ -2,6 +2,77 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 1.0.1m and 1.0.1n [11 Jun 2015]
+
+  *) Malformed ECParameters causes infinite loop
+
+     When processing an ECParameters structure OpenSSL enters an infinite loop
+     if the curve specified is over a specially malformed binary polynomial
+     field.
+
+     This can be used to perform denial of service against any
+     system which processes public keys, certificate requests or
+     certificates.  This includes TLS clients and TLS servers with
+     client authentication enabled.
+
+     This issue was reported to OpenSSL by Joseph Barr-Pixton.
+     (CVE-2015-1788)
+     [Andy Polyakov]
+
+  *) Exploitable out-of-bounds read in X509_cmp_time
+
+     X509_cmp_time does not properly check the length of the ASN1_TIME
+     string and can read a few bytes out of bounds. In addition,
+     X509_cmp_time accepts an arbitrary number of fractional seconds in the
+     time string.
+
+     An attacker can use this to craft malformed certificates and CRLs of
+     various sizes and potentially cause a segmentation fault, resulting in
+     a DoS on applications that verify certificates or CRLs. TLS clients
+     that verify CRLs are affected. TLS clients and servers with client
+     authentication enabled may be affected if they use custom verification
+     callbacks.
+
+     This issue was reported to OpenSSL by Robert Swiecki (Google), and
+     independently by Hanno Böck.
+     (CVE-2015-1789)
+     [Emilia Käsper]
+
+  *) PKCS7 crash with missing EnvelopedContent
+
+     The PKCS#7 parsing code does not handle missing inner EncryptedContent
+     correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs
+     with missing content and trigger a NULL pointer dereference on parsing.
+
+     Applications that decrypt PKCS#7 data or otherwise parse PKCS#7
+     structures from untrusted sources are affected. OpenSSL clients and
+     servers are not affected.
+
+     This issue was reported to OpenSSL by Michal Zalewski (Google).
+     (CVE-2015-1790)
+     [Emilia Käsper]
+
+  *) CMS verify infinite loop with unknown hash function
+
+     When verifying a signedData message the CMS code can enter an infinite loop
+     if presented with an unknown hash function OID. This can be used to perform
+     denial of service against any system which verifies signedData messages using
+     the CMS code.
+     This issue was reported to OpenSSL by Johannes Bauer.
+     (CVE-2015-1792)
+     [Stephen Henson]
+
+  *) Race condition handling NewSessionTicket
+
+     If a NewSessionTicket is received by a multi-threaded client when attempting to
+     reuse a previous ticket then a race condition can occur potentially leading to
+     a double free of the ticket data.
+     (CVE-2015-1791)
+     [Matt Caswell]
+
+  *) Reject DH handshakes with parameters shorter than 768 bits.
+     [Kurt Roeckx and Emilia Kasper]
+
  Changes between 1.0.1l and 1.0.1m [19 Mar 2015]
 
   *) Segmentation fault in ASN1_TYPE_cmp fix
index 12616d2..e866e94 100644 (file)
@@ -5,6 +5,14 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.0.1m and OpenSSL 1.0.1n [11 Jun 2015]
+
+      o Malformed ECParameters causes infinite loop (CVE-2015-1788)
+      o Exploitable out-of-bounds read in X509_cmp_time (CVE-2015-1789)
+      o PKCS7 crash with missing EnvelopedContent (CVE-2015-1790)
+      o CMS verify infinite loop with unknown hash function (CVE-2015-1792)
+      o Race condition handling NewSessionTicket (CVE-2015-1791)
+
   Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.1m [19 Mar 2015]
 
       o Segmentation fault in ASN1_TYPE_cmp fix (CVE-2015-0286)
index ecdcfb2..8718a24 100644 (file)
@@ -1,5 +1,5 @@
 
- OpenSSL 1.0.1m 19 Mar 2015
+ OpenSSL 1.0.1n 11 Jun 2015
 
  Copyright (c) 1998-2011 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
index 9862afd..6801238 100644 (file)
@@ -572,7 +572,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
         char *prompt = NULL;
 
         prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
-        if(!prompt) {
+        if (!prompt) {
             BIO_printf(bio_err, "Out of memory\n");
             UI_free(ui);
             return 0;
@@ -586,7 +586,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
                                      PW_MIN_LENGTH, bufsiz - 1);
         if (ok >= 0 && verify) {
             buff = (char *)OPENSSL_malloc(bufsiz);
-            if(!buff) {
+            if (!buff) {
                 BIO_printf(bio_err, "Out of memory\n");
                 UI_free(ui);
                 OPENSSL_free(prompt);
@@ -2238,6 +2238,8 @@ int args_verify(char ***pargs, int *pargc,
         flags |= X509_V_FLAG_NOTIFY_POLICY;
     else if (!strcmp(arg, "-check_ss_sig"))
         flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
+    else if (!strcmp(arg, "-no_alt_chains"))
+        flags |= X509_V_FLAG_NO_ALT_CHAINS;
     else
         return 0;
 
index 7a0f169..11b0787 100644 (file)
@@ -375,7 +375,7 @@ static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
 {
     CONF *cnf = NULL;
     int len;
-    long errline;
+    long errline = 0;
     unsigned char *p;
     ASN1_TYPE *atyp = NULL;
 
index 5d29a64..97ad0c1 100644 (file)
@@ -558,7 +558,7 @@ int MAIN(int argc, char **argv)
 #ifdef OPENSSL_SYS_VMS
         len = strlen(s) + sizeof(CONFIG_FILE);
         tofree = OPENSSL_malloc(len);
-        if(!tofree) {
+        if (!tofree) {
             BIO_printf(bio_err, "Out of memory\n");
             goto err;
         }
@@ -566,7 +566,7 @@ int MAIN(int argc, char **argv)
 #else
         len = strlen(s) + sizeof(CONFIG_FILE) + 1;
         tofree = OPENSSL_malloc(len);
-        if(!tofree) {
+        if (!tofree) {
             BIO_printf(bio_err, "Out of memory\n");
             goto err;
         }
@@ -2803,7 +2803,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
     ASN1_GENERALIZEDTIME *comp_time = NULL;
     tmp = BUF_strdup(str);
 
-    if(!tmp) {
+    if (!tmp) {
         BIO_printf(bio_err, "memory allocation failure\n");
         goto err;
     }
@@ -2825,7 +2825,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
 
     if (prevtm) {
         *prevtm = ASN1_UTCTIME_new();
-        if(!*prevtm) {
+        if (!*prevtm) {
             BIO_printf(bio_err, "memory allocation failure\n");
             goto err;
         }
@@ -2869,7 +2869,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
                 goto err;
             }
             comp_time = ASN1_GENERALIZEDTIME_new();
-            if(!comp_time) {
+            if (!comp_time) {
                 BIO_printf(bio_err, "memory allocation failure\n");
                 goto err;
             }
index 0cc4b46..d7645c0 100644 (file)
@@ -580,6 +580,8 @@ int MAIN(int argc, char **argv)
         BIO_printf(bio_err,
                    "-CApath dir    trusted certificates directory\n");
         BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
+        BIO_printf(bio_err,
+                   "-no_alt_chains only ever use the first certificate chain found\n");
         BIO_printf(bio_err,
                    "-crl_check     check revocation status of signer's certificate using CRLs\n");
         BIO_printf(bio_err,
index f86311c..d3b6d58 100644 (file)
 # undef PROG
 # define PROG    dhparam_main
 
-# define DEFBITS 512
+# define DEFBITS 2048
 
 /*-
  * -inform arg  - input format - default PEM (DER or PEM)
@@ -254,7 +254,7 @@ int MAIN(int argc, char **argv)
         BIO_printf(bio_err,
                    " -5            generate parameters using  5 as the generator value\n");
         BIO_printf(bio_err,
-                   " numbits       number of bits in to generate (default 512)\n");
+                   " numbits       number of bits in to generate (default 2048)\n");
 # ifndef OPENSSL_NO_ENGINE
         BIO_printf(bio_err,
                    " -engine e     use engine e, possibly a hardware device.\n");
index 5c2cf7a..7b7c70b 100644 (file)
@@ -548,9 +548,14 @@ int MAIN(int argc, char **argv)
             else
                 OPENSSL_cleanse(str, strlen(str));
         }
-        if ((hiv != NULL) && !set_hex(hiv, iv, sizeof iv)) {
-            BIO_printf(bio_err, "invalid hex iv value\n");
-            goto end;
+        if (hiv != NULL) {
+            int siz = EVP_CIPHER_iv_length(cipher);
+            if (siz == 0) {
+                BIO_printf(bio_err, "warning: iv not use by this cipher\n");
+            } else if (!set_hex(hiv, iv, sizeof iv)) {
+                BIO_printf(bio_err, "invalid hex iv value\n");
+                goto end;
+            }
         }
         if ((hiv == NULL) && (str == NULL)
             && EVP_CIPHER_iv_length(cipher) != 0) {
@@ -562,7 +567,7 @@ int MAIN(int argc, char **argv)
             BIO_printf(bio_err, "iv undefined\n");
             goto end;
         }
-        if ((hkey != NULL) && !set_hex(hkey, key, sizeof key)) {
+        if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) {
             BIO_printf(bio_err, "invalid hex key value\n");
             goto end;
         }
index adaa101..fef6f1b 100644 (file)
@@ -80,7 +80,7 @@
 # include <openssl/x509.h>
 # include <openssl/pem.h>
 
-# define DEFBITS 512
+# define DEFBITS 2048
 # undef PROG
 # define PROG gendh_main
 
index 71def26..572f064 100644 (file)
@@ -518,6 +518,8 @@ int MAIN(int argc, char **argv)
                    "-CApath dir          trusted certificates directory\n");
         BIO_printf(bio_err,
                    "-CAfile file         trusted certificates file\n");
+        BIO_printf(bio_err,
+                   "-no_alt_chains       only ever use the first certificate chain found\n");
         BIO_printf(bio_err,
                    "-VAfile file         validator certificates file\n");
         BIO_printf(bio_err,
index 7918500..fabf9cf 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h> /* for memcpy() */
 #define USE_SOCKETS
 #define NON_MAIN
 #include "apps.h"
@@ -747,7 +748,7 @@ int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie,
 
     /* Initialize a random secret */
     if (!cookie_initialized) {
-        if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) {
+        if (RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH) <= 0) {
             BIO_printf(bio_err, "error setting random cookie secret\n");
             return 0;
         }
index ef41cec..28737b6 100644 (file)
@@ -322,6 +322,8 @@ static void sc_usage(void)
                " -pass arg     - private key file pass phrase source\n");
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
+    BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
     BIO_printf(bio_err,
                " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
     BIO_printf(bio_err,
@@ -547,7 +549,7 @@ static char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
     PW_CB_DATA cb_tmp;
     int l;
 
-    if(!pass) {
+    if (!pass) {
         BIO_printf(bio_err, "Malloc failure\n");
         return NULL;
     }
@@ -1177,13 +1179,12 @@ int MAIN(int argc, char **argv)
     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))) {
-        /*
-         * BIO_printf(bio_err,"error setting default verify locations\n");
-         */
+    if ((CAfile || CApath)
+        && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
+        ERR_print_errors(bio_err);
+    }
+    if (!SSL_CTX_set_default_verify_paths(ctx)) {
         ERR_print_errors(bio_err);
-        /* goto end; */
     }
 #ifndef OPENSSL_NO_TLSEXT
     if (servername != NULL) {
index bcf5c33..b58e5e0 100644 (file)
@@ -219,7 +219,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile);
-static DH *get_dh512(void);
+static DH *get_dh2048(void);
 #endif
 
 #ifdef MONOLITH
@@ -227,30 +227,48 @@ static void s_server_init(void);
 #endif
 
 #ifndef OPENSSL_NO_DH
-static unsigned char dh512_p[] = {
-    0xDA, 0x58, 0x3C, 0x16, 0xD9, 0x85, 0x22, 0x89, 0xD0, 0xE4, 0xAF, 0x75,
-    0x6F, 0x4C, 0xCA, 0x92, 0xDD, 0x4B, 0xE5, 0x33, 0xB8, 0x04, 0xFB, 0x0F,
-    0xED, 0x94, 0xEF, 0x9C, 0x8A, 0x44, 0x03, 0xED, 0x57, 0x46, 0x50, 0xD3,
-    0x69, 0x99, 0xDB, 0x29, 0xD7, 0x76, 0x27, 0x6B, 0xA2, 0xD3, 0xD4, 0x12,
-    0xE2, 0x18, 0xF4, 0xDD, 0x1E, 0x08, 0x4C, 0xF6, 0xD8, 0x00, 0x3E, 0x7C,
-    0x47, 0x74, 0xE8, 0x33,
+static unsigned char dh2048_p[] = {
+    0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
+    0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
+    0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
+    0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
+    0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
+    0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
+    0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
+    0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
+    0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
+    0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
+    0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
+    0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
+    0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
+    0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
+    0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
+    0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
+    0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
+    0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
+    0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
+    0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
+    0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
+    0xE9,0x32,0x0B,0x3B,
 };
 
-static unsigned char dh512_g[] = {
+static unsigned char dh2048_g[] = {
     0x02,
 };
 
-static DH *get_dh512(void)
+DH *get_dh2048()
 {
-    DH *dh = NULL;
+    DH *dh;
 
     if ((dh = DH_new()) == NULL)
-        return (NULL);
-    dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
-    dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-    if ((dh->p == NULL) || (dh->g == NULL))
-        return (NULL);
-    return (dh);
+        return NULL;
+    dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+    dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+    if (dh->p == NULL || dh->g == NULL) {
+        DH_free(dh);
+        return NULL;
+    }
+    return dh;
 }
 #endif
 
@@ -522,6 +540,8 @@ static void sv_usage(void)
     BIO_printf(bio_err, " -state        - Print the SSL states\n");
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
+    BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
     BIO_printf(bio_err,
                " -nocert       - Don't use any certificates (Anon-DH)\n");
     BIO_printf(bio_err,
@@ -720,7 +740,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl)
             num = inl;
         wbuf =
             (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
-        if(!wbuf)
+        if (!wbuf)
             return 0;
         OPENSSL_free(b->ptr);
 
@@ -998,7 +1018,7 @@ int MAIN(int argc, char *argv[])
     int off = 0;
     int no_tmp_rsa = 0, no_dhe = 0, nocert = 0;
 #ifndef OPENSSL_NO_ECDH
-    int no_ecdhe;
+    int no_ecdhe = 0;
 #endif
     int state = 0;
     const SSL_METHOD *meth = NULL;
@@ -1654,7 +1674,11 @@ int MAIN(int argc, char *argv[])
             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
         } else {
             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
-            dh = get_dh512();
+            dh = get_dh2048();
+            if (dh == NULL) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
         }
         (void)BIO_flush(bio_s_out);
 
@@ -2251,8 +2275,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                     ret = 1;
                     goto err;
                 }
-                l += k;
-                i -= k;
+                if (k > 0) {
+                    l += k;
+                    i -= k;
+                }
                 if (i <= 0)
                     break;
             }
@@ -2916,7 +2942,8 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
 {
     unsigned int count = 0;
     do {
-        RAND_pseudo_bytes(id, *id_len);
+        if (RAND_pseudo_bytes(id, *id_len) < 0)
+            return 0;
         /*
          * Prefix the session_id with the required prefix. NB: If our prefix
          * is too long, clip it - but there will be worse effects anyway, eg.
index a40997a..38788f7 100644 (file)
@@ -302,7 +302,7 @@ static int parseArgs(int argc, char **argv)
             if (--argc < 1)
                 goto bad;
             maxTime = atoi(*(++argv));
-            if(maxTime <= 0) {
+            if (maxTime <= 0) {
                 BIO_printf(bio_err, "time must be > 0\n");
                 badop = 1;
             }
index 7b351f6..53e43c5 100644 (file)
@@ -441,6 +441,8 @@ int MAIN(int argc, char **argv)
         BIO_printf(bio_err,
                    "-CApath dir    trusted certificates directory\n");
         BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
+        BIO_printf(bio_err,
+                   "-no_alt_chains only ever use the first certificate chain found\n");
         BIO_printf(bio_err,
                    "-crl_check     check revocation status of signer's certificate using CRLs\n");
         BIO_printf(bio_err,
index c679448..c0ff417 100644 (file)
@@ -435,7 +435,7 @@ int MAIN(int argc, char **argv)
 # ifdef OPENSSL_SYS_VMS
             len = strlen(s) + sizeof(CONFIG_FILE);
             tofree = OPENSSL_malloc(len);
-            if(!tofree) {
+            if (!tofree) {
                 BIO_printf(bio_err, "Out of memory\n");
                 goto err;
             }
@@ -443,7 +443,7 @@ int MAIN(int argc, char **argv)
 # else
             len = strlen(s) + sizeof(CONFIG_FILE) + 1;
             tofree = OPENSSL_malloc(len);
-            if(!tofree) {
+            if (!tofree) {
                 BIO_printf(bio_err, "Out of memory\n");
                 goto err;
             }
index 7295c76..e29f9bb 100644 (file)
@@ -227,7 +227,7 @@ int MAIN(int argc, char **argv)
     if (ret == 1) {
         BIO_printf(bio_err,
                    "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
-        BIO_printf(bio_err, " [-attime timestamp]");
+        BIO_printf(bio_err, " [-no_alt_chains] [-attime timestamp]");
 #ifndef OPENSSL_NO_ENGINE
         BIO_printf(bio_err, " [-engine e]");
 #endif
index 70c2b8e..7e26704 100644 (file)
@@ -124,6 +124,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
     else {
         ret = a->length;
         i = a->data[0];
+        if (ret == 1 && i == 0)
+            neg = 0;
         if (!neg && (i > 127)) {
             pad = 1;
             pb = 0;
@@ -162,7 +164,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
         p += a->length - 1;
         i = a->length;
         /* Copy zeros to destination as long as source is zero */
-        while (!*n) {
+        while (!*n && i > 1) {
             *(p--) = 0;
             n--;
             i--;
@@ -419,7 +421,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
         ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
         goto err;
     }
-    if (BN_is_negative(bn))
+    if (BN_is_negative(bn) && !BN_is_zero(bn))
         ret->type = V_ASN1_NEG_INTEGER;
     else
         ret->type = V_ASN1_INTEGER;
index 11b582d..6574923 100644 (file)
@@ -74,6 +74,8 @@
 #define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
 
 #define ASN1_FLAG_EXP_MAX       20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH  50
 
 /* Input formats */
 
@@ -110,13 +112,16 @@ typedef struct {
     int exp_count;
 } tag_exp_arg;
 
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+                              int *perr);
 static int bitstr_cb(const char *elem, int len, void *bitstr);
 static int asn1_cb(const char *elem, int len, void *bitstr);
 static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
                       int exp_constructed, int exp_pad, int imp_ok);
 static int parse_tagging(const char *vstart, int vlen, int *ptag,
                          int *pclass);
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr);
 static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
 static int asn1_str2tag(const char *tagstr, int len);
 
@@ -132,6 +137,16 @@ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
 }
 
 ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
+{
+    int err = 0;
+    ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+    if (err)
+        ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+    return ret;
+}
+
+static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
+                              int *perr)
 {
     ASN1_TYPE *ret;
     tag_exp_arg asn1_tags;
@@ -152,17 +167,22 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
     asn1_tags.imp_class = -1;
     asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
     asn1_tags.exp_count = 0;
-    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+        *perr = ASN1_R_UNKNOWN_TAG;
         return NULL;
+    }
 
     if ((asn1_tags.utype == V_ASN1_SEQUENCE)
         || (asn1_tags.utype == V_ASN1_SET)) {
         if (!cnf) {
-            ASN1err(ASN1_F_ASN1_GENERATE_V3,
-                    ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+            *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
             return NULL;
         }
-        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+        if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+            *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
+            return NULL;
+        }
+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
     } else
         ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
 
@@ -280,7 +300,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
     int tmp_tag, tmp_class;
 
     if (elem == NULL)
-        return 0;
+        return -1;
 
     for (i = 0, p = elem; i < len; p++, i++) {
         /* Look for the ':' in name value pairs */
@@ -353,7 +373,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
         break;
 
     case ASN1_GEN_FLAG_FORMAT:
-        if(!vstart) {
+        if (!vstart) {
             ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
             return -1;
         }
@@ -435,7 +455,8 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
 
 /* Handle multiple types: SET and SEQUENCE */
 
-static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr)
 {
     ASN1_TYPE *ret = NULL;
     STACK_OF(ASN1_TYPE) *sk = NULL;
@@ -454,7 +475,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
             goto bad;
         for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
             ASN1_TYPE *typ =
-                ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
+                generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+                            depth + 1, perr);
             if (!typ)
                 goto bad;
             if (!sk_ASN1_TYPE_push(sk, typ))
index 7e2f28e..96110c5 100644 (file)
@@ -289,7 +289,8 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
     if ((flags & SMIME_DETACHED) && data) {
         /* We want multipart/signed */
         /* Generate a random boundary */
-        RAND_pseudo_bytes((unsigned char *)bound, 32);
+        if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+            return 0;
         for (i = 0; i < 32; i++) {
             c = bound[i] & 0xf;
             if (c < 10)
index 4a73ca9..31949b8 100644 (file)
@@ -162,7 +162,7 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
 
     derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
     p = OPENSSL_malloc(derlen);
-    if(!p)
+    if (!p)
         return 0;
 
     ndef_aux->derbuf = p;
@@ -232,7 +232,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
 
     derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
     p = OPENSSL_malloc(derlen);
-    if(!p)
+    if (!p)
         return 0;
 
     ndef_aux->derbuf = p;
index 7d2964f..b0c73be 100644 (file)
@@ -100,9 +100,6 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
     else
         asn1_cb = 0;
 
-    if (!combine)
-        *pval = NULL;
-
 #ifdef CRYPTO_MDEBUG
     if (it->sname)
         CRYPTO_push_info(it->sname);
index 7c54f9d..5e7d53e 100644 (file)
@@ -290,7 +290,7 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
             const ASN1_TEMPLATE *seqtt;
             seqtt = asn1_do_adb(fld, tt, 1);
-            if(!seqtt)
+            if (!seqtt)
                 return 0;
             tmpfld = asn1_get_field_ptr(fld, seqtt);
             if (!asn1_template_print_ctx(out, tmpfld,
index d51b76e..f56e837 100644 (file)
@@ -177,7 +177,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
     /* Save start position */
     q = *pp;
 
-    if(!a || *a == NULL) {
+    if (!a || *a == NULL) {
         freeret = 1;
     }
     ret = d2i_X509(a, pp, length);
@@ -192,7 +192,7 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
         goto err;
     return ret;
  err:
-    if(freeret) {
+    if (freeret) {
         X509_free(ret);
         if (a)
             *a = NULL;
index c2cf6e6..7c81e25 100644 (file)
@@ -704,32 +704,29 @@ doapr_outch(char **sbuffer,
     /* If we haven't at least one buffer, someone has doe a big booboo */
     assert(*sbuffer != NULL || buffer != NULL);
 
-    if (buffer) {
-        while (*currlen >= *maxlen) {
-            if (*buffer == NULL) {
-                if (*maxlen == 0)
-                    *maxlen = 1024;
-                *buffer = OPENSSL_malloc(*maxlen);
-                if(!*buffer) {
-                    /* Panic! Can't really do anything sensible. Just return */
-                    return;
-                }
-                if (*currlen > 0) {
-                    assert(*sbuffer != NULL);
-                    memcpy(*buffer, *sbuffer, *currlen);
-                }
-                *sbuffer = NULL;
-            } else {
-                *maxlen += 1024;
-                *buffer = OPENSSL_realloc(*buffer, *maxlen);
-                if(!*buffer) {
-                    /* Panic! Can't really do anything sensible. Just return */
-                    return;
-                }
+    /* |currlen| must always be <= |*maxlen| */
+    assert(*currlen <= *maxlen);
+
+    if (buffer && *currlen == *maxlen) {
+        *maxlen += 1024;
+        if (*buffer == NULL) {
+            *buffer = OPENSSL_malloc(*maxlen);
+            if (!*buffer) {
+                /* Panic! Can't really do anything sensible. Just return */
+                return;
+            }
+            if (*currlen > 0) {
+                assert(*sbuffer != NULL);
+                memcpy(*buffer, *sbuffer, *currlen);
+            }
+            *sbuffer = NULL;
+        } else {
+            *buffer = OPENSSL_realloc(*buffer, *maxlen);
+            if (!*buffer) {
+                /* Panic! Can't really do anything sensible. Just return */
+                return;
             }
         }
-        /* What to do if *buffer is NULL? */
-        assert(*sbuffer != NULL || *buffer != NULL);
     }
 
     if (*currlen < *maxlen) {
index da88a8a..a04f32a 100644 (file)
@@ -139,7 +139,8 @@ static int nbiof_read(BIO *b, char *out, int outl)
 
     BIO_clear_retry_flags(b);
 #if 1
-    RAND_pseudo_bytes(&n, 1);
+    if (RAND_pseudo_bytes(&n, 1) < 0)
+        return -1;
     num = (n & 0x07);
 
     if (outl > num)
@@ -178,7 +179,8 @@ static int nbiof_write(BIO *b, const char *in, int inl)
         num = nt->lwn;
         nt->lwn = 0;
     } else {
-        RAND_pseudo_bytes(&n, 1);
+        if (RAND_pseudo_bytes(&n, 1) < 0)
+            return -1;
         num = (n & 7);
     }
 
index 5267010..07934f8 100644 (file)
@@ -536,8 +536,10 @@ BIO *BIO_dup_chain(BIO *in)
 
         /* copy app data */
         if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
-                                &bio->ex_data))
+                                &bio->ex_data)) {
+            BIO_free(new_bio);
             goto err;
+        }
 
         if (ret == NULL) {
             eoc = new_bio;
@@ -549,8 +551,8 @@ BIO *BIO_dup_chain(BIO *in)
     }
     return (ret);
  err:
-    if (ret != NULL)
-        BIO_free(ret);
+    BIO_free_all(ret);
+
     return (NULL);
 }
 
index b495db2..e3e3dd0 100644 (file)
@@ -299,16 +299,17 @@ static void dgram_adjust_rcv_timeout(BIO *b)
 
         /* Calculate time left until timer expires */
         memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
-        timeleft.tv_sec -= timenow.tv_sec;
-        timeleft.tv_usec -= timenow.tv_usec;
-        if (timeleft.tv_usec < 0) {
+        if (timeleft.tv_usec < timenow.tv_usec) {
+            timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
             timeleft.tv_sec--;
-            timeleft.tv_usec += 1000000;
+        } else {
+            timeleft.tv_usec -= timenow.tv_usec;
         }
-
-        if (timeleft.tv_sec < 0) {
+        if (timeleft.tv_sec < timenow.tv_sec) {
             timeleft.tv_sec = 0;
             timeleft.tv_usec = 1;
+        } else {
+            timeleft.tv_sec -= timenow.tv_sec;
         }
 
         /*
@@ -953,7 +954,7 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
      */
     sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
     authchunks = OPENSSL_malloc(sockopt_len);
-    if(!authchunks) {
+    if (!authchunks) {
         BIO_vfree(bio);
         return (NULL);
     }
@@ -1293,7 +1294,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
                 (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
             authchunks = OPENSSL_malloc(optlen);
             if (!authchunks) {
-                BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_ERROR);
+                BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
                 return -1;
             }
             memset(authchunks, 0, sizeof(optlen));
@@ -1364,8 +1365,8 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl)
     if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) {
         char *tmp;
         data->saved_message.bio = b;
-        if(!(tmp = OPENSSL_malloc(inl))) {
-            BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_ERROR);
+        if (!(tmp = OPENSSL_malloc(inl))) {
+            BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE);
             return -1;
         }
         if (data->saved_message.data)
index 7d57e98..47d8c71 100644 (file)
@@ -797,6 +797,7 @@ int RAND_pseudo_bytes(unsigned char *buf, int num);
                          * wouldn't be constructed with top!=dmax. */ \
                         BN_ULONG *_not_const; \
                         memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+                        /* Debug only - safe to ignore error return */ \
                         RAND_pseudo_bytes(&_tmp_char, 1); \
                         memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
                                 (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
@@ -910,6 +911,7 @@ void ERR_load_BN_strings(void);
 # define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR                  135
 # define BN_F_BN_GF2M_MOD_SQR                             136
 # define BN_F_BN_GF2M_MOD_SQRT                            137
+# define BN_F_BN_LSHIFT                                   145
 # define BN_F_BN_MOD_EXP2_MONT                            118
 # define BN_F_BN_MOD_EXP_MONT                             109
 # define BN_F_BN_MOD_EXP_MONT_CONSTTIME                   124
@@ -925,12 +927,14 @@ void ERR_load_BN_strings(void);
 # define BN_F_BN_NEW                                      113
 # define BN_F_BN_RAND                                     114
 # define BN_F_BN_RAND_RANGE                               122
+# define BN_F_BN_RSHIFT                                   146
 # define BN_F_BN_USUB                                     115
 
 /* Reason codes. */
 # define BN_R_ARG2_LT_ARG3                                100
 # define BN_R_BAD_RECIPROCAL                              101
 # define BN_R_BIGNUM_TOO_LONG                             114
+# define BN_R_BITS_TOO_SMALL                              118
 # define BN_R_CALLED_WITH_EVEN_MODULUS                    102
 # define BN_R_DIV_BY_ZERO                                 103
 # define BN_R_ENCODING_ERROR                              104
@@ -938,6 +942,7 @@ void ERR_load_BN_strings(void);
 # define BN_R_INPUT_NOT_REDUCED                           110
 # define BN_R_INVALID_LENGTH                              106
 # define BN_R_INVALID_RANGE                               115
+# define BN_R_INVALID_SHIFT                               119
 # define BN_R_NOT_A_SQUARE                                111
 # define BN_R_NOT_INITIALIZED                             107
 # define BN_R_NO_INVERSE                                  108
index faa7e22..e7a7038 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/bn/bn_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2015 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
@@ -94,6 +94,7 @@ static ERR_STRING_DATA BN_str_functs[] = {
     {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
     {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
     {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
+    {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"},
     {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
     {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
     {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
@@ -109,6 +110,7 @@ static ERR_STRING_DATA BN_str_functs[] = {
     {ERR_FUNC(BN_F_BN_NEW), "BN_new"},
     {ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
     {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
+    {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"},
     {ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
     {0, NULL}
 };
@@ -117,6 +119,7 @@ static ERR_STRING_DATA BN_str_reasons[] = {
     {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"},
     {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"},
     {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"},
+    {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"},
     {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
     {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"},
     {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"},
@@ -125,6 +128,7 @@ static ERR_STRING_DATA BN_str_reasons[] = {
     {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
     {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
     {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
+    {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"},
     {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
     {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
     {ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
index aeee49a..a0ba8de 100644 (file)
@@ -694,9 +694,10 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
     }
 # else
     {
-        int i, ubits = BN_num_bits(u), vbits = BN_num_bits(v), /* v is copy
-                                                                * of p */
-            top = p->top;
+        int i;
+        int ubits = BN_num_bits(u);
+        int vbits = BN_num_bits(v); /* v is copy of p */
+        int top = p->top;
         BN_ULONG *udp, *bdp, *vdp, *cdp;
 
         bn_wexpand(u, top);
@@ -740,8 +741,12 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                 ubits--;
             }
 
-            if (ubits <= BN_BITS2 && udp[0] == 1)
-                break;
+            if (ubits <= BN_BITS2) {
+                if (udp[0] == 0) /* poly was reducible */
+                    goto err;
+                if (udp[0] == 1)
+                    break;
+            }
 
             if (ubits < vbits) {
                 i = ubits;
index 1059d1d..904a723 100644 (file)
@@ -276,7 +276,7 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
 #   endif
 #  elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
 #   if defined(__GNUC__) && __GNUC__>=2
-#    if __GNUC__>=4 && __GNUC_MINOR__>=4
+#    if __GNUC__>4 || (__GNUC__>=4 && __GNUC_MINOR__>=4)
                                      /* "h" constraint is no more since 4.4 */
 #     define BN_UMULT_HIGH(a,b)          (((__uint128_t)(a)*(b))>>64)
 #     define BN_UMULT_LOHI(low,high,a,b) ({     \
index 4dcaae3..ab10b95 100644 (file)
@@ -71,7 +71,12 @@ char *BN_bn2hex(const BIGNUM *a)
     char *buf;
     char *p;
 
-    buf = (char *)OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+    if (a->neg && BN_is_zero(a)) {
+        /* "-0" == 3 bytes including NULL terminator */
+        buf = OPENSSL_malloc(3);
+    } else {
+        buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+    }
     if (buf == NULL) {
         BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
         goto err;
index 7ac71ec..f9fb2e9 100644 (file)
@@ -121,6 +121,11 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
     int ret = 0, bit, bytes, mask;
     time_t tim;
 
+    if (bits < 0 || (bits == 1 && top > 0)) {
+        BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
+        return 0;
+    }
+
     if (bits == 0) {
         BN_zero(rnd);
         return 1;
@@ -157,7 +162,8 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
         unsigned char c;
 
         for (i = 0; i < bytes; i++) {
-            RAND_pseudo_bytes(&c, 1);
+            if (RAND_pseudo_bytes(&c, 1) < 0)
+                goto err;
             if (c >= 128 && i > 0)
                 buf[i] = buf[i - 1];
             else if (c < 42)
@@ -168,7 +174,7 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
     }
 #endif
 
-    if (top != -1) {
+    if (top >= 0) {
         if (top) {
             if (bit == 0) {
                 buf[0] = 1;
index 4f3e8ff..9673d9a 100644 (file)
@@ -137,6 +137,11 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
     bn_check_top(r);
     bn_check_top(a);
 
+    if (n < 0) {
+        BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
+        return 0;
+    }
+
     r->neg = a->neg;
     nw = n / BN_BITS2;
     if (bn_wexpand(r, a->top + nw + 1) == NULL)
@@ -174,6 +179,11 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
     bn_check_top(r);
     bn_check_top(a);
 
+    if (n < 0) {
+        BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
+        return 0;
+    }
+
     nw = n / BN_BITS2;
     rb = n % BN_BITS2;
     lb = BN_BITS2 - rb;
index d287e34..eff3e08 100644 (file)
@@ -88,7 +88,7 @@ void BUF_MEM_free(BUF_MEM *a)
         return;
 
     if (a->data != NULL) {
-        memset(a->data, 0, (unsigned int)a->max);
+        OPENSSL_cleanse(a->data, a->max);
         OPENSSL_free(a->data);
     }
     OPENSSL_free(a);
index c5597a3..774e6dc 100644 (file)
@@ -126,6 +126,8 @@ EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
 
 void CMAC_CTX_free(CMAC_CTX *ctx)
 {
+    if (!ctx)
+        return;
     CMAC_CTX_cleanup(ctx);
     OPENSSL_free(ctx);
 }
index 076b545..a8322dc 100644 (file)
@@ -231,7 +231,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,
         return 0;
     }
     tmp = OPENSSL_malloc(inlen);
-    if(!tmp)
+    if (!tmp)
         return 0;
     /* setup IV by decrypting last two blocks */
     EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
@@ -297,8 +297,9 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
         out[3] = in[2] ^ 0xFF;
         memcpy(out + 4, in, inlen);
         /* Add random padding to end */
-        if (olen > inlen + 4)
-            RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen);
+        if (olen > inlen + 4
+            && RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen) < 0)
+            return 0;
         /* Encrypt twice */
         EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
         EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
index 8851603..8b37560 100644 (file)
@@ -131,7 +131,7 @@ static void do_free_upto(BIO *f, BIO *upto)
             BIO_free(f);
             f = tbio;
         }
-        while (f != upto);
+        while (f && f != upto);
     } else
         BIO_free_all(f);
 }
index 6353bbe..c654a5c 100644 (file)
@@ -806,8 +806,6 @@ int OPENSSL_isservice(void)
     if (_OPENSSL_isservice.p != (void *)-1)
         return (*_OPENSSL_isservice.f) ();
 
-    (void)GetDesktopWindow();   /* return value is ignored */
-
     h = GetProcessWindowStation();
     if (h == NULL)
         return -1;
index b4eecc3..bfaabde 100644 (file)
@@ -96,6 +96,9 @@ int DES_enc_write(int fd, const void *_buf, int len,
     const unsigned char *cp;
     static int start = 1;
 
+    if (len < 0)
+        return -1;
+
     if (outbuf == NULL) {
         outbuf = OPENSSL_malloc(BSIZE + HDRSIZE);
         if (outbuf == NULL)
@@ -132,7 +135,9 @@ int DES_enc_write(int fd, const void *_buf, int len,
     if (len < 8) {
         cp = shortbuf;
         memcpy(shortbuf, buf, len);
-        RAND_pseudo_bytes(shortbuf + len, 8 - len);
+        if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) {
+            return -1;
+        }
         rnum = 8;
     } else {
         cp = buf;
index 1dec109..873eb2e 100644 (file)
@@ -135,7 +135,7 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
     dh = pkey->pkey.dh;
 
     str = ASN1_STRING_new();
-    if(!str) {
+    if (!str) {
         DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
index c808ab6..d686ab0 100644 (file)
@@ -202,7 +202,8 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                 goto err;
 
             if (!seed_len) {
-                RAND_pseudo_bytes(seed, qsize);
+                if (RAND_pseudo_bytes(seed, qsize) < 0)
+                    goto err;
                 seed_is_random = 1;
             } else {
                 seed_is_random = 0;
index b30eab0..6edb26d 100644 (file)
@@ -106,23 +106,23 @@ static DSA_METHOD openssl_dsa_meth = {
 #define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \
         do { \
         int _tmp_res53; \
-        if((dsa)->meth->dsa_mod_exp) \
+        if ((dsa)->meth->dsa_mod_exp) \
                 _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \
                                 (a2), (p2), (m), (ctx), (in_mont)); \
         else \
                 _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \
                                 (m), (ctx), (in_mont)); \
-        if(!_tmp_res53) err_instr; \
+        if (!_tmp_res53) err_instr; \
         } while(0)
 #define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \
         do { \
         int _tmp_res53; \
-        if((dsa)->meth->bn_mod_exp) \
+        if ((dsa)->meth->bn_mod_exp) \
                 _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \
                                 (m), (ctx), (m_ctx)); \
         else \
                 _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \
-        if(!_tmp_res53) err_instr; \
+        if (!_tmp_res53) err_instr; \
         } while(0)
 
 const DSA_METHOD *DSA_OpenSSL(void)
index d2a48bb..09b8eaf 100644 (file)
@@ -285,7 +285,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
  * honest. For one thing, I think I have to return a negative value for any
  * error because possible DSO_ctrl() commands may return values such as
  * "size"s that can legitimately be zero (making the standard
- * "if(DSO_cmd(...))" form that works almost everywhere else fail at odd
+ * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd
  * times. I'd prefer "output" values to be passed by reference and the return
  * value as success/failure like usual ... but we conform when we must... :-)
  */
index c245d88..0d04cc6 100644 (file)
@@ -387,7 +387,7 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
     }
 
     /* test required by X9.62 */
-    if (!EC_POINT_is_on_curve(group, point, ctx)) {
+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
         ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
         goto err;
     }
index b4b0e9f..4ad8494 100644 (file)
@@ -1114,7 +1114,7 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
 {
     int ret = 0, ok = 0;
     unsigned char *buffer = NULL;
-    size_t buf_len = 0, tmp_len;
+    size_t buf_len = 0, tmp_len, bn_len;
     EC_PRIVATEKEY *priv_key = NULL;
 
     if (a == NULL || a->group == NULL || a->priv_key == NULL ||
@@ -1130,18 +1130,32 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
 
     priv_key->version = a->version;
 
-    buf_len = (size_t)BN_num_bytes(a->priv_key);
+    bn_len = (size_t)BN_num_bytes(a->priv_key);
+
+    /* Octetstring may need leading zeros if BN is to short */
+
+    buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8;
+
+    if (bn_len > buf_len) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
+        goto err;
+    }
+
     buffer = OPENSSL_malloc(buf_len);
     if (buffer == NULL) {
         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
-    if (!BN_bn2bin(a->priv_key, buffer)) {
+    if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) {
         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
         goto err;
     }
 
+    if (buf_len - bn_len > 0) {
+        memset(buffer, 0, buf_len - bn_len);
+    }
+
     if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
         ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
         goto err;
index d3f5349..dd6f0ac 100644 (file)
@@ -85,7 +85,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
         ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
         goto err;
     }
-    if (!EC_POINT_is_on_curve(group, group->generator, ctx)) {
+    if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
         ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
         goto err;
     }
index ebdffc8..55ce3fe 100644 (file)
@@ -314,7 +314,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
         goto err;
 
     /* testing whether the pub_key is on the elliptic curve */
-    if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
+    if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
         ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
         goto err;
     }
index 319e651..d79ed1e 100644 (file)
@@ -451,14 +451,6 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
 int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
 int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
 
-/* method functions in ec2_mult.c */
-int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
-                       const BIGNUM *scalar, size_t num,
-                       const EC_POINT *points[], const BIGNUM *scalars[],
-                       BN_CTX *);
-int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
-int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
-
 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
 /* method functions in ecp_nistp224.c */
 int ec_GFp_nistp224_group_init(EC_GROUP *group);
index 9a54f41..e227520 100644 (file)
@@ -934,6 +934,13 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
     return group->meth->is_at_infinity(group, point);
 }
 
+/*
+ * Check whether an EC_POINT is on the curve or not. Note that the return
+ * value for this function should NOT be treated as a boolean. Return values:
+ *  1: The point is on the curve
+ *  0: The point is not on the curve
+ * -1: An error occurred
+ */
 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
                          BN_CTX *ctx)
 {
index a911a0a..5ef12ec 100644 (file)
@@ -338,12 +338,14 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
 
     if (buf == NULL)
         return 1;
-    if (off) {
+    if (off > 0) {
         if (off > 128)
             off = 128;
         memset(str, ' ', off);
         if (BIO_write(fp, str, off) <= 0)
             return 0;
+    } else {
+        off = 0;
     }
 
     if (BIO_printf(fp, "%s", name) <= 0)
index e5cec8b..1bc3f39 100644 (file)
@@ -413,7 +413,7 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
     }
 
     /* test required by X9.62 */
-    if (!EC_POINT_is_on_curve(group, point, ctx)) {
+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
         ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
         goto err;
     }
index 2e1a7e8..27d31f7 100644 (file)
@@ -351,6 +351,8 @@ void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
     ENGINE_PILE_DOALL dall;
     dall.cb = cb;
     dall.arg = arg;
-    lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
-                             ENGINE_PILE_DOALL, &dall);
+    if (table)
+        lh_ENGINE_PILE_doall_arg(&table->piles,
+                                 LHASH_DOALL_ARG_FN(int_cb),
+                                 ENGINE_PILE_DOALL, &dall);
 }
index a455034..5c32e35 100644 (file)
@@ -491,7 +491,8 @@ static int sig_out(BIO *b)
      * FIXME: there's absolutely no guarantee this makes any sense at all,
      * particularly now EVP_MD_CTX has been restructured.
      */
-    RAND_pseudo_bytes(md->md_data, md->digest->md_size);
+    if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0)
+        goto berr;
     memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
     longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
     ctx->buf_len += md->digest->md_size;
index 245c18a..1ede7bd 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <openssl/opensslconf.h>
 #ifndef OPENSSL_NO_AES
+#include <openssl/crypto.h>
 # include <openssl/evp.h>
 # include <openssl/err.h>
 # include <string.h>
@@ -753,7 +754,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
 
     case EVP_CTRL_AEAD_TLS1_AAD:
         /* Save the AAD for later use */
-        if (arg != 13)
+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
             return 0;
         memcpy(c->buf, ptr, arg);
         gctx->tls_aad_len = arg;
@@ -914,7 +915,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
         /* Retrieve tag */
         CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN);
         /* If tag mismatch wipe buffer */
-        if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) {
+        if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) {
             OPENSSL_cleanse(out, len);
             goto err;
         }
@@ -1259,7 +1260,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
             !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
             unsigned char tag[16];
             if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
-                if (!memcmp(tag, ctx->buf, cctx->M))
+                if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M))
                     rv = len;
             }
         }
index 3f8a5ae..d1f5928 100644 (file)
@@ -503,7 +503,12 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
     case EVP_CTRL_AEAD_TLS1_AAD:
         {
             unsigned char *p = ptr;
-            unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+            unsigned int len;
+
+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
+                return -1;
+            len = p[arg - 2] << 8 | p[arg - 1];
 
             if (ctx->encrypt) {
                 key->payload_length = len;
@@ -520,8 +525,6 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
                                AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
                              - len);
             } else {
-                if (arg > 13)
-                    arg = 13;
                 memcpy(key->aux.tls_aad, ptr, arg);
                 key->payload_length = arg;
 
index 80735d3..2da1117 100644 (file)
@@ -54,6 +54,7 @@
 
 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
 
+# include <openssl/crypto.h>
 # include <openssl/evp.h>
 # include <openssl/objects.h>
 # include <openssl/rc4.h>
@@ -210,7 +211,7 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
             MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
             MD5_Final(mac, &key->md);
 
-            if (memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+            if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
                 return 0;
         } else {
             MD5_Update(&key->md, out + md5_off, len - md5_off);
@@ -258,7 +259,12 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
     case EVP_CTRL_AEAD_TLS1_AAD:
         {
             unsigned char *p = ptr;
-            unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+            unsigned int len;
+
+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
+                return -1;
+
+            len = p[arg - 2] << 8 | p[arg - 1];
 
             if (!ctx->encrypt) {
                 len -= MD5_DIGEST_LENGTH;
index d1d8a07..5c5988f 100644 (file)
@@ -137,7 +137,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
     unsigned int total = 0;
 
     *outl = 0;
-    if (inl == 0)
+    if (inl <= 0)
         return;
     OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
     if ((ctx->num + inl) < ctx->length) {
index b00997b..6cf98ac 100644 (file)
 # define EVP_PKS_RSA     0x0100
 # define EVP_PKS_DSA     0x0200
 # define EVP_PKS_EC      0x0400
-# define EVP_PKT_EXP     0x1000 /* <= 512 bit key */
 
 # define EVP_PKEY_NONE   NID_undef
 # define EVP_PKEY_RSA    NID_rsaEncryption
@@ -409,6 +408,9 @@ struct evp_cipher_st {
 /* Set the GCM invocation field, decrypt only */
 # define         EVP_CTRL_GCM_SET_IV_INV         0x18
 
+/* RFC 5246 defines additional data to be 13 bytes in length */
+# define         EVP_AEAD_TLS1_AAD_LEN           13
+
 /* GCM TLS constants */
 /* Length of fixed part of IV derived from PRF */
 # define EVP_GCM_TLS_FIXED_IV_LEN                        4
index caabbf4..ba9dfff 100644 (file)
@@ -82,8 +82,9 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
         return 1;
     if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
         return 0;
-    if (EVP_CIPHER_CTX_iv_length(ctx))
-        RAND_pseudo_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx));
+    if (EVP_CIPHER_CTX_iv_length(ctx)
+        && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
+        return 0;
 
     if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
         return 0;
index 5477816..5925467 100644 (file)
@@ -91,8 +91,14 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
     if (md != NULL) {
         reset = 1;
         ctx->md = md;
-    } else
+    } else if (ctx->md) {
         md = ctx->md;
+    } else {
+        return 0;
+    }
+
+    if (!ctx->key_init && key == NULL)
+        return 0;
 
     if (key != NULL) {
         reset = 1;
@@ -107,13 +113,15 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
                                     &ctx->key_length))
                 goto err;
         } else {
-            OPENSSL_assert(len >= 0 && len <= (int)sizeof(ctx->key));
+            if (len < 0 || len > (int)sizeof(ctx->key))
+                return 0;
             memcpy(ctx->key, key, len);
             ctx->key_length = len;
         }
         if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
             memset(&ctx->key[ctx->key_length], 0,
                    HMAC_MAX_MD_CBLOCK - ctx->key_length);
+        ctx->key_init = 1;
     }
 
     if (reset) {
@@ -151,6 +159,9 @@ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
     if (FIPS_mode() && !ctx->i_ctx.engine)
         return FIPS_hmac_update(ctx, data, len);
 #endif
+    if (!ctx->key_init)
+        return 0;
+
     return EVP_DigestUpdate(&ctx->md_ctx, data, len);
 }
 
@@ -163,6 +174,9 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
         return FIPS_hmac_final(ctx, md, len);
 #endif
 
+    if (!ctx->key_init)
+        goto err;
+
     if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i))
         goto err;
     if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx))
@@ -181,6 +195,8 @@ void HMAC_CTX_init(HMAC_CTX *ctx)
     EVP_MD_CTX_init(&ctx->i_ctx);
     EVP_MD_CTX_init(&ctx->o_ctx);
     EVP_MD_CTX_init(&ctx->md_ctx);
+    ctx->key_init = 0;
+    ctx->md = NULL;
 }
 
 int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
@@ -191,8 +207,11 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
         goto err;
     if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx))
         goto err;
-    memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
-    dctx->key_length = sctx->key_length;
+    dctx->key_init = sctx->key_init;
+    if (sctx->key_init) {
+        memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+        dctx->key_length = sctx->key_length;
+    }
     dctx->md = sctx->md;
     return 1;
  err:
@@ -232,6 +251,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
     HMAC_CTX_cleanup(&c);
     return md;
  err:
+    HMAC_CTX_cleanup(&c);
     return NULL;
 }
 
index b8b55cd..f8e9f5e 100644 (file)
@@ -79,6 +79,7 @@ typedef struct hmac_ctx_st {
     EVP_MD_CTX o_ctx;
     unsigned int key_length;
     unsigned char key[HMAC_MAX_MD_CBLOCK];
+    int key_init;
 } HMAC_CTX;
 
 # define HMAC_size(e)    (EVP_MD_size((e)->md))
index c1efb45..1823833 100644 (file)
  */
 #undef ROTATE
 #ifndef PEDANTIC
-# if defined(_MSC_VER) || defined(__ICC)
+# if defined(_MSC_VER)
 #  define ROTATE(a,n)   _lrotl(a,n)
+# elif defined(__ICC)
+#  define ROTATE(a,n)   _rotl(a,n)
 # elif defined(__MWERKS__)
 #  if defined(__POWERPC__)
 #   define ROTATE(a,n)  __rlwinm(a,n,0,31)
index 2ce3e89..fdad49b 100644 (file)
@@ -365,6 +365,9 @@ char *CRYPTO_strdup(const char *str, const char *file, int line)
 {
     char *ret = CRYPTO_malloc(strlen(str) + 1, file, line);
 
+    if (ret == NULL)
+        return NULL;
+
     strcpy(ret, str);
     return ret;
 }
index f69f2c9..0ee569f 100644 (file)
@@ -1622,7 +1622,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
     ctx->Xi.u[1] ^= ctx->EK0.u[1];
 
     if (tag && len <= sizeof(ctx->Xi))
-        return memcmp(ctx->Xi.c, tag, len);
+        return CRYPTO_memcmp(ctx->Xi.c, tag, len);
     else
         return -1;
 }
index c6774f4..2485992 100644 (file)
@@ -313,7 +313,7 @@ void OBJ_NAME_do_all_sorted(int type,
     d.names =
         OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh) * sizeof *d.names);
     /* Really should return an error if !d.names...but its a void function! */
-    if(d.names) {
+    if (d.names) {
         d.n = 0;
         OBJ_NAME_do_all(type, do_all_sorted_fn, &d);
 
index e42a1c1..aca382a 100644 (file)
@@ -142,7 +142,7 @@ static unsigned long added_obj_hash(const ADDED_OBJ *ca)
         return 0;
     }
     ret &= 0x3fffffffL;
-    ret |= ca->type << 30L;
+    ret |= ((unsigned long)ca->type) << 30L;
     return (ret);
 }
 
@@ -400,6 +400,8 @@ static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
     j = (a->length - b->length);
     if (j)
         return (j);
+    if (a->length == 0)
+        return 0;
     return (memcmp(a->data, b->data, a->length));
 }
 
@@ -415,6 +417,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a)
     if (a->nid != 0)
         return (a->nid);
 
+    if (a->length == 0)
+        return NID_undef;
+
     if (added != NULL) {
         ad.type = ADDED_DATA;
         ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
index 4d74550..cb1d216 100644 (file)
@@ -8,9 +8,9 @@ The basic syntax for adding an object is as follows:
 
        1 2 3 4         : shortName     : Long Name
 
-               If the long name doesn't contain spaces, or no short name
-               exists, the long name is used as basis for the base name
-               in C.  Otherwise, the short name is used.
+               If Long Name contains only word characters and hyphen-minus
+               (0x2D) or full stop (0x2E) then Long Name is used as basis
+               for the base name in C. Otherwise, the shortName is used.
 
                The base name (let's call it 'base') will then be used to
                create the C macros SN_base, LN_base, NID_base and OBJ_base.
@@ -22,7 +22,7 @@ Then there are some extra commands:
 
        !Alias foo 1 2 3 4
 
-               This juts makes a name foo for an OID.  The C macro
+               This just makes a name foo for an OID.  The C macro
                OBJ_foo will be created as a result.
 
        !Cname foo
index 849cb2f..c19648c 100644 (file)
@@ -361,8 +361,8 @@ static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
     ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
     if (val)
         memcpy(tmpval, val, len);
-    else
-        RAND_pseudo_bytes(tmpval, len);
+    else if (RAND_pseudo_bytes(tmpval, len) < 0)
+        goto err;
     if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
                          &os, 0, X509V3_ADD_REPLACE))
         goto err;
index 6c0ccb5..d4a257c 100644 (file)
@@ -83,6 +83,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
 {
     X509 *signer, *x;
     STACK_OF(X509) *chain = NULL;
+    STACK_OF(X509) *untrusted = NULL;
     X509_STORE_CTX ctx;
     int i, ret = 0;
     ret = ocsp_find_signer(&signer, bs, certs, st, flags);
@@ -107,10 +108,20 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
     }
     if (!(flags & OCSP_NOVERIFY)) {
         int init_res;
-        if (flags & OCSP_NOCHAIN)
-            init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL);
-        else
-            init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
+        if (flags & OCSP_NOCHAIN) {
+            untrusted = NULL;
+        } else if (bs->certs && certs) {
+            untrusted = sk_X509_dup(bs->certs);
+            for (i = 0; i < sk_X509_num(certs); i++) {
+                if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) {
+                    OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
+                    goto end;
+                }
+            }
+        } else {
+            untrusted = bs->certs;
+        }
+        init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted);
         if (!init_res) {
             ret = -1;
             OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
@@ -161,6 +172,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
  end:
     if (chain)
         sk_X509_pop_free(chain, X509_free);
+    if (bs->certs && certs)
+        sk_X509_free(untrusted);
     return ret;
 }
 
index daf3905..94a95f3 100644 (file)
@@ -30,11 +30,11 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x100010dfL
+# define OPENSSL_VERSION_NUMBER  0x100010efL
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1m-fips 19 Mar 2015"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1n-fips 11 Jun 2015"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1m 19 Mar 2015"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1n 11 Jun 2015"
 # endif
 # define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
 
index febb53e..5507161 100644 (file)
@@ -435,7 +435,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
                   pem_password_cb *callback, void *u)
 {
-    int i, j, o, klen;
+    int i = 0, j, o, klen;
     long len;
     EVP_CIPHER_CTX ctx;
     unsigned char key[EVP_MAX_KEY_LENGTH];
index b98c76c..5747c73 100644 (file)
@@ -138,6 +138,8 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
         if (kstr == buf)
             OPENSSL_cleanse(buf, klen);
         PKCS8_PRIV_KEY_INFO_free(p8inf);
+        if (p8 == NULL)
+            return 0;
         if (isder)
             ret = i2d_PKCS8_bio(bp, p8);
         else
index 256b210..5ab4bf2 100644 (file)
@@ -60,6 +60,7 @@
 #ifndef OPENSSL_NO_HMAC
 # include <stdio.h>
 # include "cryptlib.h"
+# include <openssl/crypto.h>
 # include <openssl/hmac.h>
 # include <openssl/rand.h>
 # include <openssl/pkcs12.h>
@@ -123,7 +124,7 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
         return 0;
     }
     if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
-        || memcmp(mac, p12->mac->dinfo->digest->data, maclen))
+        || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen))
         return 0;
     return 1;
 }
index 31a1b98..c8d7db0 100644 (file)
@@ -445,6 +445,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
 
     switch (i) {
     case NID_pkcs7_signed:
+        /*
+         * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+         * field and optional content.
+         * data_body is NULL if that structure has no (=detached) content
+         * or if the contentType is wrong (i.e., not "data").
+         */
         data_body = PKCS7_get_octet_string(p7->d.sign->contents);
         if (!PKCS7_is_detached(p7) && data_body == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
@@ -456,6 +462,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
     case NID_pkcs7_signedAndEnveloped:
         rsk = p7->d.signed_and_enveloped->recipientinfo;
         md_sk = p7->d.signed_and_enveloped->md_algs;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
         enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
@@ -468,6 +475,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
     case NID_pkcs7_enveloped:
         rsk = p7->d.enveloped->recipientinfo;
         enc_alg = p7->d.enveloped->enc_data->algorithm;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.enveloped->enc_data->enc_data;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
         if (evp_cipher == NULL) {
@@ -481,6 +489,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
         goto err;
     }
 
+    /* Detached content must be supplied via in_bio instead. */
+    if (data_body == NULL && in_bio == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+        goto err;
+    }
+
     /* We will be checking the signature */
     if (md_sk != NULL) {
         for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
@@ -623,7 +637,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
         etmp = NULL;
     }
 #if 1
-    if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
+    if (in_bio != NULL) {
         bio = in_bio;
     } else {
 # if 0
index d61d6e8..6a7c67c 100644 (file)
@@ -228,8 +228,14 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
                 return ret;
             ret = sltmp;
         } else if (rctx->pad_mode == RSA_X931_PADDING) {
-            if (!setup_tbuf(rctx, ctx))
+            if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
+                RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL);
+                return -1;
+            }
+            if (!setup_tbuf(rctx, ctx)) {
+                RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE);
                 return -1;
+            }
             memcpy(rctx->tbuf, tbs, tbslen);
             rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md));
             ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
index 701b5cd..50f75d7 100644 (file)
@@ -497,7 +497,8 @@ SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
     if (!SRP_user_pwd_set_ids(user, username, NULL))
         goto err;
 
-    RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
+    if (RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH) < 0)
+        goto err;
     EVP_MD_CTX_init(&ctxt);
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
@@ -549,7 +550,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
     }
 
     if (*salt == NULL) {
-        RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+        if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+            goto err;
 
         s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
     } else {
@@ -609,7 +611,8 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
     srp_bn_print(g);
 
     if (*salt == NULL) {
-        RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+        if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+            goto err;
 
         *salt = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
     }
index 28884c2..cc8cf25 100644 (file)
@@ -117,7 +117,7 @@ void CRYPTO_thread_setup(void)
     int i;
 
     lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
-    if(!lock_cs) {
+    if (!lock_cs) {
         /* Nothing we can do about this...void function! */
         return;
     }
@@ -172,7 +172,7 @@ void CRYPTO_thread_setup(void)
 # else
     lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t));
 # endif
-    if(!lock_cs) {
+    if (!lock_cs) {
         /* Nothing we can do about this...void function! */
         return;
     }
@@ -260,7 +260,7 @@ void CRYPTO_thread_setup(void)
     char filename[20];
 
     lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
-    if(!lock_cs) {
+    if (!lock_cs) {
         /* Nothing we can do about this...void function! */
         return;
     }
@@ -328,11 +328,11 @@ void CRYPTO_thread_setup(void)
 
     lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
     lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
-    if(!lock_cs || !lock_count) {
+    if (!lock_cs || !lock_count) {
         /* Nothing we can do about this...void function! */
-        if(lock_cs)
+        if (lock_cs)
             OPENSSL_free(lock_cs);
-        if(lock_count)
+        if (lock_count)
             OPENSSL_free(lock_count);
         return;
     }
index a910636..8415d1d 100644 (file)
@@ -216,6 +216,8 @@ X509_STORE *X509_STORE_new(void)
 
 static void cleanup(X509_OBJECT *a)
 {
+    if (!a)
+        return;
     if (a->type == X509_LU_X509) {
         X509_free(a->data.x509);
     } else if (a->type == X509_LU_CRL) {
index 136bfbd..16db4c0 100644 (file)
@@ -151,11 +151,11 @@ static int x509_subject_cmp(X509 **a, X509 **b)
 
 int X509_verify_cert(X509_STORE_CTX *ctx)
 {
-    X509 *x, *xtmp, *chain_ss = NULL;
+    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
     int bad_chain = 0;
     X509_VERIFY_PARAM *param = ctx->param;
     int depth, i, ok = 0;
-    int num;
+    int num, j, retry;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
     STACK_OF(X509) *sktmp = NULL;
     if (ctx->cert == NULL) {
@@ -224,85 +224,118 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
         break;
     }
 
+    /* Remember how many untrusted certs we have */
+    j = num;
     /*
      * at this point, chain should contain a list of untrusted certificates.
      * We now need to add at least one trusted one, if possible, otherwise we
      * complain.
      */
 
-    /*
-     * Examine last certificate in chain and see if it is self signed.
-     */
-
-    i = sk_X509_num(ctx->chain);
-    x = sk_X509_value(ctx->chain, i - 1);
-    if (ctx->check_issued(ctx, x, x)) {
-        /* we have a self signed certificate */
-        if (sk_X509_num(ctx->chain) == 1) {
-            /*
-             * We have a single self signed certificate: see if we can find
-             * it in the store. We must have an exact match to avoid possible
-             * impersonation.
-             */
-            ok = ctx->get_issuer(&xtmp, ctx, x);
-            if ((ok <= 0) || X509_cmp(x, xtmp)) {
-                ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
-                ctx->current_cert = x;
-                ctx->error_depth = i - 1;
-                if (ok == 1)
-                    X509_free(xtmp);
-                bad_chain = 1;
-                ok = cb(0, ctx);
-                if (!ok)
-                    goto end;
+    do {
+        /*
+         * Examine last certificate in chain and see if it is self signed.
+         */
+        i = sk_X509_num(ctx->chain);
+        x = sk_X509_value(ctx->chain, i - 1);
+        if (ctx->check_issued(ctx, x, x)) {
+            /* we have a self signed certificate */
+            if (sk_X509_num(ctx->chain) == 1) {
+                /*
+                 * We have a single self signed certificate: see if we can
+                 * find it in the store. We must have an exact match to avoid
+                 * possible impersonation.
+                 */
+                ok = ctx->get_issuer(&xtmp, ctx, x);
+                if ((ok <= 0) || X509_cmp(x, xtmp)) {
+                    ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
+                    ctx->current_cert = x;
+                    ctx->error_depth = i - 1;
+                    if (ok == 1)
+                        X509_free(xtmp);
+                    bad_chain = 1;
+                    ok = cb(0, ctx);
+                    if (!ok)
+                        goto end;
+                } else {
+                    /*
+                     * We have a match: replace certificate with store
+                     * version so we get any trust settings.
+                     */
+                    X509_free(x);
+                    x = xtmp;
+                    (void)sk_X509_set(ctx->chain, i - 1, x);
+                    ctx->last_untrusted = 0;
+                }
             } else {
                 /*
-                 * We have a match: replace certificate with store version so
-                 * we get any trust settings.
+                 * extract and save self signed certificate for later use
                  */
-                X509_free(x);
-                x = xtmp;
-                (void)sk_X509_set(ctx->chain, i - 1, x);
-                ctx->last_untrusted = 0;
+                chain_ss = sk_X509_pop(ctx->chain);
+                ctx->last_untrusted--;
+                num--;
+                j--;
+                x = sk_X509_value(ctx->chain, num - 1);
             }
-        } else {
-            /*
-             * extract and save self signed certificate for later use
-             */
-            chain_ss = sk_X509_pop(ctx->chain);
-            ctx->last_untrusted--;
-            num--;
-            x = sk_X509_value(ctx->chain, num - 1);
         }
-    }
-
-    /* We now lookup certs from the certificate store */
-    for (;;) {
-        /* If we have enough, we break */
-        if (depth < num)
-            break;
-
-        /* If we are self signed, we break */
-        if (ctx->check_issued(ctx, x, x))
-            break;
-
-        ok = ctx->get_issuer(&xtmp, ctx, x);
+        /* We now lookup certs from the certificate store */
+        for (;;) {
+            /* If we have enough, we break */
+            if (depth < num)
+                break;
+            /* If we are self signed, we break */
+            if (ctx->check_issued(ctx, x, x))
+                break;
+            ok = ctx->get_issuer(&xtmp, ctx, x);
+            if (ok < 0)
+                return ok;
+            if (ok == 0)
+                break;
+            x = xtmp;
+            if (!sk_X509_push(ctx->chain, x)) {
+                X509_free(xtmp);
+                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            num++;
+        }
 
-        if (ok < 0)
-            return ok;
-        if (ok == 0)
-            break;
+        /*
+         * If we haven't got a least one certificate from our store then check
+         * if there is an alternative chain that could be used.  We only do this
+         * if the user hasn't switched off alternate chain checking
+         */
+        retry = 0;
+        if (j == ctx->last_untrusted &&
+            !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
+            while (j-- > 1) {
+                xtmp2 = sk_X509_value(ctx->chain, j - 1);
+                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
+                if (ok < 0)
+                    goto end;
+                /* Check if we found an alternate chain */
+                if (ok > 0) {
+                    /*
+                     * Free up the found cert we'll add it again later
+                     */
+                    X509_free(xtmp);
 
-        x = xtmp;
-        if (!sk_X509_push(ctx->chain, x)) {
-            X509_free(xtmp);
-            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
-            return 0;
+                    /*
+                     * Dump all the certs above this point - we've found an
+                     * alternate chain
+                     */
+                    while (num > j) {
+                        xtmp = sk_X509_pop(ctx->chain);
+                        X509_free(xtmp);
+                        num--;
+                        ctx->last_untrusted--;
+                    }
+                    retry = 1;
+                    break;
+                }
+            }
         }
-        num++;
-    }
-
-    /* we now have our chain, lets check it... */
+    } while (retry);
 
     /* Is last certificate looked up self signed? */
     if (!ctx->check_issued(ctx, x, x)) {
@@ -1604,47 +1637,84 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
     ASN1_TIME atm;
     long offset;
     char buff1[24], buff2[24], *p;
-    int i, j;
+    int i, j, remaining;
 
     p = buff1;
-    i = ctm->length;
+    remaining = ctm->length;
     str = (char *)ctm->data;
+    /*
+     * Note that the following (historical) code allows much more slack in the
+     * time format than RFC5280. In RFC5280, the representation is fixed:
+     * UTCTime: YYMMDDHHMMSSZ
+     * GeneralizedTime: YYYYMMDDHHMMSSZ
+     */
     if (ctm->type == V_ASN1_UTCTIME) {
-        if ((i < 11) || (i > 17))
+        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+        int min_length = sizeof("YYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
             return 0;
         memcpy(p, str, 10);
         p += 10;
         str += 10;
+        remaining -= 10;
     } else {
-        if (i < 13)
+        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
             return 0;
         memcpy(p, str, 12);
         p += 12;
         str += 12;
+        remaining -= 12;
     }
 
     if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
         *(p++) = '0';
         *(p++) = '0';
     } else {
+        /* SS (seconds) */
+        if (remaining < 2)
+            return 0;
         *(p++) = *(str++);
         *(p++) = *(str++);
-        /* Skip any fractional seconds... */
-        if (*str == '.') {
+        remaining -= 2;
+        /*
+         * Skip any (up to three) fractional seconds...
+         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+         * Can we just kill them altogether?
+         */
+        if (remaining && *str == '.') {
             str++;
-            while ((*str >= '0') && (*str <= '9'))
-                str++;
+            remaining--;
+            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+                if (*str < '0' || *str > '9')
+                    break;
+            }
         }
 
     }
     *(p++) = 'Z';
     *(p++) = '\0';
 
-    if (*str == 'Z')
+    /* We now need either a terminating 'Z' or an offset. */
+    if (!remaining)
+        return 0;
+    if (*str == 'Z') {
+        if (remaining != 1)
+            return 0;
         offset = 0;
-    else {
+    } else {
+        /* (+-)HHMM */
         if ((*str != '+') && (*str != '-'))
             return 0;
+        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+        if (remaining != 5)
+            return 0;
+        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+            return 0;
         offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
         offset += (str[3] - '0') * 10 + (str[4] - '0');
         if (*str == '-')
@@ -1921,6 +1991,8 @@ X509_STORE_CTX *X509_STORE_CTX_new(void)
 
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
 {
+    if (!ctx)
+        return;
     X509_STORE_CTX_cleanup(ctx);
     OPENSSL_free(ctx);
 }
index 1f8c0ec..aacdf55 100644 (file)
@@ -405,6 +405,12 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 # define X509_V_FLAG_USE_DELTAS                  0x2000
 /* Check selfsigned CA signature */
 # define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.1n/1.0.2b. Setting
+ * this flag will force the behaviour to match that of previous versions.
+ */
+# define X509_V_FLAG_NO_ALT_CHAINS               0x100000
 
 # define X509_VP_FLAG_DEFAULT                    0x1
 # define X509_VP_FLAG_OVERWRITE                  0x2
index d054366..6b0bf8a 100644 (file)
@@ -100,6 +100,8 @@ X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
 
 void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
 {
+    if (param == NULL)
+        return;
     x509_verify_param_zero(param);
     OPENSSL_free(param);
 }
index 0331752..9219f75 100644 (file)
@@ -121,9 +121,6 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
         }
     }
 
-    /* /8 because it's 1024 bits we look for, not bytes */
-    if (EVP_PKEY_size(pk) <= 1024 / 8)
-        ret |= EVP_PKT_EXP;
     if (pkey == NULL)
         EVP_PKEY_free(pk);
     return (ret);
index 807867b..22ec202 100644 (file)
@@ -584,24 +584,26 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
 
 static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
 {
-    int ret;
-    STACK_OF(CONF_VALUE) *sk;
-    X509_NAME *nm;
+    int ret = 0;
+    STACK_OF(CONF_VALUE) *sk = NULL;
+    X509_NAME *nm = NULL;
     if (!(nm = X509_NAME_new()))
-        return 0;
+        goto err;
     sk = X509V3_get_section(ctx, value);
     if (!sk) {
         X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
         ERR_add_error_data(2, "section=", value);
-        X509_NAME_free(nm);
-        return 0;
+        goto err;
     }
     /* FIXME: should allow other character types... */
     ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
     if (!ret)
-        X509_NAME_free(nm);
+        goto err;
     gen->d.dirn = nm;
-    X509V3_section_free(ctx, sk);
 
+err:
+    if (ret == 0)
+        X509_NAME_free(nm);
+    X509V3_section_free(ctx, sk);
     return ret;
 }
index dca6ab2..0febc1b 100644 (file)
@@ -230,11 +230,11 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
                 goto merr;
             if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
                 goto merr;
-            if(!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) {
+            if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) {
                 X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
-            if(!(qual->d.cpsuri = M_ASN1_IA5STRING_new()))
+            if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new()))
                 goto merr;
             if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
                                  strlen(cnf->value)))
@@ -294,7 +294,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
     POLICYQUALINFO *qual;
     if (!(qual = POLICYQUALINFO_new()))
         goto merr;
-    if(!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) {
+    if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) {
         X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR);
         goto err;
     }
@@ -304,7 +304,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
     for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
         cnf = sk_CONF_VALUE_value(unot, i);
         if (!strcmp(cnf->name, "explicitText")) {
-            if(!(not->exptext = M_ASN1_VISIBLESTRING_new()))
+            if (!(not->exptext = M_ASN1_VISIBLESTRING_new()))
                 goto merr;
             if (!ASN1_STRING_set(not->exptext, cnf->value,
                                  strlen(cnf->value)))
index 65dd1e2..94aaebb 100644 (file)
@@ -285,6 +285,10 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
     int state;
     /* We are going to modify the line so copy it first */
     linebuf = BUF_strdup(line);
+    if (linebuf == NULL) {
+        X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     state = HDR_NAME;
     ntmp = NULL;
     /* Go through all characters */
index d400ac7..2b1b78f 100644 (file)
@@ -109,6 +109,12 @@ extern "C" {
 #    undef OPENSSL_SYS_UNIX
 #    define OPENSSL_SYS_WIN32
 #   endif
+#   if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64)
+#    undef OPENSSL_SYS_UNIX
+#    if !defined(OPENSSL_SYS_WIN64)
+#     define OPENSSL_SYS_WIN64
+#    endif
+#   endif
 #   if defined(OPENSSL_SYSNAME_WINNT)
 #    undef OPENSSL_SYS_UNIX
 #    define OPENSSL_SYS_WINNT
@@ -121,7 +127,7 @@ extern "C" {
 # endif
 
 /* Anything that tries to look like Microsoft is "Windows" */
-# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
 #  undef OPENSSL_SYS_UNIX
 #  define OPENSSL_SYS_WINDOWS
 #  ifndef OPENSSL_SYS_MSDOS
index 3201b64..80ef58f 100644 (file)
@@ -1,6 +1,6 @@
 /* e_gost_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2015 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
@@ -90,6 +90,7 @@ static ERR_STRING_DATA GOST_str_functs[] = {
     {ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"},
     {ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"},
     {ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"},
+    {ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"},
     {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"},
     {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"},
     {ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"},
index 92be558..a2018ec 100644 (file)
@@ -90,6 +90,7 @@ void ERR_GOST_error(int function, int reason, char *file, int line);
 # define GOST_F_GOST_IMIT_CTRL                            114
 # define GOST_F_GOST_IMIT_FINAL                           140
 # define GOST_F_GOST_IMIT_UPDATE                          115
+# define GOST_F_GOST_SIGN_KEYGEN                          142
 # define GOST_F_PARAM_COPY_GOST01                         116
 # define GOST_F_PARAM_COPY_GOST94                         117
 # define GOST_F_PKEY_GOST01CP_DECRYPT                     118
index 2b96694..9536295 100644 (file)
@@ -41,6 +41,11 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
     BN_CTX *ctx = BN_CTX_new();
     int ok = 0;
 
+    if(!ctx) {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
     BN_CTX_start(ctx);
     p = BN_CTX_get(ctx);
     a = BN_CTX_get(ctx);
@@ -48,6 +53,10 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
     x = BN_CTX_get(ctx);
     y = BN_CTX_get(ctx);
     q = BN_CTX_get(ctx);
+    if(!p || !a || !b || !x || !y || !q) {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     while (params->nid != NID_undef && params->nid != nid)
         params++;
     if (params->nid == NID_undef) {
@@ -55,18 +64,33 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
                 GOST_R_UNSUPPORTED_PARAMETER_SET);
         goto err;
     }
-    BN_hex2bn(&p, params->p);
-    BN_hex2bn(&a, params->a);
-    BN_hex2bn(&b, params->b);
+    if(!BN_hex2bn(&p, params->p)
+        || !BN_hex2bn(&a, params->a)
+        || !BN_hex2bn(&b, params->b)) {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
+                ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 
     grp = EC_GROUP_new_curve_GFp(p, a, b, ctx);
+    if(!grp)  {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     P = EC_POINT_new(grp);
+    if(!P)  {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-    BN_hex2bn(&x, params->x);
-    BN_hex2bn(&y, params->y);
-    EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx);
-    BN_hex2bn(&q, params->q);
+    if(!BN_hex2bn(&x, params->x)
+        || !BN_hex2bn(&y, params->y)
+        || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx)
+        || !BN_hex2bn(&q, params->q))  {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 #ifdef DEBUG_KEYS
     fprintf(stderr, "Set params index %d oid %s\nq=",
             (params - R3410_2001_paramset), OBJ_nid2sn(params->nid));
@@ -74,16 +98,23 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
     fprintf(stderr, "\n");
 #endif
 
-    EC_GROUP_set_generator(grp, P, q, NULL);
+    if(!EC_GROUP_set_generator(grp, P, q, NULL)) {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     EC_GROUP_set_curve_name(grp, params->nid);
-
-    EC_KEY_set_group(eckey, grp);
+    if(!EC_KEY_set_group(eckey, grp)) {
+        GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     ok = 1;
  err:
-    EC_POINT_free(P);
-    EC_GROUP_free(grp);
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
+    if (P) EC_POINT_free(P);
+    if (grp) EC_GROUP_free(grp);
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
     return ok;
 }
 
@@ -94,7 +125,7 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid)
  */
 DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
 {
-    DSA_SIG *newsig = NULL;
+    DSA_SIG *newsig = NULL, *ret = NULL;
     BIGNUM *md = hashsum2bn(dgst);
     BIGNUM *order = NULL;
     const EC_GROUP *group;
@@ -103,6 +134,10 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
         NULL, *e = NULL;
     EC_POINT *C = NULL;
     BN_CTX *ctx = BN_CTX_new();
+    if(!ctx || !md) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     BN_CTX_start(ctx);
     OPENSSL_assert(dlen == 32);
     newsig = DSA_SIG_new();
@@ -111,11 +146,25 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
         goto err;
     }
     group = EC_KEY_get0_group(eckey);
+    if(!group) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     order = BN_CTX_get(ctx);
-    EC_GROUP_get_order(group, order, ctx);
+    if(!order || !EC_GROUP_get_order(group, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     priv_key = EC_KEY_get0_private_key(eckey);
+    if(!priv_key) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     e = BN_CTX_get(ctx);
-    BN_mod(e, md, order, ctx);
+    if(!e || !BN_mod(e, md, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 #ifdef DEBUG_SIGN
     fprintf(stderr, "digest as bignum=");
     BN_print_fp(stderr, md);
@@ -128,55 +177,80 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
     }
     k = BN_CTX_get(ctx);
     C = EC_POINT_new(group);
+    if(!k || !C) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     do {
         do {
             if (!BN_rand_range(k, order)) {
                 GOSTerr(GOST_F_GOST2001_DO_SIGN,
                         GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
-                DSA_SIG_free(newsig);
-                newsig = NULL;
                 goto err;
             }
             if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) {
                 GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
-                DSA_SIG_free(newsig);
-                newsig = NULL;
                 goto err;
             }
             if (!X)
                 X = BN_CTX_get(ctx);
+            if (!r)
+                r = BN_CTX_get(ctx);
+            if (!X || !r) {
+                GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
             if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) {
                 GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
-                DSA_SIG_free(newsig);
-                newsig = NULL;
                 goto err;
             }
-            if (!r)
-                r = BN_CTX_get(ctx);
-            BN_nnmod(r, X, order, ctx);
+
+            if(!BN_nnmod(r, X, order, ctx)) {
+                GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
         }
         while (BN_is_zero(r));
         /* s =  (r*priv_key+k*e) mod order */
         if (!tmp)
             tmp = BN_CTX_get(ctx);
-        BN_mod_mul(tmp, priv_key, r, order, ctx);
         if (!tmp2)
             tmp2 = BN_CTX_get(ctx);
-        BN_mod_mul(tmp2, k, e, order, ctx);
         if (!s)
             s = BN_CTX_get(ctx);
-        BN_mod_add(s, tmp, tmp2, order, ctx);
+        if (!tmp || !tmp2 || !s) {
+            GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        if(!BN_mod_mul(tmp, priv_key, r, order, ctx)
+            || !BN_mod_mul(tmp2, k, e, order, ctx)
+            || !BN_mod_add(s, tmp, tmp2, order, ctx)) {
+            GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
     }
     while (BN_is_zero(s));
 
     newsig->s = BN_dup(s);
     newsig->r = BN_dup(r);
+    if(!newsig->s || !newsig->r) {
+        GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    ret = newsig;
  err:
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    EC_POINT_free(C);
-    BN_free(md);
-    return newsig;
+    if(ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    if (C) EC_POINT_free(C);
+    if (md) BN_free(md);
+    if (!ret && newsig) {
+        DSA_SIG_free(newsig);
+    }
+    return ret;
 }
 
 /*
@@ -196,6 +270,11 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
     const EC_POINT *pub_key = NULL;
     int ok = 0;
 
+    if(!ctx || !group) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
     BN_CTX_start(ctx);
     order = BN_CTX_get(ctx);
     e = BN_CTX_get(ctx);
@@ -205,9 +284,17 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
     X = BN_CTX_get(ctx);
     R = BN_CTX_get(ctx);
     v = BN_CTX_get(ctx);
+    if(!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
-    EC_GROUP_get_order(group, order, ctx);
     pub_key = EC_KEY_get0_public_key(ec);
+    if(!pub_key || !EC_GROUP_get_order(group, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
     if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
         (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) {
         GOSTerr(GOST_F_GOST2001_DO_VERIFY,
@@ -217,19 +304,28 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
     }
     md = hashsum2bn(dgst);
 
-    BN_mod(e, md, order, ctx);
+    if(!md || !BN_mod(e, md, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 #ifdef DEBUG_SIGN
     fprintf(stderr, "digest as bignum: ");
     BN_print_fp(stderr, md);
     fprintf(stderr, "\ndigest mod q: ");
     BN_print_fp(stderr, e);
 #endif
-    if (BN_is_zero(e))
-        BN_one(e);
+    if (BN_is_zero(e) && !BN_one(e)) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     v = BN_mod_inverse(v, e, order, ctx);
-    BN_mod_mul(z1, sig->s, v, order, ctx);
-    BN_sub(tmp, order, sig->r);
-    BN_mod_mul(z2, tmp, v, order, ctx);
+    if(!v
+        || !BN_mod_mul(z1, sig->s, v, order, ctx)
+        || !BN_sub(tmp, order, sig->r)
+        || !BN_mod_mul(z2, tmp, v, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 #ifdef DEBUG_SIGN
     fprintf(stderr, "\nInverted digest value: ");
     BN_print_fp(stderr, v);
@@ -239,6 +335,10 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
     BN_print_fp(stderr, z2);
 #endif
     C = EC_POINT_new(group);
+    if (!C) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) {
         GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
         goto err;
@@ -247,7 +347,10 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
         GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
         goto err;
     }
-    BN_mod(R, X, order, ctx);
+    if(!BN_mod(R, X, order, ctx)) {
+        GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 #ifdef DEBUG_SIGN
     fprintf(stderr, "\nX=");
     BN_print_fp(stderr, X);
@@ -261,10 +364,12 @@ int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
         ok = 1;
     }
  err:
-    EC_POINT_free(C);
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    BN_free(md);
+    if (C) EC_POINT_free(C);
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    if (md) BN_free(md);
     return ok;
 }
 
@@ -287,6 +392,10 @@ int gost2001_compute_public(EC_KEY *ec)
         return 0;
     }
     ctx = BN_CTX_new();
+    if(!ctx) {
+        GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     BN_CTX_start(ctx);
     if (!(priv_key = EC_KEY_get0_private_key(ec))) {
         GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
@@ -294,6 +403,10 @@ int gost2001_compute_public(EC_KEY *ec)
     }
 
     pub_key = EC_POINT_new(group);
+    if(!pub_key) {
+        GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) {
         GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
         goto err;
@@ -304,9 +417,11 @@ int gost2001_compute_public(EC_KEY *ec)
     }
     ok = 256;
  err:
-    BN_CTX_end(ctx);
-    EC_POINT_free(pub_key);
-    BN_CTX_free(ctx);
+    if (pub_key) EC_POINT_free(pub_key);
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
     return ok;
 }
 
@@ -320,7 +435,13 @@ int gost2001_keygen(EC_KEY *ec)
 {
     BIGNUM *order = BN_new(), *d = BN_new();
     const EC_GROUP *group = EC_KEY_get0_group(ec);
-    EC_GROUP_get_order(group, order, NULL);
+
+    if(!group || !EC_GROUP_get_order(group, order, NULL)) {
+        GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
+        BN_free(d);
+        BN_free(order);
+        return 0;
+    }
 
     do {
         if (!BN_rand_range(d, order)) {
@@ -332,7 +453,13 @@ int gost2001_keygen(EC_KEY *ec)
         }
     }
     while (BN_is_zero(d));
-    EC_KEY_set_private_key(ec, d);
+
+    if(!EC_KEY_set_private_key(ec, d)) {
+        GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
+        BN_free(d);
+        BN_free(order);
+        return 0;
+    }
     BN_free(d);
     BN_free(order);
     return gost2001_compute_public(ec);
index 85f4bc8..ce57f17 100644 (file)
@@ -104,6 +104,7 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
     struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     gost_ctx cctx;
     int key_is_ephemeral = 1;
+    int tmp_outlen;
     EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
 
     /* Do not use vizir cipher parameters with cryptopro */
@@ -174,12 +175,13 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
     }
     ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
     gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
-    *outlen = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL);
-    if (*outlen <= 0) {
+    tmp_outlen = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL);
+    if (tmp_outlen <= 0) {
         GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
                 GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
         goto err;
     }
+    *outlen = tmp_outlen;
     if (!key_is_ephemeral) {
         /* Set control "public key from client certificate used" */
         if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <=
index 713a0fa..b7c5354 100644 (file)
@@ -115,7 +115,10 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
     }
     param_nid = OBJ_obj2nid(gkp->key_params);
     GOST_KEY_PARAMS_free(gkp);
-    EVP_PKEY_set_type(pkey, pkey_nid);
+    if(!EVP_PKEY_set_type(pkey, pkey_nid)) {
+        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
     switch (pkey_nid) {
     case NID_id_GostR3410_94:
         {
@@ -552,9 +555,19 @@ static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
     }
     if (!eto) {
         eto = EC_KEY_new();
-        EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto);
+        if(!eto) {
+            GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) {
+            GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+    if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) {
+        GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR);
+        return 0;
     }
-    EC_KEY_set_group(eto, EC_KEY_get0_group(efrom));
     if (EC_KEY_get0_private_key(eto)) {
         gost2001_compute_public(eto);
     }
@@ -729,8 +742,21 @@ static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
     }
     X = BN_new();
     Y = BN_new();
-    EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
-                                        pub_key, X, Y, NULL);
+    if(!X || !Y) {
+        GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
+        if(X) BN_free(X);
+        if(Y) BN_free(Y);
+        BN_free(order);
+        return 0;
+    }
+    if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
+                                        pub_key, X, Y, NULL)) {
+        GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR);
+        BN_free(X);
+        BN_free(Y);
+        BN_free(order);
+        return 0;
+    }
     data_len = 2 * BN_num_bytes(order);
     BN_free(order);
     databuf = OPENSSL_malloc(data_len);
index 9af7b06..b6275b2 100644 (file)
@@ -502,7 +502,7 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
         long keylen;
         int ret;
         unsigned char *keybuf = string_to_hex(value, &keylen);
-        if (keylen != 32) {
+        if (!keybuf || keylen != 32) {
             GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
                     GOST_R_INVALID_MAC_KEY_LENGTH);
             OPENSSL_free(keybuf);
index 0116e47..07ad921 100644 (file)
@@ -12,6 +12,7 @@
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
 #include <openssl/evp.h>
+#include <openssl/err.h>
 
 #include "gost_params.h"
 #include "gost_lcl.h"
@@ -52,11 +53,16 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig)
 DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 {
     BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL;
-    DSA_SIG *newsig = DSA_SIG_new();
+    DSA_SIG *newsig = NULL, *ret = NULL;
     BIGNUM *md = hashsum2bn(dgst);
     /* check if H(M) mod q is zero */
     BN_CTX *ctx = BN_CTX_new();
+    if(!ctx) {
+        GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     BN_CTX_start(ctx);
+    newsig = DSA_SIG_new();
     if (!newsig) {
         GOSTerr(GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY);
         goto err;
@@ -64,6 +70,10 @@ DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
     tmp = BN_CTX_get(ctx);
     k = BN_CTX_get(ctx);
     tmp2 = BN_CTX_get(ctx);
+    if(!tmp || !k || !tmp2) {
+        GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
     BN_mod(tmp, md, dsa->q, ctx);
     if (BN_is_zero(tmp)) {
         BN_one(md);
@@ -76,24 +86,41 @@ DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
             BN_rand_range(k, dsa->q);
             /* generate r = (a^x mod p) mod q */
             BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx);
-            if (!(newsig->r))
+            if (!(newsig->r)) {
                 newsig->r = BN_new();
+                if(!newsig->r) {
+                    GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+                    goto err;
+                }
+            }
             BN_mod(newsig->r, tmp, dsa->q, ctx);
         }
         while (BN_is_zero(newsig->r));
         /* generate s = (xr + k(Hm)) mod q */
         BN_mod_mul(tmp, dsa->priv_key, newsig->r, dsa->q, ctx);
         BN_mod_mul(tmp2, k, md, dsa->q, ctx);
-        if (!newsig->s)
+        if (!newsig->s) {
             newsig->s = BN_new();
+            if(!newsig->s) {
+                GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
         BN_mod_add(newsig->s, tmp, tmp2, dsa->q, ctx);
     }
     while (BN_is_zero(newsig->s));
+
+    ret = newsig;
  err:
     BN_free(md);
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    return newsig;
+    if(ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    if(!ret && newsig) {
+        DSA_SIG_free(newsig);
+    }
+    return ret;
 }
 
 /*
@@ -135,17 +162,21 @@ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
 int gost_do_verify(const unsigned char *dgst, int dgst_len,
                    DSA_SIG *sig, DSA *dsa)
 {
-    BIGNUM *md, *tmp = NULL;
+    BIGNUM *md = NULL, *tmp = NULL;
     BIGNUM *q2 = NULL;
     BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;
     BIGNUM *tmp2 = NULL, *tmp3 = NULL;
-    int ok;
+    int ok = 0;
     BN_CTX *ctx = BN_CTX_new();
+    if(!ctx) {
+        GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     BN_CTX_start(ctx);
     if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) {
         GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
-        return 0;
+        goto err;
     }
     md = hashsum2bn(dgst);
 
@@ -157,6 +188,10 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
     tmp2 = BN_CTX_get(ctx);
     tmp3 = BN_CTX_get(ctx);
     u = BN_CTX_get(ctx);
+    if(!tmp || !v || !q2 || !z1 || !z2 || !tmp2 || !tmp3 || !u) {
+        GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
 
     BN_mod(tmp, md, dsa->q, ctx);
     if (BN_is_zero(tmp)) {
@@ -172,15 +207,18 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
     BN_mod_exp(tmp2, dsa->pub_key, z2, dsa->p, ctx);
     BN_mod_mul(tmp3, tmp, tmp2, dsa->p, ctx);
     BN_mod(u, tmp3, dsa->q, ctx);
-    ok = BN_cmp(u, sig->r);
+    ok = (BN_cmp(u, sig->r) == 0);
 
-    BN_free(md);
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    if (ok != 0) {
+    if (!ok) {
         GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
     }
-    return (ok == 0);
+err:
+    if(md) BN_free(md);
+    if(ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return ok;
 }
 
 /*
@@ -190,13 +228,24 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
 int gost94_compute_public(DSA *dsa)
 {
     /* Now fill algorithm parameters with correct values */
-    BN_CTX *ctx = BN_CTX_new();
+    BN_CTX *ctx;
     if (!dsa->g) {
         GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED);
         return 0;
     }
-    /* Compute public key  y = a^x mod p */
+    ctx = BN_CTX_new();
+    if(!ctx) {
+        GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
     dsa->pub_key = BN_new();
+    if(!dsa->pub_key) {
+        GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
+        BN_CTX_free(ctx);
+        return 0;
+    }
+    /* Compute public key  y = a^x mod p */
     BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx);
     BN_CTX_free(ctx);
     return 1;
@@ -243,6 +292,10 @@ int fill_GOST94_params(DSA *dsa, int nid)
 int gost_sign_keygen(DSA *dsa)
 {
     dsa->priv_key = BN_new();
+    if(!dsa->priv_key) {
+        GOSTerr(GOST_F_GOST_SIGN_KEYGEN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
     BN_rand_range(dsa->priv_key, dsa->q);
     return gost94_compute_public(dsa);
 }
index 1005dfc..8a23763 100644 (file)
@@ -712,10 +712,12 @@ static EVP_PKEY *sureware_load_public(ENGINE *e, const char *key_id,
         /* set public big nums */
         rsatmp->e = BN_new();
         rsatmp->n = BN_new();
+        if(!rsatmp->e || !rsatmp->n)
+            goto err;
         bn_expand2(rsatmp->e, el / sizeof(BN_ULONG));
         bn_expand2(rsatmp->n, el / sizeof(BN_ULONG));
-        if (!rsatmp->e || rsatmp->e->dmax != (int)(el / sizeof(BN_ULONG)) ||
-            !rsatmp->n || rsatmp->n->dmax != (int)(el / sizeof(BN_ULONG)))
+        if (rsatmp->e->dmax != (int)(el / sizeof(BN_ULONG)) ||
+            rsatmp->n->dmax != (int)(el / sizeof(BN_ULONG)))
             goto err;
         ret = p_surewarehk_Load_Rsa_Pubkey(msg, key_id, el,
                                            (unsigned long *)rsatmp->n->d,
@@ -752,15 +754,16 @@ static EVP_PKEY *sureware_load_public(ENGINE *e, const char *key_id,
         dsatmp->p = BN_new();
         dsatmp->q = BN_new();
         dsatmp->g = BN_new();
+        if(!dsatmp->pub_key || !dsatmp->p || !dsatmp->q || !dsatmp->g)
+            goto err;
         bn_expand2(dsatmp->pub_key, el / sizeof(BN_ULONG));
         bn_expand2(dsatmp->p, el / sizeof(BN_ULONG));
         bn_expand2(dsatmp->q, 20 / sizeof(BN_ULONG));
         bn_expand2(dsatmp->g, el / sizeof(BN_ULONG));
-        if (!dsatmp->pub_key
-            || dsatmp->pub_key->dmax != (int)(el / sizeof(BN_ULONG))
-            || !dsatmp->p || dsatmp->p->dmax != (int)(el / sizeof(BN_ULONG))
-            || !dsatmp->q || dsatmp->q->dmax != 20 / sizeof(BN_ULONG)
-            || !dsatmp->g || dsatmp->g->dmax != (int)(el / sizeof(BN_ULONG)))
+        if (dsatmp->pub_key->dmax != (int)(el / sizeof(BN_ULONG))
+            || dsatmp->p->dmax != (int)(el / sizeof(BN_ULONG))
+            || dsatmp->q->dmax != 20 / sizeof(BN_ULONG)
+            || dsatmp->g->dmax != (int)(el / sizeof(BN_ULONG)))
             goto err;
 
         ret = p_surewarehk_Load_Dsa_Pubkey(msg, key_id, el,
@@ -1038,10 +1041,12 @@ static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *from, int flen,
         }
         psign->r = BN_new();
         psign->s = BN_new();
+        if(!psign->r || !psign->s)
+            goto err;
         bn_expand2(psign->r, 20 / sizeof(BN_ULONG));
         bn_expand2(psign->s, 20 / sizeof(BN_ULONG));
-        if (!psign->r || psign->r->dmax != 20 / sizeof(BN_ULONG) ||
-            !psign->s || psign->s->dmax != 20 / sizeof(BN_ULONG))
+        if (psign->r->dmax != 20 / sizeof(BN_ULONG) ||
+            psign->s->dmax != 20 / sizeof(BN_ULONG))
             goto err;
         ret = p_surewarehk_Dsa_Sign(msg, flen, from,
                                     (unsigned long *)psign->r->d,
@@ -1070,9 +1075,9 @@ static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
     char msg[64] = "ENGINE_modexp";
     if (!p_surewarehk_Mod_Exp) {
         SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP, ENGINE_R_NOT_INITIALISED);
-    } else {
+    } else if (r) {
         bn_expand2(r, m->top);
-        if (r && r->dmax == m->top) {
+        if (r->dmax == m->top) {
             /* do it */
             ret = p_surewarehk_Mod_Exp(msg,
                                        m->top * sizeof(BN_ULONG),
index c18ec03..8dd8ea3 100644 (file)
@@ -485,6 +485,12 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
         return i;
     }
 
+    if (mt >= 0 && s->s3->tmp.message_type != mt) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
+        goto f_err;
+    }
+
     p = (unsigned char *)s->init_buf->data;
     msg_len = msg_hdr->msg_len;
 
@@ -869,6 +875,20 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
     /* parse the message fragment header */
     dtls1_get_message_header(wire, &msg_hdr);
 
+    len = msg_hdr.msg_len;
+    frag_off = msg_hdr.frag_off;
+    frag_len = msg_hdr.frag_len;
+
+    /*
+     * We must have at least frag_len bytes left in the record to be read.
+     * Fragments must not span records.
+     */
+    if (frag_len > s->s3->rrec.length) {
+        al = SSL3_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH);
+        goto f_err;
+    }
+
     /*
      * if this is a future (or stale) message it gets buffered
      * (or dropped)--no further processing at this time
@@ -879,10 +899,6 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
         && !(s->d1->listen && msg_hdr.seq == 1))
         return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
 
-    len = msg_hdr.msg_len;
-    frag_off = msg_hdr.frag_off;
-    frag_len = msg_hdr.frag_len;
-
     if (frag_len && frag_len < len)
         return dtls1_reassemble_fragment(s, &msg_hdr, ok);
 
@@ -913,17 +929,16 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
     if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max)))
         goto f_err;
 
-    /* XDTLS:  ressurect this when restart is in place */
-    s->state = stn;
-
     if (frag_len > 0) {
         unsigned char *p =
             (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
 
         i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                       &p[frag_off], frag_len, 0);
+
         /*
-         * XDTLS: fix this--message fragments cannot span multiple packets
+         * This shouldn't ever fail due to NBIO because we already checked
+         * that we have enough data in the record
          */
         if (i <= 0) {
             s->rwstate = SSL_READING;
@@ -944,6 +959,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
     }
 
     *ok = 1;
+    s->state = stn;
 
     /*
      * Note that s->init_num is *not* used as current offset in
@@ -1540,7 +1556,10 @@ int dtls1_process_heartbeat(SSL *s)
         memcpy(bp, pl, payload);
         bp += payload;
         /* Random padding */
-        RAND_pseudo_bytes(bp, padding);
+        if (RAND_pseudo_bytes(bp, padding) < 0) {
+            OPENSSL_free(buffer);
+            return -1;
+        }
 
         r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
 
@@ -1574,7 +1593,7 @@ int dtls1_process_heartbeat(SSL *s)
 int dtls1_heartbeat(SSL *s)
 {
     unsigned char *buf, *p;
-    int ret;
+    int ret = -1;
     unsigned int payload = 18;  /* Sequence number + random bytes */
     unsigned int padding = 16;  /* Use minimum padding */
 
@@ -1622,10 +1641,12 @@ int dtls1_heartbeat(SSL *s)
     /* Sequence number */
     s2n(s->tlsext_hb_seq, p);
     /* 16 random bytes */
-    RAND_pseudo_bytes(p, 16);
+    if (RAND_pseudo_bytes(p, 16) < 0)
+        goto err;
     p += 16;
     /* Random padding */
-    RAND_pseudo_bytes(p, padding);
+    if (RAND_pseudo_bytes(p, padding) < 0)
+        goto err;
 
     ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
     if (ret >= 0) {
@@ -1638,6 +1659,7 @@ int dtls1_heartbeat(SSL *s)
         s->tlsext_hb_pending = 1;
     }
 
+err:
     OPENSSL_free(buf);
 
     return ret;
index 1394781..377c1e6 100644 (file)
@@ -212,6 +212,7 @@ int dtls1_connect(SSL *s)
                 (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) {
                 SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -221,10 +222,12 @@ int dtls1_connect(SSL *s)
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
@@ -233,12 +236,14 @@ int dtls1_connect(SSL *s)
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
             /* setup buffing BIO */
             if (!ssl_init_wbio_buffer(s, 0)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -417,6 +422,7 @@ int dtls1_connect(SSL *s)
              */
             if (!ssl3_check_cert_and_algorithm(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
             break;
@@ -548,6 +554,7 @@ int dtls1_connect(SSL *s)
 #endif
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -555,6 +562,7 @@ int dtls1_connect(SSL *s)
                                                           SSL3_CHANGE_CIPHER_CLIENT_WRITE))
             {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 #ifndef OPENSSL_NO_SCTP
@@ -735,6 +743,7 @@ int dtls1_connect(SSL *s)
             goto end;
             /* break; */
 
+        case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
@@ -945,6 +954,7 @@ static int dtls1_get_hello_verify(SSL *s)
 
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    s->state = SSL_ST_ERR;
     return -1;
 }
 
index 94acb15..011d7b7 100644 (file)
@@ -496,6 +496,9 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
 {
     int ret;
 
+    /* Ensure there is no state left over from a previous invocation */
+    SSL_clear(s);
+
     SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
     s->d1->listen = 1;
 
index 7b49a7d..d659ed4 100644 (file)
@@ -1065,7 +1065,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
             (s->d1->handshake_fragment[3] != 0)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
-            goto err;
+            goto f_err;
         }
 
         /*
index c4ec9fe..41c7dc5 100644 (file)
@@ -224,11 +224,13 @@ int dtls1_accept(SSL *s)
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     BUF_MEM_free(buf);
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
@@ -236,6 +238,7 @@ int dtls1_accept(SSL *s)
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -257,6 +260,7 @@ int dtls1_accept(SSL *s)
 #endif
                     if (!ssl_init_wbio_buffer(s, 1)) {
                         ret = -1;
+                        s->state = SSL_ST_ERR;
                         goto end;
                     }
 
@@ -470,7 +474,7 @@ int dtls1_accept(SSL *s)
 #ifndef OPENSSL_NO_PSK
                 || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
 #endif
-                || (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd))
+                || (alg_k & SSL_kEDH)
                 || (alg_k & SSL_kEECDH)
                 || ((alg_k & SSL_kRSA)
                     && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
@@ -665,15 +669,6 @@ int dtls1_accept(SSL *s)
 
         case SSL3_ST_SR_CERT_VRFY_A:
         case SSL3_ST_SR_CERT_VRFY_B:
-            /*
-             * This *should* be the first time we enable CCS, but be
-             * extra careful about surrounding code changes. We need
-             * to set this here because we don't know if we're
-             * expecting a CertificateVerify or not.
-             */
-            if (!s->s3->change_cipher_spec)
-                s->d1->change_cipher_spec_ok = 1;
-            /* we should decide if we expected this one */
             ret = ssl3_get_cert_verify(s);
             if (ret <= 0)
                 goto end;
@@ -690,11 +685,10 @@ int dtls1_accept(SSL *s)
         case SSL3_ST_SR_FINISHED_A:
         case SSL3_ST_SR_FINISHED_B:
             /*
-             * Enable CCS for resumed handshakes.
-             * In a full handshake, we end up here through
-             * SSL3_ST_SR_CERT_VRFY_B, so change_cipher_spec_ok was
-             * already set. Receiving a CCS clears the flag, so make
-             * sure not to re-enable it to ban duplicates.
+             * Enable CCS. Receiving a CCS clears the flag, so make
+             * sure not to re-enable it to ban duplicates. This *should* be the
+             * first time we have received one - but we check anyway to be
+             * cautious.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in d1_pkt.c, and remains set until
              * the client's Finished message is read.
@@ -744,6 +738,7 @@ int dtls1_accept(SSL *s)
             s->session->cipher = s->s3->tmp.new_cipher;
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -772,6 +767,7 @@ int dtls1_accept(SSL *s)
                                                           SSL3_CHANGE_CIPHER_SERVER_WRITE))
             {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -852,6 +848,7 @@ int dtls1_accept(SSL *s)
             goto end;
             /* break; */
 
+        case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE);
             ret = -1;
@@ -932,6 +929,7 @@ int dtls1_send_hello_verify_request(SSL *s)
                                       &(s->d1->cookie_len)) == 0) {
             SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,
                    ERR_R_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return 0;
         }
 
index 614b9a3..7a61888 100644 (file)
@@ -576,6 +576,20 @@ static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
     s->s2->padding = p;
     s->s2->mac_data = &(s->s2->wbuf[3]);
     s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]);
+
+    /*
+     * It would be clearer to write this as follows:
+     *     if (mac_size + len + p > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER)
+     * However |len| is user input that could in theory be very large. We
+     * know |mac_size| and |p| are small, so to avoid any possibility of
+     * overflow we write it like this.
+     *
+     * In theory this should never fail because the logic above should have
+     * modified |len| if it is too big. But we are being cautious.
+     */
+    if (len > (SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - (mac_size + p))) {
+        return -1;
+    }
     /* we copy the data into s->s2->wbuf */
     memcpy(s->s2->wact_data, buf, len);
     if (p)
index 19bb48c..4289272 100644 (file)
 
 #include "ssl_locl.h"
 #ifndef OPENSSL_NO_SSL2
+#include "../crypto/constant_time_locl.h"
 # include <stdio.h>
 # include <openssl/bio.h>
 # include <openssl/rand.h>
@@ -372,12 +373,15 @@ int ssl2_accept(SSL *s)
 static int get_client_master_key(SSL *s)
 {
     int is_export, i, n, keya;
-    unsigned int ek;
+    unsigned int num_encrypted_key_bytes, key_length;
     unsigned long len;
     unsigned char *p;
     const SSL_CIPHER *cp;
     const EVP_CIPHER *c;
     const EVP_MD *md;
+    unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+    unsigned char decrypt_good;
+    size_t j;
 
     p = (unsigned char *)s->init_buf->data;
     if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) {
@@ -465,12 +469,6 @@ static int get_client_master_key(SSL *s)
         return (0);
     }
 
-    if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) {
-        is_export = 1;
-        ek = 8;
-    } else
-        ek = 5;
-
     /*
      * The format of the CLIENT-MASTER-KEY message is
      * 1 byte message type
@@ -484,12 +482,27 @@ static int get_client_master_key(SSL *s)
      *
      * 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).
+     * this portion is in |num_encrypted_key_bytes|. 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))) {
+    key_length = (unsigned int)EVP_CIPHER_key_length(c);
+    if (key_length > SSL_MAX_MASTER_KEY_LENGTH) {
+        ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
+        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) {
+        is_export = 1;
+        num_encrypted_key_bytes = 8;
+    } else if (is_export) {
+        num_encrypted_key_bytes = 5;
+    } else {
+        num_encrypted_key_bytes = key_length;
+    }
+
+    if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) {
         ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
         return -1;
@@ -499,64 +512,49 @@ static int get_client_master_key(SSL *s)
      * 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))) {
+    if (s->s2->tmp.enc < num_encrypted_key_bytes) {
         ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
         return -1;
     }
 
+    /*
+     * We must not leak whether a decryption failure occurs because of
+     * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
+     * section 7.4.7.1). The code follows that advice of the TLS RFC and
+     * generates a random premaster secret for the case that the decrypt
+     * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
+     */
+
+    /*
+     * should be RAND_bytes, but we cannot work around a failure.
+     */
+    if (RAND_pseudo_bytes(rand_premaster_secret,
+                          (int)num_encrypted_key_bytes) <= 0)
+        return 0;
+
     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
+    ERR_clear_error();
     /*
      * 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 != (int)ek))) {
-        ERR_clear_error();
-        if (is_export)
-            i = ek;
-        else
-            i = EVP_CIPHER_key_length(c);
-        if (RAND_pseudo_bytes(&p[s->s2->tmp.clear], i) <= 0)
-            return 0;
-    }
-# else
-    if (i < 0) {
-        error = 1;
-        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_BAD_RSA_DECRYPT);
-    }
-    /* incorrect number of key bytes for non export cipher */
-    else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
-             || (is_export && ((i != ek) || (s->s2->tmp.clear + i !=
-                                             EVP_CIPHER_key_length(c))))) {
-        error = 1;
-        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_WRONG_NUMBER_OF_KEY_BITS);
-    }
-    if (error) {
-        ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
-        return (-1);
+    decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes);
+    for (j = 0; j < num_encrypted_key_bytes; j++) {
+        p[s->s2->tmp.clear + j] =
+                constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j],
+                                       rand_premaster_secret[j]);
     }
-# endif
 
-    if (is_export)
-        i = EVP_CIPHER_key_length(c);
+    s->session->master_key_length = (int)key_length;
+    memcpy(s->session->master_key, p, key_length);
+    OPENSSL_cleanse(p, key_length);
 
-    if (i > SSL_MAX_MASTER_KEY_LENGTH) {
-        ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
-        SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
-        return -1;
-    }
-    s->session->master_key_length = i;
-    memcpy(s->session->master_key, p, (unsigned int)i);
-    return (1);
+    return 1;
 }
 
 static int get_client_hello(SSL *s)
index 77374f4..107b460 100644 (file)
@@ -169,7 +169,7 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
         i = s->method->ssl3_enc->final_finish_mac(s,
                                                   sender, slen,
                                                   s->s3->tmp.finish_md);
-        if (i == 0)
+        if (i <= 0)
             return 0;
         s->s3->tmp.finish_md_len = i;
         memcpy(p, s->s3->tmp.finish_md, i);
index 598d27e..2fb71f2 100644 (file)
@@ -149,7 +149,7 @@ int tls1_cbc_remove_padding(const SSL *s,
      */
     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) &&
+        if ((CRYPTO_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;
         }
@@ -639,12 +639,22 @@ void ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
 
     if (k > 0) {
         if (is_sslv3) {
+            unsigned overhang;
+
             /*
              * 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).
+             * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no
+             * ciphersuites in SSLv3 that are not SHA1 or MD5 based and
+             * therefore we can be confident that the header_length will be
+             * greater than |md_block_size|. However we add a sanity check just
+             * in case
              */
-            unsigned overhang = header_length - md_block_size;
+            if (header_length <= md_block_size) {
+                /* Should never happen */
+                return;
+            }
+            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);
index 0e5acec..0879a0f 100644 (file)
 #endif
 
 static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
+#ifndef OPENSSL_NO_TLSEXT
+static int ssl3_check_finished(SSL *s);
+#endif
 
 #ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_client_method(int ver)
@@ -235,6 +238,7 @@ int ssl3_connect(SSL *s)
 
             if ((s->version & 0xff00) != 0x0300) {
                 SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR);
+                s->state = SSL_ST_ERR;
                 ret = -1;
                 goto end;
             }
@@ -245,10 +249,12 @@ int ssl3_connect(SSL *s)
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
@@ -263,6 +269,7 @@ int ssl3_connect(SSL *s)
             /* setup buffing BIO */
             if (!ssl_init_wbio_buffer(s, 0)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -317,12 +324,24 @@ int ssl3_connect(SSL *s)
 
         case SSL3_ST_CR_CERT_A:
         case SSL3_ST_CR_CERT_B:
+#ifndef OPENSSL_NO_TLSEXT
+            /* Noop (ret = 0) for everything but EAP-FAST. */
+            ret = ssl3_check_finished(s);
+            if (ret < 0)
+                goto end;
+            if (ret == 1) {
+                s->hit = 1;
+                s->state = SSL3_ST_CR_FINISHED_A;
+                s->init_num = 0;
+                break;
+            }
+#endif
             /* Check if it is anon DH/ECDH, SRP auth */
             /* or PSK */
             if (!
                 (s->s3->tmp.
                  new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
-&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
+                    && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 ret = ssl3_get_server_certificate(s);
                 if (ret <= 0)
                     goto end;
@@ -358,6 +377,7 @@ int ssl3_connect(SSL *s)
              */
             if (!ssl3_check_cert_and_algorithm(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
             break;
@@ -381,6 +401,7 @@ int ssl3_connect(SSL *s)
                 if ((ret = SRP_Calc_A_param(s)) <= 0) {
                     SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC);
                     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
             }
@@ -472,6 +493,7 @@ int ssl3_connect(SSL *s)
 #endif
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -479,6 +501,7 @@ int ssl3_connect(SSL *s)
                                                           SSL3_CHANGE_CIPHER_CLIENT_WRITE))
             {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -553,7 +576,8 @@ int ssl3_connect(SSL *s)
 
         case SSL3_ST_CR_FINISHED_A:
         case SSL3_ST_CR_FINISHED_B:
-            s->s3->flags |= SSL3_FLAGS_CCS_OK;
+            if (!s->s3->change_cipher_spec)
+                s->s3->flags |= SSL3_FLAGS_CCS_OK;
             ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
                                     SSL3_ST_CR_FINISHED_B);
             if (ret <= 0)
@@ -612,6 +636,7 @@ int ssl3_connect(SSL *s)
             goto end;
             /* break; */
 
+        case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
@@ -658,9 +683,17 @@ int ssl3_client_hello(SSL *s)
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
         SSL_SESSION *sess = s->session;
-        if ((sess == NULL) ||
-            (sess->ssl_version != s->version) ||
-            !sess->session_id_length || (sess->not_resumable)) {
+        if ((sess == NULL) || (sess->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+            !sess->session_id_length ||
+#else
+            /*
+             * In the case of EAP-FAST, we can have a pre-shared
+             * "ticket" without a session ID.
+             */
+            (!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
+            (sess->not_resumable)) {
             if (!ssl_get_new_session(s, 0))
                 goto err;
         }
@@ -798,6 +831,7 @@ int ssl3_client_hello(SSL *s)
     /* SSL3_ST_CW_CLNT_HELLO_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -867,10 +901,19 @@ int ssl3_get_server_hello(SSL *s)
     }
 #ifndef OPENSSL_NO_TLSEXT
     /*
-     * check if we want to resume the session based on external pre-shared
-     * secret
+     * Check if we can resume the session based on external pre-shared secret.
+     * EAP-FAST (RFC 4851) supports two types of session resumption.
+     * Resumption based on server-side state works with session IDs.
+     * Resumption based on pre-shared Protected Access Credentials (PACs)
+     * works by overriding the SessionTicket extension at the application
+     * layer, and does not send a session ID. (We do not know whether EAP-FAST
+     * servers would honour the session ID.) Therefore, the session ID alone
+     * is not a reliable indicator of session resumption, so we first check if
+     * we can resume, and later peek at the next handshake message to see if the
+     * server wants to resume.
      */
-    if (s->version >= TLS1_VERSION && s->tls_session_secret_cb) {
+    if (s->version >= TLS1_VERSION && s->tls_session_secret_cb &&
+        s->session->tlsext_tick) {
         SSL_CIPHER *pref_cipher = NULL;
         s->session->master_key_length = sizeof(s->session->master_key);
         if (s->tls_session_secret_cb(s, s->session->master_key,
@@ -879,12 +922,15 @@ int ssl3_get_server_hello(SSL *s)
                                      s->tls_session_secret_cb_arg)) {
             s->session->cipher = pref_cipher ?
                 pref_cipher : ssl_get_cipher_by_char(s, p + j);
-            s->hit = 1;
+        } else {
+            SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+            al = SSL_AD_INTERNAL_ERROR;
+            goto f_err;
         }
     }
 #endif                          /* OPENSSL_NO_TLSEXT */
 
-    if (!s->hit && j != 0 && j == s->session->session_id_length
+    if (j != 0 && j == s->session->session_id_length
         && memcmp(p, s->session->session_id, j) == 0) {
         if (s->sid_ctx_length != s->session->sid_ctx_length
             || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
@@ -895,12 +941,13 @@ int ssl3_get_server_hello(SSL *s)
             goto f_err;
         }
         s->hit = 1;
-    }
-    /* a miss or crap from the other end */
-    if (!s->hit) {
+    } else {
         /*
-         * If we were trying for session-id reuse, make a new SSL_SESSION so
-         * we don't stuff up other people
+         * If we were trying for session-id reuse but the server
+         * didn't echo the ID, make a new SSL_SESSION.
+         * In the case of EAP-FAST and PAC, we do not send a session ID,
+         * so the PAC-based session secret is always preserved. It'll be
+         * overwritten if the server refuses resumption.
          */
         if (s->session->session_id_length > 0) {
             if (!ssl_get_new_session(s, 0)) {
@@ -1045,6 +1092,7 @@ int ssl3_get_server_hello(SSL *s)
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -1223,8 +1271,10 @@ int ssl3_get_server_certificate(SSL *s)
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    }
  err:
+        s->state = SSL_ST_ERR;
+    }
+
     EVP_PKEY_free(pkey);
     X509_free(x);
     sk_X509_pop_free(sk, X509_free);
@@ -1546,6 +1596,13 @@ int ssl3_get_key_exchange(SSL *s)
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto err;
         }
+
+        if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
+            goto f_err;
+        }
+
         s->session->sess_cert->peer_rsa_tmp = rsa;
         rsa = NULL;
     }
@@ -1894,6 +1951,7 @@ int ssl3_get_key_exchange(SSL *s)
         EC_KEY_free(ecdh);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2050,7 +2108,10 @@ int ssl3_get_certificate_request(SSL *s)
     ca_sk = NULL;
 
     ret = 1;
+    goto done;
  err:
+    s->state = SSL_ST_ERR;
+ done:
     if (ca_sk != NULL)
         sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
     return (ret);
@@ -2085,6 +2146,38 @@ int ssl3_get_new_session_ticket(SSL *s)
     }
 
     p = d = (unsigned char *)s->init_msg;
+
+    if (s->session->session_id_length > 0) {
+        int i = s->session_ctx->session_cache_mode;
+        SSL_SESSION *new_sess;
+        /*
+         * We reused an existing session, so we need to replace it with a new
+         * one
+         */
+        if (i & SSL_SESS_CACHE_CLIENT) {
+            /*
+             * Remove the old session from the cache
+             */
+            if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) {
+                if (s->session_ctx->remove_session_cb != NULL)
+                    s->session_ctx->remove_session_cb(s->session_ctx,
+                                                      s->session);
+            } else {
+                /* We carry on if this fails */
+                SSL_CTX_remove_session(s->session_ctx, s->session);
+            }
+        }
+
+        if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+            goto f_err;
+        }
+
+        SSL_SESSION_free(s->session);
+        s->session = new_sess;
+    }
+
     n2l(p, s->session->tlsext_tick_lifetime_hint);
     n2s(p, ticklen);
     /* ticket_lifetime_hint + ticket_length + ticket */
@@ -2127,6 +2220,7 @@ int ssl3_get_new_session_ticket(SSL *s)
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2187,6 +2281,7 @@ int ssl3_get_cert_status(SSL *s)
     return 1;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 #endif
@@ -2208,6 +2303,7 @@ int ssl3_get_server_done(SSL *s)
         /* should contain no data */
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH);
+        s->state = SSL_ST_ERR;
         return -1;
     }
     ret = 1;
@@ -2506,8 +2602,6 @@ int ssl3_send_client_key_exchange(SSL *s)
             n += 2;
 
             DH_free(dh_clnt);
-
-            /* perhaps clean things up a bit EAY EAY EAY EAY */
         }
 #endif
 
@@ -2729,7 +2823,10 @@ int ssl3_send_client_key_exchange(SSL *s)
 
             EVP_PKEY_encrypt_init(pkey_ctx);
             /* Generate session key */
-            RAND_bytes(premaster_secret, 32);
+            if (RAND_bytes(premaster_secret, 32) <= 0) {
+                EVP_PKEY_CTX_free(pkey_ctx);
+                goto err;
+            }
             /*
              * If we have client certificate, use its secret as peer key
              */
@@ -2948,6 +3045,7 @@ int ssl3_send_client_key_exchange(SSL *s)
         EC_KEY_free(clnt_ecdh);
     EVP_PKEY_free(srvr_pub_pkey);
 #endif
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -3081,6 +3179,7 @@ int ssl3_send_client_verify(SSL *s)
  err:
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_CTX_free(pctx);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -3149,6 +3248,7 @@ int ssl3_send_client_certificate(SSL *s)
         if (!l) {
             SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return 0;
         }
         s->init_num = (int)l;
@@ -3165,6 +3265,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
     int i, idx;
     long alg_k, alg_a;
     EVP_PKEY *pkey = NULL;
+    int pkey_bits;
     SESS_CERT *sc;
 #ifndef OPENSSL_NO_RSA
     RSA *rsa;
@@ -3172,6 +3273,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
 #ifndef OPENSSL_NO_DH
     DH *dh;
 #endif
+    int al = SSL_AD_HANDSHAKE_FAILURE;
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
     alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -3207,6 +3309,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
     }
 #endif
     pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509);
+    pkey_bits = EVP_PKEY_bits(pkey);
     i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey);
     EVP_PKEY_free(pkey);
 
@@ -3224,38 +3327,71 @@ int ssl3_check_cert_and_algorithm(SSL *s)
     }
 #endif
 #ifndef OPENSSL_NO_RSA
-    if ((alg_k & SSL_kRSA) &&
-        !(has_bits(i, EVP_PK_RSA | EVP_PKT_ENC) || (rsa != NULL))) {
-        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
-               SSL_R_MISSING_RSA_ENCRYPTING_CERT);
-        goto f_err;
+    if (alg_k & SSL_kRSA) {
+        if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+            !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+            SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+                   SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+            goto f_err;
+        } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
+            if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+                if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+                    SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+                           SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+                    goto f_err;
+                }
+                if (rsa != NULL) {
+                    /* server key exchange is not allowed. */
+                    al = SSL_AD_INTERNAL_ERROR;
+                    SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
+                    goto f_err;
+                }
+            }
+        }
     }
 #endif
 #ifndef OPENSSL_NO_DH
-    if ((alg_k & SSL_kEDH) &&
-        !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || (dh != NULL))) {
-        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_DH_KEY);
+    if ((alg_k & SSL_kEDH) && dh == NULL) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
         goto f_err;
-    } else if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
+    }
+    if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_DH_RSA_CERT);
         goto f_err;
     }
 # ifndef OPENSSL_NO_DSA
-    else if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) {
+    if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_DH_DSA_CERT);
         goto f_err;
     }
 # endif
-#endif
 
-    if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i, EVP_PKT_EXP)) {
+    /* Check DHE only: static DH not implemented. */
+    if (alg_k & SSL_kEDH) {
+        int dh_size = BN_num_bits(dh->p);
+        if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768)
+            || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) {
+            SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL);
+            goto f_err;
+        }
+    }
+#endif  /* !OPENSSL_NO_DH */
+
+    if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
+        pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
 #ifndef OPENSSL_NO_RSA
         if (alg_k & SSL_kRSA) {
-            if (rsa == NULL
-                || RSA_size(rsa) * 8 >
+            if (rsa == NULL) {
+                SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+                       SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
+                goto f_err;
+            } else if (BN_num_bits(rsa->n) >
                 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+                /* We have a temporary RSA key but it's too large. */
+                al = SSL_AD_EXPORT_RESTRICTION;
                 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                        SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
                 goto f_err;
@@ -3263,14 +3399,21 @@ int ssl3_check_cert_and_algorithm(SSL *s)
         } else
 #endif
 #ifndef OPENSSL_NO_DH
-        if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) {
-            if (dh == NULL
-                || DH_size(dh) * 8 >
+        if (alg_k & SSL_kEDH) {
+            if (BN_num_bits(dh->p) >
                 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
+                /* We have a temporary DH key but it's too large. */
+                al = SSL_AD_EXPORT_RESTRICTION;
                 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                        SSL_R_MISSING_EXPORT_TMP_DH_KEY);
                 goto f_err;
             }
+        } else if (alg_k & (SSL_kDHr | SSL_kDHd)) {
+            /* The cert should have had an export DH key. */
+            al = SSL_AD_EXPORT_RESTRICTION;
+            SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+                   SSL_R_MISSING_EXPORT_TMP_DH_KEY);
+                goto f_err;
         } else
 #endif
         {
@@ -3281,12 +3424,62 @@ int ssl3_check_cert_and_algorithm(SSL *s)
     }
     return (1);
  f_err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     return (0);
 }
 
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#ifndef OPENSSL_NO_TLSEXT
+/*
+ * Normally, we can tell if the server is resuming the session from
+ * the session ID. EAP-FAST (RFC 4851), however, relies on the next server
+ * message after the ServerHello to determine if the server is resuming.
+ * Therefore, we allow EAP-FAST to peek ahead.
+ * ssl3_check_finished returns 1 if we are resuming from an external
+ * pre-shared secret, we have a "ticket" and the next server handshake message
+ * is Finished; and 0 otherwise. It returns -1 upon an error.
+ */
+static int ssl3_check_finished(SSL *s)
+{
+    int ok = 0;
+
+    if (s->version < TLS1_VERSION || !s->tls_session_secret_cb ||
+        !s->session->tlsext_tick)
+        return 0;
+
+    /* Need to permit this temporarily, in case the next message is Finished. */
+    s->s3->flags |= SSL3_FLAGS_CCS_OK;
+    /*
+     * This function is called when we might get a Certificate message instead,
+     * so permit appropriate message length.
+     * We ignore the return value as we're only interested in the message type
+     * and not its length.
+     */
+    s->method->ssl_get_message(s,
+                               SSL3_ST_CR_CERT_A,
+                               SSL3_ST_CR_CERT_B,
+                               -1, s->max_cert_list, &ok);
+    s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
+    if (!ok)
+        return -1;
+
+    s->s3->tmp.reuse_message = 1;
+
+    if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
+        return 1;
+
+    /* If we're not done, then the CCS arrived early and we should bail. */
+    if (s->s3->change_cipher_spec) {
+        SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY);
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+        return -1;
+    }
+
+    return 0;
+}
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
 int ssl3_send_next_proto(SSL *s)
 {
     unsigned int len, padding_len;
@@ -3309,8 +3502,8 @@ int ssl3_send_next_proto(SSL *s)
 
     return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
 }
-#endif                          /* !OPENSSL_NO_TLSEXT &&
-                                 * !OPENSSL_NO_NEXTPROTONEG */
+#endif                          /* !OPENSSL_NO_NEXTPROTONEG */
+#endif                          /* !OPENSSL_NO_TLSEXT */
 
 int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
 {
index 7c9f20c..25cf929 100644 (file)
@@ -347,11 +347,22 @@ static int ssl3_get_record(SSL *s)
             if (version != s->version) {
                 SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
                 if ((s->version & 0xFF00) == (version & 0xFF00)
-                    && !s->enc_write_ctx && !s->write_hash)
+                    && !s->enc_write_ctx && !s->write_hash) {
+                    if (rr->type == SSL3_RT_ALERT) {
+                        /*
+                         * The record is using an incorrect version number, but
+                         * what we've got appears to be an alert. We haven't
+                         * read the body yet to check whether its a fatal or
+                         * not - but chances are it is. We probably shouldn't
+                         * send a fatal alert back. We'll just end.
+                         */
+                         goto err;
+                    }
                     /*
                      * Send back error using their minor version number :-)
                      */
                     s->version = (unsigned short)version;
+                }
                 al = SSL_AD_PROTOCOL_VERSION;
                 goto f_err;
             }
index b8f91bc..9aa3292 100644 (file)
@@ -266,6 +266,7 @@ int ssl3_accept(SSL *s)
 
             if ((s->version >> 8) != 3) {
                 SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+                s->state = SSL_ST_ERR;
                 return -1;
             }
             s->type = SSL_ST_ACCEPT;
@@ -273,11 +274,13 @@ int ssl3_accept(SSL *s)
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     BUF_MEM_free(buf);
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
@@ -285,6 +288,7 @@ int ssl3_accept(SSL *s)
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -303,6 +307,7 @@ int ssl3_accept(SSL *s)
                  */
                 if (!ssl_init_wbio_buffer(s, 1)) {
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
 
@@ -320,6 +325,7 @@ int ssl3_accept(SSL *s)
                        SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             } else {
                 /*
@@ -379,6 +385,7 @@ int ssl3_accept(SSL *s)
                         SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
                     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
                     ret = -1;
+                    s->state = SSL_ST_ERR;
                     goto end;
                 }
             }
@@ -529,9 +536,12 @@ int ssl3_accept(SSL *s)
                 skip = 1;
                 s->s3->tmp.cert_request = 0;
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
-                if (s->s3->handshake_buffer)
-                    if (!ssl3_digest_cached_records(s))
+                if (s->s3->handshake_buffer) {
+                    if (!ssl3_digest_cached_records(s)) {
+                        s->state = SSL_ST_ERR;
                         return -1;
+                    }
+                }
             } else {
                 s->s3->tmp.cert_request = 1;
                 ret = ssl3_send_certificate_request(s);
@@ -629,11 +639,14 @@ int ssl3_accept(SSL *s)
                  */
                 if (!s->s3->handshake_buffer) {
                     SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+                    s->state = SSL_ST_ERR;
                     return -1;
                 }
                 s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
-                if (!ssl3_digest_cached_records(s))
+                if (!ssl3_digest_cached_records(s)) {
+                    s->state = SSL_ST_ERR;
                     return -1;
+                }
             } else {
                 int offset = 0;
                 int dgst_num;
@@ -647,9 +660,12 @@ int ssl3_accept(SSL *s)
                  * CertificateVerify should be generalized. But it is next
                  * step
                  */
-                if (s->s3->handshake_buffer)
-                    if (!ssl3_digest_cached_records(s))
+                if (s->s3->handshake_buffer) {
+                    if (!ssl3_digest_cached_records(s)) {
+                        s->state = SSL_ST_ERR;
                         return -1;
+                    }
+                }
                 for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
                     if (s->s3->handshake_dgst[dgst_num]) {
                         int dgst_size;
@@ -665,6 +681,7 @@ int ssl3_accept(SSL *s)
                         dgst_size =
                             EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
                         if (dgst_size < 0) {
+                            s->state = SSL_ST_ERR;
                             ret = -1;
                             goto end;
                         }
@@ -675,15 +692,6 @@ int ssl3_accept(SSL *s)
 
         case SSL3_ST_SR_CERT_VRFY_A:
         case SSL3_ST_SR_CERT_VRFY_B:
-            /*
-             * This *should* be the first time we enable CCS, but be
-             * extra careful about surrounding code changes. We need
-             * to set this here because we don't know if we're
-             * expecting a CertificateVerify or not.
-             */
-            if (!s->s3->change_cipher_spec)
-                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;
@@ -703,11 +711,10 @@ int ssl3_accept(SSL *s)
         case SSL3_ST_SR_NEXT_PROTO_A:
         case SSL3_ST_SR_NEXT_PROTO_B:
             /*
-             * Enable CCS for resumed handshakes with NPN.
-             * In a full handshake with NPN, we end up here through
-             * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
-             * already set. Receiving a CCS clears the flag, so make
-             * sure not to re-enable it to ban duplicates.
+             * Enable CCS for NPN. Receiving a CCS clears the flag, so make
+             * sure not to re-enable it to ban duplicates. This *should* be the
+             * first time we have received one - but we check anyway to be
+             * cautious.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
              * the client's Finished message is read.
@@ -726,10 +733,8 @@ int ssl3_accept(SSL *s)
         case SSL3_ST_SR_FINISHED_A:
         case SSL3_ST_SR_FINISHED_B:
             /*
-             * Enable CCS for resumed handshakes without NPN.
-             * In a full handshake, we end up here through
-             * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
-             * already set. Receiving a CCS clears the flag, so make
+             * Enable CCS for handshakes without NPN. In NPN the CCS flag has
+             * already been set. Receiving a CCS clears the flag, so make
              * sure not to re-enable it to ban duplicates.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
@@ -779,6 +784,7 @@ int ssl3_accept(SSL *s)
             s->session->cipher = s->s3->tmp.new_cipher;
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -795,6 +801,7 @@ int ssl3_accept(SSL *s)
                                                           SSL3_CHANGE_CIPHER_SERVER_WRITE))
             {
                 ret = -1;
+                s->state = SSL_ST_ERR;
                 goto end;
             }
 
@@ -857,6 +864,7 @@ int ssl3_accept(SSL *s)
             goto end;
             /* break; */
 
+        case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
             ret = -1;
@@ -991,6 +999,16 @@ int ssl3_get_client_hello(SSL *s)
     s->first_packet = 0;
     d = p = (unsigned char *)s->init_msg;
 
+    /*
+     * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
+     * for session id length
+     */
+    if (n < 2 + SSL3_RANDOM_SIZE + 1) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
+
     /*
      * use version from inside client hello, not from record header (may
      * differ: see RFC 2246, Appendix E, second paragraph)
@@ -1022,6 +1040,12 @@ int ssl3_get_client_hello(SSL *s)
         unsigned int session_length, cookie_length;
 
         session_length = *(p + SSL3_RANDOM_SIZE);
+
+        if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
         cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
 
         if (cookie_length == 0)
@@ -1035,6 +1059,12 @@ int ssl3_get_client_hello(SSL *s)
     /* get the session-id */
     j = *(p++);
 
+    if (p + j > d + n) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
+
     s->hit = 0;
     /*
      * Versions before 0.9.7 always allow clients to resume sessions in
@@ -1079,8 +1109,19 @@ int ssl3_get_client_hello(SSL *s)
 
     if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
         /* cookie stuff */
+        if (p + 1 > d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
         cookie_len = *(p++);
 
+        if (p + cookie_len > d + n) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+
         /*
          * The ClientHello may contain a cookie even if the
          * HelloVerify message has not been sent--make sure that it
@@ -1121,27 +1162,33 @@ int ssl3_get_client_hello(SSL *s)
         p += cookie_len;
     }
 
+    if (p + 2 > d + n) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+        goto f_err;
+    }
     n2s(p, i);
-    if ((i == 0) && (j != 0)) {
-        /* we need a cipher if we are not resuming a session */
+
+    if (i == 0) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
         goto f_err;
     }
-    if ((p + i) >= (d + n)) {
+
+    /* i bytes of cipher data + 1 byte for compression length later */
+    if ((p + i + 1) > (d + n)) {
         /* not enough data */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
-    if ((i > 0) && (ssl_bytes_to_cipher_list(s, p, i, &(ciphers))
-                    == NULL)) {
+    if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) {
         goto err;
     }
     p += i;
 
     /* If it is a hit, check that the cipher is in the list */
-    if ((s->hit) && (i > 0)) {
+    if (s->hit) {
         j = 0;
         id = s->session->cipher->id;
 
@@ -1377,8 +1424,8 @@ int ssl3_get_client_hello(SSL *s)
             sk_SSL_CIPHER_free(s->session->ciphers);
         s->session->ciphers = ciphers;
         if (ciphers == NULL) {
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_PASSED);
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto f_err;
         }
         ciphers = NULL;
@@ -1450,8 +1497,10 @@ int ssl3_get_client_hello(SSL *s)
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    }
  err:
+        s->state = SSL_ST_ERR;
+    }
+
     if (ciphers != NULL)
         sk_SSL_CIPHER_free(ciphers);
     return (ret);
@@ -1468,8 +1517,10 @@ int ssl3_send_server_hello(SSL *s)
         buf = (unsigned char *)s->init_buf->data;
 #ifdef OPENSSL_NO_TLSEXT
         p = s->s3->server_random;
-        if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
+        if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) {
+            s->state = SSL_ST_ERR;
             return -1;
+        }
 #endif
         /* Do the message type and length last */
         d = p = &(buf[4]);
@@ -1504,6 +1555,7 @@ int ssl3_send_server_hello(SSL *s)
         sl = s->session->session_id_length;
         if (sl > (int)sizeof(s->session->session_id)) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return -1;
         }
         *(p++) = sl;
@@ -1526,6 +1578,7 @@ int ssl3_send_server_hello(SSL *s)
 #ifndef OPENSSL_NO_TLSEXT
         if (ssl_prepare_serverhello_tlsext(s) <= 0) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
+            s->state = SSL_ST_ERR;
             return -1;
         }
         if ((p =
@@ -1533,6 +1586,7 @@ int ssl3_send_server_hello(SSL *s)
                                         buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
             NULL) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return -1;
         }
 #endif
@@ -2016,6 +2070,7 @@ int ssl3_send_server_key_exchange(SSL *s)
     BN_CTX_free(bn_ctx);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2113,6 +2168,7 @@ int ssl3_send_certificate_request(SSL *s)
     /* SSL3_ST_SW_CERT_REQ_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2367,6 +2423,7 @@ int ssl3_get_client_key_exchange(SSL *s)
         int padl, outl;
         krb5_timestamp authtime = 0;
         krb5_ticket_times ttimes;
+        int kerr = 0;
 
         EVP_CIPHER_CTX_init(&ciph_ctx);
 
@@ -2470,23 +2527,27 @@ int ssl3_get_client_key_exchange(SSL *s)
         {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
-            goto err;
+            kerr = 1;
+            goto kclean;
         }
         if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
+            kerr = 1;
+            goto kclean;
         }
         if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
-            goto err;
+            kerr = 1;
+            goto kclean;
         }
         outl += padl;
         if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
+            kerr = 1;
+            goto kclean;
         }
         if (!((pms[0] == (s->client_version >> 8))
               && (pms[1] == (s->client_version & 0xff)))) {
@@ -2503,7 +2564,8 @@ int ssl3_get_client_key_exchange(SSL *s)
             if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_AD_DECODE_ERROR);
-                goto err;
+                kerr = 1;
+                goto kclean;
             }
         }
 
@@ -2529,6 +2591,11 @@ int ssl3_get_client_key_exchange(SSL *s)
          *  kssl_ctx = kssl_ctx_free(kssl_ctx);
          *  if (s->kssl_ctx)  s->kssl_ctx = NULL;
          */
+
+ kclean:
+        OPENSSL_cleanse(pms, sizeof(pms));
+        if (kerr)
+            goto err;
     } else
 #endif                          /* OPENSSL_NO_KRB5 */
 
@@ -2847,6 +2914,7 @@ int ssl3_get_client_key_exchange(SSL *s)
                                                         s->
                                                         session->master_key,
                                                         premaster_secret, 32);
+        OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret));
         /* Check if pubkey from client certificate was used */
         if (EVP_PKEY_CTX_ctrl
             (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
@@ -2879,6 +2947,7 @@ int ssl3_get_client_key_exchange(SSL *s)
         EC_KEY_free(srvr_ecdh);
     BN_CTX_free(bn_ctx);
 #endif
+    s->state = SSL_ST_ERR;
     return (-1);
 }
 
@@ -2894,39 +2963,31 @@ int ssl3_get_cert_verify(SSL *s)
     EVP_MD_CTX mctx;
     EVP_MD_CTX_init(&mctx);
 
+    /*
+     * We should only process a CertificateVerify message if we have received
+     * a Certificate from the client. If so then |s->session->peer| will be non
+     * NULL. In some instances a CertificateVerify message is not required even
+     * if the peer has sent a Certificate (e.g. such as in the case of static
+     * DH). In that case the ClientKeyExchange processing will skip the
+     * CertificateVerify state so we should not arrive here.
+     */
+    if (s->session->peer == NULL) {
+        ret = 1;
+        goto end;
+    }
+
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CERT_VRFY_A,
                                    SSL3_ST_SR_CERT_VRFY_B,
-                                   -1, SSL3_RT_MAX_PLAIN_LENGTH, &ok);
+                                   SSL3_MT_CERTIFICATE_VERIFY,
+                                   SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 
     if (!ok)
         return ((int)n);
 
-    if (s->session->peer != NULL) {
-        peer = s->session->peer;
-        pkey = X509_get_pubkey(peer);
-        type = X509_certificate_type(peer, pkey);
-    } else {
-        peer = NULL;
-        pkey = NULL;
-    }
-
-    if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) {
-        s->s3->tmp.reuse_message = 1;
-        if (peer != NULL) {
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_MISSING_VERIFY_MESSAGE);
-            goto f_err;
-        }
-        ret = 1;
-        goto end;
-    }
-
-    if (peer == NULL) {
-        SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_NO_CLIENT_CERT_RECEIVED);
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        goto f_err;
-    }
+    peer = s->session->peer;
+    pkey = X509_get_pubkey(peer);
+    type = X509_certificate_type(peer, pkey);
 
     if (!(type & EVP_PKT_SIGN)) {
         SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
@@ -2935,12 +2996,6 @@ int ssl3_get_cert_verify(SSL *s)
         goto f_err;
     }
 
-    if (s->s3->change_cipher_spec) {
-        SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_CCS_RECEIVED_EARLY);
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        goto f_err;
-    }
-
     /* we now have a signature that we need to verify */
     p = (unsigned char *)s->init_msg;
     /* Check for broken implementations of GOST ciphersuites */
@@ -3093,6 +3148,7 @@ int ssl3_get_cert_verify(SSL *s)
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        s->state = SSL_ST_ERR;
     }
  end:
     if (s->s3->handshake_buffer) {
@@ -3251,8 +3307,10 @@ int ssl3_get_client_certificate(SSL *s)
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    }
  err:
+        s->state = SSL_ST_ERR;
+    }
+
     if (x != NULL)
         X509_free(x);
     if (sk != NULL)
@@ -3273,6 +3331,7 @@ int ssl3_send_server_certificate(SSL *s)
                 (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
                        ERR_R_INTERNAL_ERROR);
+                s->state = SSL_ST_ERR;
                 return (0);
             }
         }
@@ -3280,6 +3339,7 @@ int ssl3_send_server_certificate(SSL *s)
         l = ssl3_output_cert_chain(s, x);
         if (!l) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
             return (0);
         }
         s->state = SSL3_ST_SW_CERT_B;
@@ -3315,11 +3375,15 @@ int ssl3_send_newsession_ticket(SSL *s)
          * Some length values are 16 bits, so forget it if session is too
          * long
          */
-        if (slen_full == 0 || slen_full > 0xFF00)
+        if (slen_full == 0 || slen_full > 0xFF00) {
+            s->state = SSL_ST_ERR;
             return -1;
+        }
         senc = OPENSSL_malloc(slen_full);
-        if (!senc)
+        if (!senc) {
+            s->state = SSL_ST_ERR;
             return -1;
+        }
 
         EVP_CIPHER_CTX_init(&ctx);
         HMAC_CTX_init(&hctx);
@@ -3442,6 +3506,7 @@ int ssl3_send_newsession_ticket(SSL *s)
         OPENSSL_free(senc);
     EVP_CIPHER_CTX_cleanup(&ctx);
     HMAC_CTX_cleanup(&hctx);
+    s->state = SSL_ST_ERR;
     return -1;
 }
 
@@ -3455,8 +3520,10 @@ int ssl3_send_cert_status(SSL *s)
          * 1 (ocsp response type) + 3 (ocsp response length)
          * + (ocsp response)
          */
-        if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
+        if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) {
+            s->state = SSL_ST_ERR;
             return -1;
+        }
 
         p = (unsigned char *)s->init_buf->data;
 
@@ -3499,6 +3566,7 @@ int ssl3_get_next_proto(SSL *s)
     if (!s->s3->next_proto_neg_seen) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
                SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
+        s->state = SSL_ST_ERR;
         return -1;
     }
 
@@ -3518,11 +3586,14 @@ int ssl3_get_next_proto(SSL *s)
      */
     if (!s->s3->change_cipher_spec) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
+        s->state = SSL_ST_ERR;
         return -1;
     }
 
-    if (n < 2)
+    if (n < 2) {
+        s->state = SSL_ST_ERR;
         return 0;               /* The body must be > 1 bytes long */
+    }
 
     p = (unsigned char *)s->init_msg;
 
@@ -3534,15 +3605,20 @@ int ssl3_get_next_proto(SSL *s)
      *   uint8 padding[padding_len];
      */
     proto_len = p[0];
-    if (proto_len + 2 > s->init_num)
+    if (proto_len + 2 > s->init_num) {
+        s->state = SSL_ST_ERR;
         return 0;
+    }
     padding_len = p[proto_len + 1];
-    if (proto_len + padding_len + 2 != s->init_num)
+    if (proto_len + padding_len + 2 != s->init_num) {
+        s->state = SSL_ST_ERR;
         return 0;
+    }
 
     s->next_proto_negotiated = OPENSSL_malloc(proto_len);
     if (!s->next_proto_negotiated) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
+        s->state = SSL_ST_ERR;
         return 0;
     }
     memcpy(s->next_proto_negotiated, p + 1, proto_len);
index b93b67b..d2ab0c0 100644 (file)
@@ -1544,6 +1544,7 @@ extern "C" {
 # define SSL_ST_BEFORE                   0x4000
 # define SSL_ST_OK                       0x03
 # define SSL_ST_RENEGOTIATE              (0x04|SSL_ST_INIT)
+# define SSL_ST_ERR                      0x05
 
 # define SSL_CB_LOOP                     0x01
 # define SSL_CB_EXIT                     0x02
@@ -2303,6 +2304,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_F_SSL3_CHANGE_CIPHER_STATE                   129
 # define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM              130
 # define SSL_F_SSL3_CHECK_CLIENT_HELLO                    304
+# define SSL_F_SSL3_CHECK_FINISHED                        339
 # define SSL_F_SSL3_CLIENT_HELLO                          131
 # define SSL_F_SSL3_CONNECT                               132
 # define SSL_F_SSL3_CTRL                                  213
@@ -2408,6 +2410,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_F_SSL_READ                                   223
 # define SSL_F_SSL_RSA_PRIVATE_DECRYPT                    187
 # define SSL_F_SSL_RSA_PUBLIC_ENCRYPT                     188
+# define SSL_F_SSL_SESSION_DUP                            348
 # define SSL_F_SSL_SESSION_NEW                            189
 # define SSL_F_SSL_SESSION_PRINT_FP                       190
 # define SSL_F_SSL_SESSION_SET1_ID_CONTEXT                312
@@ -2522,6 +2525,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_R_DATA_LENGTH_TOO_LONG                       146
 # define SSL_R_DECRYPTION_FAILED                          147
 # define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        281
+# define SSL_R_DH_KEY_TOO_SMALL                           372
 # define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG            148
 # define SSL_R_DIGEST_CHECK_FAILED                        149
 # define SSL_R_DTLS_MESSAGE_TOO_BIG                       334
index ac7312e..88621b7 100644 (file)
@@ -160,6 +160,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {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_CHECK_FINISHED), "SSL3_CHECK_FINISHED"},
     {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),
      "SSL3_GET_CERTIFICATE_REQUEST"},
@@ -298,6 +299,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
     {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
     {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
     {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
     {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
     {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),
@@ -440,6 +442,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"},
     {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),
      "decryption failed or bad record mac"},
+    {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"},
     {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),
      "dh public value length is wrong"},
     {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"},
index dead126..e11746a 100644 (file)
@@ -1440,9 +1440,13 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
         return (NULL);
     }
-    if ((skp == NULL) || (*skp == NULL))
+    if ((skp == NULL) || (*skp == NULL)) {
         sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
-    else {
+        if(sk == NULL) {
+            SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else {
         sk = *skp;
         sk_SSL_CIPHER_zero(sk);
     }
index aff3b65..a7f3f8d 100644 (file)
@@ -865,6 +865,7 @@ int ssl_set_peer_cert_type(SESS_CERT *c, int type);
 int ssl_get_new_session(SSL *s, int session);
 int ssl_get_prev_session(SSL *s, unsigned char *session, int len,
                          const unsigned char *limit);
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
 int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
 DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
 int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
index fb4e8c5..1ad9dc7 100644 (file)
@@ -227,6 +227,130 @@ SSL_SESSION *SSL_SESSION_new(void)
     return (ss);
 }
 
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+    SSL_SESSION *dest;
+
+    dest = OPENSSL_malloc(sizeof(*src));
+    if (dest == NULL) {
+        goto err;
+    }
+    memcpy(dest, src, sizeof(*dest));
+
+    /*
+     * Set the various pointers to NULL so that we can call SSL_SESSION_free in
+     * the case of an error whilst halfway through constructing dest
+     */
+#ifndef OPENSSL_NO_PSK
+    dest->psk_identity_hint = NULL;
+    dest->psk_identity = NULL;
+#endif
+    dest->ciphers = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+    dest->tlsext_hostname = NULL;
+# ifndef OPENSSL_NO_EC
+    dest->tlsext_ecpointformatlist = NULL;
+    dest->tlsext_ellipticcurvelist = NULL;
+# endif
+#endif
+    dest->tlsext_tick = NULL;
+#ifndef OPENSSL_NO_SRP
+    dest->srp_username = NULL;
+#endif
+    memset(&dest->ex_data, 0, sizeof(dest->ex_data));
+
+    /* We deliberately don't copy the prev and next pointers */
+    dest->prev = NULL;
+    dest->next = NULL;
+
+    dest->references = 1;
+
+    if (src->sess_cert != NULL)
+        CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
+
+    if (src->peer != NULL)
+        CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
+
+#ifndef OPENSSL_NO_PSK
+    if (src->psk_identity_hint) {
+        dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
+        if (dest->psk_identity_hint == NULL) {
+            goto err;
+        }
+    }
+    if (src->psk_identity) {
+        dest->psk_identity = BUF_strdup(src->psk_identity);
+        if (dest->psk_identity == NULL) {
+            goto err;
+        }
+    }
+#endif
+
+    if(src->ciphers != NULL) {
+        dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+        if (dest->ciphers == NULL)
+            goto err;
+    }
+
+    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+                                            &dest->ex_data, &src->ex_data)) {
+        goto err;
+    }
+
+#ifndef OPENSSL_NO_TLSEXT
+    if (src->tlsext_hostname) {
+        dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
+        if (dest->tlsext_hostname == NULL) {
+            goto err;
+        }
+    }
+# ifndef OPENSSL_NO_EC
+    if (src->tlsext_ecpointformatlist) {
+        dest->tlsext_ecpointformatlist =
+            BUF_memdup(src->tlsext_ecpointformatlist,
+                       src->tlsext_ecpointformatlist_length);
+        if (dest->tlsext_ecpointformatlist == NULL)
+            goto err;
+    }
+    if (src->tlsext_ellipticcurvelist) {
+        dest->tlsext_ellipticcurvelist =
+            BUF_memdup(src->tlsext_ellipticcurvelist,
+                       src->tlsext_ellipticcurvelist_length);
+        if (dest->tlsext_ellipticcurvelist == NULL)
+            goto err;
+    }
+# endif
+#endif
+
+    if (ticket != 0) {
+        dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
+        if(dest->tlsext_tick == NULL)
+            goto err;
+    } else {
+        dest->tlsext_tick_lifetime_hint = 0;
+        dest->tlsext_ticklen = 0;
+    }
+
+#ifndef OPENSSL_NO_SRP
+    if (src->srp_username) {
+        dest->srp_username = BUF_strdup(src->srp_username);
+        if (dest->srp_username == NULL) {
+            goto err;
+        }
+    }
+#endif
+
+    return dest;
+err:
+    SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+    SSL_SESSION_free(dest);
+    return NULL;
+}
+
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                         unsigned int *len)
 {
@@ -478,9 +602,14 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
     int r;
 #endif
 
-    if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
+    if (len < 0 || len > SSL_MAX_SSL_SESSION_ID_LENGTH)
         goto err;
 
+    if (session_id + len > limit) {
+        fatal = 1;
+        goto err;
+    }
+
     if (len == 0)
         try_session_cache = 0;
 
index d725d78..1b9069f 100644 (file)
@@ -117,6 +117,9 @@ const char *SSL_state_string_long(const SSL *s)
     case SSL_ST_OK | SSL_ST_ACCEPT:
         str = "ok/accept SSL initialization";
         break;
+    case SSL_ST_ERR:
+        str = "error";
+        break;
 #ifndef OPENSSL_NO_SSL2
     case SSL2_ST_CLIENT_START_ENCRYPTION:
         str = "SSLv2 client start encryption";
@@ -496,6 +499,9 @@ const char *SSL_state_string(const SSL *s)
     case SSL_ST_OK:
         str = "SSLOK ";
         break;
+    case SSL_ST_ERR:
+        str = "SSLERR";
+        break;
 #ifndef OPENSSL_NO_SSL2
     case SSL2_ST_CLIENT_START_ENCRYPTION:
         str = "2CSENC";
index 4e2845f..8f45294 100644 (file)
@@ -261,7 +261,7 @@ static int tls1_PRF(long digest_mask,
         if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask)
             count++;
     }
-    if(!count) {
+    if (!count) {
         /* Should never happen */
         SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
         goto err;
@@ -785,7 +785,7 @@ int tls1_enc(SSL *s, int send)
         bs = EVP_CIPHER_block_size(ds->cipher);
 
         if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
-            unsigned char buf[13], *seq;
+            unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq;
 
             seq = send ? s->s3->write_sequence : s->s3->read_sequence;
 
@@ -809,7 +809,10 @@ int tls1_enc(SSL *s, int send)
             buf[10] = (unsigned char)(s->version);
             buf[11] = rec->length >> 8;
             buf[12] = rec->length & 0xff;
-            pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, 13, buf);
+            pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD,
+                                      EVP_AEAD_TLS1_AAD_LEN, buf);
+            if (pad <= 0)
+                return -1;
             if (send) {
                 l += pad;
                 rec->length += pad;
index 243a70f..c2d7d72 100644 (file)
@@ -1016,19 +1016,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
 
     s->srtp_profile = NULL;
 
-    if (data >= (d + n - 2))
-        goto ri_check;
+    if (data >= (d + n - 2)) {
+        if (data != d + n)
+            goto err;
+        else
+            goto ri_check;
+    }
     n2s(data, len);
 
     if (data > (d + n - len))
-        goto ri_check;
+        goto err;
 
     while (data <= (d + n - 4)) {
         n2s(data, type);
         n2s(data, size);
 
         if (data + size > (d + n))
-            goto ri_check;
+            goto err;
 # if 0
         fprintf(stderr, "Received extension type %d size %d\n", type, size);
 # endif
@@ -1064,16 +1068,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
             int servname_type;
             int dsize;
 
-            if (size < 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (size < 2)
+                goto err;
             n2s(data, dsize);
             size -= 2;
-            if (dsize > size) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (dsize > size)
+                goto err;
 
             sdata = data;
             while (dsize > 3) {
@@ -1081,18 +1081,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
                 n2s(sdata, len);
                 dsize -= 3;
 
-                if (len > dsize) {
-                    *al = SSL_AD_DECODE_ERROR;
-                    return 0;
-                }
+                if (len > dsize)
+                    goto err;
+
                 if (s->servername_done == 0)
                     switch (servname_type) {
                     case TLSEXT_NAMETYPE_host_name:
                         if (!s->hit) {
-                            if (s->session->tlsext_hostname) {
-                                *al = SSL_AD_DECODE_ERROR;
-                                return 0;
-                            }
+                            if (s->session->tlsext_hostname)
+                                goto err;
+
                             if (len > TLSEXT_MAXLEN_host_name) {
                                 *al = TLS1_AD_UNRECOGNIZED_NAME;
                                 return 0;
@@ -1126,31 +1124,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
 
                 dsize -= len;
             }
-            if (dsize != 0) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (dsize != 0)
+                goto err;
 
         }
 # ifndef OPENSSL_NO_SRP
         else if (type == TLSEXT_TYPE_srp) {
-            if (size <= 0 || ((len = data[0])) != (size - 1)) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (s->srp_ctx.login != NULL) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (size == 0 || ((len = data[0])) != (size - 1))
+                goto err;
+            if (s->srp_ctx.login != NULL)
+                goto err;
             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
                 return -1;
             memcpy(s->srp_ctx.login, &data[1], len);
             s->srp_ctx.login[len] = '\0';
 
-            if (strlen(s->srp_ctx.login) != len) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (strlen(s->srp_ctx.login) != len)
+                goto err;
         }
 # endif
 
@@ -1159,10 +1149,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
             unsigned char *sdata = data;
             int ecpointformatlist_length = *(sdata++);
 
-            if (ecpointformatlist_length != size - 1) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (ecpointformatlist_length != size - 1)
+                goto err;
             if (!s->hit) {
                 if (s->session->tlsext_ecpointformatlist) {
                     OPENSSL_free(s->session->tlsext_ecpointformatlist);
@@ -1196,15 +1184,13 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
             if (ellipticcurvelist_length != size - 2 ||
                 ellipticcurvelist_length < 1 ||
                 /* Each NamedCurve is 2 bytes. */
-                ellipticcurvelist_length & 1) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
+                ellipticcurvelist_length & 1)
+                    goto err;
+
             if (!s->hit) {
-                if (s->session->tlsext_ellipticcurvelist) {
-                    *al = TLS1_AD_DECODE_ERROR;
-                    return 0;
-                }
+                if (s->session->tlsext_ellipticcurvelist)
+                    goto err;
+
                 s->session->tlsext_ellipticcurvelist_length = 0;
                 if ((s->session->tlsext_ellipticcurvelist =
                      OPENSSL_malloc(ellipticcurvelist_length)) == NULL) {
@@ -1273,28 +1259,20 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
             renegotiate_seen = 1;
         } else if (type == TLSEXT_TYPE_signature_algorithms) {
             int dsize;
-            if (sigalg_seen || size < 2) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (sigalg_seen || size < 2)
+                goto err;
             sigalg_seen = 1;
             n2s(data, dsize);
             size -= 2;
-            if (dsize != size || dsize & 1) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (!tls1_process_sigalgs(s, data, dsize)) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (dsize != size || dsize & 1)
+                goto err;
+            if (!tls1_process_sigalgs(s, data, dsize))
+                goto err;
         } else if (type == TLSEXT_TYPE_status_request &&
                    s->version != DTLS1_VERSION) {
 
-            if (size < 5) {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
+            if (size < 5)
+                goto err;
 
             s->tlsext_status_type = *data++;
             size--;
@@ -1304,35 +1282,26 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
                 /* Read in responder_id_list */
                 n2s(data, dsize);
                 size -= 2;
-                if (dsize > size) {
-                    *al = SSL_AD_DECODE_ERROR;
-                    return 0;
-                }
+                if (dsize > size)
+                    goto err;
                 while (dsize > 0) {
                     OCSP_RESPID *id;
                     int idsize;
-                    if (dsize < 4) {
-                        *al = SSL_AD_DECODE_ERROR;
-                        return 0;
-                    }
+                    if (dsize < 4)
+                        goto err;
                     n2s(data, idsize);
                     dsize -= 2 + idsize;
                     size -= 2 + idsize;
-                    if (dsize < 0) {
-                        *al = SSL_AD_DECODE_ERROR;
-                        return 0;
-                    }
+                    if (dsize < 0)
+                        goto err;
                     sdata = data;
                     data += idsize;
                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
-                    if (!id) {
-                        *al = SSL_AD_DECODE_ERROR;
-                        return 0;
-                    }
+                    if (!id)
+                        goto err;
                     if (data != sdata) {
                         OCSP_RESPID_free(id);
-                        *al = SSL_AD_DECODE_ERROR;
-                        return 0;
+                        goto err;
                     }
                     if (!s->tlsext_ocsp_ids
                         && !(s->tlsext_ocsp_ids =
@@ -1349,16 +1318,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
                 }
 
                 /* Read in request_extensions */
-                if (size < 2) {
-                    *al = SSL_AD_DECODE_ERROR;
-                    return 0;
-                }
+                if (size < 2)
+                    goto err;
                 n2s(data, dsize);
                 size -= 2;
-                if (dsize != size) {
-                    *al = SSL_AD_DECODE_ERROR;
-                    return 0;
-                }
+                if (dsize != size)
+                    goto err;
                 sdata = data;
                 if (dsize > 0) {
                     if (s->tlsext_ocsp_exts) {
@@ -1368,10 +1333,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
 
                     s->tlsext_ocsp_exts =
                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
-                    if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) {
-                        *al = SSL_AD_DECODE_ERROR;
-                        return 0;
-                    }
+                    if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
+                        goto err;
                 }
             }
             /*
@@ -1432,6 +1395,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
         data += size;
     }
 
+    /* Spurious data on the end */
+    if (data != d + n)
+        goto err;
+
     *p = data;
 
  ri_check:
@@ -1447,6 +1414,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d,
     }
 
     return 1;
+err:
+    *al = SSL_AD_DECODE_ERROR;
+    return 0;
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
@@ -2612,7 +2582,10 @@ int tls1_process_heartbeat(SSL *s)
         memcpy(bp, pl, payload);
         bp += payload;
         /* Random padding */
-        RAND_pseudo_bytes(bp, padding);
+        if (RAND_pseudo_bytes(bp, padding) < 0) {
+            OPENSSL_free(buffer);
+            return -1;
+        }
 
         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
                              3 + payload + padding);
@@ -2647,7 +2620,7 @@ int tls1_process_heartbeat(SSL *s)
 int tls1_heartbeat(SSL *s)
 {
     unsigned char *buf, *p;
-    int ret;
+    int ret = -1;
     unsigned int payload = 18;  /* Sequence number + random bytes */
     unsigned int padding = 16;  /* Use minimum padding */
 
@@ -2695,10 +2668,16 @@ int tls1_heartbeat(SSL *s)
     /* Sequence number */
     s2n(s->tlsext_hb_seq, p);
     /* 16 random bytes */
-    RAND_pseudo_bytes(p, 16);
+    if (RAND_pseudo_bytes(p, 16) < 0) {
+        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
     p += 16;
     /* Random padding */
-    RAND_pseudo_bytes(p, padding);
+    if (RAND_pseudo_bytes(p, padding) < 0) {
+        SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
 
     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
     if (ret >= 0) {
@@ -2710,6 +2689,7 @@ int tls1_heartbeat(SSL *s)
         s->tlsext_hb_pending = 1;
     }
 
+err:
     OPENSSL_free(buf);
 
     return ret;
index d36cfa0..bb719ba 100644 (file)
@@ -454,7 +454,8 @@ int SRP_Calc_A_param(SSL *s)
 {
     unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
 
-    RAND_bytes(rnd, sizeof(rnd));
+    if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
+        return -1;
     s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
     OPENSSL_cleanse(rnd, sizeof(rnd));