瀏覽代碼

Check whether the card has a RNG.

* src/agent.c (learn_status_cb): Learn from the agent whether the
card supports GET CHALLENGE.
* src/agent.h (struct agent_card_info_s): New member rng_available.
* src/p11-gettokeninfo (C_GetTokenInfo): Set CKF_RNG flag.
* src/slots.c (slot_token_has_rng): New function.
* src/slots.h (slot_token_has_rng): New prototype.
Parse card capabilities
--

Now that C_GenerateRandom is implemented, we can inform the client
application that a RNG is available on the token.

But support for the GET CHALLENGE operation does not seem to be
mandatory as per the OpenPGP Card specification, so we should
first make sure that the inserted token does support it.

The code for parsing the EXTCAP line is taken from GnuPG, with
Werner's permission to reuse it under the same licensing terms as
the rest of Scute.

Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
Damien Goutte-Gattat 9 年之前
父節點
當前提交
8d6099136c
共有 5 個文件被更改,包括 43 次插入2 次删除
  1. 24 0
      src/agent.c
  2. 2 0
      src/agent.h
  3. 5 2
      src/p11-gettokeninfo.c
  4. 9 0
      src/slots.c
  5. 3 0
      src/slots.h

+ 24 - 0
src/agent.c

@@ -846,6 +846,30 @@ learn_status_cb (void *opaque, const char *line)
 	    }
 	}
     }
+  else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
+    {
+      char *p, *p2, *buf;
+      int abool;
+
+      buf = p = unescape_status_string (line);
+      if (buf)
+        {
+          for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
+            {
+              p2 = strchr (p, '=');
+              if (p2)
+                {
+                  *p2++ = 0;
+                  abool = (*p2 == '1');
+                  if (!strcmp (p, "gc"))
+                    parm->rng_available = abool;
+                  /* We're currently not interested in the
+                   * other capabilities. */
+                }
+            }
+          free (buf);
+        }
+    }
   return 0;
 }
 

+ 2 - 0
src/agent.h

@@ -73,6 +73,8 @@ struct agent_card_info_s
   char grip1[41];
   char grip2[41];
   char grip3[41];
+  int rng_available;    /* True if the GET CHALLENGE operation
+                           is supported. */
 };
 
 

+ 5 - 2
src/p11-gettokeninfo.c

@@ -72,8 +72,11 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)
   pInfo->flags = CKF_TOKEN_INITIALIZED
     | CKF_PROTECTED_AUTHENTICATION_PATH | CKF_WRITE_PROTECTED
     | CKF_USER_PIN_INITIALIZED;
-  /* FIXME: Support this later: CKF_RNG.
-     FIXME: CKF_USER_PIN_INITIALIZED only if PIN is not default pin?
+
+  if (slot_token_has_rng (slot))
+    pInfo->flags |= CKF_RNG;
+
+  /* FIXME: CKF_USER_PIN_INITIALIZED only if PIN is not default pin?
      FIXME: CKF_LOGIN_REQUIRED needed?  We could implement login via
      the "SCD CHECKPIN" command.  I am not sure how this mixes with
      CKF_PROTECTED_AUTHENTICATION_PATH.

+ 9 - 0
src/slots.c

@@ -657,6 +657,15 @@ slot_get_id (slot_iterator_t slot)
   return slot;
 }
 
+/* Return true if the token supports the GET CHALLENGE operation. */
+bool
+slot_token_has_rng (slot_iterator_t id)
+{
+  struct slot *slot = scute_table_data (slots, id);
+
+  return slot->info.rng_available;
+}
+
 
 /* Mechanism management.  */
 

+ 3 - 0
src/slots.h

@@ -116,6 +116,9 @@ void slot_token_pincount (slot_iterator_t id, int *max, int *len);
 /* Return the ID of slot SLOT.  */
 CK_SLOT_ID slot_get_id (slot_iterator_t slot);
 
+/* Return true if the token supports the GET CHALLENGE operation. */
+bool slot_token_has_rng (slot_iterator_t id);
+
 
 /* Begin iterating over the list of mechanisms.  If succeeds, will be
    followed up by a slot_iterate_end.  */