Extend algo selection menu.
[gnupg.git] / g10 / sign.c
index eeb4549..a768ac9 100644 (file)
@@ -150,7 +150,7 @@ mk_notation_policy_etc (PKT_signature *sig,
 
 
 /*
 
 
 /*
- * Helper to hash a user ID packet.  
+ * Helper to hash a user ID packet.
  */
 static void
 hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
  */
 static void
 hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
@@ -188,7 +188,7 @@ hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
 static void
 hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
 {
 static void
 hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
 {
-    if (sig->version >= 4) 
+    if (sig->version >= 4)
         gcry_md_putc (md, sig->version);
     gcry_md_putc (md, sig->sig_class);
     if (sig->version < 4) {
         gcry_md_putc (md, sig->version);
     gcry_md_putc (md, sig->sig_class);
     if (sig->version < 4) {
@@ -201,7 +201,7 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
     else {
         byte buf[6];
         size_t n;
     else {
         byte buf[6];
         size_t n;
-        
+
         gcry_md_putc (md, sig->pubkey_algo);
         gcry_md_putc (md, sig->digest_algo);
         if (sig->hashed) {
         gcry_md_putc (md, sig->pubkey_algo);
         gcry_md_putc (md, sig->digest_algo);
         if (sig->hashed) {
@@ -227,21 +227,6 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
     }
 }
 
     }
 }
 
-
-static gcry_mpi_t
-mpi_from_sexp (gcry_sexp_t sexp, const char * item)
-{
-  gcry_sexp_t list;
-  gcry_mpi_t data;
-  
-  list = gcry_sexp_find_token (sexp, item, 0);
-  assert (list);
-  data = gcry_sexp_nth_mpi (list, 1, 0);
-  assert (data);
-  gcry_sexp_release (list);
-  return data;
-}
-
 /* Perform the sign operation.  If CACHE_NONCE is given the agent is
    advised to use that cached passphrase fro the key.  */
 static int
 /* Perform the sign operation.  If CACHE_NONCE is given the agent is
    advised to use that cached passphrase fro the key.  */
 static int
@@ -251,6 +236,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
   gpg_error_t err;
   gcry_mpi_t frame;
   byte *dp;
   gpg_error_t err;
   gcry_mpi_t frame;
   byte *dp;
+  char *hexgrip;
 
   if (pksk->timestamp > sig->timestamp )
     {
 
   if (pksk->timestamp > sig->timestamp )
     {
@@ -263,7 +249,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
         return gpg_error (GPG_ERR_TIME_CONFLICT);
     }
 
         return gpg_error (GPG_ERR_TIME_CONFLICT);
     }
 
-  
+
   print_pubkey_algo_note (pksk->pubkey_algo);
 
   if (!mdalgo)
   print_pubkey_algo_note (pksk->pubkey_algo);
 
   if (!mdalgo)
@@ -277,64 +263,33 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
   sig->data[0] = NULL;
   sig->data[1] = NULL;
 
   sig->data[0] = NULL;
   sig->data[1] = NULL;
 
-#warning fixme: Use the agent for the card
-/*     if (pksk->is_protected && pksk->protect.s2k.mode == 1002)  */
-/*       {  */
-/* #ifdef ENABLE_CARD_SUPPORT */
-/*         unsigned char *rbuf; */
-/*         size_t rbuflen; */
-/*         char *snbuf; */
-        
-/*         snbuf = serialno_and_fpr_from_sk (sk->protect.iv, */
-/*                                           sk->protect.ivlen, sk); */
-/*         rc = agent_scd_pksign (snbuf, digest_algo, */
-/*                                gcry_md_read (md, digest_algo), */
-/*                                gcry_md_get_algo_dlen (digest_algo), */
-/*                                &rbuf, &rbuflen); */
-/*         xfree (snbuf); */
-/*         if (!rc) */
-/*           { */
-/*             if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG, */
-/*                                rbuf, rbuflen, NULL)) */
-/*               BUG (); */
-/*             xfree (rbuf); */
-/*           } */
-/* #else */
-/*         return gpg_error (GPG_ERR_NOT_SUPPORTED); */
-/* #endif /\* ENABLE_CARD_SUPPORT *\/ */
-/*       } */
-/*     else  */
-  if (1)
+
+  err = hexkeygrip_from_pk (pksk, &hexgrip);
+  if (!err)
     {
     {
-      char *hexgrip;
-      
-      err = hexkeygrip_from_pk (pksk, &hexgrip);
-      if (!err)
+      char *desc;
+      gcry_sexp_t s_sigval;
+
+      desc = gpg_format_keydesc (pksk, 0, 1);
+      err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
+                          dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
+                          &s_sigval);
+      xfree (desc);
+
+      if (err)
+        ;
+      else if (pksk->pubkey_algo == GCRY_PK_RSA
+               || pksk->pubkey_algo == GCRY_PK_RSA_S)
+        sig->data[0] = mpi_from_sexp (s_sigval, "s");
+      else
         {
         {
-          char *desc;
-          gcry_sexp_t s_sigval;
-          
-          desc = gpg_format_keydesc (pksk, 0, 1);
-          err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc, 
-                              dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
-                              &s_sigval);
-          xfree (desc);
-     
-          if (err)
-            ;
-          else if (pksk->pubkey_algo == GCRY_PK_RSA
-                   || pksk->pubkey_algo == GCRY_PK_RSA_S)
-            sig->data[0] = mpi_from_sexp (s_sigval, "s");
-          else
-            {
-              sig->data[0] = mpi_from_sexp (s_sigval, "r");
-              sig->data[1] = mpi_from_sexp (s_sigval, "s");
-            }
-      
-          gcry_sexp_release (s_sigval);
+          sig->data[0] = mpi_from_sexp (s_sigval, "r");
+          sig->data[1] = mpi_from_sexp (s_sigval, "s");
         }
         }
-      xfree (hexgrip);
+
+      gcry_sexp_release (s_sigval);
     }
     }
+  xfree (hexgrip);
 
   /* Check that the signature verification worked and nothing is
    * fooling us e.g. by a bug in the signature create code or by
 
   /* Check that the signature verification worked and nothing is
    * fooling us e.g. by a bug in the signature create code or by
@@ -345,7 +300,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
 
       if (get_pubkey (pk, sig->keyid ))
         err = gpg_error (GPG_ERR_NO_PUBKEY);
 
       if (get_pubkey (pk, sig->keyid ))
         err = gpg_error (GPG_ERR_NO_PUBKEY);
-      else 
+      else
         {
           frame = encode_md_value (pk, md, sig->digest_algo );
           if (!frame)
         {
           frame = encode_md_value (pk, md, sig->digest_algo );
           if (!frame)
@@ -362,14 +317,14 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
 
   if (err)
     log_error (_("signing failed: %s\n"), g10_errstr (err));
 
   if (err)
     log_error (_("signing failed: %s\n"), g10_errstr (err));
-  else 
+  else
     {
       if (opt.verbose)
         {
           char *ustr = get_user_id_string_native (sig->keyid);
           log_info (_("%s/%s signature from: \"%s\"\n"),
     {
       if (opt.verbose)
         {
           char *ustr = get_user_id_string_native (sig->keyid);
           log_info (_("%s/%s signature from: \"%s\"\n"),
-                    gcry_pk_algo_name (pksk->pubkey_algo),
-                    gcry_md_algo_name (sig->digest_algo),
+                    openpgp_pk_algo_name (pksk->pubkey_algo),
+                    openpgp_md_algo_name (sig->digest_algo),
                     ustr);
           xfree (ustr);
        }
                     ustr);
           xfree (ustr);
        }
@@ -390,6 +345,48 @@ complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
 }
 
 
 }
 
 
+/* Return true if the key seems to be on a version 1 OpenPGP card.
+   This works by asking the agent and may fail if the card has not yet
+   been used with the agent.  */
+static int
+openpgp_card_v1_p (PKT_public_key *pk)
+{
+  gpg_error_t err;
+  int result;
+
+  /* Shortcut if we are not using RSA: The v1 cards only support RSA
+     thus there is no point in looking any further.  */
+  if (!is_RSA (pk->pubkey_algo))
+    return 0;
+
+  if (!pk->flags.serialno_valid)
+    {
+      char *hexgrip;
+
+      err = hexkeygrip_from_pk (pk, &hexgrip);
+      if (err)
+        {
+          log_error ("error computing a keygrip: %s\n", gpg_strerror (err));
+          return 0; /* Ooops.  */
+        }
+
+      xfree (pk->serialno);
+      agent_get_keyinfo (NULL, hexgrip, &pk->serialno);
+      xfree (hexgrip);
+      pk->flags.serialno_valid = 1;
+    }
+
+  if (!pk->serialno)
+    result = 0; /* Error from a past agent_get_keyinfo or no card.  */
+  else
+    {
+      /* The version number of the card is included in the serialno.  */
+      result = !strncmp (pk->serialno, "D2760001240101", 14);
+    }
+  return result;
+}
+
+
 
 static int
 match_dsa_hash (unsigned int qbytes)
 
 static int
 match_dsa_hash (unsigned int qbytes)
@@ -406,7 +403,7 @@ match_dsa_hash (unsigned int qbytes)
   if (qbytes <= 48)
     return DIGEST_ALGO_SHA384;
 
   if (qbytes <= 48)
     return DIGEST_ALGO_SHA384;
 
-  if (qbytes <= 64)
+  if (qbytes <= 66 )   /* 66 corresponds to 521 (64 to 512) */
     return DIGEST_ALGO_SHA512;
 
   return DEFAULT_DIGEST_ALGO;
     return DIGEST_ALGO_SHA512;
 
   return DEFAULT_DIGEST_ALGO;
@@ -439,9 +436,14 @@ hash_for (PKT_public_key *pk)
     {
       return recipient_digest_algo;
     }
     {
       return recipient_digest_algo;
     }
-  else if (pk->pubkey_algo == PUBKEY_ALGO_DSA)
+  else if (pk->pubkey_algo == PUBKEY_ALGO_DSA
+           || pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
     {
     {
-      unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]) / 8;
+      unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
+
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        qbytes = ecdsa_qbits_from_Q (qbytes);
+      qbytes = qbytes/8;
 
       /* It's a DSA key, so find a hash that is the same size as q or
         larger.  If q is 160, assume it is an old DSA key and use a
 
       /* It's a DSA key, so find a hash that is the same size as q or
         larger.  If q is 160, assume it is an old DSA key and use a
@@ -470,10 +472,7 @@ hash_for (PKT_public_key *pk)
 
       return match_dsa_hash(qbytes);
     }
 
       return match_dsa_hash(qbytes);
     }
-  else if (0 
-           /* FIXME: call agent sk->is_protected && sk->protect.s2k.mode == 1002
-           && sk->protect.ivlen == 16
-           && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01\x01", 7)*/)
+  else if (openpgp_card_v1_p (pk))
     {
       /* The sk lives on a smartcard, and old smartcards only handle
         SHA-1 and RIPEMD/160.  Newer smartcards (v2.0) don't have
     {
       /* The sk lives on a smartcard, and old smartcards only handle
         SHA-1 and RIPEMD/160.  Newer smartcards (v2.0) don't have
@@ -514,7 +513,7 @@ only_old_style (SK_LIST sk_list)
 {
   SK_LIST sk_rover = NULL;
   int old_style = 0;
 {
   SK_LIST sk_rover = NULL;
   int old_style = 0;
-  
+
   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
     {
       PKT_public_key *pk = sk_rover->pk;
   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
     {
       PKT_public_key *pk = sk_rover->pk;
@@ -534,13 +533,13 @@ print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
   byte array[MAX_FINGERPRINT_LEN];
   char buf[100+MAX_FINGERPRINT_LEN*2];
   size_t n;
   byte array[MAX_FINGERPRINT_LEN];
   char buf[100+MAX_FINGERPRINT_LEN*2];
   size_t n;
-  
+
   snprintf (buf, sizeof buf - 2*MAX_FINGERPRINT_LEN, "%c %d %d %02x %lu ",
             what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
             (ulong)sig->timestamp );
   fingerprint_from_pk (pk, array, &n);
   bin2hex (array, n, buf + strlen (buf));
   snprintf (buf, sizeof buf - 2*MAX_FINGERPRINT_LEN, "%c %d %d %02x %lu ",
             what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
             (ulong)sig->timestamp );
   fingerprint_from_pk (pk, array, &n);
   bin2hex (array, n, buf + strlen (buf));
-  
+
   write_status_text( STATUS_SIG_CREATED, buf );
 }
 
   write_status_text( STATUS_SIG_CREATED, buf );
 }
 
@@ -549,7 +548,7 @@ print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
  * Loop over the secret certificates in SK_LIST and build the one pass
  * signature packets.  OpenPGP says that the data should be bracket by
  * the onepass-sig and signature-packet; so we build these onepass
  * Loop over the secret certificates in SK_LIST and build the one pass
  * signature packets.  OpenPGP says that the data should be bracket by
  * the onepass-sig and signature-packet; so we build these onepass
- * packet here in reverse order 
+ * packet here in reverse order
  */
 static int
 write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
  */
 static int
 write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
@@ -565,7 +564,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
         PKT_onepass_sig *ops;
         PACKET pkt;
         int i, rc;
         PKT_onepass_sig *ops;
         PACKET pkt;
         int i, rc;
-        
+
         for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
             if (++i == skcount)
                 break;
         for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
             if (++i == skcount)
                 break;
@@ -578,7 +577,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
         ops->pubkey_algo = pk->pubkey_algo;
         keyid_from_pk (pk, ops->keyid);
         ops->last = (skcount == 1);
         ops->pubkey_algo = pk->pubkey_algo;
         keyid_from_pk (pk, ops->keyid);
         ops->last = (skcount == 1);
-        
+
         init_packet(&pkt);
         pkt.pkttype = PKT_ONEPASS_SIG;
         pkt.pkt.onepass_sig = ops;
         init_packet(&pkt);
         pkt.pkttype = PKT_ONEPASS_SIG;
         pkt.pkt.onepass_sig = ops;
@@ -666,7 +665,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
         wipememory(copy_buffer,4096); /* burn buffer */
     }
     /* fixme: it seems that we never freed pt/pkt */
         wipememory(copy_buffer,4096); /* burn buffer */
     }
     /* fixme: it seems that we never freed pt/pkt */
-    
+
     return rc;
 }
 
     return rc;
 }
 
