From 10a62ec99e2839f0fb163d38f37fa09e9f7b6c1c Mon Sep 17 00:00:00 2001 From: Jackie Truong Date: Thu, 4 May 2017 12:51:22 -0400 Subject: [PATCH] Fix decoding of encryption key passed to dmcrypt This patch fixes the decoding of the encryption key passed to dmcrypt. During the key management move from Nova to Castellan, in the Newton release, conversion of the encryption key (from a string to list of unsigned ints) was removed from the key retrieval method. This patch updates dmcrypt to decode an encryption key string, rather than a list of unsigned ints. See the linked bug for more information. The method used to decode the encryption key has been updated to use binascii, as done in os-brick [1], to maintain consistency. The key generation and decoding portions of test_dmcrypt have been updated to reflect this change and ensure compatibility with both, Python 2 and Python 3. [1] https://github.com/openstack/os-brick/blob/6cf9b1cd689f70a2c50c0fa83a9a9f7c502712a1/os_brick/encryptors/cryptsetup.py#L100-L102 Closes-Bug: #1688342 Change-Id: I050585ecb55742a972038cf72b0650321ded2856 (cherry picked from commit 53a71c1241aac70018c16d174032427a172378ed) --- nova/tests/unit/virt/libvirt/storage/test_dmcrypt.py | 5 +++-- nova/virt/libvirt/storage/dmcrypt.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/storage/test_dmcrypt.py b/nova/tests/unit/virt/libvirt/storage/test_dmcrypt.py index 93c4f771d81a..0652934c50e5 100644 --- a/nova/tests/unit/virt/libvirt/storage/test_dmcrypt.py +++ b/nova/tests/unit/virt/libvirt/storage/test_dmcrypt.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +import binascii import mock from oslo_concurrency import processutils @@ -30,8 +31,8 @@ class LibvirtDmcryptTestCase(test.NoDBTestCase): self.NAME = 'disk' self.TARGET = dmcrypt.volume_name(self.NAME) self.PATH = '/dev/nova-lvm/instance_disk' - self.KEY = range(0, self.KEY_SIZE) - self.KEY_STR = ''.join(["%02x" % x for x in range(0, self.KEY_SIZE)]) + self.KEY = bytes(bytearray(x for x in range(0, self.KEY_SIZE))) + self.KEY_STR = binascii.hexlify(self.KEY).decode('utf-8') @mock.patch('nova.utils.execute') def test_create_volume(self, mock_execute): diff --git a/nova/virt/libvirt/storage/dmcrypt.py b/nova/virt/libvirt/storage/dmcrypt.py index cb82a06a0720..7b21de7ab3eb 100644 --- a/nova/virt/libvirt/storage/dmcrypt.py +++ b/nova/virt/libvirt/storage/dmcrypt.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +import binascii import os from oslo_concurrency import processutils @@ -52,7 +53,7 @@ def create_volume(target, device, cipher, key_size, key): :param device: underlying block device :param cipher: encryption cipher string digestible by cryptsetup :param key_size: encryption key size - :param key: encryption key as an array of unsigned bytes + :param key: encoded encryption key bytestring """ cmd = ('cryptsetup', 'create', @@ -61,7 +62,7 @@ def create_volume(target, device, cipher, key_size, key): '--cipher=' + cipher, '--key-size=' + str(key_size), '--key-file=-') - key = ''.join(map(lambda byte: "%02x" % byte, key)) + key = binascii.hexlify(key).decode('utf-8') try: utils.execute(*cmd, process_input=key, run_as_root=True) except processutils.ProcessExecutionError as e: