@@ -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
@@ -245,15 +258,31 @@ ngx_http_session_generate_signature(ngx_http_request_t *r,
245
258
246
259
static ngx_str_t *
247
260
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 )
261
+ ngx_str_t * iv , ngx_str_t * key , ngx_str_t * content ,
262
+ ngx_str_t * tag , enum ngx_http_encrypted_session_mode mode )
249
263
{
250
264
ngx_str_t * signature = ngx_http_session_generate_signature (r , iv , key , content );
251
265
252
- size_t new_len = iv -> len + content -> len + signature -> len ;
266
+ size_t new_len = iv -> len + signature -> len + content -> len ;
267
+
268
+ if (mode == ngx_http_encrypted_session_mode_gcm )
269
+ {
270
+ new_len += tag -> len ;
271
+ }
272
+
253
273
u_char * new_content = (u_char * )ngx_pcalloc (r -> pool , new_len + 1 );
254
274
ngx_memcpy (new_content , iv -> data , iv -> len );
255
275
ngx_memcpy (new_content + iv -> len , signature -> data , signature -> len );
256
- ngx_memcpy (new_content + iv -> len + signature -> len , content -> data , content -> len );
276
+
277
+ if (mode == ngx_http_encrypted_session_mode_gcm )
278
+ {
279
+ ngx_memcpy (new_content + iv -> len + signature -> len , tag -> data , tag -> len );
280
+ ngx_memcpy (new_content + iv -> len + signature -> len + tag -> len , content -> data , content -> len );
281
+ }
282
+ else
283
+ {
284
+ ngx_memcpy (new_content + iv -> len + signature -> len , content -> data , content -> len );
285
+ }
257
286
258
287
ngx_log_error (NGX_LOG_DEBUG , r -> connection -> log , 0 ,
259
288
"encrypted_session: encrypted data len=%d" , content -> len );
@@ -314,9 +343,11 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
314
343
content .data );
315
344
}
316
345
346
+ u_char * tag ;
317
347
rc = ngx_http_encrypted_session_aes_mac_encrypt (emcf , r -> pool ,
318
348
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
319
- content .data , content .len , (ngx_uint_t ) conf -> expires , & dst , & len );
349
+ content .data , content .len ,
350
+ (ngx_uint_t ) conf -> expires , conf -> encryption_mode , & dst , & len , & tag );
320
351
321
352
if (rc != NGX_OK ) {
322
353
res -> data = NULL ;
@@ -332,8 +363,12 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
332
363
encrypted_content .len = len ;
333
364
encrypted_content .data = dst ;
334
365
366
+ ngx_str_t tag_content ;
367
+ tag_content .len = ngx_http_encrypted_session_aes_tag_size ;
368
+ tag_content .data = tag ;
369
+
335
370
ngx_str_t * result = ngx_http_session_generate_response_with_iv (r , & iv ,
336
- & key , & encrypted_content );
371
+ & key , & encrypted_content , & tag_content , conf -> encryption_mode );
337
372
res -> data = result -> data ;
338
373
res -> len = result -> len ;
339
374
@@ -377,6 +412,8 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
377
412
378
413
ngx_str_t iv ;
379
414
ngx_str_t content ;
415
+ ngx_str_t tag ;
416
+
380
417
content .data = v -> data ;
381
418
content .len = v -> len ;
382
419
@@ -405,10 +442,28 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
405
442
u_char * signature = (u_char * )ngx_pcalloc (r -> pool , SIGNATURE_LENGTH + 1 );
406
443
ngx_memcpy (signature , content .data + iv .len , SIGNATURE_LENGTH );
407
444
445
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_gcm )
446
+ {
447
+ tag .len = ngx_http_encrypted_session_aes_tag_size ;
448
+ tag .data = (u_char * )ngx_pcalloc (r -> pool , tag .len );
449
+ ngx_memcpy (tag .data , content .data + iv .len + SIGNATURE_LENGTH , tag .len );
450
+ }
451
+
408
452
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 );
453
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_gcm )
454
+ {
455
+ encrypted_content .len = content .len - iv .len - SIGNATURE_LENGTH - tag .len ;
456
+ encrypted_content .data = (u_char * )ngx_pcalloc (r -> pool , encrypted_content .len + 1 );
457
+ ngx_memcpy (encrypted_content .data ,
458
+ v -> data + iv .len + SIGNATURE_LENGTH + tag .len ,
459
+ encrypted_content .len );
460
+ }
461
+ else
462
+ {
463
+ encrypted_content .len = content .len - iv .len - SIGNATURE_LENGTH ;
464
+ encrypted_content .data = (u_char * )ngx_pcalloc (r -> pool , encrypted_content .len + 1 );
465
+ ngx_memcpy (encrypted_content .data , v -> data + iv .len + SIGNATURE_LENGTH , encrypted_content .len );
466
+ }
412
467
413
468
content .data = encrypted_content .data ;
414
469
content .len = encrypted_content .len ;
@@ -432,7 +487,8 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
432
487
433
488
rc = ngx_http_encrypted_session_aes_mac_decrypt (emcf , r -> pool ,
434
489
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
435
- content .data , content .len , & dst , & len );
490
+ content .data , content .len , conf -> encryption_mode , tag .data ,
491
+ & dst , & len );
436
492
437
493
if (rc != NGX_OK ) {
438
494
ngx_log_error (NGX_LOG_WARN , r -> connection -> log , 0 ,
@@ -542,6 +598,24 @@ ngx_http_encrypted_session_iv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
542
598
return NGX_CONF_OK ;
543
599
}
544
600
601
+ static char *
602
+ ngx_http_encrypted_session_mode_set (ngx_conf_t * cf ,
603
+ ngx_command_t * cmd , void * conf )
604
+ {
605
+ ngx_str_t * value ;
606
+ ngx_http_encrypted_session_conf_t * llcf = conf ;
607
+
608
+ value = cf -> args -> elts ;
609
+ if (value [1 ].len == 3 && strncmp ("cbc" , (char * )value [1 ].data , 3 ) == 0 ) {
610
+ llcf -> encryption_mode = ngx_http_encrypted_session_mode_cbc ;
611
+ }
612
+ else if (value [1 ].len == 3 && strncmp ("gcm" , (char * )value [1 ].data , 3 ) == 0 ) {
613
+ llcf -> encryption_mode = ngx_http_encrypted_session_mode_gcm ;
614
+ }
615
+
616
+ return NGX_CONF_OK ;
617
+ }
618
+
545
619
546
620
static char *
547
621
ngx_http_encrypted_session_expires (ngx_conf_t * cf , ngx_command_t * cmd ,
@@ -654,6 +728,7 @@ ngx_http_encrypted_session_create_conf(ngx_conf_t *cf)
654
728
conf -> iv_len = NGX_CONF_UNSET ;
655
729
conf -> expires = NGX_CONF_UNSET ;
656
730
conf -> iv_in_content = NGX_CONF_UNSET ;
731
+ conf -> encryption_mode = ngx_http_encrypted_session_mode_unknown ;
657
732
658
733
return conf ;
659
734
}
@@ -678,5 +753,13 @@ ngx_http_encrypted_session_merge_conf(ngx_conf_t *cf, void *parent, void *child)
678
753
ngx_http_encrypted_session_default_expires );
679
754
ngx_conf_merge_value (conf -> iv_in_content , prev -> iv_in_content , 0 );
680
755
756
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_unknown ) {
757
+ conf -> encryption_mode = prev -> encryption_mode ;
758
+ }
759
+
760
+ if (conf -> encryption_mode == ngx_http_encrypted_session_mode_unknown ) {
761
+ conf -> encryption_mode = ngx_http_encrypted_session_mode_cbc ;
762
+ }
763
+
681
764
return NGX_CONF_OK ;
682
765
}
0 commit comments