Adjust for the changed Camellia draft.
[gnupg.git] / sm / verify.c
1 /* verify.c - Verify a messages signature
2  * Copyright (C) 2001, 2002, 2003, 2007 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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h> 
26 #include <time.h>
27 #include <assert.h>
28
29 #include "gpgsm.h"
30 #include <gcrypt.h>
31 #include <ksba.h>
32
33 #include "keydb.h"
34 #include "i18n.h"
35
36 static char *
37 strtimestamp_r (ksba_isotime_t atime)
38 {
39   char *buffer = xmalloc (15);
40   
41   if (!atime || !*atime)
42     strcpy (buffer, "none");
43   else
44     sprintf (buffer, "%.4s-%.2s-%.2s", atime, atime+4, atime+6);
45   return buffer;
46 }
47
48
49
50 /* Hash the data for a detached signature.  Returns 0 on success.  */
51 static gpg_error_t
52 hash_data (int fd, gcry_md_hd_t md)
53 {
54   gpg_error_t err = 0;
55   FILE *fp;
56   char buffer[4096];
57   int nread;
58
59   fp = fdopen ( dup (fd), "rb");
60   if (!fp)
61     {
62       err = gpg_error_from_syserror ();
63       log_error ("fdopen(%d) failed: %s\n", fd, gpg_strerror (err));
64       return err;
65     }
66
67   do 
68     {
69       nread = fread (buffer, 1, DIM(buffer), fp);
70       gcry_md_write (md, buffer, nread);
71     }
72   while (nread);
73   if (ferror (fp))
74     {
75       err = gpg_error_from_syserror ();
76       log_error ("read error on fd %d: %s\n", fd, gpg_strerror (err));
77     }
78   fclose (fp);
79   return err;
80 }
81
82
83
84 \f
85 /* Perform a verify operation.  To verify detached signatures, data_fd
86    must be different than -1.  With OUT_FP given and a non-detached
87    signature, the signed material is written to that stream. */
88 int
89 gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
90 {
91   int i, rc;
92   Base64Context b64reader = NULL;
93   Base64Context b64writer = NULL;
94   ksba_reader_t reader;
95   ksba_writer_t writer = NULL;
96   ksba_cms_t cms = NULL;
97   ksba_stop_reason_t stopreason;
98   ksba_cert_t cert;
99   KEYDB_HANDLE kh;
100   gcry_md_hd_t data_md = NULL;
101   int signer;
102   const char *algoid;
103   int algo;
104   int is_detached;
105   FILE *fp = NULL;
106   char *p;
107
108   audit_set_type (ctrl->audit, AUDIT_TYPE_VERIFY);
109
110   kh = keydb_new (0);
111   if (!kh)
112     {
113       log_error (_("failed to allocated keyDB handle\n"));
114       rc = gpg_error (GPG_ERR_GENERAL);
115       goto leave;
116     }
117
118
119   fp = fdopen ( dup (in_fd), "rb");
120   if (!fp)
121     {
122       rc = gpg_error (gpg_err_code_from_errno (errno));
123       log_error ("fdopen() failed: %s\n", strerror (errno));
124       goto leave;
125     }
126
127   rc = gpgsm_create_reader (&b64reader, ctrl, fp, 0, &reader);
128   if (rc)
129     {
130       log_error ("can't create reader: %s\n", gpg_strerror (rc));
131       goto leave;
132     }
133
134   if (out_fp)
135     {
136       rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
137       if (rc)
138         {
139           log_error ("can't create writer: %s\n", gpg_strerror (rc));
140           goto leave;
141         }
142     }
143
144   rc = ksba_cms_new (&cms);
145   if (rc)
146     goto leave;
147
148   rc = ksba_cms_set_reader_writer (cms, reader, writer);
149   if (rc)
150     {
151       log_error ("ksba_cms_set_reader_writer failed: %s\n",
152                  gpg_strerror (rc));
153       goto leave;
154     }
155
156   rc = gcry_md_open (&data_md, 0, 0);
157   if (rc)
158     {
159       log_error ("md_open failed: %s\n", gpg_strerror (rc));
160       goto leave;
161     }
162   if (DBG_HASHING)
163     gcry_md_start_debug (data_md, "vrfy.data");
164
165   audit_log (ctrl->audit, AUDIT_SETUP_READY);
166
167   is_detached = 0;
168   do 
169     {
170       rc = ksba_cms_parse (cms, &stopreason);
171       if (rc)
172         {
173           log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
174           goto leave;
175         }
176
177       if (stopreason == KSBA_SR_NEED_HASH)
178         {
179           is_detached = 1;
180           audit_log (ctrl->audit, AUDIT_DETACHED_SIGNATURE);
181           if (opt.verbose)
182             log_info ("detached signature\n");
183         }
184
185       if (stopreason == KSBA_SR_NEED_HASH
186           || stopreason == KSBA_SR_BEGIN_DATA)
187         { 
188           audit_log (ctrl->audit, AUDIT_GOT_DATA);
189
190           /* We are now able to enable the hash algorithms */
191           for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
192             {
193               algo = gcry_md_map_name (algoid);
194               if (!algo)
195                 {
196                   log_error ("unknown hash algorithm `%s'\n",
197                              algoid? algoid:"?");
198                   if (algoid
199                       && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
200                           ||!strcmp (algoid, "1.2.840.113549.2.2")))
201                     log_info (_("(this is the MD2 algorithm)\n"));
202                   audit_log_s (ctrl->audit, AUDIT_BAD_DATA_HASH_ALGO, algoid);
203                 }
204               else
205                 {
206                   if (DBG_X509)
207                     log_debug ("enabling hash algorithm %d (%s)\n",
208                                algo, algoid? algoid:"");
209                   gcry_md_enable (data_md, algo);
210                   audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
211                 }
212             }
213           if (opt.extra_digest_algo)
214             {
215               if (DBG_X509)
216                 log_debug ("enabling extra hash algorithm %d\n", 
217                            opt.extra_digest_algo);
218               gcry_md_enable (data_md, opt.extra_digest_algo);
219             }
220           if (is_detached)
221             {
222               if (data_fd == -1)
223                 {
224                   log_info ("detached signature w/o data "
225                             "- assuming certs-only\n");
226                   audit_log (ctrl->audit, AUDIT_CERT_ONLY_SIG);
227                 }
228               else
229                 audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING,
230                               hash_data (data_fd, data_md));
231             }
232           else
233             {
234               ksba_cms_set_hash_function (cms, HASH_FNC, data_md);
235             }
236         }
237       else if (stopreason == KSBA_SR_END_DATA)
238         { /* The data bas been hashed */
239
240         }
241     }
242   while (stopreason != KSBA_SR_READY);   
243
244   if (b64writer)
245     {
246       rc = gpgsm_finish_writer (b64writer);
247       if (rc) 
248         {
249           log_error ("write failed: %s\n", gpg_strerror (rc));
250           audit_log_ok (ctrl->audit, AUDIT_WRITE_ERROR, rc);
251           goto leave;
252         }
253     }
254
255   if (data_fd != -1 && !is_detached)
256     {
257       log_error ("data given for a non-detached signature\n");
258       rc = gpg_error (GPG_ERR_CONFLICT);
259       audit_log (ctrl->audit, AUDIT_USAGE_ERROR);
260       goto leave;
261     }
262
263   for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
264     {
265       /* Fixme: it might be better to check the validity of the
266          certificate first before entering it into the DB.  This way
267          we would avoid cluttering the DB with invalid
268          certificates. */
269       audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 
270                       keydb_store_cert (cert, 0, NULL));
271       ksba_cert_release (cert);
272     }
273
274   cert = NULL;
275   for (signer=0; ; signer++)
276     {
277       char *issuer = NULL;
278       ksba_sexp_t sigval = NULL;
279       ksba_isotime_t sigtime, keyexptime;
280       ksba_sexp_t serial;
281       char *msgdigest = NULL;
282       size_t msgdigestlen;
283       char *ctattr;
284       int sigval_hash_algo;
285       int info_pkalgo;
286       unsigned int verifyflags;
287
288       rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
289       if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
290           && data_fd == -1 && is_detached)
291         {
292           log_info ("certs-only message accepted\n");
293           rc = 0;
294           break;
295         }
296       if (rc)
297         {
298           if (signer && rc == -1)
299             rc = 0;
300           break;
301         }
302
303       gpgsm_status (ctrl, STATUS_NEWSIG, NULL);
304       audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
305
306       if (DBG_X509)
307         {
308           log_debug ("signer %d - issuer: `%s'\n",
309                      signer, issuer? issuer:"[NONE]");
310           log_debug ("signer %d - serial: ", signer);
311           gpgsm_dump_serial (serial);
312           log_printf ("\n");
313         }
314       if (ctrl->audit)
315         {
316           char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
317           audit_log_s (ctrl->audit, AUDIT_SIG_NAME, tmpstr);
318           xfree (tmpstr);
319         }
320
321       rc = ksba_cms_get_signing_time (cms, signer, sigtime);
322       if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
323         *sigtime = 0;
324       else if (rc)
325         {
326           log_error ("error getting signing time: %s\n", gpg_strerror (rc));
327           *sigtime = 0; /* (we can't encode an error in the time string.) */
328         }
329
330       rc = ksba_cms_get_message_digest (cms, signer,
331                                         &msgdigest, &msgdigestlen);
332       if (!rc)
333         {
334           size_t is_enabled;
335
336           algoid = ksba_cms_get_digest_algo (cms, signer);
337           algo = gcry_md_map_name (algoid);
338           if (DBG_X509)
339             log_debug ("signer %d - digest algo: %d\n", signer, algo);
340           is_enabled = sizeof algo;
341           if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED,
342                              &algo, &is_enabled)
343                || !is_enabled)
344             {
345               log_error ("digest algo %d (%s) has not been enabled\n", 
346                          algo, algoid?algoid:"");
347               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "unsupported");
348               goto next_signer;
349             }
350         }
351       else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
352         {
353           assert (!msgdigest);
354           rc = 0;
355           algoid = NULL;
356           algo = 0; 
357         }
358       else /* real error */
359         {
360           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
361           break;
362         }
363
364       rc = ksba_cms_get_sigattr_oids (cms, signer,
365                                       "1.2.840.113549.1.9.3", &ctattr);
366       if (!rc) 
367         {
368           const char *s;
369
370           if (DBG_X509)
371             log_debug ("signer %d - content-type attribute: %s",
372                        signer, ctattr);
373
374           s = ksba_cms_get_content_oid (cms, 1);
375           if (!s || strcmp (ctattr, s))
376             {
377               log_error ("content-type attribute does not match "
378                          "actual content-type\n");
379               ksba_free (ctattr);
380               ctattr = NULL;
381               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
382               goto next_signer;
383             }
384           ksba_free (ctattr);
385           ctattr = NULL;
386         }
387       else if (rc != -1)
388         {
389           log_error ("error getting content-type attribute: %s\n",
390                      gpg_strerror (rc));
391           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
392           goto next_signer;
393         }
394       rc = 0;
395
396
397       sigval = ksba_cms_get_sig_val (cms, signer);
398       if (!sigval)
399         {
400           log_error ("no signature value available\n");
401           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
402           goto next_signer;
403         }
404       sigval_hash_algo = hash_algo_from_sigval (sigval);
405       if (DBG_X509)
406         {
407           log_debug ("signer %d - signature available (sigval hash=%d)",
408                      signer, sigval_hash_algo);
409 /*           log_printhex ("sigval    ", sigval, */
410 /*                         gcry_sexp_canon_len (sigval, 0, NULL, NULL)); */
411         }
412       if (!sigval_hash_algo)
413         sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
414
415       /* Find the certificate of the signer */
416       keydb_search_reset (kh);
417       rc = keydb_search_issuer_sn (kh, issuer, serial);
418       if (rc)
419         {
420           if (rc == -1)
421             {
422               log_error ("certificate not found\n");
423               rc = gpg_error (GPG_ERR_NO_PUBKEY);
424             }
425           else
426             log_error ("failed to find the certificate: %s\n",
427                        gpg_strerror(rc));
428           {
429             char numbuf[50];
430             sprintf (numbuf, "%d", rc);
431
432             gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey",
433                            numbuf, NULL);
434           }
435           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "no-cert");
436           goto next_signer;
437         }
438
439       rc = keydb_get_cert (kh, &cert);
440       if (rc)
441         {
442           log_error ("failed to get cert: %s\n", gpg_strerror (rc));
443           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
444           goto next_signer;
445         }
446
447       log_info (_("Signature made "));
448       if (*sigtime)
449         gpgsm_dump_time (sigtime);
450       else
451         log_printf (_("[date not given]"));
452       log_printf (_(" using certificate ID 0x%08lX\n"),
453                   gpgsm_get_short_fingerprint (cert));
454
455
456       if (msgdigest)
457         { /* Signed attributes are available. */
458           gcry_md_hd_t md;
459           unsigned char *s;
460
461           /* Check that the message digest in the signed attributes
462              matches the one we calculated on the data.  */
463           s = gcry_md_read (data_md, algo);
464           if ( !s || !msgdigestlen
465                || gcry_md_get_algo_dlen (algo) != msgdigestlen
466                || !s || memcmp (s, msgdigest, msgdigestlen) )
467             {
468               char *fpr;
469
470               log_error (_("invalid signature: message digest attribute "
471                            "does not match computed one\n"));
472               if (DBG_X509)
473                 {
474                   if (msgdigest)
475                     log_printhex ("message:  ", msgdigest, msgdigestlen);
476                   if (s)
477                     log_printhex ("computed: ",
478                                   s, gcry_md_get_algo_dlen (algo));
479                 }
480               fpr = gpgsm_fpr_and_name_for_status (cert);
481               gpgsm_status (ctrl, STATUS_BADSIG, fpr);
482               xfree (fpr);
483               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
484               goto next_signer; 
485             }
486             
487           rc = gcry_md_open (&md, sigval_hash_algo, 0);
488           if (rc)
489             {
490               log_error ("md_open failed: %s\n", gpg_strerror (rc));
491               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
492               goto next_signer;
493             }
494           if (DBG_HASHING)
495             gcry_md_start_debug (md, "vrfy.attr");
496
497           ksba_cms_set_hash_function (cms, HASH_FNC, md);
498           rc = ksba_cms_hash_signed_attrs (cms, signer);
499           if (rc)
500             {
501               log_error ("hashing signed attrs failed: %s\n",
502                          gpg_strerror (rc));
503               gcry_md_close (md);
504               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
505               goto next_signer;
506             }
507           rc = gpgsm_check_cms_signature (cert, sigval, md, 
508                                           sigval_hash_algo, &info_pkalgo);
509           gcry_md_close (md);
510         }
511       else
512         {
513           rc = gpgsm_check_cms_signature (cert, sigval, data_md, 
514                                           algo, &info_pkalgo);
515         }
516
517       if (rc)
518         {
519           char *fpr;
520
521           log_error ("invalid signature: %s\n", gpg_strerror (rc));
522           fpr = gpgsm_fpr_and_name_for_status (cert);
523           gpgsm_status (ctrl, STATUS_BADSIG, fpr);
524           xfree (fpr);
525           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
526           goto next_signer;
527         }
528       rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
529       if (rc)
530         {
531           gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
532                                       gpg_err_code (rc));
533           rc = 0;
534         }
535
536       if (DBG_X509)
537         log_debug ("signature okay - checking certs\n");
538       audit_log (ctrl->audit, AUDIT_VALIDATE_CHAIN);
539       rc = gpgsm_validate_chain (ctrl, cert,
540                                  *sigtime? sigtime : "19700101T000000",
541                                  keyexptime, 0, 
542                                  NULL, 0, &verifyflags);
543       {
544         char *fpr, *buf, *tstr;
545
546         fpr = gpgsm_fpr_and_name_for_status (cert);
547         if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
548           {
549             gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr);
550             rc = 0;
551           }
552         else
553           gpgsm_status (ctrl, STATUS_GOODSIG, fpr);
554         
555         xfree (fpr);
556
557         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
558         tstr = strtimestamp_r (sigtime);
559         buf = xasprintf ("%s %s %s %s 0 0 %d %d 00", fpr, tstr,
560                          *sigtime? sigtime : "0",
561                          *keyexptime? keyexptime : "0",
562                          info_pkalgo, algo);
563         xfree (tstr);
564         xfree (fpr);
565         gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
566         xfree (buf);
567       }
568
569       audit_log_ok (ctrl->audit, AUDIT_CHAIN_STATUS, rc);
570       if (rc) /* of validate_chain */
571         {
572           log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
573           if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
574               || gpg_err_code (rc) == GPG_ERR_BAD_CERT
575               || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
576               || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
577             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
578                                         gpg_err_code (rc));
579           else
580             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, 
581                                         gpg_err_code (rc));
582           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
583           goto next_signer;
584         }
585
586       audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "good");
587
588       for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
589         {
590           log_info (!i? _("Good signature from")
591                       : _("                aka"));
592           log_printf (" \"");
593           gpgsm_print_name (log_get_stream (), p);
594           log_printf ("\"\n");
595           ksba_free (p);
596         }
597
598       /* Print a note if this is a qualified signature.  */
599       {
600         size_t qualbuflen;
601         char qualbuffer[1];
602         
603         rc = ksba_cert_get_user_data (cert, "is_qualified", &qualbuffer,
604                                       sizeof (qualbuffer), &qualbuflen);
605         if (!rc && qualbuflen)
606           {
607             if (*qualbuffer)
608               {
609                 log_info (_("This is a qualified signature\n"));
610                 if (!opt.qualsig_approval)
611                   log_info 
612                     (_("Note, that this software is not officially approved "
613                        "to create or verify such signatures.\n"));
614               }
615           }    
616         else if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
617           log_error ("get_user_data(is_qualified) failed: %s\n",
618                      gpg_strerror (rc)); 
619       }
620
621       gpgsm_status (ctrl, STATUS_TRUST_FULLY, 
622                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
623                     "0 chain": "0 shell");
624           
625
626     next_signer:
627       rc = 0;
628       xfree (issuer);
629       xfree (serial);
630       xfree (sigval);
631       xfree (msgdigest);
632       ksba_cert_release (cert);
633       cert = NULL;
634     }
635   rc = 0;
636
637  leave:
638   ksba_cms_release (cms);
639   gpgsm_destroy_reader (b64reader);
640   gpgsm_destroy_writer (b64writer);
641   keydb_release (kh); 
642   gcry_md_close (data_md);
643   if (fp)
644     fclose (fp);
645
646   if (rc)
647     {
648       char numbuf[50];
649       sprintf (numbuf, "%d", rc );
650       gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",
651                      numbuf, NULL);
652     }
653
654   return rc;
655 }
656