@@ -680,7 +679,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
                         int status_letter, const char *cache_nonce)
 {
   SK_LIST sk_rover;
                         int status_letter, const char *cache_nonce)
 {
   SK_LIST sk_rover;
-  
+
   /* Loop over the certificates with secret keys. */
   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
     {
   /* Loop over the certificates with secret keys. */
   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
     {
@@ -714,23 +713,23 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
 
       if (gcry_md_copy (&md, hash))
         BUG ();
 
       if (gcry_md_copy (&md, hash))
         BUG ();
-      
+
       if (sig->version >= 4)
         {
           build_sig_subpkt_from_sig (sig);
           mk_notation_policy_etc (sig, pk, NULL);
         }
       if (sig->version >= 4)
         {
           build_sig_subpkt_from_sig (sig);
           mk_notation_policy_etc (sig, pk, NULL);
         }
-      
+
       hash_sigversion_to_magic (md, sig);
       gcry_md_final (md);
 
       rc = do_sign (pk, sig, md, hash_for (pk), cache_nonce);
       gcry_md_close (md);
       if (!rc)
       hash_sigversion_to_magic (md, sig);
       gcry_md_final (md);
 
       rc = do_sign (pk, sig, md, hash_for (pk), cache_nonce);
       gcry_md_close (md);
       if (!rc)
-        { 
+        {
           /* Write the packet.  */
           PACKET pkt;
           /* Write the packet.  */
           PACKET pkt;
-          
+
           init_packet (&pkt);
           pkt.pkttype = PKT_SIGNATURE;
           pkt.pkt.signature = sig;
           init_packet (&pkt);
           pkt.pkttype = PKT_SIGNATURE;
           pkt.pkt.signature = sig;
@@ -744,7 +743,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
       if (rc)
         return rc;
     }
       if (rc)
         return rc;
     }
-  
+
   return 0;
 }
 
   return 0;
 }
 
@@ -762,7 +761,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
  * uncompressed, non-armored and in binary mode.
  */
 int
  * uncompressed, non-armored and in binary mode.
  */
 int
-sign_file( strlist_t filenames, int detached, strlist_t locusr,
+sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
           int encryptflag, strlist_t remusr, const char *outfile )
 {
     const char *fname;
           int encryptflag, strlist_t remusr, const char *outfile )
 {
     const char *fname;
@@ -822,7 +821,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
        compliance_failure();
       }
 
        compliance_failure();
       }
 
