X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=a6f2502c7214ab33cc4c50159679270c9296e349;hp=ece2b72ac609176bcfe8bd76b7b49fb5aa57919f;hb=bf7c68177b6fbb80406c60136654b6fefe7e3ba2;hpb=fbfcb2243941bc84b7585711feb906610f9111c4 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index ece2b72ac6..a6f2502c72 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -135,7 +135,6 @@ SSL3_ENC_METHOD const TLSv1_enc_data = { tls1_change_cipher_state, tls1_final_finish_mac, TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, @@ -154,7 +153,6 @@ SSL3_ENC_METHOD const TLSv1_1_enc_data = { tls1_change_cipher_state, tls1_final_finish_mac, TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, @@ -173,7 +171,6 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = { tls1_change_cipher_state, tls1_final_finish_mac, TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, @@ -262,8 +259,8 @@ static const unsigned char ecformats_default[] = { TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 }; -/* The client's default curves / the server's 'auto' curves. */ -static const unsigned char eccurves_auto[] = { +/* The default curves */ +static const unsigned char eccurves_default[] = { /* Prefer P-256 which has the fastest and most secure implementations. */ 0, 23, /* secp256r1 (23) */ /* Other >= 256-bit prime curves. */ @@ -441,13 +438,8 @@ static int tls1_get_curvelist(SSL *s, int sess, pcurveslen = s->tlsext_ellipticcurvelist_length; } if (!*pcurves) { - if (!s->server || (s->cert && s->cert->ecdh_tmp_auto)) { - *pcurves = eccurves_auto; - pcurveslen = sizeof(eccurves_auto); - } else { - *pcurves = eccurves_all; - pcurveslen = sizeof(eccurves_all); - } + *pcurves = eccurves_default; + pcurveslen = sizeof(eccurves_default); } } @@ -510,8 +502,9 @@ int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) } /*- - * Return |nmatch|th shared curve or NID_undef if there is no match. - * For nmatch == -1, return number of matches + * For nmatch >= 0, return the NID of the |nmatch|th shared curve or NID_undef + * if there is no match. + * For nmatch == -1, return number of matches * For nmatch == -2, return the NID of the curve to use for * an EC tmp key, or NID_undef if there is no match. */ @@ -599,7 +592,7 @@ int tls1_set_curves(unsigned char **pext, size_t *pextlen, */ unsigned long dup_list = 0; clist = OPENSSL_malloc(ncurves * 2); - if (!clist) + if (clist == NULL) return 0; for (i = 0, p = clist; i < ncurves; i++) { unsigned long idmask; @@ -845,11 +838,18 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) } # ifndef OPENSSL_NO_EC -/* Check EC temporary key is compatible with client extensions */ +/* + * tls1_check_ec_tmp_key - Check EC temporary key compatiblity + * @s: SSL connection + * @cid: Cipher ID we're considering using + * + * Checks that the kECDHE cipher suite we're considering using + * is compatible with the client extensions. + * + * Returns 0 when the cipher can't be used or 1 when it can. + */ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) { - unsigned char curve_id[2]; - EC_KEY *ec = s->cert->ecdh_tmp; # ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* Allow any curve: not just those peer supports */ if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) @@ -860,6 +860,7 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) * curves permitted. */ if (tls1_suiteb(s)) { + unsigned char curve_id[2]; /* Curve to check determined by ciphersuite */ if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) curve_id[1] = TLSEXT_curve_P_256; @@ -871,43 +872,12 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) /* Check this curve is acceptable */ if (!tls1_check_ec_key(s, curve_id, NULL)) return 0; - /* If auto or setting curve from callback assume OK */ - if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb) - return 1; - /* Otherwise check curve is acceptable */ - else { - unsigned char curve_tmp[2]; - if (!ec) - return 0; - if (!tls1_set_ec_id(curve_tmp, NULL, ec)) - return 0; - if (!curve_tmp[0] || curve_tmp[1] == curve_id[1]) - return 1; - return 0; - } - - } - if (s->cert->ecdh_tmp_auto) { - /* Need a shared curve */ - if (tls1_shared_curve(s, 0)) - return 1; - else - return 0; - } - if (!ec) { - if (s->cert->ecdh_tmp_cb) - return 1; - else - return 0; + return 1; } - if (!tls1_set_ec_id(curve_id, NULL, ec)) - return 0; -/* Set this to allow use of invalid curves for testing */ -# if 0 - return 1; -# else - return tls1_check_ec_key(s, curve_id, NULL); -# endif + /* Need a shared curve */ + if (tls1_shared_curve(s, 0)) + return 1; + return 0; } # endif /* OPENSSL_NO_EC */ @@ -954,6 +924,11 @@ static const unsigned char tls12_sigalgs[] = { tlsext_sigalg(TLSEXT_hash_sha256) tlsext_sigalg(TLSEXT_hash_sha224) tlsext_sigalg(TLSEXT_hash_sha1) +#ifndef OPENSSL_NO_GOST + TLSEXT_hash_gostr3411, TLSEXT_signature_gostr34102001, + TLSEXT_hash_gostr34112012_256, TLSEXT_signature_gostr34102012_256, + TLSEXT_hash_gostr34112012_512, TLSEXT_signature_gostr34102012_512 +#endif }; #ifndef OPENSSL_NO_EC @@ -1094,6 +1069,9 @@ void ssl_set_client_disabled(SSL *s) s->s3->tmp.mask_ssl = SSL_TLSV1_2; else s->s3->tmp.mask_ssl = 0; + /* Disable TLS 1.0 ciphers if using SSL v3 */ + if (s->client_version == SSL3_VERSION) + s->s3->tmp.mask_ssl |= SSL_TLSV1; ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); /* * Disable static DH if we don't include any appropriate signature @@ -1327,7 +1305,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, s->tlsext_session_ticket->data) { ticklen = s->tlsext_session_ticket->length; s->session->tlsext_tick = OPENSSL_malloc(ticklen); - if (!s->session->tlsext_tick) + if (s->session->tlsext_tick == NULL) return NULL; memcpy(s->session->tlsext_tick, s->tlsext_session_ticket->data, ticklen); @@ -1711,7 +1689,9 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, * for other cases too. */ if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD - || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4) + || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4 + || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT + || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC; else { s2n(TLSEXT_TYPE_encrypt_then_mac, ret); @@ -1787,7 +1767,7 @@ static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al) if (r == SSL_TLSEXT_ERR_OK) { OPENSSL_free(s->s3->alpn_selected); s->s3->alpn_selected = OPENSSL_malloc(selected_len); - if (!s->s3->alpn_selected) { + if (s->s3->alpn_selected == NULL) { *al = SSL_AD_INTERNAL_ERROR; return -1; } @@ -1815,10 +1795,11 @@ static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al) * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from * 10.8..10.8.3 (which don't work). */ -static void ssl_check_for_safari(SSL *s, PACKET *pkt) +static void ssl_check_for_safari(SSL *s, const PACKET *pkt) { unsigned int type, size; unsigned char *eblock1, *eblock2; + PACKET tmppkt; static const unsigned char kSafariExtensionsBlock[] = { 0x00, 0x0a, /* elliptic_curves extension */ @@ -1846,10 +1827,12 @@ static void ssl_check_for_safari(SSL *s, PACKET *pkt) 0x02, 0x03, /* SHA-1/ECDSA */ }; - if (!PACKET_forward(pkt, 2) - || !PACKET_get_net_2(pkt, &type) - || !PACKET_get_net_2(pkt, &size) - || !PACKET_forward(pkt, size)) + tmppkt = *pkt; + + if (!PACKET_forward(&tmppkt, 2) + || !PACKET_get_net_2(&tmppkt, &type) + || !PACKET_get_net_2(&tmppkt, &size) + || !PACKET_forward(&tmppkt, size)) return; if (type != TLSEXT_TYPE_server_name) @@ -1859,9 +1842,9 @@ static void ssl_check_for_safari(SSL *s, PACKET *pkt) const size_t len1 = sizeof(kSafariExtensionsBlock); const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); - if (!PACKET_get_bytes(pkt, &eblock1, len1) - || !PACKET_get_bytes(pkt, &eblock2, len2) - || PACKET_remaining(pkt)) + if (!PACKET_get_bytes(&tmppkt, &eblock1, len1) + || !PACKET_get_bytes(&tmppkt, &eblock2, len2) + || PACKET_remaining(&tmppkt)) return; if (memcmp(eblock1, kSafariExtensionsBlock, len1) != 0) return; @@ -1870,8 +1853,8 @@ static void ssl_check_for_safari(SSL *s, PACKET *pkt) } else { const size_t len = sizeof(kSafariExtensionsBlock); - if (!PACKET_get_bytes(pkt, &eblock1, len) - || PACKET_remaining(pkt)) + if (!PACKET_get_bytes(&tmppkt, &eblock1, len) + || PACKET_remaining(&tmppkt)) return; if (memcmp(eblock1, kSafariExtensionsBlock, len) != 0) return; @@ -1927,6 +1910,9 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al) if (!PACKET_get_net_2(pkt, &len)) goto err; + if (PACKET_remaining(pkt) != len) + goto err; + while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) { PACKET subpkt; @@ -2036,7 +2022,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al) } } /* We shouldn't have any bytes left */ - if (PACKET_remaining(&ssubpkt)) + if (PACKET_remaining(&ssubpkt) != 0) goto err; } @@ -2140,7 +2126,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al) || (dsize & 1) != 0 || (dsize == 0) || !PACKET_get_bytes(&subpkt, &data, dsize) - || PACKET_remaining(&subpkt) + || PACKET_remaining(&subpkt) != 0 || !tls1_save_sigalgs(s, data, dsize)) { goto err; } @@ -2344,28 +2330,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, PACKET *pkt) * elements of zero length are allowed and the set of elements must exactly * fill the length of the block. */ -static char ssl_next_proto_validate(unsigned char *d, unsigned len) +static char ssl_next_proto_validate(PACKET *pkt) { - unsigned int off = 0; + unsigned int len; - while (off < len) { - if (d[off] == 0) + while (PACKET_remaining(pkt)) { + if (!PACKET_get_1(pkt, &len) + || !PACKET_forward(pkt, len)) return 0; - off += d[off]; - off++; } - return off == len; + return 1; } #endif -static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, - unsigned char *d, int n, int *al) +static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al) { - unsigned short length; - unsigned short type; - unsigned short size; - unsigned char *data = *p; + unsigned int length, type, size; int tlsext_servername = 0; int renegotiate_seen = 0; @@ -2385,27 +2366,27 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC; #endif - if (data >= (d + n - 2)) + if (!PACKET_get_net_2(pkt, &length)) goto ri_check; - n2s(data, length); - if (data + length != d + n) { + if (PACKET_remaining(pkt) != length) { *al = SSL_AD_DECODE_ERROR; return 0; } - while (data <= (d + n - 4)) { - n2s(data, type); - n2s(data, size); + while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) { + unsigned char *data; + PACKET spkt; - if (data + size > (d + n)) + if (!PACKET_get_sub_packet(pkt, &spkt, size) + || !PACKET_peek_bytes(&spkt, &data, size)) goto ri_check; if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); if (type == TLSEXT_TYPE_renegotiate) { - if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) + if (!ssl_parse_serverhello_renegotiate_ext(s, &spkt, al)) return 0; renegotiate_seen = 1; } else if (s->version == SSL3_VERSION) { @@ -2418,10 +2399,9 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, } #ifndef OPENSSL_NO_EC else if (type == TLSEXT_TYPE_ec_point_formats) { - unsigned char *sdata = data; - int ecpointformatlist_length = *(sdata++); - - if (ecpointformatlist_length != size - 1) { + unsigned int ecpointformatlist_length; + if (!PACKET_get_1(&spkt, &ecpointformatlist_length) + || ecpointformatlist_length != size - 1) { *al = TLS1_AD_DECODE_ERROR; return 0; } @@ -2435,8 +2415,13 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, } s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, - ecpointformatlist_length); + if (!PACKET_copy_bytes(&spkt, + s->session->tlsext_ecpointformatlist, + ecpointformatlist_length)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + } } #endif /* OPENSSL_NO_EC */ @@ -2472,14 +2457,13 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, s->s3->tmp.finish_md_len == 0) { unsigned char *selected; unsigned char selected_len; - /* We must have requested it. */ if (s->ctx->next_proto_select_cb == NULL) { *al = TLS1_AD_UNSUPPORTED_EXTENSION; return 0; } /* The data must be valid */ - if (!ssl_next_proto_validate(data, size)) { + if (!ssl_next_proto_validate(&spkt)) { *al = TLS1_AD_DECODE_ERROR; return 0; } @@ -2492,7 +2476,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, return 0; } s->next_proto_negotiated = OPENSSL_malloc(selected_len); - if (!s->next_proto_negotiated) { + if (s->next_proto_negotiated == NULL) { *al = TLS1_AD_INTERNAL_ERROR; return 0; } @@ -2504,46 +2488,44 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { unsigned len; - /* We must have requested it. */ if (s->alpn_client_proto_list == NULL) { *al = TLS1_AD_UNSUPPORTED_EXTENSION; return 0; } - if (size < 4) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } /*- * The extension data consists of: * uint16 list_length * uint8 proto_length; * uint8 proto[proto_length]; */ - len = data[0]; - len <<= 8; - len |= data[1]; - if (len != (unsigned)size - 2) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - len = data[2]; - if (len != (unsigned)size - 3) { + if (!PACKET_get_net_2(&spkt, &len) + || PACKET_remaining(&spkt) != len + || !PACKET_get_1(&spkt, &len) + || PACKET_remaining(&spkt) != len) { *al = TLS1_AD_DECODE_ERROR; return 0; } OPENSSL_free(s->s3->alpn_selected); s->s3->alpn_selected = OPENSSL_malloc(len); - if (!s->s3->alpn_selected) { + if (s->s3->alpn_selected == NULL) { *al = TLS1_AD_INTERNAL_ERROR; return 0; } - memcpy(s->s3->alpn_selected, data + 3, len); + if (!PACKET_copy_bytes(&spkt, s->s3->alpn_selected, len)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } s->s3->alpn_selected_len = len; } #ifndef OPENSSL_NO_HEARTBEATS else if (type == TLSEXT_TYPE_heartbeat) { - switch (data[0]) { + unsigned int hbtype; + if (!PACKET_get_1(&spkt, &hbtype)) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + switch (hbtype) { case 0x01: /* Server allows us to send HB requests */ s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; break; @@ -2559,7 +2541,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, #endif #ifndef OPENSSL_NO_SRTP else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { - if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) + if (ssl_parse_serverhello_use_srtp_ext(s, &spkt, al)) return 0; } #endif @@ -2581,11 +2563,9 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, */ else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) return 0; - - data += size; } - if (data != d + n) { + if (PACKET_remaining(pkt) != 0) { *al = SSL_AD_DECODE_ERROR; return 0; } @@ -2605,8 +2585,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, } } - *p = data; - ri_check: /* @@ -2682,18 +2660,26 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) } } /* Initialise digests to default values */ -static void ssl_set_default_md(SSL *s) +void ssl_set_default_md(SSL *s) { const EVP_MD **pmd = s->s3->tmp.md; #ifndef OPENSSL_NO_DSA - pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1(); + pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX); #endif #ifndef OPENSSL_NO_RSA - pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1(); - pmd[SSL_PKEY_RSA_ENC] = EVP_sha1(); + if (SSL_USE_SIGALGS(s)) + pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX); + else + pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX); + pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN]; #endif #ifndef OPENSSL_NO_EC - pmd[SSL_PKEY_ECC] = EVP_sha1(); + pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX); +#endif +#ifndef OPENSSL_NO_GOST + pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX); + pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX); + pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX); #endif } @@ -2887,13 +2873,12 @@ int ssl_check_serverhello_tlsext(SSL *s) } } -int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, - int n) +int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt) { int al = -1; if (s->version < SSL3_VERSION) return 1; - if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) { + if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) { ssl3_send_alert(s, SSL3_AL_FATAL, al); return 0; } @@ -2910,11 +2895,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, * ClientHello, and other operations depend on the result, we need to handle * any TLS session ticket extension at the same time. * - * session_id: points at the session ID in the ClientHello. This code will - * read past the end of this in order to parse out the session ticket - * extension, if any. - * len: the length of the session ID. - * limit: a pointer to the first byte after the ClientHello. + * session_id: ClientHello session ID. + * ext: ClientHello extensions (including length prefix) * ret: (output) on return, if a ticket was decrypted, then this is set to * point to the resulting session. * @@ -2939,11 +2921,11 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. * Otherwise, s->tlsext_ticket_expected is set to 0. */ -int tls1_process_ticket(SSL *s, PACKET *pkt, unsigned char *session_id, - int len, SSL_SESSION **ret) +int tls1_process_ticket(SSL *s, const PACKET *ext, const PACKET *session_id, + SSL_SESSION **ret) { unsigned int i; - size_t bookmark = 0; + PACKET local_ext = *ext; int retv = -1; *ret = NULL; @@ -2958,42 +2940,20 @@ int tls1_process_ticket(SSL *s, PACKET *pkt, unsigned char *session_id, if ((s->version <= SSL3_VERSION)) return 0; - if (!PACKET_get_bookmark(pkt, &bookmark)) { - return -1; - } - - /* Skip past DTLS cookie */ - if (SSL_IS_DTLS(s)) { - if (!PACKET_get_1(pkt, &i) - || !PACKET_forward(pkt, i)) { - retv = -1; - goto end; - } - } - /* Skip past cipher list and compression algorithm list */ - if (!PACKET_get_net_2(pkt, &i) - || !PACKET_forward(pkt, i) - || !PACKET_get_1(pkt, &i) - || !PACKET_forward(pkt, i)) { - retv = -1; - goto end; - } - - /* Now at start of extensions */ - if (!PACKET_get_net_2(pkt, &i)) { + if (!PACKET_get_net_2(&local_ext, &i)) { retv = 0; goto end; } - while (PACKET_remaining (pkt) >= 4) { + while (PACKET_remaining(&local_ext) >= 4) { unsigned int type, size; - if (!PACKET_get_net_2(pkt, &type) - || !PACKET_get_net_2(pkt, &size)) { + if (!PACKET_get_net_2(&local_ext, &type) + || !PACKET_get_net_2(&local_ext, &size)) { /* Shouldn't ever happen */ retv = -1; goto end; } - if (PACKET_remaining(pkt) < size) { + if (PACKET_remaining(&local_ext) < size) { retv = 0; goto end; } @@ -3020,12 +2980,13 @@ int tls1_process_ticket(SSL *s, PACKET *pkt, unsigned char *session_id, retv = 2; goto end; } - if (!PACKET_get_bytes(pkt, &etick, size)) { + if (!PACKET_get_bytes(&local_ext, &etick, size)) { /* Shouldn't ever happen */ retv = -1; goto end; } - r = tls_decrypt_ticket(s, etick, size, session_id, len, ret); + r = tls_decrypt_ticket(s, etick, size, PACKET_data(session_id), + PACKET_remaining(session_id), ret); switch (r) { case 2: /* ticket couldn't be decrypted */ s->tlsext_ticket_expected = 1; @@ -3043,12 +3004,15 @@ int tls1_process_ticket(SSL *s, PACKET *pkt, unsigned char *session_id, break; } goto end; + } else { + if (!PACKET_forward(&local_ext, size)) { + retv = -1; + goto end; + } } } retv = 0; end: - if (!PACKET_goto_bookmark(pkt, bookmark)) - return -1; return retv; } @@ -3063,6 +3027,7 @@ end: * point to the resulting session. * * Returns: + * -2: fatal error, malloc failure. * -1: fatal error, either from parsing or decrypting the ticket. * 2: the ticket couldn't be decrypted. * 3: a ticket was successfully decrypted and *psess was set. @@ -3077,19 +3042,21 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, const unsigned char *p; int slen, mlen, renew_ticket = 0; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; - HMAC_CTX hctx; + HMAC_CTX *hctx = NULL; EVP_CIPHER_CTX ctx; SSL_CTX *tctx = s->initial_ctx; /* Need at least keyname + iv + some encrypted data */ if (eticklen < 48) return 2; /* Initialize session ticket encryption and HMAC contexts */ - HMAC_CTX_init(&hctx); + hctx = HMAC_CTX_new(); + if (hctx == NULL) + return -2; EVP_CIPHER_CTX_init(&ctx); if (tctx->tlsext_ticket_key_cb) { unsigned char *nctick = (unsigned char *)etick; int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, - &ctx, &hctx, 0); + &ctx, hctx, 0); if (rv < 0) return -1; if (rv == 0) @@ -3100,25 +3067,29 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, /* Check key name matches */ if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) return 2; - HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - EVP_sha256(), NULL); - EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, etick + 16); + if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key, 16, + EVP_sha256(), NULL) <= 0 + || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, + etick + 16) <= 0) { + goto err; + } } /* * Attempt to process session ticket, first conduct sanity and integrity * checks on ticket. */ - mlen = HMAC_size(&hctx); + mlen = HMAC_size(hctx); if (mlen < 0) { - EVP_CIPHER_CTX_cleanup(&ctx); - return -1; + goto err; } eticklen -= mlen; /* Check HMAC of encrypted ticket */ - HMAC_Update(&hctx, etick, eticklen); - HMAC_Final(&hctx, tick_hmac, NULL); - HMAC_CTX_cleanup(&hctx); + if (HMAC_Update(hctx, etick, eticklen) <= 0 + || HMAC_Final(hctx, tick_hmac, NULL) <= 0) { + goto err; + } + HMAC_CTX_free(hctx); if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { EVP_CIPHER_CTX_cleanup(&ctx); return 2; @@ -3128,11 +3099,11 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); sdec = OPENSSL_malloc(eticklen); - if (!sdec) { + if (sdec == NULL + || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { EVP_CIPHER_CTX_cleanup(&ctx); return -1; } - EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen); if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { EVP_CIPHER_CTX_cleanup(&ctx); OPENSSL_free(sdec); @@ -3165,6 +3136,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, * For session parse failure, indicate that we need to send a new ticket. */ return 2; +err: + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_free(hctx); + return -1; } /* Tables to translate from NIDs to TLS v1.2 ids */ @@ -3180,13 +3155,19 @@ static const tls12_lookup tls12_md[] = { {NID_sha224, TLSEXT_hash_sha224}, {NID_sha256, TLSEXT_hash_sha256}, {NID_sha384, TLSEXT_hash_sha384}, - {NID_sha512, TLSEXT_hash_sha512} + {NID_sha512, TLSEXT_hash_sha512}, + {NID_id_GostR3411_94, TLSEXT_hash_gostr3411}, + {NID_id_GostR3411_2012_256, TLSEXT_hash_gostr34112012_256}, + {NID_id_GostR3411_2012_512, TLSEXT_hash_gostr34112012_512}, }; static const tls12_lookup tls12_sig[] = { {EVP_PKEY_RSA, TLSEXT_signature_rsa}, {EVP_PKEY_DSA, TLSEXT_signature_dsa}, - {EVP_PKEY_EC, TLSEXT_signature_ecdsa} + {EVP_PKEY_EC, TLSEXT_signature_ecdsa}, + {NID_id_GostR3410_2001, TLSEXT_signature_gostr34102001}, + {NID_id_GostR3410_2012_256, TLSEXT_signature_gostr34102012_256}, + {NID_id_GostR3410_2012_512, TLSEXT_signature_gostr34102012_512} }; static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen) @@ -3234,29 +3215,35 @@ int tls12_get_sigid(const EVP_PKEY *pk) typedef struct { int nid; int secbits; - const EVP_MD *(*mfunc) (void); + int md_idx; + unsigned char tlsext_hash; } tls12_hash_info; static const tls12_hash_info tls12_md_info[] = { -#ifdef OPENSSL_NO_MD5 - {NID_md5, 64, 0}, -#else - {NID_md5, 64, EVP_md5}, -#endif - {NID_sha1, 80, EVP_sha1}, - {NID_sha224, 112, EVP_sha224}, - {NID_sha256, 128, EVP_sha256}, - {NID_sha384, 192, EVP_sha384}, - {NID_sha512, 256, EVP_sha512} + {NID_md5, 64, SSL_MD_MD5_IDX, TLSEXT_hash_md5}, + {NID_sha1, 80, SSL_MD_SHA1_IDX, TLSEXT_hash_sha1}, + {NID_sha224, 112, SSL_MD_SHA224_IDX, TLSEXT_hash_sha224}, + {NID_sha256, 128, SSL_MD_SHA256_IDX, TLSEXT_hash_sha256}, + {NID_sha384, 192, SSL_MD_SHA384_IDX, TLSEXT_hash_sha384}, + {NID_sha512, 256, SSL_MD_SHA512_IDX, TLSEXT_hash_sha512}, + {NID_id_GostR3411_94, 128, SSL_MD_GOST94_IDX, TLSEXT_hash_gostr3411}, + {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX, TLSEXT_hash_gostr34112012_256}, + {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX, TLSEXT_hash_gostr34112012_512}, }; static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg) { + unsigned int i; if (hash_alg == 0) return NULL; - if (hash_alg > OSSL_NELEM(tls12_md_info)) - return NULL; - return tls12_md_info + hash_alg - 1; + + for (i=0; i < OSSL_NELEM(tls12_md_info); i++) + { + if (tls12_md_info[i].tlsext_hash == hash_alg) + return tls12_md_info + i; + } + + return NULL; } const EVP_MD *tls12_get_hash(unsigned char hash_alg) @@ -3265,9 +3252,9 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg) if (hash_alg == TLSEXT_hash_md5 && FIPS_mode()) return NULL; inf = tls12_get_hash_info(hash_alg); - if (!inf || !inf->mfunc) + if (!inf) return NULL; - return inf->mfunc(); + return ssl_md(inf->md_idx); } static int tls12_get_pkey_idx(unsigned char sig_alg) @@ -3285,6 +3272,16 @@ static int tls12_get_pkey_idx(unsigned char sig_alg) case TLSEXT_signature_ecdsa: return SSL_PKEY_ECC; #endif +# ifndef OPENSSL_NO_GOST + case TLSEXT_signature_gostr34102001: + return SSL_PKEY_GOST01; + + case TLSEXT_signature_gostr34102012_256: + return SSL_PKEY_GOST12_256; + + case TLSEXT_signature_gostr34102012_512: + return SSL_PKEY_GOST12_512; +# endif } return -1; } @@ -3319,7 +3316,7 @@ static int tls12_sigalg_allowed(SSL *s, int op, const unsigned char *ptmp) { /* See if we have an entry in the hash table and it is enabled */ const tls12_hash_info *hinf = tls12_get_hash_info(ptmp[0]); - if (!hinf || !hinf->mfunc) + if (hinf == NULL || ssl_md(hinf->md_idx) == NULL) return 0; /* See if public key algorithm allowed */ if (tls12_get_pkey_idx(ptmp[1]) == -1) @@ -3334,7 +3331,7 @@ static int tls12_sigalg_allowed(SSL *s, int op, const unsigned char *ptmp) * disabled. */ -void ssl_set_sig_mask(unsigned long *pmask_a, SSL *s, int op) +void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) { const unsigned char *sigalgs; size_t i, sigalgslen; @@ -3454,7 +3451,7 @@ static int tls1_set_shared_sigalgs(SSL *s) nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); - if (!salgs) + if (salgs == NULL) return 0; nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); } else { @@ -3559,6 +3556,14 @@ int tls1_process_sigalgs(SSL *s) if (pmd[SSL_PKEY_ECC] == NULL) pmd[SSL_PKEY_ECC] = EVP_sha1(); #endif +# ifndef OPENSSL_NO_GOST + if (pmd[SSL_PKEY_GOST01] == NULL) + pmd[SSL_PKEY_GOST01] = EVP_get_digestbynid(NID_id_GostR3411_94); + if (pmd[SSL_PKEY_GOST12_256] == NULL) + pmd[SSL_PKEY_GOST12_256] = EVP_get_digestbynid(NID_id_GostR3411_2012_256); + if (pmd[SSL_PKEY_GOST12_512] == NULL) + pmd[SSL_PKEY_GOST12_512] = EVP_get_digestbynid(NID_id_GostR3411_2012_512); +# endif } return 1; } @@ -3704,17 +3709,11 @@ int tls1_heartbeat(SSL *s) } /* ...and no handshake in progress. */ - if (SSL_in_init(s) || s->in_handshake) { + if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) { SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); return -1; } - /* - * Check if padding is too long, payload and padding must not exceed 2^14 - * - 3 = 16381 bytes in total. - */ - OPENSSL_assert(payload + padding <= 16381); - /*- * Create HeartBeat message, we just use a sequence number * as payload to distuingish different messages and add @@ -3962,7 +3961,6 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, idx = ssl_cert_type(x, pk); if (idx == -1) return 0; - cpk = c->pkeys + idx; pvalid = s->s3->tmp.valid_flags + idx; if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) @@ -4013,6 +4011,21 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, default_nid = NID_ecdsa_with_SHA1; break; + case SSL_PKEY_GOST01: + rsign = TLSEXT_signature_gostr34102001; + default_nid = NID_id_GostR3411_94_with_GostR3410_2001; + break; + + case SSL_PKEY_GOST12_256: + rsign = TLSEXT_signature_gostr34102012_256; + default_nid = NID_id_tc26_signwithdigest_gost3410_2012_256; + break; + + case SSL_PKEY_GOST12_512: + rsign = TLSEXT_signature_gostr34102012_512; + default_nid = NID_id_tc26_signwithdigest_gost3410_2012_512; + break; + default: default_nid = -1; break; @@ -4183,6 +4196,9 @@ void tls1_set_cert_validity(SSL *s) tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_256); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512); } /* User level utiity function to check a chain is suitable */ @@ -4210,16 +4226,16 @@ DH *ssl_get_auto_dh(SSL *s) if (dh_secbits >= 128) { DH *dhp = DH_new(); - if (!dhp) + if (dhp == NULL) return NULL; dhp->g = BN_new(); - if (dhp->g) + if (dhp->g != NULL) BN_set_word(dhp->g, 2); if (dh_secbits >= 192) dhp->p = get_rfc3526_prime_8192(NULL); else dhp->p = get_rfc3526_prime_3072(NULL); - if (!dhp->p || !dhp->g) { + if (dhp->p == NULL || dhp->g == NULL) { DH_free(dhp); return NULL; }