@@ -21,12 +21,13 @@ const size_t IV_LENGTH = 16;
21
21
const size_t SIGNATURE_LENGTH = 32 ;
22
22
23
23
typedef struct {
24
- u_char * key ;
25
- size_t key_len ;
26
- u_char * iv ;
27
- size_t iv_len ;
28
- time_t expires ;
29
- ngx_flag_t iv_in_content ;
24
+ u_char * key ;
25
+ size_t key_len ;
26
+ u_char * iv ;
27
+ size_t iv_len ;
28
+ time_t expires ;
29
+ ngx_flag_t iv_in_content ;
30
+ enum ngx_http_encrypted_session_mode encryption_mode ;
30
31
} ngx_http_encrypted_session_conf_t ;
31
32
32
33
static ngx_int_t ngx_http_set_encode_encrypted_session (ngx_http_request_t * r ,
@@ -43,6 +44,9 @@ static char *ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd,
43
44
static char * ngx_http_encrypted_session_iv (ngx_conf_t * cf , ngx_command_t * cmd ,
44
45
void * conf );
45
46
47
+ static char * ngx_http_encrypted_session_mode_set (ngx_conf_t * cf ,
48
+ ngx_command_t * cmd , void * conf );
49
+
46
50
static char * ngx_http_encrypted_session_expires (ngx_conf_t * cf ,
47
51
ngx_command_t * cmd , void * conf );
48
52
@@ -93,6 +97,15 @@ static ngx_command_t ngx_http_encrypted_session_commands[] = {
93
97
0 ,
94
98
NULL
95
99
},
100
+ {
101
+ ngx_string ("encrypted_session_mode" ),
102
+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_SIF_CONF
103
+ |NGX_HTTP_LOC_CONF |NGX_HTTP_LIF_CONF |NGX_CONF_TAKE1 ,
104
+ ngx_http_encrypted_session_mode_set ,
105
+ NGX_HTTP_LOC_CONF_OFFSET ,
106
+ 0 ,
107
+ NULL
108
+ },
96
109
{
97
110
ngx_string ("encrypted_session_expires" ),
98
111
NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_SIF_CONF
@@ -216,12 +229,28 @@ ngx_http_session_encrypted_compute_hmac(ngx_http_request_t *r,
216
229
217
230
static ngx_str_t *
218
231
ngx_http_session_generate_signature (ngx_http_request_t * r ,
219
- ngx_str_t * iv , ngx_str_t * key , ngx_str_t * content )
232
+ ngx_str_t * iv , ngx_str_t * key , ngx_str_t * content ,
233
+ ngx_str_t * tag , enum ngx_http_encrypted_session_mode mode )
220
234
{
221
235
size_t signature_content_len = iv -> len + content -> len ;
236
+ if (mode == ngx_http_encrypted_session_mode_gcm )
237
+ {
238
+ signature_content_len += tag -> len ;
239
+ }
240
+
222
241
u_char * signature_content = (u_char * )ngx_pcalloc (r -> pool , signature_content_len + 1 );
223
242
ngx_memcpy (signature_content , iv -> data , iv -> len );
224
- ngx_memcpy (signature_content + iv -> len , content -> data , content -> len );
243
+
244
+ if (mode == ngx_http_encrypted_session_mode_gcm )
245
+ {
246
+ ngx_memcpy (signature_content + iv -> len , tag -> data , tag -> len );
247
+ ngx_memcpy (signature_content + iv -> len + tag -> len ,
248
+ content -> data , content -> len );
249
+ }
250
+ else
251
+ {
252
+ ngx_memcpy (signature_content + iv -> len , content -> data , content -> len );
253
+ }
225
254
226
255
ngx_log_error (NGX_LOG_DEBUG , r -> connection -> log , 0 ,
227
256
"encrypted_session: signature content len=%d" ,
@@ -245,15 +274,32 @@ ngx_http_session_generate_signature(ngx_http_request_t *r,
245
274
246
275
static ngx_str_t *
247
276
ngx_http_session_generate_response_with_iv (ngx_http_request_t * r ,
248
- ngx_str_t * iv , ngx_str_t * key , ngx_str_t * content )
277
+ ngx_str_t * iv , ngx_str_t * key , ngx_str_t * content ,
278
+ ngx_str_t * tag , enum ngx_http_encrypted_session_mode mode )
249
279
{
250
- ngx_str_t * signature = ngx_http_session_generate_signature (r , iv , key , content );
280
+ ngx_str_t * signature = ngx_http_session_generate_signature (r , iv , key ,
281
+ content , tag , mode );
282
+
283
+ size_t new_len = iv -> len + signature -> len + content -> len ;
284
+
285
+ if (mode == ngx_http_encrypted_session_mode_gcm )
286
+ {
287
+ new_len += tag -> len ;
288
+ }
251
289
252
- size_t new_len = iv -> len + content -> len + signature -> len ;
253
290
u_char * new_content = (u_char * )ngx_pcalloc (r -> pool , new_len + 1 );
254
291
ngx_memcpy (new_content , iv -> data , iv -> len );
255
292
ngx_memcpy (new_content + iv -> len , signature -> data , signature -> len );
256
- ngx_memcpy (new_content + iv -> len + signature -> len , content -> data , content -> len );
293
+
294
+ if (mode == ngx_http_encrypted_session_mode_gcm )
295
+ {
296
+ ngx_memcpy (new_content + iv -> len + signature -> len , tag -> data , tag -> len );
297
+ ngx_memcpy (new_content + iv -> len + signature -> len + tag -> len , content -> data , content -> len );
298
+ }
299
+ else
300
+ {
301
+ ngx_memcpy (new_content + iv -> len + signature -> len , content -> data , content -> len );
302
+ }
257
303
258
304
ngx_log_error (NGX_LOG_DEBUG , r -> connection -> log , 0 ,
259
305
"encrypted_session: encrypted data len=%d" , content -> len );
@@ -314,9 +360,11 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
314
360
content .data );
315
361
}
316
362
363
+ u_char * tag ;
317
364
rc = ngx_http_encrypted_session_aes_mac_encrypt (emcf , r -> pool ,
318
365
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
319
- content .data , content .len , (ngx_uint_t ) conf -> expires , & dst , & len );
366
+ content .data , content .len ,
367
+ (ngx_uint_t ) conf -> expires , conf -> encryption_mode , & dst , & len , & tag );
320
368
321
369
if (rc != NGX_OK ) {
322
370
res -> data = NULL ;
@@ -332,8 +380,12 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
332
380
encrypted_content .len = len ;
333
381
encrypted_content .data = dst ;
334
382
383
+ ngx_str_t tag_content ;
384
+ tag_content .len = ngx_http_encrypted_session_aes_tag_size ;
385
+ tag_content .data = tag ;
386
+
335
387
ngx_str_t * result = ngx_http_session_generate_response_with_iv (r , & iv ,
336
- & key , & encrypted_content );
388
+ & key , & encrypted_content , & tag_content , conf -> encryption_mode );
337
389
res -> data = result -> data ;
338
390
res -> len = result -> len ;
339
391
@@ -377,6 +429,8 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
377
429
378
430
ngx_str_t iv ;
379
431
ngx_str_t content ;
432
+ ngx_str_t tag ;
433
+
380
434
content .data = v -> data ;
381
435
content .len = v -> len ;
382
436
@@ -405,10 +459,28 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
405
459
u_char * signature = (u_char * )ngx_pcalloc (r -> pool , SIGNATURE_LENGTH + 1 );
406
460
ngx_memcpy (signature , content .data + iv .len , SIGNATURE_LENGTH );
407
461
462
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_gcm )
463
+ {
464
+ tag .len = ngx_http_encrypted_session_aes_tag_size ;
465
+ tag .data = (u_char * )ngx_pcalloc (r -> pool , tag .len );
466
+ ngx_memcpy (tag .data , content .data + iv .len + SIGNATURE_LENGTH , tag .len );
467
+ }
468
+
408
469
ngx_str_t encrypted_content ;
409
- encrypted_content .len = content .len - iv .len - SIGNATURE_LENGTH ;
410
- encrypted_content .data = (u_char * )ngx_pcalloc (r -> pool , encrypted_content .len + 1 );
411
- ngx_memcpy (encrypted_content .data , v -> data + iv .len + SIGNATURE_LENGTH , encrypted_content .len );
470
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_gcm )
471
+ {
472
+ encrypted_content .len = content .len - iv .len - SIGNATURE_LENGTH - tag .len ;
473
+ encrypted_content .data = (u_char * )ngx_pcalloc (r -> pool , encrypted_content .len + 1 );
474
+ ngx_memcpy (encrypted_content .data ,
475
+ v -> data + iv .len + SIGNATURE_LENGTH + tag .len ,
476
+ encrypted_content .len );
477
+ }
478
+ else
479
+ {
480
+ encrypted_content .len = content .len - iv .len - SIGNATURE_LENGTH ;
481
+ encrypted_content .data = (u_char * )ngx_pcalloc (r -> pool , encrypted_content .len + 1 );
482
+ ngx_memcpy (encrypted_content .data , v -> data + iv .len + SIGNATURE_LENGTH , encrypted_content .len );
483
+ }
412
484
413
485
content .data = encrypted_content .data ;
414
486
content .len = encrypted_content .len ;
@@ -417,7 +489,7 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
417
489
"encrypted_session: data len=%d" , content .len );
418
490
419
491
ngx_str_t * computed_signature = ngx_http_session_generate_signature (r ,
420
- & iv , & key , & encrypted_content );
492
+ & iv , & key , & encrypted_content , & tag , conf -> encryption_mode );
421
493
if (SIGNATURE_LENGTH != computed_signature -> len ||
422
494
ngx_memcmp (computed_signature -> data , signature , SIGNATURE_LENGTH ) != 0 )
423
495
{
@@ -432,7 +504,8 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
432
504
433
505
rc = ngx_http_encrypted_session_aes_mac_decrypt (emcf , r -> pool ,
434
506
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
435
- content .data , content .len , & dst , & len );
507
+ content .data , content .len , conf -> encryption_mode , tag .data ,
508
+ & dst , & len );
436
509
437
510
if (rc != NGX_OK ) {
438
511
ngx_log_error (NGX_LOG_WARN , r -> connection -> log , 0 ,
@@ -542,6 +615,24 @@ ngx_http_encrypted_session_iv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
542
615
return NGX_CONF_OK ;
543
616
}
544
617
618
+ static char *
619
+ ngx_http_encrypted_session_mode_set (ngx_conf_t * cf ,
620
+ ngx_command_t * cmd , void * conf )
621
+ {
622
+ ngx_str_t * value ;
623
+ ngx_http_encrypted_session_conf_t * llcf = conf ;
624
+
625
+ value = cf -> args -> elts ;
626
+ if (value [1 ].len == 3 && strncmp ("cbc" , (char * )value [1 ].data , 3 ) == 0 ) {
627
+ llcf -> encryption_mode = ngx_http_encrypted_session_mode_cbc ;
628
+ }
629
+ else if (value [1 ].len == 3 && strncmp ("gcm" , (char * )value [1 ].data , 3 ) == 0 ) {
630
+ llcf -> encryption_mode = ngx_http_encrypted_session_mode_gcm ;
631
+ }
632
+
633
+ return NGX_CONF_OK ;
634
+ }
635
+
545
636
546
637
static char *
547
638
ngx_http_encrypted_session_expires (ngx_conf_t * cf , ngx_command_t * cmd ,
@@ -654,6 +745,7 @@ ngx_http_encrypted_session_create_conf(ngx_conf_t *cf)
654
745
conf -> iv_len = NGX_CONF_UNSET ;
655
746
conf -> expires = NGX_CONF_UNSET ;
656
747
conf -> iv_in_content = NGX_CONF_UNSET ;
748
+ conf -> encryption_mode = ngx_http_encrypted_session_mode_unknown ;
657
749
658
750
return conf ;
659
751
}
@@ -678,5 +770,13 @@ ngx_http_encrypted_session_merge_conf(ngx_conf_t *cf, void *parent, void *child)
678
770
ngx_http_encrypted_session_default_expires );
679
771
ngx_conf_merge_value (conf -> iv_in_content , prev -> iv_in_content , 0 );
680
772
773
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_unknown ) {
774
+ conf -> encryption_mode = prev -> encryption_mode ;
775
+ }
776
+
777
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_unknown ) {
778
+ conf -> encryption_mode = ngx_http_encrypted_session_mode_cbc ;
779
+ }
780
+
681
781
return NGX_CONF_OK ;
682
782
}
0 commit comments