Keystore management changes
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 3 Dec 2010 08:35:22 +0000 (17:35 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 3 Dec 2010 08:35:22 +0000 (17:35 +0900)
ChangeLog
README
THANKS
src/flash.c
src/gnuk.h
src/gnuk.ld.in
src/openpgp-do.c

index 2259589..6129e13 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-12-03  NIIBE Yutaka  <gniibe@fsij.org>
+
+       Keystore management changes.
+       * src/flash.c (flash_key_alloc): Check FLASH_KEYSTORE_SIZE.
+       (flash_key_release): Removed.
+       (flash_keystore_release): New function.
+       * src/openpgp-do.c (gpg_do_write_prvkey): Make it static.
+       When there is a key already, return as error.
+       (proc_key_import): Call flash_keystore_release when all keys removed.
+       * src/gnuk.ld.in (_keystore_pool): Size of keystore is now 1.5KB.
+
 2010-11-30  NIIBE Yutaka  <gniibe@fsij.org>
 
        Flash ROM fixes for STM32F10X_HD.
@@ -19,7 +30,7 @@
        * ChibiOS_2.0.8/boards/OLIMEX_LPC_P2148/board.h
        * ChibiOS_2.0.8/readme.txt
        * ChibiOS_2.0.8/test/testdyn.c
-       * ChibiOS_2.0.8/docs/*
+       * ChibiOS_2.0.8/docs/*/*: Updated.
 
        New private key management.
        * src/ac.c (ac_reset_pso_cds, ac_reset_pso_other): Call
@@ -32,7 +43,6 @@
        * src/openpgp.c (cmd_pso, cmd_internal_authenticate): Use new API
        of rsa_sign and rsa_decrypt.
        (cmd_pso): Fixed bug of checking return value of gpg_get_pw1_lifetime.
-
        * src/call-rsa.c (rsa_sign): New argument KD.
        (rsa_decrypt): Likewise.
 
diff --git a/README b/README
index 049b7e9..af523aa 100644 (file)
--- a/README
+++ b/README
@@ -55,8 +55,6 @@ Tested features are:
 
 It is known not-working well:
 
-       * Key import multiple times
-
        * For some version of kernel and libccid, --enable-debug can't
           work well.  Please disable DEBUG option if it doesn't work well.
 
@@ -64,6 +62,10 @@ Not (yet) supported feature(s):
 
        * card holder certificate (its size matters (> 1KiB?), if we support)
 
+Not supported feature(s):
+
+       * Overriding key import.  You need to remove all keys first.
+
 
 Targets
 =======
diff --git a/THANKS b/THANKS
index 3b75ffe..448bc78 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -6,8 +6,9 @@ encouraging the development, testing the implementation, suggesting
 improvements, or fixing bugs.  Here is a list of those people.
 
 Hironobu SUZUKI                hironobu@h2np.net
-Jan Sur                        jan@suhr.info
+Jan Suhr               jan@suhr.info
 Kaz Kojima             kkojima@rr.iij4u.or.jp
+Ludovic Rousseau       ludovic.rousseau@free.fr
 MATSUU Takuto          matsuu@gentoo.org
 NAGAMI Takeshi         nagami-takeshi@aist.go.jp
 Shane Coughlan         scoughlan@openinventionnetwork.com
index 1f6ddce..0ad23e1 100644 (file)
@@ -150,7 +150,7 @@ flash_erase_page (uint32_t addr)
  *
  * flash-page-size data pool  * 2
  *
- * 3-KiB Key store (512-byte (p, q and N) key-store * 6)
+ * 1.5-KiB Key store (512-byte (p, q and N) key-store * 3)
  */
 #define FLASH_DATA_POOL_HEADER_SIZE    2
 #if defined(STM32F10X_HD)
@@ -159,6 +159,7 @@ flash_erase_page (uint32_t addr)
 #define FLASH_PAGE_SIZE                        1024
 #endif
 #define FLASH_DATA_POOL_SIZE           (FLASH_PAGE_SIZE*2)
+#define FLASH_KEYSTORE_SIZE            (512*3)
 
 static const uint8_t *data_pool;
 static const uint8_t *keystore_pool;
@@ -383,6 +384,9 @@ flash_key_alloc (void)
 {
   uint8_t *k = (uint8_t *)keystore;
 
+  if ((k - keystore_pool) >= FLASH_KEYSTORE_SIZE)
+    return NULL;
+
   keystore += 512;
   return k;
 }
@@ -416,9 +420,12 @@ flash_key_write (uint8_t *key_addr, const uint8_t *key_data,
 }
 
 void
-flash_key_release (const uint8_t *key_addr)
+flash_keystore_release (void)
 {
-  (void)key_addr;              /* Not yet */
+  flash_erase_page ((uint32_t)keystore_pool);
+#if FLASH_KEYSTORE_SIZE > FLASH_PAGE_SIZE
+  flash_erase_page ((uint32_t)keystore_pool + FLASH_PAGE_SIZE);
+#endif
 }
 
 void
index 9af19a4..b1b4ffc 100644 (file)
@@ -90,7 +90,7 @@ extern const uint8_t *flash_init (void);
 extern void flash_do_release (const uint8_t *);
 extern const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
 extern uint8_t *flash_key_alloc (void);
-extern void flash_key_release (const uint8_t *);
+extern void flash_keystore_release (void);
 extern void flash_set_data_pool_last (const uint8_t *p);
 extern void flash_clear_halfword (uint32_t addr);
 extern void flash_increment_counter (uint8_t counter_tag_nr);
@@ -170,8 +170,6 @@ extern const uint8_t *modulus_calc (const uint8_t *, int);
 extern void modulus_free (const uint8_t *);
 extern int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *);
 
