[Spice-devel] [PATCH libcacard v2 26/35] tests: Make sure we do not crash on bad data to sign

Jakub Jelen jjelen at redhat.com
Thu Aug 2 09:43:58 UTC 2018


 * This includes also the key bits discovery in test suite.

Signed-off-by: Jakub Jelen <jjelen at redhat.com>
Reviewed-by: Robert Relyea <rrelyea at redhat.com>
---
 tests/common.c  |  6 ++++
 tests/common.h  |  2 ++
 tests/hwtests.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/tests/common.c b/tests/common.c
index 34d411f..40e5525 100644
--- a/tests/common.c
+++ b/tests/common.c
@@ -633,5 +633,11 @@ setHWTests(int new_value)
     hw_tests = new_value;
 }
 
+int
+getBits(void)
+{
+    return key_bits;
+}
+
 
 /* vim: set ts=4 sw=4 tw=0 noet expandtab: */
diff --git a/tests/common.h b/tests/common.h
index 0c19ff8..21144a1 100644
--- a/tests/common.h
+++ b/tests/common.h
@@ -44,4 +44,6 @@ void test_get_response(void);
 int isHWTests(void);
 void setHWTests(int);
 
+int getBits(void);
+
 #endif /* _TESTS_COMMON */
diff --git a/tests/hwtests.c b/tests/hwtests.c
index 7beebac..bd8e439 100644
--- a/tests/hwtests.c
+++ b/tests/hwtests.c
@@ -268,6 +268,85 @@ static void test_get_response_hw(void) {
     test_get_response();
 }
 
+/* Try to pass bad formatted PKCS#1.5 data and make sure the libcacard does not
+ * crash while handling them
+ */
+static void test_sign_bad_data_x509(void)
+{
+    VReader *reader = vreader_get_reader_by_id(0);
+    VReaderStatus status;
+    int dwRecvLength = APDUBufSize;
+    uint8_t pbRecvBuffer[APDUBufSize];
+    uint8_t sign[] = {
+        /* VERIFY   [p1,p2=0 ]  [Lc            ] [2048b keys: 256 bytes of non PKCS#1.5 data] */
+        0x80, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+/*      ^--- the second byte of data should be 0x01 for signatures */
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0x00, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x20,
+0x28, 0x6d, 0x61, 0x78, 0x20, 0x31, 0x30, 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x29, 0x0a,
+0x00 /* <-- [Le] */
+    };
+    int sign_len = sizeof(sign);
+    int key_bits = getBits();
+
+    g_assert_nonnull(reader);
+
+    /* 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;
+    }
+
+    /* run the actual test */
+
+    key_bits = getBits();
+    /* Adjust the buffers to match the key lengths, if already retrieved */
+    if (key_bits && key_bits < 2048) {
+        sign[4] = key_bits/8; /* less than 2048b will fit the length into one byte */
+        sign[5] = 0x00;
+        /*sign[6] = 0x01; <- this should be 0x01 for PKCS#1.5 signatures */
+        memcpy(&sign[6], &sign[sign_len-key_bits/8 + 3], key_bits/8 - 1);
+        sign_len = 5 + key_bits/8 + 1;
+        sign[sign_len-1] = 0x00; /* [Le] */
+    }
+
+    dwRecvLength = APDUBufSize;
+    status = vreader_xfr_bytes(reader,
+                               sign, sign_len,
+                               pbRecvBuffer, &dwRecvLength);
+    g_assert_cmpint(status, ==, VREADER_OK);
+    /* We expect one of the following results:
+     *  * VCARD7816_STATUS_ERROR_DATA_INVALID: Invalid data
+     *  * VCARD7816_STATUS_SUCCESS: Properly signed data
+     *
+     * we should not crash as with 2.5.3
+     */
+    if (pbRecvBuffer[dwRecvLength-2] == VCARD7816_SW1_SUCCESS) {
+        g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+        g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+    } else {
+        g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_COMMAND_ERROR);
+        g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x84);
+    }
+
+    /* no need to fetch the actual response */
+    vreader_free(reader); /* get by id ref */
+}
+
 static void libcacard_finalize(void)
 {
     VReader *reader = vreader_get_reader_by_id(0);
@@ -297,6 +376,7 @@ int main(int argc, char *argv[])
     g_test_add_func("/hw-tests/passthrough-applet", test_passthrough_applets);
     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/empty-applets", test_empty_applets_hw);
     g_test_add_func("/hw-tests/get-response", test_get_response_hw);
 
-- 
2.17.1



More information about the Spice-devel mailing list