diff options
Diffstat (limited to 'src/lib/libssl/tls13_lib.c')
-rw-r--r-- | src/lib/libssl/tls13_lib.c | 150 |
1 files changed, 147 insertions, 3 deletions
diff --git a/src/lib/libssl/tls13_lib.c b/src/lib/libssl/tls13_lib.c index 61ca3d4682..6876528f50 100644 --- a/src/lib/libssl/tls13_lib.c +++ b/src/lib/libssl/tls13_lib.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* $OpenBSD: tls13_lib.c,v 1.12 2019/11/17 00:10:47 beck Exp $ */ | 1 | /* $OpenBSD: tls13_lib.c,v 1.13 2019/11/26 23:46:18 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2019 Bob Beck <beck@openbsd.org> | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 6 | * 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 | * purpose with or without fee is hereby granted, provided that the above |
@@ -90,6 +91,149 @@ tls13_alert_received_cb(uint8_t alert_desc, void *arg) | |||
90 | SSL_CTX_remove_session(s->ctx, s->session); | 91 | SSL_CTX_remove_session(s->ctx, s->session); |
91 | } | 92 | } |
92 | 93 | ||
94 | static int | ||
95 | tls13_phh_update_local_traffic_secret(struct tls13_ctx *ctx) | ||
96 | { | ||
97 | struct tls13_secrets *secrets = ctx->hs->secrets; | ||
98 | |||
99 | if (ctx->mode == TLS13_HS_CLIENT) | ||
100 | return (tls13_update_client_traffic_secret(secrets) && | ||
101 | tls13_record_layer_set_write_traffic_key(ctx->rl, | ||
102 | &secrets->client_application_traffic)); | ||
103 | return (tls13_update_server_traffic_secret(secrets) && | ||
104 | tls13_record_layer_set_read_traffic_key(ctx->rl, | ||
105 | &secrets->server_application_traffic)); | ||
106 | } | ||
107 | |||
108 | static int | ||
109 | tls13_phh_update_peer_traffic_secret(struct tls13_ctx *ctx) | ||
110 | { | ||
111 | struct tls13_secrets *secrets = ctx->hs->secrets; | ||
112 | |||
113 | if (ctx->mode == TLS13_HS_CLIENT) | ||
114 | return (tls13_update_server_traffic_secret(secrets) && | ||
115 | tls13_record_layer_set_read_traffic_key(ctx->rl, | ||
116 | &secrets->server_application_traffic)); | ||
117 | return (tls13_update_client_traffic_secret(secrets) && | ||
118 | tls13_record_layer_set_write_traffic_key(ctx->rl, | ||
119 | &secrets->client_application_traffic)); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * XXX arbitrarily chosen limit of 100 post handshake handshake | ||
124 | * messages in an hour - to avoid a hostile peer from constantly | ||
125 | * requesting certificates or key renegotiaitons, etc. | ||
126 | */ | ||
127 | static int | ||
128 | tls13_phh_limit_check(struct tls13_ctx *ctx) | ||
129 | { | ||
130 | time_t now = time(NULL); | ||
131 | |||
132 | if (ctx->phh_last_seen > now - TLS13_PHH_LIMIT_TIME) { | ||
133 | if (ctx->phh_count > TLS13_PHH_LIMIT) | ||
134 | return 0; | ||
135 | } else | ||
136 | ctx->phh_count = 0; | ||
137 | ctx->phh_count++; | ||
138 | ctx->phh_last_seen = now; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | static ssize_t | ||
143 | tls13_key_update_recv(struct tls13_ctx *ctx, CBS *cbs) | ||
144 | { | ||
145 | ssize_t ret = TLS13_IO_FAILURE; | ||
146 | |||
147 | if (!CBS_get_u8(cbs, &ctx->key_update_request)) | ||
148 | goto err; | ||
149 | if (CBS_len(cbs) != 0) | ||
150 | goto err; | ||
151 | |||
152 | if (!tls13_phh_update_peer_traffic_secret(ctx)) | ||
153 | goto err; | ||
154 | |||
155 | if (ctx->key_update_request) { | ||
156 | CBB cbb; | ||
157 | CBS cbs; /* XXX */ | ||
158 | |||
159 | free(ctx->hs_msg); | ||
160 | ctx->hs_msg = tls13_handshake_msg_new(); | ||
161 | if (!tls13_handshake_msg_start(ctx->hs_msg, &cbb, TLS13_MT_KEY_UPDATE)) | ||
162 | goto err; | ||
163 | if (!CBB_add_u8(&cbb, 0)) | ||
164 | goto err; | ||
165 | if (!tls13_handshake_msg_finish(ctx->hs_msg)) | ||
166 | goto err; | ||
167 | tls13_handshake_msg_data(ctx->hs_msg, &cbs); | ||
168 | ret = tls13_record_layer_phh(ctx->rl, &cbs); | ||
169 | |||
170 | tls13_handshake_msg_free(ctx->hs_msg); | ||
171 | ctx->hs_msg = NULL; | ||
172 | } else | ||
173 | ret = TLS13_IO_SUCCESS; | ||
174 | |||
175 | return ret; | ||
176 | err: | ||
177 | ctx->key_update_request = 0; | ||
178 | /* XXX alert */ | ||
179 | return TLS13_IO_FAILURE; | ||
180 | } | ||
181 | |||
182 | static void | ||
183 | tls13_phh_done_cb(void *cb_arg) | ||
184 | { | ||
185 | struct tls13_ctx *ctx = cb_arg; | ||
186 | |||
187 | if (ctx->key_update_request) { | ||
188 | tls13_phh_update_local_traffic_secret(ctx); | ||
189 | ctx->key_update_request = 0; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static ssize_t | ||
194 | tls13_phh_received_cb(void *cb_arg, CBS *cbs) | ||
195 | { | ||
196 | ssize_t ret = TLS13_IO_FAILURE; | ||
197 | struct tls13_ctx *ctx = cb_arg; | ||
198 | CBS phh_cbs; | ||
199 | |||
200 | if (!tls13_phh_limit_check(ctx)) | ||
201 | return tls13_send_alert(ctx->rl, SSL3_AD_UNEXPECTED_MESSAGE); | ||
202 | |||
203 | if ((ctx->hs_msg == NULL) && | ||
204 | ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)) | ||
205 | return TLS13_IO_FAILURE; | ||
206 | |||
207 | if (!tls13_handshake_msg_set_buffer(ctx->hs_msg, cbs)) | ||
208 | return TLS13_IO_FAILURE; | ||
209 | |||
210 | if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) | ||
211 | != TLS13_IO_SUCCESS) | ||
212 | return ret; | ||
213 | |||
214 | if (!tls13_handshake_msg_content(ctx->hs_msg, &phh_cbs)) | ||
215 | return TLS13_IO_FAILURE; | ||
216 | |||
217 | switch(tls13_handshake_msg_type(ctx->hs_msg)) { | ||
218 | case TLS13_MT_KEY_UPDATE: | ||
219 | ret = tls13_key_update_recv(ctx, &phh_cbs); | ||
220 | break; | ||
221 | case TLS13_MT_NEW_SESSION_TICKET: | ||
222 | /* XXX do nothing for now and ignore this */ | ||
223 | break; | ||
224 | case TLS13_MT_CERTIFICATE_REQUEST: | ||
225 | /* XXX add support if we choose to advertise this */ | ||
226 | /* FALLTHROUGH */ | ||
227 | default: | ||
228 | ret = TLS13_IO_FAILURE; /* XXX send alert */ | ||
229 | break; | ||
230 | } | ||
231 | |||
232 | tls13_handshake_msg_free(ctx->hs_msg); | ||
233 | ctx->hs_msg = NULL; | ||
234 | return ret; | ||
235 | } | ||
236 | |||
93 | struct tls13_ctx * | 237 | struct tls13_ctx * |
94 | tls13_ctx_new(int mode) | 238 | tls13_ctx_new(int mode) |
95 | { | 239 | { |
@@ -101,8 +245,8 @@ tls13_ctx_new(int mode) | |||
101 | ctx->mode = mode; | 245 | ctx->mode = mode; |
102 | 246 | ||
103 | if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb, | 247 | if ((ctx->rl = tls13_record_layer_new(tls13_legacy_wire_read_cb, |
104 | tls13_legacy_wire_write_cb, tls13_alert_received_cb, NULL, NULL, | 248 | tls13_legacy_wire_write_cb, tls13_alert_received_cb, |
105 | ctx)) == NULL) | 249 | tls13_phh_received_cb, tls13_phh_done_cb, ctx)) == NULL) |
106 | goto err; | 250 | goto err; |
107 | 251 | ||
108 | return ctx; | 252 | return ctx; |