Index: crypto/openssl/apps/dhparam.c =================================================================== --- crypto/openssl/apps/dhparam.c (revision 284286) +++ crypto/openssl/apps/dhparam.c (working copy) @@ -130,7 +130,7 @@ #undef PROG #define PROG dhparam_main -#define DEFBITS 512 +#define DEFBITS 2048 /* -inform arg - input format - default PEM (DER or PEM) * -outform arg - output format - default PEM @@ -253,7 +253,7 @@ bad: BIO_printf(bio_err," -C Output C code\n"); BIO_printf(bio_err," -2 generate parameters using 2 as the generator value\n"); BIO_printf(bio_err," -5 generate parameters using 5 as the generator value\n"); - BIO_printf(bio_err," numbits number of bits in to generate (default 512)\n"); + BIO_printf(bio_err," numbits number of bits in to generate (default 2048)\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif Index: crypto/openssl/apps/gendh.c =================================================================== --- crypto/openssl/apps/gendh.c (revision 284286) +++ crypto/openssl/apps/gendh.c (working copy) @@ -78,7 +78,7 @@ #include #include -#define DEFBITS 512 +#define DEFBITS 2048 #undef PROG #define PROG gendh_main Index: crypto/openssl/apps/s_server.c =================================================================== --- crypto/openssl/apps/s_server.c (revision 284286) +++ crypto/openssl/apps/s_server.c (working copy) @@ -214,7 +214,7 @@ static int generate_session_id(const SSL *ssl, uns unsigned int *id_len); #ifndef OPENSSL_NO_DH static DH *load_dh_param(const char *dhfile); -static DH *get_dh512(void); +static DH *get_dh2048(void); #endif #ifdef MONOLITH @@ -222,29 +222,49 @@ static void s_server_init(void); #endif #ifndef OPENSSL_NO_DH -static unsigned char dh512_p[]={ - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, - }; -static unsigned char dh512_g[]={ +static unsigned char dh2048_p[] = { + 0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6, + 0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1, + 0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9, + 0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD, + 0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17, + 0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F, + 0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD, + 0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30, + 0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E, + 0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4, + 0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58, + 0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B, + 0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C, + 0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B, + 0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD, + 0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C, + 0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C, + 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29, + 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B, + 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C, + 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55, + 0xE9,0x32,0x0B,0x3B, +}; + +static unsigned char dh2048_g[] = { 0x02, - }; +}; -static DH *get_dh512(void) - { - DH *dh=NULL; +DH *get_dh2048() +{ + DH *dh; - if ((dh=DH_new()) == NULL) return(NULL); - dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); - dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); - if ((dh->p == NULL) || (dh->g == NULL)) - return(NULL); - return(dh); + if ((dh = DH_new()) == NULL) + return NULL; + dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); + dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); + if (dh->p == NULL || dh->g == NULL) { + DH_free(dh); + return NULL; } + return dh; +} #endif @@ -1661,9 +1681,8 @@ bad: #endif #ifndef OPENSSL_NO_DH - if (!no_dhe) - { - DH *dh=NULL; + if (!no_dhe) { + DH *dh = NULL; if (dhfile) dh = load_dh_param(dhfile); @@ -1670,27 +1689,25 @@ bad: else if (s_cert_file) dh = load_dh_param(s_cert_file); - if (dh != NULL) - { - BIO_printf(bio_s_out,"Setting temp DH parameters\n"); + if (dh != NULL) { + BIO_printf(bio_s_out, "Setting temp DH parameters\n"); + } else { + BIO_printf(bio_s_out, "Using default temp DH parameters\n"); + dh = get_dh2048(); + if (dh == NULL) { + ERR_print_errors(bio_err); + goto end; } - else - { - BIO_printf(bio_s_out,"Using default temp DH parameters\n"); - dh=get_dh512(); } (void)BIO_flush(bio_s_out); - SSL_CTX_set_tmp_dh(ctx,dh); -#ifndef OPENSSL_NO_TLSEXT - if (ctx2) - { - if (!dhfile) - { - DH *dh2=load_dh_param(s_cert_file2); - if (dh2 != NULL) - { - BIO_printf(bio_s_out,"Setting temp DH parameters\n"); + SSL_CTX_set_tmp_dh(ctx, dh); +# ifndef OPENSSL_NO_TLSEXT + if (ctx2) { + if (!dhfile) { + DH *dh2 = load_dh_param(s_cert_file2); + if (dh2 != NULL) { + BIO_printf(bio_s_out, "Setting temp DH parameters\n"); (void)BIO_flush(bio_s_out); DH_free(dh); @@ -1697,9 +1714,9 @@ bad: dh = dh2; } } - SSL_CTX_set_tmp_dh(ctx2,dh); + SSL_CTX_set_tmp_dh(ctx2, dh); } -#endif +# endif DH_free(dh); } #endif Index: crypto/openssl/crypto/bio/bio_lib.c =================================================================== --- crypto/openssl/crypto/bio/bio_lib.c (revision 284286) +++ crypto/openssl/crypto/bio/bio_lib.c (working copy) @@ -543,8 +543,10 @@ BIO *BIO_dup_chain(BIO *in) /* copy app data */ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, - &bio->ex_data)) + &bio->ex_data)) { + BIO_free(new_bio); goto err; + } if (ret == NULL) { @@ -559,8 +561,8 @@ BIO *BIO_dup_chain(BIO *in) } return(ret); err: - if (ret != NULL) - BIO_free(ret); + BIO_free_all(ret); + return(NULL); } Index: crypto/openssl/crypto/bn/bn_gf2m.c =================================================================== --- crypto/openssl/crypto/bn/bn_gf2m.c (revision 284286) +++ crypto/openssl/crypto/bn/bn_gf2m.c (working copy) @@ -568,10 +568,11 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co } #else { - int i, ubits = BN_num_bits(u), - vbits = BN_num_bits(v), /* v is copy of p */ - top = p->top; - BN_ULONG *udp,*bdp,*vdp,*cdp; + int i; + int ubits = BN_num_bits(u); + int vbits = BN_num_bits(v); /* v is copy of p */ + int top = p->top; + BN_ULONG *udp, *bdp, *vdp, *cdp; bn_wexpand(u,top); udp = u->d; for (i=u->top;itop*BN_BYTES*2+2); + if (a->neg && BN_is_zero(a)) { + /* "-0" == 3 bytes including NULL terminator */ + buf = OPENSSL_malloc(3); + } else { + buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); + } if (buf == NULL) { BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE); Index: crypto/openssl/crypto/buffer/buffer.c =================================================================== --- crypto/openssl/crypto/buffer/buffer.c (revision 284286) +++ crypto/openssl/crypto/buffer/buffer.c (working copy) @@ -88,7 +88,7 @@ void BUF_MEM_free(BUF_MEM *a) if (a->data != NULL) { - memset(a->data,0,(unsigned int)a->max); + OPENSSL_cleanse(a->data, a->max); OPENSSL_free(a->data); } OPENSSL_free(a); Index: crypto/openssl/crypto/cms/cms_smime.c =================================================================== --- crypto/openssl/crypto/cms/cms_smime.c (revision 284286) +++ crypto/openssl/crypto/cms/cms_smime.c (working copy) @@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *upto) BIO_free(f); f = tbio; } - while (f != upto); + while (f && f != upto); } else BIO_free_all(f); Index: crypto/openssl/crypto/ec/ec2_oct.c =================================================================== --- crypto/openssl/crypto/ec/ec2_oct.c (revision 284286) +++ crypto/openssl/crypto/ec/ec2_oct.c (working copy) @@ -390,7 +390,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; } - if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); goto err; Index: crypto/openssl/crypto/ec/ec_check.c =================================================================== --- crypto/openssl/crypto/ec/ec_check.c (revision 284286) +++ crypto/openssl/crypto/ec/ec_check.c (working copy) @@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX * ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); goto err; } - if (!EC_POINT_is_on_curve(group, group->generator, ctx)) + if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); goto err; Index: crypto/openssl/crypto/ec/ec_key.c =================================================================== --- crypto/openssl/crypto/ec/ec_key.c (revision 284286) +++ crypto/openssl/crypto/ec/ec_key.c (working copy) @@ -326,7 +326,7 @@ int EC_KEY_check_key(const EC_KEY *eckey) goto err; /* testing whether the pub_key is on the elliptic curve */ - if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) + if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); goto err; Index: crypto/openssl/crypto/ec/ec_lib.c =================================================================== --- crypto/openssl/crypto/ec/ec_lib.c (revision 284286) +++ crypto/openssl/crypto/ec/ec_lib.c (working copy) @@ -972,7 +972,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, } -int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) +/* + * Check whether an EC_POINT is on the curve or not. Note that the return + * value for this function should NOT be treated as a boolean. Return values: + * 1: The point is on the curve + * 0: The point is not on the curve + * -1: An error occurred + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { if (group->meth->is_on_curve == 0) { Index: crypto/openssl/crypto/ec/ecp_oct.c =================================================================== --- crypto/openssl/crypto/ec/ecp_oct.c (revision 284286) +++ crypto/openssl/crypto/ec/ecp_oct.c (working copy) @@ -416,7 +416,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; } - if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); goto err; Index: crypto/openssl/crypto/ec/ectest.c =================================================================== --- crypto/openssl/crypto/ec/ectest.c (revision 284286) +++ crypto/openssl/crypto/ec/ectest.c (working copy) @@ -343,7 +343,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "D")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, Q, ctx)) + if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT; fprintf(stderr, "Point is not on curve: x = 0x"); @@ -439,7 +439,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT; if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT; if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT; if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; @@ -473,7 +473,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT; if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; @@ -507,7 +507,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT; if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; @@ -541,7 +541,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" "84F3B9CAC2FC632551")) ABORT; if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; @@ -580,7 +580,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; @@ -624,7 +624,7 @@ static void prime_field_tests(void) "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" "3C1856A429BF97E7E31C2E5BD66")) ABORT; if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" "C9B8899C47AEBB6FB71E91386409")) ABORT; @@ -657,7 +657,7 @@ static void prime_field_tests(void) if (!EC_POINT_copy(Q, P)) ABORT; if (EC_POINT_is_at_infinity(group, Q)) ABORT; if (!EC_POINT_dbl(group, P, P, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT; @@ -771,7 +771,7 @@ static void prime_field_tests(void) #define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ if (!BN_hex2bn(&x, _x)) ABORT; \ if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \ - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ if (!BN_hex2bn(&z, _order)) ABORT; \ if (!BN_hex2bn(&cof, _cof)) ABORT; \ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ @@ -789,7 +789,7 @@ static void prime_field_tests(void) if (!BN_hex2bn(&x, _x)) ABORT; \ if (!BN_hex2bn(&y, _y)) ABORT; \ if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ if (!BN_hex2bn(&z, _order)) ABORT; \ if (!BN_hex2bn(&cof, _cof)) ABORT; \ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ @@ -894,7 +894,7 @@ static void char2_field_tests(void) if (!BN_hex2bn(&y, "8")) ABORT; if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT; #endif - if (!EC_POINT_is_on_curve(group, Q, ctx)) + if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { /* Change test based on whether binary point compression is enabled or not. */ #ifdef OPENSSL_EC_BIN_PT_COMP @@ -1133,7 +1133,7 @@ static void char2_field_tests(void) if (!EC_POINT_copy(Q, P)) ABORT; if (EC_POINT_is_at_infinity(group, Q)) ABORT; if (!EC_POINT_dbl(group, P, P, ctx)) ABORT; - if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT; Index: crypto/openssl/crypto/evp/e_aes.c =================================================================== --- crypto/openssl/crypto/evp/e_aes.c (revision 284286) +++ crypto/openssl/crypto/evp/e_aes.c (working copy) @@ -50,6 +50,7 @@ #include #ifndef OPENSSL_NO_AES +#include #include #include #include @@ -967,7 +968,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); /* If tag mismatch wipe buffer */ - if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) + if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { OPENSSL_cleanse(out, len); goto err; @@ -1351,7 +1352,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, uns unsigned char tag[16]; if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { - if (!memcmp(tag, ctx->buf, cctx->M)) + if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) rv = len; } } Index: crypto/openssl/crypto/evp/e_rc4_hmac_md5.c =================================================================== --- crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (revision 284286) +++ crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (working copy) @@ -54,6 +54,7 @@ #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) +#include #include #include #include @@ -205,7 +206,7 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH); MD5_Final(mac,&key->md); - if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH)) + if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) return 0; } else { MD5_Update(&key->md,out+md5_off,len-md5_off); Index: crypto/openssl/crypto/evp/evp.h =================================================================== --- crypto/openssl/crypto/evp/evp.h (revision 284286) +++ crypto/openssl/crypto/evp/evp.h (working copy) @@ -103,7 +103,6 @@ #define EVP_PKS_RSA 0x0100 #define EVP_PKS_DSA 0x0200 #define EVP_PKS_EC 0x0400 -#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */ #define EVP_PKEY_NONE NID_undef #define EVP_PKEY_RSA NID_rsaEncryption Index: crypto/openssl/crypto/hmac/hmac.c =================================================================== --- crypto/openssl/crypto/hmac/hmac.c (revision 284286) +++ crypto/openssl/crypto/hmac/hmac.c (working copy) @@ -240,6 +240,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const vo HMAC_CTX_cleanup(&c); return md; err: + HMAC_CTX_cleanup(&c); return NULL; } Index: crypto/openssl/crypto/modes/gcm128.c =================================================================== --- crypto/openssl/crypto/modes/gcm128.c (revision 284286) +++ crypto/openssl/crypto/modes/gcm128.c (working copy) @@ -1525,7 +1525,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const ctx->Xi.u[1] ^= ctx->EK0.u[1]; if (tag && len<=sizeof(ctx->Xi)) - return memcmp(ctx->Xi.c,tag,len); + return CRYPTO_memcmp(ctx->Xi.c, tag, len); else return -1; } Index: crypto/openssl/crypto/objects/obj_dat.c =================================================================== --- crypto/openssl/crypto/objects/obj_dat.c (revision 284286) +++ crypto/openssl/crypto/objects/obj_dat.c (working copy) @@ -405,6 +405,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) if (a->nid != 0) return(a->nid); + if (a->length == 0) + return NID_undef; + if (added != NULL) { ad.type=ADDED_DATA; Index: crypto/openssl/crypto/pkcs12/p12_mutl.c =================================================================== --- crypto/openssl/crypto/pkcs12/p12_mutl.c (revision 284286) +++ crypto/openssl/crypto/pkcs12/p12_mutl.c (working copy) @@ -59,6 +59,7 @@ #ifndef OPENSSL_NO_HMAC #include #include "cryptlib.h" +#include #include #include #include @@ -123,7 +124,8 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pas return 0; } if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) - || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0; + || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) + return 0; return 1; } Index: crypto/openssl/crypto/pkcs7/pk7_doit.c =================================================================== --- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 284286) +++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy) @@ -504,6 +504,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B goto err; } + /* Detached content must be supplied via in_bio instead. */ + if (data_body == NULL && in_bio == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + goto err; + } + /* We will be checking the signature */ if (md_sk != NULL) { @@ -660,7 +666,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B } #if 1 - if (PKCS7_is_detached(p7) || (in_bio != NULL)) + if (in_bio != NULL) { bio=in_bio; } Index: crypto/openssl/crypto/x509/x509_vfy.c =================================================================== --- crypto/openssl/crypto/x509/x509_vfy.c (revision 284286) +++ crypto/openssl/crypto/x509/x509_vfy.c (working copy) @@ -1679,83 +1679,121 @@ int X509_cmp_current_time(const ASN1_TIME *ctm) } int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) - { +{ char *str; ASN1_TIME atm; long offset; - char buff1[24],buff2[24],*p; - int i,j; + char buff1[24], buff2[24], *p; + int i, j, remaining; - p=buff1; - i=ctm->length; - str=(char *)ctm->data; - if (ctm->type == V_ASN1_UTCTIME) - { - if ((i < 11) || (i > 17)) return 0; - memcpy(p,str,10); - p+=10; - str+=10; + p = buff1; + remaining = ctm->length; + str = (char *)ctm->data; + /* + * Note that the following (historical) code allows much more slack in the + * time format than RFC5280. In RFC5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ + * GeneralizedTime: YYYYMMDDHHMMSSZ + */ + if (ctm->type == V_ASN1_UTCTIME) { + /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ + int min_length = sizeof("YYMMDDHHMMZ") - 1; + int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + memcpy(p, str, 10); + p += 10; + str += 10; + remaining -= 10; + } else { + /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */ + int min_length = sizeof("YYYYMMDDHHMMZ") - 1; + int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + memcpy(p, str, 12); + p += 12; + str += 12; + remaining -= 12; } - else - { - if (i < 13) return 0; - memcpy(p,str,12); - p+=12; - str+=12; - } - if ((*str == 'Z') || (*str == '-') || (*str == '+')) - { *(p++)='0'; *(p++)='0'; } - else - { - *(p++)= *(str++); - *(p++)= *(str++); - /* Skip any fractional seconds... */ - if (*str == '.') - { + if ((*str == 'Z') || (*str == '-') || (*str == '+')) { + *(p++) = '0'; + *(p++) = '0'; + } else { + /* SS (seconds) */ + if (remaining < 2) + return 0; + *(p++) = *(str++); + *(p++) = *(str++); + remaining -= 2; + /* + * Skip any (up to three) fractional seconds... + * TODO(emilia): in RFC5280, fractional seconds are forbidden. + * Can we just kill them altogether? + */ + if (remaining && *str == '.') { str++; - while ((*str >= '0') && (*str <= '9')) str++; + remaining--; + for (i = 0; i < 3 && remaining; i++, str++, remaining--) { + if (*str < '0' || *str > '9') + break; } - } - *(p++)='Z'; - *(p++)='\0'; - if (*str == 'Z') - offset=0; - else - { + } + *(p++) = 'Z'; + *(p++) = '\0'; + + /* We now need either a terminating 'Z' or an offset. */ + if (!remaining) + return 0; + if (*str == 'Z') { + if (remaining != 1) + return 0; + offset = 0; + } else { + /* (+-)HHMM */ if ((*str != '+') && (*str != '-')) return 0; - offset=((str[1]-'0')*10+(str[2]-'0'))*60; - offset+=(str[3]-'0')*10+(str[4]-'0'); + /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */ + if (remaining != 5) + return 0; + if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || + str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') + return 0; + offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; + offset += (str[3] - '0') * 10 + (str[4] - '0'); if (*str == '-') - offset= -offset; + offset = -offset; } - atm.type=ctm->type; + atm.type = ctm->type; atm.flags = 0; - atm.length=sizeof(buff2); - atm.data=(unsigned char *)buff2; + atm.length = sizeof(buff2); + atm.data = (unsigned char *)buff2; - if (X509_time_adj(&atm, offset*60, cmp_time) == NULL) + if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) return 0; - if (ctm->type == V_ASN1_UTCTIME) - { - i=(buff1[0]-'0')*10+(buff1[1]-'0'); - if (i < 50) i+=100; /* cf. RFC 2459 */ - j=(buff2[0]-'0')*10+(buff2[1]-'0'); - if (j < 50) j+=100; + if (ctm->type == V_ASN1_UTCTIME) { + i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); + if (i < 50) + i += 100; /* cf. RFC 2459 */ + j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); + if (j < 50) + j += 100; - if (i < j) return -1; - if (i > j) return 1; + if (i < j) + return -1; + if (i > j) + return 1; } - i=strcmp(buff1,buff2); + i = strcmp(buff1, buff2); if (i == 0) /* wait a second then return younger :-) */ return -1; else return i; - } +} ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) { Index: crypto/openssl/crypto/x509/x509type.c =================================================================== --- crypto/openssl/crypto/x509/x509type.c (revision 284286) +++ crypto/openssl/crypto/x509/x509type.c (working copy) @@ -122,9 +122,6 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey) } } - if (EVP_PKEY_size(pk) <= 1024/8)/* /8 because it's 1024 bits we look - for, not bytes */ - ret|=EVP_PKT_EXP; if(pkey==NULL) EVP_PKEY_free(pk); return(ret); } Index: crypto/openssl/doc/apps/dhparam.pod =================================================================== --- crypto/openssl/doc/apps/dhparam.pod (revision 284286) +++ crypto/openssl/doc/apps/dhparam.pod (working copy) @@ -71,8 +71,10 @@ check if the parameters are valid primes and gener =item B<-2>, B<-5> -The generator to use, either 2 or 5. 2 is the default. If present then the -input file is ignored and parameters are generated instead. +The generator to use, either 2 or 5. If present then the +input file is ignored and parameters are generated instead. If not +present but B is present, parameters are generated with the +default generator 2. =item B<-rand> I @@ -85,9 +87,10 @@ all others. =item I this option specifies that a parameter set should be generated of size -I. It must be the last option. If not present then a value of 512 -is used. If this option is present then the input file is ignored and -parameters are generated instead. +I. It must be the last option. If this option is present then +the input file is ignored and parameters are generated instead. If +this option is not present but a generator (B<-2> or B<-5>) is +present, parameters are generated with a default length of 2048 bits. =item B<-noout> Index: crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod =================================================================== --- crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod (revision 284286) +++ crypto/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod (working copy) @@ -61,12 +61,12 @@ negotiation is being saved. If "strong" primes were used to generate the DH parameters, it is not strictly necessary to generate a new key for each handshake but it does improve forward -secrecy. If it is not assured, that "strong" primes were used (see especially -the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used -in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE -has an impact on the computer time needed during negotiation, but it is not -very large, so application authors/users should consider to always enable -this option. +secrecy. If it is not assured that "strong" primes were used, +SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup +attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the +computer time needed during negotiation, but it is not very large, so +application authors/users should consider always enabling this option. +The option is required to implement perfect forward secrecy (PFS). As generating DH parameters is extremely time consuming, an application should not generate the parameters on the fly but supply the parameters. @@ -74,83 +74,63 @@ DH parameters can be reused, as the actual key is the negotiation. The risk in reusing DH parameters is that an attacker may specialize on a very often used DH group. Applications should therefore generate their own DH parameters during the installation process using the -openssl L application. In order to reduce the computer -time needed for this generation, it is possible to use DSA parameters -instead (see L), but in this case SSL_OP_SINGLE_DH_USE -is mandatory. +openssl L application. This application +guarantees that "strong" primes are used. -Application authors may compile in DH parameters. Files dh512.pem, -dh1024.pem, dh2048.pem, and dh4096.pem in the 'apps' directory of current +Files dh2048.pem, and dh4096.pem in the 'apps' directory of the current version of the OpenSSL distribution contain the 'SKIP' DH parameters, which use safe primes and were generated verifiably pseudo-randomly. These files can be converted into C code using the B<-C> option of the -L application. -Authors may also generate their own set of parameters using -L, but a user may not be sure how the parameters were -generated. The generation of DH parameters during installation is therefore -recommended. +L application. Generation of custom DH +parameters during installation should still be preferred to stop an +attacker from specializing on a commonly used group. Files dh1024.pem +and dh512.pem contain old parameters that must not be used by +applications. An application may either directly specify the DH parameters or -can supply the DH parameters via a callback function. The callback approach -has the advantage, that the callback may supply DH parameters for different -key lengths. +can supply the DH parameters via a callback function. -The B is called with the B needed and -the B information. The B flag is set, when the -ephemeral DH key exchange is performed with an export cipher. +Previous versions of the callback used B and B +parameters to control parameter generation for export and non-export +cipher suites. Modern servers that do not support export ciphersuites +are advised to either use SSL_CTX_set_tmp_dh() in combination with +SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore +B and B and simply supply at least 2048-bit +parameters in the callback. =head1 EXAMPLES -Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling +Setup DH parameters with a key length of 2048 bits. (Error handling partly left out.) + Command-line parameter generation: + $ openssl dhparam -out dh_param_2048.pem 2048 + + Code for setting up parameters during server initialization: + ... - /* Set up ephemeral DH stuff */ - DH *dh_512 = NULL; - DH *dh_1024 = NULL; + SSL_CTX ctx = SSL_CTX_new(); + ... + + /* Set up ephemeral DH parameters. */ + DH *dh_2048 = NULL; FILE *paramfile; - - ... - /* "openssl dhparam -out dh_param_512.pem -2 512" */ - paramfile = fopen("dh_param_512.pem", "r"); + paramfile = fopen("dh_param_2048.pem", "r"); if (paramfile) { - dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); + dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); fclose(paramfile); + } else { + /* Error. */ } - /* "openssl dhparam -out dh_param_1024.pem -2 1024" */ - paramfile = fopen("dh_param_1024.pem", "r"); - if (paramfile) { - dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); - fclose(paramfile); + if (dh_2048 == NULL) { + /* Error. */ } + if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) { + /* Error. */ + } + SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); ... - /* "openssl dhparam -C -2 512" etc... */ - DH *get_dh512() { ... } - DH *get_dh1024() { ... } - - DH *tmp_dh_callback(SSL *s, int is_export, int keylength) - { - DH *dh_tmp=NULL; - - switch (keylength) { - case 512: - if (!dh_512) - dh_512 = get_dh512(); - dh_tmp = dh_512; - break; - case 1024: - if (!dh_1024) - dh_1024 = get_dh1024(); - dh_tmp = dh_1024; - break; - default: - /* Generating a key on the fly is very costly, so use what is there */ - setup_dh_parameters_like_above(); - } - return(dh_tmp); - } - =head1 RETURN VALUES SSL_CTX_set_tmp_dh_callback() and SSL_set_tmp_dh_callback() do not return Index: crypto/openssl/ssl/d1_both.c =================================================================== --- crypto/openssl/ssl/d1_both.c (revision 284286) +++ crypto/openssl/ssl/d1_both.c (working copy) @@ -481,6 +481,12 @@ again: else if ( i <= 0 && !*ok) return i; + if (mt >= 0 && s->s3->tmp.message_type != mt) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + p = (unsigned char *)s->init_buf->data; msg_len = msg_hdr->msg_len; @@ -869,6 +875,20 @@ dtls1_get_message_fragment(SSL *s, int st1, int st /* parse the message fragment header */ dtls1_get_message_header(wire, &msg_hdr); + len = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + + /* + * We must have at least frag_len bytes left in the record to be read. + * Fragments must not span records. + */ + if (frag_len > s->s3->rrec.length) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH); + goto f_err; + } + /* * if this is a future (or stale) message it gets buffered * (or dropped)--no further processing at this time @@ -878,10 +898,6 @@ dtls1_get_message_fragment(SSL *s, int st1, int st if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1)) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); - len = msg_hdr.msg_len; - frag_off = msg_hdr.frag_off; - frag_len = msg_hdr.frag_len; - if (frag_len && frag_len < len) return dtls1_reassemble_fragment(s, &msg_hdr, ok); @@ -913,9 +929,6 @@ dtls1_get_message_fragment(SSL *s, int st1, int st if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) goto f_err; - /* XDTLS: ressurect this when restart is in place */ - s->state=stn; - if ( frag_len > 0) { unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH; @@ -922,7 +935,10 @@ dtls1_get_message_fragment(SSL *s, int st1, int st i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, &p[frag_off],frag_len,0); - /* XDTLS: fix this--message fragments cannot span multiple packets */ + /* + * This shouldn't ever fail due to NBIO because we already checked + * that we have enough data in the record + */ if (i <= 0) { s->rwstate=SSL_READING; @@ -943,6 +959,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int st } *ok = 1; + s->state = stn; /* Note that s->init_num is *not* used as current offset in * s->init_buf->data, but as a counter summing up fragments' Index: crypto/openssl/ssl/d1_lib.c =================================================================== --- crypto/openssl/ssl/d1_lib.c (revision 284286) +++ crypto/openssl/ssl/d1_lib.c (working copy) @@ -509,6 +509,9 @@ int dtls1_listen(SSL *s, struct sockaddr *client) { int ret; + /* Ensure there is no state left over from a previous invocation */ + SSL_clear(s); + SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); s->d1->listen = 1; Index: crypto/openssl/ssl/d1_pkt.c =================================================================== --- crypto/openssl/ssl/d1_pkt.c (revision 284286) +++ crypto/openssl/ssl/d1_pkt.c (working copy) @@ -1056,7 +1056,7 @@ start: { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST); - goto err; + goto f_err; } /* no need to check sequence number on HELLO REQUEST messages */ Index: crypto/openssl/ssl/s3_cbc.c =================================================================== --- crypto/openssl/ssl/s3_cbc.c (revision 284286) +++ crypto/openssl/ssl/s3_cbc.c (working copy) @@ -143,7 +143,7 @@ int tls1_cbc_remove_padding(const SSL* s, if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && + if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) && !(padding_length & 1)) { s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; Index: crypto/openssl/ssl/s3_clnt.c =================================================================== --- crypto/openssl/ssl/s3_clnt.c (revision 284286) +++ crypto/openssl/ssl/s3_clnt.c (working copy) @@ -1606,6 +1606,13 @@ int ssl3_get_key_exchange(SSL *s) SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); goto err; } + + if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + s->session->sess_cert->peer_rsa_tmp=rsa; rsa=NULL; } @@ -2190,7 +2197,39 @@ int ssl3_get_new_session_ticket(SSL *s) goto f_err; } - p=d=(unsigned char *)s->init_msg; + p = d = (unsigned char *)s->init_msg; + + if (s->session->session_id_length > 0) { + int i = s->session_ctx->session_cache_mode; + SSL_SESSION *new_sess; + /* + * We reused an existing session, so we need to replace it with a new + * one + */ + if (i & SSL_SESS_CACHE_CLIENT) { + /* + * Remove the old session from the cache + */ + if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) { + if (s->session_ctx->remove_session_cb != NULL) + s->session_ctx->remove_session_cb(s->session_ctx, + s->session); + } else { + /* We carry on if this fails */ + SSL_CTX_remove_session(s->session_ctx, s->session); + } + } + + if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + SSL_SESSION_free(s->session); + s->session = new_sess; + } + n2l(p, s->session->tlsext_tick_lifetime_hint); n2s(p, ticklen); /* ticket_lifetime_hint + ticket_length + ticket */ @@ -3319,6 +3358,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) int i,idx; long alg_k,alg_a; EVP_PKEY *pkey=NULL; + int pkey_bits; SESS_CERT *sc; #ifndef OPENSSL_NO_RSA RSA *rsa; @@ -3326,6 +3366,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) #ifndef OPENSSL_NO_DH DH *dh; #endif + int al = SSL_AD_HANDSHAKE_FAILURE; alg_k=s->s3->tmp.new_cipher->algorithm_mkey; alg_a=s->s3->tmp.new_cipher->algorithm_auth; @@ -3367,6 +3408,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509); + pkey_bits = EVP_PKEY_bits(pkey); i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey); EVP_PKEY_free(pkey); @@ -3385,71 +3427,108 @@ int ssl3_check_cert_and_algorithm(SSL *s) } #endif #ifndef OPENSSL_NO_RSA - if ((alg_k & SSL_kRSA) && - !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT); + if (alg_k & SSL_kRSA) { + if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); goto f_err; + } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { + if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; } + if (rsa != NULL) { + /* server key exchange is not allowed. */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto f_err; + } + } + } + } #endif #ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kEDH) && - !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); + if ((alg_k & SSL_kEDH) && dh == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); goto f_err; } - else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT); + if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_RSA_CERT); goto f_err; } -#ifndef OPENSSL_NO_DSA - else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT); +# ifndef OPENSSL_NO_DSA + if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_DSA_CERT); goto f_err; } -#endif -#endif +# endif - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) + /* Check DHE only: static DH not implemented. */ + if (alg_k & SSL_kEDH) { + int dh_size = BN_num_bits(dh->p); + if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768) + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } + } +#endif /* !OPENSSL_NO_DH */ + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { #ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) - { - if (rsa == NULL - || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + if (alg_k & SSL_kRSA) { + if (rsa == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); goto f_err; + } else if (BN_num_bits(rsa->n) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary RSA key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + goto f_err; } - } - else + } else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) - { - if (dh == NULL - || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY); + if (alg_k & SSL_kEDH) { + if (BN_num_bits(dh->p) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary DH key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); goto f_err; } - } - else + } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { + /* The cert should have had an export DH key. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); + goto f_err; + } else #endif { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } } - return(1); -f_err: - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -err: - return(0); - } + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (0); +} #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) int ssl3_send_next_proto(SSL *s) Index: crypto/openssl/ssl/s3_srvr.c =================================================================== --- crypto/openssl/ssl/s3_srvr.c (revision 284286) +++ crypto/openssl/ssl/s3_srvr.c (working copy) @@ -2418,6 +2418,7 @@ int ssl3_get_client_key_exchange(SSL *s) int padl, outl; krb5_timestamp authtime = 0; krb5_ticket_times ttimes; + int kerr = 0; EVP_CIPHER_CTX_init(&ciph_ctx); @@ -2530,19 +2531,22 @@ int ssl3_get_client_key_exchange(SSL *s) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); - goto err; + kerr = 1; + goto kclean; } if (outl > SSL_MAX_MASTER_KEY_LENGTH) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); - goto err; + kerr = 1; + goto kclean; } if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DECRYPTION_FAILED); - goto err; + kerr = 1; + goto kclean; } outl += padl; if (outl > SSL_MAX_MASTER_KEY_LENGTH) @@ -2549,7 +2553,8 @@ int ssl3_get_client_key_exchange(SSL *s) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); - goto err; + kerr = 1; + goto kclean; } if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff)))) { @@ -2565,7 +2570,8 @@ int ssl3_get_client_key_exchange(SSL *s) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_AD_DECODE_ERROR); - goto err; + kerr = 1; + goto kclean; } } @@ -2591,6 +2597,11 @@ int ssl3_get_client_key_exchange(SSL *s) ** kssl_ctx = kssl_ctx_free(kssl_ctx); ** if (s->kssl_ctx) s->kssl_ctx = NULL; */ + + kclean: + OPENSSL_cleanse(pms, sizeof(pms)); + if (kerr) + goto err; } else #endif /* OPENSSL_NO_KRB5 */ Index: crypto/openssl/ssl/ssl.h =================================================================== --- crypto/openssl/ssl/ssl.h (revision 284286) +++ crypto/openssl/ssl/ssl.h (working copy) @@ -2263,6 +2263,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_READ 223 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +#define SSL_F_SSL_SESSION_DUP 348 #define SSL_F_SSL_SESSION_NEW 189 #define SSL_F_SSL_SESSION_PRINT_FP 190 #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 @@ -2377,6 +2378,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_DATA_LENGTH_TOO_LONG 146 #define SSL_R_DECRYPTION_FAILED 147 #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +#define SSL_R_DH_KEY_TOO_SMALL 372 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 #define SSL_R_DIGEST_CHECK_FAILED 149 #define SSL_R_DTLS_MESSAGE_TOO_BIG 334 Index: crypto/openssl/ssl/ssl_err.c =================================================================== --- crypto/openssl/ssl/ssl_err.c (revision 284286) +++ crypto/openssl/ssl/ssl_err.c (working copy) @@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, +{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"}, @@ -362,6 +363,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"}, {ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"}, {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"}, +{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"}, {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"}, {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"}, Index: crypto/openssl/ssl/ssl_locl.h =================================================================== --- crypto/openssl/ssl/ssl_locl.h (revision 284286) +++ crypto/openssl/ssl/ssl_locl.h (working copy) @@ -831,6 +831,7 @@ void ssl_sess_cert_free(SESS_CERT *sc); int ssl_set_peer_cert_type(SESS_CERT *c, int type); int ssl_get_new_session(SSL *s, int session); int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit); +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b); DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); Index: crypto/openssl/ssl/ssl_sess.c =================================================================== --- crypto/openssl/ssl/ssl_sess.c (revision 284286) +++ crypto/openssl/ssl/ssl_sess.c (working copy) @@ -224,6 +224,130 @@ SSL_SESSION *SSL_SESSION_new(void) return(ss); } +/* + * Create a new SSL_SESSION and duplicate the contents of |src| into it. If + * ticket == 0 then no ticket information is duplicated, otherwise it is. + */ +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) +{ + SSL_SESSION *dest; + + dest = OPENSSL_malloc(sizeof(*src)); + if (dest == NULL) { + goto err; + } + memcpy(dest, src, sizeof(*dest)); + + /* + * Set the various pointers to NULL so that we can call SSL_SESSION_free in + * the case of an error whilst halfway through constructing dest + */ +#ifndef OPENSSL_NO_PSK + dest->psk_identity_hint = NULL; + dest->psk_identity = NULL; +#endif + dest->ciphers = NULL; +#ifndef OPENSSL_NO_TLSEXT + dest->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + dest->tlsext_ecpointformatlist = NULL; + dest->tlsext_ellipticcurvelist = NULL; +# endif +#endif + dest->tlsext_tick = NULL; +#ifndef OPENSSL_NO_SRP + dest->srp_username = NULL; +#endif + memset(&dest->ex_data, 0, sizeof(dest->ex_data)); + + /* We deliberately don't copy the prev and next pointers */ + dest->prev = NULL; + dest->next = NULL; + + dest->references = 1; + + if (src->sess_cert != NULL) + CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); + + if (src->peer != NULL) + CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); + +#ifndef OPENSSL_NO_PSK + if (src->psk_identity_hint) { + dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); + if (dest->psk_identity_hint == NULL) { + goto err; + } + } + if (src->psk_identity) { + dest->psk_identity = BUF_strdup(src->psk_identity); + if (dest->psk_identity == NULL) { + goto err; + } + } +#endif + + if(src->ciphers != NULL) { + dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); + if (dest->ciphers == NULL) + goto err; + } + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, + &dest->ex_data, &src->ex_data)) { + goto err; + } + +#ifndef OPENSSL_NO_TLSEXT + if (src->tlsext_hostname) { + dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); + if (dest->tlsext_hostname == NULL) { + goto err; + } + } +# ifndef OPENSSL_NO_EC + if (src->tlsext_ecpointformatlist) { + dest->tlsext_ecpointformatlist = + BUF_memdup(src->tlsext_ecpointformatlist, + src->tlsext_ecpointformatlist_length); + if (dest->tlsext_ecpointformatlist == NULL) + goto err; + } + if (src->tlsext_ellipticcurvelist) { + dest->tlsext_ellipticcurvelist = + BUF_memdup(src->tlsext_ellipticcurvelist, + src->tlsext_ellipticcurvelist_length); + if (dest->tlsext_ellipticcurvelist == NULL) + goto err; + } +# endif +#endif + + if (ticket != 0) { + dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); + if(dest->tlsext_tick == NULL) + goto err; + } else { + dest->tlsext_tick_lifetime_hint = 0; + dest->tlsext_ticklen = 0; + } + +#ifndef OPENSSL_NO_SRP + if (src->srp_username) { + dest->srp_username = BUF_strdup(src->srp_username); + if (dest->srp_username == NULL) { + goto err; + } + } +#endif + + return dest; +err: + SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(dest); + return NULL; +} + const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) { if(len) Index: crypto/openssl/ssl/t1_lib.c =================================================================== --- crypto/openssl/ssl/t1_lib.c (revision 284286) +++ crypto/openssl/ssl/t1_lib.c (working copy) @@ -1015,12 +1015,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned s->srtp_profile = NULL; - if (data >= (d+n-2)) + if (data >= (d + n - 2)) { + if (data != d + n) + goto err; + else goto ri_check; + } n2s(data,len); if (data > (d+n-len)) - goto ri_check; + goto err; while (data <= (d+n-4)) { @@ -1028,7 +1032,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned n2s(data,size); if (data+size > (d+n)) - goto ri_check; + goto err; #if 0 fprintf(stderr,"Received extension type %d size %d\n",type,size); #endif @@ -1065,17 +1069,11 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned int dsize; if (size < 2) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; n2s(data,dsize); size -= 2; if (dsize > size ) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; sdata = data; while (dsize > 3) @@ -1085,10 +1083,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned dsize -= 3; if (len > dsize) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if (s->servername_done == 0) switch (servname_type) { @@ -1096,10 +1091,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned if (!s->hit) { if(s->session->tlsext_hostname) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if (len > TLSEXT_MAXLEN_host_name) { *al = TLS1_AD_UNRECOGNIZED_NAME; @@ -1135,10 +1127,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned dsize -= len; } if (dsize != 0) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; } #ifndef OPENSSL_NO_SRP @@ -1145,15 +1134,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned else if (type == TLSEXT_TYPE_srp) { if (size <= 0 || ((len = data[0])) != (size -1)) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if (s->srp_ctx.login != NULL) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL) return -1; memcpy(s->srp_ctx.login, &data[1], len); @@ -1160,11 +1143,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned s->srp_ctx.login[len]='\0'; if (strlen(s->srp_ctx.login) != len) - { - *al = SSL_AD_DECODE_ERROR; - return 0; + goto err; } - } #endif #ifndef OPENSSL_NO_EC @@ -1174,10 +1154,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned int ecpointformatlist_length = *(sdata++); if (ecpointformatlist_length != size - 1) - { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + goto err; if (!s->hit) { if(s->session->tlsext_ecpointformatlist) @@ -1212,17 +1189,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned ellipticcurvelist_length < 1 || /* Each NamedCurve is 2 bytes. */ ellipticcurvelist_length & 1) - { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + goto err; if (!s->hit) { if(s->session->tlsext_ellipticcurvelist) - { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } + goto err; + s->session->tlsext_ellipticcurvelist_length = 0; if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { @@ -1291,33 +1263,21 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned { int dsize; if (sigalg_seen || size < 2) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; sigalg_seen = 1; n2s(data,dsize); size -= 2; if (dsize != size || dsize & 1) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if (!tls1_process_sigalgs(s, data, dsize)) - { - *al = SSL_AD_DECODE_ERROR; - return 0; + goto err; } - } else if (type == TLSEXT_TYPE_status_request && s->version != DTLS1_VERSION) { if (size < 5) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; s->tlsext_status_type = *data++; size--; @@ -1329,41 +1289,28 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned n2s(data,dsize); size -= 2; if (dsize > size ) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; while (dsize > 0) { OCSP_RESPID *id; int idsize; if (dsize < 4) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; n2s(data, idsize); dsize -= 2 + idsize; size -= 2 + idsize; if (dsize < 0) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; sdata = data; data += idsize; id = d2i_OCSP_RESPID(NULL, &sdata, idsize); if (!id) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; if (data != sdata) { OCSP_RESPID_free(id); - *al = SSL_AD_DECODE_ERROR; - return 0; + goto err; } if (!s->tlsext_ocsp_ids && !(s->tlsext_ocsp_ids = @@ -1384,17 +1331,11 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned /* Read in request_extensions */ if (size < 2) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; n2s(data,dsize); size -= 2; if (dsize != size) - { - *al = SSL_AD_DECODE_ERROR; - return 0; - } + goto err; sdata = data; if (dsize > 0) { @@ -1409,12 +1350,9 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned &sdata, dsize); if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) - { - *al = SSL_AD_DECODE_ERROR; - return 0; + goto err; } } - } /* We don't know what to do with any other type * so ignore it. */ @@ -1475,6 +1413,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned data+=size; } + /* Spurious data on the end */ + if (data != d + n) + goto err; + *p = data; ri_check: @@ -1491,7 +1433,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned } return 1; - } +err: + *al = SSL_AD_DECODE_ERROR; + return 0; +} #ifndef OPENSSL_NO_NEXTPROTONEG /* ssl_next_proto_validate validates a Next Protocol Negotiation block. No