[Spice-devel] [PATCH libcacard 32/45] tests: Create separate hardware tests
Jakub Jelen
jjelen at redhat.com
Tue Jul 31 14:50:26 UTC 2018
* These tests are supposed to run against existing CAC card
connected to local computer, which should be presenting
certificates with 1024 b keys.
* These tests are skipped in case there is no card available.
* This also extends the existing testsuite with tests for
various empty applets
* The NSS DB needs to be created under tests/hwdb/ and local
pkcs#11 module needs to be added to the database
Signed-off-by: Jakub Jelen <jjelen at redhat.com>
Reviewed-by: Robert Relyea <rrelyea at redhat.com>
---
Makefile.am | 10 +-
docs/libcacard.txt | 1 +
tests/common.c | 504 +++++++++++++++++++++++++++++++++++++++++++++
tests/common.h | 42 ++++
tests/hwtests.c | 273 ++++++++++++++++++++++++
tests/libcacard.c | 399 ++---------------------------------
6 files changed, 843 insertions(+), 386 deletions(-)
create mode 100644 tests/common.c
create mode 100644 tests/common.h
create mode 100644 tests/hwtests.c
diff --git a/Makefile.am b/Makefile.am
index af99a33..2a9b59d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -74,12 +74,20 @@ include $(srcdir)/build-aux/glib-tap.mk
test_programs = \
tests/simpletlv \
+ tests/hwtests \
tests/libcacard
-tests_libcacard_SOURCES = tests/libcacard.c
+tests_libcacard_SOURCES = tests/common.c \
+ tests/libcacard.c
tests_libcacard_LDADD = libcacard.la \
src/common.lo \
src/simpletlv.lo \
$(GTHREAD_LIBS)
+tests_hwtests_SOURCES = tests/common.c \
+ tests/hwtests.c
+tests_hwtests_LDADD = libcacard.la \
+ src/common.lo \
+ src/simpletlv.lo \
+ $(GTHREAD_LIBS)
tests_simpletlv_LDADD = src/common.lo \
src/simpletlv.lo \
$(GTHREAD_LIBS)
diff --git a/docs/libcacard.txt b/docs/libcacard.txt
index f421054..405eed9 100644
--- a/docs/libcacard.txt
+++ b/docs/libcacard.txt
@@ -500,4 +500,5 @@ src/simpletlv.c - Simple TLV encoding functions
src/simpletlv.h - header file for Simple TLV encoding helpers
tests/libcacard.c - Test for the whole smart card emulation
tests/simpletlv.c - Unit tests for SimpleTLV encoding and decoding functions
+tests/hwtests.c - Tests intended to be ran against real card if available
diff --git a/tests/common.c b/tests/common.c
new file mode 100644
index 0000000..fdd44aa
--- /dev/null
+++ b/tests/common.c
@@ -0,0 +1,504 @@
+/*
+ * Shared test functions for libCACard
+ *
+ * Copyright 2018 Red Hat, Inc.
+ *
+ * Author: Jakub Jelen <jjelen at redhat.com>
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include <glib.h>
+#include <string.h>
+
+#include "common.h"
+#include "simpletlv.h"
+
+int key_bits = 0;
+int hw_tests = 0;
+
+
+void select_aid(VReader *reader, unsigned char *aid, unsigned int aid_len)
+{
+ VReaderStatus status;
+ int dwRecvLength = APDUBufSize;
+ uint8_t pbRecvBuffer[APDUBufSize];
+ uint8_t selfile[] = {
+ 0x00, 0xa4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00
+ };
+ size_t selfile_len = sizeof(selfile);
+
+ g_assert_cmpint(aid_len, ==, 7);
+ memcpy(&selfile[5], aid, aid_len);
+
+ g_debug("%s: Add applet with AID 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
+ __func__, aid[0], aid[1], aid[2], aid[3], aid[4], aid[5], aid[6]);
+ g_assert_nonnull(reader);
+ status = vreader_xfr_bytes(reader,
+ selfile, selfile_len,
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+}
+
+void get_properties_coid(VReader *reader, const unsigned char coid[2],
+ int object_type)
+{
+ int dwRecvLength = APDUBufSize;
+ VReaderStatus status;
+ uint8_t pbRecvBuffer[APDUBufSize], *p, *p_end, *p2, *p2_end;
+ uint8_t get_properties[] = {
+ /* Get properties */
+ 0x80, 0x56, 0x01, 0x00, 0x00
+ };
+ uint8_t get_properties_tag[] = {
+ /* Get properties [tag list] */
+ 0x80, 0x56, 0x02, 0x00, 0x02, 0x01, 0x01, 0x00
+ };
+ int verified_pki_properties = 0;
+ int num_objects = 0, num_objects_expected = -1;
+ int have_applet_information = 0;
+
+ status = vreader_xfr_bytes(reader,
+ get_properties, sizeof(get_properties),
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmpint(dwRecvLength, >, 2);
+ g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+
+ /* try to parse the response, if it makes sense */
+ p = pbRecvBuffer;
+ p_end = p + dwRecvLength - 2;
+ while (p < p_end) {
+ uint8_t tag;
+ size_t vlen;
+ if (simpletlv_read_tag(&p, p_end - p, &tag, &vlen) < 0) {
+ g_debug("The generated SimpleTLV can not be parsed");
+ g_assert_not_reached();
+ }
+ g_debug("Tag: 0x%02x, Len: %lu", tag, vlen);
+ g_assert_cmpint(vlen, <=, p_end - p);
+
+ switch (tag) {
+ case 0x01: /* Applet Information */
+ g_assert_cmpint(vlen, ==, 5);
+ g_assert_cmphex(*p, ==, 0x10); /* Applet family */
+ have_applet_information = 1;
+ break;
+
+ case 0x40: /* Number of objects */
+ g_assert_cmpint(vlen, ==, 1);
+ if (num_objects_expected != -1) {
+ g_debug("Received multiple number-of-objects tags");
+ g_assert_not_reached();
+ }
+ num_objects_expected = *p;
+ break;
+
+ case 0x50: /* TV Object */
+ case 0x51: /* PKI Object */
+ /* recursive SimpleTLV structure */
+ p2 = p;
+ p2_end = p + vlen;
+ while (p2 < p2_end) {
+ uint8_t tag2;
+ size_t vlen2;
+ if (simpletlv_read_tag(&p2, p2_end - p2, &tag2, &vlen2) < 0) {
+ g_debug("The generated SimpleTLV can not be parsed");
+ g_assert_not_reached();
+ }
+ g_assert_cmpint(vlen2, <=, p2_end - p2);
+ g_debug(" Tag: 0x%02x, Len: %lu", tag2, vlen2);
+
+ switch (tag2) {
+ case 0x41: /* Object ID */
+ g_assert_cmpmem(p2, vlen2, coid, 2);
+ break;
+
+ case 0x42: /* Buffer properties */
+ g_assert_cmpint(vlen2, ==, 5);
+ if (object_type != TEST_EMPTY_BUFFER)
+ g_assert_cmpint(p2[0], ==, 0x00);
+ break;
+
+ case 0x43: /* PKI properties */
+ g_assert_cmphex(p2[0], ==, 0x06);
+ if (hw_tests) {
+ /* Assuming CAC card with 1024 b RSA keys */
+ key_bits = 1024;
+ } else {
+ /* Assuming 2048 b RSA keys */
+ key_bits = 2048;
+ }
+ g_assert_cmphex(p2[1], ==, (key_bits / 8 / 8));
+ g_assert_cmphex(p2[2], ==, 0x01);
+ g_assert_cmphex(p2[3], ==, 0x01);
+ verified_pki_properties = 1;
+ break;
+
+ default:
+ g_debug("Unknown tag in object: 0x%02x", tag2);
+ g_assert_not_reached();
+ }
+ p2 += vlen2;
+ }
+ /* one more object processed */
+ num_objects++;
+ break;
+ default:
+ g_debug("Unknown tag in properties buffer: 0x%02x", tag);
+ g_assert_not_reached();
+ }
+ p += vlen;
+ }
+
+ if (num_objects_expected != -1) {
+ g_assert_cmpint(num_objects, ==, num_objects_expected);
+ }
+
+ if (object_type == TEST_EMPTY_BUFFER) {
+ g_assert_cmpint(num_objects_expected, ==, 1);
+ }
+
+ if (object_type == TEST_EMPTY) {
+ g_assert_cmpint(num_objects_expected, ==, 0);
+ }
+
+ if (object_type == TEST_PKI) {
+ g_assert_cmpint(verified_pki_properties, ==, 1);
+ }
+
+ g_assert_cmpint(have_applet_information, ==, 1);
+
+ /* Try to list only some properties */
+ dwRecvLength = APDUBufSize;
+ status = vreader_xfr_bytes(reader,
+ get_properties_tag, sizeof(get_properties_tag),
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmpint(dwRecvLength, ==, 16); /* Two applet information buffers + status */
+ g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+}
+
+void get_properties(VReader *reader, int object_type)
+{
+ unsigned char coid[2];
+ switch (object_type) {
+ case TEST_PKI:
+ // XXX only the first PKI for now
+ coid[0] = 0x01;
+ coid[1] = 0x00;
+ get_properties_coid(reader, coid, object_type);
+ break;
+
+ case TEST_CCC:
+ coid[0] = 0xDB;
+ coid[1] = 0x00;
+ get_properties_coid(reader, coid, object_type);
+ break;
+
+ case TEST_ACA:
+ coid[0] = 0x03;
+ coid[1] = 0x00;
+ get_properties_coid(reader, coid, object_type);
+ break;
+
+ default:
+ g_debug("Got unknown object type");
+ g_assert_not_reached();
+ }
+}
+
+void read_buffer(VReader *reader, uint8_t type, int object_type)
+{
+ int dwRecvLength = APDUBufSize, dwLength, dwReadLength, offset;
+ VReaderStatus status;
+ uint8_t pbRecvBuffer[APDUBufSize];
+ uint8_t *data;
+ uint8_t read_buffer[] = {
+ /*Read Buffer OFFSET TYPE LENGTH a_Le */
+ 0x80, 0x52, 0x00, 0x00, 0x02, 0x01, 0x02, 0x02
+ };
+ int card_urls = 0;
+
+ dwRecvLength = 4;
+ read_buffer[5] = type;
+ status = vreader_xfr_bytes(reader,
+ read_buffer, sizeof(read_buffer),
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmpint(dwRecvLength, ==, 4);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+
+ dwLength = (pbRecvBuffer[0] & 0xff) | ((pbRecvBuffer[1] << 8) & 0xff);
+ if (object_type != TEST_EMPTY_BUFFER)
+ g_assert_cmpint(dwLength, !=, 0);
+ if (dwLength == 0)
+ return;
+
+ data = g_malloc(dwLength);
+ offset = 0x02;
+ do {
+ dwReadLength = MIN(255, dwLength);
+ dwRecvLength = dwReadLength+2;
+ read_buffer[2] = (unsigned char) ((offset >> 8) & 0xff);
+ read_buffer[3] = (unsigned char) (offset & 0xff);
+ read_buffer[6] = (unsigned char) (dwReadLength);
+ read_buffer[7] = (unsigned char) (dwReadLength);
+ status = vreader_xfr_bytes(reader,
+ read_buffer, sizeof(read_buffer),
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmpint(dwRecvLength, ==, dwReadLength + 2);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
+
+ memcpy(data + offset - 2, pbRecvBuffer, dwReadLength - 2);
+ offset += dwLength;
+ dwLength -= dwReadLength;
+ } while (dwLength != 0);
+
+ /* Try to parse the TAG buffer, if it makes sense */
+ if (type == CAC_FILE_TAG) {
+ uint8_t *p = data;
+ uint8_t *p_end = p + offset - 2;
+ while (p < p_end) {
+ uint8_t tag;
+ size_t vlen;
+ if (simpletlv_read_tag(&p, p_end - p, &tag, &vlen) < 0) {
+ g_debug("The generated SimpleTLV can not be parsed");
+ g_assert_not_reached();
+ }
+ g_debug("Tag: 0x%02x, Len: %lu", tag, vlen);
+
+ switch (tag) {
+ case 0xF3: /* CardURL from CCC */
+ if (object_type == TEST_CCC) {
+ card_urls++;
+ } else {
+ g_debug("CardURLs found outside of CCC buffer");
+ g_assert_not_reached();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (object_type == TEST_CCC)
+ g_assert_cmpint(card_urls, ==, 11 + 3);
+ }
+ g_free(data);
+}
+
+void select_applet(VReader *reader, int type)
+{
+ uint8_t selfile_ccc[] = {
+ /* Select CCC Applet */
+ 0xa0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00
+ };
+ uint8_t selfile_aca[] = {
+ /* Select ACA Applet */
+ 0xa0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00
+ };
+ uint8_t selfile_pki[] = {
+ /* Select first PKI Applet */
+ 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00
+ };
+ uint8_t *aid = NULL;
+ size_t aid_len = 0;
+
+ switch (type) {
+ case TEST_PKI:
+ aid = selfile_pki;
+ aid_len = sizeof(selfile_pki);
+ break;
+
+ case TEST_CCC:
+ aid = selfile_ccc;
+ aid_len = sizeof(selfile_ccc);
+ break;
+
+ case TEST_ACA:
+ aid = selfile_aca;
+ aid_len = sizeof(selfile_aca);
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+ g_assert_nonnull(aid);
+
+ select_aid(reader, aid, aid_len);
+}
+
+void do_sign(VReader *reader)
+{
+ VReaderStatus status;
+ int dwRecvLength = APDUBufSize;
+ uint8_t pbRecvBuffer[APDUBufSize];
+ uint8_t sign[] = {
+ /* VERIFY [p1,p2=0 ] [Lc ] [2048b keys: 256 bytes of PKCS#1.5 padded data] */
+ 0x80, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x00, 0x01, 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, 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
+ };
+ int sign_len = sizeof(sign);
+ uint8_t getresp[] = {
+ /* Get Response (max we can get) */
+ 0x00, 0xc0, 0x00, 0x00, 0x00
+ };
+ g_assert_nonnull(reader);
+
+ /* 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;
+ memcpy(&sign[7], &sign[sign_len-key_bits/8+2], key_bits/8-2);
+ sign_len = 5 + key_bits/8;
+ }
+
+ status = vreader_xfr_bytes(reader,
+ sign, sign_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);
+
+}
+
+void test_empty_applets(void)
+{
+ uint8_t applet_02fb[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xFB
+ };
+ uint8_t applet_1201[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x12, 0x01
+ };
+ uint8_t applet_1202[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x12, 0x02
+ };
+ uint8_t applet_02f0[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF0
+ };
+ uint8_t applet_02f1[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF1
+ };
+ uint8_t applet_02f2[] = {
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF2
+ };
+ uint8_t coid[2] = {0x02, 0xFB};
+
+ VReader *reader = vreader_get_reader_by_id(0);
+
+
+ /* select the empty applet A00000007902FB, which should be empty buffer */
+ select_aid(reader, applet_02fb, sizeof(applet_02fb));
+
+ /* get properties */
+ get_properties_coid(reader, coid, TEST_EMPTY_BUFFER);
+
+ /* get the TAG buffer length */
+ read_buffer(reader, CAC_FILE_TAG, TEST_EMPTY_BUFFER);
+
+ /* get the VALUE buffer length */
+ read_buffer(reader, CAC_FILE_VALUE, TEST_EMPTY_BUFFER);
+
+
+ /* select the empty applet A0000000791201, which should be empty buffer */
+ select_aid(reader, applet_1201, sizeof(applet_1201));
+ coid[0] = 0x12;
+ coid[1] = 0x01;
+
+ /* get properties */
+ get_properties_coid(reader, coid, TEST_EMPTY_BUFFER);
+
+ /* get the TAG buffer length */
+ read_buffer(reader, CAC_FILE_TAG, TEST_EMPTY_BUFFER);
+
+ /* get the VALUE buffer length */
+ read_buffer(reader, CAC_FILE_VALUE, TEST_EMPTY_BUFFER);
+
+
+ /* select the empty applet A0000000791202, which should be empty buffer */
+ select_aid(reader, applet_1202, sizeof(applet_1202));
+ coid[0] = 0x12;
+ coid[1] = 0x02;
+
+ /* get properties */
+ get_properties_coid(reader, coid, TEST_EMPTY_BUFFER);
+
+ /* get the TAG buffer length */
+ read_buffer(reader, CAC_FILE_TAG, TEST_EMPTY_BUFFER);
+
+ /* get the VALUE buffer length */
+ read_buffer(reader, CAC_FILE_VALUE, TEST_EMPTY_BUFFER);
+
+
+ /* select the empty applet A00000007902F0, which should be empty */
+ select_aid(reader, applet_02f0, sizeof(applet_02f0));
+
+ /* get properties */
+ get_properties_coid(reader, NULL, TEST_EMPTY);
+
+
+ /* select the empty applet A00000007902F1, which should be empty */
+ select_aid(reader, applet_02f1, sizeof(applet_02f1));
+
+ /* get properties */
+ get_properties_coid(reader, NULL, TEST_EMPTY);
+
+
+ /* select the empty applet A00000007902F2, which should be empty */
+ select_aid(reader, applet_02f2, sizeof(applet_02f2));
+
+ /* get properties */
+ get_properties_coid(reader, NULL, TEST_EMPTY);
+
+
+ vreader_free(reader); /* get by id ref */
+}
+
+int
+isHWTests(void)
+{
+ return hw_tests;
+}
+
+void
+setHWTests(int new_value)
+{
+ hw_tests = new_value;
+}
+
+
+/* vim: set ts=4 sw=4 tw=0 noet expandtab: */
diff --git a/tests/common.h b/tests/common.h
new file mode 100644
index 0000000..4ba2619
--- /dev/null
+++ b/tests/common.h
@@ -0,0 +1,42 @@
+/*
+ * Shared test functions for libCACard
+ *
+ * Copyright 2018 Red Hat, Inc.
+ *
+ * Author: Jakub Jelen <jjelen at redhat.com>
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef _TESTS_COMMON
+#define _TESTS_COMMON
+
+#include "libcacard.h"
+
+#define APDUBufSize 270
+
+enum {
+ TEST_PKI = 1,
+ TEST_CCC = 2,
+ TEST_ACA = 3,
+ TEST_GENERIC = 4,
+ TEST_EMPTY_BUFFER = 5,
+ TEST_EMPTY = 6,
+};
+
+void select_aid(VReader *reader, unsigned char *aid, unsigned int aid_len);
+void select_applet(VReader *reader, int type);
+
+void get_properties_coid(VReader *reader, const unsigned char coid[2], int object_type);
+void get_properties(VReader *reader, int object_type);
+
+void read_buffer(VReader *reader, uint8_t type, int object_type);
+
+void do_sign(VReader *reader);
+
+void test_empty_applets(void);
+
+int isHWTests(void);
+void setHWTests(int);
+
+#endif /* _TESTS_COMMON */
diff --git a/tests/hwtests.c b/tests/hwtests.c
new file mode 100644
index 0000000..be2c801
--- /dev/null
+++ b/tests/hwtests.c
@@ -0,0 +1,273 @@
+/*
+ * Test mirroring of CAC smart card
+ *
+ * Copyright 2018 Red Hat, Inc.
+ *
+ * Author: Jakub Jelen <jjelen at redhat.com>
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libcacard.h"
+#include "simpletlv.h"
+#include "common.h"
+
+#define ARGS "db=\"sql:%s\" use_hw=yes"
+#define LOGIN_PIN "77777777"
+
+static GMainLoop *loop;
+static GThread *thread;
+static guint nreaders;
+static GMutex mutex;
+static GCond cond;
+
+static gpointer
+events_thread(gpointer arg)
+{
+ unsigned int reader_id;
+ VEvent *event;
+
+ while (1) {
+ event = vevent_wait_next_vevent();
+ if (event == NULL) {
+ break;
+ }
+ reader_id = vreader_get_id(event->reader);
+ if (reader_id == VSCARD_UNDEFINED_READER_ID) {
+ g_mutex_lock(&mutex);
+ vreader_set_id(event->reader, nreaders++);
+ g_cond_signal(&cond);
+ g_mutex_unlock(&mutex);
+ reader_id = vreader_get_id(event->reader);
+ }
+ switch (event->type) {
+ case VEVENT_READER_INSERT:
+ case VEVENT_READER_REMOVE:
+ case VEVENT_CARD_INSERT:
+ case VEVENT_CARD_REMOVE:
+ break;
+ case VEVENT_LAST:
+ default:
+ g_warn_if_reached();
+ break;
+ }
+ vevent_delete(event);
+ }
+
+ return NULL;
+}
+
+static void libcacard_init(void)
+{
+ VCardEmulOptions *command_line_options = NULL;
+ gchar *dbdir = g_test_build_filename(G_TEST_DIST, "hwdb", NULL);
+ gchar *args = g_strdup_printf(ARGS, dbdir);
+ VCardEmulError ret;
+
+ thread = g_thread_new("test/events", events_thread, NULL);
+
+ command_line_options = vcard_emul_options(args);
+ ret = vcard_emul_init(command_line_options);
+ g_assert_cmpint(ret, ==, VCARD_EMUL_OK);
+
+ /* We test with real hardware */
+ setHWTests(1);
+
+ /* Do not assume any specific reader name here */
+
+ g_mutex_lock(&mutex);
+ while (nreaders == 0)
+ g_cond_wait(&cond, &mutex);
+ g_mutex_unlock(&mutex);
+
+ g_free(args);
+ g_free(dbdir);
+}
+
+static void test_list(void)
+{
+ VReaderList *list = vreader_get_reader_list();
+ VReaderListEntry *reader_entry;
+ int cards = 0;
+
+ for (reader_entry = vreader_list_get_first(list); reader_entry;
+ reader_entry = vreader_list_get_next(reader_entry)) {
+ VReader *r = vreader_list_get_reader(reader_entry);
+ vreader_id_t id;
+ id = vreader_get_id(r);
+ g_debug("%s: VReader name = %s, card = %d", __func__, vreader_get_name(r), vreader_card_is_present(r));
+ g_assert_cmpint(id, !=, VSCARD_UNDEFINED_READER_ID);
+ if (vreader_card_is_present(r) == VREADER_OK) {
+ cards++;
+ }
+ }
+ if (cards == 0) {
+ g_test_skip("No physical card found");
+ return;
+ }
+
+ g_assert_cmpint(cards, ==, 1);
+ vreader_list_delete(list);
+}
+
+static void do_login(VReader *reader)
+{
+ VReaderStatus status;
+ int dwRecvLength = APDUBufSize;
+ uint8_t pbRecvBuffer[APDUBufSize];
+ uint8_t login[] = {
+ /* VERIFY [p1,p2=0 ] [Lc] [pin 77777777 ] */
+ 0x00, 0x20, 0x00, 0x00, 0x08,
+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37
+ };
+ g_assert_nonnull(reader);
+ status = vreader_xfr_bytes(reader,
+ login, sizeof(login),
+ pbRecvBuffer, &dwRecvLength);
+ g_assert_cmpint(status, ==, VREADER_OK);
+ g_assert_cmphex(pbRecvBuffer[0], ==, VCARD7816_SW1_SUCCESS);
+ g_assert_cmphex(pbRecvBuffer[1], ==, 0x00);
+}
+
+static void test_passthrough_applets(void)
+{
+ uint8_t applet_person[] = {
+ /*Read Buffer OFFSET TYPE LENGTH */
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00
+ };
+ uint8_t applet_personnel[] = {
+ /*Read Buffer OFFSET TYPE LENGTH */
+ 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x01
+ };
+ uint8_t person_coid[2] = {0x02, 0x00};
+ uint8_t personnel_coid[2] = {0x02, 0x01};
+
+ VReader *reader = vreader_get_reader_by_id(0);
+
+ /* Skip the HW tests without physical card */
+ if (vreader_card_is_present(reader) != VREADER_OK) {
+ g_test_skip("No physical card found");
+ return;
+ }
+
+ /* select the Person Instance applet A0000000790200 */
+ select_aid(reader, applet_person, sizeof(applet_person));
+
+ /* get properties */
+ get_properties_coid(reader, person_coid, TEST_GENERIC);
+
+ /* These objects requires a PIN to read the value buffer */
+ do_login(reader);
+
+ /* get the TAG buffer length */
+ read_buffer(reader, CAC_FILE_TAG, TEST_GENERIC);
+
+ /* get the VALUE buffer length */
+ read_buffer(reader, CAC_FILE_VALUE, TEST_GENERIC);
+
+
+ /* select the Personnel applet A0000000790201 */
+ select_aid(reader, applet_personnel, sizeof(applet_personnel));
+
+ /* get properties */
+ get_properties_coid(reader, personnel_coid, TEST_GENERIC);
+
+ /* get the TAG buffer */
+ read_buffer(reader, CAC_FILE_TAG, TEST_GENERIC);
+
+ /* get the VALUE buffer */
+ read_buffer(reader, CAC_FILE_VALUE, TEST_GENERIC);
+
+ vreader_free(reader); /* get by id ref */
+}
+
+static void test_login(void)
+{
+ VReader *reader = vreader_get_reader_by_id(0);
+
+ /* Skip the HW tests without physical card */
+ if (vreader_card_is_present(reader) != VREADER_OK) {
+ g_test_skip("No physical card found");
+ return;
+ }
+
+ /* select the ACA */
+ select_applet(reader, TEST_ACA);
+
+ do_login(reader);
+
+ vreader_free(reader); /* get by id ref */
+}
+
+static void test_sign(void)
+{
+ VReader *reader = vreader_get_reader_by_id(0);
+
+ /* Skip the HW tests without physical card */
+ if (vreader_card_is_present(reader) != VREADER_OK) {
+ 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_sign(reader);
+
+ vreader_free(reader); /* get by id ref */
+}
+
+static void test_empty_applets_hw(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;
+ }
+
+ vreader_free(reader); /* get by id ref */
+
+ test_empty_applets();
+}
+
+int main(int argc, char *argv[])
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ libcacard_init();
+
+ g_test_add_func("/hw-tests/list", test_list);
+ 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/empty-applets", test_empty_applets_hw);
+
+ ret = g_test_run();
+
+ g_main_loop_unref(loop);
+
+ /* FIXME: no wait to queue a NULL event */
+ /* g_thread_join(thread); */
+
+ return ret;
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet expandtab: */
diff --git a/tests/libcacard.c b/tests/libcacard.c
index 9352cb7..63a41e6 100644
--- a/tests/libcacard.c
+++ b/tests/libcacard.c
@@ -1,7 +1,20 @@
+/*
+ * Test general functionality of software emulated smart card
+ *
+ * Copyright 2018 Red Hat, Inc.
+ *
+ * Authors:
+ * Jakub Jelen <jjelen at redhat.com>
+ * Marc-André Lureau <marcandre.lureau at redhat.com>
+ *
+ * This code is licensed under the GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
#include <glib.h>
#include <string.h>
#include "libcacard.h"
#include "simpletlv.h"
+#include "common.h"
#define ARGS "db=\"sql:%s\" use_hw=no soft=(,Test,CAC,,cert1,cert2,cert3)"
@@ -11,13 +24,6 @@ static guint nreaders;
static GMutex mutex;
static GCond cond;
-enum {
- TEST_PKI = 1,
- TEST_CCC = 2,
- TEST_ACA = 3,
- TEST_GENERIC = 4
-};
-
static gpointer
events_thread(gpointer arg)
{
@@ -128,8 +134,6 @@ static void test_card_remove_insert(void)
vreader_free(reader); /* get by id ref */
}
-#define APDUBufSize 270
-
static void test_xfer(void)
{
VReader *reader = vreader_get_reader_by_id(0);
@@ -149,162 +153,6 @@ static void test_xfer(void)
vreader_free(reader); /* get by id ref */
}
-static void get_properties_coid(VReader *reader, const unsigned char coid[2],
- int object_type)
-{
- int dwRecvLength = APDUBufSize;
- VReaderStatus status;
- uint8_t pbRecvBuffer[APDUBufSize], *p, *p_end, *p2, *p2_end;
- uint8_t get_properties[] = {
- /* Get properties */
- 0x80, 0x56, 0x01, 0x00, 0x00
- };
- uint8_t get_properties_tag[] = {
- /* Get properties [tag list] */
- 0x80, 0x56, 0x02, 0x00, 0x02, 0x01, 0x01, 0x00
- };
- int verified_pki_properties = 0;
- int num_objects = 0, num_objects_expected = -1;
- int have_applet_information = 0;
-
- status = vreader_xfr_bytes(reader,
- get_properties, sizeof(get_properties),
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmpint(dwRecvLength, >, 2);
- g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-
- /* try to parse the response, if it makes sense */
- p = pbRecvBuffer;
- p_end = p + dwRecvLength - 2;
- while (p < p_end) {
- uint8_t tag;
- size_t vlen;
- if (simpletlv_read_tag(&p, p_end - p, &tag, &vlen) < 0) {
- g_debug("The generated SimpleTLV can not be parsed");
- g_assert_not_reached();
- }
- g_debug("Tag: 0x%02x, Len: %lu", tag, vlen);
- g_assert_cmpint(vlen, <=, p_end - p);
-
- switch (tag) {
- case 0x01: /* Applet Information */
- g_assert_cmpint(vlen, ==, 5);
- g_assert_cmphex(*p, ==, 0x10); /* Applet family */
- have_applet_information = 1;
- break;
-
- case 0x40: /* Number of objects */
- g_assert_cmpint(vlen, ==, 1);
- if (num_objects_expected != -1) {
- g_debug("Received multiple number-of-objects tags");
- g_assert_not_reached();
- }
- num_objects_expected = *p;
- break;
-
- case 0x50: /* TV Object */
- case 0x51: /* PKI Object */
- /* recursive SimpleTLV structure */
- p2 = p;
- p2_end = p + vlen;
- while (p2 < p2_end) {
- uint8_t tag2;
- size_t vlen2;
- if (simpletlv_read_tag(&p2, p2_end - p2, &tag2, &vlen2) < 0) {
- g_debug("The generated SimpleTLV can not be parsed");
- g_assert_not_reached();
- }
- g_assert_cmpint(vlen2, <=, p2_end - p2);
- g_debug(" Tag: 0x%02x, Len: %lu", tag2, vlen2);
-
- switch (tag2) {
- case 0x41: /* Object ID */
- g_assert_cmpmem(p2, vlen2, coid, 2);
- break;
-
- case 0x42: /* Buffer properties */
- g_assert_cmpint(vlen2, ==, 5);
- if (object_type != TEST_GENERIC)
- g_assert_cmpint(p2[0], ==, 0x00);
- break;
-
- case 0x43: /* PKI properties */
- /* For now, expecting 2048 b RSA keys */
- g_assert_cmphex(p2[0], ==, 0x06);
- g_assert_cmphex(p2[1], ==, (2048 / 8 / 8));
- g_assert_cmphex(p2[2], ==, 0x01);
- g_assert_cmphex(p2[3], ==, 0x01);
- verified_pki_properties = 1;
- break;
-
- default:
- g_debug("Unknown tag in object: 0x%02x", tag2);
- g_assert_not_reached();
- }
- p2 += vlen2;
- }
- /* one more object processed */
- num_objects++;
- break;
- default:
- g_debug("Unknown tag in properties buffer: 0x%02x", tag);
- g_assert_not_reached();
- }
- p += vlen;
- }
-
- if (num_objects_expected != -1) {
- g_assert_cmpint(num_objects, ==, num_objects_expected);
- }
-
- if (object_type == TEST_PKI) {
- g_assert_cmpint(verified_pki_properties, ==, 1);
- }
-
- g_assert_cmpint(have_applet_information, ==, 1);
-
- /* Try to list only some properties */
- dwRecvLength = APDUBufSize;
- status = vreader_xfr_bytes(reader,
- get_properties_tag, sizeof(get_properties_tag),
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmpint(dwRecvLength, ==, 16); /* Two applet information buffers + status */
- g_assert_cmpint(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmpint(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-}
-
-static void get_properties(VReader *reader, int object_type)
-{
- unsigned char coid[2];
- switch (object_type) {
- case TEST_PKI:
- // XXX only the first PKI for now
- coid[0] = 0x01;
- coid[1] = 0x00;
- get_properties_coid(reader, coid, object_type);
- break;
-
- case TEST_CCC:
- coid[0] = 0xDB;
- coid[1] = 0x00;
- get_properties_coid(reader, coid, object_type);
- break;
-
- case TEST_ACA:
- coid[0] = 0x03;
- coid[1] = 0x00;
- get_properties_coid(reader, coid, object_type);
- break;
-
- default:
- g_debug("Got unknown object type");
- g_assert_not_reached();
- }
-}
-
static void parse_acr(uint8_t *buf, int buflen)
{
uint8_t *p, *p_end;
@@ -540,151 +388,6 @@ static void get_acr(VReader *reader)
parse_acr(pbRecvBuffer, dwRecvLength);
}
-static void read_buffer(VReader *reader, uint8_t type, int object_type)
-{
- int dwRecvLength = APDUBufSize, dwLength, dwReadLength, offset;
- VReaderStatus status;
- uint8_t pbRecvBuffer[APDUBufSize];
- uint8_t *data;
- uint8_t read_buffer[] = {
- /*Read Buffer OFFSET TYPE LENGTH a_Le */
- 0x80, 0x52, 0x00, 0x00, 0x02, 0x01, 0x02, 0x02
- };
- int card_urls = 0;
-
- dwRecvLength = 4;
- read_buffer[5] = type;
- status = vreader_xfr_bytes(reader,
- read_buffer, sizeof(read_buffer),
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmpint(dwRecvLength, ==, 4);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-
- dwLength = (pbRecvBuffer[0] & 0xff) | ((pbRecvBuffer[1] << 8) & 0xff);
- if (dwLength == 0)
- return;
-
- data = g_malloc(dwLength);
- offset = 0x02;
- do {
- dwReadLength = MIN(255, dwLength);
- dwRecvLength = dwReadLength+2;
- read_buffer[2] = (unsigned char) ((offset >> 8) & 0xff);
- read_buffer[3] = (unsigned char) (offset & 0xff);
- read_buffer[6] = (unsigned char) (dwReadLength);
- read_buffer[7] = (unsigned char) (dwReadLength);
- status = vreader_xfr_bytes(reader,
- read_buffer, sizeof(read_buffer),
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmpint(dwRecvLength, ==, dwReadLength + 2);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-
- memcpy(data + offset - 2, pbRecvBuffer, dwReadLength);
- offset += dwLength;
- dwLength -= dwReadLength;
- } while (dwLength != 0);
-
- /* Try to parse the TAG buffer, if it makes sense */
- if (type == CAC_FILE_TAG) {
- uint8_t *p = data;
- uint8_t *p_end = p + offset - 2;
- while (p < p_end) {
- uint8_t tag;
- size_t vlen;
- if (simpletlv_read_tag(&p, p_end - p, &tag, &vlen) < 0) {
- g_debug("The generated SimpleTLV can not be parsed");
- g_assert_not_reached();
- }
- g_debug("Tag: 0x%02x, Len: %lu", tag, vlen);
-
- switch (tag) {
- case 0xF3: /* CardURL from CCC */
- if (object_type == TEST_CCC) {
- card_urls++;
- } else {
- g_debug("CardURLs found outside of CCC buffer");
- g_assert_not_reached();
- }
- break;
- default:
- break;
- }
- }
- if (object_type == TEST_CCC)
- g_assert_cmpint(card_urls, ==, 11 + 3);
- }
- g_free(data);
-}
-
-static void select_aid(VReader *reader, unsigned char *aid, unsigned int aid_len)
-{
- VReaderStatus status;
- int dwRecvLength = APDUBufSize;
- uint8_t pbRecvBuffer[APDUBufSize];
- uint8_t selfile[] = {
- 0x00, 0xa4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00
- };
- size_t selfile_len = sizeof(selfile);
-
- g_assert_cmpint(aid_len, ==, 7);
- memcpy(&selfile[5], aid, aid_len);
-
- g_debug("%s: Add applet with AID 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
- __func__, aid[0], aid[1], aid[2], aid[3], aid[4], aid[5], aid[6]);
- g_assert_nonnull(reader);
- status = vreader_xfr_bytes(reader,
- selfile, selfile_len,
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-}
-
-static void select_applet(VReader *reader, int type)
-{
- uint8_t selfile_ccc[] = {
- /* Select CCC Applet */
- 0xa0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00
- };
- uint8_t selfile_aca[] = {
- /* Select ACA Applet */
- 0xa0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00
- };
- uint8_t selfile_pki[] = {
- /* Select first PKI Applet */
- 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00
- };
- uint8_t *aid = NULL;
- size_t aid_len = 0;
-
- switch (type) {
- case TEST_PKI:
- aid = selfile_pki;
- aid_len = sizeof(selfile_pki);
- break;
-
- case TEST_CCC:
- aid = selfile_ccc;
- aid_len = sizeof(selfile_ccc);
- break;
-
- case TEST_ACA:
- aid = selfile_aca;
- aid_len = sizeof(selfile_aca);
- break;
-
- default:
- g_assert_not_reached();
- }
- g_assert_nonnull(aid);
-
- select_aid(reader, aid, aid_len);
-}
-
static void do_login(VReader *reader)
{
VReaderStatus status;
@@ -703,56 +406,6 @@ static void do_login(VReader *reader)
g_assert_cmphex(pbRecvBuffer[1], ==, 0x00);
}
-static void do_sign(VReader *reader)
-{
- VReaderStatus status;
- int dwRecvLength = APDUBufSize;
- uint8_t pbRecvBuffer[APDUBufSize];
- uint8_t sign[] = {
- /* VERIFY [p1,p2=0 ] [Lc ] [ 256 bytes of PKCS#1.5 padded data ... ] */
- 0x80, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x00, 0x01, 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, 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
- };
- uint8_t getresp[] = {
- /* Get Response (max we can get) */
- 0x00, 0xc0, 0x00, 0x00, 0x00
- };
- g_assert_nonnull(reader);
- status = vreader_xfr_bytes(reader,
- sign, sizeof(sign),
- pbRecvBuffer, &dwRecvLength);
- g_assert_cmpint(status, ==, VREADER_OK);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-
-
- /* 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, ==, 258);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
- g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
-
-}
-
static void test_cac_pki(void)
{
VReader *reader = vreader_get_reader_by_id(0);
@@ -898,30 +551,6 @@ static void test_get_response(void)
vreader_free(reader); /* get by id ref */
}
-static void test_other_applets(void)
-{
- uint8_t applet_02fb[] = {
- /*Read Buffer OFFSET TYPE LENGTH */
- 0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xFB
- };
- uint8_t coid[2] = {0x02, 0xFB};
- VReader *reader = vreader_get_reader_by_id(0);
-
- /* select the empty applet A00000007902FB, which should be empty*/
- select_aid(reader, applet_02fb, sizeof(applet_02fb));
-
- /* get properties */
- get_properties_coid(reader, coid, TEST_GENERIC);
-
- /* get the TAG buffer length */
- read_buffer(reader, CAC_FILE_TAG, TEST_GENERIC);
-
- /* get the VALUE buffer length */
- read_buffer(reader, CAC_FILE_VALUE, TEST_GENERIC);
-
- vreader_free(reader); /* get by id ref */
-}
-
int main(int argc, char *argv[])
{
int ret;
@@ -941,7 +570,7 @@ int main(int argc, char *argv[])
g_test_add_func("/libcacard/get-response", test_get_response);
g_test_add_func("/libcacard/login", test_login);
g_test_add_func("/libcacard/sign", test_sign);
- g_test_add_func("/libcacard/other-applets", test_other_applets);
+ g_test_add_func("/libcacard/empty-applets", test_empty_applets);
g_test_add_func("/libcacard/remove", test_remove);
ret = g_test_run();
--
2.17.1
More information about the Spice-devel
mailing list