bd68d44d7a506d82ac03ed698fb3c67d3d9b0522
[gnupg.git] / g10 / sig-check.c
1 /* sig-check.c -  Check a signature
2  *      Copyright (C) 1998 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
27 #include <gcrypt.h>
28 #include "util.h"
29 #include "packet.h"
30 #include "keydb.h"
31 #include "main.h"
32 #include "status.h"
33 #include "i18n.h"
34
35 struct cmp_help_context_s {
36     PKT_signature *sig;
37     GCRY_MD_HD md;
38 };
39
40
41 static int do_signature_check( PKT_signature *sig, GCRY_MD_HD digest,
42                                                       u32 *r_expire );
43 static int do_check( PKT_public_key *pk, PKT_signature *sig,
44                                                 GCRY_MD_HD digest );
45
46
47 /****************
48  * Emulate our old PK interface here - sometime in the future we might
49  * change the internal design to directly fit to libgcrypt.
50  */
51 static int
52 pk_verify( int algo, MPI hash, MPI *data, MPI *pkey,
53            int (*cmp)(void *, MPI), void *opaque )
54 {
55     GCRY_SEXP s_sig, s_hash, s_pkey;
56     int rc;
57
58     /* forget about cmp and opaque - we never used it */
59
60     /* make a sexp from pkey */
61     if( algo == GCRY_PK_DSA ) {
62         s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ),
63                           gcry_sexp_vlist( SEXP_NEW( "dsa", 3 ),
64                           gcry_sexp_new_name_mpi( "p", pkey[0] ),
65                           gcry_sexp_new_name_mpi( "q", pkey[1] ),
66                           gcry_sexp_new_name_mpi( "g", pkey[2] ),
67                           gcry_sexp_new_name_mpi( "y", pkey[3] ),
68                           NULL ));
69     }
70     else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
71         s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ),
72                           gcry_sexp_vlist( SEXP_NEW( "elg", 3 ),
73                           gcry_sexp_new_name_mpi( "p", pkey[0] ),
74                           gcry_sexp_new_name_mpi( "g", pkey[1] ),
75                           gcry_sexp_new_name_mpi( "y", pkey[2] ),
76                           NULL ));
77     }
78     else if( algo == GCRY_PK_RSA ) {
79         s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ),
80                           gcry_sexp_vlist( SEXP_NEW( "rsa", 3 ),
81                           gcry_sexp_new_name_mpi( "n", pkey[0] ),
82                           gcry_sexp_new_name_mpi( "e", pkey[1] ),
83                           NULL ));
84     }
85     else
86         return GPGERR_PUBKEY_ALGO;
87
88     /* put hash into a S-Exp s_hash */
89     s_hash = gcry_sexp_new_mpi( hash );
90
91     /* put data into a S-Exp s_sig */
92     if( algo == GCRY_PK_DSA ) {
93         s_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ),
94                           gcry_sexp_vlist( SEXP_NEW( "dsa", 0 ),
95                           gcry_sexp_new_name_mpi( "r", data[0] ),
96                           gcry_sexp_new_name_mpi( "s", data[1] ),
97                           NULL ));
98     }
99     else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
100         s_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ),
101                           gcry_sexp_vlist( SEXP_NEW( "elg", 0 ),
102                           gcry_sexp_new_name_mpi( "r", data[0] ),
103                           gcry_sexp_new_name_mpi( "s", data[1] ),
104                           NULL ));
105     }
106     else if( algo == GCRY_PK_RSA ) {
107         s_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ),
108                           gcry_sexp_vlist( SEXP_NEW( "rsa", 3 ),
109                           gcry_sexp_new_name_mpi( "s", data[0] ),
110                           NULL ));
111     }
112     else
113         BUG();
114
115
116     rc = gcry_pk_verify( s_sig, s_hash, s_pkey );
117     gcry_sexp_release( s_sig );
118     gcry_sexp_release( s_hash );
119     gcry_sexp_release( s_pkey );
120     return rc;
121 }
122
123
124
125 /****************
126  * Check the signature which is contained in SIG.
127  * The GCRY_MD_HD should be currently open, so that this function
128  * is able to append some data, before finalizing the digest.
129  */
130 int
131 signature_check( PKT_signature *sig, GCRY_MD_HD digest )
132 {
133     u32 dummy;
134     return do_signature_check( sig, digest, &dummy );
135 }
136
137 static int
138 do_signature_check( PKT_signature *sig, GCRY_MD_HD digest, u32 *r_expire )
139 {
140     PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
141     int rc=0;
142
143     if( is_RSA(sig->pubkey_algo) )
144         write_status(STATUS_RSA_OR_IDEA);
145
146     *r_expire = 0;
147     if( get_pubkey( pk, sig->keyid ) )
148         rc = GPGERR_NO_PUBKEY;
149     else {
150         *r_expire = pk->expiredate;
151         rc = do_check( pk, sig, digest );
152     }
153
154     free_public_key( pk );
155
156     if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
157         /* This signature id works best with DLP algorithms because
158          * they use a random parameter for every signature.  Instead of
159          * this sig-id we could have also used the hash of the document
160          * and the timestamp, but the drawback of this is, that it is
161          * not possible to sign more than one identical document within
162          * one second.  Some remote bacth processing applications might
163          * like this feature here */
164         GCRY_MD_HD md;
165         u32 a = sig->timestamp;
166         int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
167         byte *p, *buffer;
168
169         if( !(md = gcry_md_open( GCRY_MD_RMD160, 0)) )
170             BUG();
171         gcry_md_putc( digest, sig->pubkey_algo );
172         gcry_md_putc( digest, sig->digest_algo );
173         gcry_md_putc( digest, (a >> 24) & 0xff );
174         gcry_md_putc( digest, (a >> 16) & 0xff );
175         gcry_md_putc( digest, (a >>  8) & 0xff );
176         gcry_md_putc( digest,  a        & 0xff );
177         for(i=0; i < nsig; i++ ) {
178             size_t n = gcry_mpi_get_nbits( sig->data[i]);
179
180             gcry_md_putc( md, n>>8);
181             gcry_md_putc( md, n );
182             if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &p, &n, sig->data[i] ) )
183                 BUG();
184             gcry_md_write( md, p, n );
185             gcry_free(p);
186         }
187         gcry_md_final( md );
188         p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
189         buffer = gcry_xmalloc( strlen(p) + 60 );
190         sprintf( buffer, "%s %s %lu",
191                  p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
192         write_status_text( STATUS_SIG_ID, buffer );
193         gcry_free(buffer);
194         gcry_free(p);
195         gcry_md_close(md);
196     }
197
198     return rc;
199 }
200
201
202 #if 0 /* not anymore used */
203 /****************
204  * Check the MDC which is contained in SIG.
205  * The GCRY_MD_HD should be currently open, so that this function
206  * is able to append some data, before finalizing the digest.
207  */
208 int
209 mdc_kludge_check( PKT_signature *sig, GCRY_MD_HD digest )
210 {
211     int rc=0;
212
213     if( (rc=check_digest_algo(sig->digest_algo)) )
214         return rc;
215
216     /* make sure the digest algo is enabled (in case of a detached mdc??) */
217     md_enable( digest, sig->digest_algo );
218
219     /* complete the digest */
220     if( sig->version >= 4 )
221         gcry_md_putc( digest, sig->version );
222     gcry_md_putc( digest, sig->sig_class );
223     if( sig->version < 4 ) {
224         u32 a = sig->timestamp;
225         gcry_md_putc( digest, (a >> 24) & 0xff );
226         gcry_md_putc( digest, (a >> 16) & 0xff );
227         gcry_md_putc( digest, (a >>  8) & 0xff );
228         gcry_md_putc( digest,  a        & 0xff );
229     }
230     else {
231         byte buf[6];
232         size_t n;
233         gcry_md_putc( digest, sig->pubkey_algo );
234         gcry_md_putc( digest, sig->digest_algo );
235         if( sig->hashed_data ) {
236             n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
237             gcry_md_write( digest, sig->hashed_data, n+2 );
238             n += 6;
239         }
240         else
241             n = 6;
242         /* add some magic */
243         buf[0] = sig->version;
244         buf[1] = 0xff;
245         buf[2] = n >> 24;
246         buf[3] = n >> 16;
247         buf[4] = n >>  8;
248         buf[5] = n;
249         gcry_md_write( digest, buf, 6 );
250     }
251     md_final( digest );
252
253     rc = GPGERR_BAD_SIGN;
254     {   const byte *s1 = md_read( digest, sig->digest_algo );
255         int s1len = md_digest_length( sig->digest_algo );
256
257         log_hexdump( "MDC calculated", s1, s1len );
258
259         if( !sig->data[0] )
260             log_debug("sig_data[0] is NULL\n");
261         else {
262             unsigned s2len;
263             char *s2;
264
265             if( gcry_mpi_print( GCRYMPI_FMT_USG, &s2, &s2len, sig->data[0] ))
266                 BUG();
267
268             log_hexdump( "MDC stored    ", s2, s2len );
269
270             if( s2len != s1len )
271                 log_debug("MDC check: len differ: %d/%d\n", s1len, s2len);
272             else if( memcmp( s1, s2, s1len ) )
273                 log_debug("MDC check: hashs differ\n");
274             else
275                 rc = 0;
276             gcry_free(s2);
277         }
278     }
279
280     if( !rc && sig->flags.unknown_critical ) {
281         log_info(_("assuming bad MDC due to an unknown critical bit\n"));
282         rc = GPGERR_BAD_SIGN;
283     }
284     sig->flags.checked = 1;
285     sig->flags.valid = !rc;
286
287     /* FIXME: check that we are actually in an encrypted packet */
288
289     return rc;
290 }
291 #endif
292
293 /****************
294  * This function gets called by pubkey_verify() if the algorithm needs it.
295  */
296 static int
297 cmp_help( void *opaque, MPI result )
298 {
299   #if 0 /* we do not use this anymore */
300     int rc=0, i, j, c, old_enc;
301     byte *dp;
302     const byte *asn;
303     size_t mdlen, asnlen;
304     struct cmp_help_context_s *ctx = opaque;
305     PKT_signature *sig = ctx->sig;
306     GCRY_MD_HD digest = ctx->md;
307
308     old_enc = 0;
309     for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
310         if( !j ) {
311             if( !i && c != 1 )
312                 break;
313             else if( i && c == 0xff )
314                 ; /* skip the padding */
315             else if( i && !c )
316                 j++;
317             else
318                 break;
319         }
320         else if( ++j == 18 && c != 1 )
321             break;
322         else if( j == 19 && c == 0 ) {
323             old_enc++;
324             break;
325         }
326     }
327     if( old_enc ) {
328         log_error("old encoding scheme is not supported\n");
329         return GPGERR_GENERAL;
330     }
331
332     if( (rc=check_digest_algo(sig->digest_algo)) )
333         return rc; /* unsupported algo */
334     asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
335
336     for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
337                                                            i++, j-- )
338         if( asn[j] != c )
339             break;
340     if( j != -1 || mpi_getbyte(result, i) )
341         return GPGERR_BAD_PUBKEY;  /* ASN is wrong */
342     for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
343         if( c != 0xff  )
344             break;
345     i++;
346     if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
347         /* Padding or leading bytes in signature is wrong */
348         return GPGERR_BAD_PUBKEY;
349     }
350     if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
351         || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
352         /* Wrong key used to check the signature */
353         return GPGERR_BAD_PUBKEY;
354     }
355
356     dp = md_read( digest, sig->digest_algo );
357     for(i=mdlen-1; i >= 0; i--, dp++ ) {
358         if( mpi_getbyte( result, i ) != *dp )
359             return GPGERR_BAD_SIGN;
360     }
361     return 0;
362   #else
363     return -1;
364   #endif
365 }
366
367
368 static int
369 do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
370 {
371     MPI result = NULL;
372     int rc=0;
373     struct cmp_help_context_s ctx;
374     u32 cur_time;
375
376     if( pk->version == 4 && pk->pubkey_algo == GCRY_PK_ELG_E ) {
377         log_info(_("this is a PGP generated "
378                   "ElGamal key which is NOT secure for signatures!\n"));
379         return GPGERR_PUBKEY_ALGO;
380     }
381
382     if( pk->timestamp > sig->timestamp ) {
383         ulong d = pk->timestamp - sig->timestamp;
384         log_info( d==1
385                   ? _("public key is %lu second newer than the signature\n")
386                   : _("public key is %lu seconds newer than the signature\n"),
387                        d );
388         return GPGERR_TIME_CONFLICT; /* pubkey newer than signature */
389     }
390
391     cur_time = make_timestamp();
392     if( pk->timestamp > cur_time ) {
393         ulong d = pk->timestamp - cur_time;
394         log_info( d==1 ? _("key has been created %lu second "
395                            "in future (time warp or clock problem)\n")
396                        : _("key has been created %lu seconds "
397                            "in future (time warp or clock problem)\n"), d );
398         return GPGERR_TIME_CONFLICT;
399     }
400
401     if( pk->expiredate && pk->expiredate < cur_time ) {
402         log_info(_("NOTE: signature key expired %s\n"),
403                                         asctimestamp( pk->expiredate ) );
404         write_status(STATUS_SIGEXPIRED);
405     }
406
407
408     if( (rc=openpgp_md_test_algo(sig->digest_algo)) )
409         return rc;
410     if( (rc=openpgp_pk_test_algo(sig->pubkey_algo, 0)) )
411         return rc;
412
413     /* make sure the digest algo is enabled (in case of a detached signature)*/
414     gcry_md_enable( digest, sig->digest_algo );
415
416     /* complete the digest */
417     if( sig->version >= 4 )
418         gcry_md_putc( digest, sig->version );
419     gcry_md_putc( digest, sig->sig_class );
420     if( sig->version < 4 ) {
421         u32 a = sig->timestamp;
422         gcry_md_putc( digest, (a >> 24) & 0xff );
423         gcry_md_putc( digest, (a >> 16) & 0xff );
424         gcry_md_putc( digest, (a >>  8) & 0xff );
425         gcry_md_putc( digest,  a        & 0xff );
426     }
427     else {
428         byte buf[6];
429         size_t n;
430         gcry_md_putc( digest, sig->pubkey_algo );
431         gcry_md_putc( digest, sig->digest_algo );
432         if( sig->hashed_data ) {
433             n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
434             gcry_md_write( digest, sig->hashed_data, n+2 );
435             n += 6;
436         }
437         else
438             n = 6;
439         /* add some magic */
440         buf[0] = sig->version;
441         buf[1] = 0xff;
442         buf[2] = n >> 24;
443         buf[3] = n >> 16;
444         buf[4] = n >>  8;
445         buf[5] = n;
446         gcry_md_write( digest, buf, 6 );
447     }
448     gcry_md_final( digest );
449
450     result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
451                                       gcry_mpi_get_nbits(pk->pkey[0]));
452
453     ctx.sig = sig;
454     ctx.md = digest;
455     rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
456                         cmp_help, &ctx );
457     mpi_release( result );
458     if( !rc && sig->flags.unknown_critical ) {
459         log_info(_("assuming bad signature due to an unknown critical bit\n"));
460         rc = GPGERR_BAD_SIGN;
461     }
462     sig->flags.checked = 1;
463     sig->flags.valid = !rc;
464
465     return rc;
466 }
467
468
469 static void
470 hash_uid_node( KBNODE unode, GCRY_MD_HD md, PKT_signature *sig )
471 {
472     PKT_user_id *uid = unode->pkt->pkt.user_id;
473
474     assert( unode->pkt->pkttype == PKT_USER_ID );
475     if( sig->version >=4 ) {
476         byte buf[5];
477         buf[0] = 0xb4; /* indicates a userid packet */
478         buf[1] = uid->len >> 24;  /* always use 4 length bytes */
479         buf[2] = uid->len >> 16;
480         buf[3] = uid->len >>  8;
481         buf[4] = uid->len;
482         gcry_md_write( md, buf, 5 );
483     }
484     gcry_md_write( md, uid->name, uid->len );
485 }
486
487 /****************
488  * check the signature pointed to by NODE. This is a key signature.
489  * If the function detects a self-signature, it uses the PK from
490  * ROOT and does not read any public key.
491  */
492 int
493 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
494 {
495     u32 dummy;
496     return check_key_signature2(root, node, is_selfsig, &dummy );
497 }
498
499 int
500 check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
501 {
502     GCRY_MD_HD md;
503     PKT_public_key *pk;
504     PKT_signature *sig;
505     int algo;
506     int rc;
507
508     if( is_selfsig )
509         *is_selfsig = 0;
510     *r_expire = 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   #if 0 /* I am not sure whether this is a good thing to do */
519     if( sig->flags.checked )
520         log_debug("check_key_signature: already checked: %s\n",
521                       sig->flags.valid? "good":"bad" );
522   #endif
523
524     if( (rc=openpgp_md_test_algo(algo)) )
525         return rc;
526
527     if( sig->sig_class == 0x20 ) {
528         if( !(md = gcry_md_open( algo, 0 )) )
529             BUG();
530         hash_public_key( md, pk );
531         rc = do_check( pk, sig, md );
532         gcry_md_close(md);
533     }
534     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
535         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
536
537         if( snode ) {
538             if( !(md = gcry_md_open( algo, 0 )) )
539                 BUG();
540             hash_public_key( md, pk );
541             hash_public_key( md, snode->pkt->pkt.public_key );
542             rc = do_check( pk, sig, md );
543             gcry_md_close(md);
544         }
545         else {
546             log_error("no subkey for subkey revocation packet\n");
547             rc = GPGERR_SIG_CLASS;
548         }
549     }
550     else if( sig->sig_class == 0x18 ) {
551         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
552
553         if( snode ) {
554             if( is_selfsig ) {  /* does this make sense????? */
555                 u32 keyid[2];   /* it should always be a selfsig */
556
557                 keyid_from_pk( pk, keyid );
558                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
559                     *is_selfsig = 1;
560             }
561             if( !(md = gcry_md_open( algo, 0 )) )
562                 BUG();
563             hash_public_key( md, pk );
564             hash_public_key( md, snode->pkt->pkt.public_key );
565             rc = do_check( pk, sig, md );
566             gcry_md_close(md);
567         }
568         else {
569             log_error("no subkey for key signature packet\n");
570             rc = GPGERR_SIG_CLASS;
571         }
572     }
573     else {
574         KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
575
576         if( unode ) {
577             u32 keyid[2];
578
579             keyid_from_pk( pk, keyid );
580             if( !(md = gcry_md_open( algo, 0 )) )
581                 BUG();
582             hash_public_key( md, pk );
583             hash_uid_node( unode, md, sig );
584             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
585                 if( is_selfsig )
586                     *is_selfsig = 1;
587                 rc = do_check( pk, sig, md );
588             }
589             else
590                 rc = do_signature_check( sig, md, r_expire );
591             gcry_md_close(md);
592         }
593         else {
594             log_error("no user ID for key signature packet\n");
595             rc = GPGERR_SIG_CLASS;
596         }
597     }
598
599     return rc;
600 }
601
602