[git] Scute - branch, master, updated. scute-1.5.0-10-gff9e757

by Werner Koch cvs at cvs.gnupg.org
Thu Feb 14 20:58:35 CET 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PKCS#11 token on top of gpg-agent".

The branch, master has been updated
       via  ff9e757e352f1b4cf3b4625eb4398415051367af (commit)
      from  c4be31f93ea5f471f7ca127ed61b02fc14c418d6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ff9e757e352f1b4cf3b4625eb4398415051367af
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 14 20:57:57 2019 +0100

    Rework of some parts to support several keys pers slot.
    
    * src/cert.h (struct cert): Add member certref.
    * src/agent.h (struct agent_card_info_s): Remove legacy data.
    * src/agent.c (learn_status_cb): Ditto.
    (scute_agent_get_cert): Copy the certref to the cert object.
    * src/cert-object.c (scute_attr_cert): Add arg 'grip' and use new
    scheme for CKA_ID.
    (scute_attr_prv): Ditto.
    * src/gpgsm.c (struct search): Rename to search_cb_parm for clarity.
    Add member 'grip'.
    (search_cb): Pass GRIP to scute_attr_prv and scute_attr_cert.
    (scute_gpgsm_get_cert): Convey GRIP.
    * src/slots.c (slot_init): Replace fixed "OPENPGP.3" by a loop over
    all available keyrefs.
    (session_sign): Actually use the set key.  Add a few checks.
    
    * src/settings.h (LIBRARY_DESCRIPTION): Rename to "GnuPG".
    
    * src/slots.c (mechanism_alloc): Change ulMaxKeySize to 4096.
    
    * src/p11-gettokeninfo.c (C_GetTokenInfo): Set ulMaxSessionCount to
    CK_EFFECTIVELY_INFINITE.
    
    * tests/t-getattribute.c (dump_one_string): New.
    (dump_object): Use for some objects.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/configure.ac b/configure.ac
index 3615a49..bc56dae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,9 +73,9 @@ LIBSCUTE_LT_REVISION=3
 VERSION_MAJOR=1
 VERSION_MINOR=0
 
-NEED_GPG_ERROR_VERSION=1.14
-NEED_LIBASSUAN_VERSION=2.0.0
-NEED_GPGSM_VERSION=1.9.6
+NEED_GPG_ERROR_VERSION=1.24
+NEED_LIBASSUAN_VERSION=2.5.0
+NEED_GPGSM_VERSION=2.2.0
 # Some status variables to give feedback at the end of a configure run.
 have_gpg_error=no
 have_libassuan=no
@@ -252,7 +252,7 @@ AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
 # Generate values for the DLL version info
 if test "$have_w32_system" = yes; then
     BUILD_TIMESTAMP=`date --iso-8601=minutes`
-    changequote(,)dnl 
+    changequote(,)dnl
     BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
     changequote([,])dnl
     BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION_DEC}"
@@ -439,7 +439,7 @@ die=no
 if test "$have_gpg_error" = "no"; then
    die=yes
    AC_MSG_NOTICE([[
-***  
+***
 *** You need libgpg-error to build this program.
 **  This library is for example available at
 ***   ftp://ftp.gnupg.org/pub/gcrypt/libgpg-error
diff --git a/src/agent.c b/src/agent.c
index f8bea95..4fe969b 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -669,26 +669,6 @@ learn_status_cb (void *opaque, const char *line)
 
           strncpy (kinfo->grip, hexgrip, sizeof kinfo->grip);
           kinfo->grip[sizeof kinfo->grip -1] = 0;
-
-          /* Keep legacy info.  */
-	  if (!strcmp (keyref, "OPENPGP.1"))
-            {
-              strncpy (parm->grip1, hexgrip, sizeof parm->grip1);
-              parm->grip1[sizeof parm->grip1 - 1] = 0;
-              parm->grip1valid = 1;
-            }
-          else if (!strcmp (keyref, "OPENPGP.2"))
-            {
-              strncpy (parm->grip2, hexgrip, sizeof parm->grip2);
-              parm->grip2[sizeof parm->grip2 - 1] = 0;
-              parm->grip2valid = 1;
-            }
-          else if (!strcmp (keyref, "OPENPGP.3"))
-            {
-              strncpy (parm->grip3, hexgrip, sizeof parm->grip3);
-              parm->grip3[sizeof parm->grip3 - 1] = 0;
-              parm->grip3valid = 1;
-            }
         }
     }
   else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
@@ -854,7 +834,7 @@ pksign_cb (void *opaque, const void *buffer, size_t length)
 }
 
 /* Parse the result of an pksign operation which is a s-expression in
-   normal form that looks like (7:sig-val(3:rsa(1:s<LENGTH>:<DATA>))).
+   canonical form that looks like (7:sig-val(3:rsa(1:s<LENGTH>:<DATA>))).
    The raw result is stored in RESULT of size *LEN, and *LEN is
    adjusted to the actual size.  */
 static gpg_error_t
