X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_lib.c;h=cac18cc550b47056b25581d532cad55ae7c36d26;hp=258b897a5236550910d8856b89ce6ec21429492a;hb=5923ad4bbe5d13c2fcc11f7849594db838ea57bd;hpb=d166ed8c11e10e9fdaeac182effb9dd318843924 diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 258b897a52..cac18cc550 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -57,22 +57,38 @@ int ssl3_do_write(SSL *s, int type) return (0); } -int tls_construct_finished(SSL *s, const char *sender, int slen) +int tls_close_construct_packet(SSL *s, WPACKET *pkt) { - unsigned char *p; - int i; - unsigned long l; + size_t msglen; + + if (!WPACKET_close(pkt) + || !WPACKET_get_length(pkt, &msglen) + || msglen > INT_MAX) + return 0; + s->init_num = (int)msglen; + s->init_off = 0; - p = ssl_handshake_start(s); + return 1; +} + +int tls_construct_finished(SSL *s, WPACKET *pkt, const char *sender, int slen) +{ + int i; i = s->method->ssl3_enc->final_finish_mac(s, sender, slen, s->s3->tmp.finish_md); - if (i <= 0) - return 0; + if (i <= 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); + goto err; + } + s->s3->tmp.finish_md_len = i; - memcpy(p, s->s3->tmp.finish_md, i); - l = i; + + if (!WPACKET_memcpy(pkt, s->s3->tmp.finish_md, i)) { + SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); + goto err; + } /* * Copy the finished so we can use it for renegotiation checks @@ -87,12 +103,10 @@ int tls_construct_finished(SSL *s, const char *sender, int slen) s->s3->previous_server_finished_len = i; } - if (!ssl_set_handshake_header(s, SSL3_MT_FINISHED, l)) { - SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR); - return 0; - } - return 1; + err: + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; } #ifndef OPENSSL_NO_NEXTPROTONEG @@ -138,13 +152,13 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) */ if (SSL_IS_DTLS(s)) { if ((s->version == DTLS1_BAD_VER - && remain != DTLS1_CCS_HEADER_LENGTH + 1) - || (s->version != DTLS1_BAD_VER - && remain != DTLS1_CCS_HEADER_LENGTH - 1)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, - SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; + && remain != DTLS1_CCS_HEADER_LENGTH + 1) + || (s->version != DTLS1_BAD_VER + && remain != DTLS1_CCS_HEADER_LENGTH - 1)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, + SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto f_err; } } else { if (remain != 0) { @@ -238,36 +252,29 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -int tls_construct_change_cipher_spec(SSL *s) +int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) { - unsigned char *p; + if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } - p = (unsigned char *)s->init_buf->data; - *p = SSL3_MT_CCS; s->init_num = 1; s->init_off = 0; return 1; } -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) +unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) { - unsigned char *p; - unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s); - - if (!ssl_add_cert_chain(s, cpk, &l)) - return 0; - - l -= 3 + SSL_HM_HEADER_LENGTH(s); - p = ssl_handshake_start(s); - l2n3(l, p); - l += 3; - - if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l)) { + if (!WPACKET_start_sub_packet_u24(pkt) + || !ssl_add_cert_chain(s, pkt, cpk) + || !WPACKET_close(pkt)) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR); return 0; } - return l + SSL_HM_HEADER_LENGTH(s); + return 1; } WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst) @@ -331,6 +338,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst) s->d1->handshake_read_seq = 0; s->d1->handshake_write_seq = 0; s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); } } @@ -349,16 +357,18 @@ int tls_get_message_header(SSL *s, int *mt) do { while (s->init_num < SSL3_HM_HEADER_LENGTH) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, - &p[s->init_num], SSL3_HM_HEADER_LENGTH - s->init_num, 0); + &p[s->init_num], + SSL3_HM_HEADER_LENGTH - s->init_num, + 0); if (i <= 0) { s->rwstate = SSL_READING; return 0; } if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { /* - * A ChangeCipherSpec must be a single byte and may not occur - * in the middle of a handshake message. - */ + * A ChangeCipherSpec must be a single byte and may not occur + * in the middle of a handshake message. + */ if (s->init_num != 0 || i != 1 || p[0] != SSL3_MT_CCS) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, @@ -401,21 +411,16 @@ int tls_get_message_header(SSL *s, int *mt) *mt = *p; s->s3->tmp.message_type = *(p++); - if(RECORD_LAYER_is_sslv2_record(&s->rlayer)) { + if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { /* * Only happens with SSLv3+ in an SSLv2 backward compatible * ClientHello + * + * Total message size is the remaining record bytes to read + * plus the SSL3_HM_HEADER_LENGTH bytes that we already read */ - /* - * Total message size is the remaining record bytes to read - * plus the SSL3_HM_HEADER_LENGTH bytes that we already read - */ l = RECORD_LAYER_get_rrec_length(&s->rlayer) + SSL3_HM_HEADER_LENGTH; - if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l)) { - SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, ERR_R_BUF_LIB); - goto err; - } s->s3->tmp.message_size = l; s->init_msg = s->init_buf->data; @@ -428,11 +433,6 @@ int tls_get_message_header(SSL *s, int *mt) SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l && !BUF_MEM_grow_clean(s->init_buf, - (int)l + SSL3_HM_HEADER_LENGTH)) { - SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, ERR_R_BUF_LIB); - goto err; - } s->s3->tmp.message_size = l; s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; @@ -442,7 +442,6 @@ int tls_get_message_header(SSL *s, int *mt) return 1; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: return 0; } @@ -482,7 +481,7 @@ int tls_get_message_body(SSL *s, unsigned long *len) #endif /* Feed this message into MAC computation. */ - if(RECORD_LAYER_is_sslv2_record(&s->rlayer)) { + if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num)) { SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_EVP_LIB); @@ -491,11 +490,11 @@ int tls_get_message_body(SSL *s, unsigned long *len) return 0; } if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, + s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, (size_t)s->init_num, s, s->msg_callback_arg); } else { if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH)) { + s->init_num + SSL3_HM_HEADER_LENGTH)) { SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_EVP_LIB); ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); *len = 0; @@ -521,10 +520,9 @@ int tls_get_message_body(SSL *s, unsigned long *len) return 1; } -int ssl_cert_type(X509 *x, EVP_PKEY *pk) +int ssl_cert_type(const X509 *x, const EVP_PKEY *pk) { - if (pk == NULL && - (pk = X509_get0_pubkey(x)) == NULL) + if (pk == NULL && (pk = X509_get0_pubkey(x)) == NULL) return -1; switch (EVP_PKEY_id(pk)) { @@ -638,8 +636,8 @@ static int version_cmp(const SSL *s, int a, int b) typedef struct { int version; - const SSL_METHOD *(*cmeth)(void); - const SSL_METHOD *(*smeth)(void); + const SSL_METHOD *(*cmeth) (void); + const SSL_METHOD *(*smeth) (void); } version_info; #if TLS_MAX_VERSION != TLS1_2_VERSION @@ -648,26 +646,26 @@ typedef struct { static const version_info tls_version_table[] = { #ifndef OPENSSL_NO_TLS1_2 - { TLS1_2_VERSION, tlsv1_2_client_method, tlsv1_2_server_method }, + {TLS1_2_VERSION, tlsv1_2_client_method, tlsv1_2_server_method}, #else - { TLS1_2_VERSION, NULL, NULL }, + {TLS1_2_VERSION, NULL, NULL}, #endif #ifndef OPENSSL_NO_TLS1_1 - { TLS1_1_VERSION, tlsv1_1_client_method, tlsv1_1_server_method }, + {TLS1_1_VERSION, tlsv1_1_client_method, tlsv1_1_server_method}, #else - { TLS1_1_VERSION, NULL, NULL }, + {TLS1_1_VERSION, NULL, NULL}, #endif #ifndef OPENSSL_NO_TLS1 - { TLS1_VERSION, tlsv1_client_method, tlsv1_server_method }, + {TLS1_VERSION, tlsv1_client_method, tlsv1_server_method}, #else - { TLS1_VERSION, NULL, NULL }, + {TLS1_VERSION, NULL, NULL}, #endif #ifndef OPENSSL_NO_SSL3 - { SSL3_VERSION, sslv3_client_method, sslv3_server_method }, + {SSL3_VERSION, sslv3_client_method, sslv3_server_method}, #else - { SSL3_VERSION, NULL, NULL }, + {SSL3_VERSION, NULL, NULL}, #endif - { 0, NULL, NULL }, + {0, NULL, NULL}, }; #if DTLS_MAX_VERSION != DTLS1_2_VERSION @@ -676,16 +674,18 @@ static const version_info tls_version_table[] = { static const version_info dtls_version_table[] = { #ifndef OPENSSL_NO_DTLS1_2 - { DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method }, + {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method}, #else - { DTLS1_2_VERSION, NULL, NULL }, + {DTLS1_2_VERSION, NULL, NULL}, #endif #ifndef OPENSSL_NO_DTLS1 - { DTLS1_VERSION, dtlsv1_client_method, dtlsv1_server_method }, + {DTLS1_VERSION, dtlsv1_client_method, dtlsv1_server_method}, + {DTLS1_BAD_VER, dtls_bad_ver_client_method, NULL}, #else - { DTLS1_VERSION, NULL, NULL }, + {DTLS1_VERSION, NULL, NULL}, + {DTLS1_BAD_VER, NULL, NULL}, #endif - { 0, NULL, NULL }, + {0, NULL, NULL}, }; /* @@ -706,7 +706,7 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method) return SSL_R_VERSION_TOO_LOW; if (s->max_proto_version != 0 && - version_cmp(s, version, s->max_proto_version) > 0) + version_cmp(s, version, s->max_proto_version) > 0) return SSL_R_VERSION_TOO_HIGH; if ((s->options & method->mask) != 0) @@ -793,8 +793,7 @@ int ssl_check_version_downgrade(SSL *s) } for (vent = table; vent->version != 0; ++vent) { - if (vent->smeth != NULL && - ssl_method_error(s, vent->smeth()) == 0) + if (vent->smeth != NULL && ssl_method_error(s, vent->smeth()) == 0) return s->version == vent->version; } return 0; @@ -848,7 +847,7 @@ int ssl_set_version_bound(int method_version, int version, int *bound) case DTLS_ANY_VERSION: if (DTLS_VERSION_GT(version, DTLS_MAX_VERSION) || - DTLS_VERSION_LT(version, DTLS1_VERSION)) + DTLS_VERSION_LT(version, DTLS1_BAD_VER)) return 0; break; } @@ -994,7 +993,8 @@ int ssl_choose_client_version(SSL *s, int version) * Returns 0 on success or an SSL error reason number on failure. On failure * min_version and max_version will also be set to 0. */ -int ssl_get_client_min_max_version(const SSL *s, int *min_version, int *max_version) +int ssl_get_client_min_max_version(const SSL *s, int *min_version, + int *max_version) { int version; int hole;