浏览代码

OpenSSL 1.0.2k

Source commit: 861764cb0ac68b445e18da39736dae8bf11e49b6
Martin Prikryl 8 年之前
父节点
当前提交
6716b6394a
共有 39 个文件被更改,包括 490 次插入308 次删除
  1. 2 6
      libs/openssl/crypto/asn1/p5_pbev2.c
  2. 2 1
      libs/openssl/crypto/asn1/x_crl.c
  3. 3 2
      libs/openssl/crypto/bn/bn_exp.c
  4. 3 2
      libs/openssl/crypto/bn/bn_mul.c
  5. 2 1
      libs/openssl/crypto/bn/bn_prime.c
  6. 3 2
      libs/openssl/crypto/bn/bn_sqr.c
  7. 2 2
      libs/openssl/crypto/buildinf.h
  8. 4 1
      libs/openssl/crypto/cms/cms_kari.c
  9. 2 0
      libs/openssl/crypto/dh/dh_key.c
  10. 1 1
      libs/openssl/crypto/dsa/dsa_pmeth.c
  11. 11 9
      libs/openssl/crypto/ec/ec2_mult.c
  12. 3 1
      libs/openssl/crypto/ecdh/ech_ossl.c
  13. 3 0
      libs/openssl/crypto/err/err.c
  14. 2 2
      libs/openssl/crypto/evp/e_aes.c
  15. 2 0
      libs/openssl/crypto/evp/e_rc4_hmac_md5.c
  16. 4 2
      libs/openssl/crypto/evp/evp.h
  17. 2 1
      libs/openssl/crypto/evp/evp_err.c
  18. 16 14
      libs/openssl/crypto/evp/pmeth_fn.c
  19. 1 27
      libs/openssl/crypto/evp/pmeth_lib.c
  20. 1 1
      libs/openssl/crypto/modes/ctr128.c
  21. 3 3
      libs/openssl/crypto/opensslv.h
  22. 2 1
      libs/openssl/crypto/rsa/rsa_gen.c
  23. 6 2
      libs/openssl/crypto/rsa/rsa_oaep.c
  24. 4 0
      libs/openssl/crypto/rsa/rsa_pmeth.c
  25. 1 0
      libs/openssl/crypto/s390xcap.c
  26. 72 66
      libs/openssl/crypto/ui/ui_lib.c
  27. 38 21
      libs/openssl/crypto/ui/ui_openssl.c
  28. 9 3
      libs/openssl/ssl/s23_pkt.c
  29. 1 1
      libs/openssl/ssl/s2_lib.c
  30. 8 2
      libs/openssl/ssl/s2_pkt.c
  31. 33 11
      libs/openssl/ssl/s3_clnt.c
  32. 13 10
      libs/openssl/ssl/s3_pkt.c
  33. 30 3
      libs/openssl/ssl/s3_srvr.c
  34. 1 3
      libs/openssl/ssl/ssl_cert.c
  35. 1 0
      libs/openssl/ssl/ssl_err.c
  36. 1 3
      libs/openssl/ssl/ssl_lib.c
  37. 1 1
      libs/openssl/ssl/ssl_locl.h
  38. 9 0
      libs/openssl/ssl/ssl_sess.c
  39. 188 103
      libs/openssl/ssl/t1_lib.c

+ 2 - 6
libs/openssl/crypto/asn1/p5_pbev2.c

@@ -91,12 +91,11 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                               unsigned char *salt, int saltlen,
                               unsigned char *aiv, int prf_nid)
 {
-    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
+    X509_ALGOR *scheme = NULL, *ret = NULL;
     int alg_nid, keylen;
     EVP_CIPHER_CTX ctx;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     PBE2PARAM *pbe2 = NULL;
-    ASN1_OBJECT *obj;
 
     alg_nid = EVP_CIPHER_type(cipher);
     if (alg_nid == NID_undef) {
@@ -104,7 +103,6 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                 ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
         goto err;
     }
-    obj = OBJ_nid2obj(alg_nid);
 
     if (!(pbe2 = PBE2PARAM_new()))
         goto merr;
@@ -112,7 +110,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
     /* Setup the AlgorithmIdentifier for the encryption scheme */
     scheme = pbe2->encryption;
 
-    scheme->algorithm = obj;
+    scheme->algorithm = OBJ_nid2obj(alg_nid);
     if (!(scheme->parameter = ASN1_TYPE_new()))
         goto merr;
 
@@ -188,11 +186,9 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
  err:
     PBE2PARAM_free(pbe2);
     /* Note 'scheme' is freed as part of pbe2 */
-    X509_ALGOR_free(kalg);
     X509_ALGOR_free(ret);
 
     return NULL;
-
 }
 
 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,

+ 2 - 1
libs/openssl/crypto/asn1/x_crl.c

@@ -254,6 +254,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 
         for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
             int nid;
+
             ext = sk_X509_EXTENSION_value(exts, idx);
             nid = OBJ_obj2nid(ext->object);
             if (nid == NID_freshest_crl)
@@ -263,7 +264,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
                 if ((nid == NID_issuing_distribution_point)
                     || (nid == NID_authority_key_identifier)
                     || (nid == NID_delta_crl))
-                    break;;
+                    continue;
                 crl->flags |= EXFLAG_CRITICAL;
                 break;
             }

+ 3 - 2
libs/openssl/crypto/bn/bn_exp.c

@@ -180,8 +180,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
                 goto err;
         }
     }
-    if (r != rr)
-        BN_copy(r, rr);
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
     ret = 1;
  err:
     BN_CTX_end(ctx);

+ 3 - 2
libs/openssl/crypto/bn/bn_mul.c

@@ -1083,8 +1083,9 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
  end:
 #endif
     bn_correct_top(rr);
-    if (r != rr)
-        BN_copy(r, rr);
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
     ret = 1;
  err:
     bn_check_top(r);

+ 2 - 1
libs/openssl/crypto/bn/bn_prime.c

@@ -283,7 +283,8 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
         BIGNUM *t;
         if ((t = BN_CTX_get(ctx)) == NULL)
             goto err;
-        BN_copy(t, a);
+        if (BN_copy(t, a) == NULL)
+            goto err;
         t->neg = 0;
         A = t;
     } else

+ 3 - 2
libs/openssl/crypto/bn/bn_sqr.c

@@ -143,8 +143,9 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
         rr->top = max - 1;
     else
         rr->top = max;
-    if (rr != r)
-        BN_copy(r, rr);
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
     ret = 1;
  err:
     bn_check_top(rr);

+ 2 - 2
libs/openssl/crypto/buildinf.h

