summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2018-11-08 22:28:53 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2018-11-08 22:28:53 +0000
commitb5c0171116390d8c026d9339e8818fc11d3ac528 (patch)
treec69d3877512ba3c6448cf3fad9d054e9fe107479 /lib
parentf0d1394b9bcd3fb89a4ce301cdb802c772b3ec32 (diff)
Clean up and simplify the handshake transcript code.
This provides a cleaner, simpler and more readable API, with code that uses a BUF_MEM instead of a BIO. ok beck@ ("hurry up") and tb@.
Diffstat (limited to 'lib')
-rw-r--r--lib/libssl/d1_both.c6
-rw-r--r--lib/libssl/s3_lib.c9
-rw-r--r--lib/libssl/ssl3.h4
-rw-r--r--lib/libssl/ssl_both.c6
-rw-r--r--lib/libssl/ssl_clnt.c46
-rw-r--r--lib/libssl/ssl_locl.h17
-rw-r--r--lib/libssl/ssl_packet.c4
-rw-r--r--lib/libssl/ssl_srvr.c74
-rw-r--r--lib/libssl/t1_enc.c57
-rw-r--r--lib/libssl/t1_hash.c87
10 files changed, 144 insertions, 166 deletions
diff --git a/lib/libssl/d1_both.c b/lib/libssl/d1_both.c
index 95157630f50..f75604ef68d 100644
--- a/lib/libssl/d1_both.c
+++ b/lib/libssl/d1_both.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_both.c,v 1.55 2018/09/05 16:58:59 jsing Exp $ */
+/* $OpenBSD: d1_both.c,v 1.56 2018/11/08 22:28:52 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -360,7 +360,7 @@ dtls1_do_write(SSL *s, int type)
xlen = ret - DTLS1_HM_HEADER_LENGTH;
}
- tls1_finish_mac(s, p, xlen);
+ tls1_transcript_record(s, p, xlen);
}
if (ret == s->internal->init_num) {
@@ -436,7 +436,7 @@ again:
msg_len += DTLS1_HM_HEADER_LENGTH;
- tls1_finish_mac(s, p, msg_len);
+ tls1_transcript_record(s, p, msg_len);
if (s->internal->msg_callback)
s->internal->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, msg_len,
s, s->internal->msg_callback_arg);
diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c
index 356f43a356a..091713d12a4 100644
--- a/lib/libssl/s3_lib.c
+++ b/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.175 2018/11/08 20:55:18 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.176 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1567,8 +1567,7 @@ ssl3_free(SSL *s)
sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free);
- BIO_free(S3I(s)->handshake_buffer);
-
+ tls1_transcript_free(s);
tls1_handshake_hash_free(s);
free(S3I(s)->alpn_selected);
@@ -1602,9 +1601,7 @@ ssl3_clear(SSL *s)
rlen = S3I(s)->rbuf.len;
wlen = S3I(s)->wbuf.len;
- BIO_free(S3I(s)->handshake_buffer);
- S3I(s)->handshake_buffer = NULL;
-
+ tls1_transcript_free(s);
tls1_handshake_hash_free(s);
free(S3I(s)->alpn_selected);
diff --git a/lib/libssl/ssl3.h b/lib/libssl/ssl3.h
index 726fb9db0b1..cadf7fd3872 100644
--- a/lib/libssl/ssl3.h
+++ b/lib/libssl/ssl3.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl3.h,v 1.48 2018/10/24 18:04:50 jsing Exp $ */
+/* $OpenBSD: ssl3.h,v 1.49 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -350,7 +350,7 @@ typedef struct ssl3_buffer_st {
#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
-#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
+#define TLS1_FLAGS_FREEZE_TRANSCRIPT 0x0020
#define SSL3_FLAGS_CCS_OK 0x0080
#ifndef OPENSSL_NO_SSL_INTERN
diff --git a/lib/libssl/ssl_both.c b/lib/libssl/ssl_both.c
index 81fd1f80c5e..77ab26e8b53 100644
--- a/lib/libssl/ssl_both.c
+++ b/lib/libssl/ssl_both.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_both.c,v 1.13 2018/10/24 18:04:50 jsing Exp $ */
+/* $OpenBSD: ssl_both.c,v 1.14 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -146,7 +146,7 @@ ssl3_do_write(SSL *s, int type)
* Should not be done for 'Hello Request's, but in that case
* we'll ignore the result anyway.
*/
- tls1_finish_mac(s,
+ tls1_transcript_record(s,
(unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
if (ret == s->internal->init_num) {
@@ -557,7 +557,7 @@ ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
/* Feed this message into MAC computation. */
if (s->internal->mac_packet) {
- tls1_finish_mac(s, (unsigned char *)s->internal->init_buf->data,
+ tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
s->internal->init_num + 4);
if (s->internal->msg_callback)
diff --git a/lib/libssl/ssl_clnt.c b/lib/libssl/ssl_clnt.c
index 22e41da953c..c2aa7e81900 100644
--- a/lib/libssl/ssl_clnt.c
+++ b/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.36 2018/11/08 20:55:18 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.37 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -244,7 +244,7 @@ ssl3_connect(SSL *s)
/* don't push the buffering BIO quite yet */
if (!SSL_IS_DTLS(s)) {
- if (!tls1_init_finished_mac(s)) {
+ if (!tls1_transcript_init(s)) {
ret = -1;
goto end;
}
@@ -269,7 +269,7 @@ ssl3_connect(SSL *s)
if (SSL_IS_DTLS(s)) {
/* every DTLS ClientHello resets Finished MAC */
- if (!tls1_init_finished_mac(s)) {
+ if (!tls1_transcript_init(s)) {
ret = -1;
goto end;
}
@@ -583,7 +583,7 @@ ssl3_connect(SSL *s)
/* clean a few things up */
tls1_cleanup_key_block(s);
- if (S3I(s)->handshake_buffer != NULL) {
+ if (S3I(s)->handshake_transcript != NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
@@ -988,11 +988,8 @@ ssl3_get_server_hello(SSL *s)
* client authentication.
*/
alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
- if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) &&
- !tls1_digest_cached_records(s)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
+ if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)))
+ tls1_transcript_free(s);
if (!CBS_get_u8(&cbs, &compression_method))
goto truncated;
@@ -1619,10 +1616,7 @@ ssl3_get_certificate_request(SSL *s)
* If we get here we don't need any cached handshake records
* as we wont be doing client auth.
*/
- if (S3I(s)->handshake_buffer) {
- if (!tls1_digest_cached_records(s))
- goto err;
- }
+ tls1_transcript_free(s);
return (1);
}
@@ -2372,12 +2366,12 @@ ssl3_send_client_verify(SSL *s)
unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
unsigned char *signature = NULL;
unsigned int signature_len;
+ const unsigned char *hdata;
+ size_t hdatalen;
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey;
EVP_MD_CTX mctx;
const EVP_MD *md;
- long hdatalen;
- void *hdata;
EVP_MD_CTX_init(&mctx);
@@ -2404,10 +2398,7 @@ ssl3_send_client_verify(SSL *s)
goto err;
if (!SSL_USE_SIGALGS(s)) {
- if (S3I(s)->handshake_buffer) {
- if (!tls1_digest_cached_records(s))
- goto err;
- }
+ tls1_transcript_free(s);
if (!tls1_handshake_hash_value(s, data, sizeof(data),
NULL))
goto err;
@@ -2418,10 +2409,9 @@ ssl3_send_client_verify(SSL *s)
* using agreed digest and cached handshake records.
*/
if (SSL_USE_SIGALGS(s)) {
- hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer,
- &hdata);
md = s->cert->key->digest;
- if (hdatalen <= 0 ||
+
+ if (!tls1_transcript_data(s, &hdata, &hdatalen) ||
!tls12_get_hashandsig(&cert_verify, pkey, md)) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
@@ -2433,8 +2423,7 @@ ssl3_send_client_verify(SSL *s)
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
- if (!tls1_digest_cached_records(s))
- goto err;
+ tls1_transcript_free(s);
} else if (pkey->type == EVP_PKEY_RSA) {
if (RSA_sign(NID_md5_sha1, data,
MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, signature,
@@ -2457,8 +2446,7 @@ ssl3_send_client_verify(SSL *s)
size_t sigsize;
int nid;
- hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
+ if (!tls1_transcript_data(s, &hdata, &hdatalen)) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -2482,8 +2470,7 @@ ssl3_send_client_verify(SSL *s)
if (sigsize > UINT_MAX)
goto err;
signature_len = sigsize;
- if (!tls1_digest_cached_records(s))
- goto err;
+ tls1_transcript_free(s);
#endif
} else {
SSLerror(s, ERR_R_INTERNAL_ERROR);
@@ -2563,8 +2550,7 @@ ssl3_send_client_certificate(SSL *s)
S3I(s)->tmp.cert_req = 2;
/* There is no client certificate to verify. */
- if (!tls1_digest_cached_records(s))
- goto err;
+ tls1_transcript_free(s);
}
/* Ok, we have a cert */
diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h
index 32766de1cfc..3b08f8c7723 100644
--- a/lib/libssl/ssl_locl.h
+++ b/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.221 2018/11/08 20:55:18 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.222 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -780,8 +780,8 @@ typedef struct ssl3_state_internal_st {
int wpend_ret; /* number of bytes submitted */
const unsigned char *wpend_buf;
- /* used during startup, digest all incoming/outgoing packets */
- BIO *handshake_buffer;
+ /* Transcript of handshake messages that have been sent and received. */
+ BUF_MEM *handshake_transcript;
/* Rolling hash of handshake messages. */
EVP_MD_CTX *handshake_hash;
@@ -1238,11 +1238,14 @@ int tls1_handshake_hash_value(SSL *s, const unsigned char *out, size_t len,
size_t *outlen);
void tls1_handshake_hash_free(SSL *s);
-int tls1_init_finished_mac(SSL *s);
-int tls1_finish_mac(SSL *s, const unsigned char *buf, int len);
-void tls1_free_digest_list(SSL *s);
+int tls1_transcript_init(SSL *s);
+void tls1_transcript_free(SSL *s);
+int tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len);
+int tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len);
+void tls1_transcript_freeze(SSL *s);
+int tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len);
+
void tls1_cleanup_key_block(SSL *s);
-int tls1_digest_cached_records(SSL *s);
int tls1_change_cipher_state(SSL *s, int which);
int tls1_setup_key_block(SSL *s);
int tls1_enc(SSL *s, int snd);
diff --git a/lib/libssl/ssl_packet.c b/lib/libssl/ssl_packet.c
index ca5afb7d93c..d8fb409d81f 100644
--- a/lib/libssl/ssl_packet.c
+++ b/lib/libssl/ssl_packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_packet.c,v 1.7 2018/10/24 18:04:50 jsing Exp $ */
+/* $OpenBSD: ssl_packet.c,v 1.8 2018/11/08 22:28:52 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
@@ -120,7 +120,7 @@ ssl_convert_sslv2_client_hello(SSL *s)
if (n != record_length + 2)
return n;
- tls1_finish_mac(s, s->internal->packet + 2,
+ tls1_transcript_record(s, s->internal->packet + 2,
s->internal->packet_length - 2);
s->internal->mac_packet = 0;
diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c
index e7f1f5c9ec0..af9152d3dea 100644
--- a/lib/libssl/ssl_srvr.c
+++ b/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.50 2018/11/08 20:55:18 jsing Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.51 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -248,7 +248,8 @@ ssl3_accept(SSL *s)
ret = -1;
goto end;
}
- if (!tls1_init_finished_mac(s)) {
+
+ if (!tls1_transcript_init(s)) {
ret = -1;
goto end;
}
@@ -293,7 +294,7 @@ ssl3_accept(SSL *s)
S3I(s)->hs.state = SSL3_ST_SW_FLUSH;
s->internal->init_num = 0;
- if (!tls1_init_finished_mac(s)) {
+ if (!tls1_transcript_init(s)) {
ret = -1;
goto end;
}
@@ -366,7 +367,7 @@ ssl3_accept(SSL *s)
S3I(s)->hs.next_state = SSL3_ST_SR_CLNT_HELLO_A;
/* HelloVerifyRequest resets Finished MAC. */
- if (!tls1_init_finished_mac(s)) {
+ if (!tls1_transcript_init(s)) {
ret = -1;
goto end;
}
@@ -467,12 +468,9 @@ ssl3_accept(SSL *s)
skip = 1;
S3I(s)->tmp.cert_request = 0;
S3I(s)->hs.state = SSL3_ST_SW_SRVR_DONE_A;
- if (!SSL_IS_DTLS(s) && S3I(s)->handshake_buffer) {
- if (!tls1_digest_cached_records(s)) {
- ret = -1;
- goto end;
- }
- }
+
+ if (!SSL_IS_DTLS(s))
+ tls1_transcript_free(s);
} else {
S3I(s)->tmp.cert_request = 1;
if (SSL_IS_DTLS(s))
@@ -565,33 +563,20 @@ ssl3_accept(SSL *s)
if (!s->session->peer)
break;
/*
- * For sigalgs freeze the handshake buffer
- * at this point and digest cached records.
+ * Freeze the transcript for use during client
+ * certificate verification.
*/
- if (!S3I(s)->handshake_buffer) {
- SSLerror(s, ERR_R_INTERNAL_ERROR);
- ret = -1;
- goto end;
- }
- s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
- if (!tls1_digest_cached_records(s)) {
- ret = -1;
- goto end;
- }
+ tls1_transcript_freeze(s);
} else {
S3I(s)->hs.state = SSL3_ST_SR_CERT_VRFY_A;
s->internal->init_num = 0;
+ tls1_transcript_free(s);
+
/*
* We need to get hashes here so if there is
* a client cert, it can be verified.
*/
- if (S3I(s)->handshake_buffer) {
- if (!tls1_digest_cached_records(s)) {
- ret = -1;
- goto end;
- }
- }
if (!tls1_handshake_hash_value(s,
S3I(s)->tmp.cert_verify_md,
sizeof(S3I(s)->tmp.cert_verify_md),
@@ -701,7 +686,7 @@ ssl3_accept(SSL *s)
/* clean a few things up */
tls1_cleanup_key_block(s);
- if (S3I(s)->handshake_buffer != NULL) {
+ if (S3I(s)->handshake_transcript != NULL) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
@@ -1125,12 +1110,8 @@ ssl3_get_client_hello(SSL *s)
alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) ||
- !(s->verify_mode & SSL_VERIFY_PEER)) {
- if (!tls1_digest_cached_records(s)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
- }
+ !(s->verify_mode & SSL_VERIFY_PEER))
+ tls1_transcript_free(s);
/*
* We now have the following setup.
@@ -2110,10 +2091,10 @@ ssl3_get_cert_verify(SSL *s)
EVP_MD_CTX mctx;
uint8_t hash_id, sig_id;
int al, ok, sigalg, verify;
+ const unsigned char *hdata;
+ size_t hdatalen;
int type = 0;
int ret = 0;
- long hdatalen;
- void *hdata;
long n;
EVP_MD_CTX_init(&mctx);
@@ -2214,8 +2195,7 @@ ssl3_get_cert_verify(SSL *s)
}
if (SSL_USE_SIGALGS(s)) {
- hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
+ if (!tls1_transcript_data(s, &hdata, &hdatalen)) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
@@ -2265,8 +2245,7 @@ ssl3_get_cert_verify(SSL *s)
EVP_PKEY_CTX *pctx;
int nid;
- hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
+ if (!tls1_transcript_data(s, &hdata, &hdatalen)) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
@@ -2321,11 +2300,7 @@ ssl3_get_cert_verify(SSL *s)
ssl3_send_alert(s, SSL3_AL_FATAL, al);
}
end:
- if (S3I(s)->handshake_buffer) {
- BIO_free(S3I(s)->handshake_buffer);
- S3I(s)->handshake_buffer = NULL;
- s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
- }
+ tls1_transcript_free(s);
err:
EVP_MD_CTX_cleanup(&mctx);
EVP_PKEY_free(pkey);
@@ -2427,11 +2402,8 @@ ssl3_get_client_certificate(SSL *s)
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
- /* No client certificate so digest cached records */
- if (S3I(s)->handshake_buffer && !tls1_digest_cached_records(s)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
+ /* No client certificate so free transcript. */
+ tls1_transcript_free(s);
} else {
i = ssl_verify_cert_chain(s, sk);
if (i <= 0) {
diff --git a/lib/libssl/t1_enc.c b/lib/libssl/t1_enc.c
index 2a38d8de6a2..33158e160ea 100644
--- a/lib/libssl/t1_enc.c
+++ b/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_enc.c,v 1.115 2018/10/24 18:04:50 jsing Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.116 2018/11/08 22:28:52 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -157,61 +157,6 @@ tls1_cleanup_key_block(SSL *s)
S3I(s)->hs.key_block_len = 0;
}
-int
-tls1_init_finished_mac(SSL *s)
-{
- BIO_free(S3I(s)->handshake_buffer);
-
- S3I(s)->handshake_buffer = BIO_new(BIO_s_mem());
- if (S3I(s)->handshake_buffer == NULL)
- return (0);
-
- (void)BIO_set_close(S3I(s)->handshake_buffer, BIO_CLOSE);
-
- return (1);
-}
-
-int
-tls1_finish_mac(SSL *s, const unsigned char *buf, int len)
-{
- if (len < 0)
- return 0;
-
- if (!tls1_handshake_hash_update(s, buf, len))
- return 0;
-
- if (S3I(s)->handshake_buffer &&
- !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
- BIO_write(S3I(s)->handshake_buffer, (void *)buf, len);
- return 1;
- }
-
- return 1;
-}
-
-int
-tls1_digest_cached_records(SSL *s)
-{
- long hdatalen;
- void *hdata;
-
- hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
- SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
- goto err;
- }
-
- if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
- BIO_free(S3I(s)->handshake_buffer);
- S3I(s)->handshake_buffer = NULL;
- }
-
- return 1;
-
- err:
- return 0;
-}
-
void
tls1_record_sequence_increment(unsigned char *seq)
{
diff --git a/lib/libssl/t1_hash.c b/lib/libssl/t1_hash.c
index a7e46601e83..f514c5290ed 100644
--- a/lib/libssl/t1_hash.c
+++ b/lib/libssl/t1_hash.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_hash.c,v 1.3 2018/09/05 16:58:59 jsing Exp $ */
+/* $OpenBSD: t1_hash.c,v 1.4 2018/11/08 22:28:52 jsing Exp $ */
/*
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
*
@@ -22,9 +22,9 @@
int
tls1_handshake_hash_init(SSL *s)
{
+ const unsigned char *data;
const EVP_MD *md;
- long dlen;
- void *data;
+ size_t len;
tls1_handshake_hash_free(s);
@@ -42,12 +42,11 @@ tls1_handshake_hash_init(SSL *s)
goto err;
}
- dlen = BIO_get_mem_data(S3I(s)->handshake_buffer, &data);
- if (dlen <= 0) {
+ if (!tls1_transcript_data(s, &data, &len)) {
SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
goto err;
}
- if (!tls1_handshake_hash_update(s, data, dlen)) {
+ if (!tls1_handshake_hash_update(s, data, len)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
@@ -109,3 +108,79 @@ tls1_handshake_hash_free(SSL *s)
EVP_MD_CTX_free(S3I(s)->handshake_hash);
S3I(s)->handshake_hash = NULL;
}
+
+int
+tls1_transcript_init(SSL *s)
+{
+ if (S3I(s)->handshake_transcript != NULL)
+ return 0;
+
+ if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL)
+ return 0;
+
+ s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT;
+
+ return 1;
+}
+
+void
+tls1_transcript_free(SSL *s)
+{
+ BUF_MEM_free(S3I(s)->handshake_transcript);
+ S3I(s)->handshake_transcript = NULL;
+}
+
+int
+tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
+{
+ size_t olen, nlen;
+
+ if (S3I(s)->handshake_transcript == NULL)
+ return 1;
+
+ if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
+ return 1;
+
+ olen = S3I(s)->handshake_transcript->length;
+ nlen = olen + len;
+
+ if (nlen < olen)
+ return 0;
+
+ if (BUF_MEM_grow(S3I(s)->handshake_transcript, nlen) == 0)
+ return 0;
+
+ memcpy(S3I(s)->handshake_transcript->data + olen, buf, len);
+
+ return 1;
+}
+
+int
+tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
+{
+ if (S3I(s)->handshake_transcript == NULL)
+ return 0;
+
+ *data = S3I(s)->handshake_transcript->data;
+ *len = S3I(s)->handshake_transcript->length;
+
+ return 1;
+}
+
+void
+tls1_transcript_freeze(SSL *s)
+{
+ s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT;
+}
+
+int
+tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len)
+{
+ if (!tls1_handshake_hash_update(s, buf, len))
+ return 0;
+
+ if (!tls1_transcript_append(s, buf, len))
+ return 0;
+
+ return 1;
+}