return (0);
}
+int tls_close_construct_packet(SSL *s, WPACKET *pkt)
+{
+ size_t msglen;
+
+ if (!WPACKET_close(pkt)
+ || !WPACKET_get_length(pkt, &msglen)
+ || msglen > INT_MAX
+ || !WPACKET_finish(pkt))
+ return 0;
+ s->init_num = (int)msglen;
+ s->init_off = 0;
+
+ return 1;
+}
+
int tls_construct_finished(SSL *s, const char *sender, int slen)
{
- unsigned char *p;
int i;
- unsigned long l;
+ WPACKET pkt;
- p = ssl_handshake_start(s);
+ if (!WPACKET_init(&pkt, s->init_buf)
+ || !ssl_set_handshake_header(s, &pkt, SSL3_MT_FINISHED)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
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)) {
+ if (!ssl_close_construct_packet(s, &pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
- return 0;
+ goto err;
}
return 1;
+ err:
+ ossl_statem_set_error(s);
+ WPACKET_cleanup(&pkt);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return 0;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
*/
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) {
int tls_construct_change_cipher_spec(SSL *s)
{
- unsigned char *p;
+ WPACKET pkt;
+
+ if (!WPACKET_init(&pkt, s->init_buf)
+ || !WPACKET_put_bytes_u8(&pkt, SSL3_MT_CCS)
+ || !WPACKET_finish(&pkt)) {
+ WPACKET_cleanup(&pkt);
+ ossl_statem_set_error(s);
+ 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;
unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
{
- unsigned char *p;
- unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
+ WPACKET pkt;
- if (!ssl_add_cert_chain(s, cpk, &l))
- return 0;
+ 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_header(s, &pkt, SSL3_MT_CERTIFICATE)
+ || !WPACKET_start_sub_packet_u24(&pkt)) {
+ SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
- l -= 3 + SSL_HM_HEADER_LENGTH(s);
- p = ssl_handshake_start(s);
- l2n3(l, p);
- l += 3;
+ if (!ssl_add_cert_chain(s, &pkt, cpk))
+ goto err;
- if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l)) {
+ if (!WPACKET_close(&pkt) || !ssl_close_construct_packet(s, &pkt)) {
SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR);
- return 0;
+ goto err;
}
- return l + SSL_HM_HEADER_LENGTH(s);
+ return 1;
+ err:
+ WPACKET_cleanup(&pkt);
+ return 0;
}
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);
}
}
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,
*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;
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;
}
#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);
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;
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)) {
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
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
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},
};
/*
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)
}
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;
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;
}
* 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;