@@ -9,11 +9,11 @@
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "compiler: cl  /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS  -DDSO_WIN32  -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_WEAK_SSL_CIPHERS -DOPENSSL_NO_STATIC_ENGINE    "
   #define PLATFORM "VC-WIN32"
-  #define DATE "Fri Sep 30 11:53:43 2016"
+  #define DATE "Thu Feb  2 13:44:02 2017"
 #endif
 #ifdef MK1MF_PLATFORM_BC_NT
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "compiler: bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_WEAK_SSL_CIPHERS -DOPENSSL_NO_DYNAMIC_ENGINE    "
   #define PLATFORM "BC-NT"
-  #define DATE "Fri Sep 30 11:53:43 2016"
+  #define DATE "Thu Feb  2 13:44:03 2017"
 #endif

+ 4 - 1
libs/openssl/crypto/cms/cms_kari.c

@@ -401,9 +401,12 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
      * Pick a cipher based on content encryption cipher. If it is DES3 use
      * DES3 wrap otherwise use AES wrap similar to key size.
      */
+#ifndef OPENSSL_NO_DES
     if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
         kekcipher = EVP_des_ede3_wrap();
-    else if (keylen <= 16)
+    else
+#endif
+    if (keylen <= 16)
         kekcipher = EVP_aes_128_wrap();
     else if (keylen <= 24)
         kekcipher = EVP_aes_192_wrap();

+ 2 - 0
libs/openssl/crypto/dh/dh_key.c

@@ -223,6 +223,8 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
         goto err;
     BN_CTX_start(ctx);
     tmp = BN_CTX_get(ctx);
+    if (tmp == NULL)
+        goto err;
 
     if (dh->priv_key == NULL) {
         DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);

+ 1 - 1
libs/openssl/crypto/dsa/dsa_pmeth.c

@@ -180,7 +180,7 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
             return 0;
         }
-        dctx->md = p2;
+        dctx->pmd = p2;
         return 1;
 
     case EVP_PKEY_CTRL_MD:

+ 11 - 9
libs/openssl/crypto/ec/ec2_mult.c

@@ -267,7 +267,7 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
                                              BN_CTX *ctx)
 {
     BIGNUM *x1, *x2, *z1, *z2;
-    int ret = 0, i;
+    int ret = 0, i, group_top;
     BN_ULONG mask, word;
 
     if (r == point) {
@@ -297,10 +297,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
     x2 = &r->X;
     z2 = &r->Y;
 
-    bn_wexpand(x1, group->field.top);
-    bn_wexpand(z1, group->field.top);
-    bn_wexpand(x2, group->field.top);
-    bn_wexpand(z2, group->field.top);
+    group_top = group->field.top;
+    if (bn_wexpand(x1, group_top) == NULL
+        || bn_wexpand(z1, group_top) == NULL
+        || bn_wexpand(x2, group_top) == NULL
+        || bn_wexpand(z2, group_top) == NULL)
+        goto err;
 
     if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
         goto err;               /* x1 = x */
@@ -329,14 +331,14 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
     for (; i >= 0; i--) {
         word = scalar->d[i];
         while (mask) {
-            BN_consttime_swap(word & mask, x1, x2, group->field.top);
-            BN_consttime_swap(word & mask, z1, z2, group->field.top);
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
             if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
                 goto err;
             if (!gf2m_Mdouble(group, x1, z1, ctx))
                 goto err;
-            BN_consttime_swap(word & mask, x1, x2, group->field.top);
-            BN_consttime_swap(word & mask, z1, z2, group->field.top);
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
             mask >>= 1;
         }
         mask = BN_TBIT;

+ 3 - 1
libs/openssl/crypto/ecdh/ech_ossl.c

@@ -212,7 +212,9 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
         BN_CTX_end(ctx);
     if (ctx)
         BN_CTX_free(ctx);
-    if (buf)
+    if (buf) {
+        OPENSSL_cleanse(buf, buflen);
         OPENSSL_free(buf);
+    }
     return (ret);
 }

+ 3 - 0
libs/openssl/crypto/err/err.c

@@ -868,6 +868,9 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len)
     const char *ls, *fs, *rs;
     unsigned long l, f, r;
 
+    if (len == 0)
+        return;
+
     l = ERR_GET_LIB(e);
     f = ERR_GET_FUNC(e);
     r = ERR_GET_REASON(e);

+ 2 - 2
libs/openssl/crypto/evp/e_aes.c

@@ -155,10 +155,10 @@ void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
                        const unsigned char ivec[AES_BLOCK_SIZE]);
 # endif
 # ifdef AES_XTS_ASM
-void AES_xts_encrypt(const char *inp, char *out, size_t len,
+void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
                      const AES_KEY *key1, const AES_KEY *key2,
                      const unsigned char iv[16]);
-void AES_xts_decrypt(const char *inp, char *out, size_t len,
+void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
                      const AES_KEY *key1, const AES_KEY *key2,
                      const unsigned char iv[16]);
 # endif

+ 2 - 0
libs/openssl/crypto/evp/e_rc4_hmac_md5.c

@@ -269,6 +269,8 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
             len = p[arg - 2] << 8 | p[arg - 1];
 
             if (!ctx->encrypt) {
+                if (len < MD5_DIGEST_LENGTH)
+                    return -1;
                 len -= MD5_DIGEST_LENGTH;
                 p[arg - 2] = len >> 8;
                 p[arg - 1] = len;

+ 4 - 2
libs/openssl/crypto/evp/evp.h

@@ -1370,6 +1370,7 @@ void EVP_add_alg_module(void);
  * The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
  */
+
 void ERR_load_EVP_strings(void);
 
 /* Error codes for the EVP functions. */
@@ -1489,6 +1490,7 @@ void ERR_load_EVP_strings(void);
 # define EVP_R_INPUT_NOT_INITIALIZED                      111
 # define EVP_R_INVALID_DIGEST                             152
 # define EVP_R_INVALID_FIPS_MODE                          168
+# define EVP_R_INVALID_KEY                                171
 # define EVP_R_INVALID_KEY_LENGTH                         130
 # define EVP_R_INVALID_OPERATION                          148
 # define EVP_R_IV_TOO_LARGE                               102
@@ -1528,7 +1530,7 @@ void ERR_load_EVP_strings(void);
 # define EVP_R_WRONG_FINAL_BLOCK_LENGTH                   109
 # define EVP_R_WRONG_PUBLIC_KEY_TYPE                      110
 
-#ifdef  __cplusplus
+# ifdef  __cplusplus
 }
-#endif
+# endif
 #endif

