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