X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=eea78029da4ae7ccddb26152a1b1f6ffd1426783;hp=938f8be15f7c9977ee991fe0be7985eb1e4b0bc7;hb=418a18a2deddc0b0d6181de0008219c899ca6ddf;hpb=a230b26e0959dc5f072fbbdadcc9ed45e904c50c diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 938f8be15f..eea78029da 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -41,6 +41,8 @@ SSL3_ENC_METHOD const TLSv1_enc_data = { 0, SSL3_HM_HEADER_LENGTH, ssl3_set_handshake_header, + ssl3_set_handshake_header2, + tls_close_construct_packet, ssl3_handshake_write }; @@ -59,6 +61,8 @@ SSL3_ENC_METHOD const TLSv1_1_enc_data = { SSL_ENC_FLAG_EXPLICIT_IV, SSL3_HM_HEADER_LENGTH, ssl3_set_handshake_header, + ssl3_set_handshake_header2, + tls_close_construct_packet, ssl3_handshake_write }; @@ -78,6 +82,8 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = { | SSL_ENC_FLAG_TLS1_2_CIPHERS, SSL3_HM_HEADER_LENGTH, ssl3_set_handshake_header, + ssl3_set_handshake_header2, + tls_close_construct_packet, ssl3_handshake_write }; @@ -1007,12 +1013,8 @@ static int tls1_check_duplicate_extensions(const PACKET *packet) return ret; } -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al) +int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al) { - int extdatalen = 0; - unsigned char *orig = buf; - unsigned char *ret = buf; #ifndef OPENSSL_NO_EC /* See if we support any ECC ciphersuites */ int using_ecc = 0; @@ -1035,32 +1037,14 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, } #endif - ret += 2; - - if (ret >= limit) - return NULL; /* this really never occurs, but ... */ - /* Add RI if renegotiating */ if (s->renegotiate) { - int el; - - if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_renegotiate, 2) + || !WPACKET_sub_memcpy_u16(pkt, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - if ((limit - ret - 4 - el) < 0) - return NULL; - - s2n(TLSEXT_TYPE_renegotiate, ret); - s2n(el, ret); - - if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - - ret += el; } /* Only add RI for SSLv3 */ if (s->client_version == SSL3_VERSION) @@ -1068,61 +1052,36 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (s->tlsext_hostname != NULL) { /* Add TLS extension servername to the Client Hello message */ - unsigned long size_str; - long lenmax; - - /*- - * check for enough space. - * 4 for the servername type and extension length - * 2 for servernamelist length - * 1 for the hostname type - * 2 for hostname length - * + hostname length - */ - - if ((lenmax = limit - ret - 9) < 0 - || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) - return NULL; - - /* extension type and length */ - s2n(TLSEXT_TYPE_server_name, ret); - s2n(size_str + 5, ret); - - /* length of servername list */ - s2n(size_str + 3, ret); - - /* hostname type, length and hostname */ - *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name; - s2n(size_str, ret); - memcpy(ret, s->tlsext_hostname, size_str); - ret += size_str; + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_server_name, 2) + /* Sub-packet for server_name extension */ + || !WPACKET_start_sub_packet_u16(pkt) + /* Sub-packet for servername list (always 1 hostname)*/ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes(pkt, TLSEXT_NAMETYPE_host_name, 1) + || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname, + strlen(s->tlsext_hostname)) + || !WPACKET_close(pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #ifndef OPENSSL_NO_SRP /* Add SRP username if there is one */ - if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the - * Client Hello message */ - - int login_len = strlen(s->srp_ctx.login); - if (login_len > 255 || login_len == 0) { + if (s->srp_ctx.login != NULL) { + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_srp, 2) + /* Sub-packet for SRP extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_start_sub_packet_u8(pkt) + /* login must not be zero...internal error if so */ + || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH) + || !WPACKET_memcpy(pkt, s->srp_ctx.login, + strlen(s->srp_ctx.login)) + || !WPACKET_close(pkt) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - - /*- - * check for enough space. - * 4 for the srp type type and extension length - * 1 for the srp user identity - * + srp user identity length - */ - if ((limit - ret - 5 - login_len) < 0) - return NULL; - - /* fill in the extension */ - s2n(TLSEXT_TYPE_srp, ret); - s2n(login_len + 1, ret); - (*ret++) = (unsigned char)login_len; - memcpy(ret, s->srp_ctx.login, login_len); - ret += login_len; } #endif @@ -1131,61 +1090,52 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, /* * Add TLS extension ECPointFormats to the ClientHello message */ - long lenmax; const unsigned char *pcurves, *pformats; - size_t num_curves, num_formats, curves_list_len; + size_t num_curves, num_formats; size_t i; - unsigned char *etmp; tls1_get_formatlist(s, &pformats, &num_formats); - if ((lenmax = limit - ret - 5) < 0) - return NULL; - if (num_formats > (size_t)lenmax) - return NULL; - if (num_formats > 255) { + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_ec_point_formats, 2) + /* Sub-packet for formats extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - s2n(TLSEXT_TYPE_ec_point_formats, ret); - /* The point format list has 1-byte length. */ - s2n(num_formats + 1, ret); - *(ret++) = (unsigned char)num_formats; - memcpy(ret, pformats, num_formats); - ret += num_formats; - /* * Add TLS extension EllipticCurves to the ClientHello message */ pcurves = s->tlsext_ellipticcurvelist; - if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) - return NULL; - - if ((lenmax = limit - ret - 6) < 0) - return NULL; - if (num_curves > (size_t)lenmax / 2) - return NULL; - if (num_curves > 65532 / 2) { + if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - s2n(TLSEXT_TYPE_elliptic_curves, ret); - etmp = ret + 4; + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_elliptic_curves, 2) + /* Sub-packet for curves extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_start_sub_packet_u16(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } /* Copy curve ID if supported */ for (i = 0; i < num_curves; i++, pcurves += 2) { if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) { - *etmp++ = pcurves[0]; - *etmp++ = pcurves[1]; + if (!WPACKET_put_bytes(pkt, pcurves[0], 1) + || !WPACKET_put_bytes(pkt, pcurves[1], 1)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, + ERR_R_INTERNAL_ERROR); + return 0; + } } } - - curves_list_len = etmp - ret - 4; - - s2n(curves_list_len + 2, ret); - s2n(curves_list_len, ret); - ret += curves_list_len; + if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #endif /* OPENSSL_NO_EC */ @@ -1197,8 +1147,10 @@ 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 == NULL) - return NULL; + if (s->session->tlsext_tick == NULL) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } memcpy(s->session->tlsext_tick, s->tlsext_session_ticket->data, ticklen); s->session->tlsext_ticklen = ticklen; @@ -1207,17 +1159,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (ticklen == 0 && s->tlsext_session_ticket && s->tlsext_session_ticket->data == NULL) goto skip_ext; - /* - * Check for enough room 2 for extension type, 2 for len rest for - * ticket - */ - if ((long)(limit - ret - 4 - ticklen) < 0) - return NULL; - s2n(TLSEXT_TYPE_session_ticket, ret); - s2n(ticklen, ret); - if (ticklen) { - memcpy(ret, s->session->tlsext_tick, ticklen); - ret += ticklen; + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_session_ticket, 2) + || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick, + ticklen)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; } } skip_ext: @@ -1225,81 +1172,97 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (SSL_CLIENT_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; - unsigned char *etmp; + salglen = tls12_get_psigalgs(s, &salg); - if ((size_t)(limit - ret) < salglen + 6) - return NULL; - s2n(TLSEXT_TYPE_signature_algorithms, ret); - etmp = ret; - /* Skip over lengths for now */ - ret += 4; - salglen = tls12_copy_sigalgs(s, ret, salg, salglen); - /* Fill in lengths */ - s2n(salglen + 2, etmp); - s2n(salglen, etmp); - ret += salglen; + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_signature_algorithms, 2) + /* Sub-packet for sig-algs extension */ + || !WPACKET_start_sub_packet_u16(pkt) + /* Sub-packet for the actual list */ + || !WPACKET_start_sub_packet_u16(pkt) + || !tls12_copy_sigalgs(s, pkt, salg, salglen) + || !WPACKET_close(pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #ifndef OPENSSL_NO_OCSP if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { int i; - long extlen, idlen, itmp; - OCSP_RESPID *id; - idlen = 0; + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_status_request, 2) + /* Sub-packet for status request extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes(pkt, TLSEXT_STATUSTYPE_ocsp, 1) + /* Sub-packet for the ids */ + || !WPACKET_start_sub_packet_u16(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + unsigned char *idbytes; + int idlen; + OCSP_RESPID *id; + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - itmp = i2d_OCSP_RESPID(id, NULL); - if (itmp <= 0) - return NULL; - idlen += itmp + 2; + idlen = i2d_OCSP_RESPID(id, NULL); + if (idlen <= 0 + /* Sub-packet for an individual id */ + || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes) + || i2d_OCSP_RESPID(id, &idbytes) != idlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + } + if (!WPACKET_close(pkt) + || !WPACKET_start_sub_packet_u16(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; } - if (s->tlsext_ocsp_exts) { - extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); - if (extlen < 0) - return NULL; - } else - extlen = 0; + unsigned char *extbytes; + int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); - if ((long)(limit - ret - 7 - extlen - idlen) < 0) - return NULL; - s2n(TLSEXT_TYPE_status_request, ret); - if (extlen + idlen > 0xFFF0) - return NULL; - s2n(extlen + idlen + 5, ret); - *(ret++) = TLSEXT_STATUSTYPE_ocsp; - s2n(idlen, ret); - for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { - /* save position of id len */ - unsigned char *q = ret; - id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - /* skip over id len */ - ret += 2; - itmp = i2d_OCSP_RESPID(id, &ret); - /* write id len */ - s2n(itmp, q); + if (extlen < 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes) + || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes) + != extlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + } + if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; } - s2n(extlen, ret); - if (extlen > 0) - i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); } #endif #ifndef OPENSSL_NO_HEARTBEATS if (SSL_IS_DTLS(s)) { - /* Add Heartbeat extension */ - if ((limit - ret - 4 - 1) < 0) - return NULL; - s2n(TLSEXT_TYPE_heartbeat, ret); - s2n(1, ret); + unsigned int mode; + /*- * Set mode: * 1: peer may send requests * 2: peer not allowed to send requests */ if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS) - *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS; + mode = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS; else - *(ret++) = SSL_DTLSEXT_HB_ENABLED; + mode = SSL_DTLSEXT_HB_ENABLED; + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_heartbeat, 2) + /* Sub-packet for Hearbeat extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes(pkt, mode, 1) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #endif @@ -1309,10 +1272,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * The client advertises an empty extension to indicate its support * for Next Protocol Negotiation */ - if (limit - ret - 4 < 0) - return NULL; - s2n(TLSEXT_TYPE_next_proto_neg, ret); - s2n(0, ret); + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_next_proto_neg, 2) + || !WPACKET_put_bytes(pkt, 0, 2)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #endif @@ -1322,52 +1286,74 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * (see longer comment below) */ if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { - if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) - return NULL; - s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); - s2n(2 + s->alpn_client_proto_list_len, ret); - s2n(s->alpn_client_proto_list_len, ret); - memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len); - ret += s->alpn_client_proto_list_len; + if (!WPACKET_put_bytes(pkt, + TLSEXT_TYPE_application_layer_protocol_negotiation, 2) + /* Sub-packet ALPN extension */ + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list, + s->alpn_client_proto_list_len) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } s->s3->alpn_sent = 1; } #ifndef OPENSSL_NO_SRTP if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { - int el; - - /* Returns 0 on success!! */ - if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) { + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; + SRTP_PROTECTION_PROFILE *prof; + int i, ct; + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_use_srtp, 2) + /* Sub-packet for SRTP extension */ + || !WPACKET_start_sub_packet_u16(pkt) + /* Sub-packet for the protection profile list */ + || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - - if ((limit - ret - 4 - el) < 0) - return NULL; - - s2n(TLSEXT_TYPE_use_srtp, ret); - s2n(el, ret); - - if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { + ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); + for (i = 0; i < ct; i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + if (prof == NULL || !WPACKET_put_bytes(pkt, prof->id, 2)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + } + if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; + return 0; } - ret += el; } #endif custom_ext_init(&s->cert->cli_ext); /* Add custom TLS Extensions to ClientHello */ - if (!custom_ext_add(s, 0, &ret, limit, al)) - return NULL; - s2n(TLSEXT_TYPE_encrypt_then_mac, ret); - s2n(0, ret); + if (!custom_ext_add(s, 0, pkt, al)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_encrypt_then_mac, 2) + || !WPACKET_put_bytes(pkt, 0, 2)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + #ifndef OPENSSL_NO_CT if (s->ct_validation_callback != NULL) { - s2n(TLSEXT_TYPE_signed_certificate_timestamp, ret); - s2n(0, ret); + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_signed_certificate_timestamp, 2) + || !WPACKET_put_bytes(pkt, 0, 2)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } } #endif - s2n(TLSEXT_TYPE_extended_master_secret, ret); - s2n(0, ret); + + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_extended_master_secret, 2) + || !WPACKET_put_bytes(pkt, 0, 2)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } /* * Add padding to workaround bugs in F5 terminators. See @@ -1376,7 +1362,13 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * appear last. */ if (s->options & SSL_OP_TLSEXT_PADDING) { - int hlen = ret - (unsigned char *)s->init_buf->data; + unsigned char *padbytes; + size_t hlen; + + if (!WPACKET_get_total_written(pkt, &hlen)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } if (hlen > 0xff && hlen < 0x200) { hlen = 0x200 - hlen; @@ -1385,20 +1377,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, else hlen = 0; - s2n(TLSEXT_TYPE_padding, ret); - s2n(hlen, ret); - memset(ret, 0, hlen); - ret += hlen; + if (!WPACKET_put_bytes(pkt, TLSEXT_TYPE_padding, 2) + || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + memset(padbytes, 0, hlen); } } done: - - if ((extdatalen = ret - orig - 2) == 0) - return orig; - - s2n(extdatalen, orig); - return ret; + return 1; } unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, @@ -1589,7 +1578,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, } } #endif - if (!custom_ext_add(s, 1, &ret, limit, al)) + if (!custom_ext_add_old(s, 1, &ret, limit, al)) return NULL; if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) { /* @@ -2969,9 +2958,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, 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 */ hctx = HMAC_CTX_new(); if (hctx == NULL) @@ -3018,6 +3005,12 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (mlen < 0) { goto err; } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ + if (eticklen <= + TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) { + ret = 2; + goto err; + } eticklen -= mlen; /* Check HMAC of encrypted ticket */ if (HMAC_Update(hctx, etick, eticklen) <= 0 @@ -3126,7 +3119,32 @@ static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen) return NID_undef; } -int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md) +int tls12_get_sigandhash(WPACKET *pkt, const EVP_PKEY *pk, const EVP_MD *md) +{ + int sig_id, md_id; + + if (md == NULL) + return 0; + md_id = tls12_find_id(EVP_MD_type(md), tls12_md, OSSL_NELEM(tls12_md)); + if (md_id == -1) + return 0; + sig_id = tls12_get_sigid(pk); + if (sig_id == -1) + return 0; + if (!WPACKET_put_bytes(pkt, md_id, 1) || !WPACKET_put_bytes(pkt, sig_id, 1)) + return 0; + + return 1; +} + +/* + * Old version of the tls12_get_sigandhash function used by code that has not + * yet been converted to WPACKET yet. It will be deleted once WPACKET conversion + * is complete. + * TODO - DELETE ME + */ +int tls12_get_sigandhash_old(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md) { int sig_id, md_id; if (!md) @@ -3307,7 +3325,13 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) *pmask_a |= SSL_aECDSA; } -size_t tls12_copy_sigalgs(SSL *s, unsigned char *out, +/* + * Old version of the tls12_copy_sigalgs function used by code that has not + * yet been converted to WPACKET yet. It will be deleted once WPACKET conversion + * is complete. + * TODO - DELETE ME + */ +size_t tls12_copy_sigalgs_old(SSL *s, unsigned char *out, const unsigned char *psig, size_t psiglen) { unsigned char *tmpout = out; @@ -3321,6 +3345,21 @@ size_t tls12_copy_sigalgs(SSL *s, unsigned char *out, return tmpout - out; } +int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, + const unsigned char *psig, size_t psiglen) +{ + size_t i; + + for (i = 0; i < psiglen; i += 2, psig += 2) { + if (tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, psig)) { + if (!WPACKET_put_bytes(pkt, psig[0], 1) + || !WPACKET_put_bytes(pkt, psig[1], 1)) + return 0; + } + } + return 1; +} + /* Given preference and allowed sigalgs set shared sigalgs */ static int tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig, const unsigned char *pref, size_t preflen,