ret))
return -1;
- if (ret == s->init_num) {
+ if (ret == (int)s->init_num) {
if (s->msg_callback)
s->msg_callback(1, s->version, type, s->init_buf->data,
(size_t)(s->init_off + s->init_num), s,
return (0);
}
-int tls_close_construct_packet(SSL *s, WPACKET *pkt)
+int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype)
{
size_t msglen;
- if (!WPACKET_close(pkt)
+ if ((htype != SSL3_MT_CHANGE_CIPHER_SPEC && !WPACKET_close(pkt))
|| !WPACKET_get_length(pkt, &msglen)
- || msglen > INT_MAX
- || !WPACKET_finish(pkt))
+ || msglen > INT_MAX)
return 0;
s->init_num = (int)msglen;
s->init_off = 0;
return 1;
}
-int tls_construct_finished(SSL *s, const char *sender, int slen)
+int tls_construct_finished(SSL *s, WPACKET *pkt)
{
- unsigned char *p;
int i;
- unsigned long l;
+ const char *sender;
+ int slen;
- p = ssl_handshake_start(s);
+ if (s->server) {
+ sender = s->method->ssl3_enc->server_finished_label;
+ slen = s->method->ssl3_enc->server_finished_label_len;
+ } else {
+ sender = s->method->ssl3_enc->client_finished_label;
+ slen = s->method->ssl3_enc->client_finished_label_len;
+ }
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
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
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;
-
- p = (unsigned char *)s->init_buf->data;
- *p = SSL3_MT_CCS;
- s->init_num = 1;
- s->init_off = 0;
+ 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;
+ }
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)
{
- WPACKET pkt;
-
- if (!WPACKET_init(&pkt, s->init_buf)) {
- /* Should not happen */
- SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (!ssl_set_handshake_header2(s, &pkt, SSL3_MT_CERTIFICATE)
- || !WPACKET_start_sub_packet_u24(&pkt)) {
- SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (!ssl_add_cert_chain(s, &pkt, cpk))
- goto err;
-
- if (!WPACKET_close(&pkt) || !ssl_close_construct_packet(s, &pkt)) {
+ 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);
- goto err;
+ return 0;
}
return 1;
- err:
- WPACKET_cleanup(&pkt);
- return 0;
}
WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
/* s->init_num < SSL3_HM_HEADER_LENGTH */
int skip_message, i, recvd_type, al;
unsigned char *p;
- unsigned long l;
+ size_t l, read;
p = (unsigned char *)s->init_buf->data;
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type,
&p[s->init_num],
SSL3_HM_HEADER_LENGTH - s->init_num,
- 0);
+ 0, &read);
if (i <= 0) {
s->rwstate = SSL_READING;
return 0;
* 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) {
+ if (s->init_num != 0 || read != 1 || p[0] != SSL3_MT_CCS) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER,
SSL_R_BAD_CHANGE_CIPHER_SPEC);
goto f_err;
}
s->s3->tmp.message_type = *mt = SSL3_MT_CHANGE_CIPHER_SPEC;
- s->init_num = i - 1;
- s->s3->tmp.message_size = i;
+ s->init_num = read - 1;
+ s->s3->tmp.message_size = read;
return 1;
} else if (recvd_type != SSL3_RT_HANDSHAKE) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_CCS_RECEIVED_EARLY);
goto f_err;
}
- s->init_num += i;
+ s->init_num += read;
}
skip_message = 0;
*/
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;
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;
return 1;
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
- err:
return 0;
}
-int tls_get_message_body(SSL *s, unsigned long *len)
+int tls_get_message_body(SSL *s, size_t *len)
{
- long n;
+ size_t n, read;
unsigned char *p;
int i;
n = s->s3->tmp.message_size - s->init_num;
while (n > 0) {
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
- &p[s->init_num], n, 0);
+ &p[s->init_num], n, 0, &read);
if (i <= 0) {
s->rwstate = SSL_READING;
*len = 0;
return 0;
}
- s->init_num += i;
- n -= i;
+ s->init_num += read;
+ n -= read;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
s->msg_callback_arg);
}
- /*
- * init_num should never be negative...should probably be declared
- * unsigned
- */
- if (s->init_num < 0) {
- SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- *len = 0;
- return 0;
- }
- *len = (unsigned long)s->init_num;
+ *len = s->init_num;
return 1;
}
const SSL_METHOD *(*smeth) (void);
} version_info;
-#if TLS_MAX_VERSION != TLS1_2_VERSION
-# error Code needs update for TLS_method() support beyond TLS1_2_VERSION.
+#if TLS_MAX_VERSION != TLS1_3_VERSION
+# error Code needs update for TLS_method() support beyond TLS1_3_VERSION.
#endif
static const version_info tls_version_table[] = {
+#ifndef OPENSSL_NO_TLS1_3
+ {TLS1_3_VERSION, tlsv1_3_client_method, tlsv1_3_server_method},
+#else
+ {TLS1_3_VERSION, NULL, NULL},
+#endif
#ifndef OPENSSL_NO_TLS1_2
{TLS1_2_VERSION, tlsv1_2_client_method, tlsv1_2_server_method},
#else