+ 2 - 1
libs/openssl/crypto/evp/evp_err.c

@@ -1,6 +1,6 @@
 /* crypto/evp/evp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2013 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -192,6 +192,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"},
     {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"},
     {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
+    {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"},
     {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
     {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"},
     {ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"},

+ 16 - 14
libs/openssl/crypto/evp/pmeth_fn.c

@@ -65,20 +65,22 @@
 #include "evp_locl.h"
 
 #define M_check_autoarg(ctx, arg, arglen, err) \
-        if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
-                { \
-                size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
-                if (!arg) \
-                        { \
-                        *arglen = pksize; \
-                        return 1; \
-                        } \
-                else if (*arglen < pksize) \
-                        { \
-                        EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
-                        return 0; \
-                        } \
-                }
+    if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) {           \
+        size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey);         \
+                                                                  \
+        if (pksize == 0) {                                        \
+            EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/      \
+            return 0;                                             \
+        }                                                         \
+        if (!arg) {                                               \
+            *arglen = pksize;                                     \
+            return 1;                                             \
+        }                                                         \
+        if (*arglen < pksize) {                                   \
+            EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
+            return 0;                                             \
+        }                                                         \
+    }
 
 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
 {

+ 1 - 27
libs/openssl/crypto/evp/pmeth_lib.c

@@ -199,6 +199,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
 EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
 {
     EVP_PKEY_METHOD *pmeth;
+
     pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
     if (!pmeth)
         return NULL;
@@ -207,33 +208,6 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
 
     pmeth->pkey_id = id;
     pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
-
-    pmeth->init = 0;
-    pmeth->copy = 0;
-    pmeth->cleanup = 0;
-    pmeth->paramgen_init = 0;
-    pmeth->paramgen = 0;
-    pmeth->keygen_init = 0;
-    pmeth->keygen = 0;
-    pmeth->sign_init = 0;
-    pmeth->sign = 0;
-    pmeth->verify_init = 0;
-    pmeth->verify = 0;
-    pmeth->verify_recover_init = 0;
-    pmeth->verify_recover = 0;
-    pmeth->signctx_init = 0;
-    pmeth->signctx = 0;
-    pmeth->verifyctx_init = 0;
-    pmeth->verifyctx = 0;
-    pmeth->encrypt_init = 0;
-    pmeth->encrypt = 0;
-    pmeth->decrypt_init = 0;
-    pmeth->decrypt = 0;
-    pmeth->derive_init = 0;
-    pmeth->derive = 0;
-    pmeth->ctrl = 0;
-    pmeth->ctrl_str = 0;
-
     return pmeth;
 }
 

+ 1 - 1
libs/openssl/crypto/modes/ctr128.c

@@ -100,7 +100,7 @@ static void ctr128_inc_aligned(unsigned char *counter)
         --n;
         d = data[n] += c;
         /* did addition carry? */
-        c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
+        c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
     } while (n);
 }
 #endif

+ 3 - 3
libs/openssl/crypto/opensslv.h

@@ -30,11 +30,11 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x100020afL
+# define OPENSSL_VERSION_NUMBER  0x100020bfL
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2j-fips  26 Sep 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2k-fips  26 Jan 2017"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2j  26 Sep 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.2k  26 Jan 2017"
 # endif
 # define OPENSSL_VERSION_PTEXT   " part of " OPENSSL_VERSION_TEXT
 

+ 2 - 1
libs/openssl/crypto/rsa/rsa_gen.c

@@ -142,7 +142,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
     if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL))
         goto err;
 
-    BN_copy(rsa->e, e_value);
+    if (BN_copy(rsa->e, e_value) == NULL)
+        goto err;
 
     /* generate p and q */
     for (;;) {

+ 6 - 2
libs/openssl/crypto/rsa/rsa_oaep.c

@@ -89,17 +89,21 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
     }
 
     if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
-        return 0;
+        goto err;
     for (i = 0; i < emlen - mdlen; i++)
         db[i] ^= dbmask[i];
 
     if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
-        return 0;
+        goto err;
     for (i = 0; i < mdlen; i++)
         seed[i] ^= seedmask[i];
 
     OPENSSL_free(dbmask);
     return 1;
+
+ err:
+    OPENSSL_free(dbmask);
+    return 0;
 }
 
 int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,

+ 4 - 0
libs/openssl/crypto/rsa/rsa_pmeth.c

@@ -373,6 +373,10 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
         if (rctx->pad_mode == RSA_PKCS1_PADDING)
             return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
                               sig, siglen, rsa);
+        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
+            RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
+            return -1;
+        }
         if (rctx->pad_mode == RSA_X931_PADDING) {
             if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0)
                 return 0;

+ 1 - 0
libs/openssl/crypto/s390xcap.c

@@ -3,6 +3,7 @@
 #include <string.h>
 #include <setjmp.h>
 #include <signal.h>
+#include "cryptlib.h"
 
 extern unsigned long OPENSSL_s390xcap_P[];
 

+ 72 - 66
libs/openssl/crypto/ui/ui_lib.c

@@ -164,7 +164,7 @@ static int general_allocate_string(UI *ui, const char *prompt,
     UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
                                            type, input_flags, result_buf);
 
