Fixed an email/DN bug.
[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 calculated one\n");
472               fpr = gpgsm_fpr_and_name_for_status (cert);
473               gpgsm_status (ctrl, STATUS_BADSIG, fpr);
474               xfree (fpr);
475               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
476               goto next_signer; 
477             }
478             
479           rc = gcry_md_open (&md, sigval_hash_algo, 0);
480           if (rc)
481             {
482               log_error ("md_open failed: %s\n", gpg_strerror (rc));
483               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
484               goto next_signer;
485             }
486           if (DBG_HASHING)
487             gcry_md_start_debug (md, "vrfy.attr");
488
489           ksba_cms_set_hash_function (cms, HASH_FNC, md);
490           rc = ksba_cms_hash_signed_attrs (cms, signer);
491           if (rc)
492             {
493               log_error ("hashing signed attrs failed: %s\n",
494                          gpg_strerror (rc));
495               gcry_md_close (md);
496               audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
497               goto next_signer;
498             }
499           rc = gpgsm_check_cms_signature (cert, sigval, md, 
500                                           sigval_hash_algo, &info_pkalgo);
501           gcry_md_close (md);
502         }
503       else
504         {
505           rc = gpgsm_check_cms_signature (cert, sigval, data_md, 
506                                           algo, &info_pkalgo);
507         }
508
509       if (rc)
510         {
511           char *fpr;
512
513           log_error ("invalid signature: %s\n", gpg_strerror (rc));
514           fpr = gpgsm_fpr_and_name_for_status (cert);
515           gpgsm_status (ctrl, STATUS_BADSIG, fpr);
516           xfree (fpr);
517           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
518           goto next_signer;
519         }
520       rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
521       if (rc)
522         {
523           gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
524                                       gpg_err_code (rc));
525           rc = 0;
526         }
527
528       if (DBG_X509)
529         log_debug ("signature okay - checking certs\n");
530       audit_log (ctrl->audit, AUDIT_VALIDATE_CHAIN);
531       rc = gpgsm_validate_chain (ctrl, cert,
532                                  *sigtime? sigtime : "19700101T000000",
533                                  keyexptime, 0, 
534                                  NULL, 0, &verifyflags);
535       {
536         char *fpr, *buf, *tstr;
537
538         fpr = gpgsm_fpr_and_name_for_status (cert);
539         if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
540           {
541             gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr);
542             rc = 0;
543           }
544         else
545           gpgsm_status (ctrl, STATUS_GOODSIG, fpr);
546         
547         xfree (fpr);
548
549         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
550         tstr = strtimestamp_r (sigtime);
551         buf = xasprintf ("%s %s %s %s 0 0 %d %d 00", fpr, tstr,
552                          *sigtime? sigtime : "0",
553                          *keyexptime? keyexptime : "0",
554                          info_pkalgo, algo);
555         xfree (tstr);
556         xfree (fpr);
557         gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
558         xfree (buf);
559       }
560
561       audit_log_ok (ctrl->audit, AUDIT_CHAIN_STATUS, rc);
562       if (rc) /* of validate_chain */
563         {
564           log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
565           if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
566               || gpg_err_code (rc) == GPG_ERR_BAD_CERT
567               || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
568               || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
569             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
570                                         gpg_err_code (rc));
571           else
572             gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, 
573                                         gpg_err_code (rc));
574           audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
575           goto next_signer;
576         }
577
578       audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "good");
579
580       for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
581         {
582           log_info (!i? _("Good signature from")
583                       : _("                aka"));
584           log_printf (" \"");
585           gpgsm_print_name (log_get_stream (), p);
586           log_printf ("\"\n");
587           ksba_free (p);
588         }
589
590       /* Print a note if this is a qualified signature.  */
591       {
592         size_t qualbuflen;
593         char qualbuffer[1];
594         
595         rc = ksba_cert_get_user_data (cert, "is_qualified", &qualbuffer,
596                                       sizeof (qualbuffer), &qualbuflen);
597         if (!rc && qualbuflen)
598           {
599             if (*qualbuffer)
600               {
601                 log_info (_("This is a qualified signature\n"));
602                 if (!opt.qualsig_approval)
603                   log_info 
604                     (_("Note, that this software is not officially approved "
605                        "to create or verify such signatures.\n"));
606               }
607           }    
608         else if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
609           log_error ("get_user_data(is_qualified) failed: %s\n",
610                      gpg_strerror (rc)); 
611       }
612
613       gpgsm_status (ctrl, STATUS_TRUST_FULLY, 
614                     (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
615                     "0 chain": "0 shell");
616           
617
618     next_signer:
619       rc = 0;
620       xfree (issuer);
621       xfree (serial);
622       xfree (sigval);
623       xfree (msgdigest);
624       ksba_cert_release (cert);
625       cert = NULL;
626     }
627   rc = 0;
628
629  leave:
630   ksba_cms_release (cms);
631   gpgsm_destroy_reader (b64reader);
632   gpgsm_destroy_writer (b64writer);
633   keydb_release (kh); 
634   gcry_md_close (data_md);
635   if (fp)
636     fclose (fp);
637
638   if (rc)
639     {
640       char numbuf[50];
641       sprintf (numbuf, "%d", rc );
642       gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",
643                      numbuf, NULL);
644     }
645
646   return rc;
647 }
648