Fix difference between original OpenPGP card
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 13 Oct 2016 01:33:02 +0000 (10:33 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 13 Oct 2016 01:33:02 +0000 (10:33 +0900)
ChangeLog
src/config.h.in
src/configure
src/gnuk.h
src/openpgp-do.c
src/usb-ccid.c
tests/README

index 3177963..103f91a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2016-10-13  Niibe Yutaka  <gniibe@fsij.org>
+
+       * tests: New test suite for OpenPGP card with PyTest.
+
+       * src/configure (factory_reset): New.
+
+       * src/usb-ccid.c (ccid_power_on): Use ATR_head and historical
+       bytes.
+
+       * src/openpgp-do.c (rw_algorithm_attr): Clear fingerprint, timestamp,
+       and possibly ds_counter.
+
 2016-10-12  Niibe Yutaka  <gniibe@fsij.org>
 
        * test/features/steps.py (cmd_reset_retry_counter): Fix.
index 923ab41..5723167 100644 (file)
@@ -8,3 +8,4 @@
 @CERTDO_DEFINE@
 @HID_CARD_CHANGE_DEFINE@
 @SERIALNO_STR_LEN_DEFINE@
+@LIFE_CYCLE_MANAGEMENT_DEFINE@
index 765df6e..a4eda6b 100755 (executable)
@@ -43,6 +43,7 @@ sys1_compat=yes
 pinpad=no
 certdo=no
 hid_card_change=no
+factory_reset=no
 
 # Revision number
 if test -e ../.git; then
@@ -87,6 +88,10 @@ for option; do
     sys1_compat=yes ;;
   --disable-sys1-compat)
     sys1_compat=no ;;
+  --enable-factory-reset)
+    factory_reset=yes ;;
+  --disable-factory-reset)
+    factory_reset=no ;;
   --with-dfu)
     with_dfu=yes ;;
   --without-dfu)
@@ -131,6 +136,8 @@ Configuration:
   --disable-sys1-compat        disable SYS 1.0 compatibility   [no]
                           executable is target independent
                           but requires SYS 2.0 or newer
+  --enable-factory-reset
+                       support life cycle management   [no]
   --with-dfu           build image for DFU             [<target specific>]
 EOF
   exit 0
@@ -248,6 +255,15 @@ else
   echo "Card insert/removal by HID device is NOT supported"
 fi
 
+# --enable-factory-reset option
+if test "$factory_reset" = "yes"; then
+  LIFE_CYCLE_MANAGEMENT_DEFINE="#define LIFE_CYCLE_MANAGEMENT_SUPPORT 1"
+  echo "Life cycle management is supported"
+else
+  LIFE_CYCLE_MANAGEMENT_DEFINE="#undef LIFE_CYCLE_MANAGEMENT_SUPPORT"
+  echo "Life cycle management is NOT supported"
+fi
+
 ### !!! Replace following string of "FSIJ" to yours !!! ####
 SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-"
 
@@ -375,6 +391,7 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
     -e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
     -e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
     -e "s/@HID_CARD_CHANGE_DEFINE@/$HID_CARD_CHANGE_DEFINE/" \
+    -e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \
     -e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \
        < config.h.in > config.h
 exit 0
index 055310c..b74e03f 100644 (file)
@@ -100,6 +100,7 @@ void ac_fini (void);
 
 
 void set_res_sw (uint8_t sw1, uint8_t sw2);
+extern const uint8_t historical_bytes[];
 extern uint16_t data_objects_number_of_bytes;
 
 #define CHALLENGE_LEN  32
index dcaec7e..71b613d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * openpgp-do.c -- OpenPGP card Data Objects (DO) handling
  *
- * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
+ * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016
  *               Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
@@ -94,7 +94,7 @@ uint16_t data_objects_number_of_bytes;
  */
 
 /* Historical Bytes (template) */
-static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
+const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
   10,
   0x00,
   0x31, 0x84,                  /* Full DF name, GET DATA, MF */
