Browse Source

Implement C_GenerateRandom.

* src/agent.c (scute_agent_get_random, get_challenge_data_cb):
New functions.
* src/agent.h (scute_agent_get_random): New prototype.
* src/p11-generaterandom.c (C_GenerateRandom): Implement feature.

Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
Damien Goutte-Gattat 9 years ago
parent
commit
764de881a3
3 changed files with 62 additions and 5 deletions
  1. 36 0
      src/agent.c
  2. 3 0
      src/agent.h
  3. 23 5
      src/p11-generaterandom.c

+ 36 - 0
src/agent.c

@@ -1281,6 +1281,42 @@ scute_agent_get_cert (int no, struct cert *cert)
   return 0;
 }
 
+struct random_request
+{
+    unsigned char *buffer;
+    size_t len;
+};
+
+gpg_error_t
+get_challenge_data_cb (void *opaque, const void *line, size_t len)
+{
+  struct random_request *request = opaque;
+
+  if (len != request->len)
+    return gpg_error (GPG_ERR_INV_LENGTH);
+
+  memcpy (request->buffer, line, len);
+
+  return 0;
+}
+
+gpg_error_t
+scute_agent_get_random (unsigned char *data, size_t len)
+{
+    char command[16];
+    gpg_error_t err;
+    struct random_request request;
+
+    snprintf (command, sizeof(command), "SCD RANDOM %lu", len);
+
+    request.buffer = data;
+    request.len = len;
+    err = assuan_transact (agent_ctx, command, get_challenge_data_cb,
+                           &request, NULL, NULL, NULL, NULL);
+
+    return err;
+}
+
 
 void
 scute_agent_finalize (void)

+ 3 - 0
src/agent.h

@@ -113,4 +113,7 @@ gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted);
 /* Try to get certificate for key numer NO.  */
 gpg_error_t scute_agent_get_cert (int no, struct cert *cert);
 
+/* Get random bytes from the card. */
+gpg_error_t scute_agent_get_random (unsigned char *data, size_t len);
+
 #endif	/* AGENT_H */

+ 23 - 5
src/p11-generaterandom.c

@@ -33,14 +33,32 @@
 
 #include "cryptoki.h"
 
+#include "locking.h"
+#include "slots.h"
+#include "agent.h"
+#include "error-mapping.h"
+
 
 CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom)
      (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
       CK_ULONG ulRandomLen)
 {
-  /* FIXME: Implement me.  */
-  (void) hSession;
-  (void) pRandomData;
-  (void) ulRandomLen;
-  return CKR_FUNCTION_NOT_SUPPORTED;
+  CK_RV err;
+  slot_iterator_t slot;
+  session_iterator_t session;
+
+  if (pRandomData == NULL_PTR)
+    return CKR_ARGUMENTS_BAD;
+
+  err = scute_global_lock ();
+  if (err)
+    return err;
+
+  err = slots_lookup_session (hSession, &slot, &session);
+  if (!err)
+    err = scute_gpg_err_to_ck (scute_agent_get_random (pRandomData,
+                                                       ulRandomLen));
+
+  scute_global_unlock ();
+  return err;
 }