* sig-check.c (do_check): Properly validate v4 sigs with no hashed section
[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     if( get_pubkey( pk, sig->keyid ) )
67         rc = G10ERR_NO_PUBKEY;
68     else if(!pk->is_valid &&
69             (pk->main_keyid[0]!=pk->keyid[0] ||
70              pk->main_keyid[1]!=pk->keyid[1]))
71         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
72                                  invalid subkey */
73     else {
74         *r_expiredate = pk->expiredate;
75         rc = do_check( pk, sig, digest, r_expired );
76     }
77
78     free_public_key( pk );
79
80     if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
81         /* This signature id works best with DLP algorithms because
82          * they use a random parameter for every signature.  Instead of
83          * this sig-id we could have also used the hash of the document
84          * and the timestamp, but the drawback of this is, that it is
85          * not possible to sign more than one identical document within
86          * one second.  Some remote batch processing applications might
87          * like this feature here */
88         MD_HANDLE md;
89         u32 a = sig->timestamp;
90         int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
91         byte *p, *buffer;
92
93         md = md_open( DIGEST_ALGO_RMD160, 0);
94         md_putc( digest, sig->pubkey_algo );
95         md_putc( digest, sig->digest_algo );
96         md_putc( digest, (a >> 24) & 0xff );
97         md_putc( digest, (a >> 16) & 0xff );
98         md_putc( digest, (a >>  8) & 0xff );
99         md_putc( digest,  a        & 0xff );
100         for(i=0; i < nsig; i++ ) {
101             unsigned n = mpi_get_nbits( sig->data[i]);
102
103             md_putc( md, n>>8);
104             md_putc( md, n );
105             p = mpi_get_buffer( sig->data[i], &n, NULL );
106             md_write( md, p, n );
107             m_free(p);
108         }
109         md_final( md );
110         p = make_radix64_string( md_read( md, 0 ), 20 );
111         buffer = m_alloc( strlen(p) + 60 );
112         sprintf( buffer, "%s %s %lu",
113                  p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
114         write_status_text( STATUS_SIG_ID, buffer );
115         m_free(buffer);
116         m_free(p);
117         md_close(md);
118     }
119
120     return rc;
121 }
122
123
124 /****************
125  * This function gets called by pubkey_verify() if the algorithm needs it.
126  */
127 static int
128 cmp_help( void *opaque, MPI result )
129 {
130   #if 0 /* we do not use this anymore */
131     int rc=0, i, j, c, old_enc;
132     byte *dp;
133     const byte *asn;
134     size_t mdlen, asnlen;
135     struct cmp_help_context_s *ctx = opaque;
136     PKT_signature *sig = ctx->sig;
137     MD_HANDLE digest = ctx->md;
138
139     old_enc = 0;
140     for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
141         if( !j ) {
142             if( !i && c != 1 )
143                 break;
144             else if( i && c == 0xff )
145                 ; /* skip the padding */
146             else if( i && !c )
147                 j++;
148             else
149                 break;
150         }
151         else if( ++j == 18 && c != 1 )
152             break;
153         else if( j == 19 && c == 0 ) {
154             old_enc++;
155             break;
156         }
157     }
158     if( old_enc ) {
159         log_error("old encoding scheme is not supported\n");
160         return G10ERR_GENERAL;
161     }
162
163     if( (rc=check_digest_algo(sig->digest_algo)) )
164         return rc; /* unsupported algo */
165     asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
166
167     for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
168                                                            i++, j-- )
169         if( asn[j] != c )
170             break;
171     if( j != -1 || mpi_getbyte(result, i) )
172         return G10ERR_BAD_PUBKEY;  /* ASN is wrong */
173     for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
174         if( c != 0xff  )
175             break;
176     i++;
177     if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
178         /* Padding or leading bytes in signature is wrong */
179         return G10ERR_BAD_PUBKEY;
180     }
181     if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
182         || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
183         /* Wrong key used to check the signature */
184         return G10ERR_BAD_PUBKEY;
185     }
186
187     dp = md_read( digest, sig->digest_algo );
188     for(i=mdlen-1; i >= 0; i--, dp++ ) {
189         if( mpi_getbyte( result, i ) != *dp )
190             return G10ERR_BAD_SIGN;
191     }
192     return 0;
193   #else
194     return -1;
195   #endif
196 }
197
198
199 static int
200 do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
201                                                     int *r_expired )
202 {
203     MPI result = NULL;
204     int rc=0;
205     struct cmp_help_context_s ctx;
206     u32 cur_time;
207
208     *r_expired = 0;
209     if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
210         log_info(_("this is a PGP generated "
211                   "ElGamal key which is NOT secure for signatures!\n"));
212         return G10ERR_PUBKEY_ALGO;
213     }
214
215     if( pk->timestamp > sig->timestamp ) {
216         ulong d = pk->timestamp - sig->timestamp;
217         log_info( d==1
218                   ? _("public key is %lu second newer than the signature\n")
219                   : _("public key is %lu seconds newer than the signature\n"),
220                        d );
221         if( !opt.ignore_time_conflict )
222             return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
223     }
224
225     cur_time = make_timestamp();
226     if( pk->timestamp > cur_time ) {
227         ulong d = pk->timestamp - cur_time;
228         log_info( d==1 ? _("key has been created %lu second "
229                            "in future (time warp or clock problem)\n")
230                        : _("key has been created %lu seconds "
231                            "in future (time warp or clock problem)\n"), d );
232         if( !opt.ignore_time_conflict )
233             return G10ERR_TIME_CONFLICT;
234     }
235
236     if( pk->expiredate && pk->expiredate < cur_time ) {
237         char buf[11];
238         if (opt.verbose) {
239             u32 tmp_kid[2];
240
241             keyid_from_pk( pk, tmp_kid );
242             log_info(_("NOTE: signature key %08lX expired %s\n"),
243                      (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
244         }
245         /* SIGEXPIRED is deprecated.  Use KEYEXPIRED. */
246         sprintf(buf,"%lu",(ulong)pk->expiredate);
247         write_status_text(STATUS_KEYEXPIRED,buf);
248         write_status(STATUS_SIGEXPIRED);
249         *r_expired = 1;
250     }
251
252
253     if( (rc=check_digest_algo(sig->digest_algo)) )
254         return rc;
255     if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
256         return rc;
257
258     /* make sure the digest algo is enabled (in case of a detached signature)*/
259     md_enable( digest, sig->digest_algo );
260
261     /* complete the digest */
262     if( sig->version >= 4 )
263         md_putc( digest, sig->version );
264     md_putc( digest, sig->sig_class );
265     if( sig->version < 4 ) {
266         u32 a = sig->timestamp;
267         md_putc( digest, (a >> 24) & 0xff );
268         md_putc( digest, (a >> 16) & 0xff );
269         md_putc( digest, (a >>  8) & 0xff );
270         md_putc( digest,  a        & 0xff );
271     }
272     else {
273         byte buf[6];
274         size_t n;
275         md_putc( digest, sig->pubkey_algo );
276         md_putc( digest, sig->digest_algo );
277         if( sig->hashed ) {
278             n = sig->hashed->len;
279             md_putc (digest, (n >> 8) );
280             md_putc (digest,  n       );
281             md_write (digest, sig->hashed->data, n);
282             n += 6;
283         }
284         else {
285           /* Two octets for the (empty) length of the hashed
286              section. */
287           md_putc (digest, 0);
288           md_putc (digest, 0);
289           n = 6;
290         }
291         /* add some magic */
292         buf[0] = sig->version;
293         buf[1] = 0xff;
294         buf[2] = n >> 24;
295         buf[3] = n >> 16;
296         buf[4] = n >>  8;
297         buf[5] = n;
298         md_write( digest, buf, 6 );
299     }
300     md_final( digest );
301
302     result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
303                               mpi_get_nbits(pk->pkey[0]), 0 );
304     if (!result)
305         return G10ERR_GENERAL;
306     ctx.sig = sig;
307     ctx.md = digest;
308     rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
309                         cmp_help, &ctx );
310     mpi_free( result );
311     if( (opt.emulate_bugs & EMUBUG_MDENCODE)
312         && rc == G10ERR_BAD_SIGN && is_ELGAMAL(pk->pubkey_algo) ) {
313         /* In this case we try again because old GnuPG versions didn't encode
314          * the hash right. There is no problem with DSA however  */
315         result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
316                               mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
317         if (!result)
318             rc = G10ERR_GENERAL;
319         else {
320             ctx.sig = sig;
321             ctx.md = digest;
322             rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
323                                 cmp_help, &ctx );
324         }
325     }
326
327     if( !rc && sig->flags.unknown_critical ) {
328         log_info(_("assuming bad signature due to an unknown critical bit\n"));
329         rc = G10ERR_BAD_SIGN;
330     }
331
332     return rc;
333 }
334
335
336 static void
337 hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
338 {
339     PKT_user_id *uid = unode->pkt->pkt.user_id;
340
341     assert( unode->pkt->pkttype == PKT_USER_ID );
342     if( uid->attrib_data ) {
343         if( sig->version >=4 ) {
344             byte buf[5];
345             buf[0] = 0xd1;                   /* packet of type 17 */
346             buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
347             buf[2] = uid->attrib_len >> 16;
348             buf[3] = uid->attrib_len >>  8;
349             buf[4] = uid->attrib_len;
350             md_write( md, buf, 5 );
351         }
352         md_write( md, uid->attrib_data, uid->attrib_len );
353     }
354     else {
355         if( sig->version >=4 ) {
356             byte buf[5];
357             buf[0] = 0xb4;            /* indicates a userid packet */
358             buf[1] = uid->len >> 24;  /* always use 4 length bytes */
359             buf[2] = uid->len >> 16;
360             buf[3] = uid->len >>  8;
361             buf[4] = uid->len;
362             md_write( md, buf, 5 );
363         }
364         md_write( md, uid->name, uid->len );
365     }
366 }
367
368 static void
369 cache_sig_result ( PKT_signature *sig, int result )
370 {
371     if ( !result ) {
372         sig->flags.checked = 1;
373         sig->flags.valid = 1;
374     }
375     else if ( result == G10ERR_BAD_SIGN ) {
376         sig->flags.checked = 1;
377         sig->flags.valid = 0;
378     }
379     else {
380         sig->flags.checked = 0;
381         sig->flags.valid = 0;
382     }
383 }
384
385 /****************
386  * check the signature pointed to by NODE. This is a key signature.
387  * If the function detects a self-signature, it uses the PK from
388  * ROOT and does not read any public key.
389  */
390 int
391 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
392 {
393     u32 dummy;
394     int dum2;
395     return check_key_signature2(root, node, is_selfsig, &dummy, &dum2 );
396 }
397
398 int
399 check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
400                                        u32 *r_expiredate, int *r_expired )
401 {
402     MD_HANDLE md;
403     PKT_public_key *pk;
404     PKT_signature *sig;
405     int algo;
406     int rc;
407
408     if( is_selfsig )
409         *is_selfsig = 0;
410     *r_expiredate = 0;
411     *r_expired = 0;
412     assert( node->pkt->pkttype == PKT_SIGNATURE );
413     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
414
415     pk = root->pkt->pkt.public_key;
416     sig = node->pkt->pkt.signature;
417     algo = sig->digest_algo;
418
419     /* check whether we have cached the result of a previous signature check.*/
420     if ( !opt.no_sig_cache ) {
421         if (sig->flags.checked) { /*cached status available*/
422             if( is_selfsig ) {  
423                 u32 keyid[2];   
424
425                 keyid_from_pk( pk, keyid );
426                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
427                     *is_selfsig = 1;
428             }
429             return sig->flags.valid? 0 : G10ERR_BAD_SIGN;
430         }
431     }
432
433     if( (rc=check_digest_algo(algo)) )
434         return rc;
435
436     if( sig->sig_class == 0x20 ) { /* key revocation */
437         md = md_open( algo, 0 );
438         hash_public_key( md, pk );
439         rc = do_check( pk, sig, md, r_expired );
440         cache_sig_result ( sig, rc );
441         md_close(md);
442     }
443     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
444         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
445
446         if( snode ) {
447             md = md_open( algo, 0 );
448             hash_public_key( md, pk );
449             hash_public_key( md, snode->pkt->pkt.public_key );
450             rc = do_check( pk, sig, md, r_expired );
451             cache_sig_result ( sig, rc );
452             md_close(md);
453         }
454         else {
455             if (!opt.quiet)
456                 log_info ("key %08lX: no subkey for subkey revocation packet\n",
457                           (ulong)keyid_from_pk (pk, NULL));
458             rc = G10ERR_SIG_CLASS;
459         }
460     }
461     else if( sig->sig_class == 0x18 ) { /* key binding */
462         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
463
464         if( snode ) {
465             if( is_selfsig ) {  /* does this make sense????? */
466                 u32 keyid[2];   /* it should always be a selfsig */
467
468                 keyid_from_pk( pk, keyid );
469                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
470                     *is_selfsig = 1;
471             }
472             md = md_open( algo, 0 );
473             hash_public_key( md, pk );
474             hash_public_key( md, snode->pkt->pkt.public_key );
475             rc = do_check( pk, sig, md, r_expired );
476             cache_sig_result ( sig, rc );
477             md_close(md);
478         }
479         else {
480             if (!opt.quiet)
481                 log_info ("key %08lX: no subkey for subkey binding packet\n",
482                           (ulong)keyid_from_pk (pk, NULL));
483             rc = G10ERR_SIG_CLASS;
484         }
485     }
486     else if( sig->sig_class == 0x1f ) { /* direct key signature */
487         md = md_open( algo, 0 );
488         hash_public_key( md, pk );
489         rc = do_check( pk, sig, md, r_expired );
490         cache_sig_result ( sig, rc );
491         md_close(md);
492     }
493     else { /* all other classes */
494         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
495
496         if( unode ) {
497             u32 keyid[2];
498
499             keyid_from_pk( pk, keyid );
500             md = md_open( algo, 0 );
501             hash_public_key( md, pk );
502             hash_uid_node( unode, md, sig );
503             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
504                 if( is_selfsig )
505                     *is_selfsig = 1;
506                 rc = do_check( pk, sig, md, r_expired );
507             }
508             else {
509                 rc = signature_check2( sig, md, r_expiredate, r_expired );
510             }
511             cache_sig_result ( sig, rc );
512             md_close(md);
513         }
514         else {
515             if (!opt.quiet)
516                 log_info ("key %08lX: no user ID for key signature packet "
517                           "of class %02x\n",
518                           (ulong)keyid_from_pk (pk, NULL), sig->sig_class );
519             rc = G10ERR_SIG_CLASS;
520         }
521     }
522
523     return rc;
524 }
525
526