support factory_reset.
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 13 Oct 2016 23:45:01 +0000 (08:45 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 13 Oct 2016 23:45:01 +0000 (08:45 +0900)
ChangeLog
NEWS
src/gnuk.h
src/openpgp-do.c
src/openpgp.c
src/usb-ccid.c
test/features/002_get_data_static.feature
test/features/402_get_data_static.feature
test/features/802_get_data_static.feature
tests/test_empty_card.py

index fa11517..82c4736 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2016-10-14  Niibe Yutaka  <gniibe@fsij.org>
+
+       * src/usb-ccid.c (ccid_power_on) [LIFE_CYCLE_MANAGEMENT_SUPPORT]:
+       Change LCS value in ATR at run time.
+
+       * src/openpgp.c (gpg_init): Handle FILE_CARD_TERMINATED.
+       (cmd_select_file): Don't return AID.
+       (cmd_activate_file, cmd_terminate_df): New.
+       (process_command_apdu): Let return GPG_NO_RECORD() when
+       not selected.
+
+       * src/openpgp-do.c (gpg_do_terminate): New.
+       (gpg_data_scan): Handle p_start is NULL.
+       (do_hist_bytes): Remove.
+
+       * src/flash.c (flash_data): Change the value from 0x0000.
+       (flash_init): Support termination state.  Fix handling
+       of the boundary case where gen0 is 0xfffe.
+       (flash_terminate, flash_activate): New.
+       (flash_copying_gc): Skip 0xffff for generation number.
+
 2016-10-13  Niibe Yutaka  <gniibe@fsij.org>
 
        * src/status-code.h: Rename from openpgp.h.
diff --git a/NEWS b/NEWS
index e0de640..4d3c3ee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,21 @@
 Gnuk NEWS - User visible changes
 
+* Major changes in Gnuk 1.2.2
+
+  Released 2016-10-14, by NIIBE Yutaka
+
+** Change of SELECT FILE behavior 
+Gnuk used to reply AID upon SELECT FILE command.  Now, to be compatible
+to original OpenPGP card, it returns nothing but status code of 9000.
+
+** Added feature of Factory Reset as compile time option
+Original OpenPGP card has the feature, and Gnuk is now configurable to
+support the feature.
+
+** Upgrade of Chopstx
+We use Chopstx 1.2.
+
+
 * Major changes in Gnuk 1.2.1
 
   Released 2016-07-11, by NIIBE Yutaka
index 5586040..d6c6f67 100644 (file)
@@ -100,6 +100,7 @@ void ac_fini (void);
 
 
 void set_res_sw (uint8_t sw1, uint8_t sw2);
+extern uint8_t file_selection;
 extern const uint8_t historical_bytes[];
 extern uint16_t data_objects_number_of_bytes;
 
index be21f29..5f5f7de 100644 (file)
@@ -90,10 +90,10 @@ uint16_t data_objects_number_of_bytes;
 
 /*
  * Compile time vars:
- *   Historical Bytes (template), Extended Capabilities.
+ *   Historical Bytes, Extended Capabilities.
  */
 
-/* Historical Bytes (template) */
+/* Historical Bytes */
 const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
   10,
   0x00,
@@ -102,7 +102,12 @@ const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
   0x80, 0x01, 0x80,            /* Full DF name */
                                /* 1-byte */
                                /* Command chaining, No extended Lc and Le */
-  0x00, 0x90, 0x00             /* Status info (no life cycle management) */
+#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
+  0x05,
+#else
+  0x00,
+#endif
+  0x90, 0x00                   /* Status info */
 };
 
 /* Extended Capabilities */
@@ -485,23 +490,6 @@ copy_tag (uint16_t tag)
     }
 }
 
-static int
-do_hist_bytes (uint16_t tag, int with_tag)
-{
-  /*
-   * Currently, we support no life cycle management.  In case of Gnuk,
-   * user could flash the MCU with SWD/JTAG, instead.  It is also
-   * possible for user to do firmware upgrade through USB.
-   *
-   * Thus, here, it just returns the template as is.
-   *
-   * In future (when Gnuk will be on the real smartcard),
-   * we can support life cycle management by implementing
-   * TERMINATE DF / ACTIVATE FILE and fix code around here.
-   */
-  copy_do_1 (tag, historical_bytes, with_tag);
-  return 1;
-}
 
 #define SIZE_FP 20
 #define SIZE_KGTIME 4
