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