diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-09 14:02:09 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:38 +0200 |
commit | bb80d9df8bac71eedee1a6787ca63aef972a7e48 (patch) | |
tree | 1b5cb9443c5ead5706c35afb618abbbd1592315e /freebsd/crypto | |
parent | Update to FreeBSD head 2017-10-01 (diff) | |
download | rtems-libbsd-bb80d9df8bac71eedee1a6787ca63aef972a7e48.tar.bz2 |
Update to FreeBSD head 2017-12-01
Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266.
Update #3472.
Diffstat (limited to 'freebsd/crypto')
59 files changed, 847 insertions, 261 deletions
diff --git a/freebsd/crypto/openssl/crypto/asn1/a_bitstr.c b/freebsd/crypto/openssl/crypto/asn1/a_bitstr.c index a98bb9b9..deb4cb53 100644 --- a/freebsd/crypto/openssl/crypto/asn1/a_bitstr.c +++ b/freebsd/crypto/openssl/crypto/asn1/a_bitstr.c @@ -58,6 +58,7 @@ * [including the GNU Public Licence.] */ +#include <limits.h> #include <stdio.h> #include "cryptlib.h" #include <openssl/asn1.h> @@ -138,6 +139,11 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, goto err; } + if (len > INT_MAX) { + i = ASN1_R_STRING_TOO_LONG; + goto err; + } + if ((a == NULL) || ((*a) == NULL)) { if ((ret = M_ASN1_BIT_STRING_new()) == NULL) return (NULL); diff --git a/freebsd/crypto/openssl/crypto/asn1/asn1_int.h b/freebsd/crypto/openssl/crypto/asn1/asn1_int.h new file mode 100644 index 00000000..c9fd8b12 --- /dev/null +++ b/freebsd/crypto/openssl/crypto/asn1/asn1_int.h @@ -0,0 +1,63 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Internal ASN1 template structures and functions: not for application use */ + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); diff --git a/freebsd/crypto/openssl/crypto/asn1/tasn_fre.c b/freebsd/crypto/openssl/crypto/asn1/tasn_fre.c index b298dceb..e734f2d5 100644 --- a/freebsd/crypto/openssl/crypto/asn1/tasn_fre.c +++ b/freebsd/crypto/openssl/crypto/asn1/tasn_fre.c @@ -63,9 +63,7 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/objects.h> - -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); +#include "asn1_int.h" /* Free up an ASN1 structure */ @@ -79,8 +77,7 @@ void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) asn1_item_combine_free(pval, it, 0); } -static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) { const ASN1_TEMPLATE *tt = NULL, *seqtt; const ASN1_EXTERN_FUNCS *ef; diff --git a/freebsd/crypto/openssl/crypto/asn1/tasn_new.c b/freebsd/crypto/openssl/crypto/asn1/tasn_new.c index 96f8cc87..3e0f792c 100644 --- a/freebsd/crypto/openssl/crypto/asn1/tasn_new.c +++ b/freebsd/crypto/openssl/crypto/asn1/tasn_new.c @@ -65,6 +65,7 @@ #include <openssl/err.h> #include <openssl/asn1t.h> #include <string.h> +#include "asn1_int.h" static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); @@ -201,7 +202,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 1; memerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); memerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); #ifdef CRYPTO_MDEBUG @@ -211,7 +212,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; auxerr2: - ASN1_item_ex_free(pval, it); + asn1_item_combine_free(pval, it, combine); auxerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); #ifdef CRYPTO_MDEBUG diff --git a/freebsd/crypto/openssl/crypto/asn1/x_name.c b/freebsd/crypto/openssl/crypto/asn1/x_name.c index d0460b34..258a05ad 100644 --- a/freebsd/crypto/openssl/crypto/asn1/x_name.c +++ b/freebsd/crypto/openssl/crypto/asn1/x_name.c @@ -525,19 +525,11 @@ static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, int X509_NAME_set(X509_NAME **xn, X509_NAME *name) { - X509_NAME *in; - - if (!xn || !name) - return (0); - - if (*xn != name) { - in = X509_NAME_dup(name); - if (in != NULL) { - X509_NAME_free(*xn); - *xn = in; - } - } - return (*xn != NULL); + if ((name = X509_NAME_dup(name)) == NULL) + return 0; + X509_NAME_free(*xn); + *xn = name; + return 1; } IMPLEMENT_STACK_OF(X509_NAME_ENTRY) diff --git a/freebsd/crypto/openssl/crypto/asn1/x_pkey.c b/freebsd/crypto/openssl/crypto/asn1/x_pkey.c index 75ebc078..a3765035 100644 --- a/freebsd/crypto/openssl/crypto/asn1/x_pkey.c +++ b/freebsd/crypto/openssl/crypto/asn1/x_pkey.c @@ -108,10 +108,14 @@ X509_PKEY *X509_PKEY_new(void) X509_PKEY *ret = NULL; ASN1_CTX c; - M_ASN1_New_Malloc(ret, X509_PKEY); + ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + c.line = __LINE__; + goto err; + } ret->version = 0; - M_ASN1_New(ret->enc_algor, X509_ALGOR_new); - M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new); + ret->enc_algor = X509_ALGOR_new(); + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); ret->dec_pkey = NULL; ret->key_length = 0; ret->key_data = NULL; @@ -119,8 +123,15 @@ X509_PKEY *X509_PKEY_new(void) ret->cipher.cipher = NULL; memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); ret->references = 1; - return (ret); - M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW); + if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { + c.line = __LINE__; + goto err; + } + return ret; +err: + X509_PKEY_free(ret); + ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE, c.line); + return NULL; } void X509_PKEY_free(X509_PKEY *x) diff --git a/freebsd/crypto/openssl/crypto/bn/bn_exp.c b/freebsd/crypto/openssl/crypto/bn/bn_exp.c index ff7592cb..7c1ea0a4 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_exp.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_exp.c @@ -147,7 +147,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int i, bits, ret = 0; BIGNUM *v, *rr; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -247,7 +248,9 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { # ifdef MONT_EXP_WORD if (a->top == 1 && !a->neg - && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { BN_ULONG A = a->d[0]; ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); } else @@ -279,7 +282,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -413,7 +418,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_MONT_CTX *mont = NULL; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); } @@ -1219,7 +1226,8 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; @@ -1350,7 +1358,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* Table of variables obtained from 'ctx' */ BIGNUM *val[TABLE_SIZE]; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return -1; diff --git a/freebsd/crypto/openssl/crypto/bn/bn_lib.c b/freebsd/crypto/openssl/crypto/bn/bn_lib.c index 10679fbd..da58a91a 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_lib.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_lib.c @@ -526,6 +526,9 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); #endif + if (BN_get_flags(b, BN_FLG_CONSTTIME) != 0) + BN_set_flags(a, BN_FLG_CONSTTIME); + a->top = b->top; a->neg = b->neg; bn_check_top(a); diff --git a/freebsd/crypto/openssl/crypto/bn/bn_mont.c b/freebsd/crypto/openssl/crypto/bn/bn_mont.c index a9c001f7..ddf25f5c 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_mont.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_mont.c @@ -396,6 +396,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) tmod.dmax = 2; tmod.neg = 0; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(&tmod, BN_FLG_CONSTTIME); + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) diff --git a/freebsd/crypto/openssl/crypto/bn/bn_mul.c b/freebsd/crypto/openssl/crypto/bn/bn_mul.c index ac45a788..2cd04c19 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_mul.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_mul.c @@ -1034,46 +1034,6 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) rr->top = top; goto end; } -# if 0 - if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)b; - if (bn_wexpand(tmp_bn, al) == NULL) - goto err; - tmp_bn->d[bl] = 0; - bl++; - i--; - } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { - BIGNUM *tmp_bn = (BIGNUM *)a; - if (bn_wexpand(tmp_bn, bl) == NULL) - goto err; - tmp_bn->d[al] = 0; - al++; - i++; - } - if (i == 0) { - /* symmetric and > 4 */ - /* 16 or larger */ - j = BN_num_bits_word((BN_ULONG)al); - j = 1 << (j - 1); - k = j + j; - t = BN_CTX_get(ctx); - if (al == j) { /* exact multiple */ - if (bn_wexpand(t, k * 2) == NULL) - goto err; - if (bn_wexpand(rr, k * 2) == NULL) - goto err; - bn_mul_recursive(rr->d, a->d, b->d, al, t->d); - } else { - if (bn_wexpand(t, k * 4) == NULL) - goto err; - if (bn_wexpand(rr, k * 4) == NULL) - goto err; - bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); - } - rr->top = top; - goto end; - } -# endif } #endif /* BN_RECURSION */ if (bn_wexpand(rr, top) == NULL) diff --git a/freebsd/crypto/openssl/crypto/bn/bn_x931p.c b/freebsd/crypto/openssl/crypto/bn/bn_x931p.c index b8971d20..4e081b2f 100644 --- a/freebsd/crypto/openssl/crypto/bn/bn_x931p.c +++ b/freebsd/crypto/openssl/crypto/bn/bn_x931p.c @@ -219,6 +219,8 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) BN_CTX_start(ctx); t = BN_CTX_get(ctx); + if (t == NULL) + goto err; for (i = 0; i < 1000; i++) { if (!BN_rand(Xq, nbits, 1, 0)) @@ -257,10 +259,12 @@ int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, int ret = 0; BN_CTX_start(ctx); - if (!Xp1) + if (Xp1 == NULL) Xp1 = BN_CTX_get(ctx); - if (!Xp2) + if (Xp2 == NULL) Xp2 = BN_CTX_get(ctx); + if (Xp1 == NULL || Xp2 == NULL) + goto error; if (!BN_rand(Xp1, 101, 0, 0)) goto error; diff --git a/freebsd/crypto/openssl/crypto/cryptlib.c b/freebsd/crypto/openssl/crypto/cryptlib.c index a204ad4b..8445beb9 100644 --- a/freebsd/crypto/openssl/crypto/cryptlib.c +++ b/freebsd/crypto/openssl/crypto/cryptlib.c @@ -471,11 +471,18 @@ void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) } } +#ifdef OPENSSL_FIPS +extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *)); +#endif + int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) { if (threadid_callback) return 0; threadid_callback = func; +#ifdef OPENSSL_FIPS + FIPS_crypto_threadid_set_callback(func); +#endif return 1; } diff --git a/freebsd/crypto/openssl/crypto/dh/dh.h b/freebsd/crypto/openssl/crypto/dh/dh.h index a228c7a7..80b28fb3 100644 --- a/freebsd/crypto/openssl/crypto/dh/dh.h +++ b/freebsd/crypto/openssl/crypto/dh/dh.h @@ -257,11 +257,13 @@ DH *DH_get_1024_160(void); DH *DH_get_2048_224(void); DH *DH_get_2048_256(void); +# ifndef OPENSSL_NO_CMS /* RFC2631 KDF */ int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif # define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ diff --git a/freebsd/crypto/openssl/crypto/dh/dh_kdf.c b/freebsd/crypto/openssl/crypto/dh/dh_kdf.c index b44aaeba..10a7b61d 100644 --- a/freebsd/crypto/openssl/crypto/dh/dh_kdf.c +++ b/freebsd/crypto/openssl/crypto/dh/dh_kdf.c @@ -53,6 +53,9 @@ * ==================================================================== */ +#include <e_os.h> + +#ifndef OPENSSL_NO_CMS #include <string.h> #include <openssl/dh.h> #include <openssl/evp.h> @@ -187,3 +190,4 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, EVP_MD_CTX_cleanup(&mctx); return rv; } +#endif diff --git a/freebsd/crypto/openssl/crypto/dh/dh_pmeth.c b/freebsd/crypto/openssl/crypto/dh/dh_pmeth.c index 34d7dc88..fe5684ce 100644 --- a/freebsd/crypto/openssl/crypto/dh/dh_pmeth.c +++ b/freebsd/crypto/openssl/crypto/dh/dh_pmeth.c @@ -209,7 +209,11 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; +#ifdef OPENSSL_NO_CMS + if (p1 != EVP_PKEY_DH_KDF_NONE) +#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) +#endif return -2; dctx->kdf_type = p1; return 1; @@ -450,7 +454,9 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, return ret; *keylen = ret; return 1; - } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { + } +#ifndef OPENSSL_NO_CMS + else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; size_t Zlen = 0; if (!dctx->kdf_outlen || !dctx->kdf_oid) @@ -481,6 +487,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, } return ret; } +#endif return 1; } diff --git a/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c b/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c index c5f642f3..3da90130 100644 --- a/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c +++ b/freebsd/crypto/openssl/crypto/dsa/dsa_ameth.c @@ -260,6 +260,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) goto dsaerr; } + BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); goto dsaerr; diff --git a/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c b/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c index a130c7be..cdca6fcc 100644 --- a/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c +++ b/freebsd/crypto/openssl/crypto/dsa/dsa_gen.c @@ -484,6 +484,8 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, } else { p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); + if (q == NULL) + goto err; } if (!BN_lshift(test, BN_value_one(), L - 1)) diff --git a/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c index 5207d8f2..715511c2 100644 --- a/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c +++ b/freebsd/crypto/openssl/crypto/dsa/dsa_ossl.c @@ -226,7 +226,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, { BN_CTX *ctx; BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; + BIGNUM l, m; int ret = 0; + int q_bits; if (!dsa->p || !dsa->q || !dsa->g) { DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); @@ -235,6 +237,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_init(&k); BN_init(&kq); + BN_init(&l); + BN_init(&m); if (ctx_in == NULL) { if ((ctx = BN_CTX_new()) == NULL) @@ -245,6 +249,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if ((r = BN_new()) == NULL) goto err; + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q); + if (!BN_set_bit(&k, q_bits) + || !BN_set_bit(&l, q_bits) + || !BN_set_bit(&m, q_bits)) + goto err; + /* Get random k */ do if (!BN_rand_range(&k, dsa->q)) @@ -265,24 +276,23 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, /* Compute r = (g^k mod p) mod q */ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - if (!BN_copy(&kq, &k)) - goto err; - - BN_set_flags(&kq, BN_FLG_CONSTTIME); - /* * We do not want timing information to leak the length of k, so we - * compute g^k using an equivalent exponent of fixed length. (This - * is a kludge that we need because the BN_mod_exp_mont() does not - * let us specify the desired timing behaviour.) + * compute G^k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(&kq, &kq, dsa->q)) + if (!BN_add(&l, &k, dsa->q) + || !BN_add(&m, &l, dsa->q) + || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) goto err; - if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { - if (!BN_add(&kq, &kq, dsa->q)) - goto err; - } + + BN_set_flags(&kq, BN_FLG_CONSTTIME); K = &kq; } else { @@ -316,7 +326,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BN_CTX_free(ctx); BN_clear_free(&k); BN_clear_free(&kq); - return (ret); + BN_clear_free(&l); + BN_clear_free(&m); + return ret; } static int dsa_do_verify(const unsigned char *dgst, int dgst_len, diff --git a/freebsd/crypto/openssl/crypto/ec/ecp_mont.c b/freebsd/crypto/openssl/crypto/ec/ecp_mont.c index 22acc3d1..f3524e2c 100644 --- a/freebsd/crypto/openssl/crypto/ec/ecp_mont.c +++ b/freebsd/crypto/openssl/crypto/ec/ecp_mont.c @@ -249,6 +249,8 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, BN_CTX_free(new_ctx); if (mont != NULL) BN_MONT_CTX_free(mont); + if (one != NULL) + BN_free(one); return ret; } diff --git a/freebsd/crypto/openssl/crypto/ec/ecp_nistp224.c b/freebsd/crypto/openssl/crypto/ec/ecp_nistp224.c index d40f611b..aba7ff6d 100644 --- a/freebsd/crypto/openssl/crypto/ec/ecp_nistp224.c +++ b/freebsd/crypto/openssl/crypto/ec/ecp_nistp224.c @@ -718,7 +718,7 @@ static limb felem_is_zero(const felem in) return (zero | two224m96p1 | two225m97p2); } -static limb felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1393,7 +1393,6 @@ static void make_points_affine(size_t num, felem points[ /* num */ ][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/freebsd/crypto/openssl/crypto/ec/ecp_nistp256.c b/freebsd/crypto/openssl/crypto/ec/ecp_nistp256.c index adf1a459..c34288fc 100644 --- a/freebsd/crypto/openssl/crypto/ec/ecp_nistp256.c +++ b/freebsd/crypto/openssl/crypto/ec/ecp_nistp256.c @@ -979,7 +979,7 @@ static limb smallfelem_is_zero(const smallfelem small) return result; } -static int smallfelem_is_zero_int(const smallfelem small) +static int smallfelem_is_zero_int(const void *small) { return (int)(smallfelem_is_zero(small) & ((limb) 1)); } @@ -1981,7 +1981,6 @@ static void make_points_affine(size_t num, smallfelem points[][3], sizeof(smallfelem), tmp_smallfelems, (void (*)(void *))smallfelem_one, - (int (*)(const void *)) smallfelem_is_zero_int, (void (*)(void *, const void *)) smallfelem_assign, diff --git a/freebsd/crypto/openssl/crypto/ec/ecp_nistp521.c b/freebsd/crypto/openssl/crypto/ec/ecp_nistp521.c index 8e28ecd7..3d83b2d7 100644 --- a/freebsd/crypto/openssl/crypto/ec/ecp_nistp521.c +++ b/freebsd/crypto/openssl/crypto/ec/ecp_nistp521.c @@ -873,7 +873,7 @@ static limb felem_is_zero(const felem in) return is_zero; } -static int felem_is_zero_int(const felem in) +static int felem_is_zero_int(const void *in) { return (int)(felem_is_zero(in) & ((limb) 1)); } @@ -1789,7 +1789,6 @@ static void make_points_affine(size_t num, felem points[][3], sizeof(felem), tmp_felems, (void (*)(void *))felem_one, - (int (*)(const void *)) felem_is_zero_int, (void (*)(void *, const void *)) felem_assign, diff --git a/freebsd/crypto/openssl/crypto/ecdh/ech_lib.c b/freebsd/crypto/openssl/crypto/ecdh/ech_lib.c index 3bf95415..4bf047a6 100644 --- a/freebsd/crypto/openssl/crypto/ecdh/ech_lib.c +++ b/freebsd/crypto/openssl/crypto/ecdh/ech_lib.c @@ -227,9 +227,16 @@ ECDH_DATA *ecdh_check(EC_KEY *key) */ ecdh_data_free(ecdh_data); ecdh_data = (ECDH_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, + ecdh_data_free) != ecdh_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdh_data_free(ecdh_data); + return NULL; } - } else + } else { ecdh_data = (ECDH_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/freebsd/crypto/openssl/crypto/ecdsa/ecs_lib.c b/freebsd/crypto/openssl/crypto/ecdsa/ecs_lib.c index b97747d9..d6ae2c01 100644 --- a/freebsd/crypto/openssl/crypto/ecdsa/ecs_lib.c +++ b/freebsd/crypto/openssl/crypto/ecdsa/ecs_lib.c @@ -205,9 +205,16 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key) */ ecdsa_data_free(ecdsa_data); ecdsa_data = (ECDSA_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, + ecdsa_data_free) != ecdsa_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdsa_data_free(ecdsa_data); + return NULL; } - } else + } else { ecdsa_data = (ECDSA_DATA *)data; + } #ifdef OPENSSL_FIPS if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { diff --git a/freebsd/crypto/openssl/crypto/ecdsa/ecs_ossl.c b/freebsd/crypto/openssl/crypto/ecdsa/ecs_ossl.c index 786ff794..ccc1d30a 100644 --- a/freebsd/crypto/openssl/crypto/ecdsa/ecs_ossl.c +++ b/freebsd/crypto/openssl/crypto/ecdsa/ecs_ossl.c @@ -97,6 +97,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, EC_POINT *tmp_point = NULL; const EC_GROUP *group; int ret = 0; + int order_bits; if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); @@ -128,6 +129,13 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, goto err; } + /* Preallocate space */ + order_bits = BN_num_bits(order); + if (!BN_set_bit(k, order_bits) + || !BN_set_bit(r, order_bits) + || !BN_set_bit(X, order_bits)) + goto err; + do { /* get random k */ do @@ -141,13 +149,19 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, /* * We do not want timing information to leak the length of k, so we * compute G*k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the order. This guarantees the code + * path used in the constant time implementations elsewhere. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. */ - - if (!BN_add(k, k, order)) + if (!BN_add(r, k, order) + || !BN_add(X, r, order) + || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) goto err; - if (BN_num_bits(k) <= BN_num_bits(order)) - if (!BN_add(k, k, order)) - goto err; /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { diff --git a/freebsd/crypto/openssl/crypto/err/err.c b/freebsd/crypto/openssl/crypto/err/err.c index d4be17cd..326a1670 100644 --- a/freebsd/crypto/openssl/crypto/err/err.c +++ b/freebsd/crypto/openssl/crypto/err/err.c @@ -727,6 +727,8 @@ void ERR_put_error(int lib, int func, int reason, const char *file, int line) } #endif es = ERR_get_state(); + if (es == NULL) + return; es->top = (es->top + 1) % ERR_NUM_ERRORS; if (es->top == es->bottom) @@ -744,6 +746,8 @@ void ERR_clear_error(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return; for (i = 0; i < ERR_NUM_ERRORS; i++) { err_clear(es, i); @@ -808,6 +812,8 @@ static unsigned long get_error_values(int inc, int top, const char **file, unsigned long ret; es = ERR_get_state(); + if (es == NULL) + return 0; if (inc && top) { if (file) @@ -1018,7 +1024,6 @@ void ERR_remove_state(unsigned long pid) ERR_STATE *ERR_get_state(void) { - static ERR_STATE fallback; ERR_STATE *ret, tmp, *tmpp = NULL; int i; CRYPTO_THREADID tid; @@ -1032,7 +1037,7 @@ ERR_STATE *ERR_get_state(void) if (ret == NULL) { ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); if (ret == NULL) - return (&fallback); + return NULL; CRYPTO_THREADID_cpy(&ret->tid, &tid); ret->top = 0; ret->bottom = 0; @@ -1044,7 +1049,7 @@ ERR_STATE *ERR_get_state(void) /* To check if insertion failed, do a get. */ if (ERRFN(thread_get_item) (ret) != ret) { ERR_STATE_free(ret); /* could not insert it */ - return (&fallback); + return NULL; } /* * If a race occured in this function and we came second, tmpp is the @@ -1068,10 +1073,10 @@ void ERR_set_error_data(char *data, int flags) int i; es = ERR_get_state(); + if (es == NULL) + return; i = es->top; - if (i == 0) - i = ERR_NUM_ERRORS - 1; err_clear_data(es, i); es->err_data[i] = data; @@ -1123,6 +1128,8 @@ int ERR_set_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; if (es->bottom == es->top) return 0; @@ -1135,6 +1142,8 @@ int ERR_pop_to_mark(void) ERR_STATE *es; es = ERR_get_state(); + if (es == NULL) + return 0; while (es->bottom != es->top && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { diff --git a/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c index 2aaf8a62..90be1fb0 100644 --- a/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -581,12 +581,17 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c index 1a683da2..49e41a4c 100644 --- a/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/freebsd/crypto/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -509,10 +509,12 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, * to identify it and avoid stitch invocation. So that after we * establish that current CPU supports AVX, we even see if it's * either even XOP-capable Bulldozer-based or GenuineIntel one. + * But SHAEXT-capable go ahead... */ - if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */ - ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ - | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */ + if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */ + ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */ + ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ + | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */ plen > (sha_off + iv) && (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) { SHA256_Update(&key->md, in + iv, sha_off); @@ -592,12 +594,17 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= 255; - ret &= constant_time_ge(maxpad, pad); + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1); - mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); - inp_len &= mask; - ret &= (int)mask; key->aux.tls_aad[plen - 2] = inp_len >> 8; key->aux.tls_aad[plen - 1] = inp_len; diff --git a/freebsd/crypto/openssl/crypto/evp/evp.h b/freebsd/crypto/openssl/crypto/evp/evp.h index d258ef87..cf1de15e 100644 --- a/freebsd/crypto/openssl/crypto/evp/evp.h +++ b/freebsd/crypto/openssl/crypto/evp/evp.h @@ -1363,6 +1363,98 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, const char *type, const char *value)); +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + void EVP_add_alg_module(void); /* BEGIN ERROR CODES */ diff --git a/freebsd/crypto/openssl/crypto/evp/evp_key.c b/freebsd/crypto/openssl/crypto/evp/evp_key.c index 083f4638..9544f496 100644 --- a/freebsd/crypto/openssl/crypto/evp/evp_key.c +++ b/freebsd/crypto/openssl/crypto/evp/evp_key.c @@ -99,7 +99,7 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int verify) { - int ret; + int ret = -1; char buff[BUFSIZ]; UI *ui; @@ -107,16 +107,18 @@ int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, prompt = prompt_string; ui = UI_new(); if (ui == NULL) - return -1; - UI_add_input_string(ui, prompt, 0, buf, min, - (len >= BUFSIZ) ? BUFSIZ - 1 : len); - if (verify) - UI_add_verify_string(ui, prompt, 0, - buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len, - buf); + return ret; + if (UI_add_input_string(ui, prompt, 0, buf, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 + || (verify + && UI_add_verify_string(ui, prompt, 0, buff, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len, + buf) < 0)) + goto end; ret = UI_process(ui); - UI_free(ui); OPENSSL_cleanse(buff, BUFSIZ); + end: + UI_free(ui); return ret; } diff --git a/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c b/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c index 5b170cf2..78cbc4d3 100644 --- a/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c +++ b/freebsd/crypto/openssl/crypto/evp/pmeth_lib.c @@ -591,3 +591,170 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl = ctrl; pmeth->ctrl_str = ctrl_str; } + +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)) +{ + *pinit = pmeth->init; +} + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + *pcopy = pmeth->copy; +} + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)) +{ + *pcleanup = pmeth->cleanup; +} + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pparamgen_init) + *pparamgen_init = pmeth->paramgen_init; + if (pparamgen) + *pparamgen = pmeth->paramgen; +} + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pkeygen_init) + *pkeygen_init = pmeth->keygen_init; + if (pkeygen) + *pkeygen = pmeth->keygen; +} + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (psign_init) + *psign_init = pmeth->sign_init; + if (psign) + *psign = pmeth->sign; +} + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (pverify_init) + *pverify_init = pmeth->verify_init; + if (pverify) + *pverify = pmeth->verify; +} + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + if (pverify_recover_init) + *pverify_recover_init = pmeth->verify_recover_init; + if (pverify_recover) + *pverify_recover = pmeth->verify_recover; +} + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + if (psignctx_init) + *psignctx_init = pmeth->signctx_init; + if (psignctx) + *psignctx = pmeth->signctx; +} + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + if (pverifyctx_init) + *pverifyctx_init = pmeth->verifyctx_init; + if (pverifyctx) + *pverifyctx = pmeth->verifyctx; +} + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pencrypt_init) + *pencrypt_init = pmeth->encrypt_init; + if (pencryptfn) + *pencryptfn = pmeth->encrypt; +} + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pdecrypt_init) + *pdecrypt_init = pmeth->decrypt_init; + if (pdecrypt) + *pdecrypt = pmeth->decrypt; +} + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + if (pderive_init) + *pderive_init = pmeth->derive_init; + if (pderive) + *pderive = pmeth->derive; +} + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + if (pctrl) + *pctrl = pmeth->ctrl; + if (pctrl_str) + *pctrl_str = pmeth->ctrl_str; +} diff --git a/freebsd/crypto/openssl/crypto/ex_data.c b/freebsd/crypto/openssl/crypto/ex_data.c index f0e2fd50..631a48b9 100644 --- a/freebsd/crypto/openssl/crypto/ex_data.c +++ b/freebsd/crypto/openssl/crypto/ex_data.c @@ -475,7 +475,14 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (j < mx) mx = j; if (mx > 0) { - if (!CRYPTO_set_ex_data(to, mx - 1, NULL)) + /* + * Make sure the ex_data stack is at least |mx| elements long to avoid + * issues in the for loop that follows; so go get the |mx|'th element + * (if it does not exist CRYPTO_get_ex_data() returns NULL), and assign + * to itself. This is normally a no-op; but ensures the stack is the + * proper size + */ + if (!CRYPTO_set_ex_data(to, mx - 1, CRYPTO_get_ex_data(to, mx - 1))) goto skip; storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); if (!storage) diff --git a/freebsd/crypto/openssl/crypto/lhash/lhash.c b/freebsd/crypto/openssl/crypto/lhash/lhash.c index 5bd72269..1e7194e3 100644 --- a/freebsd/crypto/openssl/crypto/lhash/lhash.c +++ b/freebsd/crypto/openssl/crypto/lhash/lhash.c @@ -103,6 +103,24 @@ #include <openssl/crypto.h> #include <openssl/lhash.h> +/* + * A hashing implementation that appears to be based on the linear hashing + * alogrithm: + * https://en.wikipedia.org/wiki/Linear_hashing + * + * Litwin, Witold (1980), "Linear hashing: A new tool for file and table + * addressing", Proc. 6th Conference on Very Large Databases: 212–223 + * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf + * + * From the wikipedia article "Linear hashing is used in the BDB Berkeley + * database system, which in turn is used by many software systems such as + * OpenLDAP, using a C implementation derived from the CACM article and first + * published on the Usenet in 1988 by Esmond Pitt." + * + * The CACM paper is available here: + * https://pdfs.semanticscholar.org/ff4d/1c5deca6269cc316bfd952172284dbf610ee.pdf + */ + const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #undef MIN_NODES @@ -110,7 +128,7 @@ const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ -static void expand(_LHASH *lh); +static int expand(_LHASH *lh); static void contract(_LHASH *lh); static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); @@ -184,8 +202,9 @@ void *lh_insert(_LHASH *lh, void *data) void *ret; lh->error = 0; - if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) - expand(lh); + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes) + && !expand(lh)) + return NULL; rn = getrn(lh, data, &hash); @@ -302,19 +321,37 @@ void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); } -static void expand(_LHASH *lh) +static int expand(_LHASH *lh) { LHASH_NODE **n, **n1, **n2, *np; - unsigned int p, i, j; - unsigned long hash, nni; + unsigned int p, pmax, nni, j; + unsigned long hash; + + nni = lh->num_alloc_nodes; + p = lh->p; + pmax = lh->pmax; + if (p + 1 >= pmax) { + j = nni * 2; + n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); + if (n == NULL) { + lh->error++; + return 0; + } + lh->b = n; + memset(n + nni, 0, sizeof(*n) * (j - nni)); + lh->pmax = nni; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + } else { + lh->p++; + } lh->num_nodes++; lh->num_expands++; - p = (int)lh->p++; n1 = &(lh->b[p]); - n2 = &(lh->b[p + (int)lh->pmax]); - *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ - nni = lh->num_alloc_nodes; + n2 = &(lh->b[p + pmax]); + *n2 = NULL; for (np = *n1; np != NULL;) { #ifndef OPENSSL_NO_HASH_COMP @@ -332,25 +369,7 @@ static void expand(_LHASH *lh) np = *n1; } - if ((lh->p) >= lh->pmax) { - j = (int)lh->num_alloc_nodes * 2; - n = (LHASH_NODE **)OPENSSL_realloc(lh->b, - (int)(sizeof(LHASH_NODE *) * j)); - if (n == NULL) { - lh->error++; - lh->num_nodes--; - lh->p = 0; - return; - } - /* else */ - for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */ - n[i] = NULL; /* 02/03/92 eay */ - lh->pmax = lh->num_alloc_nodes; - lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; - lh->p = 0; - lh->b = n; - } + return 1; } static void contract(_LHASH *lh) diff --git a/freebsd/crypto/openssl/crypto/ocsp/ocsp_vfy.c b/freebsd/crypto/openssl/crypto/ocsp/ocsp_vfy.c index 1105f574..23ffe63c 100644 --- a/freebsd/crypto/openssl/crypto/ocsp/ocsp_vfy.c +++ b/freebsd/crypto/openssl/crypto/ocsp/ocsp_vfy.c @@ -120,6 +120,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, goto end; } } + } else if (certs != NULL) { + untrusted = certs; } else { untrusted = bs->certs; } diff --git a/freebsd/crypto/openssl/crypto/opensslv.h b/freebsd/crypto/openssl/crypto/opensslv.h index 9eae57ca..83867763 100644 --- a/freebsd/crypto/openssl/crypto/opensslv.h +++ b/freebsd/crypto/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x100020cfL +# define OPENSSL_VERSION_NUMBER 0x100020dfL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-fips 2 Nov 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-freebsd 25 May 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2m-freebsd 2 Nov 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/freebsd/crypto/openssl/crypto/pem/pem_lib.c b/freebsd/crypto/openssl/crypto/pem/pem_lib.c index 36f4d7eb..877f6424 100644 --- a/freebsd/crypto/openssl/crypto/pem/pem_lib.c +++ b/freebsd/crypto/openssl/crypto/pem/pem_lib.c @@ -538,7 +538,8 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) ((c >= '0') && (c <= '9')))) break; #else - if (!(isupper(c) || (c == '-') || isdigit(c))) + if (!(isupper((unsigned char)c) || (c == '-') + || isdigit((unsigned char)c))) break; #endif header++; diff --git a/freebsd/crypto/openssl/crypto/pem/pem_pk8.c b/freebsd/crypto/openssl/crypto/pem/pem_pk8.c index c7cd0997..f0e375c8 100644 --- a/freebsd/crypto/openssl/crypto/pem/pem_pk8.c +++ b/freebsd/crypto/openssl/crypto/pem/pem_pk8.c @@ -180,6 +180,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) return NULL; ret = EVP_PKCS82PKEY(p8inf); diff --git a/freebsd/crypto/openssl/crypto/pem/pem_pkey.c b/freebsd/crypto/openssl/crypto/pem/pem_pkey.c index 7384b8e2..839e7bf6 100644 --- a/freebsd/crypto/openssl/crypto/pem/pem_pkey.c +++ b/freebsd/crypto/openssl/crypto/pem/pem_pkey.c @@ -122,6 +122,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, } p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); if (!p8inf) goto p8err; ret = EVP_PKCS82PKEY(p8inf); diff --git a/freebsd/crypto/openssl/crypto/pkcs12/p12_kiss.c b/freebsd/crypto/openssl/crypto/pkcs12/p12_kiss.c index 7245322d..27cd87e1 100644 --- a/freebsd/crypto/openssl/crypto/pkcs12/p12_kiss.c +++ b/freebsd/crypto/openssl/crypto/pkcs12/p12_kiss.c @@ -86,6 +86,12 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, { STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; + + if (pkey) + *pkey = NULL; + if (cert) + *cert = NULL; + /* Check for NULL PKCS12 structure */ if (!p12) { @@ -94,11 +100,6 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, return 0; } - if (pkey) - *pkey = NULL; - if (cert) - *cert = NULL; - /* Check the mac */ /* @@ -127,7 +128,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, if (!ocerts) { PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { @@ -165,10 +166,14 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, err: - if (pkey && *pkey) + if (pkey) { EVP_PKEY_free(*pkey); - if (cert && *cert) + *pkey = NULL; + } + if (cert) { X509_free(*cert); + *cert = NULL; + } if (x) X509_free(x); if (ocerts) diff --git a/freebsd/crypto/openssl/crypto/rsa/rsa_ameth.c b/freebsd/crypto/openssl/crypto/rsa/rsa_ameth.c index 59335b6f..bf4713bf 100644 --- a/freebsd/crypto/openssl/crypto/rsa/rsa_ameth.c +++ b/freebsd/crypto/openssl/crypto/rsa/rsa_ameth.c @@ -770,6 +770,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } +#ifndef OPENSSL_NO_CMS static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash) { @@ -793,7 +794,6 @@ static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, return pss; } -#ifndef OPENSSL_NO_CMS static int rsa_cms_decrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pkctx; diff --git a/freebsd/crypto/openssl/crypto/rsa/rsa_oaep.c b/freebsd/crypto/openssl/crypto/rsa/rsa_oaep.c index a50e0f39..b4f1aa59 100644 --- a/freebsd/crypto/openssl/crypto/rsa/rsa_oaep.c +++ b/freebsd/crypto/openssl/crypto/rsa/rsa_oaep.c @@ -239,10 +239,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR); cleanup: - if (db != NULL) + if (db != NULL) { + OPENSSL_cleanse(db, dblen); OPENSSL_free(db); - if (em != NULL) + } + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } return mlen; } diff --git a/freebsd/crypto/openssl/crypto/rsa/rsa_pk1.c b/freebsd/crypto/openssl/crypto/rsa/rsa_pk1.c index f4b568a6..0dd288b1 100644 --- a/freebsd/crypto/openssl/crypto/rsa/rsa_pk1.c +++ b/freebsd/crypto/openssl/crypto/rsa/rsa_pk1.c @@ -257,8 +257,6 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, * We can't continue in constant-time because we need to copy the result * and we cannot fake its length. This unavoidably leaks timing * information at the API boundary. - * TODO(emilia): this could be addressed at the call site, - * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. */ if (!good) { mlen = -1; @@ -268,8 +266,10 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, memcpy(to, em + msg_index, mlen); err: - if (em != NULL) + if (em != NULL) { + OPENSSL_cleanse(em, num); OPENSSL_free(em); + } if (mlen == -1) RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); diff --git a/freebsd/crypto/openssl/crypto/rsa/rsa_pmeth.c b/freebsd/crypto/openssl/crypto/rsa/rsa_pmeth.c index 1d50e6c9..902b7008 100644 --- a/freebsd/crypto/openssl/crypto/rsa/rsa_pmeth.c +++ b/freebsd/crypto/openssl/crypto/rsa/rsa_pmeth.c @@ -182,27 +182,25 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) * FIPS mode. */ -static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) +static int pkey_fips_check_rsa(const RSA *rsa, const EVP_MD **pmd, + const EVP_MD **pmgf1md) { - RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; int rv = -1; + if (!FIPS_mode()) return 0; if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) rv = 0; if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) return -1; - if (rctx->md) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmd != NULL) { + *pmd = FIPS_get_digestbynid(EVP_MD_type(*pmd)); + if (*pmd == NULL || !((*pmd)->flags & EVP_MD_FLAG_FIPS)) return rv; } - if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) { - const EVP_MD *fmd; - fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md)); - if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + if (*pmgf1md != NULL) { + *pmgf1md = FIPS_get_digestbynid(EVP_MD_type(*pmgf1md)); + if (*pmgf1md == NULL || !((*pmgf1md)->flags & EVP_MD_FLAG_FIPS)) return rv; } return 1; @@ -216,27 +214,27 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; #ifdef OPENSSL_FIPS - ret = pkey_fips_check_ctx(ctx); + ret = pkey_fips_check_rsa(rsa, &md, &mgf1md); if (ret < 0) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (md != NULL) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } #ifdef OPENSSL_FIPS if (ret > 0) { unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, &slen); + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, &slen); if (ret > 0) *siglen = slen; else @@ -245,12 +243,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, } #endif - if (EVP_MD_type(rctx->md) == NID_mdc2) { + if (EVP_MD_type(md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; - ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, + rsa); if (ret <= 0) return ret; @@ -265,23 +263,20 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, return -1; } memcpy(rctx->tbuf, tbs, tbslen); - rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; - ret = RSA_sign(EVP_MD_type(rctx->md), - tbs, tbslen, sig, &sltmp, rsa); + ret = RSA_sign(EVP_MD_type(md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; - if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, - rctx->tbuf, tbs, - rctx->md, rctx->mgf1md, - rctx->saltlen)) + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, + md, mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); @@ -350,32 +345,31 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; size_t rslen; + #ifdef OPENSSL_FIPS - int rv; - rv = pkey_fips_check_ctx(ctx); + int rv = pkey_fips_check_rsa(rsa, &md, &mgf1md); + if (rv < 0) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif - if (rctx->md) { + if (md != NULL) { #ifdef OPENSSL_FIPS if (rv > 0) { - return FIPS_rsa_verify_digest(rsa, - tbs, tbslen, - rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, siglen); + return FIPS_rsa_verify_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, siglen); } #endif if (rctx->pad_mode == RSA_PKCS1_PADDING) - return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + return RSA_verify(EVP_MD_type(md), tbs, tbslen, sig, siglen, rsa); - if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + if (tbslen != (size_t)EVP_MD_size(md)) { RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); return -1; } @@ -390,8 +384,7 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, rsa, RSA_NO_PADDING); if (ret <= 0) return 0; - ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, - rctx->md, rctx->mgf1md, + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, md, mgf1md, rctx->tbuf, rctx->saltlen); if (ret <= 0) return 0; diff --git a/freebsd/crypto/openssl/crypto/ui/ui_lib.c b/freebsd/crypto/openssl/crypto/ui/ui_lib.c index 6b5ee5dd..a967246c 100644 --- a/freebsd/crypto/openssl/crypto/ui/ui_lib.c +++ b/freebsd/crypto/openssl/crypto/ui/ui_lib.c @@ -522,6 +522,7 @@ int UI_process(UI *ui) } } } + err: if (ui->meth->ui_close_session != NULL && ui->meth->ui_close_session(ui) <= 0) diff --git a/freebsd/crypto/openssl/crypto/whrlpool/wp_dgst.c b/freebsd/crypto/openssl/crypto/whrlpool/wp_dgst.c index a9b33867..0da00640 100644 --- a/freebsd/crypto/openssl/crypto/whrlpool/wp_dgst.c +++ b/freebsd/crypto/openssl/crypto/whrlpool/wp_dgst.c @@ -168,7 +168,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) goto reconsider; } else #endif - if (bits >= 8) { + if (bits > 8) { b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); b &= 0xff; if (bitrem) @@ -185,7 +185,7 @@ void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) } if (bitrem) c->data[byteoff] = b << (8 - bitrem); - } else { /* remaining less than 8 bits */ + } else { /* remaining less than or equal to 8 bits */ b = (inp[0] << inpgap) & 0xff; if (bitrem) diff --git a/freebsd/crypto/openssl/crypto/x509/by_dir.c b/freebsd/crypto/openssl/crypto/x509/by_dir.c index a93bbc99..d6fb51e0 100644 --- a/freebsd/crypto/openssl/crypto/x509/by_dir.c +++ b/freebsd/crypto/openssl/crypto/x509/by_dir.c @@ -404,6 +404,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, if (!hent) { hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); if (hent == NULL) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); goto finish; } diff --git a/freebsd/crypto/openssl/crypto/x509/by_file.c b/freebsd/crypto/openssl/crypto/x509/by_file.c index f6b4b96b..f795f1cb 100644 --- a/freebsd/crypto/openssl/crypto/x509/by_file.c +++ b/freebsd/crypto/openssl/crypto/x509/by_file.c @@ -94,12 +94,12 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) { int ok = 0; - char *file; + const char *file; switch (cmd) { case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = (char *)getenv(X509_get_default_cert_file_env()); + file = getenv(X509_get_default_cert_file_env()); if (file) ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); @@ -142,7 +142,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -201,7 +201,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { @@ -255,7 +255,7 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); BIO_free(in); if (!inf) { X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); diff --git a/freebsd/crypto/openssl/crypto/x509v3/pcy_tree.c b/freebsd/crypto/openssl/crypto/x509v3/pcy_tree.c index 2efe5621..31661ed4 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/pcy_tree.c +++ b/freebsd/crypto/openssl/crypto/x509v3/pcy_tree.c @@ -734,6 +734,7 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) { int ret; + int calc_ret; X509_POLICY_TREE *tree = NULL; STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; *ptree = NULL; @@ -802,17 +803,20 @@ int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, /* Tree is not empty: continue */ - ret = tree_calculate_authority_set(tree, &auth_nodes); + calc_ret = tree_calculate_authority_set(tree, &auth_nodes); - if (!ret) + if (!calc_ret) goto error; - if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) - goto error; + ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); - if (ret == 2) + if (calc_ret == 2) sk_X509_POLICY_NODE_free(auth_nodes); + if (!ret) + goto error; + + if (tree) *ptree = tree; diff --git a/freebsd/crypto/openssl/crypto/x509v3/v3_addr.c b/freebsd/crypto/openssl/crypto/x509v3/v3_addr.c index f40b7ceb..cbf6ef30 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/v3_addr.c +++ b/freebsd/crypto/openssl/crypto/x509v3/v3_addr.c @@ -132,10 +132,12 @@ static int length_from_afi(const unsigned afi) */ unsigned int v3_addr_get_afi(const IPAddressFamily *f) { - return ((f != NULL && - f->addressFamily != NULL && f->addressFamily->data != NULL) - ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) - : 0); + if (f == NULL + || f->addressFamily == NULL + || f->addressFamily->data == NULL + || f->addressFamily->length < 2) + return 0; + return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; } /* diff --git a/freebsd/crypto/openssl/crypto/x509v3/v3_genn.c b/freebsd/crypto/openssl/crypto/x509v3/v3_genn.c index 5d0a23a4..b6e2f409 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/v3_genn.c +++ b/freebsd/crypto/openssl/crypto/x509v3/v3_genn.c @@ -233,6 +233,7 @@ int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, oth = OTHERNAME_new(); if (!oth) return 0; + ASN1_TYPE_free(oth->value); oth->type_id = oid; oth->value = value; GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); diff --git a/freebsd/crypto/openssl/crypto/x509v3/v3_ncons.c b/freebsd/crypto/openssl/crypto/x509v3/v3_ncons.c index 41a77067..006c2009 100644 --- a/freebsd/crypto/openssl/crypto/x509v3/v3_ncons.c +++ b/freebsd/crypto/openssl/crypto/x509v3/v3_ncons.c @@ -109,6 +109,47 @@ ASN1_SEQUENCE(NAME_CONSTRAINTS) = { IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) +/* + * We cannot use strncasecmp here because that applies locale specific rules. + * For example in Turkish 'I' is not the uppercase character for 'i'. We need to + * do a simple ASCII case comparison ignoring the locale (that is why we use + * numeric constants below). + */ +static int ia5ncasecmp(const char *s1, const char *s2, size_t n) +{ + for (; n > 0; n--, s1++, s2++) { + if (*s1 != *s2) { + unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2; + + /* Convert to lower case */ + if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */) + c1 += 0x20; + if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */) + c2 += 0x20; + + if (c1 == c2) + continue; + + if (c1 < c2) + return -1; + + /* c1 > c2 */ + return 1; + } else if (*s1 == 0) { + /* If we get here we know that *s2 == 0 too */ + return 0; + } + } + + return 0; +} + +static int ia5casecmp(const char *s1, const char *s2) +{ + /* No portable definition of SIZE_MAX, so we use (size_t)(-1) instead */ + return ia5ncasecmp(s1, s2, (size_t)(-1)); +} + static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { @@ -386,7 +427,7 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) return X509_V_ERR_PERMITTED_VIOLATION; } - if (strcasecmp(baseptr, dnsptr)) + if (ia5casecmp(baseptr, dnsptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -406,7 +447,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) if (!baseat && (*baseptr == '.')) { if (eml->length > base->length) { emlptr += eml->length - base->length; - if (!strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; @@ -427,7 +468,7 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) } emlptr = emlat + 1; /* Just have hostname left to match: case insensitive */ - if (strcasecmp(baseptr, emlptr)) + if (ia5casecmp(baseptr, emlptr)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; @@ -466,14 +507,14 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) if (*baseptr == '.') { if (hostlen > base->length) { p = hostptr + hostlen - base->length; - if (!strncasecmp(p, baseptr, base->length)) + if (ia5ncasecmp(p, baseptr, base->length) == 0) return X509_V_OK; } return X509_V_ERR_PERMITTED_VIOLATION; } if ((base->length != (int)hostlen) - || strncasecmp(hostptr, baseptr, hostlen)) + || ia5ncasecmp(hostptr, baseptr, hostlen)) return X509_V_ERR_PERMITTED_VIOLATION; return X509_V_OK; diff --git a/freebsd/crypto/openssl/ssl/s23_clnt.c b/freebsd/crypto/openssl/ssl/s23_clnt.c index 4a7d7a39..197ae215 100644 --- a/freebsd/crypto/openssl/ssl/s23_clnt.c +++ b/freebsd/crypto/openssl/ssl/s23_clnt.c @@ -737,7 +737,35 @@ static int ssl23_get_server_hello(SSL *s) s->version = TLS1_2_VERSION; s->method = TLSv1_2_client_method(); } else { + /* + * Unrecognised version, we'll send a protocol version alert using + * our preferred version. + */ + switch(s->client_version) { + default: + /* + * Shouldn't happen + * Fall through + */ + case TLS1_2_VERSION: + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_client_method(); + break; + case TLS1_1_VERSION: + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_client_method(); + break; + case TLS1_VERSION: + s->version = TLS1_VERSION; + s->method = TLSv1_client_method(); + break; + case SSL3_VERSION: + s->version = SSL3_VERSION; + s->method = SSLv3_client_method(); + break; + } SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); goto err; } diff --git a/freebsd/crypto/openssl/ssl/s3_pkt.c b/freebsd/crypto/openssl/ssl/s3_pkt.c index 77225b8b..679517f2 100644 --- a/freebsd/crypto/openssl/ssl/s3_pkt.c +++ b/freebsd/crypto/openssl/ssl/s3_pkt.c @@ -1429,7 +1429,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) (s->s3->handshake_fragment_len >= 4) && (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && (s->session != NULL) && (s->session->cipher != NULL) && - !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { /* * s->s3->handshake_fragment_len = 0; */ diff --git a/freebsd/crypto/openssl/ssl/s3_srvr.c b/freebsd/crypto/openssl/ssl/s3_srvr.c index 6bba7dfc..6162941b 100644 --- a/freebsd/crypto/openssl/ssl/s3_srvr.c +++ b/freebsd/crypto/openssl/ssl/s3_srvr.c @@ -2204,7 +2204,7 @@ int ssl3_get_client_key_exchange(SSL *s) unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; int decrypt_len; unsigned char decrypt_good, version_good; - size_t j; + size_t j, padding_len; /* FIX THIS UP EAY EAY EAY EAY */ if (s->s3->tmp.use_rsa_tmp) { @@ -2272,16 +2272,38 @@ int ssl3_get_client_key_exchange(SSL *s) if (RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret)) <= 0) goto err; + + /* + * Decrypt with no padding. PKCS#1 padding will be removed as part of + * the timing-sensitive code below. + */ decrypt_len = - RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); - ERR_clear_error(); + RSA_private_decrypt((int)n, p, p, rsa, RSA_NO_PADDING); + if (decrypt_len < 0) + goto err; + + /* Check the padding. See RFC 3447, section 7.2.2. */ /* - * decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. decrypt_good will - * be 0xff if so and zero otherwise. + * The smallest padded premaster is 11 bytes of overhead. Small keys + * are publicly invalid, so this may return immediately. This ensures + * PS is at least 8 bytes. */ - decrypt_good = - constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH); + if (decrypt_len < 11 + SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto f_err; + } + + padding_len = decrypt_len - SSL_MAX_MASTER_KEY_LENGTH; + decrypt_good = constant_time_eq_int_8(p[0], 0) & + constant_time_eq_int_8(p[1], 2); + for (j = 2; j < padding_len - 1; j++) { + decrypt_good &= ~constant_time_is_zero_8(p[j]); + } + decrypt_good &= constant_time_is_zero_8(p[padding_len - 1]); + p += padding_len; /* * If the version in the decrypted pre-master secret is correct then diff --git a/freebsd/crypto/openssl/ssl/ssl_ciph.c b/freebsd/crypto/openssl/ssl/ssl_ciph.c index 3649ed69..2591b69b 100644 --- a/freebsd/crypto/openssl/ssl/ssl_ciph.c +++ b/freebsd/crypto/openssl/ssl/ssl_ciph.c @@ -1207,7 +1207,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) #else - while (isalnum(ch) || (ch == '-') || (ch == '.')) + while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.')) #endif { ch = *(++l); diff --git a/freebsd/crypto/openssl/ssl/ssl_lib.c b/freebsd/crypto/openssl/ssl/ssl_lib.c index 54b831ea..43e3f76b 100644 --- a/freebsd/crypto/openssl/ssl/ssl_lib.c +++ b/freebsd/crypto/openssl/ssl/ssl_lib.c @@ -1827,15 +1827,15 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const char *label, size_t llen, - const unsigned char *p, size_t plen, + const unsigned char *context, size_t contextlen, int use_context) { if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, - llen, p, plen, - use_context); + llen, context, + contextlen, use_context); } static unsigned long ssl_session_hash(const SSL_SESSION *a) @@ -3182,6 +3182,7 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) #endif ssl->cert = ssl_cert_dup(ctx->cert); if (ocert) { + int i; /* Preserve any already negotiated parameters */ if (ssl->server) { ssl->cert->peer_sigalgs = ocert->peer_sigalgs; @@ -3191,6 +3192,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; ocert->ciphers_raw = NULL; } + for (i = 0; i < SSL_PKEY_NUM; i++) { + ssl->cert->pkeys[i].digest = ocert->pkeys[i].digest; + } #ifndef OPENSSL_NO_TLSEXT ssl->cert->alpn_proposed = ocert->alpn_proposed; ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; diff --git a/freebsd/crypto/openssl/ssl/ssl_sess.c b/freebsd/crypto/openssl/ssl/ssl_sess.c index 8fd8c79c..fbded359 100644 --- a/freebsd/crypto/openssl/ssl/ssl_sess.c +++ b/freebsd/crypto/openssl/ssl/ssl_sess.c @@ -263,7 +263,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) #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; @@ -277,6 +276,9 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) if (src->peer != NULL) CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) + goto err; + #ifndef OPENSSL_NO_PSK if (src->psk_identity_hint) { dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); @@ -327,7 +329,7 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) } # endif - if (ticket != 0) { + if (ticket != 0 && src->tlsext_tick != NULL) { dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); if(dest->tlsext_tick == NULL) goto err; diff --git a/freebsd/crypto/openssl/ssl/ssltest.c b/freebsd/crypto/openssl/ssl/ssltest.c index c05929c0..5eafe9e3 100644 --- a/freebsd/crypto/openssl/ssl/ssltest.c +++ b/freebsd/crypto/openssl/ssl/ssltest.c @@ -317,6 +317,9 @@ static int s_ticket1 = 0; static int s_ticket2 = 0; static int c_ticket = 0; static int ticket_expect = -1; +static int sni_in_cert_cb = 0; +static const char *client_sigalgs = NULL; +static const char *server_digest_expect = NULL; static int servername_cb(SSL *s, int *ad, void *arg) { @@ -357,6 +360,11 @@ static int verify_servername(SSL *client, SSL *server) BIO_printf(bio_stdout, "Servername: context is unknown\n"); return -1; } +static int cert_cb(SSL *ssl, void *arg) +{ + int unused; + return servername_cb(ssl, &unused, NULL) != SSL_TLSEXT_ERR_ALERT_FATAL; +} static int verify_ticket(SSL* ssl) { @@ -373,6 +381,20 @@ static int verify_ticket(SSL* ssl) return -1; } +static int verify_server_digest(SSL* ssl) +{ + int nid = NID_undef; + + if (server_digest_expect == NULL) + return 0; + SSL_get_peer_signature_nid(ssl, &nid); + if (strcmp(server_digest_expect, OBJ_nid2sn(nid)) == 0) + return 1; + BIO_printf(bio_stdout, "Expected server digest %s, got %s.\n", + server_digest_expect, OBJ_nid2sn(nid)); + return -1; +} + /*- * next_protos_parse parses a comma separated list of strings into a string * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. @@ -833,6 +855,7 @@ static void sv_usage(void) #endif #ifndef OPENSSL_NO_TLS1 fprintf(stderr, " -tls1 - use TLSv1\n"); + fprintf(stderr, " -tls12 - use TLSv1.2\n"); #endif #ifndef OPENSSL_NO_DTLS fprintf(stderr, " -dtls1 - use DTLSv1\n"); @@ -886,6 +909,9 @@ static void sv_usage(void) fprintf(stderr, " -c_ticket <yes|no> - enable/disable session tickets on the client\n"); fprintf(stderr, " -ticket_expect <yes|no> - indicate that the client should (or should not) have a ticket\n"); #endif + fprintf(stderr, " -sni_in_cert_cb - have the server handle SNI in the certificate callback\n"); + fprintf(stderr, " -client_sigalgs arg - the signature algorithms to configure on the client\n"); + fprintf(stderr, " -server_digest_expect arg - the expected server signing digest\n"); } static void print_details(SSL *c_ssl, const char *prefix) @@ -1012,7 +1038,7 @@ int main(int argc, char *argv[]) int badop = 0; int bio_pair = 0; int force = 0; - int dtls1 = 0, dtls12 = 0, tls1 = 0, ssl2 = 0, ssl3 = 0, ret = 1; + int dtls1 = 0, dtls12 = 0, tls1 = 0, tls12 = 0, ssl2 = 0, ssl3 = 0, ret = 1; int client_auth = 0; int server_auth = 0, i; struct app_verify_arg app_verify_arg = @@ -1166,6 +1192,11 @@ int main(int argc, char *argv[]) no_protocol = 1; #endif tls1 = 1; + } else if (strcmp(*argv, "-tls12") == 0) { +#ifdef OPENSSL_NO_TLS1 + no_protocol = 1; +#endif + tls12 = 1; } else if (strcmp(*argv, "-ssl3") == 0) { #ifdef OPENSSL_NO_SSL3_METHOD no_protocol = 1; @@ -1345,6 +1376,16 @@ int main(int argc, char *argv[]) else if (strcmp(*argv, "no") == 0) ticket_expect = 0; #endif + } else if (strcmp(*argv, "-sni_in_cert_cb") == 0) { + sni_in_cert_cb = 1; + } else if (strcmp(*argv, "-client_sigalgs") == 0) { + if (--argc < 1) + goto bad; + client_sigalgs = *(++argv); + } else if (strcmp(*argv, "-server_digest_expect") == 0) { + if (--argc < 1) + goto bad; + server_digest_expect = *(++argv); } else { fprintf(stderr, "unknown option %s\n", *argv); badop = 1; @@ -1375,9 +1416,9 @@ int main(int argc, char *argv[]) goto end; } - if (ssl2 + ssl3 + tls1 + dtls1 + dtls12 > 1) { - fprintf(stderr, "At most one of -ssl2, -ssl3, -tls1, -dtls1 or -dtls12 should " - "be requested.\n"); + if (ssl2 + ssl3 + tls1 + tls12 + dtls1 + dtls12 > 1) { + fprintf(stderr, "At most one of -ssl2, -ssl3, -tls1, -tls12, -dtls1 or " + "-dtls12 should be requested.\n"); EXIT(1); } @@ -1393,10 +1434,11 @@ int main(int argc, char *argv[]) goto end; } - if (!ssl2 && !ssl3 && !tls1 && !dtls1 && !dtls12 && number > 1 && !reuse && !force) { + if (!ssl2 && !ssl3 && !tls1 && !tls12 && !dtls1 && !dtls12 && number > 1 + && !reuse && !force) { fprintf(stderr, "This case cannot work. Use -f to perform " "the test anyway (and\n-d to see what happens), " - "or add one of ssl2, -ssl3, -tls1, -dtls1, -dtls12, -reuse\n" + "or add one of ssl2, -ssl3, -tls1, -tls12, -dtls1, -dtls12, -reuse\n" "to avoid protocol mismatch.\n"); EXIT(1); } @@ -1460,7 +1502,7 @@ int main(int argc, char *argv[]) #endif /* - * At this point, ssl2/ssl3/tls1 is only set if the protocol is + * At this point, ssl2/ssl3/tls1/tls12 is only set if the protocol is * available. (Otherwise we exit early.) However the compiler doesn't * know this, so we ifdef. */ @@ -1484,6 +1526,8 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_TLS1 if (tls1) meth = TLSv1_method(); + else if (tls12) + meth = TLSv1_2_method(); else #endif meth = SSLv23_method(); @@ -1780,8 +1824,12 @@ int main(int argc, char *argv[]) OPENSSL_free(alpn); } - if (sn_server1 || sn_server2) - SSL_CTX_set_tlsext_servername_callback(s_ctx, servername_cb); + if (sn_server1 || sn_server2) { + if (sni_in_cert_cb) + SSL_CTX_set_cert_cb(s_ctx, cert_cb, NULL); + else + SSL_CTX_set_tlsext_servername_callback(s_ctx, servername_cb); + } #ifndef OPENSSL_NO_TLSEXT if (s_ticket1 == 0) @@ -1801,6 +1849,9 @@ int main(int argc, char *argv[]) SSL_CTX_set_options(c_ctx, SSL_OP_NO_TICKET); #endif + if (client_sigalgs != NULL) + SSL_CTX_set1_sigalgs_list(c_ctx, client_sigalgs); + c_ssl = SSL_new(c_ctx); s_ssl = SSL_new(s_ctx); @@ -1866,6 +1917,8 @@ int main(int argc, char *argv[]) ret = 1; if (verify_ticket(c_ssl) < 0) ret = 1; + if (verify_server_digest(c_ssl) < 0) + ret = 1; SSL_free(s_ssl); SSL_free(c_ssl); diff --git a/freebsd/crypto/openssl/ssl/tls1.h b/freebsd/crypto/openssl/ssl/tls1.h index 7e237d06..dd1d8c10 100644 --- a/freebsd/crypto/openssl/ssl/tls1.h +++ b/freebsd/crypto/openssl/ssl/tls1.h @@ -317,7 +317,7 @@ int SSL_get_servername_type(const SSL *s); */ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const char *label, size_t llen, - const unsigned char *p, size_t plen, + const unsigned char *context, size_t contextlen, int use_context); int SSL_get_sigalgs(SSL *s, int idx, |