@@ -1513,7 +1501,6 @@ gpg_do_table[] = {
   { GPG_DO_NAME, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[12] },
   { GPG_DO_LANGUAGE, DO_VAR, AC_ALWAYS, AC_ADMIN_AUTHORIZED, &do_ptr[13] },
   /* Pseudo DO READ: calculated */
-  { GPG_DO_HIST_BYTES, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_hist_bytes },
   { GPG_DO_FP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_fp_all },
   { GPG_DO_CAFP_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_cafp_all },
   { GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
@@ -1530,6 +1517,7 @@ gpg_do_table[] = {
   { GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
     rw_algorithm_attr },
   /* Fixed data */
+  { GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
   { GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
   /* Compound data: Read access only */
   { GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
index b4b9f40..a30450a 100644 (file)
@@ -101,7 +101,7 @@ set_res_sw (uint8_t sw1, uint8_t sw2)
 #define FILE_CARD_TERMINATED_OPENPGP   254
 #define FILE_CARD_TERMINATED   255
 
-static uint8_t file_selection;
+uint8_t file_selection;
 
 static void
 gpg_init (void)
@@ -765,18 +765,9 @@ cmd_select_file (void)
        }
 
       file_selection = FILE_DF_OPENPGP;
-      if ((P2 (apdu) & 0x0c) == 0x0c)  /* No FCI */
-       GPG_SUCCESS ();
-      else
-       {
-         gpg_do_get_data (0x004f, 1); /* AID */
-         memmove (res_APDU+2, res_APDU, res_APDU_size);
-         res_APDU[0] = 0x6f;
-         res_APDU[1] = 0x12;
-         res_APDU[2] = 0x84;   /* overwrite: DF name */
-         res_APDU_size += 2;
-         GPG_SUCCESS ();
-       }
+
+      /* Behave just like original OpenPGP card.  */
+      GPG_SUCCESS ();
     }
   else if (apdu.cmd_apdu_data_len == 2
           && apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
index 736d4ee..c533e13 100644 (file)
@@ -795,6 +795,10 @@ ccid_power_on (struct ccid *c)
   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]);
+#ifdef LIFE_CYCLE_MANAGEMENT_SUPPORT
+  if (file_selection == 255)
+    p[CCID_MSG_HEADER_SIZE + sizeof (ATR_head) + 7] = 0x03;
+#endif
   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;
index 4815aeb..290e98e 100644 (file)
@@ -4,7 +4,7 @@ Feature: command GET DATA
 
   Scenario: data object historical bytes
      When requesting historical bytes: 5f52
-     Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
+     Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
 
   Scenario: data object extended capabilities
      When requesting extended capabilities: c0
index 4815aeb..290e98e 100644 (file)
@@ -4,7 +4,7 @@ Feature: command GET DATA
 
   Scenario: data object historical bytes
      When requesting historical bytes: 5f52
-     Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
+     Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
 
   Scenario: data object extended capabilities
      When requesting extended capabilities: c0
index 4815aeb..290e98e 100644 (file)
@@ -4,7 +4,7 @@ Feature: command GET DATA
 
   Scenario: data object historical bytes
      When requesting historical bytes: 5f52
-     Then you should get: \x00\x31\x84\x73\x80\x01\x80\x00\x90\x00
+     Then data should match: \x00\x31\x84\x73\x80\x01\x80[\x00\x05]\x90\x00
 
   Scenario: data object extended capabilities
      When requesting extended capabilities: c0
index f70e7c0..8199f1a 100644 (file)
@@ -133,7 +133,8 @@ def test_verify_pw3(card):
 def test_historical_bytes(card):
     h = get_data_object(card, 0x5f52)
     assert h == b'\x001\xc5s\xc0\x01@\x05\x90\x00' or \
-           h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00'
+           h == b'\x00\x31\x84\x73\x80\x01\x80\x00\x90\x00' or \
+           h == b'\x00\x31\x84\x73\x80\x01\x80\x05\x90\x00'
 
 def test_extended_capabilities(card):
     a = get_data_object(card, 0xc0)