From c1bfb597bcc24179f1d343f6e8380f4a64beff07 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 9 Mar 2023 20:10:25 +0100 Subject: [PATCH] Added first tests of key wrapping. Signed-off-by: Pol Henarejos --- tests/conftest.py | 22 +++++++--- tests/pico-hsm/test_025_key_export.py | 62 +++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 tests/pico-hsm/test_025_key_export.py diff --git a/tests/conftest.py b/tests/conftest.py index 6dea18a..c191a53 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -105,12 +105,12 @@ class Device: if (sw1 != 0x90): if (sw1 == 0x63 and sw2 & 0xF0 == 0xC0): pass - elif (code == 0x6A82): - self.select_applet() - if (sw1 == 0x90): - response, sw1, sw2 = self.__card.connection.transmit(apdu) - if (sw1 == 0x90): - return response + # elif (code == 0x6A82): + # self.select_applet() + # if (sw1 == 0x90): + # response, sw1, sw2 = self.__card.connection.transmit(apdu) + # if (sw1 == 0x90): + # return response elif (code == 0x6982): response, sw1, sw2 = self.__card.connection.transmit([0x00, 0x20, 0x00, 0x81, len(self.__pin)] + list(self.__pin.encode()) + [0x0]) if (sw1 == 0x90): @@ -250,6 +250,12 @@ class Device: resp = self.get_contents(p1=p1 >> 8, p2=p1 & 0xff) return bytes(resp) + def put_contents(self, p1, p2=None, data=None): + if (p2): + self.send(command=0xD7, p1=p1, p2=p2, data=[0x54, 0x02, 0x00, 0x00, 0x53, len(data) if data else 0] + list(data) if data else []) + else: + self.put_contents(p1=p1 >> 8, p2=p1 & 0xff, data=data) + def public_key(self, keyid, param=None): response = self.get_contents(p1=DOPrefixes.EE_CERTIFICATE_PREFIX.value, p2=keyid) @@ -396,6 +402,10 @@ class Device: _ = self.send(cla=0x80, command=0x74, p1=p1, p2=0x93, data=data) return p1 + def export_key(self, keyid): + resp = self.send(cla=0x80, command=0x72, p1=keyid, p2=0x92) + return resp + def exchange(self, keyid, pubkey): resp = self.send(cla=0x80, command=0x62, p1=keyid, p2=Algorithm.ALGO_EC_ECDH.value, data=pubkey.public_bytes(Encoding.X962, PublicFormat.UncompressedPoint)) return resp diff --git a/tests/pico-hsm/test_025_key_export.py b/tests/pico-hsm/test_025_key_export.py new file mode 100644 index 0000000..b22b165 --- /dev/null +++ b/tests/pico-hsm/test_025_key_export.py @@ -0,0 +1,62 @@ +""" +/* + * This file is part of the Pico HSM distribution (https://github.com/polhenarejos/pico-hsm). + * Copyright (c) 2023 Pol Henarejos. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +""" + +import pytest +from utils import KeyType, DOPrefixes, APDUResponse, SWCodes +from const import DEFAULT_DKEK + +def test_initialize(device): + device.initialize(key_domains=1) + assert(device.get_key_domains() == 1) + + device.set_key_domain(key_domain=0, total=1) + +keyid_in = -1 +keyid_out = -1 +def test_key_generation_no_key_domain(device): + global keyid_out + keyid_out = device.key_generation(KeyType.ECC, 'brainpoolP256r1') + device.put_contents(p1=DOPrefixes.PRKD_PREFIX.value, p2=keyid_out, data=[0xA0]) + resp = device.list_keys() + assert((DOPrefixes.KEY_PREFIX.value, keyid_out) in resp) + assert((DOPrefixes.PRKD_PREFIX.value, keyid_out) in resp) + +def test_key_generation_with_key_domain(device): + global keyid_in + keyid_in = device.key_generation(KeyType.ECC, 'brainpoolP256r1', key_domain=0) + device.put_contents(p1=DOPrefixes.PRKD_PREFIX.value, p2=keyid_in, data=[0xA0]) + resp = device.list_keys() + assert((DOPrefixes.KEY_PREFIX.value, keyid_in) in resp) + assert((DOPrefixes.PRKD_PREFIX.value, keyid_in) in resp) + +def test_export_key_out(device): + with pytest.raises(APDUResponse) as e: + device.export_key(keyid_out) + assert(e.value.sw == SWCodes.SW_REFERENCE_NOT_FOUND.value) + +def test_export_key_in_fail(device): + with pytest.raises(APDUResponse) as e: + device.export_key(keyid_in) + assert(e.value.sw == SWCodes.SW_REFERENCE_NOT_FOUND.value) + +def test_export_import_dkek(device): + resp = device.import_dkek(DEFAULT_DKEK, key_domain=0) + +def test_export_key_in_ok(device): + resp = device.export_key(2)