external authenticate implemented
authorNIIBE Yutaka <gniibe@fsij.org>
Wed, 30 May 2012 09:50:22 +0000 (18:50 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Wed, 30 May 2012 09:50:22 +0000 (18:50 +0900)
ChangeLog
README
src/gnuk.h
src/openpgp.c

index e01de34..9b05e18 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-30  Niibe Yutaka  <gniibe@fsij.org>
+
+       * src/openpgp.c (CHALLENGE_LEN): New.
+       (cmd_external_authenticate): Authentication by response with
+       public key.
+       (cmd_get_challenge): 16-byte is enough for challenge.
+
 2012-05-29  Niibe Yutaka  <gniibe@fsij.org>
 
        * src/call-rsa.c (rsa_verify): New function.
        (std_set_address, std_get_descriptor, std_get_configuration)
        (std_set_configuration, std_get_interface, std_set_interface):
        Check direction.
-       (handle_setup0): Add length for setup_with_data
+       (handle_setup0): Add length for setup_with_data.
 
 2012-05-16  Niibe Yutaka  <gniibe@fsij.org>
 
diff --git a/README b/README
index d49abac..b0627b7 100644 (file)
--- a/README
+++ b/README
@@ -228,6 +228,9 @@ Gnuk is distributed with external source code.
   The file include/polarssl/bn_mul.h is heavily modified for ARM
   Cortex-M3.
 
+  The file library/aes.c is modified so that some constants can
+  go to .sys section.
+
 
 USB vendor ID and product ID (USB device ID)
 ============================================
index 45bb99c..7e55465 100644 (file)
@@ -121,6 +121,7 @@ extern void gpg_do_get_data (uint16_t tag, int with_tag);
 extern void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
 extern void gpg_do_public_key (uint8_t kk_byte);
 
+extern const uint8_t *gpg_get_firmware_update_key (uint8_t keyno);
 
 
 enum kind_of_key {
index d062f11..076f245 100644 (file)
@@ -50,6 +50,9 @@
 #define INS_PUT_DATA                           0xda
 #define INS_PUT_DATA_ODD                       0xdb    /* For key import */
 
+#define CHALLENGE_LEN  16
+static const uint8_t *challenge; /* Random bytes */
+
 static const uint8_t
 select_file_TOP_result[] __attribute__ ((aligned (1))) = {
   0x00, 0x00,       /* unused */
@@ -826,9 +829,31 @@ cmd_write_binary (void)
 static void
 cmd_external_authenticate (void)
 {
+  const uint8_t *pubkey;
+  const uint8_t *signature = apdu.cmd_apdu_data;
+  int len = apdu.cmd_apdu_data_len;
+  uint8_t keyno = P2 (apdu);
+  int r;
+
   DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
 
-  if (!ac_check_status (AC_ADMIN_AUTHORIZED))
+  if (keyno > 2)
+    {
+      GPG_CONDITION_NOT_SATISFIED ();
+      return;
+    }
+
+  pubkey = gpg_get_firmware_update_key (keyno);
+  if (pubkey == NULL || len != 256)
+    {
+      GPG_CONDITION_NOT_SATISFIED ();
+      return;
+    }
+
+  r = rsa_verify (pubkey, challenge, CHALLENGE_LEN, signature);
+  random_bytes_free (challenge);
+  challenge = NULL;
+  if (r < 0)
     {
       GPG_SECURITY_FAILURE ();
       return;
@@ -842,19 +867,14 @@ cmd_external_authenticate (void)
 static void
 cmd_get_challenge (void)
 {
-  const uint8_t *rand;
-  int i;
-
   DEBUG_INFO (" - GET CHALLENGE\r\n");
 
-  for (i = 0; i < 6; i++)
-    {
-      rand = random_bytes_get ();
-      memcpy (res_APDU + i * 16, rand, 16);
-      random_bytes_free (rand);
-    }
+  if (challenge)
+    random_bytes_free (challenge);
 
-  res_APDU_size = 96;
+  challenge = random_bytes_get ();
+  memcpy (res_APDU, challenge, CHALLENGE_LEN);
+  res_APDU_size = CHALLENGE_LEN;
   GPG_SUCCESS ();
   DEBUG_INFO ("GET CHALLENGE done.\r\n");
 }