With --enable-gpg the keyservers are now build and a first test using gpg2
[gnupg.git] / sm / sign.c
index 473cf93..d656825 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -15,7 +15,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 #include <config.h>
@@ -126,7 +127,7 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
 /* Get the default certificate which is defined as the first one our
    keyDB returns and has a secret key available. */
 int
-gpgsm_get_default_cert (ksba_cert_t *r_cert)
+gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
 {
   KEYDB_HANDLE hd;
   ksba_cert_t cert = NULL;
@@ -156,7 +157,7 @@ gpgsm_get_default_cert (ksba_cert_t *r_cert)
       p = gpgsm_get_keygrip_hexstring (cert);
       if (p)
         {
-          if (!gpgsm_agent_havekey (p))
+          if (!gpgsm_agent_havekey (ctrl, p))
             {
               xfree (p);
               keydb_release (hd);
@@ -180,7 +181,7 @@ gpgsm_get_default_cert (ksba_cert_t *r_cert)
 
 
 static ksba_cert_t
-get_default_signer (void)
+get_default_signer (ctrl_t ctrl)
 {
   KEYDB_SEARCH_DESC desc;
   ksba_cert_t cert = NULL;
@@ -189,7 +190,7 @@ get_default_signer (void)
 
   if (!opt.local_user)
     {
-      rc = gpgsm_get_default_cert (&cert);
+      rc = gpgsm_get_default_cert (ctrl, &cert);
       if (rc)
         {
           if (rc != -1)
@@ -365,7 +366,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
   /* If no list of signers is given, use a default one. */
   if (!signerlist)
     {
-      ksba_cert_t cert = get_default_signer ();
+      ksba_cert_t cert = get_default_signer (ctrl);
       if (!cert)
         {
           log_error ("no default signer found\n");
@@ -426,6 +427,35 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
           goto leave;
         }
     }
+
+
+  /* Check whether one of the certificates is qualified.  Note that we
+     already validated the certificate and thus the user data stored
+     flag must be available. */
+  for (cl=signerlist; cl; cl = cl->next)
+    {
+      size_t buflen;
+      char buffer[1];
+      
+      err = ksba_cert_get_user_data (cl->cert, "is_qualified", 
+                                     &buffer, sizeof (buffer), &buflen);
+      if (err || !buflen)
+        {
+          log_error (_("checking for qualified certificate failed: %s\n"),
+                     gpg_strerror (err)); 
+          rc = err;
+          goto leave;
+        }
+      if (*buffer)
+        err = gpgsm_qualified_consent (ctrl, cl->cert);
+      else
+        err = gpgsm_not_qualified_warning (ctrl, cl->cert);
+      if (err)
+        {
+          rc = err;
+          goto leave;
+        }
+    }
   
   /* Prepare hashing (actually we are figuring out what we have set above)*/
   rc = gcry_md_open (&data_md, 0, 0);
@@ -443,6 +473,10 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
       if (!algo)
         {
           log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+          if (algoid
+              && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
+                    ||!strcmp (algoid, "1.2.840.113549.2.2")))
+            log_info (_("(this is the MD2 algorithm)\n"));
           rc = gpg_error (GPG_ERR_BUG);
           goto leave;
         }
@@ -456,8 +490,8 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
       unsigned char *digest;
       size_t digest_len;
       /* Fixme do this for all signers and get the algo to use from
-         the signer's certificate - does not make mich sense, bu we
-         should do this consistent as we have already done it above */
+         the signer's certificate - does not make mich sense, but we
+         should do this consistent as we have already done it above. */
       algo = GCRY_MD_SHA1; 
       hash_data (data_fd, data_md);
       digest = gcry_md_read (data_md, algo);
@@ -575,7 +609,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
           ksba_cms_set_hash_function (cms, HASH_FNC, md);
           for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
             {
-              char *sigval = NULL;
+              unsigned char *sigval = NULL;
               char *buf, *fpr;
 
               if (signer)
@@ -589,7 +623,8 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
                   goto leave;
                 }
             
-              rc = gpgsm_create_cms_signature (cl->cert, md, algo, &sigval);
+              rc = gpgsm_create_cms_signature (ctrl, cl->cert,
+                                               md, algo, &sigval);
               if (rc)
                 {
                   gcry_md_close (md);
@@ -615,12 +650,15 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
                   gcry_md_close (md);
                   goto leave;
                 }
-              rc = asprintf (&buf, "%c %d %d 00 %s %s",
-                             detached? 'D':'S',
-                             GCRY_PK_RSA,  /* FIXME: get pk algo from cert */
-                             algo, 
-                             signed_at,
-                             fpr);
+              {
+                int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL);
+                rc = asprintf (&buf, "%c %d %d 00 %s %s",
+                               detached? 'D':'S',
+                               pkalgo, 
+                               algo, 
+                               signed_at,
+                               fpr);
+              }
               xfree (fpr);
               if (rc < 0)
                 {
@@ -650,7 +688,8 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
 
  leave:
   if (rc)
-    log_error ("error creating signature: %s\n", gpg_strerror (rc));
+    log_error ("error creating signature: %s <%s>\n",
+               gpg_strerror (rc), gpg_strsource (rc) );
   if (release_signerlist)
     gpgsm_release_certlist (signerlist);
   ksba_cms_release (cms);