-    if (s) {
+    if (s != NULL) {
         if (allocate_string_stack(ui) >= 0) {
             s->_.string_data.result_minsize = minsize;
             s->_.string_data.result_maxsize = maxsize;
@@ -197,8 +197,8 @@ static int general_allocate_boolean(UI *ui,
     } else if (cancel_chars == NULL) {
         UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
     } else {
-        for (p = ok_chars; *p; p++) {
-            if (strchr(cancel_chars, *p)) {
+        for (p = ok_chars; *p != '\0'; p++) {
+            if (strchr(cancel_chars, *p) != NULL) {
                 UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
                       UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
             }
@@ -207,7 +207,7 @@ static int general_allocate_boolean(UI *ui,
         s = general_allocate_prompt(ui, prompt, prompt_freeable,
                                     type, input_flags, result_buf);
 
-        if (s) {
+        if (s != NULL) {
             if (allocate_string_stack(ui) >= 0) {
                 s->_.boolean_data.action_desc = action_desc;
                 s->_.boolean_data.ok_chars = ok_chars;
@@ -243,7 +243,7 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,
 {
     char *prompt_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
@@ -271,7 +271,7 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
 {
     char *prompt_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
@@ -302,7 +302,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
     char *ok_chars_copy = NULL;
     char *cancel_chars_copy = NULL;
 
-    if (prompt) {
+    if (prompt != NULL) {
         prompt_copy = BUF_strdup(prompt);
         if (prompt_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -310,7 +310,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
         }
     }
 
-    if (action_desc) {
+    if (action_desc != NULL) {
         action_desc_copy = BUF_strdup(action_desc);
         if (action_desc_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -318,7 +318,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
         }
     }
 
-    if (ok_chars) {
+    if (ok_chars != NULL) {
         ok_chars_copy = BUF_strdup(ok_chars);
         if (ok_chars_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -326,7 +326,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
         }
     }
 
-    if (cancel_chars) {
+    if (cancel_chars != NULL) {
         cancel_chars_copy = BUF_strdup(cancel_chars);
         if (cancel_chars_copy == NULL) {
             UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -359,7 +359,7 @@ int UI_dup_info_string(UI *ui, const char *text)
 {
     char *text_copy = NULL;
 
-    if (text) {
+    if (text != NULL) {
         text_copy = BUF_strdup(text);
         if (text_copy == NULL) {
             UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
@@ -381,7 +381,7 @@ int UI_dup_error_string(UI *ui, const char *text)
 {
     char *text_copy = NULL;
 
-    if (text) {
+    if (text != NULL) {
         text_copy = BUF_strdup(text);
         if (text_copy == NULL) {
             UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
@@ -397,7 +397,7 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
 {
     char *prompt = NULL;
 
-    if (ui->meth->ui_construct_prompt)
+    if (ui->meth->ui_construct_prompt != NULL)
         prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
     else {
         char prompt1[] = "Enter ";
@@ -408,7 +408,7 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
         if (object_desc == NULL)
             return NULL;
         len = sizeof(prompt1) - 1 + strlen(object_desc);
-        if (object_name)
+        if (object_name != NULL)
             len += sizeof(prompt2) - 1 + strlen(object_name);
         len += sizeof(prompt3) - 1;
 
@@ -417,7 +417,7 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
             return NULL;
         BUF_strlcpy(prompt, prompt1, len + 1);
         BUF_strlcat(prompt, object_desc, len + 1);
-        if (object_name) {
+        if (object_name != NULL) {
             BUF_strlcat(prompt, prompt2, len + 1);
             BUF_strlcat(prompt, object_name, len + 1);
         }
@@ -459,7 +459,8 @@ static int print_error(const char *str, size_t len, UI *ui)
     uis.type = UIT_ERROR;
     uis.out_string = str;
 
-    if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
+    if (ui->meth->ui_write_string != NULL
+        && ui->meth->ui_write_string(ui, &uis) <= 0)
         return -1;
     return 0;
 }
@@ -468,24 +469,28 @@ int UI_process(UI *ui)
 {
     int i, ok = 0;
 
-    if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
-        return -1;
+    if (ui->meth->ui_open_session != NULL
+        && ui->meth->ui_open_session(ui) <= 0) {
+        ok = -1;
+        goto err;
+    }
 
     if (ui->flags & UI_FLAG_PRINT_ERRORS)
         ERR_print_errors_cb((int (*)(const char *, size_t, void *))
                             print_error, (void *)ui);
 
     for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-        if (ui->meth->ui_write_string
-            && !ui->meth->ui_write_string(ui,
-                                          sk_UI_STRING_value(ui->strings, i)))
+        if (ui->meth->ui_write_string != NULL
+            && (ui->meth->ui_write_string(ui,
+                                          sk_UI_STRING_value(ui->strings, i))
+                <= 0))
         {
             ok = -1;
             goto err;
         }
     }
 
-    if (ui->meth->ui_flush)
+    if (ui->meth->ui_flush != NULL)
         switch (ui->meth->ui_flush(ui)) {
         case -1:               /* Interrupt/Cancel/something... */
             ok = -2;
@@ -499,7 +504,7 @@ int UI_process(UI *ui)
         }
 
     for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
-        if (ui->meth->ui_read_string) {
+        if (ui->meth->ui_read_string != NULL) {
             switch (ui->meth->ui_read_string(ui,
                                              sk_UI_STRING_value(ui->strings,
                                                                 i))) {
@@ -516,7 +521,8 @@ int UI_process(UI *ui)
         }
     }
  err:
-    if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+    if (ui->meth->ui_close_session != NULL
+        && ui->meth->ui_close_session(ui) <= 0)
         return -1;
     return ok;
 }
@@ -612,49 +618,49 @@ void UI_destroy_method(UI_METHOD *ui_method)
 
 int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_open_session = opener;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_writer(UI_METHOD *method,
                          int (*writer) (UI *ui, UI_STRING *uis))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_write_string = writer;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_flush = flusher;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_reader(UI_METHOD *method,
                          int (*reader) (UI *ui, UI_STRING *uis))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_read_string = reader;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_close_session = closer;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
 int UI_method_set_prompt_constructor(UI_METHOD *method,
@@ -664,55 +670,55 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
                                                                   const char
                                                                   *object_name))
 {
-    if (method) {
+    if (method != NULL) {
         method->ui_construct_prompt = prompt_constructor;
         return 0;
-    } else
-        return -1;
+    }
+    return -1;
 }
 
-int (*UI_method_get_opener(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_open_session;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
-    if (method)
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+    if (method != NULL)
         return method->ui_write_string;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_flush;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
-    if (method)
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+    if (method != NULL)
         return method->ui_read_string;
-    else
-        return NULL;
+    return NULL;
 }
 
-int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
-    if (method)
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
+{
+    if (method != NULL)
         return method->ui_close_session;
-    else
-        return NULL;
+    return NULL;
 }
 
 char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
                                                               const char *,
-                                                              const char *) {
-    if (method)
+                                                              const char *)
+{
+    if (method != NULL)
         return method->ui_construct_prompt;
-    else
-        return NULL;
+    return NULL;
 }
 
 enum UI_string_types UI_get_string_type(UI_STRING *uis)

+ 38 - 21
libs/openssl/crypto/ui/ui_openssl.c

@@ -440,7 +440,7 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
 # else
     p = fgets(result, maxsize, tty_in);
 # endif
-    if (!p)
+    if (p == NULL)
         goto error;
     if (feof(tty_in))
         goto error;
@@ -508,19 +508,32 @@ static int open_console(UI *ui)
         if (errno == EINVAL)
             is_a_tty = 0;
         else
+# endif
+# ifdef ENODEV
+            /*
+             * MacOS X returns ENODEV (Operation not supported by device),
+             * which seems appropriate.
+             */
+        if (errno == ENODEV)
+            is_a_tty = 0;
+        else
 # endif
             return 0;
     }
 #endif
 #ifdef OPENSSL_SYS_VMS
     status = sys$assign(&terminal, &channel, 0, 0);
+
+    /* if there isn't a TT device, something is very wrong */
     if (status != SS$_NORMAL)
         return 0;
-    status =
-        sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0,
-                 0, 0);
+
+    status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12,
+                      0, 0, 0, 0);
+
+    /* If IO$_SENSEMODE doesn't work, this is not a terminal device */
     if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+        is_a_tty = 0;
 #endif
     return 1;
 }
@@ -537,14 +550,15 @@ static int noecho_console(UI *ui)
         return 0;
 #endif
 #ifdef OPENSSL_SYS_VMS
-    tty_new[0] = tty_orig[0];
-    tty_new[1] = tty_orig[1] | TT$M_NOECHO;
-    tty_new[2] = tty_orig[2];
-    status =
-        sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
-                 0);
-    if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+    if (is_a_tty) {
+        tty_new[0] = tty_orig[0];
+        tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+        tty_new[2] = tty_orig[2];
+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+                          0, 0, 0, 0);
+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+            return 0;
+    }
 #endif
     return 1;
 }
@@ -561,14 +575,15 @@ static int echo_console(UI *ui)
         return 0;
 #endif
 #ifdef OPENSSL_SYS_VMS
-    tty_new[0] = tty_orig[0];
-    tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
-    tty_new[2] = tty_orig[2];
-    status =
-        sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
-                 0);
-    if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
-        return 0;
+    if (is_a_tty) {
+        tty_new[0] = tty_orig[0];
+        tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
+        tty_new[2] = tty_orig[2];
+        status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+                          0, 0, 0, 0);
+        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+            return 0;
+    }
 #endif
     return 1;
 }
@@ -581,6 +596,8 @@ static int close_console(UI *ui)
         fclose(tty_out);
 #ifdef OPENSSL_SYS_VMS
     status = sys$dassgn(channel);
+    if (status != SS$_NORMAL)
+        return 0;
 #endif
     CRYPTO_w_unlock(CRYPTO_LOCK_UI);
 

+ 9 - 3
libs/openssl/ssl/s23_pkt.c

@@ -63,6 +63,9 @@
 #include <openssl/evp.h>
 #include <openssl/buffer.h>
 
+/*
+ * Return values are as per SSL_write()
+ */
 int ssl23_write_bytes(SSL *s)
 {
     int i, num, tot;
@@ -77,7 +80,7 @@ int ssl23_write_bytes(SSL *s)
         if (i <= 0) {
             s->init_off = tot;
             s->init_num = num;
-            return (i);
+            return i;
         }
         s->rwstate = SSL_NOTHING;
         if (i == num)
@@ -88,7 +91,10 @@ int ssl23_write_bytes(SSL *s)
     }
 }
 
-/* return regularly only when we have read (at least) 'n' bytes */
+/* return regularly only when we have read (at least) 'n' bytes
+ *
+ * Return values are as per SSL_read()
+ */
 int ssl23_read_bytes(SSL *s, int n)
 {
     unsigned char *p;
@@ -102,7 +108,7 @@ int ssl23_read_bytes(SSL *s, int n)
             j = BIO_read(s->rbio, (char *)&(p[s->packet_length]),
                          n - s->packet_length);
             if (j <= 0)
-                return (j);
+                return j;
             s->rwstate = SSL_NOTHING;
             s->packet_length += j;
             if (s->packet_length >= (unsigned int)n)

+ 1 - 1
libs/openssl/ssl/s2_lib.c

@@ -254,7 +254,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = {
      SSL_3DES,
      SSL_MD5,
      SSL_SSLV2,
-     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
      0,
      112,
      168,

+ 8 - 2
libs/openssl/ssl/s2_pkt.c

@@ -307,6 +307,9 @@ int ssl2_peek(SSL *s, void *buf, int len)
     return ssl2_read_internal(s, buf, len, 1);
 }
 
+/*
+ * Return values are as per SSL_read()
+ */
 static int read_n(SSL *s, unsigned int n, unsigned int max,
                   unsigned int extend)
 {
@@ -374,7 +377,7 @@ static int read_n(SSL *s, unsigned int n, unsigned int max,
 # endif
         if (i <= 0) {
             s->s2->rbuf_left += newb;
-            return (i);
+            return i;
         }
         newb += i;
     }
@@ -441,6 +444,9 @@ int ssl2_write(SSL *s, const void *_buf, int len)
     }
 }
 
+/*
+ * Return values are as per SSL_write()
+ */
 static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
 {
     int i;
@@ -477,7 +483,7 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
             s->rwstate = SSL_NOTHING;
             return (s->s2->wpend_ret);
         } else if (i <= 0)
-            return (i);
+            return i;
         s->s2->wpend_off += i;
         s->s2->wpend_len -= i;
     }

+ 33 - 11
libs/openssl/ssl/s3_clnt.c

@@ -1710,12 +1710,6 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
-        if (BN_is_zero(dh->p)) {
-            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
-            goto f_err;
-        }
-
-
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1736,11 +1730,6 @@ int ssl3_get_key_exchange(SSL *s)
         }
         p += i;
 
-        if (BN_is_zero(dh->g)) {
-            SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
-            goto f_err;
-        }
-
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
@@ -1767,6 +1756,39 @@ int ssl3_get_key_exchange(SSL *s)
             goto f_err;
         }
 
+        /*-
+         * Check that p and g are suitable enough
+         *
+         * p is odd
+         * 1 < g < p - 1
+         */
+        {
+            BIGNUM *tmp = NULL;
+
+            if (!BN_is_odd(dh->p)) {
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
+                goto f_err;
+            }
+            if (BN_is_negative(dh->g) || BN_is_zero(dh->g)
+                || BN_is_one(dh->g)) {
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+                goto f_err;
+            }
+            if ((tmp = BN_new()) == NULL
+                || BN_copy(tmp, dh->p) == NULL
+                || !BN_sub_word(tmp, 1)) {
+                BN_free(tmp);
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
+                goto err;
+            }
+            if (BN_cmp(dh->g, tmp) >= 0) {
+                BN_free(tmp);
+                SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+                goto f_err;
+            }
+            BN_free(tmp);
+        }
+
 # ifndef OPENSSL_NO_RSA
         if (alg_a & SSL_aRSA)
             pkey =

+ 13 - 10
libs/openssl/ssl/s3_pkt.c

@@ -136,6 +136,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
                          unsigned int len, int create_empty_fragment);
 static int ssl3_get_record(SSL *s);
 
+/*
+ * Return values are as per SSL_read()
+ */
 int ssl3_read_n(SSL *s, int n, int max, int extend)
 {
     /*
@@ -1082,7 +1085,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     return -1;
 }
 
-/* if s->s3->wbuf.left != 0, we need to call this */
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write(), i.e.
+ */
 int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        unsigned int len)
 {
@@ -1122,7 +1128,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                  */
                 wb->left = 0;
             }
-            return (i);
+            return i;
         }
         wb->offset += i;
         wb->left -= i;
@@ -1593,16 +1599,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
 
     switch (rr->type) {
     default:
-#ifndef OPENSSL_NO_TLS
         /*
-         * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
-         * an unexpected message alert.
+         * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
+         * TLS 1.2 says you MUST send an unexpected message alert. We use the
+         * TLS 1.2 behaviour for all protocol versions to prevent issues where
+         * no progress is being made and the peer continually sends unrecognised
+         * record types, using up resources processing them.
          */
-        if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
-            rr->length = 0;
-            goto start;
-        }
-#endif
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
         goto f_err;

+ 30 - 3
libs/openssl/ssl/s3_srvr.c

@@ -506,7 +506,7 @@ int ssl3_accept(SSL *s)
                     * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
                     * during re-negotiation:
                     */
-                   ((s->session->peer != NULL) &&
+                   (s->s3->tmp.finish_md_len != 0 &&
                     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
                    /*
                     * never request cert in anonymous ciphersuites (see
@@ -1465,9 +1465,9 @@ int ssl3_get_client_hello(SSL *s)
 
     /* Handles TLS extensions that we couldn't check earlier */
     if (s->version >= SSL3_VERSION) {
-        if (ssl_check_clienthello_tlsext_late(s) <= 0) {
+        if (!ssl_check_clienthello_tlsext_late(s, &al)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
-            goto err;
+            goto f_err;
         }
     }
 
@@ -1601,6 +1601,9 @@ int ssl3_send_server_key_exchange(SSL *s)
     unsigned int u;
 #endif
 #ifndef OPENSSL_NO_DH
+# ifdef OPENSSL_NO_RSA
+    int j;
+# endif
     DH *dh = NULL, *dhp;
 #endif
 #ifndef OPENSSL_NO_ECDH
@@ -1861,6 +1864,16 @@ int ssl3_send_server_key_exchange(SSL *s)
             if ((i == 2) && (type & SSL_kSRP))
                 n += 1 + nr[i];
             else
+#endif
+#ifndef OPENSSL_NO_DH
+            /*
+             * for interoperability with some versions of the Microsoft TLS
+             * stack, we need to zero pad the DHE pub key to the same length
+             * as the prime, so use the length of the prime here
+             */
+            if ((i == 2) && (type & (SSL_kEDH)))
+                n += 2 + nr[0];
+            else
 #endif
                 n += 2 + nr[i];
         }
@@ -1895,6 +1908,20 @@ int ssl3_send_server_key_exchange(SSL *s)
                 *p = nr[i];
                 p++;
             } else
+#endif
+#ifndef OPENSSL_NO_DH
+            /*
+             * for interoperability with some versions of the Microsoft TLS
+             * stack, we need to zero pad the DHE pub key to the same length
+             * as the prime
+             */
+            if ((i == 2) && (type & (SSL_kEDH))) {
+                s2n(nr[0], p);
+                for (j = 0; j < (nr[0] - nr[2]); ++j) {
+                    *p = 0;
+                    ++p;
+                }
+            } else
 #endif
                 s2n(nr[i], p);
             BN_bn2bin(r[i], p);

+ 1 - 3
libs/openssl/ssl/ssl_cert.c

@@ -315,7 +315,7 @@ CERT *ssl_cert_dup(CERT *cert)
                 OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
             if (ret->pkeys[i].serverinfo == NULL) {
                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
-                return NULL;
+                goto err;
             }
             ret->pkeys[i].serverinfo_length =
                 cert->pkeys[i].serverinfo_length;
@@ -392,9 +392,7 @@ CERT *ssl_cert_dup(CERT *cert)
 
     return (ret);
 
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
  err:
-#endif
 #ifndef OPENSSL_NO_RSA
     if (ret->rsa_tmp != NULL)
         RSA_free(ret->rsa_tmp);

+ 1 - 0
libs/openssl/ssl/ssl_err.c

@@ -753,6 +753,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
      "tls illegal exporter label"},
     {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
      "tls invalid ecpointformat list"},
+    {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
     {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),
      "tls peer did not respond with certificate list"},
     {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),

+ 1 - 3
libs/openssl/ssl/ssl_lib.c

@@ -2030,10 +2030,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     ret->rbuf_freelist->len = 0;
     ret->rbuf_freelist->head = NULL;
     ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
-    if (!ret->wbuf_freelist) {
-        OPENSSL_free(ret->rbuf_freelist);
+    if (!ret->wbuf_freelist)
         goto err;
-    }
     ret->wbuf_freelist->chunklen = 0;
     ret->wbuf_freelist->len = 0;
     ret->wbuf_freelist->head = NULL;

+ 1 - 1
libs/openssl/ssl/ssl_locl.h

@@ -1384,7 +1384,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *limit);
 int tls1_set_server_sigalgs(SSL *s);
-int ssl_check_clienthello_tlsext_late(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *d, int n);
 int ssl_prepare_clienthello_tlsext(SSL *s);

+ 9 - 0
libs/openssl/ssl/ssl_sess.c

@@ -769,6 +769,15 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
          * obtain the same session from an external cache)
          */
         s = NULL;
+    } else if (s == NULL &&
+               lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
+        /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */
+
+        /*
+         * ... so take back the extra reference and also don't add
+         * the session to the SSL_SESSION_list at this time
+         */
+        s = c;
     }
 
     /* Put at the head of the queue unless it is already in the cache */

+ 188 - 103
libs/openssl/ssl/t1_lib.c

@@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_early(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 #endif
 
+#define CHECKLEN(curr, val, limit) \
+    (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
+
 SSL3_ENC_METHOD TLSv1_enc_data = {
     tls1_enc,
     tls1_mac,
@@ -1263,8 +1266,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 
     if (s->tlsext_hostname != NULL) {
         /* Add TLS extension servername to the Client Hello message */
-        unsigned long size_str;
-        long lenmax;
+        size_t size_str;
 
         /*-
          * check for enough space.
@@ -1274,10 +1276,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 2 for hostname length
          * + hostname length
          */
-
-        if ((lenmax = limit - ret - 9) < 0
-            || (size_str =
-                strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
+        size_str = strlen(s->tlsext_hostname);
+        if (CHECKLEN(ret, 9 + size_str, limit))
             return NULL;
 
         /* extension type and length */
@@ -1321,7 +1321,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
                                      * Client Hello message */
 
-        int login_len = strlen(s->srp_ctx.login);
+        size_t login_len = strlen(s->srp_ctx.login);
         if (login_len > 255 || login_len == 0) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
@@ -1333,7 +1333,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * 1 for the srp user identity
          * + srp user identity length
          */
-        if ((limit - ret - 5 - login_len) < 0)
+        if (CHECKLEN(ret, 5 + login_len, limit))
             return NULL;
 
         /* fill in the extension */
@@ -1350,20 +1350,23 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         /*
          * Add TLS extension ECPointFormats to the ClientHello message
          */
-        long lenmax;
         const unsigned char *pcurves, *pformats;
         size_t num_curves, num_formats, curves_list_len;
 
         tls1_get_formatlist(s, &pformats, &num_formats);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (num_formats > (size_t)lenmax)
-            return NULL;
         if (num_formats > 255) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec point formats type and extension length
+         * 1 byte for the length of the formats
+         * + formats length
+         */
+        if (CHECKLEN(ret, 5 + num_formats, limit))
+            return NULL;
 
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
         /* The point format list has 1-byte length. */
@@ -1379,15 +1382,20 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
             return NULL;
 
-        if ((lenmax = limit - ret - 6) < 0)
-            return NULL;
-        if (num_curves > (size_t)lenmax / 2)
-            return NULL;
         if (num_curves > 65532 / 2) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
         curves_list_len = 2 * num_curves;
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec curves type and extension length
+         * 2 bytes for the curve list length
+         * + curve list length
+         */
+        if (CHECKLEN(ret, 6 + curves_list_len, limit))
+            return NULL;
+
         s2n(TLSEXT_TYPE_elliptic_curves, ret);
         s2n(curves_list_len + 2, ret);
         s2n(curves_list_len, ret);
@@ -1397,7 +1405,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 # endif                         /* OPENSSL_NO_EC */
 
     if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
-        int ticklen;
+        size_t ticklen;
         if (!s->new_session && s->session && s->session->tlsext_tick)
             ticklen = s->session->tlsext_ticklen;
         else if (s->session && s->tlsext_session_ticket &&
@@ -1418,11 +1426,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * Check for enough room 2 for extension type, 2 for len rest for
          * ticket
          */
-        if ((long)(limit - ret - 4 - ticklen) < 0)
+        if (CHECKLEN(ret, 4 + ticklen, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(ticklen, ret);
-        if (ticklen) {
+        if (ticklen > 0) {
             memcpy(ret, s->session->tlsext_tick, ticklen);
             ret += ticklen;
         }
@@ -1433,7 +1441,14 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
         size_t salglen;
         const unsigned char *salg;
         salglen = tls12_get_psigalgs(s, &salg);
-        if ((size_t)(limit - ret) < salglen + 6)
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the sigalgs type and extension length
+         * 2 bytes for the sigalg list length
+         * + sigalg list length
+         */
+        if (CHECKLEN(ret, salglen + 6, limit))
             return NULL;
         s2n(TLSEXT_TYPE_signature_algorithms, ret);
         s2n(salglen + 2, ret);
@@ -1460,30 +1475,42 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
         int i;
-        long extlen, idlen, itmp;
+        size_t extlen, idlen;
+        int lentmp;
         OCSP_RESPID *id;
 
         idlen = 0;
         for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            itmp = i2d_OCSP_RESPID(id, NULL);
-            if (itmp <= 0)
+            lentmp = i2d_OCSP_RESPID(id, NULL);
+            if (lentmp <= 0)
                 return NULL;
-            idlen += itmp + 2;
+            idlen += (size_t)lentmp + 2;
         }
 
         if (s->tlsext_ocsp_exts) {
-            extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
-            if (extlen < 0)
+            lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+            if (lentmp < 0)
                 return NULL;
+            extlen = (size_t)lentmp;
         } else
             extlen = 0;
 
-        if ((long)(limit - ret - 7 - extlen - idlen) < 0)
-            return NULL;
-        s2n(TLSEXT_TYPE_status_request, ret);
         if (extlen + idlen > 0xFFF0)
             return NULL;
+        /*
+         * 2 bytes for status request type
+         * 2 bytes for status request len
+         * 1 byte for OCSP request type
+         * 2 bytes for length of ids
+         * 2 bytes for length of extensions
+         * + length of ids
+         * + length of extensions
+         */
+        if (CHECKLEN(ret, 9 + idlen + extlen, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_status_request, ret);
         s2n(extlen + idlen + 5, ret);
         *(ret++) = TLSEXT_STATUSTYPE_ocsp;
         s2n(idlen, ret);
@@ -1493,9 +1520,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
             /* skip over id len */
             ret += 2;
-            itmp = i2d_OCSP_RESPID(id, &ret);
+            lentmp = i2d_OCSP_RESPID(id, &ret);
             /* write id len */
-            s2n(itmp, q);
+            s2n(lentmp, q);
         }
         s2n(extlen, ret);
         if (extlen > 0)
@@ -1503,8 +1530,15 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension */
-    if ((limit - ret - 4 - 1) < 0)
+
+    /*-
+     * check for enough space.
+     * 4 bytes for the heartbeat ext type and extension length
+     * 1 byte for the mode
+     */
+    if (CHECKLEN(ret, 5, limit))
         return NULL;
+
     s2n(TLSEXT_TYPE_heartbeat, ret);
     s2n(1, ret);
     /*-
@@ -1524,7 +1558,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
          * The client advertises an emtpy extension to indicate its support
          * for Next Protocol Negotiation
          */
-        if (limit - ret - 4 < 0)
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the NPN ext type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_next_proto_neg, ret);
         s2n(0, ret);
@@ -1532,7 +1571,13 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 # endif
 
     if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
-        if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for the ALPN protocol list length
+         * + ALPN protocol list length
+         */
+        if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(2 + s->alpn_client_proto_list_len, ret);
@@ -1547,7 +1592,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
 
         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP type and extension length
+         * + SRTP profiles length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1587,6 +1637,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
             else
                 hlen = 0;
 
+            /*-
+             * check for enough space. Strictly speaking we know we've already
+             * got enough space because to get here the message size is < 0x200,
+             * but we know that we've allocated far more than that in the buffer
+             * - but for consistency and robustness we're going to check anyway.
+             *
+             * 4 bytes for the padding type and extension length
+             * + padding length
+             */
+            if (CHECKLEN(ret, 4 + hlen, limit))
+                return NULL;
             s2n(TLSEXT_TYPE_padding, ret);
             s2n(hlen, ret);
             memset(ret, 0, hlen);
@@ -1644,7 +1705,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             return NULL;
         }
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the reneg type and extension length
+         * + reneg data length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_renegotiate, ret);
@@ -1664,19 +1730,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
         /*
          * Add TLS extension ECPointFormats to the ServerHello message
          */
-        long lenmax;
 
         tls1_get_formatlist(s, &plist, &plistlen);
 
-        if ((lenmax = limit - ret - 5) < 0)
-            return NULL;
-        if (plistlen > (size_t)lenmax)
-            return NULL;
         if (plistlen > 255) {
             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
 
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec points format type and extension length
+         * 1 byte for the points format list length
+         * + length of points format list
+         */
+        if (CHECKLEN(ret, 5 + plistlen, limit))
+            return NULL;
+
         s2n(TLSEXT_TYPE_ec_point_formats, ret);
         s2n(plistlen + 1, ret);
         *(ret++) = (unsigned char)plistlen;
@@ -1691,14 +1761,22 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 # endif                         /* OPENSSL_NO_EC */
 
     if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
-        if ((long)(limit - ret - 4) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Ticket type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_session_ticket, ret);
         s2n(0, ret);
     }
 
     if (s->tlsext_status_expected) {
-        if ((long)(limit - ret - 4) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Status request type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
             return NULL;
         s2n(TLSEXT_TYPE_status_request, ret);
         s2n(0, ret);
@@ -1726,7 +1804,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 
         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
 
-        if ((limit - ret - 4 - el) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP profiles type and extension length
+         * + length of the SRTP profiles list
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1751,16 +1834,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
             0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
             0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
         };
-        if (limit - ret < 36)
+
+        /* check for enough space. */
+        if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
             return NULL;
-        memcpy(ret, cryptopro_ext, 36);
-        ret += 36;
+        memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
+        ret += sizeof(cryptopro_ext);
 
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension if we've received one */
     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
-        if ((limit - ret - 4 - 1) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the Heartbeat type and extension length
+         * 1 byte for the mode
+         */
+        if (CHECKLEN(ret, 5, limit))
             return NULL;
         s2n(TLSEXT_TYPE_heartbeat, ret);
         s2n(1, ret);
@@ -1789,7 +1879,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
                                               s->
                                               ctx->next_protos_advertised_cb_arg);
         if (r == SSL_TLSEXT_ERR_OK) {
-            if ((long)(limit - ret - 4 - npalen) < 0)
+            /*-
+             * check for enough space.
+             * 4 bytes for the NPN type and extension length
+             * + length of protocols list
+             */
+            if (CHECKLEN(ret, 4 + npalen, limit))
                 return NULL;
             s2n(TLSEXT_TYPE_next_proto_neg, ret);
             s2n(npalen, ret);
@@ -1804,9 +1899,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
 
     if (s->s3->alpn_selected) {
         const unsigned char *selected = s->s3->alpn_selected;
-        unsigned len = s->s3->alpn_selected_len;
+        size_t len = s->s3->alpn_selected_len;
 
-        if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for ALPN data length
+         * 1 byte for selected protocol length
+         * + length of the selected protocol
+         */
+        if (CHECKLEN(ret, 7 + len, limit))
             return NULL;
         s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
         s2n(3 + len, ret);
@@ -1966,11 +2068,10 @@ static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
 
 /*
  * Process the ALPN extension in a ClientHello.
- * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_*
  * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on failure: al/ret set only on failure
+ * returns 1 on success, 0 on failure: al set only on failure
  */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
 {
     const unsigned char *selected = NULL;
     unsigned char selected_len = 0;
@@ -1986,7 +2087,6 @@ static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
             s->s3->alpn_selected = OPENSSL_malloc(selected_len);
             if (s->s3->alpn_selected == NULL) {
                 *al = SSL_AD_INTERNAL_ERROR;
-                *ret = SSL_TLSEXT_ERR_ALERT_FATAL;
                 return 0;
             }
             memcpy(s->s3->alpn_selected, selected, selected_len);
@@ -3064,10 +3164,12 @@ int tls1_set_server_sigalgs(SSL *s)
     return 0;
 }
 
-int ssl_check_clienthello_tlsext_late(SSL *s)
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
 {
-    int ret = SSL_TLSEXT_ERR_OK;
-    int al;
 
     /*
      * If status request then ask callback what to do. Note: this must be
@@ -3076,58 +3178,41 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
      * influence which certificate is sent
      */
     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
-        int r;
+        int ret;
         CERT_PKEY *certpkey;
         certpkey = ssl_get_server_send_pkey(s);
         /* If no certificate can't return certificate status */
-        if (certpkey == NULL) {
-            s->tlsext_status_expected = 0;
-            return 1;
-        }
-        /*
-         * Set current certificate to one we will use so SSL_get_certificate
-         * et al can pick it up.
-         */
-        s->cert->key = certpkey;
-        r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-        switch (r) {
-            /* We don't want to send a status request response */
-        case SSL_TLSEXT_ERR_NOACK:
-            s->tlsext_status_expected = 0;
-            break;
-            /* status request response should be sent */
-        case SSL_TLSEXT_ERR_OK:
-            if (s->tlsext_ocsp_resp)
-                s->tlsext_status_expected = 1;
-            else
+        if (certpkey != NULL) {
+            /*
+             * Set current certificate to one we will use so SSL_get_certificate
+             * et al can pick it up.
+             */
+            s->cert->key = certpkey;
+            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+            switch (ret) {
+                /* We don't want to send a status request response */
+            case SSL_TLSEXT_ERR_NOACK:
                 s->tlsext_status_expected = 0;
-            break;
-            /* something bad happened */
-        case SSL_TLSEXT_ERR_ALERT_FATAL:
-            ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-            al = SSL_AD_INTERNAL_ERROR;
-            goto err;
+                break;
+                /* status request response should be sent */
+            case SSL_TLSEXT_ERR_OK:
+                if (s->tlsext_ocsp_resp)
+                    s->tlsext_status_expected = 1;
+                break;
+                /* something bad happened */
+            case SSL_TLSEXT_ERR_ALERT_FATAL:
+            default:
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
         }
-    } else
-        s->tlsext_status_expected = 0;
-
-    if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) {
-        goto err;
     }
 
- err:
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    default:
-        return 1;
+    if (!tls1_alpn_handle_client_hello_late(s, al)) {
+        return 0;
     }
+
+    return 1;
 }
 
 int ssl_check_serverhello_tlsext(SSL *s)