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;
+ if (mt == SSL3_MT_CERTIFICATE_VERIFY) {
+ st->hand_state = TLS_ST_CR_CERT_VRFY;
return 1;
}
- /* Fall through */
+ break;
- case TLS_ST_CR_CERT_STATUS:
+ case TLS_ST_CR_CERT_VRFY:
if (mt == SSL3_MT_FINISHED) {
st->hand_state = TLS_ST_CR_FINISHED;
return 1;
}
break;
-
}
/* No valid transition found */
case TLS_ST_CR_SRVR_HELLO:
if (s->hit) {
- if (s->tlsext_ticket_expected) {
+ if (s->ext.ticket_expected) {
if (mt == SSL3_MT_NEWSESSION_TICKET) {
st->hand_state = TLS_ST_CR_SESSION_TICKET;
return 1;
st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST;
return 1;
} else if (s->version >= TLS1_VERSION
- && s->tls_session_secret_cb != NULL
- && s->session->tlsext_tick != NULL
+ && s->ext.session_secret_cb != NULL
+ && s->session->ext.tick != NULL
&& mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
/*
* Normally, we can tell if the server is resuming the session
case TLS_ST_CR_CERT:
/*
* The CertificateStatus message is optional even if
- * |tlsext_status_expected| is set
+ * |ext.status_expected| is set
*/
- if (s->tlsext_status_expected && mt == SSL3_MT_CERTIFICATE_STATUS) {
+ if (s->ext.status_expected && mt == SSL3_MT_CERTIFICATE_STATUS) {
st->hand_state = TLS_ST_CR_CERT_STATUS;
return 1;
}
break;
case TLS_ST_CW_FINISHED:
- if (s->tlsext_ticket_expected) {
+ if (s->ext.ticket_expected) {
if (mt == SSL3_MT_NEWSESSION_TICKET) {
st->hand_state = TLS_ST_CR_SESSION_TICKET;
return 1;
#if defined(OPENSSL_NO_NEXTPROTONEG)
st->hand_state = TLS_ST_CW_FINISHED;
#else
- if (!SSL_IS_DTLS(s) && s->s3->next_proto_neg_seen)
+ if (!SSL_IS_DTLS(s) && s->s3->npn_seen)
st->hand_state = TLS_ST_CW_NEXT_PROTO;
else
st->hand_state = TLS_ST_CW_FINISHED;
/*
* Perform any work that needs to be done after sending a message from the
* client to the server.
+ case TLS_ST_SR_CERT_VRFY:
+ return SSL3_RT_MAX_PLAIN_LENGTH;
*/
WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
{
break;
case TLS_ST_CW_CERT_VRFY:
- *confunc = tls_construct_client_verify;
+ *confunc = tls_construct_cert_verify;
*mt = SSL3_MT_CERTIFICATE_VERIFY;
break;
case TLS_ST_CR_CERT:
return s->max_cert_list;
+ case TLS_ST_CR_CERT_VRFY:
+ return SSL3_RT_MAX_PLAIN_LENGTH;
+
case TLS_ST_CR_CERT_STATUS:
return SSL3_RT_MAX_PLAIN_LENGTH;
case TLS_ST_CR_CERT:
return tls_process_server_certificate(s, pkt);
+ case TLS_ST_CR_CERT_VRFY:
+ return tls_process_cert_verify(s, pkt);
+
case TLS_ST_CR_CERT_STATUS:
return tls_process_cert_status(s, pkt);
* In the case of EAP-FAST, we can have a pre-shared
* "ticket" without a session ID.
*/
- (!sess->session_id_length && !sess->tlsext_tick) ||
+ (!sess->session_id_length && !sess->ext.tick) ||
(sess->not_resumable)) {
if (!ssl_get_new_session(s, 0))
return 0;
}
/* 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;
* server wants to resume.
*/
if (s->version >= TLS1_VERSION && !SSL_IS_TLS13(s)
- && s->tls_session_secret_cb != NULL && s->session->tlsext_tick) {
+ && s->ext.session_secret_cb != NULL && s->session->ext.tick) {
const SSL_CIPHER *pref_cipher = NULL;
/*
* s->session->master_key_length is a size_t, but this is an int for
*/
int master_key_length;
master_key_length = sizeof(s->session->master_key);
- if (s->tls_session_secret_cb(s, s->session->master_key,
+ if (s->ext.session_secret_cb(s, s->session->master_key,
&master_key_length,
NULL, &pref_cipher,
- s->tls_session_secret_cb_arg)
+ s->ext.session_secret_cb_arg)
&& master_key_length > 0) {
s->session->master_key_length = master_key_length;
s->session->cipher = pref_cipher ?
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 */
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
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,
const unsigned char *certstart, *certbytes;
STACK_OF(X509) *sk = NULL;
EVP_PKEY *pkey = NULL;
+ size_t chainidx;
+ 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 (chainidx = 0; PACKET_remaining(pkt); chainidx++) {
if (!PACKET_get_net_3(pkt, &cert_len)
|| !PACKET_get_bytes(pkt, &certbytes, cert_len)) {
al = SSL_AD_DECODE_ERROR;
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, chainidx, &al))
+ goto f_err;
+ }
+
if (!sk_X509_push(sk, x)) {
SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
goto err;
X509_up_ref(x);
s->session->peer = x;
s->session->verify_result = s->verify_result;
-
x = NULL;
+
+ /* Save the current hash state for when we receive the CertificateVerify */
+ if (SSL_IS_TLS13(s)
+ && !ssl_handshake_hash(s, s->cert_verify_hash,
+ sizeof(s->cert_verify_hash),
+ &s->cert_verify_hash_len)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+
ret = MSG_PROCESS_CONTINUE_READING;
goto done;
MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
{
- int al = -1;
+ int al = -1, ispss = 0;
long alg_k;
EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *md_ctx = NULL;
+ EVP_PKEY_CTX *pctx = NULL;
PACKET save_param_start, signature;
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
PACKET params;
int maxsig;
const EVP_MD *md = NULL;
- EVP_MD_CTX *md_ctx;
/*
* |pkt| now points to the beginning of the signature, so the difference
}
if (SSL_USE_SIGALGS(s)) {
- const unsigned char *sigalgs;
+ unsigned int sigalg;
int rv;
- if (!PACKET_get_bytes(pkt, &sigalgs, 2)) {
+
+ if (!PACKET_get_net_2(pkt, &sigalg)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto err;
}
- rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey);
+ rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
if (rv == -1) {
al = SSL_AD_INTERNAL_ERROR;
goto err;
al = SSL_AD_DECODE_ERROR;
goto err;
}
+ ispss = SIGID_IS_PSS(sigalg);
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
goto err;
}
- if (EVP_VerifyInit_ex(md_ctx, md, NULL) <= 0
- || EVP_VerifyUpdate(md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_VerifyUpdate(md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_VerifyUpdate(md_ctx, PACKET_data(¶ms),
- PACKET_remaining(¶ms)) <= 0) {
- EVP_MD_CTX_free(md_ctx);
+ if (EVP_DigestVerifyInit(md_ctx, &pctx, md, NULL, pkey) <= 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
}
- /* TODO(size_t): Convert this call */
- if (EVP_VerifyFinal(md_ctx, PACKET_data(&signature),
- (unsigned int)PACKET_remaining(&signature),
- pkey) <= 0) {
+ if (ispss) {
+ if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
+ /* -1 here means set saltlen to the digest len */
+ || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto err;
+ }
+ }
+ if (EVP_DigestVerifyUpdate(md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestVerifyUpdate(md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestVerifyUpdate(md_ctx, PACKET_data(¶ms),
+ PACKET_remaining(¶ms)) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (EVP_DigestVerifyFinal(md_ctx, PACKET_data(&signature),
+ PACKET_remaining(&signature)) <= 0) {
/* bad signature */
- EVP_MD_CTX_free(md_ctx);
al = SSL_AD_DECRYPT_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
goto err;
}
EVP_MD_CTX_free(md_ctx);
+ md_ctx = NULL;
} else {
/* aNULL, aSRP or PSK do not need public keys */
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
if (al != -1)
ssl3_send_alert(s, SSL3_AL_FATAL, al);
ossl_statem_set_error(s);
+ EVP_MD_CTX_free(md_ctx);
return MSG_PROCESS_ERROR;
}
s->s3->tmp.ctype[i] = data[i];
if (SSL_USE_SIGALGS(s)) {
- if (!PACKET_get_net_2(pkt, &list_len)
- || !PACKET_get_bytes(pkt, &data, list_len)) {
+ PACKET sigalgs;
+
+ if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
SSL_R_LENGTH_MISMATCH);
s->s3->tmp.md[i] = NULL;
s->s3->tmp.valid_flags[i] = 0;
}
- if ((list_len & 1) || !tls1_save_sigalgs(s, data, list_len)) {
+ if (!tls1_save_sigalgs(s, &sigalgs)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
SSL_R_SIGNATURE_ALGORITHMS_ERROR);
s->session = new_sess;
}
- OPENSSL_free(s->session->tlsext_tick);
- s->session->tlsext_ticklen = 0;
+ OPENSSL_free(s->session->ext.tick);
+ s->session->ext.tick = NULL;
+ s->session->ext.ticklen = 0;
- s->session->tlsext_tick = OPENSSL_malloc(ticklen);
- if (s->session->tlsext_tick == NULL) {
+ s->session->ext.tick = OPENSSL_malloc(ticklen);
+ if (s->session->ext.tick == NULL) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!PACKET_copy_bytes(pkt, s->session->tlsext_tick, ticklen)) {
+ if (!PACKET_copy_bytes(pkt, s->session->ext.tick, ticklen)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
- s->session->tlsext_ticklen = ticklen;
+ s->session->ext.tick_lifetime_hint = ticket_lifetime_hint;
+ s->session->ext.ticklen = ticklen;
/*
* There are two ways to detect a resumed ticket session. One is to set
* an appropriate session ID and then the server must return a match in
* TODO(size_t): we use sess_len here because EVP_Digest expects an int
* but s->session->session_id_length is a size_t
*/
- if (!EVP_Digest(s->session->tlsext_tick, ticklen,
+ if (!EVP_Digest(s->session->ext.tick, ticklen,
s->session->session_id, &sess_len,
EVP_sha256(), NULL)) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_EVP_LIB);
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;
+ s->ext.ocsp.resp = OPENSSL_malloc(resplen);
+ if (s->ext.ocsp.resp == NULL) {
+ *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;
+ if (!PACKET_copy_bytes(pkt, s->ext.ocsp.resp, resplen)) {
+ *al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS_BODY, SSL_R_LENGTH_MISMATCH);
+ return 0;
}
- s->tlsext_ocsp_resplen = resplen;
+ s->ext.ocsp.resp_len = 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;
}
/*
}
/*
- * Call the ocsp status callback if needed. The |tlsext_ocsp_resp| and
- * |tlsext_ocsp_resplen| values will be set if we actually received a status
+ * Call the ocsp status callback if needed. The |ext.ocsp.resp| and
+ * |ext.ocsp.resp_len| values will be set if we actually received a status
* message, or NULL and -1 otherwise
*/
- if (s->tlsext_status_type != TLSEXT_STATUSTYPE_nothing
- && s->ctx->tlsext_status_cb != NULL) {
- int ret;
- ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+ if (s->ext.status_type != TLSEXT_STATUSTYPE_nothing
+ && s->ctx->ext.status_cb != NULL) {
+ int ret = s->ctx->ext.status_cb(s, s->ctx->ext.status_arg);
+
if (ret == 0) {
*al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
SSLerr(SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT,
return 0;
}
-int tls_construct_client_verify(SSL *s, WPACKET *pkt)
-{
- EVP_PKEY *pkey;
- const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
- EVP_MD_CTX *mctx = NULL;
- unsigned u = 0;
- long hdatalen = 0;
- void *hdata;
- unsigned char *sig = NULL;
-
- mctx = EVP_MD_CTX_new();
- if (mctx == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- pkey = s->cert->key->privatekey;
-
- hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- if (SSL_USE_SIGALGS(s)&& !tls12_get_sigandhash(pkt, pkey, md)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-#ifdef SSL_DEBUG
- fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
-#endif
- sig = OPENSSL_malloc(EVP_PKEY_size(pkey));
- if (sig == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!EVP_SignInit_ex(mctx, md, NULL)
- || !EVP_SignUpdate(mctx, hdata, hdatalen)
- || (s->version == SSL3_VERSION
- && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
- (int)s->session->master_key_length,
- s->session->master_key))
- || !EVP_SignFinal(mctx, sig, &u, pkey)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
- goto err;
- }
-#ifndef OPENSSL_NO_GOST
- {
- int pktype = EVP_PKEY_id(pkey);
- if (pktype == NID_id_GostR3410_2001
- || pktype == NID_id_GostR3410_2012_256
- || pktype == NID_id_GostR3410_2012_512)
- BUF_reverse(sig, NULL, u);
- }
-#endif
-
- if (!WPACKET_sub_memcpy_u16(pkt, sig, u)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- /* Digest cached records and discard handshake buffer */
- if (!ssl3_digest_cached_records(s, 0))
- goto err;
-
- OPENSSL_free(sig);
- EVP_MD_CTX_free(mctx);
- return 1;
- err:
- OPENSSL_free(sig);
- EVP_MD_CTX_free(mctx);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return 0;
-}
-
/*
* Check a certificate can be used for client authentication. Currently check
* cert exists, if we have a suitable digest for TLS 1.2 if static DH client
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;
}
size_t len, padding_len;
unsigned char *padding = NULL;
- len = s->next_proto_negotiated_len;
+ len = s->ext.npn_len;
padding_len = 32 - ((len + 2) % 32);
- if (!WPACKET_sub_memcpy_u8(pkt, s->next_proto_negotiated, len)
+ if (!WPACKET_sub_memcpy_u8(pkt, s->ext.npn, len)
|| !WPACKET_sub_allocate_bytes_u8(pkt, padding_len, &padding)) {
SSLerr(SSL_F_TLS_CONSTRUCT_NEXT_PROTO, ERR_R_INTERNAL_ERROR);
goto err;
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);