@@ -51,6 +51,8 @@ def setUp(self):
51
51
def test_object_path (self ):
52
52
self .verify_keys_for_path (
53
53
'/a/c/o' , expected_keys = ('object' , 'container' ))
54
+ self .verify_keys_for_path (
55
+ '/a/c//o' , expected_keys = ('object' , 'container' ))
54
56
55
57
def test_container_path (self ):
56
58
self .verify_keys_for_path (
@@ -79,7 +81,7 @@ def verify_keys_for_path(self, path, expected_keys, key_id=None):
79
81
self .assertIn ('id' , keys )
80
82
id = keys .pop ('id' )
81
83
self .assertEqual (path , id ['path' ])
82
- self .assertEqual ('1 ' , id ['v' ])
84
+ self .assertEqual ('2 ' , id ['v' ])
83
85
keys .pop ('all_ids' )
84
86
self .assertListEqual (sorted (expected_keys ), sorted (keys .keys ()),
85
87
'%s %s got keys %r, but expected %r'
@@ -203,7 +205,7 @@ def test_chained_keymasters(self):
203
205
keys = copy .deepcopy (req .environ [CRYPTO_KEY_CALLBACK ](key_id = None ))
204
206
self .assertIn ('id' , keys )
205
207
self .assertEqual (keys .pop ('id' ), {
206
- 'v' : '1 ' ,
208
+ 'v' : '2 ' ,
207
209
'path' : '/a/c' ,
208
210
'secret_id' : '22' ,
209
211
})
@@ -227,7 +229,7 @@ def test_chained_keymasters(self):
227
229
at_least_one_old_style_id = True
228
230
self .assertEqual (key_id , {
229
231
'path' : '/a/c' ,
230
- 'v' : '1 ' ,
232
+ 'v' : '2 ' ,
231
233
})
232
234
self .assertTrue (at_least_one_old_style_id )
233
235
self .assertEqual (len (all_keys ), 3 )
@@ -245,7 +247,7 @@ def test_chained_keymasters(self):
245
247
keys = req .environ .get (CRYPTO_KEY_CALLBACK )(key_id = None )
246
248
self .assertIn ('id' , keys )
247
249
self .assertEqual (keys .pop ('id' ), {
248
- 'v' : '1 ' ,
250
+ 'v' : '2 ' ,
249
251
'path' : '/a/c/o' ,
250
252
'secret_id' : '22' ,
251
253
})
@@ -267,7 +269,7 @@ def test_chained_keymasters(self):
267
269
self .assertIn (key_id .pop ('secret_id' ), {'22' , 'my_secret_id' })
268
270
self .assertEqual (key_id , {
269
271
'path' : '/a/c/o' ,
270
- 'v' : '1 ' ,
272
+ 'v' : '2 ' ,
271
273
})
272
274
self .assertTrue (at_least_one_old_style_id )
273
275
self .assertEqual (len (all_keys ), 3 )
@@ -346,8 +348,9 @@ def test_correct_root_secret_used(self):
346
348
347
349
# secret_id passed to fetch_crypto_keys callback
348
350
for secret_id in ('my_secret_id' , None ):
349
- keys = self .verify_keys_for_path ('/a/c/o' , ('container' , 'object' ),
350
- key_id = {'secret_id' : secret_id })
351
+ keys = self .verify_keys_for_path (
352
+ '/a/c/o' , ('container' , 'object' ),
353
+ key_id = {'secret_id' : secret_id , 'v' : '2' , 'path' : '/a/c/o' })
351
354
expected_keys = {
352
355
'container' : hmac .new (secrets [secret_id ], b'/a/c' ,
353
356
digestmod = hashlib .sha256 ).digest (),
@@ -381,11 +384,11 @@ def mock_create_key(path, secret_id=None):
381
384
digestmod = hashlib .sha256 ).digest (),
382
385
'object' : hmac .new (secrets ['22' ], b'/a/c/o' ,
383
386
digestmod = hashlib .sha256 ).digest (),
384
- 'id' : {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '1 ' },
387
+ 'id' : {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '2 ' },
385
388
'all_ids' : [
386
- {'path' : '/a/c/o' , 'v' : '1 ' },
387
- {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '1 ' },
388
- {'path' : '/a/c/o' , 'secret_id' : 'my_secret_id' , 'v' : '1 ' }]}
389
+ {'path' : '/a/c/o' , 'v' : '2 ' },
390
+ {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '2 ' },
391
+ {'path' : '/a/c/o' , 'secret_id' : 'my_secret_id' , 'v' : '2 ' }]}
389
392
self .assertEqual (expected_keys , keys )
390
393
self .assertEqual ([('/a/c' , '22' ), ('/a/c/o' , '22' )], calls )
391
394
with mock .patch .object (self .app , 'create_key' , mock_create_key ):
@@ -394,22 +397,91 @@ def mock_create_key(path, secret_id=None):
394
397
self .assertEqual ([('/a/c' , '22' ), ('/a/c/o' , '22' )], calls )
395
398
self .assertEqual (expected_keys , keys )
396
399
with mock .patch .object (self .app , 'create_key' , mock_create_key ):
397
- keys = context .fetch_crypto_keys (key_id = {'secret_id' : None })
400
+ keys = context .fetch_crypto_keys (key_id = {
401
+ 'secret_id' : None , 'v' : '2' , 'path' : '/a/c/o' })
398
402
expected_keys = {
399
403
'container' : hmac .new (secrets [None ], b'/a/c' ,
400
404
digestmod = hashlib .sha256 ).digest (),
401
405
'object' : hmac .new (secrets [None ], b'/a/c/o' ,
402
406
digestmod = hashlib .sha256 ).digest (),
403
- 'id' : {'path' : '/a/c/o' , 'v' : '1 ' },
407
+ 'id' : {'path' : '/a/c/o' , 'v' : '2 ' },
404
408
'all_ids' : [
405
- {'path' : '/a/c/o' , 'v' : '1 ' },
406
- {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '1 ' },
407
- {'path' : '/a/c/o' , 'secret_id' : 'my_secret_id' , 'v' : '1 ' }]}
409
+ {'path' : '/a/c/o' , 'v' : '2 ' },
410
+ {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : '2 ' },
411
+ {'path' : '/a/c/o' , 'secret_id' : 'my_secret_id' , 'v' : '2 ' }]}
408
412
self .assertEqual (expected_keys , keys )
409
413
self .assertEqual ([('/a/c' , '22' ), ('/a/c/o' , '22' ),
410
414
('/a/c' , None ), ('/a/c/o' , None )],
411
415
calls )
412
416
417
+ def test_v1_keys (self ):
418
+ secrets = {None : os .urandom (32 ),
419
+ '22' : os .urandom (33 )}
420
+ conf = {}
421
+ for secret_id , secret in secrets .items ():
422
+ opt = ('encryption_root_secret%s' %
423
+ (('_%s' % secret_id ) if secret_id else '' ))
424
+ conf [opt ] = base64 .b64encode (secret )
425
+ conf ['active_root_secret_id' ] = '22'
426
+ self .app = keymaster .KeyMaster (self .swift , conf )
427
+ orig_create_key = self .app .create_key
428
+ calls = []
429
+
430
+ def mock_create_key (path , secret_id = None ):
431
+ calls .append ((path , secret_id ))
432
+ return orig_create_key (path , secret_id )
433
+
434
+ context = keymaster .KeyMasterContext (self .app , 'a' , 'c' , 'o' )
435
+ for version in ('1' , '2' ):
436
+ with mock .patch .object (self .app , 'create_key' , mock_create_key ):
437
+ keys = context .fetch_crypto_keys (key_id = {
438
+ 'v' : version , 'path' : '/a/c/o' })
439
+ expected_keys = {
440
+ 'container' : hmac .new (secrets [None ], b'/a/c' ,
441
+ digestmod = hashlib .sha256 ).digest (),
442
+ 'object' : hmac .new (secrets [None ], b'/a/c/o' ,
443
+ digestmod = hashlib .sha256 ).digest (),
444
+ 'id' : {'path' : '/a/c/o' , 'v' : version },
445
+ 'all_ids' : [
446
+ {'path' : '/a/c/o' , 'v' : version },
447
+ {'path' : '/a/c/o' , 'secret_id' : '22' , 'v' : version }]}
448
+ self .assertEqual (expected_keys , keys )
449
+ self .assertEqual ([('/a/c' , None ), ('/a/c/o' , None )], calls )
450
+ del calls [:]
451
+
452
+ context = keymaster .KeyMasterContext (self .app , 'a' , 'c' , '/o' )
453
+ with mock .patch .object (self .app , 'create_key' , mock_create_key ):
454
+ keys = context .fetch_crypto_keys (key_id = {
455
+ 'v' : '1' , 'path' : '/o' })
456
+ expected_keys = {
457
+ 'container' : hmac .new (secrets [None ], b'/a/c' ,
458
+ digestmod = hashlib .sha256 ).digest (),
459
+ 'object' : hmac .new (secrets [None ], b'/o' ,
460
+ digestmod = hashlib .sha256 ).digest (),
461
+ 'id' : {'path' : '/o' , 'v' : '1' },
462
+ 'all_ids' : [
463
+ {'path' : '/o' , 'v' : '1' },
464
+ {'path' : '/o' , 'secret_id' : '22' , 'v' : '1' }]}
465
+ self .assertEqual (expected_keys , keys )
466
+ self .assertEqual ([('/a/c' , None ), ('/o' , None )], calls )
467
+ del calls [:]
468
+
469
+ context = keymaster .KeyMasterContext (self .app , 'a' , 'c' , '/o' )
470
+ with mock .patch .object (self .app , 'create_key' , mock_create_key ):
471
+ keys = context .fetch_crypto_keys (key_id = {
472
+ 'v' : '2' , 'path' : '/a/c//o' })
473
+ expected_keys = {
474
+ 'container' : hmac .new (secrets [None ], b'/a/c' ,
475
+ digestmod = hashlib .sha256 ).digest (),
476
+ 'object' : hmac .new (secrets [None ], b'/a/c//o' ,
477
+ digestmod = hashlib .sha256 ).digest (),
478
+ 'id' : {'path' : '/a/c//o' , 'v' : '2' },
479
+ 'all_ids' : [
480
+ {'path' : '/a/c//o' , 'v' : '2' },
481
+ {'path' : '/a/c//o' , 'secret_id' : '22' , 'v' : '2' }]}
482
+ self .assertEqual (expected_keys , keys )
483
+ self .assertEqual ([('/a/c' , None ), ('/a/c//o' , None )], calls )
484
+
413
485
@mock .patch ('swift.common.middleware.crypto.keymaster.readconf' )
414
486
def test_keymaster_config_path (self , mock_readconf ):
415
487
for secret in (os .urandom (32 ), os .urandom (33 ), os .urandom (50 )):
0 commit comments