Started to implement the audit log feature.
[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         { /* We are now able to enable the hash algorithms */
188           for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
189             {
190               algo = gcry_md_map_name (algoid);
191               if (!algo)
192                 {
193                   log_error ("unknown hash algorithm `%s'\n",
194                              algoid? algoid:"?");
195                   if (algoid
196                       && (  !strcmp (algoid, "1.2.840.113549.1.1.2")
197                           ||!strcmp (algoid, "1.2.840.113549.2.2")))
198                     log_info (_("(this is the MD2 algorithm)\n"));
199                   audit_log_s (ctrl->audit, AUDIT_BAD_DATA_HASH_ALGO, algoid);
200                 }
201               else
202                 {
203                   gcry_md_enable (data_md, algo);
204                   audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
205                 }
206             }
207           if (is_detached)
208             {
209               if (data_fd == -1)
210                 {
211                   log_info ("detached signature w/o data "
212                             "- assuming certs-only\n");
213                   audit_log (ctrl->audit, AUDIT_CERT_ONLY_SIG);
214                 }
215               else
216                 audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING,
217                               hash_data (data_fd, data_md));
218             }
219           else
220             {
221               ksba_cms_set_hash_function (cms, HASH_FNC, data_md);
222             }
223         }
224       else if (stopreason == KSBA_SR_END_DATA)
225         { /* The data bas been hashed */
226
227         }
228     }
229   while (stopreason != KSBA_SR_READY);   
230
231   if (b64writer)
232     {
233       rc = gpgsm_finish_writer (b64writer);
234       if (rc) 
235         {
236           log_error ("write failed: %s\n", gpg_strerror (rc));
237           audit_log_ok (ctrl->audit, AUDIT_WRITE_ERROR, rc);
238           goto leave;
239         }
240     }
241
242   if (data_fd != -1 && !is_detached)
243     {
244       log_error ("data given for a non-detached signature\n");
245       rc = gpg_error (GPG_ERR_CONFLICT);
246       audit_log (ctrl->audit, AUDIT_USAGE_ERROR);
247       goto leave;
248     }
249
250   for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
251     {
252       /* Fixme: it might be better to check the validity of the
253          certificate first before entering it into the DB.  This way
254          we would avoid cluttering the DB with invalid
255          certificates. */
256       audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 
257                       keydb_store_cert (cert, 0, NULL));
258       ksba_cert_release (cert);
259     }
260
261   cert = NULL;
262   for (signer=0; ; signer++)
263     {
264       char *issuer = NULL;
265       ksba_sexp_t sigval = NULL;
266       ksba_isotime_t sigtime, keyexptime;
267       ksba_sexp_t serial;
268       char *msgdigest = NULL;
269       size_t msgdigestlen;
270       char *ctattr;
271       int info_pkalgo;
272       unsigned int verifyflags;
273
274       rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
275       if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
276           && data_fd == -1 && is_detached)
277         {
278           log_info ("certs-only message accepted\n");
279           rc = 0;
280           break;
281         }
282       if (rc)
283         {
284           if (signer && rc == -1)
285             rc = 0;
286           break;
287         }
288
289       gpgsm_status (ctrl, STATUS_NEWSIG, NULL);
290       audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
291
292       if (DBG_X509)
293         {
294           log_debug ("signer %d - issuer: `%s'\n",
295                      signer, issuer? issuer:"[NONE]");
296           log_debug ("signer %d - serial: ", signer);
297           gpgsm_dump_serial (serial);
298           log_printf ("\n");
299         }
300       if (ctrl->audit)
301         {
302           char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
303           audit_log_s (ctrl->audit, AUDIT_SIG_NAME, tmpstr);
304           xfree (tmpstr);
305         }
306
307       rc = ksba_cms_get_signing_time (cms, signer, sigtime);
308       if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
309         *sigtime = 0;
310       else if (rc)
311         {
312           log_error ("error getting signing time: %s\n", gpg_strerror (rc));
313           *sigtime = 0; /* (we can't encode an error in the time string.) */
314         }
315
316       rc = ksba_cms_get_message_digest (cms, signer,
317                                         &msgdigest, &msgdigestlen);
318       if (!rc)
319         {
320           size_t is_enabled;
321
322           algoid = ksba_cms_get_digest_algo (cms, signer);
323           algo = gcry_md_map_name (algoid);
324           if (DBG_X509)
325             log_debug ("signer %d - digest algo: %d\n", signer, algo);
326           is_enabled = sizeof algo;
327           if ( gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED,
328                              &algo, &is_enabled)
329                || !is_enabled)
330             {
331               log_error ("digest algo %d has not been enabled\n", algo);
332               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "unsupported");
333               goto next_signer;
334             }
335         }
336       else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
337         {
338           assert (!msgdigest);
339           rc = 0;
340           algoid = NULL;
341           algo = 0; 
342         }
343       else /* real error */
344         {
345           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
346           break;
347         }
348
349       rc = ksba_cms_get_sigattr_oids (cms, signer,
350                                       "1.2.840.113549.1.9.3", &ctattr);
351       if (!rc) 
352         {
353           const char *s;
354
355           if (DBG_X509)
356             log_debug ("signer %d - content-type attribute: %s",
357                        signer, ctattr);
358
359           s = ksba_cms_get_content_oid (cms, 1);
360           if (!s || strcmp (ctattr, s))
361             {
362               log_error ("content-type attribute does not match "
363                          "actual content-type\n");
364               ksba_free (ctattr);
365               ctattr = NULL;
366               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
367               goto next_signer;
368             }
369           ksba_free (ctattr);
370           ctattr = NULL;
371         }
372       else if (rc != -1)
373         {
374           log_error ("error getting content-type attribute: %s\n",
375                      gpg_strerror (rc));
376           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
377           goto next_signer;
378         }
379       rc = 0;
380
381
382       sigval = ksba_cms_get_sig_val (cms, signer);
383       if (!sigval)
384         {
385           log_error ("no signature value available\n");
386           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
387           goto next_signer;
388         }
389       if (DBG_X509)
390         log_debug ("signer %d - signature available", signer);
391
392       /* Find the certificate of the signer */
393       keydb_search_reset (kh);
394       rc = keydb_search_issuer_sn (kh, issuer, serial);
395       if (rc)
396         {
397           if (rc == -1)
398             {
399               log_error ("certificate not found\n");
400               rc = gpg_error (GPG_ERR_NO_PUBKEY);
401             }
402           else
403             log_error ("failed to find the certificate: %s\n",
404                        gpg_strerror(rc));
405           {
406             char numbuf[50];
407             sprintf (numbuf, "%d", rc);
408
409             gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey",
410                            numbuf, NULL);
411           }
412           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "no-cert");
413           goto next_signer;
414         }
415
416       rc = keydb_get_cert (kh, &cert);
417       if (rc)
418         {
419           log_error ("failed to get cert: %s\n", gpg_strerror (rc));
420           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
421           goto next_signer;
422         }
423
424       log_info (_("Signature made "));
425       if (*sigtime)
426         gpgsm_dump_time (sigtime);
427       else
428         log_printf (_("[date not given]"));
429       log_printf (_(" using certificate ID 0x%08lX\n"),
430                   gpgsm_get_short_fingerprint (cert));
431
432
433       if (msgdigest)
434         { /* Signed attributes are available. */
435           gcry_md_hd_t md;
436           unsigned char *s;
437
438           /* check that the message digest in the signed attributes
439              matches the one we calculated on the data */
440           s = gcry_md_read (data_md, algo);
441           if ( !s || !msgdigestlen
442                || gcry_md_get_algo_dlen (algo) != msgdigestlen
443                || !s || memcmp (s, msgdigest, msgdigestlen) )
444             {
445               char *fpr;
446
447               log_error ("invalid signature: message digest attribute "
448                          "does not match calculated one\n");
449               fpr = gpgsm_fpr_and_name_for_status (cert);
450               gpgsm_status (ctrl, STATUS_BADSIG, fpr);
451               xfree (fpr);
452               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
453               goto next_signer; 
454             }
455             
456           rc = gcry_md_open (&md, algo, 0);
457           if (rc)
458             {
459               log_error ("md_open failed: %s\n", gpg_strerror (rc));
460               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
461               goto next_signer;
462             }
463           if (DBG_HASHING)
464             gcry_md_start_debug (md, "vrfy.attr");
465
466           ksba_cms_set_hash_function (cms, HASH_FNC, md);
467           rc = ksba_cms_hash_signed_attrs (cms, signer);
468           if (rc)
469             {
470               log_error ("hashing signed attrs failed: %s\n",
471                          gpg_strerror (rc));
472               gcry_md_close (md);
473               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
474               goto next_signer;
475             }
476           rc = gpgsm_check_cms_signature (cert, sigval, md, algo, 
477                                           &info_pkalgo);
478           gcry_md_close (md);
479         }
480       else
481         {
482           rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo, 
483                                           &info_pkalgo);
484         }
485
486       if (rc)
487         {
488           char *fpr;
489
490           log_error ("invalid signature: %s\n", gpg_strerror (rc));
491           fpr = gpgsm_fpr_and_name_for_status (cert);
492           gpgsm_status (ctrl, STATUS_BADSIG, fpr);
493           xfree (fpr);
494           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
495           goto next_signer;
496         }
497       rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
498       if (rc)
499         {
500           gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
501                                       gpg_err_code (rc));
502           rc = 0;
503         }
504
505       if (DBG_X509)
506         log_debug ("signature okay - checking certs\n");
507       audit_log (ctrl->audit, AUDIT_VALIDATE_CHAIN);
508       rc = gpgsm_validate_chain (ctrl, cert,
509                                  *sigtime? sigtime : "19700101T000000",
510                                  keyexptime, 0, 
511                                  NULL, 0, &verifyflags);
512       {
513         char *fpr, *buf, *tstr;
514
515         fpr = gpgsm_fpr_and_name_for_status (cert);
516         if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
517           {
518             gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr);
519             rc = 0;
520           }
521         else
522           gpgsm_status (ctrl, STATUS_GOODSIG, fpr);
523         
524         xfree (fpr);
525
526         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
527         tstr = strtimestamp_r (sigtime);
528         buf = xasprintf ("%s %s %s %s 0 0 %d %d 00", fpr, tstr,
529                          *sigtime? sigtime : "0",
530                          *keyexptime? keyexptime : "0",
531                          info_pkalgo, algo);
532         xfree (tstr);
533         xfree (fpr);
534         gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
535         xfree (buf);
536       }
537
538       if (rc) /* of validate_chain */
539         {
540           log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
541           if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
542               || gpg_err_code (rc) == GPG_ERR_BAD_CERT
543               || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
544               || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
545             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
546                                         gpg_err_code (rc));
547           else
548             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, 
549                                         gpg_err_code (rc));
550           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
551           goto next_signer;
552         }
553
554       audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "good");
555
556       for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
557         {
558           log_info (!i? _("Good signature from")
559                       : _("                aka"));
560           log_printf (" \"");
561           gpgsm_print_name (log_get_stream (), p);
562           log_printf ("\"\n");
563           ksba_free (p);
564         }
565
566       /* Print a note if this is a qualified signature.  */
567       {
568         size_t qualbuflen;
569         char qualbuffer[1];
570         
571         rc = ksba_cert_get_user_data (cert, "is_qualified", &qualbuffer,
572                                       sizeof (qualbuffer), &qualbuflen);
573         if (!rc && qualbuflen)
574           {
575             if (*qualbuffer)
576               {
577                 log_info (_("This is a qualified signature\n"));
578                 if (!opt.qualsig_approval)
579                   log_info 
580                     (_("Note, that this software is not officially approved "
581                        "to create or verify such signatures.\n"));
582               }
583           }    
584         else if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
585           log_error ("get_user_data(is_qualified) failed: %s\n",
586                      gpg_strerror (rc)); 
587       }
588
589       gpgsm_status (ctrl, STATUS_TRUST_FULLY, 
590                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
591                     "0 chain": "0 shell");
592           
593
594     next_signer:
595       rc = 0;
596       xfree (issuer);
597       xfree (serial);
598       xfree (sigval);
599       xfree (msgdigest);
600       ksba_cert_release (cert);
601       cert = NULL;
602     }
603   rc = 0;
604
605  leave:
606   ksba_cms_release (cms);
607   gpgsm_destroy_reader (b64reader);
608   gpgsm_destroy_writer (b64writer);
609   keydb_release (kh); 
610   gcry_md_close (data_md);
611   if (fp)
612     fclose (fp);
613
614   if (rc)
615     {
616       char numbuf[50];
617       sprintf (numbuf, "%d", rc );
618       gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",
619                      numbuf, NULL);
620     }
621
622   return rc;
623 }
624