1 /* $OpenBSD: ssl_transcript.c,v 1.9 2022/11/26 16:08:56 tb Exp $ */
2 /*
3 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <openssl/ssl.h>
19
20 #include "ssl_local.h"
21 #include "tls_internal.h"
22
23 int
tls1_transcript_hash_init(SSL * s)24 tls1_transcript_hash_init(SSL *s)
25 {
26 const unsigned char *data;
27 const EVP_MD *md;
28 size_t len;
29
30 tls1_transcript_hash_free(s);
31
32 if (!ssl_get_handshake_evp_md(s, &md)) {
33 SSLerrorx(ERR_R_INTERNAL_ERROR);
34 goto err;
35 }
36
37 if ((s->s3->handshake_hash = EVP_MD_CTX_new()) == NULL) {
38 SSLerror(s, ERR_R_MALLOC_FAILURE);
39 goto err;
40 }
41 if (!EVP_DigestInit_ex(s->s3->handshake_hash, md, NULL)) {
42 SSLerror(s, ERR_R_EVP_LIB);
43 goto err;
44 }
45
46 if (!tls1_transcript_data(s, &data, &len)) {
47 SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
48 goto err;
49 }
50 if (!tls1_transcript_hash_update(s, data, len)) {
51 SSLerror(s, ERR_R_EVP_LIB);
52 goto err;
53 }
54
55 return 1;
56
57 err:
58 tls1_transcript_hash_free(s);
59
60 return 0;
61 }
62
63 int
tls1_transcript_hash_update(SSL * s,const unsigned char * buf,size_t len)64 tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len)
65 {
66 if (s->s3->handshake_hash == NULL)
67 return 1;
68
69 return EVP_DigestUpdate(s->s3->handshake_hash, buf, len);
70 }
71
72 int
tls1_transcript_hash_value(SSL * s,unsigned char * out,size_t len,size_t * outlen)73 tls1_transcript_hash_value(SSL *s, unsigned char *out, size_t len,
74 size_t *outlen)
75 {
76 EVP_MD_CTX *mdctx = NULL;
77 unsigned int mdlen;
78 int ret = 0;
79
80 if (s->s3->handshake_hash == NULL)
81 goto err;
82
83 if (EVP_MD_CTX_size(s->s3->handshake_hash) > len)
84 goto err;
85
86 if ((mdctx = EVP_MD_CTX_new()) == NULL) {
87 SSLerror(s, ERR_R_MALLOC_FAILURE);
88 goto err;
89 }
90 if (!EVP_MD_CTX_copy_ex(mdctx, s->s3->handshake_hash)) {
91 SSLerror(s, ERR_R_EVP_LIB);
92 goto err;
93 }
94 if (!EVP_DigestFinal_ex(mdctx, out, &mdlen)) {
95 SSLerror(s, ERR_R_EVP_LIB);
96 goto err;
97 }
98 if (outlen != NULL)
99 *outlen = mdlen;
100
101 ret = 1;
102
103 err:
104 EVP_MD_CTX_free(mdctx);
105
106 return (ret);
107 }
108
109 void
tls1_transcript_hash_free(SSL * s)110 tls1_transcript_hash_free(SSL *s)
111 {
112 EVP_MD_CTX_free(s->s3->handshake_hash);
113 s->s3->handshake_hash = NULL;
114 }
115
116 int
tls1_transcript_init(SSL * s)117 tls1_transcript_init(SSL *s)
118 {
119 if (s->s3->handshake_transcript != NULL)
120 return 0;
121
122 if ((s->s3->handshake_transcript = tls_buffer_new(0)) == NULL)
123 return 0;
124
125 tls1_transcript_reset(s);
126
127 return 1;
128 }
129
130 void
tls1_transcript_free(SSL * s)131 tls1_transcript_free(SSL *s)
132 {
133 tls_buffer_free(s->s3->handshake_transcript);
134 s->s3->handshake_transcript = NULL;
135 }
136
137 void
tls1_transcript_reset(SSL * s)138 tls1_transcript_reset(SSL *s)
139 {
140 tls_buffer_clear(s->s3->handshake_transcript);
141
142 tls1_transcript_unfreeze(s);
143 }
144
145 int
tls1_transcript_append(SSL * s,const unsigned char * buf,size_t len)146 tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
147 {
148 if (s->s3->handshake_transcript == NULL)
149 return 1;
150
151 if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
152 return 1;
153
154 return tls_buffer_append(s->s3->handshake_transcript, buf, len);
155 }
156
157 int
tls1_transcript_data(SSL * s,const unsigned char ** data,size_t * len)158 tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
159 {
160 CBS cbs;
161
162 if (s->s3->handshake_transcript == NULL)
163 return 0;
164
165 if (!tls_buffer_data(s->s3->handshake_transcript, &cbs))
166 return 0;
167
168 /* XXX - change to caller providing a CBS argument. */
169 *data = CBS_data(&cbs);
170 *len = CBS_len(&cbs);
171
172 return 1;
173 }
174
175 void
tls1_transcript_freeze(SSL * s)176 tls1_transcript_freeze(SSL *s)
177 {
178 s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT;
179 }
180
181 void
tls1_transcript_unfreeze(SSL * s)182 tls1_transcript_unfreeze(SSL *s)
183 {
184 s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT;
185 }
186
187 int
tls1_transcript_record(SSL * s,const unsigned char * buf,size_t len)188 tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len)
189 {
190 if (!tls1_transcript_hash_update(s, buf, len))
191 return 0;
192
193 if (!tls1_transcript_append(s, buf, len))
194 return 0;
195
196 return 1;
197 }
198