diff options
author | Jakub Jelen <jjelen@redhat.com> | 2020-10-30 15:15:19 +0100 |
---|---|---|
committer | Jakub Jelen <jjelen@redhat.com> | 2021-01-04 17:33:22 +0100 |
commit | 4e1e4aebf384d2afcfb958c23f87db26de1495c1 (patch) | |
tree | c1980a7d08559a74e74a228ba8564244d4be8cdd | |
parent | 371b8841032a5c6db2c97c1aec9e3428a063209e (diff) |
tests: Implement decipher test to execute missing use case
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r-- | tests/common.c | 81 | ||||
-rw-r--r-- | tests/common.h | 2 | ||||
-rw-r--r-- | tests/db.crypt | bin | 0 -> 256 bytes | |||
-rw-r--r-- | tests/hwtests.c | 28 | ||||
-rw-r--r-- | tests/libcacard.c | 18 | ||||
-rwxr-xr-x | tests/setup-softhsm2.sh | 5 |
6 files changed, 134 insertions, 0 deletions
diff --git a/tests/common.c b/tests/common.c index ef34d94..e5bc3e2 100644 --- a/tests/common.c +++ b/tests/common.c @@ -562,6 +562,87 @@ void do_sign(VReader *reader, int parts) } +void do_decipher(VReader *reader) +{ + VReaderStatus status; + int dwRecvLength = APDUBufSize; + uint8_t pbRecvBuffer[APDUBufSize]; + uint8_t apdu[7 + 256] = { + /* DECRYPT [p1,p2=0 ] [Lc ] */ + 0x80, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, + /* [2048b keys: 256 bytes of encrypted data to be filled by the following code ] */ + }; + int apdu_len = sizeof(apdu); + uint8_t getresp[] = { + /* Get Response (max we can get) */ + 0x00, 0xc0, 0x00, 0x00, 0x00 + }; + uint8_t cleartext[] = "1234567890\n"; + int cleartext_len = sizeof(cleartext) - 1; + gchar *filename = NULL; + gchar *ciphertext = NULL; + gsize ciphertext_len = 0; + g_assert_nonnull(reader); + + /* To decipher, we need some sensible data encrypted using public key + * (done in setup-softhsm.sh) */ + + /* Read the encrypted file */ + if (hw_tests) { + filename = g_test_build_filename(G_TEST_BUILT, "01.crypt", NULL); + } else { + /* Generated from existing db using: + * echo "1234567890" > data + * certutil -L -d sql:$PWD/tests/db/ -n cert1 -r > tests/db.cert + * openssl rsautl -encrypt -inkey "tests/db.cert" -keyform DER -certin -in data -out "tests/db.crypt" + */ + filename = g_test_build_filename(G_TEST_DIST, "db.crypt", NULL); + } + if (!g_file_get_contents(filename, &ciphertext, &ciphertext_len, NULL)) { + g_test_skip("The encrypted file not found"); + g_free(filename); + return; + } + g_free(filename); + + /* Adjust the place where to store the read ciphertext */ + if (key_bits && key_bits < 2048) { + apdu[4] = key_bits/8; /* less than 2048b will fit the length into one byte */ + apdu_len = 5 + key_bits/8; + memcpy(&apdu[5], ciphertext, ciphertext_len); + } else { + /* This might be an issue for even larger keys than 2k */ + assert(ciphertext_len < (size_t) apdu_len + 7); + memcpy(&apdu[7], ciphertext, ciphertext_len); + } + g_free(ciphertext); + + dwRecvLength = APDUBufSize; + status = vreader_xfr_bytes(reader, + apdu, apdu_len, + pbRecvBuffer, &dwRecvLength); + g_assert_cmpint(status, ==, VREADER_OK); + g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES); + g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, (unsigned char) (key_bits/8)); + + /* fetch the actual response */ + dwRecvLength = APDUBufSize; + status = vreader_xfr_bytes(reader, + getresp, sizeof(getresp), + pbRecvBuffer, &dwRecvLength); + g_assert_cmpint(status, ==, VREADER_OK); + g_assert_cmpint(dwRecvLength, ==, key_bits/8+2); + g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS); + g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00); + /* Compare the actual deciphered data */ + g_assert_cmphex(pbRecvBuffer[0], ==, 0x00); /* Padding bytes */ + g_assert_cmphex(pbRecvBuffer[1], ==, 0x02); + g_assert_cmphex(pbRecvBuffer[dwRecvLength - 2 - cleartext_len - 1], ==, 0x00); + g_assert_cmpmem(&pbRecvBuffer[dwRecvLength - 2 - cleartext_len], cleartext_len, + cleartext, cleartext_len); + +} + void test_empty_applets(void) { uint8_t applet_02fb[] = { diff --git a/tests/common.h b/tests/common.h index f59a91b..db217b4 100644 --- a/tests/common.h +++ b/tests/common.h @@ -40,6 +40,8 @@ void read_buffer(VReader *reader, uint8_t type, int object_type); void do_sign(VReader *reader, int parts); +void do_decipher(VReader *reader); + void test_empty_applets(void); void test_get_response(void); diff --git a/tests/db.crypt b/tests/db.crypt Binary files differnew file mode 100644 index 0000000..f37331d --- /dev/null +++ b/tests/db.crypt diff --git a/tests/hwtests.c b/tests/hwtests.c index e5fec72..3684642 100644 --- a/tests/hwtests.c +++ b/tests/hwtests.c @@ -259,6 +259,33 @@ static void test_sign(void) vreader_free(reader); /* get by id ref */ } +static void test_decipher(void) +{ + VReader *reader = vreader_get_reader_by_id(0); + + /* Skip the HW tests without physical card */ + if (vreader_card_is_present(reader) != VREADER_OK) { + vreader_free(reader); + g_test_skip("No physical card found"); + return; + } + + /* select the ACA */ + select_applet(reader, TEST_ACA); + + do_login(reader); + + /* select the PKI */ + select_applet(reader, TEST_PKI); + + /* get properties to figure out the key length */ + get_properties(reader, TEST_PKI); + + do_decipher(reader); + + vreader_free(reader); /* get by id ref */ +} + /* Try to pass bad formatted PKCS#1.5 data and make sure the libcacard does not * crash while handling them */ @@ -397,6 +424,7 @@ int main(int argc, char *argv[]) g_test_add_func("/hw-tests/login", test_login); g_test_add_func("/hw-tests/sign", test_sign); g_test_add_func("/hw-tests/sign-bad-data", test_sign_bad_data_x509); + g_test_add_func("/hw-tests/decipher", test_decipher); g_test_add_func("/hw-tests/empty-applets", test_empty_applets); g_test_add_func("/hw-tests/get-response", test_get_response); g_test_add_func("/hw-tests/sign-logout-sign", test_sign_logout_sign); diff --git a/tests/libcacard.c b/tests/libcacard.c index 25642fc..5328ace 100644 --- a/tests/libcacard.c +++ b/tests/libcacard.c @@ -582,6 +582,23 @@ static void test_sign(void) vreader_free(reader); /* get by id ref */ } +static void test_decipher(void) +{ + VReader *reader = vreader_get_reader_by_id(0); + + /* select the ACA */ + select_applet(reader, TEST_ACA); + + do_login(reader); + + /* select the PKI */ + select_applet(reader, TEST_PKI); + + do_decipher(reader); + + vreader_free(reader); /* get by id ref */ +} + static void test_remove(void) { VReader *reader = vreader_get_reader_by_id(0); @@ -1111,6 +1128,7 @@ int main(int argc, char *argv[]) g_test_add_func("/libcacard/check-login-count", check_login_count); g_test_add_func("/libcacard/login", test_login); g_test_add_func("/libcacard/sign", test_sign); + g_test_add_func("/libcacard/decipher", test_decipher); g_test_add_func("/libcacard/empty-applets", test_empty_applets); g_test_add_func("/libcacard/gp-applet", test_gp_applet); g_test_add_func("/libcacard/msft-applet", test_msft_applet); diff --git a/tests/setup-softhsm2.sh b/tests/setup-softhsm2.sh index 32c49ca..c3874e5 100755 --- a/tests/setup-softhsm2.sh +++ b/tests/setup-softhsm2.sh @@ -53,6 +53,11 @@ generate_cert() { pkcs11-tool --write-object "$TYPE.cert.der" --type=cert --id=$ID \ --label="$LABEL" --module="$P11LIB" + # Encrypt some data using the public key (its pain to do it in the tests) + echo "1234567890" > data + openssl rsautl -encrypt -inkey "$TYPE.cert" -certin -in data -out "$ID.crypt" + rm data + rm "$TYPE.cert" "$TYPE.cert.der" p11tool --login --provider="$P11LIB" --list-all |