X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_clnt.c;h=84dcf08bd46c1c50038549b63b9636a3802785cb;hb=0baed5e90b5c211b092a1279b0dac50166cd34d2;hp=35ca8defa90d6b11309e861f61edd7d4850c4cfb;hpb=625b0d514e4f917c1eeaac621e66c6cba29aeae8;p=openssl.git diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 35ca8defa9..84dcf08bd4 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -169,17 +169,6 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) break; case TLS_ST_CR_CERT: - /* - * The CertificateStatus message is optional even if - * |tlsext_status_expected| is set - */ - if (s->tlsext_status_expected && mt == SSL3_MT_CERTIFICATE_STATUS) { - st->hand_state = TLS_ST_CR_CERT_STATUS; - return 1; - } - /* Fall through */ - - case TLS_ST_CR_CERT_STATUS: if (mt == SSL3_MT_FINISHED) { st->hand_state = TLS_ST_CR_FINISHED; return 1; @@ -1011,7 +1000,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) } /* TLS extensions */ - if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, &al)) { + if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, NULL, 0, &al)) { ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); return 0; @@ -1186,8 +1175,9 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) s->session->ssl_version = s->version; s->session->session_id_length = session_id_len; /* session_id_len could be 0 */ - memcpy(s->session->session_id, PACKET_data(&session_id), - session_id_len); + if (session_id_len > 0) + memcpy(s->session->session_id, PACKET_data(&session_id), + session_id_len); } /* Session version and negotiated protocol version should match */ @@ -1311,7 +1301,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) context = SSL_IS_TLS13(s) ? EXT_TLS1_3_SERVER_HELLO : EXT_TLS1_2_SERVER_HELLO; if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al) - || !tls_parse_all_extensions(s, context, extensions, &al)) + || !tls_parse_all_extensions(s, context, extensions, NULL, 0, &al)) goto f_err; #ifndef OPENSSL_NO_SCTP @@ -1330,7 +1320,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) sizeof(sctpauthkey), labelbuffer, sizeof(labelbuffer), NULL, 0, 0) <= 0) - goto err; + goto f_err; BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, @@ -1370,19 +1360,23 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) const unsigned char *certstart, *certbytes; STACK_OF(X509) *sk = NULL; EVP_PKEY *pkey = NULL; + size_t chain; + unsigned int context = 0; if ((sk = sk_X509_new_null()) == NULL) { SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto err; } - if (!PACKET_get_net_3(pkt, &cert_list_len) - || PACKET_remaining(pkt) != cert_list_len) { + if ((SSL_IS_TLS13(s) && !PACKET_get_1(pkt, &context)) + || context != 0 + || !PACKET_get_net_3(pkt, &cert_list_len) + || PACKET_remaining(pkt) != cert_list_len) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); goto f_err; } - while (PACKET_remaining(pkt)) { + for (chain = 0; PACKET_remaining(pkt); chain++) { if (!PACKET_get_net_3(pkt, &cert_len) || !PACKET_get_bytes(pkt, &certbytes, cert_len)) { al = SSL_AD_DECODE_ERROR; @@ -1404,6 +1398,23 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } + + if (SSL_IS_TLS13(s)) { + RAW_EXTENSION *rawexts = NULL; + PACKET extensions; + + if (!PACKET_get_length_prefixed_2(pkt, &extensions)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_BAD_LENGTH); + goto f_err; + } + if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE, + &rawexts, &al) + || !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE, + rawexts, x, chain, &al)) + goto f_err; + } + if (!sk_X509_push(sk, x)) { SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto err; @@ -2169,41 +2180,57 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) return MSG_PROCESS_ERROR; } -MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) +/* + * In TLSv1.3 this is called from the extensions code, otherwise it is used to + * parse a separate message. Returns 1 on success or 0 on failure. On failure + * |*al| is populated with a suitable alert code. + */ +int tls_process_cert_status_body(SSL *s, PACKET *pkt, int *al) { - int al; size_t resplen; unsigned int type; if (!PACKET_get_1(pkt, &type) || type != TLSEXT_STATUSTYPE_ocsp) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); - goto f_err; + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS_BODY, + SSL_R_UNSUPPORTED_STATUS_TYPE); + return 0; } if (!PACKET_get_net_3_len(pkt, &resplen) || PACKET_remaining(pkt) != resplen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS_BODY, SSL_R_LENGTH_MISMATCH); + return 0; } s->tlsext_ocsp_resp = OPENSSL_malloc(resplen); if (s->tlsext_ocsp_resp == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS_BODY, ERR_R_MALLOC_FAILURE); + return 0; } if (!PACKET_copy_bytes(pkt, s->tlsext_ocsp_resp, resplen)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS_BODY, SSL_R_LENGTH_MISMATCH); + return 0; } s->tlsext_ocsp_resplen = resplen; + + return 1; +} + + +MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt) +{ + int al; + + if (!tls_process_cert_status_body(s, pkt, &al)) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + ossl_statem_set_error(s); + return MSG_PROCESS_ERROR; + } + return MSG_PROCESS_CONTINUE_READING; - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - ossl_statem_set_error(s); - return MSG_PROCESS_ERROR; } /* @@ -2985,11 +3012,19 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) int tls_construct_client_certificate(SSL *s, WPACKET *pkt) { - if (!ssl3_output_cert_chain(s, pkt, + int al = SSL_AD_INTERNAL_ERROR; + + /* + * TODO(TLS1.3): For now we must put an empty context. Needs to be filled in + * later + */ + if ((SSL_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) + || !ssl3_output_cert_chain(s, pkt, (s->s3->tmp.cert_req == 2) ? NULL - : s->cert->key)) { + : s->cert->key, + &al)) { SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, al); return 0; } @@ -3107,19 +3142,10 @@ static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt) goto err; } - /* - * TODO(TLS1.3): For now we are processing Encrypted Extensions and - * Certificate extensions as part of this one message. Later we need to - * split out the Certificate extensions into the Certificate message - */ - if (!tls_collect_extensions(s, &extensions, - EXT_TLS1_3_ENCRYPTED_EXTENSIONS - | EXT_TLS1_3_CERTIFICATE, + if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS, &rawexts, &al) - || !tls_parse_all_extensions(s, - EXT_TLS1_3_ENCRYPTED_EXTENSIONS - | EXT_TLS1_3_CERTIFICATE, - rawexts, &al)) + || !tls_parse_all_extensions(s, EXT_TLS1_3_ENCRYPTED_EXTENSIONS, + rawexts, NULL, 0, &al)) goto err; OPENSSL_free(rawexts);