@@ -897,7 +877,7 @@ pksign_parse_result (const struct signature *sig,
   if (! n)
     return gpg_error (GPG_ERR_INV_SEXP);
 
-  /* Remove nul byte prepended by gpg-agent. */
+  /* Remove a possible prepended zero byte. */
   if (!*s && n > 1)
     {
       n -= 1;
@@ -990,9 +970,13 @@ decode_hash (const unsigned char *data, int len,
   return 0;
 }
 
-/* Call the agent to learn about a smartcard.  */
+
+/* Call the agent to sign (DATA,LEN) using the key described by
+ * HEXGRIP.  Stores the signature in SIG_RESULT and its lengtn at
+ * SIG_LEN; SIGLEN must initially point to the allocated size of
+ * SIG_RESULT.  */
 gpg_error_t
-scute_agent_sign (char *grip, unsigned char *data, int len,
+scute_agent_sign (const char *hexgrip, unsigned char *data, int len,
 		  unsigned char *sig_result, unsigned int *sig_len)
 {
   char cmd[150];
@@ -1020,10 +1004,11 @@ scute_agent_sign (char *grip, unsigned char *data, int len,
       return 0;
     }
 
-  if (grip == NULL || sig_result == NULL)
+  if (!hexgrip || !sig_result)
     return gpg_error (GPG_ERR_INV_ARG);
 
-  snprintf (cmd, sizeof (cmd), "SIGKEY %s", grip);
+  snprintf (cmd, sizeof (cmd), "SIGKEY %s", hexgrip);
+
   err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb,
 			 NULL, NULL, NULL);
   if (err)
@@ -1149,6 +1134,8 @@ scute_agent_get_cert (const char *certref, struct cert *cert)
 
   cert->cert_der = cert_s.cert_der;
   cert->cert_der_len = cert_s.cert_der_len;
+  strncpy (cert->certref, certref, sizeof cert->certref -1);
+  cert->certref[sizeof cert->certref - 1] = 0;
 
   return 0;
 }
diff --git a/src/agent.h b/src/agent.h
index 3fb2f89..367b7e2 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -90,12 +90,6 @@ struct agent_card_info_s
 			   cache it anyway.  */
   int chvmaxlen[3];	/* Maximum allowed length of a CHV.  */
   int chvretry[3];	/* Allowed retries for the CHV; 0 = blocked.  */
-  char grip1valid;
-  char grip2valid;
-  char grip3valid;
-  char grip1[41];
-  char grip2[41];
-  char grip3[41];
   int rng_available;    /* True if the GET CHALLENGE operation
                            is supported. */
   int is_piv;           /* True if this is a PIV card.  */
@@ -131,11 +125,11 @@ void scute_agent_release_card_info (struct agent_card_info_s *info);
 key_info_t scute_find_kinfo (agent_card_info_t info, const char *keyref);
 
 
-/* Sign the data DATA of length LEN with the key GRIP and return the
-   signature in SIG_RESULT and SIG_LEN.  */
-gpg_error_t scute_agent_sign (char *grip, unsigned char *data, int len,
-			      unsigned char *sig_result,
-			      unsigned int *sig_len);
+/* Sign the data DATA of length LEN with the key HEXGRIP and return
+ * the signature in SIG_RESULT and SIG_LEN.  */
+gpg_error_t scute_agent_sign (const char *hexgrip,
+                              unsigned char *data, int len,
+			      unsigned char *sig_result, unsigned int *sig_len);
 
 /* Determine if FPR is trusted.  */
 gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted);
diff --git a/src/cert-object.c b/src/cert-object.c
index 6b559a8..a0f07bd 100644
--- a/src/cert-object.c
+++ b/src/cert-object.c
@@ -414,7 +414,7 @@ scute_attr_free (CK_ATTRIBUTE_PTR attr, CK_ULONG attr_count)
 
 
 gpg_error_t
-scute_attr_cert (struct cert *cert,
+scute_attr_cert (struct cert *cert, const char *grip,
 		 CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp)
 {
   CK_RV err = 0;
@@ -432,9 +432,6 @@ scute_attr_cert (struct cert *cert,
   CK_BBOOL obj_token = CK_TRUE;
   CK_BBOOL obj_private = CK_FALSE;
   CK_BBOOL obj_modifiable = CK_FALSE;
-  CK_BYTE obj_label[] = { 'D', 'u', 'm', 'm', 'y', ' ',
-			  'L', 'a', 'b', 'e', 'l' };
-
   CK_CERTIFICATE_TYPE obj_cert_type = CKC_X_509;
   CK_BBOOL obj_trusted = cert->is_trusted;
   CK_ULONG obj_cert_cat = 0;
@@ -493,8 +490,14 @@ scute_attr_cert (struct cert *cert,
     err = attr_one (attr, &attr_count, CKA_MODIFIABLE,
                     &obj_modifiable, sizeof obj_modifiable);
   if (!err)
-    err = attr_one (attr, &attr_count, CKA_LABEL,
-                    &obj_label, sizeof obj_label);
+    {
+      if (*cert->certref)
+        err = attr_one (attr, &attr_count, CKA_LABEL,
+                        cert->certref, strlen (cert->certref));
+      else
+        err = attr_one (attr, &attr_count, CKA_LABEL,
+                        "DummyLabel", 10);
+    }
   if (!err)
     err = attr_one (attr, &attr_count, CKA_CERTIFICATE_TYPE,
                     &obj_cert_type, sizeof obj_cert_type);
@@ -543,22 +546,19 @@ scute_attr_cert (struct cert *cert,
     err = attr_one (attr, &attr_count, CKA_SUBJECT,
                     subject_start, subject_len);
 
-#if 0
-  /* If we get the info directly from the card, we don't have a
-     fingerprint, and parsing the subject key identifier is quite a
-     mouth full.  Let's try a different approach for now.  */
+  /* We construct the CKA_ID from the CERTREF and the KEYGRIP.  This
+   * allows us to use both values as needed.  */
   if (!err)
-    err = attr_one (attr, &attr_count, CKA_ID,
-                    cert->fpr, 40);
-#else
-  {
-    char certptr[40];
-    snprintf (certptr, DIM (certptr), "%p", cert);
-    if (!err)
+    {
+      char cka_id_buffer[200];
+
+      snprintf (cka_id_buffer, sizeof cka_id_buffer, "%s %s",
+                *cert->certref ? cert->certref:"-",
+                grip && *grip? grip : "?" );
       err = attr_one (attr, &attr_count, CKA_ID,
-                      certptr, strlen (certptr));
-  }
-#endif
+                      cka_id_buffer, strlen (cka_id_buffer));
+    }
+
 
   if (!err)
     err = attr_one (attr, &attr_count, CKA_ISSUER,
@@ -599,8 +599,8 @@ scute_attr_cert (struct cert *cert,
 
 
 gpg_error_t
-scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp,
-		CK_ULONG *attr_countp)
+scute_attr_prv (struct cert *cert, const char *grip,
+                CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp)
 {
   CK_RV err = 0;
   CK_ATTRIBUTE_PTR attr;
@@ -617,9 +617,6 @@ scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp,
   CK_BBOOL obj_token = CK_TRUE;
   CK_BBOOL obj_private = CK_FALSE;
   CK_BBOOL obj_modifiable = CK_FALSE;
-  CK_BYTE obj_label[] = { 'O', 'P', 'E', 'N', 'P', 'G',
-			  'P', '.', '3' };
-
   CK_KEY_TYPE obj_key_type = CKK_RSA;
   CK_DATE obj_start_date;
   CK_DATE obj_end_date;
@@ -686,28 +683,31 @@ scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp,
     err = attr_one (attr, &attr_count, CKA_MODIFIABLE,
                     &obj_modifiable, sizeof obj_modifiable);
   if (!err)
-    err = attr_one (attr, &attr_count, CKA_LABEL,
-                    &obj_label, sizeof obj_label);
+    {
+      if (*cert->certref)
+        err = attr_one (attr, &attr_count, CKA_LABEL,
+                        cert->certref, strlen (cert->certref));
+      else
+        err = attr_one (attr, &attr_count, CKA_LABEL,
+                        "DummyLabel", 10);
+    }
 
   if (!err)
     err = attr_one (attr, &attr_count, CKA_KEY_TYPE,
                     &obj_key_type, sizeof obj_key_type);
-#if 0
-  /* If we get the info directly from the card, we don't have a
-     fingerprint, and parsing the subject key identifier is quite a
-     mouth full.  Let's try a different approach for now.  */
+
+  /* We construct the CKA_ID from the CERTREF and the KEYGRIP.  This
+   * allows us to use both values as needed.  */
   if (!err)
-    err = attr_one (attr, &attr_count, CKA_ID,
-                    &cert->fpr, 40);
-#else
-  {
-    char certptr[40];
-    snprintf (certptr, DIM (certptr), "%p", cert);
-    if (!err)
+    {
+      char cka_id_buffer[200];
+
+      snprintf (cka_id_buffer, sizeof cka_id_buffer, "%s %s",
+                *cert->certref ? cert->certref:"-",
+                grip && *grip? grip : "?" );
       err = attr_one (attr, &attr_count, CKA_ID,
-                      certptr, strlen (certptr));
-  }
-#endif
+                      cka_id_buffer, strlen (cka_id_buffer));
+    }
 
 #if 0
   /* For now, we disable these fields.  We can parse them from the
diff --git a/src/cert.h b/src/cert.h
index eb09802..b57db0f 100644
--- a/src/cert.h
+++ b/src/cert.h
@@ -2,7 +2,7 @@
    Copyright (C) 2006, 2007 g10 Code GmbH
 
    This file is part of Scute.
- 
+
    Scute is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -46,6 +46,10 @@ struct cert
   /* True if we started to fill in a certificate.  */
   bool valid;
 
+  /* The certifciate reference if retrieved from a card or an empty
+   * string if not known.  Example value: "OPENPGP.3".  */
+  char certref[25];
+
 #if 1
   /* We disable some elements, because they are easy to get from gpgsm
      but hard to get from the card directly.  These fields are only
@@ -121,15 +125,15 @@ gpg_error_t scute_gpgsm_search_certs_by_grip (const char *grip,
 gpg_error_t scute_gpgsm_search_certs_by_fpr (const char *fpr,
 					     cert_search_cb_t search_cb,
 					     void *search_cb_hook);
-     
+
 

 /* From cert-object.c.  */
 
-gpg_error_t scute_attr_cert (struct cert *cert,
+gpg_error_t scute_attr_cert (struct cert *cert, const char *grip,
 			     CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp);
 
-gpg_error_t scute_attr_prv (struct cert *cert, CK_ATTRIBUTE_PTR *attrp,
-			    CK_ULONG *attr_countp);
+gpg_error_t scute_attr_prv (struct cert *cert, const char *grip,
+                            CK_ATTRIBUTE_PTR *attrp, CK_ULONG *attr_countp);
 
 void scute_attr_free (CK_ATTRIBUTE_PTR attr, CK_ULONG attr_count);
 
diff --git a/src/gpgsm.c b/src/gpgsm.c
index 57a364f..27e5036 100644
--- a/src/gpgsm.c
+++ b/src/gpgsm.c
@@ -49,19 +49,21 @@
 #include "debug.h"
 
 

-struct search
+/* Communication object for search_cb.  */
+struct search_cb_parm
 {
   bool found;    /* Set to true if a private key object was found.  */
   cert_get_cb_t cert_get_cb;
   void *hook;
   bool with_chain;
+  const char *grip;
 };
 
 
 static gpg_error_t
 search_cb (void *hook, struct cert *cert)
 {
-  struct search *ctx = hook;
+  struct search_cb_parm *ctx = hook;
   gpg_error_t err = 0;
 
   CK_ATTRIBUTE_PTR attrp;
@@ -70,7 +72,7 @@ search_cb (void *hook, struct cert *cert)
   /* Add the private key object only once.  */
   if (!ctx->found)
     {
-      err = scute_attr_prv (cert, &attrp, &attr_countp);
+      err = scute_attr_prv (cert, ctx->grip, &attrp, &attr_countp);
       if (err)
 	return err;
 
@@ -92,7 +94,7 @@ search_cb (void *hook, struct cert *cert)
     scute_gpgsm_search_certs_by_fpr (cert->chain_id, search_cb, ctx);
 
   /* Turn this certificate into a certificate object.  */
-  err = scute_attr_cert (cert, &attrp, &attr_countp);
+  err = scute_attr_cert (cert, ctx->grip, &attrp, &attr_countp);
   if (err)
     return err;
 
@@ -123,12 +125,15 @@ scute_gpgsm_get_cert (char *grip, const char *certref,
                       cert_get_cb_t cert_get_cb, void *hook)
 {
   gpg_error_t err;
-  struct search search;
+  struct search_cb_parm search;
 
   search.found = false;
   search.cert_get_cb = cert_get_cb;
   search.hook = hook;
   search.with_chain = false;
+  search.grip = grip;
+
+  DEBUG (DBG_INFO, "scute_gpgsm_get_cert: certref='%s'", certref);
 
   /* If the cert is requested from the card, we try to get it from
    * the card as well.  */
@@ -154,6 +159,7 @@ scute_gpgsm_get_cert (char *grip, const char *certref,
 	}
     }
 
+  DEBUG (DBG_INFO, "scute_gpgsm_get_cert: falling back to gpgsm");
   search.with_chain = true;
   err = scute_gpgsm_search_certs_by_grip (grip, search_cb, &search);
   return err;
diff --git a/src/p11-gettokeninfo.c b/src/p11-gettokeninfo.c
index 3a78598..4094f42 100644
--- a/src/p11-gettokeninfo.c
+++ b/src/p11-gettokeninfo.c
@@ -97,9 +97,9 @@ C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
   else if (len == 0)
     pInfo->flags |= CKF_USER_PIN_LOCKED;
 
-  pInfo->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION;
+  pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
   pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
-  pInfo->ulMaxRwSessionCount = CK_UNAVAILABLE_INFORMATION;
+  pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
   pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
   slot_token_maxpinlen (slot, &pInfo->ulMaxPinLen, &pInfo->ulMinPinLen);
 
diff --git a/src/p11-sign.c b/src/p11-sign.c
index ceb262e..344bfd8 100644
--- a/src/p11-sign.c
+++ b/src/p11-sign.c
@@ -37,6 +37,18 @@
 #include "slots.h"
 
 
+/* Sign the data (PDATA,ULDATALEN) using the information recorded in
+ * the HSESSION by C_SignInit.  PSIGNAURE is a buffer to receive the
+ * signature.  The length of that buffer must be stored in a variable
+ * to which PULSIGNATURELEN points to; on success that length is
+ * updated to the actual length of the signature in PULSIGNATURE.
+ *
+ * If the function returns CKR_BUFFER_TOO_SMALL no further C_SignInit
+ * is required, instead the function can be called again with a larger
+ * buffer.  On a successful operation CKR_OK is returned and other
+ * signatures may be created without an new C_SignInit.  On all other
+ * return codes a new C_SignInit is required.
+ */
 CK_RV CK_SPEC
 C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
         CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
@@ -56,11 +68,14 @@ C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
   if (err)
     goto out;
 
-  /* FIXME: Who cares if they called sign init correctly.  */
+  /* FIXME: Check that C_SignInit has been called.  */
+
   err = session_sign (slot, session, pData, ulDataLen,
 		      pSignature, pulSignatureLen);
 
  out:
+  /* FIXME: Update the flag which indicates whether C_SignInit has
+   * been called.  */
   scute_global_unlock ();
   return err;
 }
diff --git a/src/p11-signinit.c b/src/p11-signinit.c
index 560f37e..598d91d 100644
--- a/src/p11-signinit.c
+++ b/src/p11-signinit.c
@@ -36,7 +36,11 @@
 #include "locking.h"
 #include "slots.h"
 
-
+/* Prepare a signature operation.  HSESSION is the session's handle.
+ * PMECHANISM describes the mechanism to be used.  HKEY describes the
+ * key to be used.  After calling this function either C_Sign or
+ * (C_SignUpdate, C_SignFinal) can be used to actually sign the data.
+ * The preparation is valid until C_Sign or C_SignFinal.   */
 CK_RV CK_SPEC
 C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
             CK_OBJECT_HANDLE hKey)
diff --git a/src/settings.h b/src/settings.h
index 40375c7..8f3f4c8 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -2,7 +2,7 @@
    Copyright (C) 2006 g10 Code GmbH
 
    This file is part of Scute.
- 
+
    Scute is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -37,14 +37,14 @@
 /* The manufacturer ID in UTF-8.  Only up to 32 bytes are used.  */
 #define MANUFACTURER_ID	"g10 Code GmbH"
 
-#define LIBRARY_DESCRIPTION	"Cryptoki for SCDaemon"
+#define LIBRARY_DESCRIPTION "Cryptoki for GnuPG"
 
 /* The version number of this library.  Defined by config.h.  */
 #if (! defined VERSION_MAJOR) || (! defined VERSION_MINOR)
 #error Define VERSION_MAJOR and VERSION_MINOR in config.h.
 #endif
 
-/* FIXME: The following should be queried from SCD, really.  */
+/* FIXME: The following should be queried from GnuPG, really.  */
 #define SLOT_DESCRIPTION "GnuPG Smart Card Daemon"
 #define SLOT_MANUFACTURER_ID "g10 Code GmbH"
 #define SLOT_HARDWARE_VERSION_MAJOR 0
diff --git a/src/slots.c b/src/slots.c
index 5dfc94a..1e9b1a6 100644
--- a/src/slots.c
+++ b/src/slots.c
@@ -167,7 +167,7 @@ mechanism_alloc (void **data_r, void *hook)
   /* Set some default values.  */
   mechanism->type = CKM_RSA_PKCS;
   mechanism->info.ulMinKeySize = 1024;
-  mechanism->info.ulMaxKeySize = 1024;
+  mechanism->info.ulMaxKeySize = 4096;
   mechanism->info.flags = CKF_HW | (*flags);
 
   *data_r = mechanism;
@@ -384,16 +384,20 @@ slot_init (slot_iterator_t id)
 {
   gpg_error_t err = 0;
   struct slot *slot = scute_table_data (slots, id);
+  key_info_t ki;
 
-  err = scute_gpgsm_get_cert (slot->info.grip3, "OPENPGP.3", add_object, slot);
-  if (err)
-    goto init_out;
+  for (ki = slot->info.kinfo; ki; ki = ki->next)
+    {
+      err = scute_gpgsm_get_cert (ki->grip, ki->keyref, add_object, slot);
+      if (err)
+        goto leave;
+    }
 
   /* FIXME: Perform the rest of the initialization of the
      token.  */
   slot->token_present = true;
 
- init_out:
+ leave:
   if (err)
     slot_reset (id);
 
@@ -1027,6 +1031,7 @@ session_set_signing_key (slot_iterator_t id, session_iterator_t sid,
   if (err)
     return err;
 
+  /* FIXME: What kind of strange loop is this?  */
   while (attr_count-- > 0)
     if (attr->type == CKA_CLASS)
       break;
@@ -1045,7 +1050,7 @@ session_set_signing_key (slot_iterator_t id, session_iterator_t sid,
 }
 
 
-/* FIXME: The dscription is wrong:
+/* FIXME: The description is wrong:
    Set the signing key for session SID in slot ID to KEY.  */
 CK_RV
 session_sign (slot_iterator_t id, session_iterator_t sid,
@@ -1053,27 +1058,57 @@ session_sign (slot_iterator_t id, session_iterator_t sid,
 	      CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
 {
   struct slot *slot = scute_table_data (slots, id);
+  struct session *session = scute_table_data (slot->sessions, sid);
   gpg_error_t err;
+  CK_ATTRIBUTE_PTR attr;
+  CK_ULONG attr_count;
+  CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
   unsigned int sig_len;
+  CK_BYTE key_id[100];
+  int i;
+  const char *keyref;
 
-   /* FIXME: Who cares if they called sign init correctly.  Should
-      check the signing_key object.  */
+  if (!pSignature)
+    return CKR_ARGUMENTS_BAD;
 
-  if (pSignature == NULL_PTR)
-    {
-      err = scute_agent_sign (NULL, NULL, 0, NULL, &sig_len);
-      if (err)
-	return scute_gpg_err_to_ck (err);
-      *pulSignatureLen = sig_len;
-      return 0;
-    }
+  if (!session->signing_key)
+    return CKR_OPERATION_NOT_INITIALIZED;
+
+  err = slot_get_object (id, session->signing_key, &attr, &attr_count);
+  if (err)
+    return err;
+  if (attr_count == (CK_ULONG) -1)
+    return CKR_KEY_HANDLE_INVALID;
+  if (attr->ulValueLen != sizeof (key_class)
+      || memcmp (attr->pValue, &key_class, sizeof (key_class)))
+    return CKR_KEY_HANDLE_INVALID;
+
+  /* Find the CKA_ID */
+  for (i = 0; i < attr_count; i++)
+    if (attr[i].type == CKA_ID)
+      break;
+  if (i == attr_count)
+    return CKR_GENERAL_ERROR;
+
+  if (attr[i].ulValueLen >= sizeof key_id - 1)
+    return CKR_GENERAL_ERROR;
+  strncpy (key_id, attr[i].pValue, attr[i].ulValueLen);
+  key_id[attr[i].ulValueLen] = 0;
+  DEBUG (DBG_INFO, "Found CKA_ID '%s'", key_id);
+  for (keyref=key_id; *keyref && *keyref != ' '; keyref++)
+    ;
+  if (*keyref)
+    keyref++;  /* Point to the grip.  */
+  DEBUG (DBG_INFO, "Using keyref '%s'", keyref);
 
   sig_len = *pulSignatureLen;
-  err = scute_agent_sign (slot->info.grip3, pData, ulDataLen,
-			  pSignature, &sig_len);
-  /* FIXME: Oh well.  */
-  if (gpg_err_code (err) == GPG_ERR_INV_ARG)
-    return CKR_BUFFER_TOO_SMALL;
+  err = scute_agent_sign (keyref, pData, ulDataLen, pSignature, &sig_len);
 
-  return scute_gpg_err_to_ck (err);
+  /* Take care of error codes which are not mapped by default.  */
+  if (gpg_err_code (err) == GPG_ERR_INV_LENGTH)
+    return CKR_BUFFER_TOO_SMALL;
+  else if (gpg_err_code (err) == GPG_ERR_INV_ARG)
+    return CKR_ARGUMENTS_BAD;
+  else
+    return scute_gpg_err_to_ck (err);
 }
diff --git a/tests/t-auth.c b/tests/t-auth.c
index 53c23ed..ba69ccd 100644
--- a/tests/t-auth.c
+++ b/tests/t-auth.c
@@ -2,7 +2,7 @@
    Copyright (C) 2006 g10 Code GmbH
 
    This file is part of Scute.
- 
+
    Scute is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -128,7 +128,7 @@ main (int argc, char *argv[])
       err = C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL,
 			   &session);
       fail_if_err (err);
-     
+
       printf ("    Session ID: %lu\n", session);
 
       err = C_FindObjectsInit (session, attr, DIM (attr));
diff --git a/tests/t-getattribute.c b/tests/t-getattribute.c
index a2be7c0..982aaae 100644
--- a/tests/t-getattribute.c
+++ b/tests/t-getattribute.c
@@ -85,6 +85,35 @@ dump_one (CK_ATTRIBUTE_PTR attr, unsigned char *data, unsigned int max_size)
 
 
 CK_RV
+dump_one_string (CK_ATTRIBUTE_PTR attr,
+                 unsigned char *data, unsigned int max_size)
+{
+  unsigned int i;
+  int blanks = 0;
+
+  if (attr->ulValueLen > max_size)
+    {
+      putc ('\n', stdout);
+      return CKR_GENERAL_ERROR;
+    }
+  for (i = 0; i < attr->ulValueLen; i++)
+    {
+      if (data[i] == ' ')
+        {
+          blanks++;
+          continue;
+        }
+      for (; blanks; blanks--)
+        putc (' ', stdout);
+      putc (data[i], stdout);
+    }
+  putc ('\n', stdout);
+
+  return 0;
+}
+
+
+CK_RV
 dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
 {
   CK_RV err;
@@ -186,9 +215,8 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
 	printf ("     Certificate Modifiable: %s\n",
 		cert_modifiable ? "true" : "false");
 
-	printf ("     Certificate Label: Length %lu\n",
-		cert_attr[4].ulValueLen);
-	err = dump_one (&cert_attr[4], cert_label, sizeof (cert_label));
+	printf ("     Certificate Label: ");
+	err = dump_one_string (&cert_attr[4], cert_label, sizeof (cert_label));
 	fail_if_err (err);
 
 	fail_if_err ((cert_attr[5].ulValueLen != sizeof (cert_trusted)) ?
@@ -246,9 +274,8 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
 	err = dump_one (&cert_attr[10], cert_subject, sizeof (cert_subject));
 	fail_if_err (err);
 
-	printf ("     Certificate ID: Length %lu\n",
-		cert_attr[11].ulValueLen);
-	err = dump_one (&cert_attr[11], cert_id, sizeof (cert_id));
+	printf ("     Certificate ID: ");
+	err = dump_one_string (&cert_attr[11], cert_id, sizeof (cert_id));
 	fail_if_err (err);
 
 	printf ("     Certificate Issuer: Length %lu\n",
@@ -405,14 +432,12 @@ dump_object (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
 	printf ("     Key Modifiable: %s\n",
 		key_modifiable ? "true" : "false");
 
-	printf ("     Key Label: Length %lu\n",
-		key_attr[4].ulValueLen);
-	err = dump_one (&key_attr[4], key_label, sizeof (key_label));
+	printf ("     Key Label: ");
+	err = dump_one_string (&key_attr[4], key_label, sizeof (key_label));
 	fail_if_err (err);
 
-	printf ("     Key ID: Length %lu\n",
-		key_attr[5].ulValueLen);
-	err = dump_one (&key_attr[5], key_id, sizeof (key_id));
+	printf ("     Key ID: ");
+	err = dump_one_string (&key_attr[5], key_id, sizeof (key_id));
 	fail_if_err (err);
 
 	if (key_attr[6].ulValueLen && key_attr[7].ulValueLen)
diff --git a/tests/t-getinfo.c b/tests/t-getinfo.c
index b90f132..f246254 100644
--- a/tests/t-getinfo.c
+++ b/tests/t-getinfo.c
@@ -2,7 +2,7 @@
    Copyright (C) 2006 g10 Code GmbH
 
    This file is part of Scute.
- 
+
    Scute is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -46,7 +46,7 @@ main (int argc, char *argv[])
   err = C_GetInfo (&info);
   fail_if_err (err);
 
-  printf ("Cryptoki version: %i.%i\n", info.cryptokiVersion.major, 
+  printf ("Cryptoki version: %i.%i\n", info.cryptokiVersion.major,
 	  info.cryptokiVersion.minor);
   if (info.cryptokiVersion.major != 2)
     fail ("Cryptoki major version is not 2");
@@ -59,8 +59,8 @@ main (int argc, char *argv[])
     fail ("Flags is not 0");
 
   printf ("Library description: %.32s\n", info.libraryDescription);
-  printf ("Library version: %i.%i\n", info.cryptokiVersion.major, 
-	  info.cryptokiVersion.minor);
+  printf ("Library version: %i.%i\n", info.libraryVersion.major,
+	  info.libraryVersion.minor);
 
   return 0;
 }

-----------------------------------------------------------------------

Summary of changes:
 configure.ac           | 10 +++---
 src/agent.c            | 39 ++++++++----------------
 src/agent.h            | 16 +++-------
 src/cert-object.c      | 82 +++++++++++++++++++++++++-------------------------
 src/cert.h             | 14 ++++++---
 src/gpgsm.c            | 16 +++++++---
 src/p11-gettokeninfo.c |  4 +--
 src/p11-sign.c         | 17 ++++++++++-
 src/p11-signinit.c     |  6 +++-
 src/settings.h         |  6 ++--
 src/slots.c            | 79 ++++++++++++++++++++++++++++++++++--------------
 tests/t-auth.c         |  4 +--
 tests/t-getattribute.c | 49 ++++++++++++++++++++++--------
 tests/t-getinfo.c      |  8 ++---
 14 files changed, 210 insertions(+), 140 deletions(-)


hooks/post-receive
-- 
PKCS#11 token on top of gpg-agent
http://git.gnupg.org




More information about the Gnupg-commits mailing list