Have a bit more fun with Span. Change-Id: Iba909603a72ec0d149d9898423c114304a5011fa Reviewed-on: https://boringssl-review.googlesource.com/21644 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc index f865de9..1110e98 100644 --- a/ssl/d1_both.cc +++ b/ssl/d1_both.cc
@@ -574,7 +574,7 @@ // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript // on hs. if (ssl->s3->hs != NULL && - !ssl->s3->hs->transcript.Update(data.data(), data.size())) { + !ssl->s3->hs->transcript.Update(data)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; }
diff --git a/ssl/handshake.cc b/ssl/handshake.cc index 41ff7dc..80b64f3 100644 --- a/ssl/handshake.cc +++ b/ssl/handshake.cc
@@ -216,7 +216,7 @@ return true; } - return hs->transcript.Update(CBS_data(&msg.raw), CBS_len(&msg.raw)); + return hs->transcript.Update(msg.raw); } int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert,
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index 1533411..5466b56 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc
@@ -1028,8 +1028,7 @@ } ScopedCBB transcript; - uint8_t *transcript_data; - size_t transcript_len; + Array<uint8_t> transcript_data; if (!CBB_init(transcript.get(), 2 * SSL3_RANDOM_SIZE + CBS_len(¶meter)) || !CBB_add_bytes(transcript.get(), ssl->s3->client_random, @@ -1038,19 +1037,16 @@ SSL3_RANDOM_SIZE) || !CBB_add_bytes(transcript.get(), CBS_data(¶meter), CBS_len(¶meter)) || - !CBB_finish(transcript.get(), &transcript_data, &transcript_len)) { + !CBBFinishArray(transcript.get(), &transcript_data)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_hs_error; } - int sig_ok = ssl_public_key_verify( - ssl, CBS_data(&signature), CBS_len(&signature), signature_algorithm, - hs->peer_pubkey.get(), transcript_data, transcript_len); - OPENSSL_free(transcript_data); - + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), transcript_data); #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) - sig_ok = 1; + sig_ok = true; ERR_clear_error(); #endif if (!sig_ok) { @@ -1347,19 +1343,15 @@ if (alg_a & SSL_aPSK) { ScopedCBB pms_cbb; CBB child; - uint8_t *new_pms; - size_t new_pms_len; - if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) || !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || !CBB_add_bytes(&child, pms.data(), pms.size()) || !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || - !CBB_finish(pms_cbb.get(), &new_pms, &new_pms_len)) { + !CBBFinishArray(pms_cbb.get(), &pms)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } - pms.Reset(new_pms, new_pms_len); } // The message must be added to the finished hash before calculating the @@ -1438,9 +1430,9 @@ return ssl_hs_error; } } else { - switch (ssl_private_key_sign( - hs, ptr, &sig_len, max_sig_len, signature_algorithm, - hs->transcript.buffer_data(), hs->transcript.buffer_len())) { + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, + hs->transcript.buffer())) { case ssl_private_key_success: break; case ssl_private_key_failure:
diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc index 74bfce9..7b282d8 100644 --- a/ssl/handshake_server.cc +++ b/ssl/handshake_server.cc
@@ -876,8 +876,7 @@ size_t sig_len; switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, - signature_algorithm, hs->server_params.data(), - hs->server_params.size())) { + signature_algorithm, hs->server_params)) { case ssl_private_key_success: if (!CBB_did_write(&child, sig_len)) { return ssl_hs_error; @@ -1113,8 +1112,7 @@ size_t decrypt_len; switch (ssl_private_key_decrypt(hs, decrypt_buf.data(), &decrypt_len, decrypt_buf.size(), - CBS_data(&encrypted_premaster_secret), - CBS_len(&encrypted_premaster_secret))) { + encrypted_premaster_secret)) { case ssl_private_key_success: break; case ssl_private_key_failure: @@ -1226,8 +1224,6 @@ ScopedCBB new_premaster; CBB child; - uint8_t *new_data; - size_t new_len; if (!CBB_init(new_premaster.get(), 2 + psk_len + 2 + premaster_secret.size()) || !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || @@ -1235,12 +1231,10 @@ premaster_secret.size()) || !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || !CBB_add_bytes(&child, psk, psk_len) || - !CBB_finish(new_premaster.get(), &new_data, &new_len)) { + !CBBFinishArray(new_premaster.get(), &premaster_secret)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return ssl_hs_error; } - - premaster_secret.Reset(new_data, new_len); } if (!ssl_hash_message(hs, msg)) { @@ -1312,7 +1306,7 @@ return ssl_hs_error; } - int sig_ok; + bool sig_ok; // The SSL3 construction for CertificateVerify does not decompose into a // single final digest and signature, and must be special-cased. if (ssl_protocol_version(ssl) == SSL3_VERSION) { @@ -1330,14 +1324,13 @@ EVP_PKEY_verify(pctx.get(), CBS_data(&signature), CBS_len(&signature), digest, digest_len); } else { - sig_ok = ssl_public_key_verify( - ssl, CBS_data(&signature), CBS_len(&signature), signature_algorithm, - hs->peer_pubkey.get(), hs->transcript.buffer_data(), - hs->transcript.buffer_len()); + sig_ok = + ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), hs->transcript.buffer()); } #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) - sig_ok = 1; + sig_ok = true; ERR_clear_error(); #endif if (!sig_ok) {
diff --git a/ssl/internal.h b/ssl/internal.h index 092ad8c..4c1f9ea 100644 --- a/ssl/internal.h +++ b/ssl/internal.h
@@ -545,10 +545,10 @@ // to call this function after the handshake buffer is released. bool InitHash(uint16_t version, const SSL_CIPHER *cipher); - const uint8_t *buffer_data() const { - return reinterpret_cast<const uint8_t *>(buffer_->data); + Span<const uint8_t> buffer() { + return MakeConstSpan(reinterpret_cast<const uint8_t *>(buffer_->data), + buffer_->length); } - size_t buffer_len() const { return buffer_->length; } // FreeBuffer releases the handshake buffer. Subsequent calls to // |Update| will not update the handshake buffer. @@ -563,7 +563,7 @@ // Update adds |in| to the handshake buffer and handshake hash, whichever is // enabled. It returns true on success and false on failure. - bool Update(const uint8_t *in, size_t in_len); + bool Update(Span<const uint8_t> in); // GetHash writes the handshake hash to |out| which must have room for at // least |DigestLen| bytes. On success, it returns true and sets |*out_len| to @@ -877,22 +877,24 @@ enum ssl_private_key_result_t ssl_private_key_sign( SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, - uint16_t sigalg, const uint8_t *in, size_t in_len); + uint16_t sigalg, Span<const uint8_t> in); -enum ssl_private_key_result_t ssl_private_key_decrypt( - SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, - const uint8_t *in, size_t in_len); +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span<const uint8_t> in); -// ssl_private_key_supports_signature_algorithm returns one if |hs|'s private -// key supports |sigalg| and zero otherwise. -int ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, +// ssl_private_key_supports_signature_algorithm returns whether |hs|'s private +// key supports |sigalg|. +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t sigalg); // ssl_public_key_verify verifies that the |signature| is valid for the public // key |pkey| and input |in|, using the signature algorithm |sigalg|. -int ssl_public_key_verify(SSL *ssl, const uint8_t *signature, - size_t signature_len, uint16_t sigalg, EVP_PKEY *pkey, - const uint8_t *in, size_t in_len); +bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span<const uint8_t> in); // Custom extensions @@ -1533,11 +1535,10 @@ // tls13_get_cert_verify_signature_input generates the message to be signed for // TLS 1.3's CertificateVerify message. |cert_verify_context| determines the -// type of signature. It sets |*out| and |*out_len| to a newly allocated buffer -// containing the result. The caller must free it with |OPENSSL_free| to release -// it. This function returns one on success and zero on failure. -int tls13_get_cert_verify_signature_input( - SSL_HANDSHAKE *hs, uint8_t **out, size_t *out_len, +// type of signature. It sets |*out| to a newly allocated buffer containing the +// result. This function returns true on success and false on failure. +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array<uint8_t> *out, enum ssl_cert_verify_context_t cert_verify_context); // ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc index b2edc9e..3cc01e9 100644 --- a/ssl/s3_both.cc +++ b/ssl/s3_both.cc
@@ -198,7 +198,7 @@ // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on // hs. if (ssl->s3->hs != NULL && - !ssl->s3->hs->transcript.Update(msg.data(), msg.size())) { + !ssl->s3->hs->transcript.Update(msg)) { return 0; } return 1; @@ -345,8 +345,7 @@ // The V2ClientHello without the length is incorporated into the handshake // hash. This is only ever called at the start of the handshake, so hs is // guaranteed to be non-NULL. - if (!ssl->s3->hs->transcript.Update(CBS_data(&v2_client_hello), - CBS_len(&v2_client_hello))) { + if (!ssl->s3->hs->transcript.Update(v2_client_hello)) { return -1; }
diff --git a/ssl/ssl_privkey.cc b/ssl/ssl_privkey.cc index a07f291..b00613d 100644 --- a/ssl/ssl_privkey.cc +++ b/ssl/ssl_privkey.cc
@@ -222,16 +222,16 @@ enum ssl_private_key_result_t ssl_private_key_sign( SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, - uint16_t sigalg, const uint8_t *in, size_t in_len) { + uint16_t sigalg, Span<const uint8_t> in) { SSL *const ssl = hs->ssl; if (ssl->cert->key_method != NULL) { enum ssl_private_key_result_t ret; if (hs->pending_private_key_op) { ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); } else { - ret = (ssl->cert->key_method->sign != NULL - ? ssl->cert->key_method->sign - : legacy_sign)(ssl, out, out_len, max_out, sigalg, in, in_len); + ret = (ssl->cert->key_method->sign != NULL ? ssl->cert->key_method->sign + : legacy_sign)( + ssl, out, out_len, max_out, sigalg, in.data(), in.size()); } hs->pending_private_key_op = ret == ssl_private_key_retry; return ret; @@ -240,31 +240,34 @@ *out_len = max_out; ScopedEVP_MD_CTX ctx; if (!setup_ctx(ssl, ctx.get(), ssl->cert->privatekey, sigalg, 0 /* sign */) || - !EVP_DigestSign(ctx.get(), out, out_len, in, in_len)) { + !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { return ssl_private_key_failure; } return ssl_private_key_success; } -int ssl_public_key_verify(SSL *ssl, const uint8_t *signature, - size_t signature_len, uint16_t sigalg, EVP_PKEY *pkey, - const uint8_t *in, size_t in_len) { +bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span<const uint8_t> in) { ScopedEVP_MD_CTX ctx; return setup_ctx(ssl, ctx.get(), pkey, sigalg, 1 /* verify */) && - EVP_DigestVerify(ctx.get(), signature, signature_len, in, in_len); + EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), + in.data(), in.size()); } -enum ssl_private_key_result_t ssl_private_key_decrypt( - SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, - const uint8_t *in, size_t in_len) { +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span<const uint8_t> in) { SSL *const ssl = hs->ssl; if (ssl->cert->key_method != NULL) { enum ssl_private_key_result_t ret; if (hs->pending_private_key_op) { ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); } else { - ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in, - in_len); + ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, + in.data(), in.size()); } hs->pending_private_key_op = ret == ssl_private_key_retry; return ret; @@ -279,17 +282,18 @@ // Decrypt with no padding. PKCS#1 padding will be removed as part of the // timing-sensitive code by the caller. - if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) { + if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(), + RSA_NO_PADDING)) { return ssl_private_key_failure; } return ssl_private_key_success; } -int ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, - uint16_t sigalg) { +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg) { SSL *const ssl = hs->ssl; if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) { - return 0; + return false; } // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that @@ -301,7 +305,7 @@ const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) < 2 * EVP_MD_size(alg->digest_func()) + 2) { - return 0; + return false; } // Newer algorithms require message-based private keys. @@ -309,10 +313,10 @@ if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL && !legacy_sign_digest_supported(alg)) { - return 0; + return false; } - return 1; + return true; } } // namespace bssl
diff --git a/ssl/ssl_transcript.cc b/ssl/ssl_transcript.cc index b9c1713..8bddbe2 100644 --- a/ssl/ssl_transcript.cc +++ b/ssl/ssl_transcript.cc
@@ -209,26 +209,26 @@ return EVP_MD_CTX_md(hash_.get()); } -bool SSLTranscript::Update(const uint8_t *in, size_t in_len) { +bool SSLTranscript::Update(Span<const uint8_t> in) { // Depending on the state of the handshake, either the handshake buffer may be // active, the rolling hash, or both. if (buffer_) { - size_t new_len = buffer_->length + in_len; - if (new_len < in_len) { + size_t new_len = buffer_->length + in.size(); + if (new_len < in.size()) { OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); return false; } if (!BUF_MEM_grow(buffer_.get(), new_len)) { return false; } - OPENSSL_memcpy(buffer_->data + new_len - in_len, in, in_len); + OPENSSL_memcpy(buffer_->data + new_len - in.size(), in.data(), in.size()); } if (EVP_MD_CTX_md(hash_.get()) != NULL) { - EVP_DigestUpdate(hash_.get(), in, in_len); + EVP_DigestUpdate(hash_.get(), in.data(), in.size()); } if (EVP_MD_CTX_md(md5_.get()) != NULL) { - EVP_DigestUpdate(md5_.get(), in, in_len); + EVP_DigestUpdate(md5_.get(), in.data(), in.size()); } return true;
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc index 3ebb15d..32a0471 100644 --- a/ssl/t1_lib.cc +++ b/ssl/t1_lib.cc
@@ -3330,15 +3330,13 @@ int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) { SSL *const ssl = hs->ssl; if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { - uint8_t *msg; - size_t msg_len; - if (!tls13_get_cert_verify_signature_input(hs, &msg, &msg_len, + Array<uint8_t> msg; + if (!tls13_get_cert_verify_signature_input(hs, &msg, ssl_cert_verify_channel_id)) { return 0; } - SHA256(msg, msg_len, out); + SHA256(msg.data(), msg.size(), out); *out_len = SHA256_DIGEST_LENGTH; - OPENSSL_free(msg); return 1; }
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc index 1e7bdf1..5796bf4 100644 --- a/ssl/tls13_both.cc +++ b/ssl/tls13_both.cc
@@ -37,57 +37,55 @@ // without being able to return application data. static const uint8_t kMaxKeyUpdates = 32; -int tls13_get_cert_verify_signature_input( - SSL_HANDSHAKE *hs, uint8_t **out, size_t *out_len, +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array<uint8_t> *out, enum ssl_cert_verify_context_t cert_verify_context) { ScopedCBB cbb; if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; + return false; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(cbb.get(), 0x20)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; + return false; } } - const uint8_t *context; - size_t context_len; + Span<const char> context; if (cert_verify_context == ssl_cert_verify_server) { - // Include the NUL byte. static const char kContext[] = "TLS 1.3, server CertificateVerify"; - context = (const uint8_t *)kContext; - context_len = sizeof(kContext); + context = kContext; } else if (cert_verify_context == ssl_cert_verify_client) { static const char kContext[] = "TLS 1.3, client CertificateVerify"; - context = (const uint8_t *)kContext; - context_len = sizeof(kContext); + context = kContext; } else if (cert_verify_context == ssl_cert_verify_channel_id) { static const char kContext[] = "TLS 1.3, Channel ID"; - context = (const uint8_t *)kContext; - context_len = sizeof(kContext); + context = kContext; } else { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; + return false; } - if (!CBB_add_bytes(cbb.get(), context, context_len)) { + // Note |context| includes the NUL byte separator. + if (!CBB_add_bytes(cbb.get(), + reinterpret_cast<const uint8_t *>(context.data()), + context.size())) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; + return false; } uint8_t context_hash[EVP_MAX_MD_SIZE]; size_t context_hash_len; if (!hs->transcript.GetHash(context_hash, &context_hash_len) || !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || - !CBB_finish(cbb.get(), out, out_len)) { + !CBBFinishArray(cbb.get(), out)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; + return false; } - return 1; + return true; } int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, @@ -285,21 +283,18 @@ } hs->new_session->peer_signature_algorithm = signature_algorithm; - uint8_t *input = NULL; - size_t input_len; + Array<uint8_t> input; if (!tls13_get_cert_verify_signature_input( - hs, &input, &input_len, + hs, &input, ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; } - UniquePtr<uint8_t> free_input(input); - int sig_ok = ssl_public_key_verify(ssl, CBS_data(&signature), - CBS_len(&signature), signature_algorithm, - hs->peer_pubkey.get(), input, input_len); + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), input); #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) - sig_ok = 1; + sig_ok = true; ERR_clear_error(); #endif if (!sig_ok) { @@ -441,18 +436,16 @@ return ssl_private_key_failure; } - uint8_t *msg = NULL; - size_t msg_len; + Array<uint8_t> msg; if (!tls13_get_cert_verify_signature_input( - hs, &msg, &msg_len, + hs, &msg, ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) { ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_private_key_failure; } - UniquePtr<uint8_t> free_msg(msg); enum ssl_private_key_result_t sign_result = ssl_private_key_sign( - hs, sig, &sig_len, max_sig_len, signature_algorithm, msg, msg_len); + hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); if (sign_result != ssl_private_key_success) { return sign_result; }
diff --git a/ssl/tls13_enc.cc b/ssl/tls13_enc.cc index e4f14c3..6c7e1da 100644 --- a/ssl/tls13_enc.cc +++ b/ssl/tls13_enc.cc
@@ -382,8 +382,8 @@ uint8_t context[EVP_MAX_MD_SIZE]; unsigned context_len; if (!EVP_DigestInit_ex(ctx.get(), digest, NULL) || - !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer_data(), - hs->transcript.buffer_len()) || + !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer().data(), + hs->transcript.buffer().size()) || !EVP_DigestUpdate(ctx.get(), msg, len - hash_len - 3) || !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) { return 0;
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index c48c5b4..09437a5 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc
@@ -668,8 +668,9 @@ assert(hs->hash_len <= 0xff); uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0, static_cast<uint8_t>(hs->hash_len)}; - if (!hs->transcript.Update(header, sizeof(header)) || - !hs->transcript.Update(hs->expected_client_finished, hs->hash_len) || + if (!hs->transcript.Update(header) || + !hs->transcript.Update( + MakeConstSpan(hs->expected_client_finished, hs->hash_len)) || !tls13_derive_resumption_secret(hs) || !add_new_session_tickets(hs)) { return ssl_hs_error;