Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 8169:bd006bd520a9 quic
QUIC set_encryption_secrets callback.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Fri, 28 Feb 2020 13:09:51 +0300 |
parents | 5d91389e0fd3 |
children | 53a5cdbe500c |
comparison
equal
deleted
inserted
replaced
8168:b507592c15a7 | 8169:bd006bd520a9 |
---|---|
87 | 87 |
88 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); | 88 static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); |
89 static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 89 static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
90 static void ngx_openssl_exit(ngx_cycle_t *cycle); | 90 static void ngx_openssl_exit(ngx_cycle_t *cycle); |
91 | 91 |
92 | |
92 #if NGX_OPENSSL_QUIC | 93 #if NGX_OPENSSL_QUIC |
93 | 94 |
94 static int | 95 static int |
95 quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | 96 quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, |
96 enum ssl_encryption_level_t level, const uint8_t *read_secret, | 97 enum ssl_encryption_level_t level, const uint8_t *read_secret, |
97 const uint8_t *write_secret, size_t secret_len) | 98 const uint8_t *write_secret, size_t secret_len) |
98 { | 99 { |
99 size_t *len; | 100 size_t *rlen, *wlen; |
100 uint8_t **rsec, **wsec; | 101 uint8_t **rsec, **wsec; |
102 const char *name; | |
103 const EVP_MD *digest; | |
104 const EVP_AEAD *aead; | |
101 ngx_connection_t *c; | 105 ngx_connection_t *c; |
102 | 106 |
103 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | 107 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
104 | 108 |
105 ngx_ssl_handshake_log(c); | 109 ngx_ssl_handshake_log(c); |
109 u_char buf[64]; | 113 u_char buf[64]; |
110 size_t m; | 114 size_t m; |
111 | 115 |
112 m = ngx_hex_dump(buf, (u_char *) read_secret, secret_len) - buf; | 116 m = ngx_hex_dump(buf, (u_char *) read_secret, secret_len) - buf; |
113 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | 117 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
114 "set_encryption_secrets: %*s, len: %uz, level:%d", | 118 "set_encryption_secrets: read %*s, len: %uz, level:%d", |
115 m, buf, secret_len, (int) level); | 119 m, buf, secret_len, (int) level); |
116 | 120 |
117 m = ngx_hex_dump(buf, (u_char *) write_secret, secret_len) - buf; | 121 m = ngx_hex_dump(buf, (u_char *) write_secret, secret_len) - buf; |
118 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | 122 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
119 "set_encryption_secrets: %*s, len: %uz, level:%d", | 123 "set_encryption_secrets: write %*s, len: %uz, level:%d", |
120 m, buf, secret_len, (int) level); | 124 m, buf, secret_len, (int) level); |
121 } | 125 } |
122 #endif | 126 #endif |
123 | 127 |
128 name = SSL_get_cipher(ssl_conn); | |
129 | |
130 if (OPENSSL_strcasecmp(name, "TLS_AES_128_GCM_SHA256") == 0) { | |
131 aead = EVP_aead_aes_128_gcm(); | |
132 digest = EVP_sha256(); | |
133 | |
134 } else if (OPENSSL_strcasecmp(name, "TLS_AES_256_GCM_SHA384") == 0) { | |
135 aead = EVP_aead_aes_256_gcm(); | |
136 digest = EVP_sha384(); | |
137 | |
138 } else { | |
139 return 0; | |
140 } | |
141 | |
142 size_t hkdfl_len; | |
143 uint8_t hkdfl[20]; | |
144 uint8_t *p; | |
145 const char *label; | |
146 | |
147 ngx_str_t *client_key, *client_iv, *client_hp; | |
148 ngx_str_t *server_key, *server_iv, *server_hp; | |
149 | |
124 switch (level) { | 150 switch (level) { |
125 | 151 |
126 case ssl_encryption_handshake: | 152 case ssl_encryption_handshake: |
127 len = &c->quic->handshake_secret_len; | 153 rlen = &c->quic->client_hs.len; |
128 rsec = &c->quic->handshake_read_secret; | 154 rsec = &c->quic->client_hs.data; |
129 wsec = &c->quic->handshake_write_secret; | 155 wlen = &c->quic->server_hs.len; |
156 wsec = &c->quic->server_hs.data; | |
157 | |
158 client_key = &c->quic->client_hs_key; | |
159 client_iv = &c->quic->client_hs_iv; | |
160 client_hp = &c->quic->client_hs_hp; | |
161 | |
162 server_key = &c->quic->server_hs_key; | |
163 server_iv = &c->quic->server_hs_iv; | |
164 server_hp = &c->quic->server_hs_hp; | |
165 | |
130 break; | 166 break; |
131 | 167 |
132 case ssl_encryption_application: | 168 case ssl_encryption_application: |
133 len = &c->quic->application_secret_len; | 169 rlen = &c->quic->client_ad.len; |
134 rsec = &c->quic->application_read_secret; | 170 rsec = &c->quic->client_ad.data; |
135 wsec = &c->quic->application_write_secret; | 171 wlen = &c->quic->server_ad.len; |
172 wsec = &c->quic->server_ad.data; | |
173 | |
174 client_key = &c->quic->client_ad_key; | |
175 client_iv = &c->quic->client_ad_iv; | |
176 client_hp = &c->quic->client_ad_hp; | |
177 | |
178 server_key = &c->quic->server_ad_key; | |
179 server_iv = &c->quic->server_ad_iv; | |
180 server_hp = &c->quic->server_ad_hp; | |
181 | |
136 break; | 182 break; |
137 | 183 |
138 default: | 184 default: |
139 return 0; | 185 return 0; |
140 } | 186 } |
141 | 187 |
142 *len = secret_len; | 188 *rlen = *wlen = secret_len; |
143 | 189 |
144 *rsec = ngx_pnalloc(c->pool, secret_len); | 190 *rsec = ngx_pnalloc(c->pool, secret_len); |
145 if (*rsec == NULL) { | 191 if (*rsec == NULL) { |
146 return NGX_ERROR; | 192 return 0; |
147 } | 193 } |
148 | 194 |
149 ngx_memcpy(*rsec, read_secret, secret_len); | 195 ngx_memcpy(*rsec, read_secret, secret_len); |
150 | 196 |
151 *wsec = ngx_pnalloc(c->pool, secret_len); | 197 *wsec = ngx_pnalloc(c->pool, secret_len); |
152 if (*wsec == NULL) { | 198 if (*wsec == NULL) { |
153 return NGX_ERROR; | 199 return 0; |
154 } | 200 } |
155 | 201 |
156 ngx_memcpy(*wsec, write_secret, secret_len); | 202 ngx_memcpy(*wsec, write_secret, secret_len); |
203 | |
204 // client keys | |
205 | |
206 client_key->len = EVP_AEAD_key_length(aead); | |
207 client_key->data = ngx_pnalloc(c->pool, client_key->len); | |
208 if (client_key->data == NULL) { | |
209 return 0; | |
210 } | |
211 | |
212 label = "tls13 quic key"; | |
213 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
214 hkdfl[0] = client_key->len / 256; | |
215 hkdfl[1] = client_key->len % 256; | |
216 hkdfl[2] = sizeof(label) - 1; | |
217 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
218 *p = '\0'; | |
219 | |
220 if (HKDF_expand(client_key->data, client_key->len, | |
221 digest, *rsec, *rlen, | |
222 hkdfl, hkdfl_len) | |
223 == 0) | |
224 { | |
225 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
226 "HKDF_expand(client_key) failed"); | |
227 return 0; | |
228 } | |
229 | |
230 | |
231 client_iv->len = EVP_AEAD_nonce_length(aead); | |
232 client_iv->data = ngx_pnalloc(c->pool, client_iv->len); | |
233 if (client_iv->data == NULL) { | |
234 return 0; | |
235 } | |
236 | |
237 label = "tls13 quic iv"; | |
238 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
239 hkdfl[0] = client_iv->len / 256; | |
240 hkdfl[1] = client_iv->len % 256; | |
241 hkdfl[2] = sizeof(label) - 1; | |
242 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
243 *p = '\0'; | |
244 | |
245 if (HKDF_expand(client_iv->data, client_iv->len, | |
246 digest, *rsec, *rlen, | |
247 hkdfl, hkdfl_len) | |
248 == 0) | |
249 { | |
250 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
251 "HKDF_expand(client_iv) failed"); | |
252 return 0; | |
253 } | |
254 | |
255 | |
256 client_hp->len = EVP_AEAD_key_length(aead); | |
257 client_hp->data = ngx_pnalloc(c->pool, client_hp->len); | |
258 if (client_hp->data == NULL) { | |
259 return 0; | |
260 } | |
261 | |
262 label = "tls13 quic hp"; | |
263 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
264 hkdfl[0] = client_hp->len / 256; | |
265 hkdfl[1] = client_hp->len % 256; | |
266 hkdfl[2] = sizeof(label) - 1; | |
267 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
268 *p = '\0'; | |
269 | |
270 if (HKDF_expand(client_hp->data, client_hp->len, | |
271 digest, *rsec, *rlen, | |
272 hkdfl, hkdfl_len) | |
273 == 0) | |
274 { | |
275 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
276 "HKDF_expand(client_hp) failed"); | |
277 return 0; | |
278 } | |
279 | |
280 | |
281 // server keys | |
282 | |
283 server_key->len = EVP_AEAD_key_length(aead); | |
284 server_key->data = ngx_pnalloc(c->pool, server_key->len); | |
285 if (server_key->data == NULL) { | |
286 return 0; | |
287 } | |
288 | |
289 label = "tls13 quic key"; | |
290 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
291 hkdfl[0] = server_key->len / 256; | |
292 hkdfl[1] = server_key->len % 256; | |
293 hkdfl[2] = sizeof(label) - 1; | |
294 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
295 *p = '\0'; | |
296 | |
297 if (HKDF_expand(server_key->data, server_key->len, | |
298 digest, *wsec, *wlen, | |
299 hkdfl, hkdfl_len) | |
300 == 0) | |
301 { | |
302 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
303 "HKDF_expand(server_key) failed"); | |
304 return 0; | |
305 } | |
306 | |
307 | |
308 server_iv->len = EVP_AEAD_nonce_length(aead); | |
309 server_iv->data = ngx_pnalloc(c->pool, server_iv->len); | |
310 if (server_iv->data == NULL) { | |
311 return 0; | |
312 } | |
313 | |
314 label = "tls13 quic iv"; | |
315 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
316 hkdfl[0] = server_iv->len / 256; | |
317 hkdfl[1] = server_iv->len % 256; | |
318 hkdfl[2] = sizeof(label) - 1; | |
319 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
320 *p = '\0'; | |
321 | |
322 if (HKDF_expand(server_iv->data, server_iv->len, | |
323 digest, *wsec, *wlen, | |
324 hkdfl, hkdfl_len) | |
325 == 0) | |
326 { | |
327 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
328 "HKDF_expand(server_iv) failed"); | |
329 return 0; | |
330 } | |
331 | |
332 | |
333 server_hp->len = EVP_AEAD_key_length(aead); | |
334 server_hp->data = ngx_pnalloc(c->pool, server_hp->len); | |
335 if (server_hp->data == NULL) { | |
336 return 0; | |
337 } | |
338 | |
339 label = "tls13 quic hp"; | |
340 hkdfl_len = 2 + 1 + sizeof(label) - 1 + 1; | |
341 hkdfl[0] = server_hp->len / 256; | |
342 hkdfl[1] = server_hp->len % 256; | |
343 hkdfl[2] = sizeof(label) - 1; | |
344 p = ngx_cpymem(&hkdfl[3], label, sizeof(label) - 1); | |
345 *p = '\0'; | |
346 | |
347 if (HKDF_expand(server_hp->data, server_hp->len, | |
348 digest, *wsec, *wlen, | |
349 hkdfl, hkdfl_len) | |
350 == 0) | |
351 { | |
352 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
353 "HKDF_expand(server_hp) failed"); | |
354 return 0; | |
355 } | |
157 | 356 |
158 return 1; | 357 return 1; |
159 } | 358 } |
160 | 359 |
161 | 360 |