@@ -763,6 +763,22 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
        {
          gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
          flash_enum_clear (algo_attr_pp);
+         if (kk == GPG_KEY_FOR_SIGNING)
+           {
+             gpg_reset_digital_signature_counter ();
+             gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
+           }
+         else if (kk == GPG_KEY_FOR_DECRYPTION)
+           {
+             gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
+           }
+         else
+           {
+             gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
+           }
          if (*algo_attr_pp != NULL)
            return 0;
        }
@@ -770,6 +786,22 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
               || (*algo_attr_pp)[1] != algo)
        {
          gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
+         if (kk == GPG_KEY_FOR_SIGNING)
+           {
+             gpg_reset_digital_signature_counter ();
+             gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0);
+           }
+         else if (kk == GPG_KEY_FOR_DECRYPTION)
+           {
+             gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0);
+           }
+         else
+           {
+             gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0);
+             gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0);
+           }
          *algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
          if (*algo_attr_pp == NULL)
            return 0;
index 1222381..736d4ee 100644 (file)
@@ -720,24 +720,12 @@ usb_tx_done (uint8_t ep_num, uint16_t len)
  * TB3 = 0x55: BWI = 5, CWI = 5   (BWT timeout 3.2 sec)
  * TD3 = 0x1f: TA4 follows, T=15
  * TA4 = 0x03: 5V or 3.3V
- * Historical bytes: to be explained...
- * XOR check
  *
- * Minimum: 0x3b, 0x8a, 0x80, 0x01, + historical bytes, xor check
+ * Minimum: 0x3b, 0x8a, 0x80, 0x01
  *
  */
-static const uint8_t ATR[] = {
+static const uint8_t ATR_head[] = {
   0x3b, 0xda, 0x11, 0xff, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0x03,
-  0x00,
-       0x31, 0x84, /* full DF name, GET DATA, MF */
-        0x73,
-              0x80, /* DF full name */
-             0x01, /* 1-byte */
-             0x80, /* Command chaining, No extended Lc and extended Le */
-       0x00,
-        0x90, 0x00,
- (0xda^0x11^0xff^0x81^0xb1^0xfe^0x55^0x1f^0x03
-  ^0x00^0x31^0x84^0x73^0x80^0x01^0x80^0x00^0x90^0x00)
 };
 
 /*
@@ -783,8 +771,10 @@ extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
 static enum ccid_state
 ccid_power_on (struct ccid *c)
 {
-  size_t size_atr = sizeof (ATR);
-  uint8_t p[CCID_MSG_HEADER_SIZE];
+  size_t size_atr = sizeof (ATR_head) + historical_bytes[0] + 1;
+  uint8_t p[CCID_MSG_HEADER_SIZE+size_atr];
+  uint8_t xor_check = 0;
+  int i;
 
   if (c->application == 0)
     c->application = chopstx_create (PRIO_GPG, STACK_ADDR_GPG,
@@ -802,8 +792,14 @@ ccid_power_on (struct ccid *c)
   p[CCID_MSG_ERROR_OFFSET] = 0x00;
   p[CCID_MSG_CHAIN_OFFSET] = 0x00;
 
-  usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE);
-  usb_lld_txcpy (ATR, c->epi->ep_num, CCID_MSG_HEADER_SIZE, size_atr);
+  memcpy (p + CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
+  memcpy (p + CCID_MSG_HEADER_SIZE + sizeof (ATR_head),
+         historical_bytes + 1, historical_bytes[0]);
+  for (i = 1; i < (int)size_atr - 1; i++)
+    xor_check ^= p[CCID_MSG_HEADER_SIZE + i];
+  p[CCID_MSG_HEADER_SIZE+size_atr-1] = xor_check;
+
+  usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE + size_atr);
 
   /* This is a single packet Bulk-IN transaction */
   c->epi->buf = NULL;
index e51c643..8aefe70 100644 (file)
@@ -1,5 +1,9 @@
 Here is a test suite for OpenPGP card.
 
+For now, only TPDU card reader is supported for OpenPGP card.
+Gnuk Token is supported as well.
+
+
 You need to install:
 
    $ sudo apt-get install python3-pytest python3-usb