)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b226d8c76f2e08c66b29c99841f0d80eb91c37aa","unresolved":false,"context_lines":[{"line_number":15,"context_line":"Co-Authored-By: Alistair Coles \u003calistair.coles@hpe.com\u003e"},{"line_number":16,"context_line":"Co-Authored-By: Jonathan Hinson \u003cjlhinson@us.ibm.com\u003e"},{"line_number":17,"context_line":"Co-Authored-By: Hamdi Roumani \u003croumani@ca.ibm.com\u003e"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Change-Id: Ie6db22697ceb1021baaa6bddcf8e41ae3acb5376"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7aa08908_c46569e1","line":18,"updated":"2016-06-14 18:08:27.000000000","message":"Add UpgradeImpact","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a5d4861595705abf7b83db38649b3b998eaf43d","unresolved":false,"context_lines":[{"line_number":15,"context_line":"Co-Authored-By: Alistair Coles \u003calistair.coles@hpe.com\u003e"},{"line_number":16,"context_line":"Co-Authored-By: Jonathan Hinson \u003cjlhinson@us.ibm.com\u003e"},{"line_number":17,"context_line":"Co-Authored-By: Hamdi Roumani \u003croumani@ca.ibm.com\u003e"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Change-Id: Ie6db22697ceb1021baaa6bddcf8e41ae3acb5376"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7aa08908_0116f8f0","line":18,"in_reply_to":"7aa08908_449deb08","updated":"2016-06-15 18:43:31.000000000","message":"Done","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"597ef9249a8fd515cfad5d19c974ef02cdb17bde","unresolved":false,"context_lines":[{"line_number":15,"context_line":"Co-Authored-By: Alistair Coles \u003calistair.coles@hpe.com\u003e"},{"line_number":16,"context_line":"Co-Authored-By: Jonathan Hinson \u003cjlhinson@us.ibm.com\u003e"},{"line_number":17,"context_line":"Co-Authored-By: Hamdi Roumani \u003croumani@ca.ibm.com\u003e"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Change-Id: Ie6db22697ceb1021baaa6bddcf8e41ae3acb5376"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7aa08908_449deb08","line":18,"in_reply_to":"7aa08908_c46569e1","updated":"2016-06-14 18:37:54.000000000","message":"Thanks. I actually had a draft about just that!\n\nIn particular, you won\u0027t be able to turn on encryption until *all* of your object servers *and* proxies have upgraded to post-crypto, right? Object servers need to upgrade to support csv etag-is-at functionality, and proxies need to upgrade to ensure you don\u0027t have one proxy allowing encrypted uploads while another proxy doesn\u0027t know how to decrypt.","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"}],"doc/source/middleware.rst":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":104,"context_line":".. automodule:: swift.common.middleware.crypto"},{"line_number":105,"context_line":"    :members:"},{"line_number":106,"context_line":"    :show-inheritance:"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":".. _formpost:"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"FormPost"}],"source_content_type":"text/x-rst","patch_set":16,"id":"3aaa91ec_6e2284ba","line":107,"updated":"2016-07-01 08:14:58.000000000","message":"I need to think of more yet but probably I\u0027d like to add some module docs to be better than now because this one shows just:\n\n\nImplements middleware for object encryption which comprises an instance of a Decrypter combined with an instance of an Encrypter.\n\nswift.common.middleware.crypto.filter_factory(global_conf, **local_conf)\nProvides a factory function for loading encryption middleware.\n\n\nrather than other middleware shows some descriptions and Middleware class description. (just a link for encryption docs seems ok though)","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1ba0cfc92ebd719c0846f08b16b351e967e6d995","unresolved":false,"context_lines":[{"line_number":104,"context_line":".. automodule:: swift.common.middleware.crypto"},{"line_number":105,"context_line":"    :members:"},{"line_number":106,"context_line":"    :show-inheritance:"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":".. _formpost:"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"FormPost"}],"source_content_type":"text/x-rst","patch_set":16,"id":"3aaa91ec_f9b475f1","line":107,"in_reply_to":"3aaa91ec_6e2284ba","updated":"2016-07-01 10:10:37.000000000","message":"+1 I just put this as a placeholder to not delay the patch while I figure out all the rst directives to produce something better.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7faa00f7afe580951206819df4f12e908e28acbb","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"3aaa91ec_a573a6b3","line":789,"updated":"2016-06-28 07:52:02.000000000","message":"when will this TODO happen? Cause you mention it\u0027ll stay here while in the feature branch, well soon it\u0027ll be in the master.. and having it here means people will use it :) Happy for it to be a follow up patch after merge.. just want to be sure there is a plan.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"3aaa91ec_dff144cf","line":789,"in_reply_to":"3aaa91ec_a573a6b3","updated":"2016-06-28 16:23:06.000000000","message":"It is done in the final patch of the chain (docs) https://review.openstack.org/#/c/328209/10\n\nThe idea is that we have a root secret so that we can have encryption in the pipeline for func tests while on this feature branch, so the gate is helping us.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"925e7bbcf835264f479d0c029a4e76241d9fe2f4","unresolved":false,"context_lines":[{"line_number":794,"context_line":"# Encryption of new data and/or metadata may be disabled by setting"},{"line_number":795,"context_line":"# disable_encryption to True. However, all encryption middlware should remain"},{"line_number":796,"context_line":"# in the pipeline in order for existing encrypted data to be read."},{"line_number":797,"context_line":"# disable_encryption \u003d False"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"3aaa91ec_5caf3e94","line":797,"updated":"2016-06-28 07:00:46.000000000","message":"So we\u0027ve got three middlewares... that all work together... and will break horribly if they\u0027re in the wrong order... and expose a total of two config options.\n\nI kinda feel like we ought to have (and recommend using) a keymaster_crypto filter that bundles all three together in the right order. All config options are passed to all three middlewares. Maybe we could even provide some crypto_filter_factory_factory or something that could be used to wrap out-of-tree keymasters.\n\nThis isn\u0027t to say we should get rid of the three separate filters; I think having them separable will be helpful for the developers of those out-of-tree keymasters, or for operators that need a multi-keymaster setup. I just want to make it easier for operators to deploy a good config.\n\nBut then, maybe having more than one way to do the same thing would just make it worse...","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":794,"context_line":"# Encryption of new data and/or metadata may be disabled by setting"},{"line_number":795,"context_line":"# disable_encryption to True. However, all encryption middlware should remain"},{"line_number":796,"context_line":"# in the pipeline in order for existing encrypted data to be read."},{"line_number":797,"context_line":"# disable_encryption \u003d False"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"3aaa91ec_bfd6f8ee","line":797,"in_reply_to":"3aaa91ec_5caf3e94","updated":"2016-06-28 16:23:06.000000000","message":"Let\u0027s talk! I would like to collapse encrypter and decrypter into one middleware. I am not so sure about the need to bind keymaster in since it is intended to be replaced (or to co-exist with others) and we cope with getting other dependent middlewares in the right order.\n\nIf we do this I would like to make it an isolated change i.e. new version of review with no other changes, for the sake of reviewers following.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":768,"context_line":""},{"line_number":769,"context_line":"# Note: To enable encryption, add the following 3 dependent pieces of"},{"line_number":770,"context_line":"# crypto middleware to the proxy-server pipeline as follows:"},{"line_number":771,"context_line":"# ... decrypter keymaster encrypter proxy-logging (end of pipeline)"},{"line_number":772,"context_line":"[filter:decrypter]"},{"line_number":773,"context_line":"use \u003d egg:swift#decrypter"},{"line_number":774,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_7553c5e2","line":771,"range":{"start_line":771,"start_character":50,"end_line":771,"end_character":67},"updated":"2016-06-30 07:28:43.000000000","message":"Didn\u0027t I see a patchset somewhere with this changed to \"proxy-server\"? Maybe that was the docs patch. I think I like that more, though.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":768,"context_line":""},{"line_number":769,"context_line":"# Note: To enable encryption, add the following 3 dependent pieces of"},{"line_number":770,"context_line":"# crypto middleware to the proxy-server pipeline as follows:"},{"line_number":771,"context_line":"# ... decrypter keymaster encrypter proxy-logging (end of pipeline)"},{"line_number":772,"context_line":"[filter:decrypter]"},{"line_number":773,"context_line":"use \u003d egg:swift#decrypter"},{"line_number":774,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_d2f6f65b","line":771,"range":{"start_line":771,"start_character":50,"end_line":771,"end_character":67},"in_reply_to":"3aaa91ec_7553c5e2","updated":"2016-06-30 16:40:17.000000000","message":"Yes it\u0027s in the docs patch. Should be here.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6a433b661fd58672a01fc78fa9ca597c2b0c985b","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_66dcb6e4","line":789,"updated":"2016-06-29 23:58:47.000000000","message":"I\u0027d like +2 whoever said this config value should be for a file path... It\u0027s annoying to have to come up with a good way to DRY out in my internal-client.conf (for container-sync) and the proxies.\n\nwith conf.d and symlinks it\u0027s *possible* - but annoying\n\nPlus if someone was ever like \"hey security people can you give me root key for my cluster\" they\u0027re probably going to hand them some sort of \"file\"","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"54f124d55818e37b1d4811e6060b1fdc8ae6448f","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_5da047f4","line":789,"in_reply_to":"3aaa91ec_16a8758b","updated":"2016-06-30 14:14:46.000000000","message":"I like Matt\u0027s suggestion","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b294c5cd7ccbaeec69280dc95621b150ecc332bc","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"1aa78d24_eeaadf84","line":789,"in_reply_to":"3aaa91ec_5da047f4","updated":"2016-07-01 23:04:17.000000000","message":"re: encryption_root_secret_path -- see https://review.openstack.org/#/c/336720/","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"10b9ba832f692a0210760375d992c047cc7b555f","unresolved":false,"context_lines":[{"line_number":786,"context_line":"# continues on the feature/crypto branch.  Later, this will be added"},{"line_number":787,"context_line":"# to the devstack proxy-config so that gate tests can pass."},{"line_number":788,"context_line":"# base64 encoding of \"dontEverUseThisIn_PRODUCTION_xxxxxxxxxxxxxxx\""},{"line_number":789,"context_line":"encryption_root_secret \u003d ZG9udEV2ZXJVc2VUaGlzSW5fUFJPRFVDVElPTl94eHh4eHh4eHh4eHh4eHg\u003d"},{"line_number":790,"context_line":""},{"line_number":791,"context_line":"[filter:encrypter]"},{"line_number":792,"context_line":"use \u003d egg:swift#encrypter"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_16a8758b","line":789,"in_reply_to":"3aaa91ec_66dcb6e4","updated":"2016-06-30 07:45:35.000000000","message":"Maybe parameters encryption_root_secret and encryption_root_secret_path, and the latter trumps the former... just so we have best of both worlds. And to still make it simpler for testing (devstack).\n\nBut I think this can be a follow up patch. Unless we think a path would be something we always want and not be so bad for testing... in which case my arm is easily twisted.\n\nTLDR: I\u0027m +2 for path.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"etc/swift.conf-sample":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"# By default the maximum number of allowed headers depends on the number of max"},{"line_number":139,"context_line":"# allowed metadata settings plus a default value of 132 for swift internally"},{"line_number":140,"context_line":"# generated headers and regular http headers.  If for some reason this is not"},{"line_number":141,"context_line":"# enough (custom middleware for example) it can be increased with the"},{"line_number":142,"context_line":"# extra_header_count constraint."},{"line_number":143,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_d5b279e4","line":140,"updated":"2016-06-30 07:28:43.000000000","message":"No longer needed, right?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"# By default the maximum number of allowed headers depends on the number of max"},{"line_number":139,"context_line":"# allowed metadata settings plus a default value of 132 for swift internally"},{"line_number":140,"context_line":"# generated headers and regular http headers.  If for some reason this is not"},{"line_number":141,"context_line":"# enough (custom middleware for example) it can be increased with the"},{"line_number":142,"context_line":"# extra_header_count constraint."},{"line_number":143,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":12,"id":"3aaa91ec_f5c15c30","line":140,"in_reply_to":"3aaa91ec_d5b279e4","updated":"2016-06-30 16:40:17.000000000","message":"132 is now wrong. We do add 4 extra headers (sysmeta -Body-Meta, -Crypto-Etag, -Crypto-Etag-Hmac and transient sysmeta -Crypto-Meta) so i will bump this to 36.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"other-requirements.txt":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6a433b661fd58672a01fc78fa9ca597c2b0c985b","unresolved":false,"context_lines":[{"line_number":14,"context_line":"rsync"},{"line_number":15,"context_line":"xfsprogs"},{"line_number":16,"context_line":"libssl-dev [platform:dpkg]"},{"line_number":17,"context_line":"openssl-devel [platform:rpm]"}],"source_content_type":"text/plain","patch_set":12,"id":"3aaa91ec_49f6ed8f","line":17,"updated":"2016-06-29 23:58:47.000000000","message":"looks like everyone has openssl 1.0.1 dev packages - which I guess crypto needs [1]\n\n1. https://cryptography.io/en/latest/installation/#supported-platforms","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":14,"context_line":"rsync"},{"line_number":15,"context_line":"xfsprogs"},{"line_number":16,"context_line":"libssl-dev [platform:dpkg]"},{"line_number":17,"context_line":"openssl-devel [platform:rpm]"}],"source_content_type":"text/plain","patch_set":12,"id":"3aaa91ec_d5df00d4","line":17,"in_reply_to":"3aaa91ec_49f6ed8f","updated":"2016-06-30 16:40:17.000000000","message":"Are you suggesting that 1.0.1 gets included here? I\u0027m not sure what the syntax is for that.\n\nOr maybe you are just saying this is OK?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"requirements.txt":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6a433b661fd58672a01fc78fa9ca597c2b0c985b","unresolved":false,"context_lines":[{"line_number":11,"context_line":"six\u003e\u003d1.9.0"},{"line_number":12,"context_line":"xattr\u003e\u003d0.4"},{"line_number":13,"context_line":"PyECLib\u003e\u003d1.2.0                          # BSD"},{"line_number":14,"context_line":"cryptography\u003e\u003d1.0,!\u003d1.3.0               # BSD/Apache-2.0"}],"source_content_type":"text/plain","patch_set":12,"id":"3aaa91ec_e9887924","line":14,"updated":"2016-06-29 23:58:47.000000000","message":"FWIW, cent7 ships 0.8.2 of PyCA\u0027s cryptography library\n\ncent6, trusty, and of course precise - have nothing at all\n\ngo go packaging team!","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":11,"context_line":"six\u003e\u003d1.9.0"},{"line_number":12,"context_line":"xattr\u003e\u003d0.4"},{"line_number":13,"context_line":"PyECLib\u003e\u003d1.2.0                          # BSD"},{"line_number":14,"context_line":"cryptography\u003e\u003d1.0,!\u003d1.3.0               # BSD/Apache-2.0"}],"source_content_type":"text/plain","patch_set":12,"id":"3aaa91ec_75e56ca2","line":14,"in_reply_to":"3aaa91ec_e9887924","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"setup.cfg":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d7546f8a82b4af46fc4e6d9c894120dd31bb3322","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    xprofile \u003d swift.common.middleware.xprofile:filter_factory"},{"line_number":98,"context_line":"    versioned_writes \u003d swift.common.middleware.versioned_writes:filter_factory"},{"line_number":99,"context_line":"    copy \u003d swift.common.middleware.copy:filter_factory"},{"line_number":100,"context_line":"    keymaster \u003d swift.common.middleware.keymaster:filter_factory"},{"line_number":101,"context_line":"    encryption \u003d swift.common.middleware.crypto:filter_factory"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"[build_sphinx]"}],"source_content_type":"text/x-ttcn-cfg","patch_set":14,"id":"3aaa91ec_7006f386","line":100,"updated":"2016-06-30 20:25:28.000000000","message":"Good catch, John! We want\n\n keymaster \u003d swift.common.middleware.crypto.keymaster:filter_factory\n\nhere. Note the \".crypto\".","commit_id":"306d605fafa35695175280c9e34b6faeb54af16a"}],"swift/common/constraints.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"10b9ba832f692a0210760375d992c047cc7b555f","unresolved":false,"context_lines":[{"line_number":114,"context_line":"# generated headers and regular http headers.  If for some reason this is not"},{"line_number":115,"context_line":"# enough (custom middleware for example) it can be increased with the"},{"line_number":116,"context_line":"# extra_header_count constraint."},{"line_number":117,"context_line":"MAX_HEADER_COUNT \u003d MAX_META_COUNT + 132 + max(EXTRA_HEADER_COUNT, 0)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"def check_metadata(req, target_type):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_513b27d1","line":117,"range":{"start_line":117,"start_character":36,"end_line":117,"end_character":39},"updated":"2016-06-30 07:45:35.000000000","message":"Now that we are combining the crypto_meta with the encrypted data + now moving user meta, are we still adding too many headers that warrant the increase to the default max headers?\n\nI don\u0027t mind if this is raised (tho 100 is quite a large raise), just want to make sure it\u0027s a artifact.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":114,"context_line":"# generated headers and regular http headers.  If for some reason this is not"},{"line_number":115,"context_line":"# enough (custom middleware for example) it can be increased with the"},{"line_number":116,"context_line":"# extra_header_count constraint."},{"line_number":117,"context_line":"MAX_HEADER_COUNT \u003d MAX_META_COUNT + 132 + max(EXTRA_HEADER_COUNT, 0)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"def check_metadata(req, target_type):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_950ab188","line":117,"updated":"2016-06-30 07:28:43.000000000","message":"This is no longer needed, right?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":114,"context_line":"# generated headers and regular http headers.  If for some reason this is not"},{"line_number":115,"context_line":"# enough (custom middleware for example) it can be increased with the"},{"line_number":116,"context_line":"# extra_header_count constraint."},{"line_number":117,"context_line":"MAX_HEADER_COUNT \u003d MAX_META_COUNT + 132 + max(EXTRA_HEADER_COUNT, 0)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"def check_metadata(req, target_type):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_759c4c0e","line":117,"range":{"start_line":117,"start_character":36,"end_line":117,"end_character":39},"in_reply_to":"3aaa91ec_513b27d1","updated":"2016-06-30 16:40:17.000000000","message":"no longer needs top be 132. We add 4 headers, so I will make this 36","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"fbc030c9dbb05f79465be8aaa5d25cf60d89475f","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            return HTTPBadRequest("},{"line_number":167,"context_line":"                body\u003d\u0027Too many metadata items; max %d\u0027 % MAX_META_COUNT,"},{"line_number":168,"context_line":"                request\u003dreq, content_type\u003d\u0027text/plain\u0027)"},{"line_number":169,"context_line":"        elif meta_size \u003e MAX_META_OVERALL_SIZE:"},{"line_number":170,"context_line":"            return HTTPBadRequest("},{"line_number":171,"context_line":"                body\u003d\u0027Total metadata too large; max %d\u0027"},{"line_number":172,"context_line":"                % MAX_META_OVERALL_SIZE,"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3df00991","line":169,"updated":"2016-06-29 18:13:54.000000000","message":"elif was added back in here and above","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            return HTTPBadRequest("},{"line_number":167,"context_line":"                body\u003d\u0027Too many metadata items; max %d\u0027 % MAX_META_COUNT,"},{"line_number":168,"context_line":"                request\u003dreq, content_type\u003d\u0027text/plain\u0027)"},{"line_number":169,"context_line":"        elif meta_size \u003e MAX_META_OVERALL_SIZE:"},{"line_number":170,"context_line":"            return HTTPBadRequest("},{"line_number":171,"context_line":"                body\u003d\u0027Total metadata too large; max %d\u0027"},{"line_number":172,"context_line":"                % MAX_META_OVERALL_SIZE,"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_d50ef98a","line":169,"in_reply_to":"3aaa91ec_3df00991","updated":"2016-06-30 07:28:43.000000000","message":"No, elif is no longer changed. I feel like this can be done as a follow-up on master if we really want it.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":166,"context_line":"            return HTTPBadRequest("},{"line_number":167,"context_line":"                body\u003d\u0027Too many metadata items; max %d\u0027 % MAX_META_COUNT,"},{"line_number":168,"context_line":"                request\u003dreq, content_type\u003d\u0027text/plain\u0027)"},{"line_number":169,"context_line":"        elif meta_size \u003e MAX_META_OVERALL_SIZE:"},{"line_number":170,"context_line":"            return HTTPBadRequest("},{"line_number":171,"context_line":"                body\u003d\u0027Total metadata too large; max %d\u0027"},{"line_number":172,"context_line":"                % MAX_META_OVERALL_SIZE,"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_f5a79c4d","line":169,"in_reply_to":"3aaa91ec_d50ef98a","updated":"2016-06-30 16:40:17.000000000","message":"+1 change on master, not in scope of this patch.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"swift/common/middleware/crypto/decrypter.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"318ed266177388b0dfdeba8ab7058c4ebb1e243b","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            start_response(self._response_status, self._response_headers,"},{"line_number":332,"context_line":"                           self._response_exc_info)"},{"line_number":333,"context_line":"        else:"},{"line_number":334,"context_line":"            mod_resp_headers \u003d self.decrypt_resp_headers(keys)"},{"line_number":335,"context_line":"            mod_resp_headers \u003d purge_crypto_sysmeta_headers(mod_resp_headers)"},{"line_number":336,"context_line":"            start_response(self._response_status, mod_resp_headers,"},{"line_number":337,"context_line":"                           self._response_exc_info)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3aaa91ec_3f554cf9","line":334,"updated":"2016-07-01 04:47:43.000000000","message":"When decrypting the user metadata we move it back into the x-object-meta namespace. However we do so all lowercase. So it gets back to the user lowercase:\n\n  HTTP/1.1 200 OK\n  Etag: 81dc9bdb52d04dc20036dbd8313ed055\n  x-object-meta-Foo: mwuhahaha\n  Content-Length: 4\n  Accept-Ranges: bytes\n  Last-Modified: Fri, 01 Jul 2016 04:15:50 GMT\n  X-Timestamp: 1467346549.67032\n  Content-Type: application/x-www-form-urlencoded\n  X-Trans-Id: tx6572f0da4b18474ea04ab-005775ee9b\n  Date: Fri, 01 Jul 2016 04:16:27 GMT\n\n  1234\n\nNOTE: see x-object-meta-Foo above\n\nWe need to wrap this in a HeaderKeyDict or something. Something like http://paste.openstack.org/show/524383/\n\nOf course this can be a follow up change.","commit_id":"c5f0c96da96b61a5f2749b62c0e11ef183b4e423"}],"swift/common/middleware/crypto/encrypter.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":39,"context_line":"        dict of form returned by"},{"line_number":40,"context_line":"        :py:func:`~swift.common.middleware.crypto.Crypto.get_crypto_meta`"},{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":"    if not value:"},{"line_number":43,"context_line":"        return \u0027\u0027, None"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    crypto_meta \u003d crypto.create_crypto_meta()"},{"line_number":46,"context_line":"    crypto_ctxt \u003d crypto.create_encryption_ctxt(key, crypto_meta[\u0027iv\u0027])"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_d3fa3f42","line":43,"range":{"start_line":42,"start_character":0,"end_line":43,"end_character":23},"updated":"2016-07-01 08:14:58.000000000","message":"nits) Perhaps, we don\u0027t need this if condition because it seems callers is doing the validation for value and when I remove those 2 lines, nothing (at least unit) failed.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":147,"context_line":"            # This may be None if no override was set and no data was read"},{"line_number":148,"context_line":"            container_listing_etag \u003d footers.get("},{"line_number":149,"context_line":"                \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027,"},{"line_number":150,"context_line":"                container_listing_etag_header) or plaintext_etag"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"            if container_listing_etag is not None:"},{"line_number":153,"context_line":"                # Encrypt the container-listing etag using the container key"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_cee57838","line":150,"range":{"start_line":150,"start_character":16,"end_line":150,"end_character":45},"updated":"2016-07-01 08:14:58.000000000","message":"memo) oh, yeah. This is *header_container_listing_etag_header*.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":236,"context_line":"        enc_input_proxy \u003d EncInputWrapper(self.crypto, keys, req, self.logger)"},{"line_number":237,"context_line":"        req.environ[\u0027wsgi.input\u0027] \u003d enc_input_proxy"},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"        # If an etag is in the response headers and a plaintext etag was"},{"line_number":242,"context_line":"        # calculated, then overwrite the response value with the plaintext etag"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_33de233e","line":239,"updated":"2016-07-01 08:14:58.000000000","message":"nits) To be correct, self._app_call will return an iterator (note that is\u0027s not swift.swob.Response instance) so that resp_iter seems better[1]. Probably same for other method calling self._app_call.\n\n1: https://github.com/openstack/swift/blob/master/swift/common/wsgi.py#L1035-L1053","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        a masked etag value would collide with an unmasked value."},{"line_number":287,"context_line":""},{"line_number":288,"context_line":"        :param req: an instance of swob.Request"},{"line_number":289,"context_line":"        :param header_name: name of header that has etags to mask"},{"line_number":290,"context_line":"        :return: True if any etags were masked, False otherwise"},{"line_number":291,"context_line":"        \"\"\""},{"line_number":292,"context_line":"        masked \u003d False"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_38ae0281","line":289,"updated":"2016-07-01 08:14:58.000000000","message":"nits) it should be either If-Match or If-None-Match, probably.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":337,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"encrypter\")"},{"line_number":338,"context_line":"        self.crypto \u003d Crypto(conf)"},{"line_number":339,"context_line":"        self.disable_encryption \u003d config_true_value("},{"line_number":340,"context_line":"            conf.get(\u0027disable_encryption\u0027, \u0027false\u0027))"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def __call__(self, env, start_response):"},{"line_number":343,"context_line":"        # If override is set in env, then just pass along"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_b818321f","line":340,"updated":"2016-07-01 08:14:58.000000000","message":"nits) Regarding to upgrading secenario, we should set disable_encryption as True in default. Otherwise operators can deploy encryption without setting this value and unfortunately encryption will start to work unexpectedly.\n\nI know docs says this value set to True at first but it\u0027s not default I\u0027m concerned.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1ba0cfc92ebd719c0846f08b16b351e967e6d995","unresolved":false,"context_lines":[{"line_number":337,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"encrypter\")"},{"line_number":338,"context_line":"        self.crypto \u003d Crypto(conf)"},{"line_number":339,"context_line":"        self.disable_encryption \u003d config_true_value("},{"line_number":340,"context_line":"            conf.get(\u0027disable_encryption\u0027, \u0027false\u0027))"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def __call__(self, env, start_response):"},{"line_number":343,"context_line":"        # If override is set in env, then just pass along"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_59d30904","line":340,"in_reply_to":"3aaa91ec_b818321f","updated":"2016-07-01 10:10:37.000000000","message":"I can see both sides of the argument. I think the reason for making the default False is to avoid an op mistakenly thinking they are encrypting data, because the middleware is deployed, when actually they are not.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"}],"swift/common/middleware/crypto/keymaster.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":136,"context_line":"                return err_resp(env, start_response)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"        # anything else"},{"line_number":139,"context_line":"        return self.app(env, start_response)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def create_key(self, key_id):"},{"line_number":142,"context_line":"        return hmac.new(self.root_secret, key_id,"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_4ea9888f","line":139,"updated":"2016-07-01 08:14:58.000000000","message":"Just a memo) As I discussed with Alistair, we will be able to make a context manager to ristrict fetch_keys is available only on right of keymaster in pipeline. It could be at later of landing.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"}],"swift/common/middleware/crypto_utils.py":[{"author":{"_account_id":8004,"name":"Paul Kehrer","email":"paul.l.kehrer@gmail.com","username":"reaperhulk"},"change_message_id":"0d924ab97ee4de5a251f6d394b17e7e2850927d9","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        \"\"\""},{"line_number":57,"context_line":"        self.check_key(key)"},{"line_number":58,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":59,"context_line":"                        backend\u003ddefault_backend())"},{"line_number":60,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":61,"context_line":"        return CryptoContext(enc, iv, 0)"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_6847d877","line":59,"updated":"2016-06-15 21:53:38.000000000","message":"You probably want to memoize these default_backend() calls if this method gets called frequently. Each one results in a call into setuptools entrypoints and you can remove that cost by just setting up a backend global initially.","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba4ab6a5f023d5b3604d4c71c0503e418900ff3f","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        \"\"\""},{"line_number":57,"context_line":"        self.check_key(key)"},{"line_number":58,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":59,"context_line":"                        backend\u003ddefault_backend())"},{"line_number":60,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":61,"context_line":"        return CryptoContext(enc, iv, 0)"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_b4c57a0b","line":59,"in_reply_to":"7aa08908_6847d877","updated":"2016-06-16 13:36:56.000000000","message":"Done, thank you!","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"b39b1db4c95d6b350dd7483fbcf79dae2c8cd2b7","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.check_key(key)"},{"line_number":73,"context_line":"        if offset \u003c 0:"},{"line_number":74,"context_line":"            raise ValueError(\u0027Offset must not be negative\u0027)"},{"line_number":75,"context_line":"        if offset \u003e 0:"},{"line_number":76,"context_line":"            # Adjust IV so that it is correct for decryption at offset."},{"line_number":77,"context_line":"            # ( 1\u003c\u003c (16 *8)) is to make \u0027ivl\u0027 big enough so that the following"},{"line_number":78,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":79,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":80,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":81,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":82,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":85,"context_line":"                        backend\u003ddefault_backend())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_71d5d9e3","line":82,"range":{"start_line":75,"start_character":0,"end_line":82,"end_character":70},"updated":"2016-06-16 17:18:14.000000000","message":"Went through this again, it\u0027s easily the most cryptic part here and not even due to cryptography. I double-checked the offset computation according to NIST SP800-38A Sec. 6.5.","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"e48322017f52979e8f66a98d6aa82af9c9843ff4","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.check_key(key)"},{"line_number":73,"context_line":"        if offset \u003c 0:"},{"line_number":74,"context_line":"            raise ValueError(\u0027Offset must not be negative\u0027)"},{"line_number":75,"context_line":"        if offset \u003e 0:"},{"line_number":76,"context_line":"            # Adjust IV so that it is correct for decryption at offset."},{"line_number":77,"context_line":"            # ( 1\u003c\u003c (16 *8)) is to make \u0027ivl\u0027 big enough so that the following"},{"line_number":78,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":79,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":80,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":81,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":82,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":85,"context_line":"                        backend\u003ddefault_backend())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_f4da49e8","line":82,"range":{"start_line":75,"start_character":0,"end_line":82,"end_character":70},"in_reply_to":"7aa08908_0a541752","updated":"2016-06-16 21:36:05.000000000","message":"Yes, that\u0027s fine. Let\u0027s add another line of comment here (after line 1, before line 2):\n---\nThe CTR mode offset is incremented for every AES block and taken modulo 2^128.\n---","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":10298,"name":"Mark Korondi","email":"korondi.mark@gmail.com","username":"oro"},"change_message_id":"1586c2ff8e9cd0c5c3aa3e3b43c880fafca864ef","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.check_key(key)"},{"line_number":73,"context_line":"        if offset \u003c 0:"},{"line_number":74,"context_line":"            raise ValueError(\u0027Offset must not be negative\u0027)"},{"line_number":75,"context_line":"        if offset \u003e 0:"},{"line_number":76,"context_line":"            # Adjust IV so that it is correct for decryption at offset."},{"line_number":77,"context_line":"            # ( 1\u003c\u003c (16 *8)) is to make \u0027ivl\u0027 big enough so that the following"},{"line_number":78,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":79,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":80,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":81,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":82,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":85,"context_line":"                        backend\u003ddefault_backend())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_381490e7","line":82,"range":{"start_line":75,"start_character":0,"end_line":82,"end_character":70},"in_reply_to":"7aa08908_34178def","updated":"2016-06-17 19:21:43.000000000","message":"Yes I think that interpretation is correct. It\u0027s just a note that I wanted to include for the readers\u0027 understanding, because it might not be obvious what the last line with the fromhex magic is about. Although I have other suggestions, see the latest comments plz.","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"1e3092352d8a8608d3ffbe590e7a31cac52bfe07","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.check_key(key)"},{"line_number":73,"context_line":"        if offset \u003c 0:"},{"line_number":74,"context_line":"            raise ValueError(\u0027Offset must not be negative\u0027)"},{"line_number":75,"context_line":"        if offset \u003e 0:"},{"line_number":76,"context_line":"            # Adjust IV so that it is correct for decryption at offset."},{"line_number":77,"context_line":"            # ( 1\u003c\u003c (16 *8)) is to make \u0027ivl\u0027 big enough so that the following"},{"line_number":78,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":79,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":80,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":81,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":82,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":85,"context_line":"                        backend\u003ddefault_backend())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_0a541752","line":82,"range":{"start_line":75,"start_character":0,"end_line":82,"end_character":70},"in_reply_to":"7aa08908_71d5d9e3","updated":"2016-06-16 17:32:46.000000000","message":"...and it\u0027s good, according to that spec?","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5e6ce1b16cc08e92bf8c945ab564b1376596d209","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.check_key(key)"},{"line_number":73,"context_line":"        if offset \u003c 0:"},{"line_number":74,"context_line":"            raise ValueError(\u0027Offset must not be negative\u0027)"},{"line_number":75,"context_line":"        if offset \u003e 0:"},{"line_number":76,"context_line":"            # Adjust IV so that it is correct for decryption at offset."},{"line_number":77,"context_line":"            # ( 1\u003c\u003c (16 *8)) is to make \u0027ivl\u0027 big enough so that the following"},{"line_number":78,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":79,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":80,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":81,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":82,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":85,"context_line":"                        backend\u003ddefault_backend())"}],"source_content_type":"text/x-python","patch_set":4,"id":"7aa08908_34178def","line":82,"range":{"start_line":75,"start_character":0,"end_line":82,"end_character":70},"in_reply_to":"7aa08908_f4da49e8","updated":"2016-06-17 13:19:34.000000000","message":"I took lines 1 and 2 to refer to the comment so mapping to lines 76 and 77, please correct me if you intended otherwise. Thanks for the text.","commit_id":"b28ddb526cbad9a582316447c4a06e626a78b0a1"},{"author":{"_account_id":10298,"name":"Mark Korondi","email":"korondi.mark@gmail.com","username":"oro"},"change_message_id":"373fcc904f0e8c90643015b53deeb1c72a405570","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":89,"context_line":"                        backend\u003dself.backend)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7aa08908_f8a04892","line":86,"range":{"start_line":86,"start_character":12,"end_line":86,"end_character":70},"updated":"2016-06-17 19:21:20.000000000","message":"ivstr[(len(ivstr) - 2 * 16):]\n\nis basically the same as \n\nivstr[-2*16:]\n\nThis might express clearly yet less convoluted that we want the last (overflown) 16 bytes (128 bit) from the calculated temporary iv.","commit_id":"bad829134d3113b9f308cf06fc290d1317c886fa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c5aea7bb2dcc9e52a5fef7d32201adcf3688e8e2","unresolved":false,"context_lines":[{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[(len(ivstr) - 2 * 16):]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":89,"context_line":"                        backend\u003dself.backend)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_33a0c790","line":86,"range":{"start_line":86,"start_character":12,"end_line":86,"end_character":70},"in_reply_to":"7aa08908_f8a04892","updated":"2016-06-21 18:30:17.000000000","message":"Done, thanks.","commit_id":"bad829134d3113b9f308cf06fc290d1317c886fa"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[-2 * 16:]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_0240d355","line":85,"range":{"start_line":85,"start_character":32,"end_line":85,"end_character":35},"updated":"2016-06-22 00:09:22.000000000","message":"We can avoid adding the (1 \u003c\u003c (16 * 8)) constant by specifying \u0027032x\u0027 here. I could also see a case for pulling bytes_per_block out as a constant here, and maybe using divmod. Something like http://paste.openstack.org/show/520984/, maybe?\n\nAlthough, by making the modular arithmetic look like modular arithmetic (instead of string manipulations), the constant came back... and that final `iv \u003d ...` might still be trying to do too much in one line.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[-2 * 16:]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_375e6812","line":85,"range":{"start_line":85,"start_character":32,"end_line":85,"end_character":35},"in_reply_to":"3aaa91ec_0240d355","updated":"2016-06-23 22:49:18.000000000","message":"Ack, waiting for Janie to look into this method before changing.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"c8baeb70c03552c6834ceede61560c40d693b6fb","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[-2 * 16:]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_ba750dfb","line":85,"range":{"start_line":85,"start_character":32,"end_line":85,"end_character":35},"in_reply_to":"3aaa91ec_375e6812","updated":"2016-06-24 06:04:47.000000000","message":"The changes in the paste look good (will need to change to now use the self.iv_length of course).  \n\nAgreed the last line does a lot, but I do like the divmod and not having to add the padding to the left.\n\nChristian had mentioned testing the case where the iv is the maximum value, so that the increment will wrap.  I only had time to mimic the current test with that value at : http://paste.openstack.org/show/521837/\n\nThe code in the paste passes that test.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"67baf72ab75ddae92fb9694bfe4b2b5f899ea4d7","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # bytearray.fromhex() can be successful in all conditions."},{"line_number":83,"context_line":"            ivl \u003d long(binascii.hexlify(iv), 16)"},{"line_number":84,"context_line":"            ivl +\u003d int(offset / 16) + (1 \u003c\u003c (16 * 8))"},{"line_number":85,"context_line":"            ivstr \u003d format(ivl, \u0027x\u0027)"},{"line_number":86,"context_line":"            iv \u003d str(bytearray.fromhex(ivstr[-2 * 16:]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_ef050411","line":85,"range":{"start_line":85,"start_character":32,"end_line":85,"end_character":35},"in_reply_to":"3aaa91ec_ba750dfb","updated":"2016-06-27 09:48:50.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        dec.update(\u0027*\u0027 * (offset % 16))"},{"line_number":93,"context_line":"        return CryptoContext(dec, iv, offset)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def get_required_iv_length(self):"},{"line_number":96,"context_line":"        return algorithms.AES.block_size / 8"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_f1f7d088","line":95,"updated":"2016-06-23 22:49:18.000000000","message":"doe snot need to be a public method","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"67baf72ab75ddae92fb9694bfe4b2b5f899ea4d7","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        dec.update(\u0027*\u0027 * (offset % 16))"},{"line_number":93,"context_line":"        return CryptoContext(dec, iv, offset)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def get_required_iv_length(self):"},{"line_number":96,"context_line":"        return algorithms.AES.block_size / 8"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_6fc3d489","line":95,"in_reply_to":"3aaa91ec_f1f7d088","updated":"2016-06-27 09:48:50.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"},{"line_number":99,"context_line":"        target_length \u003d self.get_required_iv_length()"},{"line_number":100,"context_line":"        if len(base) \u003c target_length:"},{"line_number":101,"context_line":"            return base.zfill(target_length)"},{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_bd4e4094","line":101,"range":{"start_line":101,"start_character":24,"end_line":101,"end_character":29},"updated":"2016-06-22 00:09:22.000000000","message":"The more I think about it, the less I like it.\n\n- Not a deal-breaker, but \u0027\\x00\u0027 feels like a better nothing-up-my-sleeves filler than \u00270\u0027.\n- zfill pads on the *left*, which means the bits from base get incremented *first*. As a result, /a/c/o is encrypted with the same keystream as /a/c/n with Range: bytes\u003d16-\n\nI\u0027m fairly certain we want ljust here.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d1d3b8a092d29646901c710e6d871bc48f63cb35","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"},{"line_number":99,"context_line":"        target_length \u003d self.get_required_iv_length()"},{"line_number":100,"context_line":"        if len(base) \u003c target_length:"},{"line_number":101,"context_line":"            return base.zfill(target_length)"},{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_f8eee189","line":101,"range":{"start_line":101,"start_character":24,"end_line":101,"end_character":29},"in_reply_to":"3aaa91ec_0a745a9a","updated":"2016-06-22 16:36:44.000000000","message":"@Tim - derived IV is only used for etag so the scenario with a range of object data doesn\u0027t happen, we should be careful to avoid but IV overlaps with etags.\n\nre Janie\u0027s statement that \"our goal is for the nonce part (first 8 bytes) of the returned iv to be different for /a/c/o versus a/c/n\" - this implementation doesn\u0027t appear to achieve that because its using zfill so the first 8 bytes (reading from left) will be \u00270\u0027 in both cases.\n\nBut where does the \"first 8 bytes\" part come into play? I tried to follow the code path down to the openssl lib that implements AES CTR (I could have ended up in wrong lib!) and I found this func that increments the IV (ivec) which as far as I can tell is whatever we pass to modes.CTR() (at line 88 for example).\n\nSo given we only use this derived iv for Etags, then we only encrypt 256bits with a derived etag, or 2 blocks. So for any etag the encrypter will use derived_iv and (derived_iv + 1), correct?\n\nNow I\u0027m not sure how endianess works out here, so to be safe, if we made the first and last bytes of our derived_iv always be zero and the rest be unique based on path then we\u0027d allow more than enough room for the IV to increment (by just 1 for an etag) without any overlap. Unless the path is longer then 14 bytes I see no need to has it, since the IV spacing would be guaranteed by the zero bytes.\n\nThat said, this code has been reviewed by crypto experts so I am not rushing to change it.\n\n[1] http://osxr.org:8080/openssl/source/crypto/modes/ctr128.c#0080","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"},{"line_number":99,"context_line":"        target_length \u003d self.get_required_iv_length()"},{"line_number":100,"context_line":"        if len(base) \u003c target_length:"},{"line_number":101,"context_line":"            return base.zfill(target_length)"},{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_6d330a15","line":101,"range":{"start_line":101,"start_character":24,"end_line":101,"end_character":29},"in_reply_to":"3aaa91ec_1fa2acae","updated":"2016-06-23 22:49:18.000000000","message":"If we switch back to using object key whenever we use a derived key then I think there is no longer a requirement for IV\u0027s to be distinct w.r.t. other object paths - we\u0027ll never use the same (key, derived_iv) so it doesn\u0027t matter if the derived_iv for /a/c/n is within a count +/- 1 of the derived_iv for /a/c/o.\n\nThat said, zfill seems like a weird choice since it not a numeric string to start with. Will change to ljust.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a709c37452c0a8393a5394caa2e72aa482a103d3","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"},{"line_number":99,"context_line":"        target_length \u003d self.get_required_iv_length()"},{"line_number":100,"context_line":"        if len(base) \u003c target_length:"},{"line_number":101,"context_line":"            return base.zfill(target_length)"},{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_0a745a9a","line":101,"range":{"start_line":101,"start_character":24,"end_line":101,"end_character":29},"in_reply_to":"3aaa91ec_bd4e4094","updated":"2016-06-22 03:50:43.000000000","message":"Good point:\nMy understanding is that as it is now, the keystream would not be the same immediately, because the counter part of the iv would still be starting at a different number for the first block for something encrypted at one path versus another.  But this might decrease the amount of iv\u0027s that could be used until there are collisions between blocks of something encrypted at one path versus another, (depending on what bit starts to differ and what bit starts the counter).\n\nI think this provides a good argument to use a hash of some sort of the path in all cases.  that way, the output is more - I dont want to say random - but scattered?  That way, if two paths are similar (like in the case where the container is the same - and etags are using the same container key), the md5 will still be different enough that we are making full use of all the bits in the iv.  \n\nThe point is, our goal is for the nonce part (first 8 bytes) of the returned iv to be different for /a/c/o versus a/c/n.  The easiest way to have a high chance of that is to use a hash of some sort.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"c52668662876bdf7f72caeb76b4ff76a0e13304a","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def _get_derived_iv(self, base):"},{"line_number":99,"context_line":"        target_length \u003d self.get_required_iv_length()"},{"line_number":100,"context_line":"        if len(base) \u003c target_length:"},{"line_number":101,"context_line":"            return base.zfill(target_length)"},{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_1fa2acae","line":101,"range":{"start_line":101,"start_character":24,"end_line":101,"end_character":29},"in_reply_to":"3aaa91ec_f8eee189","updated":"2016-06-22 18:03:02.000000000","message":"I follow - and am with you.  And yes, I was forgetting about the fact that we only have to worry about 2 blocks. Thanks for adding the reference to the code.  I am interested in checking out the details :-)","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"},{"line_number":105,"context_line":"            return hash.hexdigest()[-target_length:]"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            return base"},{"line_number":108,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_18a5e203","line":105,"range":{"start_line":105,"start_character":24,"end_line":105,"end_character":33},"updated":"2016-06-22 00:09:22.000000000","message":"A few issues here.\n\n- Why lose half our bits? Why not just use .digest()?\n- We shouldn\u0027t use hash; that shadows a builtin.\n- The update call is unnecessary; we can provide an initialization string to the constructor.\n\nHow about http://paste.openstack.org/show/520986/ instead?\n\nStepping back a little, why use MD5 here, as opposed to another hash algorithm? Relatedly, do we anticipate adding support for any other encryption algorithms? Say, ones with a longer block size?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d1d3b8a092d29646901c710e6d871bc48f63cb35","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        elif len(base) \u003e target_length:"},{"line_number":103,"context_line":"            hash \u003d md5()"},{"line_number":104,"context_line":"            hash.update(base)"},{"line_number":105,"context_line":"            return hash.hexdigest()[-target_length:]"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            return base"},{"line_number":108,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_588575ab","line":105,"range":{"start_line":105,"start_character":24,"end_line":105,"end_character":33},"in_reply_to":"3aaa91ec_18a5e203","updated":"2016-06-22 16:36:44.000000000","message":"Ack -waiting for more discussion on the wider issues around this method.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            return self._get_derived_iv(iv_base)"},{"line_number":116,"context_line":"        return self._get_random_iv()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def get_cipher(self):"},{"line_number":119,"context_line":"        return \u0027AES_CTR_256\u0027"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def create_crypto_meta(self, iv_base\u003dNone):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_51da2418","line":118,"updated":"2016-06-23 22:49:18.000000000","message":"does not need to be a method","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"67baf72ab75ddae92fb9694bfe4b2b5f899ea4d7","unresolved":false,"context_lines":[{"line_number":115,"context_line":"            return self._get_derived_iv(iv_base)"},{"line_number":116,"context_line":"        return self._get_random_iv()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def get_cipher(self):"},{"line_number":119,"context_line":"        return \u0027AES_CTR_256\u0027"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def create_crypto_meta(self, iv_base\u003dNone):"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_afb93c17","line":118,"in_reply_to":"3aaa91ec_51da2418","updated":"2016-06-27 09:48:50.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    Crypto context used in encryption middleware.  Created by calling"},{"line_number":174,"context_line":"    :func:`create_encryption_ctxt` or :func:`create_decryption_ctxt`."},{"line_number":175,"context_line":"    \"\"\""},{"line_number":176,"context_line":"    def __init__(self, engine, iv, offset):"},{"line_number":177,"context_line":"        self.engine \u003d engine"},{"line_number":178,"context_line":"        self.iv \u003d iv"},{"line_number":179,"context_line":"        self.offset \u003d offset"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_c5eecbeb","line":176,"range":{"start_line":176,"start_character":31,"end_line":176,"end_character":41},"updated":"2016-06-22 00:09:22.000000000","message":"All of the iv and offset handling was done before this was called, yes? Do we actually need either of these? Would it be better for us to just return enc/dec above and nix this whole class?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"c52668662876bdf7f72caeb76b4ff76a0e13304a","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    Crypto context used in encryption middleware.  Created by calling"},{"line_number":174,"context_line":"    :func:`create_encryption_ctxt` or :func:`create_decryption_ctxt`."},{"line_number":175,"context_line":"    \"\"\""},{"line_number":176,"context_line":"    def __init__(self, engine, iv, offset):"},{"line_number":177,"context_line":"        self.engine \u003d engine"},{"line_number":178,"context_line":"        self.iv \u003d iv"},{"line_number":179,"context_line":"        self.offset \u003d offset"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_a42b8f93","line":176,"range":{"start_line":176,"start_character":31,"end_line":176,"end_character":41},"in_reply_to":"3aaa91ec_19164f55","updated":"2016-06-22 18:03:02.000000000","message":"I am on board with having middleware make calls directly to engine, I suppose.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    Crypto context used in encryption middleware.  Created by calling"},{"line_number":174,"context_line":"    :func:`create_encryption_ctxt` or :func:`create_decryption_ctxt`."},{"line_number":175,"context_line":"    \"\"\""},{"line_number":176,"context_line":"    def __init__(self, engine, iv, offset):"},{"line_number":177,"context_line":"        self.engine \u003d engine"},{"line_number":178,"context_line":"        self.iv \u003d iv"},{"line_number":179,"context_line":"        self.offset \u003d offset"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_1429aae6","line":176,"range":{"start_line":176,"start_character":31,"end_line":176,"end_character":41},"in_reply_to":"3aaa91ec_a42b8f93","updated":"2016-06-23 22:49:18.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a709c37452c0a8393a5394caa2e72aa482a103d3","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    Crypto context used in encryption middleware.  Created by calling"},{"line_number":174,"context_line":"    :func:`create_encryption_ctxt` or :func:`create_decryption_ctxt`."},{"line_number":175,"context_line":"    \"\"\""},{"line_number":176,"context_line":"    def __init__(self, engine, iv, offset):"},{"line_number":177,"context_line":"        self.engine \u003d engine"},{"line_number":178,"context_line":"        self.iv \u003d iv"},{"line_number":179,"context_line":"        self.offset \u003d offset"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_ead74e21","line":176,"range":{"start_line":176,"start_character":31,"end_line":176,"end_character":41},"in_reply_to":"3aaa91ec_c5eecbeb","updated":"2016-06-22 03:50:43.000000000","message":"This exists because it is saving the engine which holds a specific state about where the streaming is at in the message.  The engine is different for each message encryption or decryption.  Maybe I would need to see how the proposed solution and how this \u0027context\u0027 info would be persisted during the streaming. Currently, the encrypter keeps the reference to the context and calls update.  Would this change mean that the engine is exposed to the encrypter?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d1d3b8a092d29646901c710e6d871bc48f63cb35","unresolved":false,"context_lines":[{"line_number":173,"context_line":"    Crypto context used in encryption middleware.  Created by calling"},{"line_number":174,"context_line":"    :func:`create_encryption_ctxt` or :func:`create_decryption_ctxt`."},{"line_number":175,"context_line":"    \"\"\""},{"line_number":176,"context_line":"    def __init__(self, engine, iv, offset):"},{"line_number":177,"context_line":"        self.engine \u003d engine"},{"line_number":178,"context_line":"        self.iv \u003d iv"},{"line_number":179,"context_line":"        self.offset \u003d offset"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_19164f55","line":176,"range":{"start_line":176,"start_character":31,"end_line":176,"end_character":41},"in_reply_to":"3aaa91ec_ead74e21","updated":"2016-06-22 16:36:44.000000000","message":"I think Tim is pointing out that this class does nothing other than wrap the engine update method - we never access the encapsulated state (iv, offset).\n\nI did try a while back to make the context generate the iv (ie setup its own crypto_meta) but it didn\u0027t prove much gain.\n\nSo I agree this class could disappear and we just have the middlewares call engine.update directly, unless there is an argument to maintain the abstraction?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":208,"context_line":"        except Exception as err:  # noqa"},{"line_number":209,"context_line":"            self.logger.exception(_("},{"line_number":210,"context_line":"                \u0027ERROR get_keys(): from %(callback)s: %(err)s\u0027),"},{"line_number":211,"context_line":"                {\u0027callback\u0027: CRYPTO_KEY_CALLBACK, \u0027err\u0027: str(err)})"},{"line_number":212,"context_line":"            raise HTTPInternalServerError("},{"line_number":213,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":214,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_853e83b6","line":211,"range":{"start_line":211,"start_character":29,"end_line":211,"end_character":48},"updated":"2016-06-22 00:09:22.000000000","message":"How much utility do we really get out of including the callback key name?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d1d3b8a092d29646901c710e6d871bc48f63cb35","unresolved":false,"context_lines":[{"line_number":208,"context_line":"        except Exception as err:  # noqa"},{"line_number":209,"context_line":"            self.logger.exception(_("},{"line_number":210,"context_line":"                \u0027ERROR get_keys(): from %(callback)s: %(err)s\u0027),"},{"line_number":211,"context_line":"                {\u0027callback\u0027: CRYPTO_KEY_CALLBACK, \u0027err\u0027: str(err)})"},{"line_number":212,"context_line":"            raise HTTPInternalServerError("},{"line_number":213,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":214,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_eb028a08","line":211,"range":{"start_line":211,"start_character":29,"end_line":211,"end_character":48},"in_reply_to":"3aaa91ec_853e83b6","updated":"2016-06-22 16:36:44.000000000","message":"trending towards zero ;)","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":208,"context_line":"        except Exception as err:  # noqa"},{"line_number":209,"context_line":"            self.logger.exception(_("},{"line_number":210,"context_line":"                \u0027ERROR get_keys(): from %(callback)s: %(err)s\u0027),"},{"line_number":211,"context_line":"                {\u0027callback\u0027: CRYPTO_KEY_CALLBACK, \u0027err\u0027: str(err)})"},{"line_number":212,"context_line":"            raise HTTPInternalServerError("},{"line_number":213,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":214,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_94975aeb","line":211,"range":{"start_line":211,"start_character":29,"end_line":211,"end_character":48},"in_reply_to":"3aaa91ec_eb028a08","updated":"2016-06-23 22:49:18.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        return {"},{"line_number":276,"context_line":"            str(name): (base64.b64decode(val) if name in (\u0027iv\u0027, \u0027key\u0027)"},{"line_number":277,"context_line":"                        else b64_decode_meta(val) if isinstance(val, dict)"},{"line_number":278,"context_line":"                        else str(val))"},{"line_number":279,"context_line":"            for name, val in crypto_meta.items()}"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_336d5805","line":278,"range":{"start_line":278,"start_character":33,"end_line":278,"end_character":36},"updated":"2016-06-22 00:09:22.000000000","message":"This should never have non-ASCII data, right?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a709c37452c0a8393a5394caa2e72aa482a103d3","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        return {"},{"line_number":276,"context_line":"            str(name): (base64.b64decode(val) if name in (\u0027iv\u0027, \u0027key\u0027)"},{"line_number":277,"context_line":"                        else b64_decode_meta(val) if isinstance(val, dict)"},{"line_number":278,"context_line":"                        else str(val))"},{"line_number":279,"context_line":"            for name, val in crypto_meta.items()}"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_eabaaebf","line":278,"range":{"start_line":278,"start_character":33,"end_line":278,"end_character":36},"in_reply_to":"3aaa91ec_336d5805","updated":"2016-06-22 03:50:43.000000000","message":"correct.  My understanding is that is exactly the reason we had to b64 encode and decode.  crypto-meta has to be a valid header value.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":308,"context_line":"    crypto_meta \u003d None"},{"line_number":309,"context_line":"    parts \u003d value.rsplit(\u0027;\u0027, 1)"},{"line_number":310,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":311,"context_line":"        value, param \u003d parts"},{"line_number":312,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"},{"line_number":313,"context_line":"        if param.strip().startswith(crypto_meta_tag):"},{"line_number":314,"context_line":"            param \u003d param.strip()[len(crypto_meta_tag):]"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_53c74445","line":311,"updated":"2016-06-22 00:09:22.000000000","message":"So value always loses its param, even if the param isn\u0027t swift_meta?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d1d3b8a092d29646901c710e6d871bc48f63cb35","unresolved":false,"context_lines":[{"line_number":308,"context_line":"    crypto_meta \u003d None"},{"line_number":309,"context_line":"    parts \u003d value.rsplit(\u0027;\u0027, 1)"},{"line_number":310,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":311,"context_line":"        value, param \u003d parts"},{"line_number":312,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"},{"line_number":313,"context_line":"        if param.strip().startswith(crypto_meta_tag):"},{"line_number":314,"context_line":"            param \u003d param.strip()[len(crypto_meta_tag):]"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_2b5c92ec","line":311,"in_reply_to":"3aaa91ec_53c74445","updated":"2016-06-22 16:36:44.000000000","message":"we should only use this with etag values that have no \u0027;\u0027","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"042c155b4863a4d02d81d9a7d30972693669a547","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    Used by middleware: Calls cryptography library"},{"line_number":45,"context_line":"    \"\"\""},{"line_number":46,"context_line":"    cipher \u003d \u0027AES_CTR_256\u0027"},{"line_number":47,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":50,"context_line":"        conf \u003d {} if conf is None else conf"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_bd2ce402","line":47,"updated":"2016-06-24 08:14:02.000000000","message":"Nice. Much more pythonic.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"69ca95d955203df97b9491f5170146c9f6278a0d","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    Used by middleware: Calls cryptography library"},{"line_number":45,"context_line":"    \"\"\""},{"line_number":46,"context_line":"    cipher \u003d \u0027AES_CTR_256\u0027"},{"line_number":47,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":50,"context_line":"        conf \u003d {} if conf is None else conf"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_6f947442","line":47,"in_reply_to":"3aaa91ec_1b7a6077","updated":"2016-06-24 13:30:52.000000000","message":"I think replacing all the 16s may be part of the plan to make that offset handling a little easier to read. Agreed that both of these are unlikely to change in the near future.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"9a52aa34481ee6a3ac94a80a38f34d3d6908fcda","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    Used by middleware: Calls cryptography library"},{"line_number":45,"context_line":"    \"\"\""},{"line_number":46,"context_line":"    cipher \u003d \u0027AES_CTR_256\u0027"},{"line_number":47,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":50,"context_line":"        conf \u003d {} if conf is None else conf"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_1b7a6077","line":47,"in_reply_to":"3aaa91ec_bd2ce402","updated":"2016-06-24 08:30:21.000000000","message":"Yes, but for stylistic consistency then all the values \"16\" that show up in create_decrypto_ctxt() should also be iv_length or block_length (which is the same as iv_length for any block cipher).  And if we already are at it, then one might also make the block cipher modular... But any such modularity was decided a long time ago to be \"out-of-scope\".\n\nHence we might simply leave it as a const \"16\", it wont unless a lot of other things change as well.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2015 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":4,"context_line":"# you may not use this file except in compliance with the License."}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_b305c815","line":1,"range":{"start_line":1,"start_character":16,"end_line":1,"end_character":20},"updated":"2016-06-27 19:11:46.000000000","message":"nit: 2015-2016, now. Probably true for some others, as well.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2015 OpenStack Foundation"},{"line_number":2,"context_line":"#"},{"line_number":3,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\");"},{"line_number":4,"context_line":"# you may not use this file except in compliance with the License."}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_766cb69c","line":1,"range":{"start_line":1,"start_character":16,"end_line":1,"end_character":20},"in_reply_to":"3aaa91ec_b305c815","updated":"2016-06-28 16:23:06.000000000","message":"errr, does it matter [1] ? We don\u0027t seem to maintain the year range in general across swift.\n\n\n[1] https://wiki.openstack.org/wiki/LegalIssuesFAQ","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"# AES will accept several key sizes - we are using 256 bits i.e. 32 bytes"},{"line_number":38,"context_line":"KEY_LENGTH \u003d 32"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class Crypto(object):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_651f175c","line":38,"range":{"start_line":38,"start_character":0,"end_line":38,"end_character":10},"updated":"2016-06-27 19:11:46.000000000","message":"Should this get baked into Crypto now, too?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"# AES will accept several key sizes - we are using 256 bits i.e. 32 bytes"},{"line_number":38,"context_line":"KEY_LENGTH \u003d 32"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class Crypto(object):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_7fd81080","line":38,"range":{"start_line":38,"start_character":0,"end_line":38,"end_character":10},"in_reply_to":"3aaa91ec_651f175c","updated":"2016-06-28 16:23:06.000000000","message":"Done","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":49,"context_line":"        conf \u003d {} if conf is None else conf"},{"line_number":50,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"},{"line_number":51,"context_line":"        # memoize backend to avoid repeated iteration over entry points"},{"line_number":52,"context_line":"        self.backend \u003d default_backend()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c5308beb","line":49,"updated":"2016-06-27 19:11:46.000000000","message":"nit: Looks like get_logger would accept conf\u003dNone; is this necessary?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":49,"context_line":"        conf \u003d {} if conf is None else conf"},{"line_number":50,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"},{"line_number":51,"context_line":"        # memoize backend to avoid repeated iteration over entry points"},{"line_number":52,"context_line":"        self.backend \u003d default_backend()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_7fbf70fc","line":49,"in_reply_to":"3aaa91ec_c5308beb","updated":"2016-06-28 16:23:06.000000000","message":"Done","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":282,"context_line":"    crypto_meta \u003d None"},{"line_number":283,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":284,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":285,"context_line":"    parts \u003d value.rsplit(\u0027;\u0027, 1)"},{"line_number":286,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":287,"context_line":"        value, param \u003d parts"},{"line_number":288,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_25734fb6","line":285,"range":{"start_line":285,"start_character":18,"end_line":285,"end_character":24},"updated":"2016-06-27 19:11:46.000000000","message":"In light of the above, does it matter whether we use split or rsplit? The *only* param we ever expect to find is swift_meta, right?\n\nI guess maybe this could guard against a semicolon randomly appearing in the ciphertext, but I don\u0027t think that should ever happen since we base64 encode.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":282,"context_line":"    crypto_meta \u003d None"},{"line_number":283,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":284,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":285,"context_line":"    parts \u003d value.rsplit(\u0027;\u0027, 1)"},{"line_number":286,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":287,"context_line":"        value, param \u003d parts"},{"line_number":288,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_1f058cc1","line":285,"range":{"start_line":285,"start_character":18,"end_line":285,"end_character":24},"in_reply_to":"3aaa91ec_25734fb6","updated":"2016-06-28 16:23:06.000000000","message":"Done","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"7a76ca51ffbef3ba1de2e49f81c44b00f874dcd6","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_b79c465e","line":172,"updated":"2016-06-28 23:41:10.000000000","message":"do we want this behavior?\n\nImagine this: a keymaster that can choose to install a callback for some requests and not others. This try/except will prevent that sort of functionality.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"c2121daddd59a8af693c64e0e89e3997f3d9236b","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_367af888","line":172,"in_reply_to":"3aaa91ec_149b8d73","updated":"2016-06-29 13:41:22.000000000","message":"Thanks Mahati.  Yes, I remember when we removed it from our keymaster.  But I was wanting to address the concerns about whether or not we would support a custom keymaster that would like to choose to install a callback on some requests, but not for others, as John mentioned.\n\nCurrently, we would support such a custom keymaster.  If the keymaster set the override flag, then the middleware will not call get keys:\n\nencrypter:\n   def __call__(self, env, start_response):\n        # If override is set in env, then just pass along\n        if config_true_value(env.get(\u0027swift.crypto.override\u0027)):\n            return self.app(env, start_response)\n\ndecrypter:\n    def process_resp(self, req):\n        if config_true_value(req.environ.get(\u0027swift.crypto.override\u0027)):\n            self.logger.debug(\u0027No decryption is necessary because of override\u0027)\n            return None\n\n        return self.get_keys(req.environ)","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ab06b4f8062b73b8763cbf014b64879824111f90","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_792beceb","line":172,"in_reply_to":"3aaa91ec_1930e8e7","updated":"2016-06-29 06:15:44.000000000","message":"True.\n\n- https://review.openstack.org/#/c/328208/11/swift/common/middleware/encrypter.py@315\n- https://review.openstack.org/#/c/328208/11/swift/common/middleware/decrypter.py@285\n- https://review.openstack.org/#/c/328208/11/swift/common/middleware/decrypter.py@373\n\nDecrypter using keys\u003dNone around https://review.openstack.org/#/c/328208/11/swift/common/middleware/decrypter.py@134 was a decent part of what gave me the idea.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d6d294ff","line":172,"in_reply_to":"3aaa91ec_367af888","updated":"2016-06-29 17:06:47.000000000","message":"Added to \"follow up\" on trello.\n\nAs said, the swift.crypto.override flag is there to cater for future keymasters that may not wish to provide keys. It is just not used right now.\n\nIf we merge the middlewares into a single filter then we remove the ability for the keymaster to set that before the decrypter might use the callback. personnaly I\u0027d like us to think a bit harder about the fetch keys callback interface (on master). It should be possible to use a single call back to communicate (a) keymaster not installed (no callback), (b) keymaster not providing keys or (c) here are the keys.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"9e3ceaedb4702b36a4511c84321d9420277ec54f","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_311b18cc","line":172,"in_reply_to":"3aaa91ec_367af888","updated":"2016-06-29 16:36:53.000000000","message":"Ah, great. Consider my concern addressed.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"9b43509aa334a1276097407c3c978045b30e0cea","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_1930e8e7","line":172,"in_reply_to":"3aaa91ec_62e69eb5","updated":"2016-06-29 05:51:25.000000000","message":"It\u0027s late, so I will dig into the exact code tomorrow.  But I believe that both the encrypter and decrypter will check for the override flag to be set before calling get_keys (used to be that way).  That is what gives the keymaster the capability of choosing not to encrypt/decrypt.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"5e0b80f4da0e2e1093b33f6596c9474b58bb29d4","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_149b8d73","line":172,"in_reply_to":"3aaa91ec_792beceb","updated":"2016-06-29 06:41:06.000000000","message":"Earlier keymaster would use the override flag for such a case. But we removed that in this review - https://review.openstack.org/#/c/318148/\n\nI think it\u0027d be good foolproof the CRYPTO_KEY_CALLBACK now.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"5665b457674e958b8588d01631bf31ab77f9b68a","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_dd7c9374","line":172,"in_reply_to":"3aaa91ec_7d02bf0a","updated":"2016-06-29 00:54:54.000000000","message":"Yeah, maybe it should raise an encryption exception and let the encryper/decrypter deal with whether this is actaully a server error or not, seeing as they know more about the current state.\n\nAnd the try catch below.. but sure, happy for that to be cleaned up as a follow up.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_62e69eb5","line":172,"in_reply_to":"3aaa91ec_b79c465e","updated":"2016-06-29 05:10:17.000000000","message":"Some other ideas:\n\n- Require that keymasters always install the callback, but allow it return either usable data or None. If None, neither encrypt nor decrypt.\n- With just the None handling above, do something like we do for swift.authorize:\n\n     env.setdefault(CRYPTO_KEY_CALLBACK, lambda *a, **kw: None)\n\n- Provide an option (allow_no_keymaster?) which has us only do the above when True. Default it to False. Additionally, auto-insert the encrypter/decrypter middleware(s); if auto-inserted, default allow_no_keymaster (and maybe also disable_encryption?) to True.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"fd8a248918e2f3c54aa1cc23752b56a8afb48787","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_7d02bf0a","line":172,"in_reply_to":"3aaa91ec_b79c465e","updated":"2016-06-29 00:46:06.000000000","message":"but, this is a relatively minor change that could come in a follow-up later","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fcb0b5123d851a947e67203d93409dba485ddd05","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        except KeyError:"},{"line_number":170,"context_line":"            self.logger.exception(_(\u0027ERROR get_keys() missing callback\u0027))"},{"line_number":171,"context_line":"            raise HTTPInternalServerError("},{"line_number":172,"context_line":"                \"Unable to retrieve encryption keys.\")"},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"        try:"},{"line_number":175,"context_line":"            keys \u003d fetch_crypto_keys()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_62e310da","line":172,"in_reply_to":"3aaa91ec_d6d294ff","updated":"2016-06-29 17:32:18.000000000","message":"\u003e we remove the ability for the keymaster to set that before the decrypter might use the callback\n\nNot entirely. It just can\u0027t do it based on the data in the response. It can still do it based on auth info or the path (or some combination of the two).\n\nAgreed on the need to think more about the callback interface. Maybe for (a) raise error (which may be caught and translated to a (b), for example if we auto-inserted encryption into the pipeline), for (b) return None, and for (c) return a dict like we do now? We can hash it out on master.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    crypto_meta \u003d None"},{"line_number":280,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":281,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":282,"context_line":"    parts \u003d value.split(\u0027;\u0027)"},{"line_number":283,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":284,"context_line":"        value, param \u003d parts"},{"line_number":285,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_f1725ee2","line":282,"updated":"2016-06-29 05:10:17.000000000","message":"I hadn\u0027t actually meant to imply that anything needed to change here :-)\n\nThis is one of those situations where there\u0027s like a half-dozen different ways to express the same basic thing -- these are all essentially the same given the constraints:\n\n parts \u003d value.split(\u0027;\u0027)\n parts \u003d value.rsplit(\u0027;\u0027, 1)\n value, _junk, params \u003d value.partition(\u0027;\u0027)\n\nand I don\u0027t think there\u0027s any sort of consensus on what would be preferred where, when, or why.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":279,"context_line":"    crypto_meta \u003d None"},{"line_number":280,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":281,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":282,"context_line":"    parts \u003d value.split(\u0027;\u0027)"},{"line_number":283,"context_line":"    if len(parts) \u003d\u003d 2:"},{"line_number":284,"context_line":"        value, param \u003d parts"},{"line_number":285,"context_line":"        crypto_meta_tag \u003d \u0027swift_meta\u003d\u0027"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_5696a4f0","line":282,"in_reply_to":"3aaa91ec_f1725ee2","updated":"2016-06-29 17:06:47.000000000","message":"OK, as you can see I have become somewhat robotic - your wish (or even not) is my command ;)","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import collections"},{"line_number":18,"context_line":"import json"},{"line_number":19,"context_line":"import os"},{"line_number":20,"context_line":"import urllib"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_49c8ad55","line":20,"range":{"start_line":20,"start_character":7,"end_line":20,"end_character":13},"updated":"2016-06-30 07:28:43.000000000","message":"Since we\u0027re already importing six, should we do\n\n from six.moves.urllib import parse as urlparse\n\n...and use that to get to quote_plus/unquote_plus?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import collections"},{"line_number":18,"context_line":"import json"},{"line_number":19,"context_line":"import os"},{"line_number":20,"context_line":"import urllib"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_aed2d3ce","line":20,"in_reply_to":"3aaa91ec_0ccea82c","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import collections"},{"line_number":18,"context_line":"import json"},{"line_number":19,"context_line":"import os"},{"line_number":20,"context_line":"import urllib"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_580b4724","line":20,"range":{"start_line":20,"start_character":7,"end_line":20,"end_character":13},"in_reply_to":"3aaa91ec_49c8ad55","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"966c23e0592f6cb1c2de67dbc0e2041d1a109565","unresolved":false,"context_lines":[{"line_number":17,"context_line":"import collections"},{"line_number":18,"context_line":"import json"},{"line_number":19,"context_line":"import os"},{"line_number":20,"context_line":"import urllib"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from cryptography.hazmat.backends import default_backend"},{"line_number":23,"context_line":"from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_0ccea82c","line":20,"in_reply_to":"3aaa91ec_49c8ad55","updated":"2016-06-30 08:56:12.000000000","message":"Good idea, might be end up in a follow up patch though?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"966c23e0592f6cb1c2de67dbc0e2041d1a109565","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    cipher \u003d \u0027AES_CTR_256\u0027"},{"line_number":42,"context_line":"    # AES will accept several key sizes - we are using 256 bits i.e. 32 bytes"},{"line_number":43,"context_line":"    key_length \u003d 32"},{"line_number":44,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":47,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_ec6ebcfe","line":44,"updated":"2016-06-30 08:56:12.000000000","message":"nit: this could be explicit as well, ie 16?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    cipher \u003d \u0027AES_CTR_256\u0027"},{"line_number":42,"context_line":"    # AES will accept several key sizes - we are using 256 bits i.e. 32 bytes"},{"line_number":43,"context_line":"    key_length \u003d 32"},{"line_number":44,"context_line":"    iv_length \u003d algorithms.AES.block_size / 8"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":47,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_4e57ef25","line":44,"in_reply_to":"3aaa91ec_ec6ebcfe","updated":"2016-06-30 16:40:17.000000000","message":"IDK. I think this is ok, the key length is one of several options, here we just want to derive a value from the lib, but that said, it won\u0027t ever change. We do the divide once per lifetime of the middleware so no great cost ;)","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"966c23e0592f6cb1c2de67dbc0e2041d1a109565","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":47,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"},{"line_number":48,"context_line":"        # memoize backend to avoid repeated iteration over entry points"},{"line_number":49,"context_line":"        self.backend \u003d default_backend()"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def create_encryption_ctxt(self, key, iv):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_6c7becbe","line":48,"updated":"2016-06-30 08:56:12.000000000","message":"nit: memorize","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"54f124d55818e37b1d4811e6060b1fdc8ae6448f","unresolved":false,"context_lines":[{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def __init__(self, conf\u003dNone):"},{"line_number":47,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"crypto\")"},{"line_number":48,"context_line":"        # memoize backend to avoid repeated iteration over entry points"},{"line_number":49,"context_line":"        self.backend \u003d default_backend()"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def create_encryption_ctxt(self, key, iv):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_fdfbf3be","line":48,"in_reply_to":"3aaa91ec_6c7becbe","updated":"2016-06-30 14:14:46.000000000","message":"it\u0027s meaning here is like https://en.wikipedia.org/wiki/Memoization.  The comment is explaining why we save backend as an attribute.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        self.check_key(key)"},{"line_number":61,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":62,"context_line":"                        backend\u003dself.backend)"},{"line_number":63,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":64,"context_line":"        return enc"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_decryption_ctxt(self, key, iv, offset):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_4e7c3ab5","line":63,"updated":"2016-06-30 07:28:43.000000000","message":"nit: could just return","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        self.check_key(key)"},{"line_number":61,"context_line":"        engine \u003d Cipher(algorithms.AES(key), modes.CTR(iv),"},{"line_number":62,"context_line":"                        backend\u003dself.backend)"},{"line_number":63,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":64,"context_line":"        return enc"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_decryption_ctxt(self, key, iv, offset):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_d8457743","line":63,"in_reply_to":"3aaa91ec_4e7c3ab5","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":64,"context_line":"        return enc"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_decryption_ctxt(self, key, iv, offset):"},{"line_number":67,"context_line":"        \"\"\""},{"line_number":68,"context_line":"        Creates a crypto context for decrypting"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1df6d88e","line":66,"range":{"start_line":66,"start_character":46,"end_line":66,"end_character":52},"updated":"2016-06-30 07:28:43.000000000","message":"Should this default to 0? Or do we prefer that callers be explicit?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":64,"context_line":"        return enc"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_decryption_ctxt(self, key, iv, offset):"},{"line_number":67,"context_line":"        \"\"\""},{"line_number":68,"context_line":"        Creates a crypto context for decrypting"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_98948f8b","line":66,"range":{"start_line":66,"start_character":46,"end_line":66,"end_character":52},"in_reply_to":"3aaa91ec_1df6d88e","updated":"2016-06-30 16:40:17.000000000","message":"2/3 call sites use offset. Leaving for now.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"54f124d55818e37b1d4811e6060b1fdc8ae6448f","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        enc \u003d engine.encryptor()"},{"line_number":64,"context_line":"        return enc"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def create_decryption_ctxt(self, key, iv, offset):"},{"line_number":67,"context_line":"        \"\"\""},{"line_number":68,"context_line":"        Creates a crypto context for decrypting"},{"line_number":69,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3df0dbc8","line":66,"range":{"start_line":66,"start_character":46,"end_line":66,"end_character":52},"in_reply_to":"3aaa91ec_1df6d88e","updated":"2016-06-30 14:14:46.000000000","message":"default of 0 sounds good to me.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return dec"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def _get_random_iv(self):"},{"line_number":98,"context_line":"        # this method is separated out here so that tests can mock it"},{"line_number":99,"context_line":"        return os.urandom(self.iv_length)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def create_iv(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_a02cc6ac","line":98,"updated":"2016-06-30 07:28:43.000000000","message":"Can these tests now just mock out create_iv?\n\nI suppose I should have investigated that when I was ripping out the derived-IV code.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return dec"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def _get_random_iv(self):"},{"line_number":98,"context_line":"        # this method is separated out here so that tests can mock it"},{"line_number":99,"context_line":"        return os.urandom(self.iv_length)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def create_iv(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_58cce7ba","line":98,"in_reply_to":"3aaa91ec_a02cc6ac","updated":"2016-06-30 16:40:17.000000000","message":"yes, this has become redundant","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        # create a set of parameters"},{"line_number":106,"context_line":"        return {\u0027iv\u0027: self.create_iv(), \u0027cipher\u0027: self.cipher}"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    def check_crypto_meta(self, meta):"},{"line_number":109,"context_line":"        \"\"\""},{"line_number":110,"context_line":"        Check that crypto meta dict has valid items."},{"line_number":111,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_06a7b20b","line":108,"updated":"2016-06-30 07:28:43.000000000","message":"Should this take an expect_body_key arg (defaulted to False) so we can do all our checking in one place? It should remove the need for some of the error handling in BaseDecrypterContext.get_unwrapped_key -- I think to the point that it\u0027d make sense to let callers just call self.crypto.unwrap_key() themselves.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        # create a set of parameters"},{"line_number":106,"context_line":"        return {\u0027iv\u0027: self.create_iv(), \u0027cipher\u0027: self.cipher}"},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    def check_crypto_meta(self, meta):"},{"line_number":109,"context_line":"        \"\"\""},{"line_number":110,"context_line":"        Check that crypto meta dict has valid items."},{"line_number":111,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5b434113","line":108,"in_reply_to":"3aaa91ec_06a7b20b","updated":"2016-06-30 16:40:17.000000000","message":"I\u0027d like to revisit this checking because I\u0027d like to not store cipher with every piece of user metadata. So changing to either a parameterised method or separate methods for each context makes sense. But that could IMO happen on master.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            if len(meta[\u0027iv\u0027]) !\u003d self.iv_length:"},{"line_number":120,"context_line":"                raise EncryptionException("},{"line_number":121,"context_line":"                    \u0027Bad crypto meta: IV must be length %s bytes\u0027"},{"line_number":122,"context_line":"                    % self.iv_length)"},{"line_number":123,"context_line":"        except KeyError as err:"},{"line_number":124,"context_line":"            raise EncryptionException("},{"line_number":125,"context_line":"                \u0027Bad crypto meta: Missing %s\u0027 % err)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_235580c1","line":122,"updated":"2016-06-30 07:28:43.000000000","message":"Should we also check that there exists *some* key_id? We can\u0027t validate that it\u0027s a version we know how to handle (keymaster is responsible for that), but we could at least see that it exists.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":119,"context_line":"            if len(meta[\u0027iv\u0027]) !\u003d self.iv_length:"},{"line_number":120,"context_line":"                raise EncryptionException("},{"line_number":121,"context_line":"                    \u0027Bad crypto meta: IV must be length %s bytes\u0027"},{"line_number":122,"context_line":"                    % self.iv_length)"},{"line_number":123,"context_line":"        except KeyError as err:"},{"line_number":124,"context_line":"            raise EncryptionException("},{"line_number":125,"context_line":"                \u0027Bad crypto meta: Missing %s\u0027 % err)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1831bf5a","line":122,"in_reply_to":"3aaa91ec_235580c1","updated":"2016-06-30 16:40:17.000000000","message":"key_id is not included in every crypto_meta (i.e. not in every encrypted user metadata crypto-meta) so that again require some parameterisation of the method.\n\nAlso, strictly, key_id has nothing to do with the \"crypto\" aspects, so should arguably be checked elsewhere. Maybe.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":122,"context_line":"                    % self.iv_length)"},{"line_number":123,"context_line":"        except KeyError as err:"},{"line_number":124,"context_line":"            raise EncryptionException("},{"line_number":125,"context_line":"                \u0027Bad crypto meta: Missing %s\u0027 % err)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def create_random_key(self):"},{"line_number":128,"context_line":"        # helper method to create random key of correct length"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e926b9b8","line":125,"updated":"2016-06-30 07:28:43.000000000","message":"I\u0027m a bit nervous that there\u0027s no way for us to quarantine an object that triggers EncryptionExceptions...","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":122,"context_line":"                    % self.iv_length)"},{"line_number":123,"context_line":"        except KeyError as err:"},{"line_number":124,"context_line":"            raise EncryptionException("},{"line_number":125,"context_line":"                \u0027Bad crypto meta: Missing %s\u0027 % err)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def create_random_key(self):"},{"line_number":128,"context_line":"        # helper method to create random key of correct length"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9ba12997","line":125,"in_reply_to":"3aaa91ec_e926b9b8","updated":"2016-06-30 16:40:17.000000000","message":"hmmm, makes me think of similar existing gotcha\u0027s :/ Such as x-object-sysmeta-ec-etag getting corrupted, or the -frag-index. We don\u0027t have any checksums on metadata that is critical for recovering or being able to validate data.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"54f124d55818e37b1d4811e6060b1fdc8ae6448f","unresolved":false,"context_lines":[{"line_number":122,"context_line":"                    % self.iv_length)"},{"line_number":123,"context_line":"        except KeyError as err:"},{"line_number":124,"context_line":"            raise EncryptionException("},{"line_number":125,"context_line":"                \u0027Bad crypto meta: Missing %s\u0027 % err)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def create_random_key(self):"},{"line_number":128,"context_line":"        # helper method to create random key of correct length"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5d17a7a2","line":125,"in_reply_to":"3aaa91ec_e926b9b8","updated":"2016-06-30 14:14:46.000000000","message":"interesting point.  just another challenge of making encryption a plug-in feature.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    def wrap_key(self, wrapping_key, key_to_wrap):"},{"line_number":132,"context_line":"        # we don\u0027t use an RFC 3394 key wrap algorithm such as cryptography\u0027s"},{"line_number":133,"context_line":"        # aes_wrap_key because it\u0027s slower and we have iv material readily"},{"line_number":134,"context_line":"        # available so don\u0027t need a deterministic algorithm"},{"line_number":135,"context_line":"        iv \u003d self._get_random_iv()"},{"line_number":136,"context_line":"        encryptor \u003d Cipher(algorithms.AES(wrapping_key), modes.CTR(iv),"},{"line_number":137,"context_line":"                           backend\u003dself.backend).encryptor()"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_8629e29d","line":134,"updated":"2016-06-30 07:28:43.000000000","message":"What does determinism have to do with things? I thought RFC 3394 was useful more for its integrity-check properties.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"d851cc3fe809c9f6d6d331e16e08949e94c18379","unresolved":false,"context_lines":[{"line_number":131,"context_line":"    def wrap_key(self, wrapping_key, key_to_wrap):"},{"line_number":132,"context_line":"        # we don\u0027t use an RFC 3394 key wrap algorithm such as cryptography\u0027s"},{"line_number":133,"context_line":"        # aes_wrap_key because it\u0027s slower and we have iv material readily"},{"line_number":134,"context_line":"        # available so don\u0027t need a deterministic algorithm"},{"line_number":135,"context_line":"        iv \u003d self._get_random_iv()"},{"line_number":136,"context_line":"        encryptor \u003d Cipher(algorithms.AES(wrapping_key), modes.CTR(iv),"},{"line_number":137,"context_line":"                           backend\u003dself.backend).encryptor()"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_b27d2a1e","line":134,"in_reply_to":"3aaa91ec_8629e29d","updated":"2016-06-30 08:23:25.000000000","message":"NIST\u0027s AES Key Wrap (also in that RFC) provides authenticity, yes, but it is also deterministic and might leak equality of keys. Being a deterministic encryption scheme is a limitation in that sense. \n\nThe overall approach here is to not make authenticity checks at all, consequently also here. Then, using CTR mode as for the rest is simpler.\n\nSee this here about NIST\u0027s Key Wrap:\nhttp://web.cs.ucdavis.edu/~rogaway/papers/keywrap.pdf","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":277,"context_line":"            (\u003cvalue without crypto meta\u003e, \u003cdeserialized crypto meta\u003e or None)"},{"line_number":278,"context_line":"    \"\"\""},{"line_number":279,"context_line":"    crypto_meta \u003d None"},{"line_number":280,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":281,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":282,"context_line":"    parts \u003d value.split(\u0027;\u0027)"},{"line_number":283,"context_line":"    if len(parts) \u003d\u003d 2:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_0a3850ed","line":280,"range":{"start_line":280,"start_character":28,"end_line":280,"end_character":39},"updated":"2016-06-30 07:28:43.000000000","message":"etag or crypto transient-sysmeta values, now.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":277,"context_line":"            (\u003cvalue without crypto meta\u003e, \u003cdeserialized crypto meta\u003e or None)"},{"line_number":278,"context_line":"    \"\"\""},{"line_number":279,"context_line":"    crypto_meta \u003d None"},{"line_number":280,"context_line":"    # we only use this with etag values so it\u0027s safe to split on \u0027;\u0027 even if"},{"line_number":281,"context_line":"    # it turns out that the value was not encrypted"},{"line_number":282,"context_line":"    parts \u003d value.split(\u0027;\u0027)"},{"line_number":283,"context_line":"    if len(parts) \u003d\u003d 2:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5b14e14b","line":280,"range":{"start_line":280,"start_character":28,"end_line":280,"end_character":39},"in_reply_to":"3aaa91ec_0a3850ed","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":292,"context_line":"def is_crypto_meta(header, server_type):"},{"line_number":293,"context_line":"    return (strip_sys_meta_prefix("},{"line_number":294,"context_line":"        server_type, header.lower()).startswith(\u0027crypto-meta\u0027) or"},{"line_number":295,"context_line":"        strip_object_transient_sysmeta_prefix("},{"line_number":296,"context_line":"        header.lower()).startswith(\u0027crypto-meta\u0027))"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_090ea58b","line":295,"range":{"start_line":295,"start_character":8,"end_line":295,"end_character":45},"updated":"2016-06-30 07:28:43.000000000","message":"This doesn\u0027t (yet) check for is_object_transient_sysmeta, though, right? So something like X-Object-Meta-blahblahblah-Crypto-Meta returns True. There are similar troubles with strip_sys_meta_prefix and X-Object-Meta-zz-Crypto-Meta.\n\nAlso, if server_type \u003d\u003d \u0027container\u0027, we shouldn\u0027t still check strip_object_transient_sysmeta_prefix.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":292,"context_line":"def is_crypto_meta(header, server_type):"},{"line_number":293,"context_line":"    return (strip_sys_meta_prefix("},{"line_number":294,"context_line":"        server_type, header.lower()).startswith(\u0027crypto-meta\u0027) or"},{"line_number":295,"context_line":"        strip_object_transient_sysmeta_prefix("},{"line_number":296,"context_line":"        header.lower()).startswith(\u0027crypto-meta\u0027))"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_8666f0ea","line":295,"range":{"start_line":295,"start_character":8,"end_line":295,"end_character":45},"in_reply_to":"3aaa91ec_090ea58b","updated":"2016-06-30 16:40:17.000000000","message":"Function is not used","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b8d2bd3f5f443ecb4ea87708948568d9746c895b","unresolved":false,"context_lines":[{"line_number":235,"context_line":"        return {"},{"line_number":236,"context_line":"            str(name): (base64.b64decode(val) if name in (\u0027iv\u0027, \u0027key\u0027)"},{"line_number":237,"context_line":"                        else b64_decode_meta(val) if isinstance(val, dict)"},{"line_number":238,"context_line":"                        else val.encode(\u0027utf8\u0027))"},{"line_number":239,"context_line":"            for name, val in crypto_meta.items()}"},{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_405cd318","line":238,"range":{"start_line":238,"start_character":30,"end_line":238,"end_character":47},"updated":"2016-06-30 16:49:08.000000000","message":"I needed to make this change when I changed the keymaster to not base64 encode the path it put into the key_id meta.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"}],"swift/common/middleware/decrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"925e7bbcf835264f479d0c029a4e76241d9fe2f4","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                return None"},{"line_number":172,"context_line":"        except EncryptionException as e:"},{"line_number":173,"context_line":"            msg \u003d \"Error decrypting header\""},{"line_number":174,"context_line":"            self.logger.error(\"%s %s: %s\", msg, header, e)"},{"line_number":175,"context_line":"            raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def decrypt_user_metadata(self, keys):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_023710e4","line":174,"range":{"start_line":174,"start_character":48,"end_line":174,"end_character":54},"updated":"2016-06-28 07:00:46.000000000","message":"So the only reason we pass in header is for a log message if something goes wrong? And to the extent that the problem can be fixed, that fix will almost certainly need to be in `crypto_meta_header` rather than `header`?\n\nI\u0027m not sure it\u0027s bad, but it feels weird.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":171,"context_line":"                return None"},{"line_number":172,"context_line":"        except EncryptionException as e:"},{"line_number":173,"context_line":"            msg \u003d \"Error decrypting header\""},{"line_number":174,"context_line":"            self.logger.error(\"%s %s: %s\", msg, header, e)"},{"line_number":175,"context_line":"            raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    def decrypt_user_metadata(self, keys):"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_bfe0b897","line":174,"range":{"start_line":174,"start_character":48,"end_line":174,"end_character":54},"in_reply_to":"3aaa91ec_023710e4","updated":"2016-06-28 16:23:06.000000000","message":"Ack. I have a feeling this companion header pattern may go away. With the other changes in flight (to user meta handling and the etag hmac) we can append crypto meta to every encrypted header. Currently the (now) anomalous case is the ETag.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7faa00f7afe580951206819df4f12e908e28acbb","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"        if is_success(self._get_status_int()):"},{"line_number":356,"context_line":"            # only decrypt body of 2xx responses"},{"line_number":357,"context_line":"            keys \u003d self.process_resp(req)"},{"line_number":358,"context_line":"            if keys:"},{"line_number":359,"context_line":"                key \u003d keys[\u0027container\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_e843c56a","line":356,"updated":"2016-06-28 07:52:02.000000000","message":"Correct me if I\u0027m wrong, but object names aren\u0027t encrypted in the container database.. if that\u0027s so, would it make sense to shortcircuit the response if listing_content_type is text? We don\u0027t know how long a future keymaster might take, so adding any possible speeds up the better. (ie we don\u0027t need to search for keys if we don\u0027t need em)","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        app_resp \u003d self._app_call(req.environ)"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"        if is_success(self._get_status_int()):"},{"line_number":356,"context_line":"            # only decrypt body of 2xx responses"},{"line_number":357,"context_line":"            keys \u003d self.process_resp(req)"},{"line_number":358,"context_line":"            if keys:"},{"line_number":359,"context_line":"                key \u003d keys[\u0027container\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_da76723d","line":356,"in_reply_to":"3aaa91ec_e843c56a","updated":"2016-06-28 16:23:06.000000000","message":"You are correct. Good suggestion.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            key, crypto_meta[\u0027iv\u0027], 0)"},{"line_number":123,"context_line":"        return crypto_ctxt.update(base64.b64decode(value))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def process_resp(self, req):"},{"line_number":126,"context_line":"        \"\"\""},{"line_number":127,"context_line":"        Determine if a response should be decrypted, and if so then fetch keys."},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_bc5a6d28","line":125,"updated":"2016-06-29 05:10:17.000000000","message":"I feel like this should have a different name; something to better separate it from DecrypterContContext.process_json_resp and DecrypterContContext.process_xml_resp.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            key, crypto_meta[\u0027iv\u0027], 0)"},{"line_number":123,"context_line":"        return crypto_ctxt.update(base64.b64decode(value))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def process_resp(self, req):"},{"line_number":126,"context_line":"        \"\"\""},{"line_number":127,"context_line":"        Determine if a response should be decrypted, and if so then fetch keys."},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_31532219","line":125,"in_reply_to":"3aaa91ec_bc5a6d28","updated":"2016-06-29 17:06:47.000000000","message":"Yeah, its kind of non-descriptive\n\nI\u0027ll try get_decryption_keys() as an alternative","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":207,"context_line":"            try:"},{"line_number":208,"context_line":"                mod_hdr_pairs.append((\u0027Etag\u0027, self.decrypt_value_with_meta("},{"line_number":209,"context_line":"                    encrypted_etag, keys[\u0027object\u0027], required\u003dTrue)))"},{"line_number":210,"context_line":"            except EncryptionException as e:"},{"line_number":211,"context_line":"                msg \u003d \"Error decrypting header\""},{"line_number":212,"context_line":"                self.logger.error(\"%s %s: %s\", msg, etag_header, e)"},{"line_number":213,"context_line":"                raise HTTPInternalServerError(body\u003dmsg,"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_3102260c","line":210,"updated":"2016-06-29 05:10:17.000000000","message":"Note that there may be a better way to do this. I\u0027d just cribbed from _decrypt_header because a test was failing and it was getting late.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":207,"context_line":"            try:"},{"line_number":208,"context_line":"                mod_hdr_pairs.append((\u0027Etag\u0027, self.decrypt_value_with_meta("},{"line_number":209,"context_line":"                    encrypted_etag, keys[\u0027object\u0027], required\u003dTrue)))"},{"line_number":210,"context_line":"            except EncryptionException as e:"},{"line_number":211,"context_line":"                msg \u003d \"Error decrypting header\""},{"line_number":212,"context_line":"                self.logger.error(\"%s %s: %s\", msg, etag_header, e)"},{"line_number":213,"context_line":"                raise HTTPInternalServerError(body\u003dmsg,"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_a6c7d796","line":210,"in_reply_to":"3aaa91ec_3102260c","updated":"2016-06-29 17:06:47.000000000","message":"Turns out _decrypt_header is no longer used, so I am going to repurpose that and use it here (and also to handle \u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027 below which is not currently in a try/except)","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":18,"context_line":"try:"},{"line_number":19,"context_line":"    import xml.etree.cElementTree as ElementTree"},{"line_number":20,"context_line":"except ImportError:"},{"line_number":21,"context_line":"    import xml.etree.ElementTree as ElementTree"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from swift.common.http import is_success"},{"line_number":24,"context_line":"from swift.common.middleware.crypto_utils import CryptoWSGIContext, \\"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_4ad25801","line":21,"updated":"2016-06-30 07:28:43.000000000","message":"Would we ever hit this path? Similar code in the contain server -- https://github.com/openstack/swift/blob/2.8.0/swift/container/server.py#L21 -- doesn\u0027t have this guard.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":18,"context_line":"try:"},{"line_number":19,"context_line":"    import xml.etree.cElementTree as ElementTree"},{"line_number":20,"context_line":"except ImportError:"},{"line_number":21,"context_line":"    import xml.etree.ElementTree as ElementTree"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from swift.common.http import is_success"},{"line_number":24,"context_line":"from swift.common.middleware.crypto_utils import CryptoWSGIContext, \\"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_8693905a","line":21,"in_reply_to":"3aaa91ec_4ad25801","updated":"2016-06-30 16:40:17.000000000","message":"Hmmm, it does seem to have been available since py2.5\n\nhttp://effbot.org/zone/celementtree.htm","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":31,"context_line":"    parse_content_range, closing_if_possible, parse_content_type, \\"},{"line_number":32,"context_line":"    FileLikeIter, multipart_byteranges_to_document_iters"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"DECRYPT_CHUNK_SIZE \u003d 65536"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"def purge_crypto_sysmeta_headers(headers):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_ead224d0","line":34,"updated":"2016-06-30 07:28:43.000000000","message":"I think I get why we need (or at any rate, will use) this. But I still find it odd that we get an iterator out of the app, turn it into a file-like, then read() from it in chunks to get it back to an iterator. Que sera sera.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class BaseDecrypterContext(CryptoWSGIContext):"},{"line_number":45,"context_line":"    def __init__(self, decrypter, server_type, logger):"},{"line_number":46,"context_line":"        super(BaseDecrypterContext, self).__init__("},{"line_number":47,"context_line":"            decrypter, server_type, logger)"},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_aac13ce6","line":45,"updated":"2016-06-30 07:28:43.000000000","message":"Do we actually need this? Won\u0027t the MRO take care of this for us?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class BaseDecrypterContext(CryptoWSGIContext):"},{"line_number":45,"context_line":"    def __init__(self, decrypter, server_type, logger):"},{"line_number":46,"context_line":"        super(BaseDecrypterContext, self).__init__("},{"line_number":47,"context_line":"            decrypter, server_type, logger)"},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_6632e45f","line":45,"in_reply_to":"3aaa91ec_aac13ce6","updated":"2016-06-30 16:40:17.000000000","message":"Done. I guess at one point there was some customisation here","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.logger.error(\u0027%s: %s\u0027, msg, err)"},{"line_number":86,"context_line":"        raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def decrypt_value_with_meta(self, value, key, required\u003dFalse):"},{"line_number":89,"context_line":"        \"\"\""},{"line_number":90,"context_line":"        Decrypt a value if suitable crypto_meta can be extracted from the"},{"line_number":91,"context_line":"        value itself."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_fde30cd6","line":88,"range":{"start_line":88,"start_character":59,"end_line":88,"end_character":64},"updated":"2016-06-30 07:28:43.000000000","message":"I know I\u0027d added this, but that was before moving all user meta to transient sysmeta. Now, I think we require meta (or should) a lot more than we don\u0027t. The only time we don\u0027t require it now is for container listings, right? Should we change the default to be True?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        self.logger.error(\u0027%s: %s\u0027, msg, err)"},{"line_number":86,"context_line":"        raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def decrypt_value_with_meta(self, value, key, required\u003dFalse):"},{"line_number":89,"context_line":"        \"\"\""},{"line_number":90,"context_line":"        Decrypt a value if suitable crypto_meta can be extracted from the"},{"line_number":91,"context_line":"        value itself."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_c1c2a252","line":88,"range":{"start_line":88,"start_character":59,"end_line":88,"end_character":64},"in_reply_to":"3aaa91ec_fde30cd6","updated":"2016-06-30 16:40:17.000000000","message":"also False for and override-etag. I\u0027m inclined to leave it as it is.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":88,"context_line":"    def decrypt_value_with_meta(self, value, key, required\u003dFalse):"},{"line_number":89,"context_line":"        \"\"\""},{"line_number":90,"context_line":"        Decrypt a value if suitable crypto_meta can be extracted from the"},{"line_number":91,"context_line":"        value itself."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        :param value: value to decrypt"},{"line_number":94,"context_line":"        :param key: crypto key to use"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5deb40dc","line":91,"updated":"2016-06-30 07:28:43.000000000","message":"This docstring implies that this test [1] should pass. Should we clarify that this should only receive values that have no parameters or a single swift_meta parameter? We currently satisfy that condition (and moving everything to transient sysmeta helps, I think), but for the sake of future-us we may want to be explicit in our assumptions.\n\n[1] http://paste.openstack.org/show/524169/","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":88,"context_line":"    def decrypt_value_with_meta(self, value, key, required\u003dFalse):"},{"line_number":89,"context_line":"        \"\"\""},{"line_number":90,"context_line":"        Decrypt a value if suitable crypto_meta can be extracted from the"},{"line_number":91,"context_line":"        value itself."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        :param value: value to decrypt"},{"line_number":94,"context_line":"        :param key: crypto key to use"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_ec0075ad","line":91,"in_reply_to":"3aaa91ec_5deb40dc","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"7540eddcb070f22cb1ecc95b33c57e0b305a7059","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        value itself."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        :param value: value to decrypt"},{"line_number":94,"context_line":"        :param key: crypto key to use"},{"line_number":95,"context_line":"        :returns: decrypted value if valid crypto_meta is found, otherwise the"},{"line_number":96,"context_line":"            unmodified value"},{"line_number":97,"context_line":"        :raises EncryptionException: if an error occurs while parsing"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9e2e2c8a","line":94,"updated":"2016-06-30 13:41:40.000000000","message":"nit: add \"required\" param desc?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        value itself."},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"        :param value: value to decrypt"},{"line_number":94,"context_line":"        :param key: crypto key to use"},{"line_number":95,"context_line":"        :returns: decrypted value if valid crypto_meta is found, otherwise the"},{"line_number":96,"context_line":"            unmodified value"},{"line_number":97,"context_line":"        :raises EncryptionException: if an error occurs while parsing"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_491c096a","line":94,"in_reply_to":"3aaa91ec_9e2e2c8a","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        \"\"\""},{"line_number":111,"context_line":"        Decrypt a value using the crypto_meta provided."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        :param value: value to decrypt"},{"line_number":114,"context_line":"        :param key: crypto key to use"},{"line_number":115,"context_line":"        :param crypto_meta: a crypto-meta dict of form returned by"},{"line_number":116,"context_line":"            :py:func:`~swift.common.middleware.crypto.Crypto.get_crypto_meta`"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3d40f4a4","line":113,"updated":"2016-06-30 07:28:43.000000000","message":"Should we mention the fact that it should be base64-encoded?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        \"\"\""},{"line_number":111,"context_line":"        Decrypt a value using the crypto_meta provided."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        :param value: value to decrypt"},{"line_number":114,"context_line":"        :param key: crypto key to use"},{"line_number":115,"context_line":"        :param crypto_meta: a crypto-meta dict of form returned by"},{"line_number":116,"context_line":"            :py:func:`~swift.common.middleware.crypto.Crypto.get_crypto_meta`"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_2c2d5d46","line":113,"in_reply_to":"3aaa91ec_3d40f4a4","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        try:"},{"line_number":160,"context_line":"            return self.decrypt_value_with_meta(value, key, required)"},{"line_number":161,"context_line":"        except EncryptionException as e:"},{"line_number":162,"context_line":"            msg \u003d \"Error decrypting header\""},{"line_number":163,"context_line":"            self.logger.error(\"%s %s: %s\", msg, header, e)"},{"line_number":164,"context_line":"            raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3d6e342f","line":162,"updated":"2016-06-30 07:28:43.000000000","message":"crypto_utils marks log messages for translation, but neither this module nor encrypter does. Intentional?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        try:"},{"line_number":160,"context_line":"            return self.decrypt_value_with_meta(value, key, required)"},{"line_number":161,"context_line":"        except EncryptionException as e:"},{"line_number":162,"context_line":"            msg \u003d \"Error decrypting header\""},{"line_number":163,"context_line":"            self.logger.error(\"%s %s: %s\", msg, header, e)"},{"line_number":164,"context_line":"            raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":165,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e71a4e6e","line":162,"in_reply_to":"3aaa91ec_3d6e342f","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":172,"context_line":"            if name.lower().startswith(prefix) and val:"},{"line_number":173,"context_line":"                short_name \u003d name[prefix_len:]"},{"line_number":174,"context_line":"                decrypted_value \u003d self._decrypt_header("},{"line_number":175,"context_line":"                    name, val, keys[self.server_type])"},{"line_number":176,"context_line":"                result.append((new_prefix + short_name, decrypted_value))"},{"line_number":177,"context_line":"        return result"},{"line_number":178,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_80737f4d","line":175,"updated":"2016-06-30 07:28:43.000000000","message":"Should this include required\u003dTrue?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":172,"context_line":"            if name.lower().startswith(prefix) and val:"},{"line_number":173,"context_line":"                short_name \u003d name[prefix_len:]"},{"line_number":174,"context_line":"                decrypted_value \u003d self._decrypt_header("},{"line_number":175,"context_line":"                    name, val, keys[self.server_type])"},{"line_number":176,"context_line":"                result.append((new_prefix + short_name, decrypted_value))"},{"line_number":177,"context_line":"        return result"},{"line_number":178,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_8ce5710a","line":175,"in_reply_to":"3aaa91ec_80737f4d","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        if encrypted_etag:"},{"line_number":202,"context_line":"            decrypted_etag \u003d self._decrypt_header("},{"line_number":203,"context_line":"                etag_header, encrypted_etag, keys[\u0027container\u0027])"},{"line_number":204,"context_line":"            mod_hdr_pairs.append((etag_header, decrypted_etag))"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        # Decrypt all user metadata. Encrypted user metadata values are stored"},{"line_number":207,"context_line":"        # in the x-object-transient-sysmeta-crypt-meta- namespace. Those are"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_fd9b0c15","line":204,"range":{"start_line":204,"start_character":34,"end_line":204,"end_character":45},"updated":"2016-06-30 07:28:43.000000000","message":"I can\u0027t think of why any middleware would ever need this decrypted... eh, better to do it since we can, I suppose.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        if encrypted_etag:"},{"line_number":202,"context_line":"            decrypted_etag \u003d self._decrypt_header("},{"line_number":203,"context_line":"                etag_header, encrypted_etag, keys[\u0027container\u0027])"},{"line_number":204,"context_line":"            mod_hdr_pairs.append((etag_header, decrypted_etag))"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        # Decrypt all user metadata. Encrypted user metadata values are stored"},{"line_number":207,"context_line":"        # in the x-object-transient-sysmeta-crypt-meta- namespace. Those are"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e7bb6e0d","line":204,"range":{"start_line":204,"start_character":34,"end_line":204,"end_character":45},"in_reply_to":"3aaa91ec_fd9b0c15","updated":"2016-06-30 16:40:17.000000000","message":"Isn\u0027t this to allow for case where another middleware set the override etag, we encrypted it and now we need to decrypt it?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"7540eddcb070f22cb1ecc95b33c57e0b305a7059","unresolved":false,"context_lines":[{"line_number":204,"context_line":"            mod_hdr_pairs.append((etag_header, decrypted_etag))"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        # Decrypt all user metadata. Encrypted user metadata values are stored"},{"line_number":207,"context_line":"        # in the x-object-transient-sysmeta-crypt-meta- namespace. Those are"},{"line_number":208,"context_line":"        # decrypted and moved back to the x-object-meta- namespace. Prior to"},{"line_number":209,"context_line":"        # decryption, the response should have no x-object-meta- headers, but"},{"line_number":210,"context_line":"        # if it does then they will be overwritten by any decrypted headers"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1eccfcb9","line":207,"updated":"2016-06-30 13:41:40.000000000","message":"nit: s/crypt/crypto","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":204,"context_line":"            mod_hdr_pairs.append((etag_header, decrypted_etag))"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"        # Decrypt all user metadata. Encrypted user metadata values are stored"},{"line_number":207,"context_line":"        # in the x-object-transient-sysmeta-crypt-meta- namespace. Those are"},{"line_number":208,"context_line":"        # decrypted and moved back to the x-object-meta- namespace. Prior to"},{"line_number":209,"context_line":"        # decryption, the response should have no x-object-meta- headers, but"},{"line_number":210,"context_line":"        # if it does then they will be overwritten by any decrypted headers"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_6952a514","line":207,"in_reply_to":"3aaa91ec_1eccfcb9","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        mod_hdr_pairs.extend(self.decrypt_user_metadata(keys))"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        mod_hdr_names \u003d {h.lower() for h, v in mod_hdr_pairs}"},{"line_number":216,"context_line":"        mod_resp_headers \u003d [(h, v) for h, v in self._response_headers"},{"line_number":217,"context_line":"                            if h.lower() not in mod_hdr_names]"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        mod_resp_headers.extend(mod_hdr_pairs)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1d0a5826","line":216,"range":{"start_line":216,"start_character":8,"end_line":216,"end_character":24},"updated":"2016-06-30 07:28:43.000000000","message":"This seems awfully similar to mod_hdr_pairs. Could we find some way to differentiate the two?\n\nCome to think of it, why do we have them both? How important is it that the decrypted values appear at the end of the list instead of the beginning?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":213,"context_line":"        mod_hdr_pairs.extend(self.decrypt_user_metadata(keys))"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"        mod_hdr_names \u003d {h.lower() for h, v in mod_hdr_pairs}"},{"line_number":216,"context_line":"        mod_resp_headers \u003d [(h, v) for h, v in self._response_headers"},{"line_number":217,"context_line":"                            if h.lower() not in mod_hdr_names]"},{"line_number":218,"context_line":""},{"line_number":219,"context_line":"        mod_resp_headers.extend(mod_hdr_pairs)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e7a7ee4d","line":216,"range":{"start_line":216,"start_character":8,"end_line":216,"end_character":24},"in_reply_to":"3aaa91ec_1d0a5826","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":236,"context_line":"            for first_byte, last_byte, length, headers, body in parts_iter:"},{"line_number":237,"context_line":"                yield \"--\" + boundary + \"\\r\\n\""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"                for header in headers:"},{"line_number":240,"context_line":"                    yield \"%s: %s\\r\\n\" % header"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"                yield \"\\r\\n\""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_4042373f","line":239,"range":{"start_line":239,"start_character":20,"end_line":239,"end_character":26},"updated":"2016-06-30 07:28:43.000000000","message":"nit: header_pair?\n\nI was confused for a bit by the next line.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":236,"context_line":"            for first_byte, last_byte, length, headers, body in parts_iter:"},{"line_number":237,"context_line":"                yield \"--\" + boundary + \"\\r\\n\""},{"line_number":238,"context_line":""},{"line_number":239,"context_line":"                for header in headers:"},{"line_number":240,"context_line":"                    yield \"%s: %s\\r\\n\" % header"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"                yield \"\\r\\n\""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_194ede6e","line":239,"range":{"start_line":239,"start_character":20,"end_line":239,"end_character":26},"in_reply_to":"3aaa91ec_4042373f","updated":"2016-06-30 16:40:17.000000000","message":"ok but don\u0027t now say that headers should be renamed header_pairs ;)","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":245,"context_line":"                    body_key, crypto_meta[\u0027iv\u0027], first_byte)"},{"line_number":246,"context_line":"                for chunk in iter(lambda: body.read(DECRYPT_CHUNK_SIZE), \u0027\u0027):"},{"line_number":247,"context_line":"                    chunk \u003d decrypt_ctxt.update(chunk)"},{"line_number":248,"context_line":"                    yield chunk"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"                yield \"\\r\\n\""},{"line_number":251,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_60b3f34d","line":248,"updated":"2016-06-30 07:28:43.000000000","message":"We could just\n\n yield decrypt_ctxt.update(chunk)\n\nyeah?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":245,"context_line":"                    body_key, crypto_meta[\u0027iv\u0027], first_byte)"},{"line_number":246,"context_line":"                for chunk in iter(lambda: body.read(DECRYPT_CHUNK_SIZE), \u0027\u0027):"},{"line_number":247,"context_line":"                    chunk \u003d decrypt_ctxt.update(chunk)"},{"line_number":248,"context_line":"                    yield chunk"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"                yield \"\\r\\n\""},{"line_number":251,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_67381eef","line":248,"in_reply_to":"3aaa91ec_60b3f34d","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":277,"context_line":"                           self._response_exc_info)"},{"line_number":278,"context_line":"            return app_resp"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        # retrieve content-type before headers are modified"},{"line_number":281,"context_line":"        ct \u003d self._response_header_value(\u0027Content-Type\u0027)"},{"line_number":282,"context_line":"        content_type, content_type_attrs \u003d parse_content_type(ct)"},{"line_number":283,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_60b81312","line":280,"updated":"2016-06-30 07:28:43.000000000","message":"This is... in anticipation of us eventually encrypting content-type?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":277,"context_line":"                           self._response_exc_info)"},{"line_number":278,"context_line":"            return app_resp"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        # retrieve content-type before headers are modified"},{"line_number":281,"context_line":"        ct \u003d self._response_header_value(\u0027Content-Type\u0027)"},{"line_number":282,"context_line":"        content_type, content_type_attrs \u003d parse_content_type(ct)"},{"line_number":283,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_d94bb6af","line":280,"in_reply_to":"3aaa91ec_60b81312","updated":"2016-06-30 16:40:17.000000000","message":"IDK, doesn\u0027t make sense being here even if it is in anticipation since we\u0027d want to decrypt it before parsing it.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"54f124d55818e37b1d4811e6060b1fdc8ae6448f","unresolved":false,"context_lines":[{"line_number":277,"context_line":"                           self._response_exc_info)"},{"line_number":278,"context_line":"            return app_resp"},{"line_number":279,"context_line":""},{"line_number":280,"context_line":"        # retrieve content-type before headers are modified"},{"line_number":281,"context_line":"        ct \u003d self._response_header_value(\u0027Content-Type\u0027)"},{"line_number":282,"context_line":"        content_type, content_type_attrs \u003d parse_content_type(ct)"},{"line_number":283,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e81df30f","line":280,"in_reply_to":"3aaa91ec_60b81312","updated":"2016-06-30 14:14:46.000000000","message":"its probably unintentionally left there from the time when we were working on multi-range get.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":294,"context_line":"                    body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"            if not crypto_meta:"},{"line_number":297,"context_line":"                self.logger.debug(\"No sysmeta-crypto-meta for body.\")"},{"line_number":298,"context_line":"                resp_iter \u003d app_resp"},{"line_number":299,"context_line":"            elif (self._get_status_int() \u003d\u003d 206 and"},{"line_number":300,"context_line":"                  content_type \u003d\u003d \u0027multipart/byteranges\u0027):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_606653bc","line":297,"updated":"2016-06-30 07:28:43.000000000","message":"Should we drop this logging? It seems... verbose, particularly for a pre-existing cluster.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":294,"context_line":"                    body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":295,"context_line":""},{"line_number":296,"context_line":"            if not crypto_meta:"},{"line_number":297,"context_line":"                self.logger.debug(\"No sysmeta-crypto-meta for body.\")"},{"line_number":298,"context_line":"                resp_iter \u003d app_resp"},{"line_number":299,"context_line":"            elif (self._get_status_int() \u003d\u003d 206 and"},{"line_number":300,"context_line":"                  content_type \u003d\u003d \u0027multipart/byteranges\u0027):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_bc45f843","line":297,"in_reply_to":"3aaa91ec_606653bc","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":359,"context_line":"            else:"},{"line_number":360,"context_line":"                handler \u003d keys \u003d None"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"            if handler and keys:"},{"line_number":363,"context_line":"                key \u003d keys[\u0027container\u0027]"},{"line_number":364,"context_line":"                try:"},{"line_number":365,"context_line":"                    app_resp \u003d handler(key, app_resp)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_80eedfea","line":362,"updated":"2016-06-30 07:28:43.000000000","message":"nit: we could just say\n\n if handler:\n\nhere, and call get_decryption_keys below.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":359,"context_line":"            else:"},{"line_number":360,"context_line":"                handler \u003d keys \u003d None"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"            if handler and keys:"},{"line_number":363,"context_line":"                key \u003d keys[\u0027container\u0027]"},{"line_number":364,"context_line":"                try:"},{"line_number":365,"context_line":"                    app_resp \u003d handler(key, app_resp)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9cfabcbb","line":362,"in_reply_to":"3aaa91ec_80eedfea","updated":"2016-06-30 16:40:17.000000000","message":"No. get_decryption_keys may return None, in which case we don\u0027t want to enter this clause.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":360,"context_line":"                handler \u003d keys \u003d None"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"            if handler and keys:"},{"line_number":363,"context_line":"                key \u003d keys[\u0027container\u0027]"},{"line_number":364,"context_line":"                try:"},{"line_number":365,"context_line":"                    app_resp \u003d handler(key, app_resp)"},{"line_number":366,"context_line":"                except EncryptionException as e:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_a0d83b54","line":363,"updated":"2016-06-30 07:28:43.000000000","message":"nit: we could just say\n\n app_resp \u003d handler(keys[\u0027container\u0027], app_resp)\n\nbelow.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":360,"context_line":"                handler \u003d keys \u003d None"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"            if handler and keys:"},{"line_number":363,"context_line":"                key \u003d keys[\u0027container\u0027]"},{"line_number":364,"context_line":"                try:"},{"line_number":365,"context_line":"                    app_resp \u003d handler(key, app_resp)"},{"line_number":366,"context_line":"                except EncryptionException as e:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5cda144c","line":363,"in_reply_to":"3aaa91ec_a0d83b54","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":375,"context_line":""},{"line_number":376,"context_line":"        return app_resp"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def update_content_length(self, new_total_len):"},{"line_number":379,"context_line":"        self._response_headers \u003d ["},{"line_number":380,"context_line":"            (h, v) for h, v in self._response_headers"},{"line_number":381,"context_line":"            if h.lower() !\u003d \u0027content-length\u0027]"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_60993379","line":378,"updated":"2016-06-30 07:28:43.000000000","message":"nit: might be a good candidate for a decorator.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":375,"context_line":""},{"line_number":376,"context_line":"        return app_resp"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def update_content_length(self, new_total_len):"},{"line_number":379,"context_line":"        self._response_headers \u003d ["},{"line_number":380,"context_line":"            (h, v) for h, v in self._response_headers"},{"line_number":381,"context_line":"            if h.lower() !\u003d \u0027content-length\u0027]"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3ca10847","line":378,"in_reply_to":"3aaa91ec_60993379","updated":"2016-06-30 16:40:17.000000000","message":"I generally prefer the explicit call in the method body rather than a decorator that can easily be missed.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":424,"context_line":"    def __init__(self, app, conf):"},{"line_number":425,"context_line":"        self.app \u003d app"},{"line_number":426,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"decrypter\")"},{"line_number":427,"context_line":"        self.conf \u003d conf"},{"line_number":428,"context_line":"        self.crypto \u003d Crypto(self.conf)"},{"line_number":429,"context_line":""},{"line_number":430,"context_line":"    def __call__(self, env, start_response):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_40d23701","line":427,"updated":"2016-06-30 07:28:43.000000000","message":"Does this need to be an attribute? We never seem to use it outside of the constructor.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":424,"context_line":"    def __init__(self, app, conf):"},{"line_number":425,"context_line":"        self.app \u003d app"},{"line_number":426,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"decrypter\")"},{"line_number":427,"context_line":"        self.conf \u003d conf"},{"line_number":428,"context_line":"        self.crypto \u003d Crypto(self.conf)"},{"line_number":429,"context_line":""},{"line_number":430,"context_line":"    def __call__(self, env, start_response):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_dc4ba4af","line":427,"in_reply_to":"3aaa91ec_40d23701","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        except ValueError as err:"},{"line_number":77,"context_line":"            pass"},{"line_number":78,"context_line":"        msg \u003d \u0027Error decrypting %s\u0027 % self.server_type"},{"line_number":79,"context_line":"        self.logger.error(_(\u0027%(msg)s: %(err)s\u0027) % {\u0027msg\u0027: msg, \u0027err\u0027: err})"},{"line_number":80,"context_line":"        raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    def decrypt_value_with_meta(self, value, key, required\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_a9f5a383","line":79,"updated":"2016-06-30 18:03:09.000000000","message":"No. We want to mark msg and err (or possibly combine them and mark *that*); there\u0027s nothing to translate here.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            return self.decrypt_value_with_meta(value, key, required)"},{"line_number":165,"context_line":"        except EncryptionException as e:"},{"line_number":166,"context_line":"            msg \u003d \"Error decrypting header\""},{"line_number":167,"context_line":"            self.logger.error(_(\"%(msg)s %(hdr)s: %(e)s\") %"},{"line_number":168,"context_line":"                              {\u0027msg\u0027: msg, \u0027hdr\u0027: header, \u0027e\u0027: e})"},{"line_number":169,"context_line":"            raise HTTPInternalServerError(body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_299a5314","line":167,"updated":"2016-06-30 18:03:09.000000000","message":"Similar to above: we want to mark msg for translation, not this. (And probably also interpolate header into msg.)","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":280,"context_line":""},{"line_number":281,"context_line":"        mod_resp_headers \u003d self.decrypt_resp_headers(keys)"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"        crypto_meta \u003d None"},{"line_number":284,"context_line":"        if is_success(self._get_status_int()):"},{"line_number":285,"context_line":"            try:"},{"line_number":286,"context_line":"                crypto_meta \u003d self.get_crypto_meta("}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_ece05928","line":283,"updated":"2016-06-30 18:03:09.000000000","message":"Wait -- we didn\u0027t do that before? How did we not catch that earlier!?","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":288,"context_line":"            except EncryptionException as err:"},{"line_number":289,"context_line":"                msg \u003d \u0027Error decrypting object\u0027"},{"line_number":290,"context_line":"                self.logger.error(_(\u0027%(msg)s: %(err)s\u0027) %"},{"line_number":291,"context_line":"                                  {\u0027msg\u0027: msg, \u0027err\u0027: err})"},{"line_number":292,"context_line":"                raise HTTPInternalServerError("},{"line_number":293,"context_line":"                    body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":294,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_ec5b3920","line":291,"updated":"2016-06-30 18:03:09.000000000","message":"msg is what needs to be marked.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            # 2xx response and encrypted body"},{"line_number":297,"context_line":"            body_key \u003d self.get_unwrapped_key(crypto_meta, keys[\u0027object\u0027])"},{"line_number":298,"context_line":"            content_type, content_type_attrs \u003d parse_content_type("},{"line_number":299,"context_line":"                self._response_header_value(\u0027Content-Type\u0027))"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"            if (self._get_status_int() \u003d\u003d 206 and"},{"line_number":302,"context_line":"                    content_type \u003d\u003d \u0027multipart/byteranges\u0027):"}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_2c526113","line":299,"updated":"2016-06-30 18:03:09.000000000","message":"If we ever encrypt content-type, there\u0027s actually good reason to do this extraction *before* decrypting headers. The only reason we need to look at content-type here is it to check for and handle multipart responses, in which case the object-server would have\n\n- pulled the encrypted version down into the headers for each part and then\n- provided an (unencrypted) multipart content-type.\n\nBut we\u0027ll cross that bridge later. This is fine.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":365,"context_line":"                except EncryptionException as err:"},{"line_number":366,"context_line":"                    msg \u003d \"Error decrypting container listing\""},{"line_number":367,"context_line":"                    self.logger.error(_(\u0027%(msg)s: %(err)s\u0027) %"},{"line_number":368,"context_line":"                                      {\u0027msg\u0027: msg, \u0027err\u0027: err})"},{"line_number":369,"context_line":"                    raise HTTPInternalServerError("},{"line_number":370,"context_line":"                        body\u003dmsg, content_type\u003d\u0027text/plain\u0027)"},{"line_number":371,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_ecea19d7","line":368,"updated":"2016-06-30 18:03:09.000000000","message":"Mark msg, not this.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"}],"swift/common/middleware/encrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":145,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":146,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":147,"context_line":"                    self.keys[\u0027container\u0027],"},{"line_number":148,"context_line":"                    iv_base\u003dos.path.join(os.sep, path_for_base))"},{"line_number":149,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":150,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":151,"context_line":"                    append_crypto_meta(val, crypto_meta)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_be6c779d","line":148,"updated":"2016-06-22 00:09:22.000000000","message":"Performance nit: we may compute iv_base\u0027s MD5 twice (assuming it\u0027s sufficiently long). We might want to pull it out of etag_crypto_meta if available.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":145,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":146,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":147,"context_line":"                    self.keys[\u0027container\u0027],"},{"line_number":148,"context_line":"                    iv_base\u003dos.path.join(os.sep, path_for_base))"},{"line_number":149,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":150,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":151,"context_line":"                    append_crypto_meta(val, crypto_meta)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_ad8172c5","line":148,"in_reply_to":"3aaa91ec_be6c779d","updated":"2016-06-23 22:49:18.000000000","message":"we won\u0027t be doing this anymore, we\u0027ll be using a random IV with the container key","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":154,"context_line":"                # with its crypto parameters appended"},{"line_number":155,"context_line":"                etag_crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":156,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":157,"context_line":"                    append_crypto_meta(encrypted_etag, etag_crypto_meta)"},{"line_number":158,"context_line":"            # else: no override was set and no data was read"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"        req.environ[\u0027swift.callback.update_footers\u0027] \u003d footers_callback"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_21b98aea","line":157,"range":{"start_line":157,"start_character":39,"end_line":157,"end_character":53},"updated":"2016-06-22 00:09:22.000000000","message":"So the ciphertext-etag (generally, barring some other middleware setting an override) will match between the object and container servers. Right?\n\nIs there a *need* for this? It makes sense that the container server\u0027s etag ought to be encrypted with the container key, and I see why conditional requests will need the object server to get an etag whose IV is derived from the path. Why can\u0027t the container server still get a random IV? Why can\u0027t the object server\u0027s etag still be encrypted by the object key? Are we just trying to save on encrypt operations?","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":154,"context_line":"                # with its crypto parameters appended"},{"line_number":155,"context_line":"                etag_crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":156,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":157,"context_line":"                    append_crypto_meta(encrypted_etag, etag_crypto_meta)"},{"line_number":158,"context_line":"            # else: no override was set and no data was read"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"        req.environ[\u0027swift.callback.update_footers\u0027] \u003d footers_callback"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_6d62ea3f","line":157,"range":{"start_line":157,"start_character":39,"end_line":157,"end_character":53},"in_reply_to":"3aaa91ec_0aee1a8b","updated":"2016-06-23 22:49:18.000000000","message":"Done","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"a709c37452c0a8393a5394caa2e72aa482a103d3","unresolved":false,"context_lines":[{"line_number":154,"context_line":"                # with its crypto parameters appended"},{"line_number":155,"context_line":"                etag_crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":156,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":157,"context_line":"                    append_crypto_meta(encrypted_etag, etag_crypto_meta)"},{"line_number":158,"context_line":"            # else: no override was set and no data was read"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"        req.environ[\u0027swift.callback.update_footers\u0027] \u003d footers_callback"}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_0aee1a8b","line":157,"range":{"start_line":157,"start_character":39,"end_line":157,"end_character":53},"in_reply_to":"3aaa91ec_21b98aea","updated":"2016-06-22 03:50:43.000000000","message":"I agree.  Great idea!  If we switch to random IV for container db etag and switch back to object key for object etag (since we no longer would have the benefit of encrypted value re-use), we reduce the one-time pad re-use on etag encryption.  Not sure of performance impacts.  Alistair had said md5\u0027s were more of a burden then the encryption, but still worth considering the impacts of course.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"042c155b4863a4d02d81d9a7d30972693669a547","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":150,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":151,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":152,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":153,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":154,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":155,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_ddea9073","line":152,"updated":"2016-06-24 08:14:02.000000000","message":"Remind me why we need key_id, please.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"d71ccc3b4bc8e0363dbf84b017a9a0ec11b80c57","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":150,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":151,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":152,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":153,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":154,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":155,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_81234cbc","line":152,"in_reply_to":"3aaa91ec_a83dabde","updated":"2016-06-27 04:13:59.000000000","message":"I Thought some more on this.  I am in favor of keeping the key_id as the way that we futureproof against the object possibly moving to another path in the future.\n\nSaving as a generic \"key_id\" (as opposed to just the saved object original path) also makes sense for more advanced keymasters that might be used where an id or accessor must be stored to associate to the object key.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"769884d2ea9eeb3252e9bda8bf2b16cdd62ac4dd","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":150,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":151,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":152,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":153,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":154,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":155,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8601d03a","line":152,"in_reply_to":"3aaa91ec_ddea9073","updated":"2016-06-27 09:48:02.000000000","message":"See https://review.openstack.org/#/c/328209/8/doc/source/overview_encryption.rst@410\n\nTBH I flip either way in this. I\u0027d hate to break any future attempt to relocate objects internally to swift (e.g. automatic tiering) so trying to find the minimum metadata that we could persist that would allow us to deal with that. \n\nBut at the same time i am not 100% certain that this is sufficient and it does add the object path into the metadata, so some days I think we should drop this - at least, remove the object path from the key_id meta. I do think that having the key manager version in there might be smart to allow for future keymanagers to co-exist.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"25e0393b99ad21888f68e3b54efe31ee9adf4ce7","unresolved":false,"context_lines":[{"line_number":149,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":150,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":151,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":152,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":153,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":154,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":155,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_a83dabde","line":152,"in_reply_to":"3aaa91ec_ddea9073","updated":"2016-06-24 16:42:07.000000000","message":"Some of these details have changed so quickly, I will need to revisit this topic.\n\nI know that we are wanting to save the path so that later if the object moves, we could still decrypt.  But I do recall we are saving off the derived iv.  there is the matter of the derived key as well.  Alistair had also mentioned, at one point, this may be a futureproof move against maybe having a different key for body vs. metadata.\n\nThere is some history on the topic here:\nhttps://trello.com/c/xFGTzVD7/110-low-priority-store-key-id-in-crypto-meta-not-in-its-own-header","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"042c155b4863a4d02d81d9a7d30972693669a547","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        for name, val in req.headers.items():"},{"line_number":202,"context_line":"            if is_user_meta(self.server_type, name) and val:"},{"line_number":203,"context_line":"                req.headers[name], meta \u003d encrypt_header_val("},{"line_number":204,"context_line":"                    self.crypto, val, keys[self.server_type])"},{"line_number":205,"context_line":"                meta[\u0027key_id\u0027] \u003d keys[\u0027id\u0027]"},{"line_number":206,"context_line":"                # short_name is extracted in order to use it for naming the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_bdd4e41f","line":203,"updated":"2016-06-24 08:14:02.000000000","message":"Remind me: why do we need to have separate crypto meta for each user meta?\n\nUser meta will be replaced en-masse with every POST, so when it comes time to reconcile, all of the meta that\u0027s preserved will be from a single PUT or POST, right? So they would\u0027ve all been encrypted together. Can\u0027t we generate a single keystream from a the object key and a random IV, then sort the user meta by header and encrypt each value in order?\n\nIt seems like then we could avoid roughly doubling MAX_HEADER_COUNT.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"25e0393b99ad21888f68e3b54efe31ee9adf4ce7","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        for name, val in req.headers.items():"},{"line_number":202,"context_line":"            if is_user_meta(self.server_type, name) and val:"},{"line_number":203,"context_line":"                req.headers[name], meta \u003d encrypt_header_val("},{"line_number":204,"context_line":"                    self.crypto, val, keys[self.server_type])"},{"line_number":205,"context_line":"                meta[\u0027key_id\u0027] \u003d keys[\u0027id\u0027]"},{"line_number":206,"context_line":"                # short_name is extracted in order to use it for naming the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_431d0865","line":203,"in_reply_to":"3aaa91ec_0f7b30f6","updated":"2016-06-24 16:42:07.000000000","message":"we are using a different iv for each piece of metadata because they use the same key.  So we need some place to store each piece.  Alistair did create a card to consider other ways: https://trello.com/c/6kiiS8KZ/47-consider-deriving-the-nonce-for-user-metadata","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"69ca95d955203df97b9491f5170146c9f6278a0d","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        for name, val in req.headers.items():"},{"line_number":202,"context_line":"            if is_user_meta(self.server_type, name) and val:"},{"line_number":203,"context_line":"                req.headers[name], meta \u003d encrypt_header_val("},{"line_number":204,"context_line":"                    self.crypto, val, keys[self.server_type])"},{"line_number":205,"context_line":"                meta[\u0027key_id\u0027] \u003d keys[\u0027id\u0027]"},{"line_number":206,"context_line":"                # short_name is extracted in order to use it for naming the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0f7b30f6","line":203,"in_reply_to":"3aaa91ec_9bc2d032","updated":"2016-06-24 13:30:52.000000000","message":"Ah, I think this predates some scope reduction. Account and container user-meta can have individual headers updated one at a time. Objects have an all-or-nothing approach.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"769884d2ea9eeb3252e9bda8bf2b16cdd62ac4dd","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        for name, val in req.headers.items():"},{"line_number":202,"context_line":"            if is_user_meta(self.server_type, name) and val:"},{"line_number":203,"context_line":"                req.headers[name], meta \u003d encrypt_header_val("},{"line_number":204,"context_line":"                    self.crypto, val, keys[self.server_type])"},{"line_number":205,"context_line":"                meta[\u0027key_id\u0027] \u003d keys[\u0027id\u0027]"},{"line_number":206,"context_line":"                # short_name is extracted in order to use it for naming the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_a1fb16c0","line":203,"in_reply_to":"3aaa91ec_9bc2d032","updated":"2016-06-27 09:48:02.000000000","message":"All the user metadata headers will be updated en-masse. We have discussed using a single nonce here [1]. I quite like that scheme but so far it did not get implemented.\n\n[1] https://trello.com/c/6kiiS8KZ/47-consider-deriving-the-nonce-for-user-metadata","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"9a52aa34481ee6a3ac94a80a38f34d3d6908fcda","unresolved":false,"context_lines":[{"line_number":200,"context_line":""},{"line_number":201,"context_line":"        for name, val in req.headers.items():"},{"line_number":202,"context_line":"            if is_user_meta(self.server_type, name) and val:"},{"line_number":203,"context_line":"                req.headers[name], meta \u003d encrypt_header_val("},{"line_number":204,"context_line":"                    self.crypto, val, keys[self.server_type])"},{"line_number":205,"context_line":"                meta[\u0027key_id\u0027] \u003d keys[\u0027id\u0027]"},{"line_number":206,"context_line":"                # short_name is extracted in order to use it for naming the"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_9bc2d032","line":203,"in_reply_to":"3aaa91ec_bdd4e41f","updated":"2016-06-24 08:30:21.000000000","message":"I understood that headers can be updated selectively.  If all user-meta was a single encryption context, then it would have to be en/decrypted always as one.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1793e6fbe0bd2c889d59f0a24b5a3caaee89ca4b","unresolved":false,"context_lines":[{"line_number":272,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % crypto_etag))"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":275,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            yield"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_80bcfbbb","line":275,"updated":"2016-06-24 20:45:24.000000000","message":"Earlier today, we discussed the possibility of using an HMAC of the etag for conditional requests. I like the idea, and think we\u0027d just need to apply something like http://paste.openstack.org/show/522038/ to get it.","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"44c19542d1bcfca8917f92a619d7805d22529fee","unresolved":false,"context_lines":[{"line_number":272,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % crypto_etag))"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":275,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            yield"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_e9d5ce42","line":275,"in_reply_to":"3aaa91ec_80bcfbbb","updated":"2016-06-27 04:14:10.000000000","message":"You can remove line 268/266 path_ver, path_for_base \u003d req.split_path(1, 2, True)\nother than that small thing, looks good.  Ran tests against this and they pass. (except for probetests TestWSGIServerProcessHandling, but those have been failing for me occasionally even with master)","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1781821143edc83a73f4b7a5aca7955bc817d3dd","unresolved":false,"context_lines":[{"line_number":272,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % crypto_etag))"},{"line_number":273,"context_line":""},{"line_number":274,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":275,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag\u0027)"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            yield"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_5be12f9a","line":275,"in_reply_to":"3aaa91ec_e9d5ce42","updated":"2016-06-27 13:49:32.000000000","message":"Done. Applied Tim\u0027s patch with some changes\n\n- made the header name x-object-sysmeta-crypto-etag-mac since that\u0027s what it is (I was hedging my bets with -Sig since we may have used the converged encryption idea)\n\n- I decided not to have the hmac method in crypto_utils because (a) I felt it was clearer to have a dedicated function in the encrypter rather than the parameterised function and (b) if it is a public crypto_utils function then it would require a set of unit tests. I also added another assertion for the hmac sysmeta in test_encrypter_decrypter.py\n\nBTW crude benchmarking showed the HMAC to be approx 5x faster than encrypting the etag, so performance hit of the extra HMAC header should not be too noticeable.","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"925e7bbcf835264f479d0c029a4e76241d9fe2f4","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                encrypted_etag, etag_crypto_meta \u003d encrypt_header_val("},{"line_number":124,"context_line":"                    self.crypto, plaintext_etag, self.keys[\u0027object\u0027])"},{"line_number":125,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d encrypted_etag"},{"line_number":126,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \u003d \\"},{"line_number":127,"context_line":"                    dump_crypto_meta(etag_crypto_meta)"},{"line_number":128,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d dump_crypto_meta("},{"line_number":129,"context_line":"                    self.body_crypto_meta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_8262e0ab","line":126,"updated":"2016-06-28 07:00:46.000000000","message":"I saw the card about dropping this -- http://paste.openstack.org/show/523732/ is a decent stab at it.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                encrypted_etag, etag_crypto_meta \u003d encrypt_header_val("},{"line_number":124,"context_line":"                    self.crypto, plaintext_etag, self.keys[\u0027object\u0027])"},{"line_number":125,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d encrypted_etag"},{"line_number":126,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027] \u003d \\"},{"line_number":127,"context_line":"                    dump_crypto_meta(etag_crypto_meta)"},{"line_number":128,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Meta\u0027] \u003d dump_crypto_meta("},{"line_number":129,"context_line":"                    self.body_crypto_meta)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_7aabfe1e","line":126,"in_reply_to":"3aaa91ec_8262e0ab","updated":"2016-06-28 16:23:06.000000000","message":"Done - thanks!","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":161,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":162,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":163,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":164,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":165,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":166,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_2587cf13","line":163,"updated":"2016-06-27 19:11:46.000000000","message":"OK, I think I get the arguments for having this now. The future-proofing for background processes moving data without a (crypto-aware) proxy pipeline makes some sense, especially given the direction some of the tiering work has been taking.\n\nConditional requests would be problemtatic (as Alistair noted over on keymaster.py), but what else is new? :-/\n\nIf we get some crypto meta that includes a key_id we maybe weren\u0027t expecting, how will the decrypter get the key corresponding to that key_id? I guess we\u0027d have to add key_id as an argument to the fetch_keys callback. Should we do that now?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":161,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":162,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":163,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":164,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":165,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":166,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_b59a976c","line":163,"in_reply_to":"3aaa91ec_2587cf13","updated":"2016-06-28 16:23:06.000000000","message":"I am in favour of keeping key_id, because it also persists the keymanager version. But I still doubt the usefulness of including the path (in every instance of this metadata). We\u0027re worried about user metadata headers being too long, but by including the path we\u0027re adding a ton of redundant bytes.\n\nRe passing as an arg to keymaster. Yes. We could do it now, or on master - it is not urgent imho.\n\nIt\u0027s a change I have had in mind, but at same time to merge encrypter and decrypter into one middleware, because I don\u0027t think we need them to be separate and sandwiching the keymaster.\n\nIf we\u0027re passing key_id to fetch_crypto_keys then presumably the keymaster cannot have chosen keys when it set the callback in the env. So, we can just callback with key_id, resp headers and req env and let the keymaster do its business during the callback.\n\nThen, as discussed elsewhere, we reduce possibility for pipeline config mistakes.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":20988,"name":"Mathias Bjoerkqvist","email":"mbj@zurich.ibm.com","username":"mathiasb"},"change_message_id":"ac36ee0992e9314c3db03ca9d608a61e17441cf0","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":161,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":162,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":163,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":164,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":165,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":166,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c98248c8","line":163,"in_reply_to":"3aaa91ec_2587cf13","updated":"2016-06-28 11:59:48.000000000","message":"Would it be possible to store the crypto_meta in a structure indicating e.g., the keymaster type and version used to encrypt the object? For this keymaster, we might need only the key_id, but for another keymaster that stores the wrapped object key in the object metadata, other crypto meta would be needed. It might be cleaner to have all such information inside a single structure (or not)?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"626f6d6ec35fa29d24577ec108300a34c500aea9","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":161,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":162,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":163,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":164,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":165,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":166,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_ab2a33e5","line":163,"in_reply_to":"3aaa91ec_b59a976c","updated":"2016-06-28 19:07:09.000000000","message":"Agreed - it would be good to have a default location for path used.  I think it would be good to have a way to specify path that would override that, in the case that later there is a way to update meta individually.  I know we dont want to jump through hoops for a feature we dont have, but this seems easy enough to support.\n\nmerge encrypter and decrypter: i am open to this.  might be a lot of work (like busy work) doing that impl","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                val, crypto_meta \u003d encrypt_header_val("},{"line_number":161,"context_line":"                    self.crypto, container_listing_etag,"},{"line_number":162,"context_line":"                    self.keys[\u0027container\u0027])"},{"line_number":163,"context_line":"                crypto_meta[\u0027key_id\u0027] \u003d self.keys[\u0027id\u0027]"},{"line_number":164,"context_line":"                footers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027] \u003d \\"},{"line_number":165,"context_line":"                    append_crypto_meta(val, crypto_meta)"},{"line_number":166,"context_line":"            # else: no override was set and no data was read"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_555893fa","line":163,"in_reply_to":"3aaa91ec_c98248c8","updated":"2016-06-28 16:23:06.000000000","message":"@Mathias - key[\u0027id\u0027] can be a dict (in fact, it is in the keymaster), so that should allow other key manager impls to persist arbitrary private metadata with the object crypto-meta.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"925e7bbcf835264f479d0c029a4e76241d9fe2f4","unresolved":false,"context_lines":[{"line_number":342,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":343,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":344,"context_line":"    conf.update(local_conf)"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def encrypter_filter(app):"},{"line_number":347,"context_line":"        return Encrypter(app, conf)"},{"line_number":348,"context_line":"    return encrypter_filter"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_3ce87216","line":345,"updated":"2016-06-28 07:00:46.000000000","message":"I feel like this (or maybe keymaster, or maybe some combination of the two) should call register_swift_info, possibly with admin\u003dTrue though.\n\nI know Swift3 would be interested in whether encryption is available. Clients might be, as well.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":342,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":343,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":344,"context_line":"    conf.update(local_conf)"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    def encrypter_filter(app):"},{"line_number":347,"context_line":"        return Encrypter(app, conf)"},{"line_number":348,"context_line":"    return encrypter_filter"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_d576433d","line":345,"in_reply_to":"3aaa91ec_3ce87216","updated":"2016-06-28 16:23:06.000000000","message":"Done","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":279,"context_line":"                    new_etags.append(etag)"},{"line_number":280,"context_line":"                    continue"},{"line_number":281,"context_line":"                etag_sig \u003d _hmac_etag(keys[\u0027object\u0027], etag)"},{"line_number":282,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % etag_sig))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":285,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_3ec94a79","line":282,"updated":"2016-06-29 05:10:17.000000000","message":"In the future, when we want to support multiple keymasters or rotating keys, I think we can just calculate and append an etag_sig for each candidate key, yeah?","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"9b43509aa334a1276097407c3c978045b30e0cea","unresolved":false,"context_lines":[{"line_number":279,"context_line":"                    new_etags.append(etag)"},{"line_number":280,"context_line":"                    continue"},{"line_number":281,"context_line":"                etag_sig \u003d _hmac_etag(keys[\u0027object\u0027], etag)"},{"line_number":282,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % etag_sig))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":285,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d991409c","line":282,"in_reply_to":"3aaa91ec_3ec94a79","updated":"2016-06-29 05:51:25.000000000","message":"ah, true","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":279,"context_line":"                    new_etags.append(etag)"},{"line_number":280,"context_line":"                    continue"},{"line_number":281,"context_line":"                etag_sig \u003d _hmac_etag(keys[\u0027object\u0027], etag)"},{"line_number":282,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % etag_sig))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":285,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_19abac76","line":282,"in_reply_to":"3aaa91ec_d991409c","updated":"2016-06-29 17:06:47.000000000","message":"yes","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"class Encrypter(object):"},{"line_number":303,"context_line":"    \"\"\"Middleware for encrypting data and user metadata.\"\"\""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    def __init__(self, app, conf):"},{"line_number":306,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_5e8b761e","line":303,"updated":"2016-06-29 05:10:17.000000000","message":"Should we document the disable_encryption option here as well, so it appears in http://docs-draft.openstack.org/08/328208/11/check/gate-swift-docs/4f5c2eb//doc/build/html/middleware.html#swift.common.middleware.encrypter.Encrypter ?","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":""},{"line_number":302,"context_line":"class Encrypter(object):"},{"line_number":303,"context_line":"    \"\"\"Middleware for encrypting data and user metadata.\"\"\""},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    def __init__(self, app, conf):"},{"line_number":306,"context_line":"        self.app \u003d app"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_99addc86","line":303,"in_reply_to":"3aaa91ec_5e8b761e","updated":"2016-06-29 17:06:47.000000000","message":"Done","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":343,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":344,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":345,"context_line":"    conf.update(local_conf)"},{"line_number":346,"context_line":"    register_swift_info(\u0027encrypter\u0027, admin\u003dTrue)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def encrypter_filter(app):"},{"line_number":349,"context_line":"        return Encrypter(app, conf)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_9c821151","line":346,"updated":"2016-06-29 05:10:17.000000000","message":"No indication of whether it\u0027s turned on or not?","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":343,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":344,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":345,"context_line":"    conf.update(local_conf)"},{"line_number":346,"context_line":"    register_swift_info(\u0027encrypter\u0027, admin\u003dTrue)"},{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    def encrypter_filter(app):"},{"line_number":349,"context_line":"        return Encrypter(app, conf)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_dcfab2bc","line":346,"in_reply_to":"3aaa91ec_9c821151","updated":"2016-06-29 17:06:47.000000000","message":"Are we sure we want to advertise that? remind me, what restriction does admin imply? I\u0027m always nervous about clients discovering my system config.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    register_swift_info"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def encrypt_header_val(crypto, value, key):"},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":"    Encrypt a header value using the supplied key."},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_40dcf7e3","line":32,"updated":"2016-06-30 07:28:43.000000000","message":"Why do we have decrypt_value_with_meta and decrypt_value dangling off of BaseDecrypterContext, while this is module-level?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    register_swift_info"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"def encrypt_header_val(crypto, value, key):"},{"line_number":33,"context_line":"    \"\"\""},{"line_number":34,"context_line":"    Encrypt a header value using the supplied key."},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_0f9cd0be","line":32,"in_reply_to":"3aaa91ec_40dcf7e3","updated":"2016-06-30 16:40:17.000000000","message":"Because this is used in EncInputWrapper","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"20a44356e1adfa5df3e6c8a1499e14efe4fb8be9","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    crypto_meta \u003d crypto.create_crypto_meta()"},{"line_number":47,"context_line":"    crypto_ctxt \u003d crypto.create_encryption_ctxt(key, crypto_meta[\u0027iv\u0027])"},{"line_number":48,"context_line":"    enc_val \u003d base64.b64encode(crypto_ctxt.update(value))"},{"line_number":49,"context_line":"    return enc_val, crypto_meta"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def _hmac_etag(key, etag):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_fb9af460","line":49,"updated":"2016-06-30 06:54:47.000000000","message":"crypto_ctxt.update() is no longer as modular as originally intended, this is now directly the Cipher\u0027s update() from the crypto library underneath. If the semantics change there, it affects us here. It\u0027s no longer possible to change the cryptography provider library by only making changes inside crypto_utils. I\u0027d suggest to completely wrap the library in crypto_utils ... but I understand it was decided not to.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"d851cc3fe809c9f6d6d331e16e08949e94c18379","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    crypto_meta \u003d crypto.create_crypto_meta()"},{"line_number":47,"context_line":"    crypto_ctxt \u003d crypto.create_encryption_ctxt(key, crypto_meta[\u0027iv\u0027])"},{"line_number":48,"context_line":"    enc_val \u003d base64.b64encode(crypto_ctxt.update(value))"},{"line_number":49,"context_line":"    return enc_val, crypto_meta"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def _hmac_etag(key, etag):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_b2cb6a52","line":49,"in_reply_to":"3aaa91ec_d6ba6de0","updated":"2016-06-30 08:23:25.000000000","message":"Agreed, was only pointing out the potential pitfall.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    crypto_meta \u003d crypto.create_crypto_meta()"},{"line_number":47,"context_line":"    crypto_ctxt \u003d crypto.create_encryption_ctxt(key, crypto_meta[\u0027iv\u0027])"},{"line_number":48,"context_line":"    enc_val \u003d base64.b64encode(crypto_ctxt.update(value))"},{"line_number":49,"context_line":"    return enc_val, crypto_meta"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def _hmac_etag(key, etag):"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_d6ba6de0","line":49,"in_reply_to":"3aaa91ec_fb9af460","updated":"2016-06-30 07:28:43.000000000","message":"We still can completely change out the provider in crypto_utils, I think. We\u0027d just need to expose a update() interface in whatever we return. It seems like a sensible-enough interface; I\u0027m not sure I see the value in adding the indirection now instead of when we decide we actually need it.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    \"\"\"File-like object to be swapped in for wsgi.input.\"\"\""},{"line_number":66,"context_line":"    def __init__(self, crypto, keys, req, logger):"},{"line_number":67,"context_line":"        self.env \u003d req.environ"},{"line_number":68,"context_line":"        self.wsgi_input \u003d req.environ[\u0027wsgi.input\u0027]"},{"line_number":69,"context_line":"        self.path \u003d req.path"},{"line_number":70,"context_line":"        self.crypto \u003d crypto"},{"line_number":71,"context_line":"        self.body_crypto_ctxt \u003d None"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5b4068a5","line":68,"updated":"2016-06-30 07:28:43.000000000","message":"I was debating about whether we ought to set\n\n req.environ[\u0027wsgi.input\u0027] \u003d self\n\nafter this, but maybe that\u0027s a little too action-at-a-distance. On the other hand, we already do something similar with install_footers_callback...","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            self.body_crypto_ctxt \u003d self.crypto.create_encryption_ctxt("},{"line_number":88,"context_line":"                body_key, self.body_crypto_meta.get(\u0027iv\u0027))"},{"line_number":89,"context_line":"            self.plaintext_md5 \u003d md5()"},{"line_number":90,"context_line":"            self.ciphertext_md5 \u003d md5()"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def install_footers_callback(self, req):"},{"line_number":93,"context_line":"        # the proxy controller will call back for footer metadata after"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_c060e737","line":90,"range":{"start_line":90,"start_character":34,"end_line":90,"end_character":37},"updated":"2016-06-30 07:28:43.000000000","message":"nit: Maybe just say hashlib.md5()? It\u0027d save us a line up in the imports.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            self.body_crypto_ctxt \u003d self.crypto.create_encryption_ctxt("},{"line_number":88,"context_line":"                body_key, self.body_crypto_meta.get(\u0027iv\u0027))"},{"line_number":89,"context_line":"            self.plaintext_md5 \u003d md5()"},{"line_number":90,"context_line":"            self.ciphertext_md5 \u003d md5()"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def install_footers_callback(self, req):"},{"line_number":93,"context_line":"        # the proxy controller will call back for footer metadata after"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_6f491431","line":90,"range":{"start_line":90,"start_character":34,"end_line":90,"end_character":37},"in_reply_to":"3aaa91ec_c060e737","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"7540eddcb070f22cb1ecc95b33c57e0b305a7059","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                    self.crypto, plaintext_etag, self.keys[\u0027object\u0027])"},{"line_number":126,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"},{"line_number":127,"context_line":"                    append_crypto_meta(encrypted_etag, etag_crypto_meta)"},{"line_number":128,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Body-Meta\u0027] \u003d \\"},{"line_number":129,"context_line":"                    dump_crypto_meta(self.body_crypto_meta)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"                # Also add an HMAC of the etag for use when evaluating"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1ac24553","line":128,"updated":"2016-06-30 13:41:40.000000000","message":"just a thought - rename to Crypto-Meta-Body? more readable and consistent i think. (we\u0027re also logging the error msg in decrypter as \"No sysmeta-crypto-meta for body\")","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":125,"context_line":"                    self.crypto, plaintext_etag, self.keys[\u0027object\u0027])"},{"line_number":126,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Etag\u0027] \u003d \\"},{"line_number":127,"context_line":"                    append_crypto_meta(encrypted_etag, etag_crypto_meta)"},{"line_number":128,"context_line":"                footers[\u0027X-Object-Sysmeta-Crypto-Body-Meta\u0027] \u003d \\"},{"line_number":129,"context_line":"                    dump_crypto_meta(self.body_crypto_meta)"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"                # Also add an HMAC of the etag for use when evaluating"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_298a5d64","line":128,"in_reply_to":"3aaa91ec_1ac24553","updated":"2016-06-30 16:40:17.000000000","message":"I made it Crypto-Body-Meta deliberately so that anything starting Crypto-Meta- in any namespace is relates to user metadata.\n\nI\u0027ll check on the logger message","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        return self.readChunk(self.wsgi_input.read, *args, **kwargs)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    def readline(self, *args, **kwargs):"},{"line_number":174,"context_line":"        return self.readChunk(self.wsgi_input.readline, *args, **kwargs)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def readChunk(self, read_method, *args, **kwargs):"},{"line_number":177,"context_line":"        chunk \u003d read_method(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_db4d7873","line":174,"updated":"2016-06-30 07:28:43.000000000","message":"Might be able to simplify these a bit with functools.partial","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        # Check the user-metadata length before encrypting and encoding"},{"line_number":197,"context_line":"        error_response \u003d check_metadata(req, self.server_type)"},{"line_number":198,"context_line":"        if error_response:"},{"line_number":199,"context_line":"                raise error_response"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def encrypt_user_metadata(self, req, keys):"},{"line_number":202,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9bc5b05d","line":199,"range":{"start_line":199,"start_character":12,"end_line":199,"end_character":16},"updated":"2016-06-30 07:28:43.000000000","message":"Quite the indent.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        # Check the user-metadata length before encrypting and encoding"},{"line_number":197,"context_line":"        error_response \u003d check_metadata(req, self.server_type)"},{"line_number":198,"context_line":"        if error_response:"},{"line_number":199,"context_line":"                raise error_response"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"    def encrypt_user_metadata(self, req, keys):"},{"line_number":202,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_0fd4d01d","line":199,"range":{"start_line":199,"start_character":12,"end_line":199,"end_character":16},"in_reply_to":"3aaa91ec_9bc5b05d","updated":"2016-06-30 16:40:17.000000000","message":"always surprises me that pep8 doesn\u0027t catch those, or at least warn","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":239,"context_line":""},{"line_number":240,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        # If an etag is in the response headers, then replace its value with"},{"line_number":243,"context_line":"        # the plaintext version if one was calculated in encrypter"},{"line_number":244,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":245,"context_line":"        if enc_input_proxy.plaintext_md5:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9b4bf0b0","line":242,"range":{"start_line":242,"start_character":10,"end_line":242,"end_character":47},"updated":"2016-06-30 07:28:43.000000000","message":"...and it should be unnecessary to check that the response ETag matches ciphertext_md5.hexdigest(), right?\n\nAlso, this should *only* be present for successful requests, yeah?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":239,"context_line":""},{"line_number":240,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        # If an etag is in the response headers, then replace its value with"},{"line_number":243,"context_line":"        # the plaintext version if one was calculated in encrypter"},{"line_number":244,"context_line":"        mod_resp_headers \u003d self._response_headers"},{"line_number":245,"context_line":"        if enc_input_proxy.plaintext_md5:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_e865fa44","line":242,"range":{"start_line":242,"start_character":10,"end_line":242,"end_character":47},"in_reply_to":"3aaa91ec_9b4bf0b0","updated":"2016-06-30 16:40:17.000000000","message":"1) I was hesitant to put in a check wrt ciphertext md5 because I see an optimisation whereby for EC policy we do not need to calculate the ciphertext md5 (because the EC obj controller repeats the same md5). But we could (in future) make the check conditional on us having a ciphertext md5.\n\n2) the response should only have an etag is it is success, and my logic was that if the app includes an etag then it means for an etag to be returned, and the only sensible one to use would be the plaintext etag. It appears no func tests fail if I add a check for success so perhaps it is safest to do so.\n\nMy feeling is that if the response etag doe not match the ciphertext etag then we should simply allow it to pass to client. AFAICT nowhere else in the response path do we check the validity of the response etag (e.g. in EC). The app said the request was successful, and maybe there is some reason for the etag mismatch that the encrypter does not know about.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"3393d77be4456458a45bab602c329caf6eb1389f","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        return resp"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @contextmanager"},{"line_number":271,"context_line":"    def _encrypt_conditional_etags(self, req, header_name):"},{"line_number":272,"context_line":"        \"\"\""},{"line_number":273,"context_line":"        Calculate HMACs of etags in header value and append to existing list."},{"line_number":274,"context_line":"        The HMACs are calculated in the same way as was done for the object"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_b5735e4d","line":271,"updated":"2016-06-30 02:15:05.000000000","message":"(nit) \"encrypt\" technically isn\u0027t correct any more, right?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"20a44356e1adfa5df3e6c8a1499e14efe4fb8be9","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        return resp"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @contextmanager"},{"line_number":271,"context_line":"    def _encrypt_conditional_etags(self, req, header_name):"},{"line_number":272,"context_line":"        \"\"\""},{"line_number":273,"context_line":"        Calculate HMACs of etags in header value and append to existing list."},{"line_number":274,"context_line":"        The HMACs are calculated in the same way as was done for the object"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_c04aa782","line":271,"in_reply_to":"3aaa91ec_b5735e4d","updated":"2016-06-30 06:54:47.000000000","message":"Yes, \"mask\" could be a more common term for this.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        return resp"},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    @contextmanager"},{"line_number":271,"context_line":"    def _encrypt_conditional_etags(self, req, header_name):"},{"line_number":272,"context_line":"        \"\"\""},{"line_number":273,"context_line":"        Calculate HMACs of etags in header value and append to existing list."},{"line_number":274,"context_line":"        The HMACs are calculated in the same way as was done for the object"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_94de0c3c","line":271,"in_reply_to":"3aaa91ec_c04aa782","updated":"2016-06-30 16:40:17.000000000","message":"Done, thanks for the alternative suggestion","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"20a44356e1adfa5df3e6c8a1499e14efe4fb8be9","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        The existing etag values are left in the list of values to match in"},{"line_number":280,"context_line":"        case the object was not encrypted when it was PUT. It is unlikely that"},{"line_number":281,"context_line":"        an encrypted etag value would collide with an unencrypted value."},{"line_number":282,"context_line":"        \"\"\""},{"line_number":283,"context_line":"        old_etags \u003d req.headers.get(header_name)"},{"line_number":284,"context_line":"        if old_etags:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_c018e786","line":281,"range":{"start_line":281,"start_character":11,"end_line":281,"end_character":65},"updated":"2016-06-30 06:54:47.000000000","message":"ditto: \"masked\" and \"unmasked\"","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        The existing etag values are left in the list of values to match in"},{"line_number":280,"context_line":"        case the object was not encrypted when it was PUT. It is unlikely that"},{"line_number":281,"context_line":"        an encrypted etag value would collide with an unencrypted value."},{"line_number":282,"context_line":"        \"\"\""},{"line_number":283,"context_line":"        old_etags \u003d req.headers.get(header_name)"},{"line_number":284,"context_line":"        if old_etags:"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_74bc40dc","line":281,"range":{"start_line":281,"start_character":11,"end_line":281,"end_character":65},"in_reply_to":"3aaa91ec_c018e786","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":292,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % etag_sig))"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":295,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"        try:"},{"line_number":298,"context_line":"            yield"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_9b55b01f","line":295,"updated":"2016-06-30 07:28:43.000000000","message":"So if a client sends both If-Match and If-None-Match headers, this gets added twice?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":292,"context_line":"                new_etags.extend((\u0027\"%s\"\u0027 % etag, \u0027\"%s\"\u0027 % etag_sig))"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"            req.headers[header_name] \u003d \u0027, \u0027.join(new_etags)"},{"line_number":295,"context_line":"            update_etag_is_at_header(req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"        try:"},{"line_number":298,"context_line":"            yield"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_fa4db93e","line":295,"in_reply_to":"3aaa91ec_9b55b01f","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":322,"context_line":"    def __init__(self, app, conf):"},{"line_number":323,"context_line":"        self.app \u003d app"},{"line_number":324,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"encrypter\")"},{"line_number":325,"context_line":"        self.conf \u003d conf"},{"line_number":326,"context_line":"        self.crypto \u003d Crypto(self.conf)"},{"line_number":327,"context_line":"        self.disable_encryption \u003d config_true_value("},{"line_number":328,"context_line":"            conf.get(\u0027disable_encryption\u0027, \u0027false\u0027))"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1606b51b","line":325,"updated":"2016-06-30 07:28:43.000000000","message":"Like with Decrypter, we don\u0027t seem to use conf outside of the constructor.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":322,"context_line":"    def __init__(self, app, conf):"},{"line_number":323,"context_line":"        self.app \u003d app"},{"line_number":324,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\"encrypter\")"},{"line_number":325,"context_line":"        self.conf \u003d conf"},{"line_number":326,"context_line":"        self.crypto \u003d Crypto(self.conf)"},{"line_number":327,"context_line":"        self.disable_encryption \u003d config_true_value("},{"line_number":328,"context_line":"            conf.get(\u0027disable_encryption\u0027, \u0027false\u0027))"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_94ff2c65","line":325,"in_reply_to":"3aaa91ec_1606b51b","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":360,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":361,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":362,"context_line":"    conf.update(local_conf)"},{"line_number":363,"context_line":"    register_swift_info(\u0027encrypter\u0027, admin\u003dTrue)"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    def encrypter_filter(app):"},{"line_number":366,"context_line":"        return Encrypter(app, conf)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_76457941","line":363,"updated":"2016-06-30 07:28:43.000000000","message":"As Sam mentioned on the other patch, I\u0027d rather like to know whether this is actually *active*.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":360,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":361,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":362,"context_line":"    conf.update(local_conf)"},{"line_number":363,"context_line":"    register_swift_info(\u0027encrypter\u0027, admin\u003dTrue)"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    def encrypter_filter(app):"},{"line_number":366,"context_line":"        return Encrypter(app, conf)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_3d1c5b69","line":363,"in_reply_to":"3aaa91ec_7538ccee","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"966c23e0592f6cb1c2de67dbc0e2041d1a109565","unresolved":false,"context_lines":[{"line_number":360,"context_line":"def filter_factory(global_conf, **local_conf):"},{"line_number":361,"context_line":"    conf \u003d global_conf.copy()"},{"line_number":362,"context_line":"    conf.update(local_conf)"},{"line_number":363,"context_line":"    register_swift_info(\u0027encrypter\u0027, admin\u003dTrue)"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    def encrypter_filter(app):"},{"line_number":366,"context_line":"        return Encrypter(app, conf)"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_7538ccee","line":363,"in_reply_to":"3aaa91ec_76457941","updated":"2016-06-30 08:56:12.000000000","message":"By active you mean if \"disable_encryption \u003d False\"?\nYes, that would be useful. Could be also used to register the info only if it\u0027s set to False (ie encryption is enabled)","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca05041e62ab9435414af0a10604f199e2172376","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def handle_get_or_head(self, req, start_response):"},{"line_number":315,"context_line":"        with self._mask_conditional_etags(req, \u0027If-Match\u0027) as masked1:"},{"line_number":316,"context_line":"            with self._mask_conditional_etags(req, \u0027If-None-Match\u0027) as masked2:"},{"line_number":317,"context_line":"                if masked1 or masked2:"},{"line_number":318,"context_line":"                    update_etag_is_at_header("},{"line_number":319,"context_line":"                        req, \u0027X-Object-Sysmeta-Crypto-Etag-Mac\u0027)"},{"line_number":320,"context_line":"                resp \u003d self._app_call(req.environ)"}],"source_content_type":"text/x-python","patch_set":13,"id":"3aaa91ec_6c0d898e","line":317,"updated":"2016-06-30 18:03:09.000000000","message":"Nice.","commit_id":"3837bf7fafeaa0c7028f3c75db4408d95d74d663"}],"swift/common/middleware/keymaster.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"042c155b4863a4d02d81d9a7d30972693669a547","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    def create_key(self, key_id):"},{"line_number":133,"context_line":"        return hmac.new(self.root_secret, key_id,"},{"line_number":134,"context_line":"                        digestmod\u003dhashlib.sha256).digest()"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"def filter_factory(global_conf, **local_conf):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_e0b6c3f7","line":134,"updated":"2016-06-24 08:14:02.000000000","message":"Any reason to go for a simple HMAC over HKDF?\n\nSee also: https://tools.ietf.org/html/rfc5869","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"69ca95d955203df97b9491f5170146c9f6278a0d","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    def create_key(self, key_id):"},{"line_number":133,"context_line":"        return hmac.new(self.root_secret, key_id,"},{"line_number":134,"context_line":"                        digestmod\u003dhashlib.sha256).digest()"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"def filter_factory(global_conf, **local_conf):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0f62103e","line":134,"in_reply_to":"3aaa91ec_7b50c4d4","updated":"2016-06-24 13:30:52.000000000","message":"Cool. Just noticed it had \"Key Derivation Function\" in the name :-)","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"9a52aa34481ee6a3ac94a80a38f34d3d6908fcda","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    def create_key(self, key_id):"},{"line_number":133,"context_line":"        return hmac.new(self.root_secret, key_id,"},{"line_number":134,"context_line":"                        digestmod\u003dhashlib.sha256).digest()"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"def filter_factory(global_conf, **local_conf):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_7b50c4d4","line":134,"in_reply_to":"3aaa91ec_e0b6c3f7","updated":"2016-06-24 08:30:21.000000000","message":"Because HMAC is the right primitive, the other one is overkill. See discussion here, under \"2) Key derivation - using HMAC\"\nhttps://etherpad.openstack.org/p/swift_encryption_issues","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        self.obj \u003d obj"},{"line_number":49,"context_line":"        self._keys \u003d None"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def fetch_crypto_keys(self):"},{"line_number":52,"context_line":"        \"\"\""},{"line_number":53,"context_line":"        Setup container and object keys based on the request path."},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_65fd576e","line":51,"updated":"2016-06-27 19:11:46.000000000","message":"I feel like this should accept a key_id param...","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        self.obj \u003d obj"},{"line_number":49,"context_line":"        self._keys \u003d None"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def fetch_crypto_keys(self):"},{"line_number":52,"context_line":"        \"\"\""},{"line_number":53,"context_line":"        Setup container and object keys based on the request path."},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_d03491df","line":51,"in_reply_to":"3aaa91ec_65fd576e","updated":"2016-06-28 16:23:06.000000000","message":"ack. I fear someone will point out that it is not used ;) It will only be useful if this keymastyer impl was to call any other pre-installed callbacks, which is another change that we\u0027d need to make if/when they come along, so I don\u0027t think its urgent to add the arg?\n\ntracking... https://trello.com/c/e3Sqki8N/124-pass-key-id-to-crypto-keys-callback-could-wait-for-master","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4a590a0f8c078c3dc2b0ff46fb766cdb8ec195a0","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":85,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":86,"context_line":"            # this information for future use."},{"line_number":87,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_8592039e","line":87,"updated":"2016-06-27 18:19:03.000000000","message":"Including the path is of questionable value - we do not have this meta available when handling a conditional request, so if an object is relocated, conditional requests would not work.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":85,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":86,"context_line":"            # this information for future use."},{"line_number":87,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_d003f1b6","line":87,"in_reply_to":"3aaa91ec_379c0469","updated":"2016-06-28 16:23:06.000000000","message":"I mean that when handling a conditional request we do not currently use a subrequest to retrieve any crypto-meta, so we would not be able to pass the \u0027id\u0027 metadata back to a keymaster to inform it of which keys to issue.\n\nWe have worked very hard to avoid that kind of subrequest during conditional request handling.\n\nFuture keymasters would make their own decision as to what to include in the \u0027id\u0027 entry. But they will be subject to the same challenge as above for conditional requests.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":20988,"name":"Mathias Bjoerkqvist","email":"mbj@zurich.ibm.com","username":"mathiasb"},"change_message_id":"ac36ee0992e9314c3db03ca9d608a61e17441cf0","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":85,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":86,"context_line":"            # this information for future use."},{"line_number":87,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_379c0469","line":87,"in_reply_to":"3aaa91ec_8592039e","updated":"2016-06-28 11:59:48.000000000","message":"When you say that \"we do not have this meta available\", does that mean the (original) path is not included in the request, that it would be possible to retrieve it (using a subrequest?) but that it\u0027s too much overhead, or it is impossible to retrieve the information? I\u0027m also wondering how much this might impact future keymasters, and not only for conditional requests.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"626f6d6ec35fa29d24577ec108300a34c500aea9","unresolved":false,"context_lines":[{"line_number":84,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":85,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":86,"context_line":"            # this information for future use."},{"line_number":87,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_33e23502","line":87,"in_reply_to":"3aaa91ec_d003f1b6","updated":"2016-06-28 19:07:09.000000000","message":"@Mathias: Basically, if somebody created a keymaster that required information from the object meta-data on the object server, then the conditional GET may as well do the whole GET unconditionally,  and then modify the response to match what is expected from the api.  This sort of defeats the purpose of a conditional GET.\n\nThis is why we are deriving the key - and you must use what you have on the client request - and try to make it unique enough for a good key.  In this case, we chose the path.  The problem is that the path might someday change if your object might move due to tiering or a different storage policy.\n\nUsing the HMAC solved the iv issue, but we are still making use of the fact that the key is unique (up to path) here to say its cryptographically secure.  And, we are still relying on being able to determine the key from only client provided info in this case as well.\n\nIt seems to me that if we dont persist the path as breadcrumbs now, then we are resigning to never be able to move encrypted objects - or to later have deployments that don\u0027t support efficient conditional GETs.\n\nIf we are holding out hope to find a solution, I would expect a solution will be easier to develop if we have this path persisted for the time being.  IMHO. but i am flexible if there is a significant gain for removing the path.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def handle_request(self, req, start_response):"},{"line_number":92,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":93,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":94,"context_line":"        start_response(self._response_status, self._response_headers,"},{"line_number":95,"context_line":"                       self._response_exc_info)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_3bba4e6f","line":92,"updated":"2016-06-27 19:11:46.000000000","message":"What if the callback was already set, from some third-party keymaster? Can we support having multiple keymasters in a single pipeline, or will the recommendation be \"only use one\" for the foreseeable future?\n\nAt some point, I\u0027m sure we\u0027ll want a migration path from the this keymaster to a castellan/barbican-based one...","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":20988,"name":"Mathias Bjoerkqvist","email":"mbj@zurich.ibm.com","username":"mathiasb"},"change_message_id":"ac36ee0992e9314c3db03ca9d608a61e17441cf0","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def handle_request(self, req, start_response):"},{"line_number":92,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":93,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":94,"context_line":"        start_response(self._response_status, self._response_headers,"},{"line_number":95,"context_line":"                       self._response_exc_info)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c74fc868","line":92,"in_reply_to":"3aaa91ec_3bba4e6f","updated":"2016-06-28 11:59:48.000000000","message":"Could a keymaster decide if it should provide keys or not based on e.g., the crypto_meta information (for GETs) or config settings/place of keymaster in the pipeline (for PUTs)? Would there even be enough information to make these kinds of decisions for conditional requests?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def handle_request(self, req, start_response):"},{"line_number":92,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":93,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":94,"context_line":"        start_response(self._response_status, self._response_headers,"},{"line_number":95,"context_line":"                       self._response_exc_info)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_b0ec65f4","line":92,"in_reply_to":"3aaa91ec_3bba4e6f","updated":"2016-06-28 16:23:06.000000000","message":"Sure, we will. But that can be follow work IMO.\n\nWhen that time comes, the version \u0027v\u0027 item in the \u0027id\u0027 dict is a hint for this keymaster to either handle the callback or forward it to another keymaster.\n\nAs I said in another reply, I do think that will require us to call the callback from the decrypter *after* we have all the resp headers and ahve extracted the keymaster id info from crypto_meta (which could be different for the body vs user metadata).\n\nSo the current decrypter/keymanager/encrypter pipeline sequence is of questionable value.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        return self._keys"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    def handle_request(self, req, start_response):"},{"line_number":92,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":93,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":94,"context_line":"        start_response(self._response_status, self._response_headers,"},{"line_number":95,"context_line":"                       self._response_exc_info)"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_b07c65b6","line":92,"in_reply_to":"3aaa91ec_c74fc868","updated":"2016-06-28 16:23:06.000000000","message":"It could be based on pipeline position in the PUT path (or other mechanisms yet-to-be-invented). In the GET path the \u0027v\u0027 field in the keymaster id info can be used to discriminate which requests a keymaster should provide keys for.\n\nConditional requests...are harder ;) but the approach we now have in these patches (using an hmac) may well be re-usable with other keymasters.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da5c4ea926427c1d6ae71a2f30c4ed4307655a1a","unresolved":false,"context_lines":[{"line_number":123,"context_line":"            km_context \u003d KeyMasterContext(self, *parts[1:])"},{"line_number":124,"context_line":"            try:"},{"line_number":125,"context_line":"                return km_context.handle_request(req, start_response)"},{"line_number":126,"context_line":"            except HTTPException as err_resp:"},{"line_number":127,"context_line":"                return err_resp(env, start_response)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        # anything else"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_051613a7","line":126,"updated":"2016-06-27 19:11:46.000000000","message":"What are the pros/cons of returning err_resp here vs. letting it propagate up the call stack (potentially all the way to catch_errors)? Ditto for encrypter and decrypter.","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f18698c31559d2292fc2081f1da54698ff68420","unresolved":false,"context_lines":[{"line_number":123,"context_line":"            km_context \u003d KeyMasterContext(self, *parts[1:])"},{"line_number":124,"context_line":"            try:"},{"line_number":125,"context_line":"                return km_context.handle_request(req, start_response)"},{"line_number":126,"context_line":"            except HTTPException as err_resp:"},{"line_number":127,"context_line":"                return err_resp(env, start_response)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        # anything else"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_f66d46cd","line":126,"in_reply_to":"3aaa91ec_051613a7","updated":"2016-06-28 16:23:06.000000000","message":"IDK. I see other middleware use this pattern so assume it is ok, but I\u0027m not sure if it would be better to propagate the exception. Does WSGI give any guidance?","commit_id":"d15d4c7742604bf644d53a779d65dfd7ec283e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ca38c9d601763d91eb9f5114b343f0f26079d070","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.obj \u003d obj"},{"line_number":47,"context_line":"        self._keys \u003d None"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def fetch_crypto_keys(self):"},{"line_number":50,"context_line":"        \"\"\""},{"line_number":51,"context_line":"        Setup container and object keys based on the request path."},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_3ec5ca3b","line":49,"updated":"2016-06-29 05:10:17.000000000","message":"I still feel like this ought to take (at the very least) a key_id arg, even if just to verify that the version is something we know how to handle.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dbd2a175d788a7a17e48960f5c355b0a1a64080e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_9084c25d","line":85,"updated":"2016-06-28 17:14:12.000000000","message":"re-applying previous comment: I would prefer that we did not insert the object path here. This meta dict gets serialized and written into every user metadata meta header AND every etag sent in container updates, so every container db row will have crypto meta with an object path in it.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ab06b4f8062b73b8763cbf014b64879824111f90","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_d9778039","line":85,"in_reply_to":"3aaa91ec_391b241d","updated":"2016-06-29 06:15:44.000000000","message":"Well.... up to twice (currently). Once for the .data, once for the .meta -- otherwise, we could move an object from gold to silver, post to it, move it from silver to bronze, and find ourselves able to decrypt body or meta but not both (depending on whether we stored that one copy in sysmeta during PUT or transient-sysmeta during POST).\n\nBut I think Alistair was proposing dropping it and never writing it down, in no small part because conditional requests wouldn\u0027t be able to use it. I\u0027m still thinking it over...","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"9b43509aa334a1276097407c3c978045b30e0cea","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_391b241d","line":85,"in_reply_to":"3aaa91ec_9084c25d","updated":"2016-06-29 05:51:25.000000000","message":"Just so that I understand the impacts of the suggestion, there would no longer be a path/key-id string for persisting what key derivation input was used to encrypt? So if later an encrypted object is moved due to tiering, then something in the moving process would need to account for this not being persisted?\n\nOr is that stored somewhere else and I am just not remembering?  I agree we only need this stored once for each object.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_fc716e0d","line":85,"in_reply_to":"3aaa91ec_d9778039","updated":"2016-06-29 17:06:47.000000000","message":"...three times - .data, .meta and container db\n\n(from IRC) \n\"at this point I am ok with leaving it there, because we can always remove it later if it is deemed unnecessary, and worst case some objects and container dbs have unnecessary metadata. \n\nbut for the record, my doubt is based on it not helping fix conditional requests for relocated objects, and it being a relatively large amount of extra metadata.\n\nI will not act unilaterally on it, so it will stay there unless others vote it down.\"","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":11330,"name":"Christian Cachin","email":"cca@zurich.ibm.com","username":"cca88"},"change_message_id":"20a44356e1adfa5df3e6c8a1499e14efe4fb8be9","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        Setup container and object keys based on the request path."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        Keys are derived from request path. The \u0027id\u0027 entry in the results dict"},{"line_number":54,"context_line":"        includes the part of the path used to derived keys. Other keymaster"},{"line_number":55,"context_line":"        implementations may use a different strategy to generate keys and may"},{"line_number":56,"context_line":"        include a different type of \u0027id\u0027, so callers should treat the \u0027id\u0027 as"},{"line_number":57,"context_line":"        opaque keymaster-specific data."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_1b6a60ed","line":54,"range":{"start_line":54,"start_character":52,"end_line":54,"end_character":53},"updated":"2016-06-30 06:54:47.000000000","message":"derive","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        Setup container and object keys based on the request path."},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"        Keys are derived from request path. The \u0027id\u0027 entry in the results dict"},{"line_number":54,"context_line":"        includes the part of the path used to derived keys. Other keymaster"},{"line_number":55,"context_line":"        implementations may use a different strategy to generate keys and may"},{"line_number":56,"context_line":"        include a different type of \u0027id\u0027, so callers should treat the \u0027id\u0027 as"},{"line_number":57,"context_line":"        opaque keymaster-specific data."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_5d2b2782","line":54,"range":{"start_line":54,"start_character":52,"end_line":54,"end_character":53},"in_reply_to":"3aaa91ec_1b6a60ed","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_168075be","line":85,"range":{"start_line":85,"start_character":57,"end_line":85,"end_character":66},"updated":"2016-06-30 07:28:43.000000000","message":"Why base64-encoded? We already know this will be valid utf8 with no surrogate pairs... we should be able to serialize and deserialize just fine.","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            # that particular data or metadata had its keys generated."},{"line_number":83,"context_line":"            # Currently we have no need to do that, so we are simply persisting"},{"line_number":84,"context_line":"            # this information for future use."},{"line_number":85,"context_line":"            self._keys[\u0027id\u0027] \u003d {\u0027v\u0027: \u00271\u0027, \u0027path\u0027: base64.b64encode(path)}"},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_8828af87","line":85,"range":{"start_line":85,"start_character":57,"end_line":85,"end_character":66},"in_reply_to":"3aaa91ec_168075be","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"427109b9d418290cbef1fd7dff198382a0fb23cd","unresolved":false,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"        return self._keys"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def handle_request(self, req, start_response):"},{"line_number":90,"context_line":"        req.environ[CRYPTO_KEY_CALLBACK] \u003d self.fetch_crypto_keys"},{"line_number":91,"context_line":"        resp \u003d self._app_call(req.environ)"},{"line_number":92,"context_line":"        start_response(self._response_status, self._response_headers,"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_7648d9b3","line":89,"range":{"start_line":89,"start_character":29,"end_line":89,"end_character":32},"updated":"2016-06-30 07:28:43.000000000","message":"Really, we only need the environ, yeah?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"swift/common/swob.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c899694d9f8a6e16e32e330dd20834a5b28c94be","unresolved":false,"context_lines":[{"line_number":1419,"context_line":"HTTPCreated \u003d status_map[201]"},{"line_number":1420,"context_line":"HTTPAccepted \u003d status_map[202]"},{"line_number":1421,"context_line":"HTTPNoContent \u003d status_map[204]"},{"line_number":1422,"context_line":"HTTPPartialContent \u003d status_map[206]"},{"line_number":1423,"context_line":"HTTPMovedPermanently \u003d status_map[301]"},{"line_number":1424,"context_line":"HTTPFound \u003d status_map[302]"},{"line_number":1425,"context_line":"HTTPSeeOther \u003d status_map[303]"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_8ea530a3","line":1422,"updated":"2016-07-01 08:14:58.000000000","message":"I\u0027m surprised at we haven\u0027t have a class for 206 PartialContent yet.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"}],"test/unit/common/middleware/crypto/test_crypto.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d7546f8a82b4af46fc4e6d9c894120dd31bb3322","unresolved":false,"context_lines":[{"line_number":22,"context_line":"    def test_filter_factory(self):"},{"line_number":23,"context_line":"        factory \u003d crypto.filter_factory({})"},{"line_number":24,"context_line":"        self.assertTrue(callable(factory))"},{"line_number":25,"context_line":"        self.assertIsInstance(factory({}), crypto.decrypter.Decrypter)"},{"line_number":26,"context_line":"        self.assertIsInstance(factory({}).app, crypto.encrypter.Encrypter)"},{"line_number":27,"context_line":"        self.assertIn(\u0027encryption\u0027, utils._swift_admin_info)"},{"line_number":28,"context_line":"        self.assertDictEqual("}],"source_content_type":"text/x-python","patch_set":14,"id":"3aaa91ec_d0f6c7d5","line":25,"range":{"start_line":25,"start_character":38,"end_line":25,"end_character":40},"updated":"2016-06-30 20:25:28.000000000","message":"Doesn\u0027t much resemble what we\u0027d *expect* factory to be called with, but whatever.\n\nAt some point in the future, we could always do something like\n\n fake_app \u003d object()\n filtered_app \u003d factory(fake_app)\n self.assertIsInstance(filtered_app, crypto.decrypter.Decrypter)\n self.assertIsInstance(filtered_app.app, crypto.encrypter.Encrypter)\n self.assertIs(filtered_app.app.app, fake_app)","commit_id":"306d605fafa35695175280c9e34b6faeb54af16a"}],"test/unit/common/middleware/crypto/test_decrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"615b4ec05c9ed277bdc50a5a16f617116a966028","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            len(enc_body), plaintext_etag, fetch_crypto_keys(), body_key)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        hdrs.update({"},{"line_number":135,"context_line":"            \u0027x-Object-mEta-ignoRes-caSe\u0027: \u0027thIs pArt WilL bE cOol\u0027,"},{"line_number":136,"context_line":"        })"},{"line_number":137,"context_line":"        self.app.register("},{"line_number":138,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, HTTPOk, body\u003denc_body, headers\u003dhdrs)"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_15366f50","line":135,"updated":"2016-07-01 06:40:16.000000000","message":"This won\u0027t do what you think it does. FakeSwift uses HeaderKeyDict already.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"cbe2aa873b45384bdf2f0dbcec30ec600f4135a1","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            len(enc_body), plaintext_etag, fetch_crypto_keys(), body_key)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        hdrs.update({"},{"line_number":135,"context_line":"            \u0027x-Object-mEta-ignoRes-caSe\u0027: \u0027thIs pArt WilL bE cOol\u0027,"},{"line_number":136,"context_line":"        })"},{"line_number":137,"context_line":"        self.app.register("},{"line_number":138,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, HTTPOk, body\u003denc_body, headers\u003dhdrs)"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_55511761","line":135,"in_reply_to":"3aaa91ec_15366f50","updated":"2016-07-01 06:51:41.000000000","message":"that\u0027s *exactly* what I thought it would do?\n\nour backend connection on PUT to storage nodes use HeaderKeyDict already too - that\u0027s the point?  It\u0027d be a different test to check if an object server returned sensitive header keys if we\u0027d muck \u0027em up - but object servers don\u0027t do that because that\u0027s not what it gets sent - so the Fake ignores them too - not on accident?\n\nFWIW, I think they\u0027d be fine tho... If we preserved the case the client sent this title fix would change case on the prefix part:\n\nX-Object-Meta-ignoRes-caSe\n\n... so that\u0027d suck differently?","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1ba0cfc92ebd719c0846f08b16b351e967e6d995","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            len(enc_body), plaintext_etag, fetch_crypto_keys(), body_key)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        hdrs.update({"},{"line_number":135,"context_line":"            \u0027x-Object-mEta-ignoRes-caSe\u0027: \u0027thIs pArt WilL bE cOol\u0027,"},{"line_number":136,"context_line":"        })"},{"line_number":137,"context_line":"        self.app.register("},{"line_number":138,"context_line":"            \u0027GET\u0027, \u0027/v1/a/c/o\u0027, HTTPOk, body\u003denc_body, headers\u003dhdrs)"}],"source_content_type":"text/x-python","patch_set":16,"id":"3aaa91ec_d94b7985","line":135,"in_reply_to":"3aaa91ec_55511761","updated":"2016-07-01 10:10:37.000000000","message":"WFM. Thanks. Using call_application avoid wrapping the response in a swob.Response (which stashes all headers in a case insensitive dict) so see what\u0027s really in the header pairs.","commit_id":"96a0e077532c3227b9290af7d74a0b42ee08e8de"}],"test/unit/common/middleware/crypto_helpers.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"042c155b4863a4d02d81d9a7d30972693669a547","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def fake_get_crypto_meta(**kwargs):"},{"line_number":52,"context_line":"    meta \u003d {\u0027iv\u0027: FAKE_IV, \u0027cipher\u0027: \u0027AES_CTR_256\u0027}"},{"line_number":53,"context_line":"    meta.update(kwargs)"},{"line_number":54,"context_line":"    return meta"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_9d500834","line":52,"range":{"start_line":52,"start_character":38,"end_line":52,"end_character":49},"updated":"2016-06-24 08:14:02.000000000","message":"I think you could still get away with Crypto.cipher if you wanted.","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"769884d2ea9eeb3252e9bda8bf2b16cdd62ac4dd","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def fake_get_crypto_meta(**kwargs):"},{"line_number":52,"context_line":"    meta \u003d {\u0027iv\u0027: FAKE_IV, \u0027cipher\u0027: \u0027AES_CTR_256\u0027}"},{"line_number":53,"context_line":"    meta.update(kwargs)"},{"line_number":54,"context_line":"    return meta"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2c2efd42","line":52,"range":{"start_line":52,"start_character":38,"end_line":52,"end_character":49},"in_reply_to":"3aaa91ec_9d500834","updated":"2016-06-27 09:48:02.000000000","message":"yeah that was a bit over-zealous","commit_id":"6bca16d07add98e21624d8f18fdbe651d579ab8f"}],"test/unit/common/middleware/test_copy.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"94cf0ca4cb7613c3f11e0404a14a42e02462bb74","unresolved":false,"context_lines":[{"line_number":606,"context_line":"        source_headers \u003d {"},{"line_number":607,"context_line":"            \u0027x-object-sysmeta-test1\u0027: \u0027copy me\u0027,"},{"line_number":608,"context_line":"            \u0027x-object-meta-test2\u0027: \u0027copy me too\u0027,"},{"line_number":609,"context_line":"            \u0027x-object-transient-sysmeta-test3\u0027: \u0027ditto\u0027,"},{"line_number":610,"context_line":"            \u0027x-object-sysmeta-container-update-override-etag\u0027: \u0027etag val\u0027,"},{"line_number":611,"context_line":"            \u0027x-object-sysmeta-container-update-override-size\u0027: \u0027size val\u0027,"},{"line_number":612,"context_line":"            \u0027x-object-sysmeta-container-update-override-foo\u0027: \u0027bar\u0027}"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_6c6650bc","line":609,"updated":"2016-06-14 14:19:59.000000000","message":"should be in https://review.openstack.org/#/c/328206","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1a5d4861595705abf7b83db38649b3b998eaf43d","unresolved":false,"context_lines":[{"line_number":606,"context_line":"        source_headers \u003d {"},{"line_number":607,"context_line":"            \u0027x-object-sysmeta-test1\u0027: \u0027copy me\u0027,"},{"line_number":608,"context_line":"            \u0027x-object-meta-test2\u0027: \u0027copy me too\u0027,"},{"line_number":609,"context_line":"            \u0027x-object-transient-sysmeta-test3\u0027: \u0027ditto\u0027,"},{"line_number":610,"context_line":"            \u0027x-object-sysmeta-container-update-override-etag\u0027: \u0027etag val\u0027,"},{"line_number":611,"context_line":"            \u0027x-object-sysmeta-container-update-override-size\u0027: \u0027size val\u0027,"},{"line_number":612,"context_line":"            \u0027x-object-sysmeta-container-update-override-foo\u0027: \u0027bar\u0027}"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_6610b2ac","line":609,"in_reply_to":"7aa08908_6c6650bc","updated":"2016-06-15 18:43:31.000000000","message":"Done","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"}],"test/unit/common/middleware/test_crypto_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"597ef9249a8fd515cfad5d19c974ef02cdb17bde","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                ValueError, self.crypto.create_encryption_ctxt, bad_key, iv)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def test_create_decryption_context(self):"},{"line_number":252,"context_line":"        # TODO: add tests here for non-zero offset"},{"line_number":253,"context_line":"        value \u003d \u0027decrypt me\u0027 * 100  # more than one cipher block"},{"line_number":254,"context_line":"        key \u003d os.urandom(32)"},{"line_number":255,"context_line":"        iv \u003d os.urandom(16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_22f60f8f","line":252,"updated":"2016-06-14 18:37:54.000000000","message":"Dangling TODO.","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"d4cb1447423dd3be7d8d289bfb20dddb1087a41f","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                ValueError, self.crypto.create_encryption_ctxt, bad_key, iv)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def test_create_decryption_context(self):"},{"line_number":252,"context_line":"        # TODO: add tests here for non-zero offset"},{"line_number":253,"context_line":"        value \u003d \u0027decrypt me\u0027 * 100  # more than one cipher block"},{"line_number":254,"context_line":"        key \u003d os.urandom(32)"},{"line_number":255,"context_line":"        iv \u003d os.urandom(16)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7aa08908_e3995b6e","line":252,"in_reply_to":"7aa08908_22f60f8f","updated":"2016-06-15 04:15:31.000000000","message":"This is here as a reminder to pull in https://review.openstack.org/#/c/327028/","commit_id":"ff0272409c202f17929bd34392cf9eb62d0f10ac"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a9d5655a9899b2b646c8410539e57edb1c1475ba","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        self.assertEqual(self.meta, actual)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        actual \u003d crypto_utils.load_crypto_meta(self.serialized_meta_with_key)"},{"line_number":179,"context_line":"        self.assertEqual(self.meta_with_key, actual)"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    def test_dump_then_load_crypto_meta(self):"},{"line_number":182,"context_line":"        actual \u003d crypto_utils.load_crypto_meta("}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_938d2c7e","line":179,"updated":"2016-06-22 00:09:22.000000000","message":"We should add some cases that raise EncryptionException. Nonsense, empty data, valid JSON that isn\u0027t a dict...","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f69ca617f6bcf76a549ffef885c3547765c0158","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        self.assertEqual(self.meta, actual)"},{"line_number":177,"context_line":""},{"line_number":178,"context_line":"        actual \u003d crypto_utils.load_crypto_meta(self.serialized_meta_with_key)"},{"line_number":179,"context_line":"        self.assertEqual(self.meta_with_key, actual)"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"    def test_dump_then_load_crypto_meta(self):"},{"line_number":182,"context_line":"        actual \u003d crypto_utils.load_crypto_meta("}],"source_content_type":"text/x-python","patch_set":7,"id":"3aaa91ec_2b7a80bd","line":179,"in_reply_to":"3aaa91ec_938d2c7e","updated":"2016-06-23 22:49:18.000000000","message":"Done. There\u0027s coverage in test_decrypter but yeah, best to have some direct tests too.","commit_id":"d969fcfa24d332b765cef21a36324791782edd2e"},{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"44c19542d1bcfca8917f92a619d7805d22529fee","unresolved":false,"context_lines":[{"line_number":367,"context_line":"                    1024: str(bytearray.fromhex(\u002700\u0027 * 15 + \u00273f\u0027)),"},{"line_number":368,"context_line":"                    5119: str(bytearray.fromhex(\u002700\u0027 * 14 + \u0027013E\u0027))"},{"line_number":369,"context_line":"                    }"},{"line_number":370,"context_line":"        do_test()"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"    def test_check_key(self):"},{"line_number":373,"context_line":"        for key in (\u0027objKey\u0027, \u0027a\u0027 * 31, \u0027a\u0027 * 33, \u0027a\u0027 * 16, \u0027a\u0027 * 24):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_c98f3273","line":370,"updated":"2016-06-27 04:14:10.000000000","message":"Looks good.  Maybe these tests too to get a couple more iv\u0027s in there:\nhttp://paste.openstack.org/show/523479/","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1781821143edc83a73f4b7a5aca7955bc817d3dd","unresolved":false,"context_lines":[{"line_number":367,"context_line":"                    1024: str(bytearray.fromhex(\u002700\u0027 * 15 + \u00273f\u0027)),"},{"line_number":368,"context_line":"                    5119: str(bytearray.fromhex(\u002700\u0027 * 14 + \u0027013E\u0027))"},{"line_number":369,"context_line":"                    }"},{"line_number":370,"context_line":"        do_test()"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"    def test_check_key(self):"},{"line_number":373,"context_line":"        for key in (\u0027objKey\u0027, \u0027a\u0027 * 31, \u0027a\u0027 * 33, \u0027a\u0027 * 16, \u0027a\u0027 * 24):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_c63546a9","line":370,"in_reply_to":"3aaa91ec_c98f3273","updated":"2016-06-27 13:49:32.000000000","message":"Done, thanks for paste","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"fbc030c9dbb05f79465be8aaa5d25cf60d89475f","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        # For a ranged GET we pass a non-zero offset so that the decrypter"},{"line_number":336,"context_line":"        # counter is incremented to the correct value to start decrypting at"},{"line_number":337,"context_line":"        # that offset into the object body. The counter should increment by"},{"line_number":338,"context_line":"        # from the starting IV value one for every 16 bytes offset into the"},{"line_number":339,"context_line":"        # object body, until it reaches 2^128 -1 when it should wrap to zero."},{"line_number":340,"context_line":"        # We check that is happening by verifying a decrypted value using"},{"line_number":341,"context_line":"        # various offsets."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_a8b679f6","line":338,"updated":"2016-06-29 18:13:54.000000000","message":"\"...should increment by from the starting IV value one...\"\n\nsomething\u0027s off here\n\nShould it be \"...should increment by one from the starting IV value for every...\"?","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":335,"context_line":"        # For a ranged GET we pass a non-zero offset so that the decrypter"},{"line_number":336,"context_line":"        # counter is incremented to the correct value to start decrypting at"},{"line_number":337,"context_line":"        # that offset into the object body. The counter should increment by"},{"line_number":338,"context_line":"        # from the starting IV value one for every 16 bytes offset into the"},{"line_number":339,"context_line":"        # object body, until it reaches 2^128 -1 when it should wrap to zero."},{"line_number":340,"context_line":"        # We check that is happening by verifying a decrypted value using"},{"line_number":341,"context_line":"        # various offsets."}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_eea05b92","line":338,"in_reply_to":"3aaa91ec_a8b679f6","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"fbc030c9dbb05f79465be8aaa5d25cf60d89475f","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        # from the starting IV value one for every 16 bytes offset into the"},{"line_number":339,"context_line":"        # object body, until it reaches 2^128 -1 when it should wrap to zero."},{"line_number":340,"context_line":"        # We check that is happening by verifying a decrypted value using"},{"line_number":341,"context_line":"        # various offsets."},{"line_number":342,"context_line":"        key \u003d \u0027objL7wjV6L79Sfs4y7dy41273l0k6Wki\u0027"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        def do_test():"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_48ef15e9","line":341,"updated":"2016-06-29 18:13:54.000000000","message":"thank you for adding this!","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"54b66b640ddf06d6959886cf8764c669c1f99324","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        # from the starting IV value one for every 16 bytes offset into the"},{"line_number":339,"context_line":"        # object body, until it reaches 2^128 -1 when it should wrap to zero."},{"line_number":340,"context_line":"        # We check that is happening by verifying a decrypted value using"},{"line_number":341,"context_line":"        # various offsets."},{"line_number":342,"context_line":"        key \u003d \u0027objL7wjV6L79Sfs4y7dy41273l0k6Wki\u0027"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        def do_test():"}],"source_content_type":"text/x-python","patch_set":12,"id":"3aaa91ec_2ea703a8","line":341,"in_reply_to":"3aaa91ec_48ef15e9","updated":"2016-06-30 16:40:17.000000000","message":"Done","commit_id":"8a0a0f4d3923468a6bd7398c2363f657b6793299"}],"test/unit/common/middleware/test_decrypter.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0076f387297cda070cddfd178f41524419340f70","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            \u0027encrypt me, too\u0027,"},{"line_number":94,"context_line":"            resp.headers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027])"},{"line_number":95,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta\u0027, resp.headers)"},{"line_number":96,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027, resp.headers)"},{"line_number":97,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Etag\u0027, resp.headers)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _test_412_response(self, method):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_ebb55b7e","line":96,"updated":"2016-06-28 18:09:36.000000000","message":"This particular assertion doesn\u0027t make a whole lot of sense anymore. Sorry, I missed it in the patch I left for you.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":93,"context_line":"            \u0027encrypt me, too\u0027,"},{"line_number":94,"context_line":"            resp.headers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027])"},{"line_number":95,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta\u0027, resp.headers)"},{"line_number":96,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027, resp.headers)"},{"line_number":97,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Etag\u0027, resp.headers)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def _test_412_response(self, method):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_9722c3a1","line":96,"in_reply_to":"3aaa91ec_ebb55b7e","updated":"2016-06-29 17:06:47.000000000","message":"Done. Think I removed them all.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0076f387297cda070cddfd178f41524419340f70","unresolved":false,"context_lines":[{"line_number":197,"context_line":"                \u0027content-type\u0027: \u0027text/plain\u0027,"},{"line_number":198,"context_line":"                \u0027content-length\u0027: len(enc_body),"},{"line_number":199,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Etag\u0027: md5hex(body),"},{"line_number":200,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027: get_crypto_meta_header(),"},{"line_number":201,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Meta\u0027: get_crypto_meta_header(),"},{"line_number":202,"context_line":"                \u0027x-object-meta-test\u0027:"},{"line_number":203,"context_line":"                    base64.b64encode(encrypt(\u0027encrypt me\u0027, key, FAKE_IV)),"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_6b068b21","line":200,"updated":"2016-06-28 18:09:36.000000000","message":"Another X-Object-Sysmeta-Crypto-Meta-Etag I missed.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":197,"context_line":"                \u0027content-type\u0027: \u0027text/plain\u0027,"},{"line_number":198,"context_line":"                \u0027content-length\u0027: len(enc_body),"},{"line_number":199,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Etag\u0027: md5hex(body),"},{"line_number":200,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027: get_crypto_meta_header(),"},{"line_number":201,"context_line":"                \u0027X-Object-Sysmeta-Crypto-Meta\u0027: get_crypto_meta_header(),"},{"line_number":202,"context_line":"                \u0027x-object-meta-test\u0027:"},{"line_number":203,"context_line":"                    base64.b64encode(encrypt(\u0027encrypt me\u0027, key, FAKE_IV)),"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_b706df19","line":200,"in_reply_to":"3aaa91ec_6b068b21","updated":"2016-06-29 17:06:47.000000000","message":"Done","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0076f387297cda070cddfd178f41524419340f70","unresolved":false,"context_lines":[{"line_number":363,"context_line":"            \u0027encrypt me, too\u0027,"},{"line_number":364,"context_line":"            resp.headers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027])"},{"line_number":365,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta\u0027, resp.headers)"},{"line_number":366,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027, resp.headers)"},{"line_number":367,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Etag\u0027, resp.headers)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def _test_req_content_type_not_encrypted(self, method):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_1d090a2d","line":366,"updated":"2016-06-28 18:09:36.000000000","message":"Another X-Object-Sysmeta-Crypto-Meta-Etag I missed.","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f52533c017ccdca261a7e791cd90de1e4be0a11","unresolved":false,"context_lines":[{"line_number":363,"context_line":"            \u0027encrypt me, too\u0027,"},{"line_number":364,"context_line":"            resp.headers[\u0027X-Object-Sysmeta-Container-Update-Override-Etag\u0027])"},{"line_number":365,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta\u0027, resp.headers)"},{"line_number":366,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Meta-Etag\u0027, resp.headers)"},{"line_number":367,"context_line":"        self.assertNotIn(\u0027X-Object-Sysmeta-Crypto-Etag\u0027, resp.headers)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    def _test_req_content_type_not_encrypted(self, method):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_772757b6","line":366,"in_reply_to":"3aaa91ec_1d090a2d","updated":"2016-06-29 17:06:47.000000000","message":"Done","commit_id":"46ed71fd298fd741ad22cbcd635bc8cc7b4473cc"}],"test/unit/common/middleware/test_keymaster.py":[{"author":{"_account_id":12279,"name":"Janie Richling","email":"jrichli@us.ibm.com","username":"jrichli"},"change_message_id":"44c19542d1bcfca8917f92a619d7805d22529fee","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                (\u0027HEAD\u0027, swob.HTTPNoContent, \u0027204\u0027)):"},{"line_number":60,"context_line":"            resp_headers \u003d {}"},{"line_number":61,"context_line":"            if key_id is not None:"},{"line_number":62,"context_line":"                resp_headers.update({\u0027X-Object-Sysmeta-Crypto-Id\u0027: key_id})"},{"line_number":63,"context_line":"            self.swift.register("},{"line_number":64,"context_line":"                method, \u0027/v1\u0027 + path, resp_class, resp_headers, \u0027\u0027)"},{"line_number":65,"context_line":"            req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_335c637c","line":62,"updated":"2016-06-27 04:14:10.000000000","message":"Lines 61 and 62 can be removed.","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1781821143edc83a73f4b7a5aca7955bc817d3dd","unresolved":false,"context_lines":[{"line_number":59,"context_line":"                (\u0027HEAD\u0027, swob.HTTPNoContent, \u0027204\u0027)):"},{"line_number":60,"context_line":"            resp_headers \u003d {}"},{"line_number":61,"context_line":"            if key_id is not None:"},{"line_number":62,"context_line":"                resp_headers.update({\u0027X-Object-Sysmeta-Crypto-Id\u0027: key_id})"},{"line_number":63,"context_line":"            self.swift.register("},{"line_number":64,"context_line":"                method, \u0027/v1\u0027 + path, resp_class, resp_headers, \u0027\u0027)"},{"line_number":65,"context_line":"            req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":9,"id":"3aaa91ec_6672924b","line":62,"in_reply_to":"3aaa91ec_335c637c","updated":"2016-06-27 13:49:32.000000000","message":"Done","commit_id":"45a6ab1a02f9b84a58f929c03b369410d5fe80af"}]}
