* sig-check.c (signature_check2): Signatures made by invalid subkeys
[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             n = 6;
286         /* add some magic */
287         buf[0] = sig->version;
288         buf[1] = 0xff;
289         buf[2] = n >> 24;
290         buf[3] = n >> 16;
291         buf[4] = n >>  8;
292         buf[5] = n;
293         md_write( digest, buf, 6 );
294     }
295     md_final( digest );
296
297     result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
298                               mpi_get_nbits(pk->pkey[0]), 0 );
299     if (!result)
300         return G10ERR_GENERAL;
301     ctx.sig = sig;
302     ctx.md = digest;
303     rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
304                         cmp_help, &ctx );
305     mpi_free( result );
306     if( (opt.emulate_bugs & EMUBUG_MDENCODE)
307         && rc == G10ERR_BAD_SIGN && is_ELGAMAL(pk->pubkey_algo) ) {
308         /* In this case we try again because old GnuPG versions didn't encode
309          * the hash right. There is no problem with DSA however  */
310         result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
311                               mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
312         if (!result)
313             rc = G10ERR_GENERAL;
314         else {
315             ctx.sig = sig;
316             ctx.md = digest;
317             rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
318                                 cmp_help, &ctx );
319         }
320     }
321
322     if( !rc && sig->flags.unknown_critical ) {
323         log_info(_("assuming bad signature due to an unknown critical bit\n"));
324         rc = G10ERR_BAD_SIGN;
325     }
326
327     return rc;
328 }
329
330
331 static void
332 hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
333 {
334     PKT_user_id *uid = unode->pkt->pkt.user_id;
335
336     assert( unode->pkt->pkttype == PKT_USER_ID );
337     if( uid->attrib_data ) {
338         if( sig->version >=4 ) {
339             byte buf[5];
340             buf[0] = 0xd1;                   /* packet of type 17 */
341             buf[1] = uid->attrib_len >> 24;  /* always use 4 length bytes */
342             buf[2] = uid->attrib_len >> 16;
343             buf[3] = uid->attrib_len >>  8;
344             buf[4] = uid->attrib_len;
345             md_write( md, buf, 5 );
346         }
347         md_write( md, uid->attrib_data, uid->attrib_len );
348     }
349     else {
350         if( sig->version >=4 ) {
351             byte buf[5];
352             buf[0] = 0xb4;            /* indicates a userid packet */
353             buf[1] = uid->len >> 24;  /* always use 4 length bytes */
354             buf[2] = uid->len >> 16;
355             buf[3] = uid->len >>  8;
356             buf[4] = uid->len;
357             md_write( md, buf, 5 );
358         }
359         md_write( md, uid->name, uid->len );
360     }
361 }
362
363 static void
364 cache_sig_result ( PKT_signature *sig, int result )
365 {
366     if ( !result ) {
367         sig->flags.checked = 1;
368         sig->flags.valid = 1;
369     }
370     else if ( result == G10ERR_BAD_SIGN ) {
371         sig->flags.checked = 1;
372         sig->flags.valid = 0;
373     }
374     else {
375         sig->flags.checked = 0;
376         sig->flags.valid = 0;
377     }
378 }
379
380 /****************
381  * check the signature pointed to by NODE. This is a key signature.
382  * If the function detects a self-signature, it uses the PK from
383  * ROOT and does not read any public key.
384  */
385 int
386 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
387 {
388     u32 dummy;
389     int dum2;
390     return check_key_signature2(root, node, is_selfsig, &dummy, &dum2 );
391 }
392
393 int
394 check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
395                                        u32 *r_expiredate, int *r_expired )
396 {
397     MD_HANDLE md;
398     PKT_public_key *pk;
399     PKT_signature *sig;
400     int algo;
401     int rc;
402
403     if( is_selfsig )
404         *is_selfsig = 0;
405     *r_expiredate = 0;
406     *r_expired = 0;
407     assert( node->pkt->pkttype == PKT_SIGNATURE );
408     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
409
410     pk = root->pkt->pkt.public_key;
411     sig = node->pkt->pkt.signature;
412     algo = sig->digest_algo;
413
414     /* check whether we have cached the result of a previous signature check.*/
415     if ( !opt.no_sig_cache ) {
416         if (sig->flags.checked) { /*cached status available*/
417             if( is_selfsig ) {  
418                 u32 keyid[2];   
419
420                 keyid_from_pk( pk, keyid );
421                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
422                     *is_selfsig = 1;
423             }
424             return sig->flags.valid? 0 : G10ERR_BAD_SIGN;
425         }
426     }
427
428     if( (rc=check_digest_algo(algo)) )
429         return rc;
430
431     if( sig->sig_class == 0x20 ) { /* key revocation */
432         md = md_open( algo, 0 );
433         hash_public_key( md, pk );
434         rc = do_check( pk, sig, md, r_expired );
435         cache_sig_result ( sig, rc );
436         md_close(md);
437     }
438     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
439         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
440
441         if( snode ) {
442             md = md_open( algo, 0 );
443             hash_public_key( md, pk );
444             hash_public_key( md, snode->pkt->pkt.public_key );
445             rc = do_check( pk, sig, md, r_expired );
446             cache_sig_result ( sig, rc );
447             md_close(md);
448         }
449         else {
450             if (!opt.quiet)
451                 log_info ("key %08lX: no subkey for subkey revocation packet\n",
452                           (ulong)keyid_from_pk (pk, NULL));
453             rc = G10ERR_SIG_CLASS;
454         }
455     }
456     else if( sig->sig_class == 0x18 ) { /* key binding */
457         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
458
459         if( snode ) {
460             if( is_selfsig ) {  /* does this make sense????? */
461                 u32 keyid[2];   /* it should always be a selfsig */
462
463                 keyid_from_pk( pk, keyid );
464                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
465                     *is_selfsig = 1;
466             }
467             md = md_open( algo, 0 );
468             hash_public_key( md, pk );
469             hash_public_key( md, snode->pkt->pkt.public_key );
470             rc = do_check( pk, sig, md, r_expired );
471             cache_sig_result ( sig, rc );
472             md_close(md);
473         }
474         else {
475             if (!opt.quiet)
476                 log_info ("key %08lX: no subkey for subkey binding packet\n",
477                           (ulong)keyid_from_pk (pk, NULL));
478             rc = G10ERR_SIG_CLASS;
479         }
480     }
481     else if( sig->sig_class == 0x1f ) { /* direct key signature */
482         md = md_open( algo, 0 );
483         hash_public_key( md, pk );
484         rc = do_check( pk, sig, md, r_expired );
485         cache_sig_result ( sig, rc );
486         md_close(md);
487     }
488     else { /* all other classes */
489         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
490
491         if( unode ) {
492             u32 keyid[2];
493
494             keyid_from_pk( pk, keyid );
495             md = md_open( algo, 0 );
496             hash_public_key( md, pk );
497             hash_uid_node( unode, md, sig );
498             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
499                 if( is_selfsig )
500                     *is_selfsig = 1;
501                 rc = do_check( pk, sig, md, r_expired );
502             }
503             else {
504                 rc = signature_check2( sig, md, r_expiredate, r_expired );
505             }
506             cache_sig_result ( sig, rc );
507             md_close(md);
508         }
509         else {
510             if (!opt.quiet)
511                 log_info ("key %08lX: no user ID for key signature packet "
512                           "of class %02x\n",
513                           (ulong)keyid_from_pk (pk, NULL), sig->sig_class );
514             rc = G10ERR_SIG_CLASS;
515         }
516     }
517
518     return rc;
519 }
520
521