-    if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )))
+    if (encryptflag
+        && (rc=build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
       goto leave;
 
     /* prepare iobufs */
       goto leave;
 
     /* prepare iobufs */
@@ -836,7 +836,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
           inp = NULL;
           gpg_err_set_errno (EPERM);
         }
           inp = NULL;
           gpg_err_set_errno (EPERM);
         }
-      if( !inp ) 
+      if( !inp )
         {
           rc = gpg_error_from_syserror ();
           log_error (_("can't open `%s': %s\n"), fname? fname: "[stdin]",
         {
           rc = gpg_error_from_syserror ();
           log_error (_("can't open `%s': %s\n"), fname? fname: "[stdin]",
@@ -880,7 +880,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
       gcry_md_start_debug (mfx.md, "sign");
 
     /* If we're encrypting and signing, it is reasonable to pick the
       gcry_md_start_debug (mfx.md, "sign");
 
     /* If we're encrypting and signing, it is reasonable to pick the
-       hash algorithm to use out of the recepient key prefs.  This is
+       hash algorithm to use out of the recipient key prefs.  This is
        best effort only, as in a DSA2 and smartcard world there are
        cases where we cannot please everyone with a single hash (DSA2
        wants >160 and smartcards want =160).  In the future this could
        best effort only, as in a DSA2 and smartcard world there are
        cases where we cannot please everyone with a single hash (DSA2
        wants >160 and smartcards want =160).  In the future this could
@@ -925,10 +925,15 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
 
            for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
              {
 
            for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
              {
-               if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA)
+               if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA
+                    || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
                  {
                  {
-                   int temp_hashlen = gcry_mpi_get_nbits
-                      (sk_rover->pk->pkey[1])+7/8;
+                   int temp_hashlen = (gcry_mpi_get_nbits
+                                        (sk_rover->pk->pkey[1]));
+
+                   if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+                     temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen);
+                   temp_hashlen = (temp_hashlen+7)/8;
 
                    /* Pick a hash that is large enough for our
                       largest q */
 
                    /* Pick a hash that is large enough for our
                       largest q */
@@ -987,7 +992,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
               there is an assumed preference for uncompressed data.
               Still, if it did fail, we'll also end up with the
               default. */
               there is an assumed preference for uncompressed data.
               Still, if it did fail, we'll also end up with the
               default. */
+
            if((compr_algo=
                select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
              compr_algo=default_compress_algo();
            if((compr_algo=
                select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
              compr_algo=default_compress_algo();
@@ -1152,7 +1157,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
-       log_error (_("can't open `%s': %s\n"), 
+       log_error (_("can't open `%s': %s\n"),
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
@@ -1163,7 +1168,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
             outfile = NULL;
             gpg_err_set_errno (EPERM);
         }
             outfile = NULL;
             gpg_err_set_errno (EPERM);
         }
-        else 
+        else
             out = iobuf_create( outfile );
        if( !out )
          {
             out = iobuf_create( outfile );
        if( !out )
          {
@@ -1183,7 +1188,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
       {
        if (hash_for (sk_rover->pk) == DIGEST_ALGO_MD5)
           only_md5 = 1;
       {
        if (hash_for (sk_rover->pk) == DIGEST_ALGO_MD5)
           only_md5 = 1;
-       else 
+       else
           {
            only_md5 = 0;
            break;
           {
            only_md5 = 0;
            break;
@@ -1251,7 +1256,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
     gcry_md_close ( textmd );
     release_sk_list( sk_list );
     release_progress_context (pfx);
     gcry_md_close ( textmd );
     release_sk_list( sk_list );
     release_progress_context (pfx);
-    release_armor_context (afx); 
+    release_armor_context (afx);
     return rc;
 }
 
     return rc;
 }
 
@@ -1297,7 +1302,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
     /* Note: In the old non-agent version the following call used to
        unprotect the secret key.  This is now done on demand by the agent.  */
     rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG);
     /* Note: In the old non-agent version the following call used to
        unprotect the secret key.  This is now done on demand by the agent.  */
     rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG);
-    if (rc) 
+    if (rc)
        goto leave;
 
     /* prepare iobufs */
        goto leave;
 
     /* prepare iobufs */
@@ -1310,7 +1315,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
       }
     if( !inp ) {
         rc = gpg_error_from_syserror ();
-       log_error (_("can't open `%s': %s\n"), 
+       log_error (_("can't open `%s': %s\n"),
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
                    fname? fname: "[stdin]", strerror(errno) );
        goto leave;
     }
@@ -1399,7 +1404,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
     rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
     if (rc)
        goto leave;
     rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
     if (rc)
        goto leave;
-    
+
     /* Write the signatures */
     /*(current filters: zip - encrypt - armor)*/
     rc = write_signature_packets (sk_list, out, mfx.md,
     /* Write the signatures */
     /*(current filters: zip - encrypt - armor)*/
     rc = write_signature_packets (sk_list, out, mfx.md,
@@ -1480,11 +1485,14 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
 
        if(opt.cert_digest_algo)
          digest_algo=opt.cert_digest_algo;
 
        if(opt.cert_digest_algo)
          digest_algo=opt.cert_digest_algo;
-       else if(pksk->pubkey_algo==PUBKEY_ALGO_RSA
+       else if(pksk->pubkey_algo == PUBKEY_ALGO_RSA
                && pk->version<4 && sigversion<4)
          digest_algo = DIGEST_ALGO_MD5;
                && pk->version<4 && sigversion<4)
          digest_algo = DIGEST_ALGO_MD5;
-       else if(pksk->pubkey_algo==PUBKEY_ALGO_DSA)
+       else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA)
          digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
          digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
+        else if(pksk->pubkey_algo == PUBKEY_ALGO_ECDSA )
+         digest_algo = match_dsa_hash (ecdsa_qbits_from_Q
+                                        (gcry_mpi_get_nbits (pksk->pkey[1]))/8);
        else
          digest_algo = DIGEST_ALGO_SHA1;
       }
        else
          digest_algo = DIGEST_ALGO_SHA1;
       }
@@ -1561,7 +1569,7 @@ int
 update_keysig_packet( PKT_signature **ret_sig,
                       PKT_signature *orig_sig,
                       PKT_public_key *pk,
 update_keysig_packet( PKT_signature **ret_sig,
                       PKT_signature *orig_sig,
                       PKT_public_key *pk,
-                      PKT_user_id *uid, 
+                      PKT_user_id *uid,
                       PKT_public_key *subpk,
                       PKT_public_key *pksk,
                       int (*mksubpkt)(PKT_signature *, void *),
                       PKT_public_key *subpk,
                       PKT_public_key *pksk,
                       int (*mksubpkt)(PKT_signature *, void *),
@@ -1589,7 +1597,7 @@ update_keysig_packet( PKT_signature **ret_sig,
 
     /* create a new signature packet */
     sig = copy_signature (NULL, orig_sig);
 
     /* create a new signature packet */
     sig = copy_signature (NULL, orig_sig);
+
     /* We need to create a new timestamp so that new sig expiration
        calculations are done correctly... */
     sig->timestamp=make_timestamp();
     /* We need to create a new timestamp so that new sig expiration
        calculations are done correctly... */
     sig->timestamp=make_timestamp();