See ChangeLog: Tue Oct 26 14:10:21 CEST 1999 Werner Koch
[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 "memory.h"
31 #include "mpi.h"
32 #include "keydb.h"
33 #include "main.h"
34 #include "status.h"
35 #include "i18n.h"
36
37 struct cmp_help_context_s {
38     PKT_signature *sig;
39     GCRY_MD_HD md;
40 };
41
42
43 static int do_signature_check( PKT_signature *sig, GCRY_MD_HD digest,
44                                                       u32 *r_expire );
45 static int do_check( PKT_public_key *pk, PKT_signature *sig,
46                                                 GCRY_MD_HD digest );
47
48
49 /****************
50  * Check the signature which is contained in SIG.
51  * The GCRY_MD_HD should be currently open, so that this function
52  * is able to append some data, before finalizing the digest.
53  */
54 int
55 signature_check( PKT_signature *sig, GCRY_MD_HD digest )
56 {
57     u32 dummy;
58     return do_signature_check( sig, digest, &dummy );
59 }
60
61 static int
62 do_signature_check( PKT_signature *sig, GCRY_MD_HD digest, u32 *r_expire )
63 {
64     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
65     int rc=0;
66
67     if( is_RSA(sig->pubkey_algo) )
68         write_status(STATUS_RSA_OR_IDEA);
69
70     *r_expire = 0;
71     if( get_pubkey( pk, sig->keyid ) )
72         rc = G10ERR_NO_PUBKEY;
73     else {
74         *r_expire = pk->expiredate;
75         rc = do_check( pk, sig, digest );
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 bacth processing applications might
87          * like this feature here */
88         GCRY_MD_HD md;
89         u32 a = sig->timestamp;
90         int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
91         byte *p, *buffer;
92
93         if( !(md = gcry_md_open( DIGEST_ALGO_RMD160, 0)) )
94             BUG();
95         gcry_md_putc( digest, sig->pubkey_algo );
96         gcry_md_putc( digest, sig->digest_algo );
97         gcry_md_putc( digest, (a >> 24) & 0xff );
98         gcry_md_putc( digest, (a >> 16) & 0xff );
99         gcry_md_putc( digest, (a >>  8) & 0xff );
100         gcry_md_putc( digest,  a        & 0xff );
101         for(i=0; i < nsig; i++ ) {
102             unsigned n = mpi_get_nbits( sig->data[i]);
103
104             gcry_md_putc( md, n>>8);
105             gcry_md_putc( md, n );
106             p = mpi_get_buffer( sig->data[i], &n, NULL );
107             gcry_md_write( md, p, n );
108             m_free(p);
109         }
110         gcry_md_final( md );
111         p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
112         buffer = m_alloc( strlen(p) + 60 );
113         sprintf( buffer, "%s %s %lu",
114                  p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
115         write_status_text( STATUS_SIG_ID, buffer );
116         m_free(buffer);
117         m_free(p);
118         gcry_md_close(md);
119     }
120
121     return rc;
122 }
123
124
125 #if 0 /* not anymore used */
126 /****************
127  * Check the MDC which is contained in SIG.
128  * The GCRY_MD_HD should be currently open, so that this function
129  * is able to append some data, before finalizing the digest.
130  */
131 int
132 mdc_kludge_check( PKT_signature *sig, GCRY_MD_HD digest )
133 {
134     int rc=0;
135
136     if( (rc=check_digest_algo(sig->digest_algo)) )
137         return rc;
138
139     /* make sure the digest algo is enabled (in case of a detached mdc??) */
140     md_enable( digest, sig->digest_algo );
141
142     /* complete the digest */
143     if( sig->version >= 4 )
144         gcry_md_putc( digest, sig->version );
145     gcry_md_putc( digest, sig->sig_class );
146     if( sig->version < 4 ) {
147         u32 a = sig->timestamp;
148         gcry_md_putc( digest, (a >> 24) & 0xff );
149         gcry_md_putc( digest, (a >> 16) & 0xff );
150         gcry_md_putc( digest, (a >>  8) & 0xff );
151         gcry_md_putc( digest,  a        & 0xff );
152     }
153     else {
154         byte buf[6];
155         size_t n;
156         gcry_md_putc( digest, sig->pubkey_algo );
157         gcry_md_putc( digest, sig->digest_algo );
158         if( sig->hashed_data ) {
159             n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
160             gcry_md_write( digest, sig->hashed_data, n+2 );
161             n += 6;
162         }
163         else
164             n = 6;
165         /* add some magic */
166         buf[0] = sig->version;
167         buf[1] = 0xff;
168         buf[2] = n >> 24;
169         buf[3] = n >> 16;
170         buf[4] = n >>  8;
171         buf[5] = n;
172         gcry_md_write( digest, buf, 6 );
173     }
174     md_final( digest );
175
176     rc = G10ERR_BAD_SIGN;
177     {   const byte *s1 = md_read( digest, sig->digest_algo );
178         int s1len = md_digest_length( sig->digest_algo );
179
180         log_hexdump( "MDC calculated", s1, s1len );
181
182         if( !sig->data[0] )
183             log_debug("sig_data[0] is NULL\n");
184         else {
185             unsigned s2len;
186             byte *s2;
187             s2 = mpi_get_buffer( sig->data[0], &s2len, NULL );
188             log_hexdump( "MDC stored    ", s2, s2len );
189
190             if( s2len != s1len )
191                 log_debug("MDC check: len differ: %d/%d\n", s1len, s2len);
192             else if( memcmp( s1, s2, s1len ) )
193                 log_debug("MDC check: hashs differ\n");
194             else
195                 rc = 0;
196             m_free(s2);
197         }
198     }
199
200     if( !rc && sig->flags.unknown_critical ) {
201         log_info(_("assuming bad MDC due to an unknown critical bit\n"));
202         rc = G10ERR_BAD_SIGN;
203     }
204     sig->flags.checked = 1;
205     sig->flags.valid = !rc;
206
207     /* FIXME: check that we are actually in an encrypted packet */
208
209     return rc;
210 }
211 #endif
212
213 /****************
214  * This function gets called by pubkey_verify() if the algorithm needs it.
215  */
216 static int
217 cmp_help( void *opaque, MPI result )
218 {
219   #if 0 /* we do not use this anymore */
220     int rc=0, i, j, c, old_enc;
221     byte *dp;
222     const byte *asn;
223     size_t mdlen, asnlen;
224     struct cmp_help_context_s *ctx = opaque;
225     PKT_signature *sig = ctx->sig;
226     GCRY_MD_HD digest = ctx->md;
227
228     old_enc = 0;
229     for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
230         if( !j ) {
231             if( !i && c != 1 )
232                 break;
233             else if( i && c == 0xff )
234                 ; /* skip the padding */
235             else if( i && !c )
236                 j++;
237             else
238                 break;
239         }
240         else if( ++j == 18 && c != 1 )
241             break;
242         else if( j == 19 && c == 0 ) {
243             old_enc++;
244             break;
245         }
246     }
247     if( old_enc ) {
248         log_error("old encoding scheme is not supported\n");
249         return G10ERR_GENERAL;
250     }
251
252     if( (rc=check_digest_algo(sig->digest_algo)) )
253         return rc; /* unsupported algo */
254     asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
255
256     for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
257                                                            i++, j-- )
258         if( asn[j] != c )
259             break;
260     if( j != -1 || mpi_getbyte(result, i) )
261         return G10ERR_BAD_PUBKEY;  /* ASN is wrong */
262     for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
263         if( c != 0xff  )
264             break;
265     i++;
266     if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
267         /* Padding or leading bytes in signature is wrong */
268         return G10ERR_BAD_PUBKEY;
269     }
270     if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
271         || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
272         /* Wrong key used to check the signature */
273         return G10ERR_BAD_PUBKEY;
274     }
275
276     dp = md_read( digest, sig->digest_algo );
277     for(i=mdlen-1; i >= 0; i--, dp++ ) {
278         if( mpi_getbyte( result, i ) != *dp )
279             return G10ERR_BAD_SIGN;
280     }
281     return 0;
282   #else
283     return -1;
284   #endif
285 }
286
287
288 static int
289 do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest )
290 {
291     MPI result = NULL;
292     int rc=0;
293     struct cmp_help_context_s ctx;
294     u32 cur_time;
295
296     if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
297         log_info(_("this is a PGP generated "
298                   "ElGamal key which is NOT secure for signatures!\n"));
299         return G10ERR_PUBKEY_ALGO;
300     }
301
302     if( pk->timestamp > sig->timestamp ) {
303         ulong d = pk->timestamp - sig->timestamp;
304         log_info( d==1
305                   ? _("public key is %lu second newer than the signature\n")
306                   : _("public key is %lu seconds newer than the signature\n"),
307                        d );
308         return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
309     }
310
311     cur_time = make_timestamp();
312     if( pk->timestamp > cur_time ) {
313         ulong d = pk->timestamp - cur_time;
314         log_info( d==1 ? _("key has been created %lu second "
315                            "in future (time warp or clock problem)\n")
316                        : _("key has been created %lu seconds "
317                            "in future (time warp or clock problem)\n"), d );
318         return G10ERR_TIME_CONFLICT;
319     }
320
321     if( pk->expiredate && pk->expiredate < cur_time ) {
322         log_info(_("NOTE: signature key expired %s\n"),
323                                         asctimestamp( pk->expiredate ) );
324         write_status(STATUS_SIGEXPIRED);
325     }
326
327
328     if( (rc=openpgp_md_test_algo(sig->digest_algo)) )
329         return rc;
330     if( (rc=openpgp_pk_test_algo(sig->pubkey_algo)) )
331         return rc;
332
333     /* make sure the digest algo is enabled (in case of a detached signature)*/
334     gcry_md_enable( digest, sig->digest_algo );
335
336     /* complete the digest */
337     if( sig->version >= 4 )
338         gcry_md_putc( digest, sig->version );
339     gcry_md_putc( digest, sig->sig_class );
340     if( sig->version < 4 ) {
341         u32 a = sig->timestamp;
342         gcry_md_putc( digest, (a >> 24) & 0xff );
343         gcry_md_putc( digest, (a >> 16) & 0xff );
344         gcry_md_putc( digest, (a >>  8) & 0xff );
345         gcry_md_putc( digest,  a        & 0xff );
346     }
347     else {
348         byte buf[6];
349         size_t n;
350         gcry_md_putc( digest, sig->pubkey_algo );
351         gcry_md_putc( digest, sig->digest_algo );
352         if( sig->hashed_data ) {
353             n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
354             gcry_md_write( digest, sig->hashed_data, n+2 );
355             n += 6;
356         }
357         else
358             n = 6;
359         /* add some magic */
360         buf[0] = sig->version;
361         buf[1] = 0xff;
362         buf[2] = n >> 24;
363         buf[3] = n >> 16;
364         buf[4] = n >>  8;
365         buf[5] = n;
366         gcry_md_write( digest, buf, 6 );
367     }
368     gcry_md_final( digest );
369
370     result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
371                                       mpi_get_nbits(pk->pkey[0]));
372
373     ctx.sig = sig;
374     ctx.md = digest;
375     rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,
376                         cmp_help, &ctx );
377     mpi_free( result );
378     if( !rc && sig->flags.unknown_critical ) {
379         log_info(_("assuming bad signature due to an unknown critical bit\n"));
380         rc = G10ERR_BAD_SIGN;
381     }
382     sig->flags.checked = 1;
383     sig->flags.valid = !rc;
384
385     return rc;
386 }
387
388
389 static void
390 hash_uid_node( KBNODE unode, GCRY_MD_HD md, PKT_signature *sig )
391 {
392     PKT_user_id *uid = unode->pkt->pkt.user_id;
393
394     assert( unode->pkt->pkttype == PKT_USER_ID );
395     if( sig->version >=4 ) {
396         byte buf[5];
397         buf[0] = 0xb4; /* indicates a userid packet */
398         buf[1] = uid->len >> 24;  /* always use 4 length bytes */
399         buf[2] = uid->len >> 16;
400         buf[3] = uid->len >>  8;
401         buf[4] = uid->len;
402         gcry_md_write( md, buf, 5 );
403     }
404     gcry_md_write( md, uid->name, uid->len );
405 }
406
407 /****************
408  * check the signature pointed to by NODE. This is a key signature.
409  * If the function detects a self-signature, it uses the PK from
410  * ROOT and does not read any public key.
411  */
412 int
413 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
414 {
415     u32 dummy;
416     return check_key_signature2(root, node, is_selfsig, &dummy );
417 }
418
419 int
420 check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
421 {
422     GCRY_MD_HD md;
423     PKT_public_key *pk;
424     PKT_signature *sig;
425     int algo;
426     int rc;
427
428     if( is_selfsig )
429         *is_selfsig = 0;
430     *r_expire = 0;
431     assert( node->pkt->pkttype == PKT_SIGNATURE );
432     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
433
434     pk = root->pkt->pkt.public_key;
435     sig = node->pkt->pkt.signature;
436     algo = sig->digest_algo;
437
438   #if 0 /* I am not sure whether this is a good thing to do */
439     if( sig->flags.checked )
440         log_debug("check_key_signature: already checked: %s\n",
441                       sig->flags.valid? "good":"bad" );
442   #endif
443
444     if( (rc=openpgp_md_test_algo(algo)) )
445         return rc;
446
447     if( sig->sig_class == 0x20 ) {
448         if( !(md = gcry_md_open( algo, 0 )) )
449             BUG();
450         hash_public_key( md, pk );
451         rc = do_check( pk, sig, md );
452         gcry_md_close(md);
453     }
454     else if( sig->sig_class == 0x28 ) { /* subkey revocation */
455         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
456
457         if( snode ) {
458             if( !(md = gcry_md_open( algo, 0 )) )
459                 BUG();
460             hash_public_key( md, pk );
461             hash_public_key( md, snode->pkt->pkt.public_key );
462             rc = do_check( pk, sig, md );
463             gcry_md_close(md);
464         }
465         else {
466             log_error("no subkey for subkey revocation packet\n");
467             rc = G10ERR_SIG_CLASS;
468         }
469     }
470     else if( sig->sig_class == 0x18 ) {
471         KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
472
473         if( snode ) {
474             if( is_selfsig ) {  /* does this make sense????? */
475                 u32 keyid[2];   /* it should always be a selfsig */
476
477                 keyid_from_pk( pk, keyid );
478                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
479                     *is_selfsig = 1;
480             }
481             if( !(md = gcry_md_open( algo, 0 )) )
482                 BUG();
483             hash_public_key( md, pk );
484             hash_public_key( md, snode->pkt->pkt.public_key );
485             rc = do_check( pk, sig, md );
486             gcry_md_close(md);
487         }
488         else {
489             log_error("no subkey for key signature packet\n");
490             rc = G10ERR_SIG_CLASS;
491         }
492     }
493     else {
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             if( !(md = gcry_md_open( algo, 0 )) )
501                 BUG();
502             hash_public_key( md, pk );
503             hash_uid_node( unode, md, sig );
504             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
505                 if( is_selfsig )
506                     *is_selfsig = 1;
507                 rc = do_check( pk, sig, md );
508             }
509             else
510                 rc = do_signature_check( sig, md, r_expire );
511             gcry_md_close(md);
512         }
513         else {
514             log_error("no user ID for key signature packet\n");
515             rc = G10ERR_SIG_CLASS;
516         }
517     }
518
519     return rc;
520 }
521
522