10
10
#include "ddebug.h"
11
11
12
12
#include <ndk.h>
13
+ #include <string.h>
13
14
#include "ngx_http_encrypted_session_cipher.h"
14
15
15
16
#define ngx_http_encrypted_session_default_iv (u_char *) "deadbeefdeadbeef"
19
20
20
21
typedef struct {
21
22
u_char * key ;
23
+ size_t key_len ;
22
24
u_char * iv ;
25
+ size_t iv_len ;
23
26
time_t expires ;
24
-
27
+ ngx_flag_t iv_in_content ;
25
28
} ngx_http_encrypted_session_conf_t ;
26
29
27
30
@@ -42,6 +45,8 @@ static char *ngx_http_encrypted_session_iv(ngx_conf_t *cf, ngx_command_t *cmd,
42
45
static char * ngx_http_encrypted_session_expires (ngx_conf_t * cf ,
43
46
ngx_command_t * cmd , void * conf );
44
47
48
+ static char * ngx_http_encrypted_iv_in_content (ngx_conf_t * cf ,
49
+ ngx_command_t * cmd , void * conf );
45
50
46
51
static ngx_int_t ngx_http_encrypted_session_init (ngx_conf_t * cf );
47
52
static void * ngx_http_encrypted_session_create_main_conf (ngx_conf_t * cf );
@@ -53,7 +58,6 @@ static void *ngx_http_encrypted_session_create_conf(ngx_conf_t *cf);
53
58
static char * ngx_http_encrypted_session_merge_conf (ngx_conf_t * cf , void * parent ,
54
59
void * child );
55
60
56
-
57
61
static ndk_set_var_t ngx_http_set_encode_encrypted_session_filter = {
58
62
NDK_SET_VAR_VALUE ,
59
63
(void * ) ngx_http_set_encode_encrypted_session ,
@@ -115,7 +119,14 @@ static ngx_command_t ngx_http_encrypted_session_commands[] = {
115
119
0 ,
116
120
& ngx_http_set_decode_encrypted_session_filter
117
121
},
118
-
122
+ { ngx_string ("include_iv_in_encrypted_payload" ),
123
+ NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_SIF_CONF
124
+ |NGX_HTTP_LOC_CONF |NGX_HTTP_LIF_CONF |NGX_CONF_NOARGS ,
125
+ ngx_http_encrypted_iv_in_content ,
126
+ NGX_HTTP_LOC_CONF_OFFSET ,
127
+ 0 ,
128
+ NULL
129
+ },
119
130
ngx_null_command
120
131
};
121
132
@@ -151,14 +162,14 @@ ngx_module_t ngx_http_encrypted_session_module = {
151
162
};
152
163
153
164
static ngx_str_t ngx_http_get_variable_by_name (ngx_http_request_t * r ,
154
- unsigned char * name , ngx_http_encrypted_session_conf_t * conf )
165
+ unsigned char * name , size_t name_len , ngx_http_encrypted_session_conf_t * conf )
155
166
{
156
167
ngx_http_variable_value_t * v ;
157
168
ngx_str_t name_str ;
158
169
name_str .data = name ;
159
- name_str .len = strlen (( const char * ) name ) ;
170
+ name_str .len = name_len ;
160
171
161
- ngx_uint_t key = ngx_hash_strlow (name , name , name_str . len );
172
+ ngx_uint_t key = ngx_hash_strlow (name , name , name_len );
162
173
v = ngx_http_get_variable (r , & name_str , key );
163
174
164
175
if (v -> not_found ) {
@@ -171,6 +182,19 @@ static ngx_str_t ngx_http_get_variable_by_name(ngx_http_request_t *r,
171
182
return var_value ;
172
183
}
173
184
185
+ static char *
186
+ ngx_http_encrypted_session_build_payload (ngx_http_request_t * r ,
187
+ char * input , size_t input_len , ngx_str_t * iv )
188
+ {
189
+ size_t new_len = input_len + iv -> len + 2 ;
190
+ char * data = (char * )ngx_pcalloc (r -> pool , new_len );
191
+ data = strncat (data , input , input_len );
192
+ data = strcat (data , ":" );
193
+ data = strncat (data , (char * )iv -> data , iv -> len );
194
+
195
+ return data ;
196
+ }
197
+
174
198
static ngx_int_t
175
199
ngx_http_set_encode_encrypted_session (ngx_http_request_t * r ,
176
200
ngx_str_t * res , ngx_http_variable_value_t * v )
@@ -196,12 +220,19 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
196
220
ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
197
221
"encrypted_session: expires=%T" , conf -> expires );
198
222
199
- ngx_str_t iv = ngx_http_get_variable_by_name (r , conf -> iv , conf );
200
- ngx_str_t key = ngx_http_get_variable_by_name (r , conf -> key , conf );
223
+ ngx_str_t iv = ngx_http_get_variable_by_name (r , conf -> iv , conf -> iv_len ,
224
+ conf );
225
+ ngx_str_t key = ngx_http_get_variable_by_name (r , conf -> key , conf -> key_len ,
226
+ conf );
227
+
228
+ char * data = (char * )v -> data ;
229
+ if (conf -> iv_in_content ) {
230
+ data = ngx_http_encrypted_session_build_payload (r , data , v -> len , & iv );
231
+ }
201
232
202
233
rc = ngx_http_encrypted_session_aes_mac_encrypt (emcf , r -> pool ,
203
234
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
204
- v -> data , v -> len , (ngx_uint_t ) conf -> expires , & dst , & len );
235
+ ( u_char * ) data , v -> len , (ngx_uint_t ) conf -> expires , & dst , & len );
205
236
206
237
if (rc != NGX_OK ) {
207
238
dst = NULL ;
@@ -211,6 +242,16 @@ ngx_http_set_encode_encrypted_session(ngx_http_request_t *r,
211
242
"encrypted_session: failed to encrypt" );
212
243
}
213
244
245
+ if (conf -> iv_in_content ) {
246
+ size_t new_len = iv .len + len + 1 ;
247
+ char * new_content = (char * )ngx_pcalloc (r -> pool , new_len );
248
+ new_content = strncat (new_content , (char * )iv .data , iv .len );
249
+ new_content = strcat (new_content , ":" );
250
+ new_content = strncat (new_content , (char * )dst , len );
251
+ len = new_len ;
252
+ dst = (u_char * )new_content ;
253
+ }
254
+
214
255
res -> data = dst ;
215
256
res -> len = len ;
216
257
@@ -240,12 +281,29 @@ ngx_http_set_decode_encrypted_session(ngx_http_request_t *r,
240
281
return NGX_ERROR ;
241
282
}
242
283
243
- ngx_str_t iv = ngx_http_get_variable_by_name (r , conf -> iv , conf );
244
- ngx_str_t key = ngx_http_get_variable_by_name (r , conf -> key , conf );
284
+ ngx_str_t iv ;
285
+ char * data = (char * )v -> data ;
286
+ size_t data_len = v -> len ;
287
+
288
+ if (!conf -> iv_in_content ) {
289
+ iv = ngx_http_get_variable_by_name (r , conf -> iv , conf -> iv_len , conf );
290
+ } else {
291
+ iv .len = strcspn (data , ":" );
292
+ iv .data = (u_char * )ngx_pcalloc (r -> pool , iv .len + 1 );
293
+
294
+ strncpy ((char * )iv .data , (char * )v -> data , iv .len );
295
+
296
+ data_len = v -> len - iv .len - 1 ;
297
+ data = (char * )ngx_pcalloc (r -> pool , data_len );
298
+ strncpy (data , (char * )(& v -> data [iv .len + 1 ]), data_len );
299
+ }
300
+
301
+ ngx_str_t key = ngx_http_get_variable_by_name (r , conf -> key , conf -> key_len ,
302
+ conf );
245
303
246
304
rc = ngx_http_encrypted_session_aes_mac_decrypt (emcf , r -> pool ,
247
305
r -> connection -> log , iv .data , iv .len , key .data , key .len ,
248
- v -> data , v -> len , & dst , & len );
306
+ ( u_char * ) data , data_len , & dst , & len );
249
307
250
308
if (rc != NGX_OK ) {
251
309
dst = NULL ;
@@ -273,7 +331,9 @@ ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
273
331
value = cf -> args -> elts ;
274
332
275
333
if (value [1 ].len > 1 && value [1 ].data [0 ] == '$' ) {
276
- llcf -> key = & (value [1 ].data [1 ]);
334
+ llcf -> key_len = value [1 ].len - 1 ;
335
+ llcf -> key = (u_char * )ngx_pcalloc (cf -> pool , llcf -> key_len );
336
+ strncpy ((char * )llcf -> key , (char * )& (value [1 ].data [1 ]), llcf -> key_len );
277
337
return NGX_CONF_OK ;
278
338
}
279
339
@@ -287,6 +347,7 @@ ngx_http_encrypted_session_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
287
347
}
288
348
289
349
llcf -> key = value [1 ].data ;
350
+ llcf -> key_len = value [1 ].len ;
290
351
291
352
return NGX_CONF_OK ;
292
353
}
@@ -307,6 +368,7 @@ ngx_http_encrypted_session_iv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
307
368
308
369
if (value [1 ].len > 1 && value [1 ].data [0 ] == '$' ) {
309
370
llcf -> iv = & (value [1 ].data [1 ]);
371
+ llcf -> iv_len = value [1 ].len - 1 ;
310
372
return NGX_CONF_OK ;
311
373
}
312
374
@@ -320,6 +382,7 @@ ngx_http_encrypted_session_iv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
320
382
}
321
383
322
384
llcf -> iv = ngx_pcalloc (cf -> pool , ngx_http_encrypted_session_iv_length );
385
+ llcf -> iv_len = ngx_http_encrypted_session_iv_length ;
323
386
324
387
if (llcf -> iv == NULL ) {
325
388
return NGX_CONF_ERROR ;
@@ -360,6 +423,13 @@ ngx_http_encrypted_session_expires(ngx_conf_t *cf, ngx_command_t *cmd,
360
423
return NGX_CONF_OK ;
361
424
}
362
425
426
+ static char * ngx_http_encrypted_iv_in_content (ngx_conf_t * cf ,
427
+ ngx_command_t * cmd , void * conf )
428
+ {
429
+ ngx_http_encrypted_session_conf_t * llcf = conf ;
430
+ llcf -> iv_in_content = 1 ;
431
+ return NGX_CONF_OK ;
432
+ }
363
433
364
434
static void
365
435
ngx_http_encrypted_session_free_cipher_ctx (void * data )
@@ -435,8 +505,11 @@ ngx_http_encrypted_session_create_conf(ngx_conf_t *cf)
435
505
}
436
506
437
507
conf -> key = NGX_CONF_UNSET_PTR ;
508
+ conf -> key_len = NGX_CONF_UNSET ;
438
509
conf -> iv = NGX_CONF_UNSET_PTR ;
510
+ conf -> iv_len = NGX_CONF_UNSET ;
439
511
conf -> expires = NGX_CONF_UNSET ;
512
+ conf -> iv_in_content = NGX_CONF_UNSET ;
440
513
441
514
return conf ;
442
515
}
@@ -449,12 +522,17 @@ ngx_http_encrypted_session_merge_conf(ngx_conf_t *cf, void *parent, void *child)
449
522
ngx_http_encrypted_session_conf_t * conf = child ;
450
523
451
524
ngx_conf_merge_ptr_value (conf -> key , prev -> key , NULL );
525
+ ngx_conf_merge_size_value (conf -> key_len , prev -> key_len ,
526
+ (size_t )ngx_http_encrypted_session_key_length );
452
527
453
528
ngx_conf_merge_ptr_value (conf -> iv , prev -> iv ,
454
529
ngx_http_encrypted_session_default_iv );
530
+ ngx_conf_merge_size_value (conf -> iv_len , prev -> iv_len ,
531
+ (size_t )ngx_http_encrypted_session_iv_length );
455
532
456
533
ngx_conf_merge_value (conf -> expires , prev -> expires ,
457
534
ngx_http_encrypted_session_default_expires );
535
+ ngx_conf_merge_value (conf -> iv_in_content , prev -> iv_in_content , 0 );
458
536
459
537
return NGX_CONF_OK ;
460
538
}
0 commit comments