* main.h, seskey.c (encode_md_value): Modify to allow a q size greater
[gnupg.git] / g10 / sign.c
index 2e64abb..925fef4 100644 (file)
@@ -1,6 +1,6 @@
 /* sign.c - sign data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ *               2006 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -55,9 +55,9 @@ void __stdcall Sleep(ulong);
 static int recipient_digest_algo=0;
 
 /****************
- * Create a notation.  It is assumed that the stings in STRLIST
- * are already checked to contain only printable data and have a valid
- * NAME=VALUE format.
+ * Create notations and other stuff.  It is assumed that the stings in
+ * STRLIST are already checked to contain only printable data and have
+ * a valid NAME=VALUE format.
  */
 static void
 mk_notation_policy_etc( PKT_signature *sig,
@@ -65,9 +65,8 @@ mk_notation_policy_etc( PKT_signature *sig,
 {
     const char *string;
     char *s=NULL;
-    byte *buf;
-    unsigned n1, n2;
-    STRLIST nd=NULL,pu=NULL;
+    STRLIST pu=NULL;
+    struct notation *nd=NULL;
     struct expando_args args;
 
     memset(&args,0,sizeof(args));
@@ -80,57 +79,43 @@ mk_notation_policy_etc( PKT_signature *sig,
        good to do these checks anyway. */
 
     /* notation data */
-    if(IS_SIG(sig) && opt.sig_notation_data)
+    if(IS_SIG(sig) && opt.sig_notations)
       {
        if(sig->version<4)
          log_error(_("can't put notation data into v3 (PGP 2.x style) "
                      "signatures\n"));
        else
-         nd=opt.sig_notation_data;
+         nd=opt.sig_notations;
       }
-    else if( IS_CERT(sig) && opt.cert_notation_data )
+    else if( IS_CERT(sig) && opt.cert_notations )
       {
        if(sig->version<4)
          log_error(_("can't put notation data into v3 (PGP 2.x style) "
                      "key signatures\n"));
        else
-         nd=opt.cert_notation_data;
+         nd=opt.cert_notations;
       }
 
-    for( ; nd; nd = nd->next ) {
-        char *expanded;
-
-        string = nd->d;
-       s = strchr( string, '=' );
-       if( !s )
-         BUG(); /* we have already parsed this */
-       n1 = s - string;
-       s++;
+    if(nd)
+      {
+       struct notation *i;
 
-       expanded=pct_expando(s,&args);
-       if(!expanded)
+       for(i=nd;i;i=i->next)
          {
-           log_error(_("WARNING: unable to %%-expand notation "
-                       "(too large).  Using unexpanded.\n"));
-           expanded=xstrdup(s);
+           i->altvalue=pct_expando(i->value,&args);
+           if(!i->altvalue)
+             log_error(_("WARNING: unable to %%-expand notation "
+                         "(too large).  Using unexpanded.\n"));
          }
 
-       n2 = strlen(expanded);
-       buf = xmalloc( 8 + n1 + n2 );
-       buf[0] = 0x80; /* human readable */
-       buf[1] = buf[2] = buf[3] = 0;
-       buf[4] = n1 >> 8;
-       buf[5] = n1;
-       buf[6] = n2 >> 8;
-       buf[7] = n2;
-       memcpy(buf+8, string, n1 );
-       memcpy(buf+8+n1, expanded, n2 );
-       build_sig_subpkt( sig, SIGSUBPKT_NOTATION
-                         | ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0),
-                         buf, 8+n1+n2 );
-       xfree(expanded);
-       xfree(buf);
-    }
+       keygen_add_notations(sig,nd);
+
+       for(i=nd;i;i=i->next)
+         {
+           xfree(i->altvalue);
+           i->altvalue=NULL;
+         }
+      }
 
     /* set policy URL */
     if( IS_SIG(sig) && opt.sig_policy_url )
@@ -334,8 +319,17 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
       }
     else 
       {
-        frame = encode_md_value( sk->pubkey_algo, md,
-                                 digest_algo, mpi_get_nbits(sk->skey[0]) );
+       /* TODO: remove this check in the future once all the
+          variable-q DSA stuff makes it into the standard. */
+       if(!opt.expert
+          && sk->pubkey_algo==PUBKEY_ALGO_DSA
+          && md_digest_length(digest_algo)!=20)
+         {
+           log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
+           return G10ERR_GENERAL;
+         }
+
+        frame = encode_md_value( NULL, sk, md, digest_algo );
         if (!frame)
           return G10ERR_GENERAL;
         rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
@@ -351,9 +345,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
         if( get_pubkey( pk, sig->keyid ) )
             rc = G10ERR_NO_PUBKEY;
         else {
-            frame = encode_md_value (pk->pubkey_algo, md,
-                                     sig->digest_algo,
-                                     mpi_get_nbits(pk->pkey[0]) );
+           frame = encode_md_value (pk, NULL, md, sig->digest_algo );
             if (!frame)
                 rc = G10ERR_GENERAL;
             else
@@ -650,7 +642,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, MD_HANDLE hash,
        if(opt.force_v3_sigs || RFC1991)
          sig->version=3;
        else if(duration || opt.sig_policy_url
-               || opt.sig_notation_data || opt.sig_keyserver_url)
+               || opt.sig_notations || opt.sig_keyserver_url)
          sig->version=4;
        else
          sig->version=sk->version;
@@ -1374,9 +1366,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
 
        if(opt.cert_digest_algo)
          digest_algo=opt.cert_digest_algo;
-       else if((sk->pubkey_algo==PUBKEY_ALGO_RSA ||
-                sk->pubkey_algo==PUBKEY_ALGO_RSA_S) &&
-               pk->version<4 && sigversion < 4)
+       else if(sk->pubkey_algo==PUBKEY_ALGO_RSA
+               && pk->version<4 && sigversion<4)
          digest_algo = DIGEST_ALGO_MD5;
        else
          digest_algo = DIGEST_ALGO_SHA1;