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