2003-09-28 Timo Schulz <twoaday@freakmail.de>
[gnupg.git] / g10 / sig-check.c
1 /* sig-check.c -  Check a signature
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *               Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include "util.h"
28 #include "packet.h"
29 #include "memory.h"
30 #include "mpi.h"
31 #include "keydb.h"
32 #include "cipher.h"
33 #include "main.h"
34 #include "status.h"
35 #include "i18n.h"
36 #include "options.h"
37
38 struct cmp_help_context_s {
39     PKT_signature *sig;
40     MD_HANDLE md;
41 };
42
43 static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
44                      int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
45
46 /****************
47  * Check the signature which is contained in SIG.
48  * The MD_HANDLE should be currently open, so that this function
49  * is able to append some data, before finalizing the digest.
50  */
51 int
52 signature_check( PKT_signature *sig, MD_HANDLE digest )
53 {
54     return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
55 }
56
57 int
58 signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, 
59                   int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
60 {
61     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
62     int rc=0;
63
64     /* Sanity check that the md has a context for the hash that the
65        sig is expecting.  This can happen if a onepass sig header does
66        not match the actual sig, and also if the clearsign "Hash:"
67        header is missing or does not match the actual sig. */
68
69     if(!md_algo_present(digest,sig->digest_algo)) {
70         log_info(_("WARNING: signature digest conflict in message\n"));
71         rc=G10ERR_GENERAL;
72     }
73     else if( get_pubkey( pk, sig->keyid ) )
74         rc = G10ERR_NO_PUBKEY;
75     else if(!pk->is_valid && !pk->is_primary)
76         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
77                                  invalid subkey */
78     else {
79         if(r_expiredate)
80           *r_expiredate = pk->expiredate;
81         rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
82     }
83
84     free_public_key( pk );
85
86     if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
87         /* This signature id works best with DLP algorithms because
88          * they use a random parameter for every signature.  Instead of
89          * this sig-id we could have also used the hash of the document
90          * and the timestamp, but the drawback of this is, that it is
91          * not possible to sign more than one identical document within
92          * one second.  Some remote batch processing applications might
93          * like this feature here */
94         MD_HANDLE md;
95         u32 a = sig->timestamp;
96         int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
97         byte *p, *buffer;
98
99         md = md_open( DIGEST_ALGO_RMD160, 0);
100         md_putc( digest, sig->pubkey_algo );
101         md_putc( digest, sig->digest_algo );
102         md_putc( digest, (a >> 24) & 0xff );
103         md_putc( digest, (a >> 16) & 0xff );
104         md_putc( digest, (a >>  8) & 0xff );
105         md_putc( digest,  a        & 0xff );
106         for(i=0; i < nsig; i++ ) {
107             unsigned n = mpi_get_nbits( sig->data[i]);
108
109             md_putc( md, n>>8);
110             md_putc( md, n );
111             p = mpi_get_buffer( sig->data[i], &n, NULL );
112             md_write( md, p, n );
113             m_free(p);
114         }
115         md_final( md );
116         p = make_radix64_string( md_read( md, 0 ), 20 );
117         buffer = m_alloc( strlen(p) + 60 );
118         sprintf( buffer, "%s %s %lu",
119                  p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
120         write_status_text( STATUS_SIG_ID, buffer );
121         m_free(buffer);
122         m_free(p);
123         md_close(md);
124     }
125
126     return rc;
127 }
128
129
130 /****************
131  * This function gets called by pubkey_verify() if the algorithm needs it.
132  */
133 static int
134 cmp_help( void *opaque, MPI result )
135 {
136 #if 0 /* we do not use this anymore */
137     int rc=0, i, j, c, old_enc;
138     byte *dp;
139     const byte *asn;
140     size_t mdlen, asnlen;
141     struct cmp_help_context_s *ctx = opaque;
142     PKT_signature *sig = ctx->sig;
143     MD_HANDLE digest = ctx->md;
144
145     old_enc = 0;
146     for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
147         if( !j ) {
148             if( !i && c != 1 )
149                 break;
150             else if( i && c == 0xff )
151                 ; /* skip the padding */
152             else if( i && !c )
153                 j++;
154             else
155                 break;
156         }
157         else if( ++j == 18 && c != 1 )
158             break;
159         else if( j == 19 && c == 0 ) {
160             old_enc++;
161             break;
162         }
163     }
164     if( old_enc ) {
165         log_error("old encoding scheme is not supported\n");
166         return G10ERR_GENERAL;
167     }
168
169     if( (rc=check_digest_algo(sig->digest_algo)) )
170         return rc; /* unsupported algo */
171     asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
172
173     for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
174                                                            i++, j-- )
175         if( asn[j] != c )
176             break;
177     if( j != -1 || mpi_getbyte(result, i) )
178         return G10ERR_BAD_PUBKEY;  /* ASN is wrong */
179     for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
180         if( c != 0xff  )
181             break;
182     i++;
183     if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
184         /* Padding or leading bytes in signature is wrong */
185         return G10ERR_BAD_PUBKEY;
186     }
187     if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
188         || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
189         /* Wrong key used to check the signature */
190         return G10ERR_BAD_PUBKEY;
191     }
192
193     dp = md_read( digest, sig->digest_algo );
194     for(i=mdlen-1; i >= 0; i--, dp++ ) {
195         if( mpi_getbyte( result, i ) != *dp )
196             return G10ERR_BAD_SIGN;
197     }
198     return 0;
199 #else
200     return -1;
201 #endif
202 }
203
204 static int
205 do_check_messages( PKT_public_key *pk, PKT_signature *sig,
206                    int *r_expired, int *r_revoked )
207 {
208     u32 cur_time;
209
210     if(r_expired)
211       *r_expired = 0;
212     if(r_revoked)
213       *r_revoked = 0;
214     if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
215         log_info(_("key %08lX: this is a PGP generated "
216                    "ElGamal key which is NOT secure for signatures!\n"),
217                   (ulong)keyid_from_pk(pk,NULL));
218         return G10ERR_PUBKEY_ALGO;
219     }
220
221     if( pk->timestamp > sig->timestamp ) {
222         ulong d = pk->timestamp - sig->timestamp;
223         log_info( d==1
224              ? _("public key %08lX is %lu second newer than the signature\n")
225              : _("public key %08lX is %lu seconds newer than the signature\n"),
226                 (ulong)keyid_from_pk(pk,NULL),d );
227         if( !opt.ignore_time_conflict )
228             return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
229     }
230
231     cur_time = make_timestamp();
232     if( pk->timestamp > cur_time ) {
233         ulong d = pk->timestamp - cur_time;
234         log_info( d==1 ? _("key %08lX has been created %lu second "
235                            "in future (time warp or clock problem)\n")
236                        : _("key %08lX has been created %lu seconds "
237                            "in future (time warp or clock problem)\n"),
238                        (ulong)keyid_from_pk(pk,NULL),d );
239         if( !opt.ignore_time_conflict )
240             return G10ERR_TIME_CONFLICT;
241     }
242
243     if( pk->expiredate && pk->expiredate < cur_time ) {
244         char buf[11];
245         if (opt.verbose) {
246             u32 tmp_kid[2];
247
248             keyid_from_pk( pk, tmp_kid );
249             log_info(_("NOTE: signature key %08lX expired %s\n"),
250                      (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
251         }
252         /* SIGEXPIRED is deprecated.  Use KEYEXPIRED. */
253         sprintf(buf,"%lu",(ulong)pk->expiredate);
254         write_status_text(STATUS_KEYEXPIRED,buf);
255         write_status(STATUS_SIGEXPIRED);
256         if(r_expired)
257           *r_expired = 1;
258     }
259
260     if(pk->is_revoked && r_revoked)
261       *r_revoked=1;
262
263     return 0;
264 }
265
266
267 static int
268 do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
269           int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
270 {
271     MPI result = NULL;
272     int rc=0;
273     struct cmp_help_context_s ctx;
274
275     if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
276         return rc;
277     if( (rc=check_digest_algo(sig->digest_algo)) )
278         return rc;
279     if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
280         return rc;
281
282     /* make sure the digest algo is enabled (in case of a detached signature)*/
283     md_enable( digest, sig->digest_algo );
284
285     /* complete the digest */
286     if( sig->version >= 4 )
287         md_putc( digest, sig->version );
288     md_putc( digest, sig->sig_class );
289     if( sig->version < 4 ) {
290         u32 a = sig->timestamp;
291         md_putc( digest, (a >> 24) & 0xff );
292         md_putc( digest, (a >> 16) & 0xff );
293         md_putc( digest, (a >>  8) & 0xff );
294         md_putc( digest,  a        & 0xff );
295     }
296     else {
297         byte buf[6];
298         size_t n;
299         md_putc( digest, sig->pubkey_algo );
300         md_putc( digest, sig->digest_algo );
301         if( sig->hashed ) {
302             n = sig->hashed->len;
303             md_putc (digest, (n >> 8) );
304             md_putc (digest,  n       );
305             md_write (digest, sig->hashed->data, n);
306             n += 6;
307         }
308         else {
309           /* Two octets for the (empty) length of the hashed
310              section. */
311           md_putc (digest, 0);
312           md_putc (digest, 0);
313           n = 6;
314         }
315         /* add some magic */
316         buf[0] = sig->version;
317         buf[1] = 0xff;
318         buf[2] = n >> 24;
319         buf[3] = n >> 16;
320         buf[4] = n >>  8;
321         buf[5] = n;
322         md_write( digest, buf, 6 );
323     }
324     md_final( digest );
325
326     result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
327                               mpi_get_nbits(pk->pkey[0]), 0 );
328     if (!result)
329         return G10ERR_GENERAL;
330     ctx.sig = sig;
331     ctx.md = digest;
332     rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
333                         cmp_help, &ctx );
334     mpi_free( result );
335     if( (opt.emulate_bugs & EMUBUG_MDENCODE)
336         && rc == G10ERR_BAD_SIGN && is_ELGAMAL(pk->pubkey_algo) ) {
337         /* In this case we try again because old GnuPG versions didn't encode
338          * the hash right. There is no problem with DSA however  */
339         result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
340                               mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
341         if (!result)
342             rc = G10ERR_GENERAL;
343         else {
344             ctx.sig = sig;
345             ctx.md = digest;
346             rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
347                                 cmp_help, &ctx );
348         }
349     }
350
351     if( !rc && sig->flags.unknown_critical ) {
352       log_info(_("assuming bad signature from key %08lX due to an unknown critical bit\n"),(ulong)keyid_from_pk(pk,NULL));
353         rc = G10ERR_BAD_SIGN;
354     }
355
356     if(!rc && ret_pk)
357       copy_public_key(ret_pk,pk);
358
359     return rc;
360 }
361
362
363 static void
364 hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
365 {
366     PKT_user_id *uid = unode->pkt->pkt.user_id;
367
368     assert( unode->pkt->pkttype == PKT_USER_ID );
369     if( uid->attrib_data ) {
370         if( sig->version >=4 ) {
371             byte buf[5];
372             buf[0] = 0xd1;                   /* packet of type 17 */
373             buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
374             buf[2] = uid->attrib_len >> 16;
375             buf[3] = uid->attrib_len >>  8;
376             buf[4] = uid->attrib_len;
377             md_write( md, buf, 5 );
378         }
379         md_write( md, uid->attrib_data, uid->attrib_len );
380     }
381     else {
382         if( sig->version >=4 ) {
383             byte buf[5];
384             buf[0] = 0xb4;            /* indicates a userid packet */
385             buf[1] = uid->len >> 24;  /* always use 4 length bytes */
386             buf[2] = uid->len >> 16;
387             buf[3] = uid->len >>  8;
388             buf[4] = uid->len;
389             md_write( md, buf, 5 );
390         }
391         md_write( md, uid->name, uid->len );
392     }
393 }
394
395 static void
396 cache_sig_result ( PKT_signature *sig, int result )
397 {
398     if ( !result ) {
399         sig->flags.checked = 1;
400         sig->flags.valid = 1;
401     }
402     else if ( result == G10ERR_BAD_SIGN ) {
403         sig->flags.checked = 1;
404         sig->flags.valid = 0;
405     }
406     else {
407         sig->flags.checked = 0;
408         sig->flags.valid = 0;
409     }
410 }
411
412
413 /* Check the revocation keys to see if any of them have revoked our
414    pk.  sig is the revocation sig.  pk is the key it is on.  This code
415    will need to be modified if gpg ever becomes multi-threaded.  Note
416    that this guarantees that a designated revocation sig will never be
417    considered valid unless it is actually valid, as well as being
418    issued by a revocation key in a valid direct signature.  Note that
419    this is written so that a revoked revoker can still issue
420    revocations: i.e. If A revokes B, but A is revoked, B is still
421    revoked.  I'm not completely convinced this is the proper behavior,
422    but it matches how PGP does it. -dms */
423
424 /* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
425    revoked */
426 int
427 check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
428 {
429   static int busy=0;
430   int i,rc=G10ERR_GENERAL;
431
432   assert(IS_KEY_REV(sig));
433   assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
434
435   if(busy)
436     {
437       /* return -1 (i.e. not revoked), but mark the pk as uncacheable
438          as we don't really know its revocation status until it is
439          checked directly. */
440
441       pk->dont_cache=1;
442       return rc;
443     }
444
445   busy=1;
446
447   /*  printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1],
448       (ulong)sig->keyid[1]); */
449
450   /* is the issuer of the sig one of our revokers? */
451   if( !pk->revkey && pk->numrevkeys )
452      BUG();
453   else
454       for(i=0;i<pk->numrevkeys;i++)
455         {
456           u32 keyid[2];
457     
458           keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid);
459     
460           if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
461             {
462               MD_HANDLE md;
463     
464               md=md_open(sig->digest_algo,0);
465               hash_public_key(md,pk);
466               rc=signature_check(sig,md);
467               cache_sig_result(sig,rc);
468               break;
469             }
470         }
471
472   busy=0;
473
474   return rc;
475
476
477 /****************
478  * check the signature pointed to by NODE. This is a key signature.
479  * If the function detects a self-signature, it uses the PK from
480  * ROOT and does not read any public key.
481  */
482 int
483 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
484 {
485   return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL );
486 }
487
488 /* If check_pk is set, then use it to check the signature in node
489    rather than getting it from root or the keydb.  If ret_pk is set,
490    fill in the public key that was used to verify the signature.
491    ret_pk is only meaningful when the verification was successful. */
492 /* TODO: add r_revoked here as well.  It has the same problems as
493    r_expiredate and r_expired and the cache. */
494 int
495 check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
496                       PKT_public_key *ret_pk, int *is_selfsig,
497                       u32 *r_expiredate, int *r_expired )
498 {
499     MD_HANDLE md;
500     PKT_public_key *pk;
501     PKT_signature *sig;
502     int algo;
503     int rc;
504
505     if( is_selfsig )
506         *is_selfsig = 0;
507     if( r_expiredate )
508         *r_expiredate = 0;
509     if( r_expired )
510         *r_expired = 0;
511     assert( node->pkt->pkttype == PKT_SIGNATURE );
512     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
513
514     pk = root->pkt->pkt.public_key;
515     sig = node->pkt->pkt.signature;
516     algo = sig->digest_algo;
517
518     /* check whether we have cached the result of a previous signature check.*/
519     if ( !opt.no_sig_cache ) {
520         if (sig->flags.checked) { /*cached status available*/
521             if( is_selfsig ) {  
522                 u32 keyid[2];   
523
524                 keyid_from_pk( pk, keyid );
525                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
526                     *is_selfsig = 1;
527             }
528             /* BUG: This is wrong for non-self-sigs.. needs to be the
529                actual pk */
530             if((rc=do_check_messages(pk,sig,r_expired,NULL)))
531               return rc;
532             return sig->flags.valid? 0 : G10ERR_BAD_SIGN;
533         }
534     }
535
536     if( (rc=check_digest_algo(algo)) )
537         return rc;
538
539     if( sig->sig_class == 0x20 ) { /* key revocation */
540         u32 keyid[2];   
541         keyid_from_pk( pk, keyid );
542
543         /* is it a designated revoker? */
544         if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1])
545           rc=check_revocation_keys(pk,sig);
546         else
547           {
548             md = md_open( algo, 0 );
549             hash_public_key( md, pk );
550             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
551             cache_sig_result ( sig, rc );
552             md_close(md);
553           }
554     }
555     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
556         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
557
558         if( snode ) {
559             md = md_open( algo, 0 );
560             hash_public_key( md, pk );
561             hash_public_key( md, snode->pkt->pkt.public_key );
562             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
563             cache_sig_result ( sig, rc );
564             md_close(md);
565         }
566         else {
567             if (opt.verbose)
568                 log_info (_("key %08lX: no subkey for subkey "
569                             "revocation signature\n"),
570                           (ulong)keyid_from_pk (pk, NULL));
571             rc = G10ERR_SIG_CLASS;
572         }
573     }
574     else if( sig->sig_class == 0x18 ) { /* key binding */
575         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
576
577         if( snode ) {
578             if( is_selfsig ) {  /* does this make sense????? */
579                 u32 keyid[2];   /* it should always be a selfsig */
580
581                 keyid_from_pk( pk, keyid );
582                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
583                     *is_selfsig = 1;
584             }
585             md = md_open( algo, 0 );
586             hash_public_key( md, pk );
587             hash_public_key( md, snode->pkt->pkt.public_key );
588             rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
589             cache_sig_result ( sig, rc );
590             md_close(md);
591         }
592         else {
593             if (opt.verbose)
594                 log_info(_("key %08lX: no subkey for subkey "
595                            "binding signature\n"),
596                          (ulong)keyid_from_pk (pk, NULL));
597             rc = G10ERR_SIG_CLASS;
598         }
599     }
600     else if( sig->sig_class == 0x1f ) { /* direct key signature */
601         md = md_open( algo, 0 );
602         hash_public_key( md, pk );
603         rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
604         cache_sig_result ( sig, rc );
605         md_close(md);
606     }
607     else { /* all other classes */
608         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
609
610         if( unode ) {
611             u32 keyid[2];
612
613             keyid_from_pk( pk, keyid );
614             md = md_open( algo, 0 );
615             hash_public_key( md, pk );
616             hash_uid_node( unode, md, sig );
617             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
618               {
619                 if( is_selfsig )
620                   *is_selfsig = 1;
621                 rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
622               }
623             else if (check_pk)
624               rc=do_check(check_pk,sig,md,r_expired,NULL,ret_pk);
625             else
626               rc=signature_check2(sig,md,r_expiredate,r_expired,NULL,ret_pk);
627
628             cache_sig_result ( sig, rc );
629             md_close(md);
630         }
631         else {
632             if (!opt.quiet)
633                 log_info ("key %08lX: no user ID for key signature packet "
634                           "of class %02x\n",
635                           (ulong)keyid_from_pk (pk, NULL), sig->sig_class );
636             rc = G10ERR_SIG_CLASS;
637         }
638     }
639
640     return rc;
641 }