1 /* $OpenBSD: ssl_transcript.c,v 1.8 2022/07/22 19:54:46 jsing 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_locl.h" 21 #include "tls_internal.h" 22 23 int 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 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 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 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 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 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 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 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 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 176 tls1_transcript_freeze(SSL *s) 177 { 178 s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT; 179 } 180 181 void 182 tls1_transcript_unfreeze(SSL *s) 183 { 184 s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT; 185 } 186 187 int 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