-extern int gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, const uint8_t *keystring);
-
 extern const uint8_t *gpg_do_read_simple (uint8_t);
 extern void gpg_do_write_simple (uint8_t, const uint8_t *, int);
 extern void gpg_increment_digital_signature_counter (void);
index 43f1e62..8478d32 100644 (file)
@@ -129,7 +129,7 @@ SECTIONS
        . += @FLASH_PAGE_SIZE@;
        _keystore_pool = .;
        FILL(0xffffffff);
-       . += 1024*3;
+       . += 512*3;
     } > flash
 }
 
index 7e01fae..b0af770 100644 (file)
@@ -615,7 +615,7 @@ calc_check32 (const uint8_t *p, int len)
 
 static int8_t num_prv_keys;
 
-int
+static int
 gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
                     const uint8_t *keystring)
 {
@@ -637,6 +637,10 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
   DEBUG_INFO ("Key import\r\n");
   DEBUG_SHORT (key_len);
 
+  if (do_data)
+    /* No replace support, you need to remove it first.  */
+    return -1;
+
   pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
   if (pd == NULL)
     return -1;
@@ -665,31 +669,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
   kd[kk].random = get_random ();
   memcpy (kd[kk].magic, GNUK_MAGIC, KEY_MAGIC_LEN);
 
-  if (do_data)                 /* We have old prvkey */
-    {
-      /* Write new prvkey resetting PW1 and RC */
-      /* Note: if you have other prvkey(s), it becomes bogus */
-      memcpy (pd, do_data+1, sizeof (struct prvkey_data));
-      decrypt (keystring_md_pw3, pd->dek_encrypted_3, DATA_ENCRYPTION_KEY_SIZE);
-      dek = pd->dek_encrypted_3;
-      memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE);
-      memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE);
-      gpg_do_write_simple (NR_DO_KEYSTRING_PW1, NULL, 0);
-      gpg_do_write_simple (NR_DO_KEYSTRING_RC, NULL, 0);
-      flash_key_release (pd->key_addr);
-      flash_do_release (do_data);
-      ks_pw1 = NULL;
-      ks_rc = NULL;
-    }
-  else
-    {
-      dek = random_bytes_get (); /* 16-byte random bytes */
-      memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE);
-      memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE);
-      memcpy (pd->dek_encrypted_3, dek, DATA_ENCRYPTION_KEY_SIZE);
-      ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
-      ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
-    }
+  dek = random_bytes_get (); /* 16-byte random bytes */
+  memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE);
+  memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE);
+  memcpy (pd->dek_encrypted_3, dek, DATA_ENCRYPTION_KEY_SIZE);
+  ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
+  ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
 
   encrypt (dek, (uint8_t *)&kd[kk], sizeof (struct key_data));
 
@@ -698,8 +683,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
 
   if (r < 0)
     {
-      if (do_data == NULL)
-       random_bytes_free (dek);
+      random_bytes_free (dek);
       free (pd);
       return r;
     }
@@ -734,14 +718,12 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
   p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data));
   do_ptr[nr - NR_DO__FIRST__] = p;
 
-  if (do_data == NULL)
-    random_bytes_free (dek);
+  random_bytes_free (dek);
   free (pd);
   if (p == NULL)
     return -1;
 
-  if (do_data == NULL
-      && ++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered.  */
+  if (++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered.  */
     {
       /* Remove contents of keystrings from DO, but length */
       if (ks_pw1)
@@ -827,18 +809,16 @@ proc_key_import (const uint8_t *data, int len)
       uint8_t nr = get_do_ptr_nr_for_kk (kk);
       const uint8_t *do_data = do_ptr[nr - NR_DO__FIRST__];
 
-      /* Delete the key */
-      if (do_data)
-       {
-         uint8_t *key_addr = *(uint8_t **)&do_data[1];
+      if (do_data == NULL)
+       return 1;
 
-         flash_key_release (key_addr);
-         flash_do_release (do_data);
-       }
       do_ptr[nr - NR_DO__FIRST__] = NULL;
+      flash_do_release (do_data);
 
       if (--num_prv_keys == 0)
        {
+         flash_keystore_release ();
+
          /* Delete PW1 and RC if any */
          gpg_do_write_simple (NR_DO_KEYSTRING_PW1, NULL, 0);
          gpg_do_write_simple (NR_DO_KEYSTRING_RC, NULL, 0);