1 /* verify.c - Verify a messages signature
2 * Copyright (C) 2001, 2002, 2003, 2007,
3 * 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
38 strtimestamp_r (ksba_isotime_t atime)
40 char *buffer = xmalloc (15);
42 if (!atime || !*atime)
43 strcpy (buffer, "none");
45 sprintf (buffer, "%.4s-%.2s-%.2s", atime, atime+4, atime+6);
51 /* Hash the data for a detached signature. Returns 0 on success. */
53 hash_data (int fd, gcry_md_hd_t md)
60 fp = es_fdopen_nc (fd, "rb");
63 err = gpg_error_from_syserror ();
64 log_error ("fdopen(%d) failed: %s\n", fd, gpg_strerror (err));
70 nread = es_fread (buffer, 1, DIM(buffer), fp);
71 gcry_md_write (md, buffer, nread);
76 err = gpg_error_from_syserror ();
77 log_error ("read error on fd %d: %s\n", fd, gpg_strerror (err));
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. */
90 gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
93 Base64Context b64reader = NULL;
94 Base64Context b64writer = NULL;
96 ksba_writer_t writer = NULL;
97 ksba_cms_t cms = NULL;
98 ksba_stop_reason_t stopreason;
101 gcry_md_hd_t data_md = NULL;
106 estream_t in_fp = NULL;
109 audit_set_type (ctrl->audit, AUDIT_TYPE_VERIFY);
114 log_error (_("failed to allocate keyDB handle\n"));
115 rc = gpg_error (GPG_ERR_GENERAL);
120 in_fp = es_fdopen_nc (in_fd, "rb");
123 rc = gpg_error_from_syserror ();
124 log_error ("fdopen() failed: %s\n", strerror (errno));
128 rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
131 log_error ("can't create reader: %s\n", gpg_strerror (rc));
137 rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
140 log_error ("can't create writer: %s\n", gpg_strerror (rc));
145 rc = ksba_cms_new (&cms);
149 rc = ksba_cms_set_reader_writer (cms, reader, writer);
152 log_error ("ksba_cms_set_reader_writer failed: %s\n",
157 rc = gcry_md_open (&data_md, 0, 0);
160 log_error ("md_open failed: %s\n", gpg_strerror (rc));
164 gcry_md_debug (data_md, "vrfy.data");
166 audit_log (ctrl->audit, AUDIT_SETUP_READY);
171 rc = ksba_cms_parse (cms, &stopreason);
174 log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
178 if (stopreason == KSBA_SR_NEED_HASH)
181 audit_log (ctrl->audit, AUDIT_DETACHED_SIGNATURE);
183 log_info ("detached signature\n");
186 if (stopreason == KSBA_SR_NEED_HASH
187 || stopreason == KSBA_SR_BEGIN_DATA)
189 audit_log (ctrl->audit, AUDIT_GOT_DATA);
191 /* We are now able to enable the hash algorithms */
192 for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
194 algo = gcry_md_map_name (algoid);
197 log_error ("unknown hash algorithm '%s'\n",
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);
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);
214 if (opt.extra_digest_algo)
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);
227 log_info ("detached signature w/o data "
228 "- assuming certs-only\n");
229 audit_log (ctrl->audit, AUDIT_CERT_ONLY_SIG);
232 audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING,
233 hash_data (data_fd, data_md));
237 ksba_cms_set_hash_function (cms, HASH_FNC, data_md);
240 else if (stopreason == KSBA_SR_END_DATA)
241 { /* The data bas been hashed */
242 audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING, 0);
245 while (stopreason != KSBA_SR_READY);
249 rc = gpgsm_finish_writer (b64writer);
252 log_error ("write failed: %s\n", gpg_strerror (rc));
253 audit_log_ok (ctrl->audit, AUDIT_WRITE_ERROR, rc);
258 if (data_fd != -1 && !is_detached)
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);
266 for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
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
272 audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert,
273 keydb_store_cert (ctrl, cert, 0, NULL));
274 ksba_cert_release (cert);
278 for (signer=0; ; signer++)
281 ksba_sexp_t sigval = NULL;
282 ksba_isotime_t sigtime, keyexptime;
284 char *msgdigest = NULL;
287 int sigval_hash_algo;
289 unsigned int verifyflags;
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)
295 log_info ("certs-only message accepted\n");
301 if (signer && rc == -1)
306 gpgsm_status (ctrl, STATUS_NEWSIG, NULL);
307 audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
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);
319 char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
320 audit_log_s (ctrl->audit, AUDIT_SIG_NAME, tmpstr);
324 rc = ksba_cms_get_signing_time (cms, signer, sigtime);
325 if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
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.) */
333 rc = ksba_cms_get_message_digest (cms, signer,
334 &msgdigest, &msgdigestlen);
339 algoid = ksba_cms_get_digest_algo (cms, signer);
340 algo = gcry_md_map_name (algoid);
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,
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");
354 else if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
361 else /* real error */
363 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
367 rc = ksba_cms_get_sigattr_oids (cms, signer,
368 "1.2.840.113549.1.9.3", &ctattr);
374 log_debug ("signer %d - content-type attribute: %s",
377 s = ksba_cms_get_content_oid (cms, 1);
378 if (!s || strcmp (ctattr, s))
380 log_error ("content-type attribute does not match "
381 "actual content-type\n");
384 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
392 log_error ("error getting content-type attribute: %s\n",
394 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
400 sigval = ksba_cms_get_sig_val (cms, signer);
403 log_error ("no signature value available\n");
404 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
407 sigval_hash_algo = hash_algo_from_sigval (sigval);
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)); */
415 if (!sigval_hash_algo)
416 sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
418 /* Find the certificate of the signer */
419 keydb_search_reset (kh);
420 rc = keydb_search_issuer_sn (ctrl, kh, issuer, serial);
425 log_error ("certificate not found\n");
426 rc = gpg_error (GPG_ERR_NO_PUBKEY);
429 log_error ("failed to find the certificate: %s\n",
433 sprintf (numbuf, "%d", rc);
435 gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey",
438 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "no-cert");
442 rc = keydb_get_cert (kh, &cert);
445 log_error ("failed to get cert: %s\n", gpg_strerror (rc));
446 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
450 log_info (_("Signature made "));
452 dump_isotime (sigtime);
454 log_printf (_("[date not given]"));
455 log_printf (_(" using certificate ID 0x%08lX\n"),
456 gpgsm_get_short_fingerprint (cert, NULL));
458 audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
461 { /* Signed attributes are available. */
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) )
474 log_error (_("invalid signature: message digest attribute "
475 "does not match computed one\n"));
479 log_printhex ("message: ", msgdigest, msgdigestlen);
481 log_printhex ("computed: ",
482 s, gcry_md_get_algo_dlen (algo));
484 fpr = gpgsm_fpr_and_name_for_status (cert);
485 gpgsm_status (ctrl, STATUS_BADSIG, fpr);
487 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
491 audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO, sigval_hash_algo);
492 rc = gcry_md_open (&md, sigval_hash_algo, 0);
495 log_error ("md_open failed: %s\n", gpg_strerror (rc));
496 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
500 gcry_md_debug (md, "vrfy.attr");
502 ksba_cms_set_hash_function (cms, HASH_FNC, md);
503 rc = ksba_cms_hash_signed_attrs (cms, signer);
506 log_error ("hashing signed attrs failed: %s\n",
509 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
512 rc = gpgsm_check_cms_signature (cert, sigval, md,
513 sigval_hash_algo, &info_pkalgo);
518 rc = gpgsm_check_cms_signature (cert, sigval, data_md,
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);
530 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
533 rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
536 gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
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",
547 NULL, 0, &verifyflags);
549 char *fpr, *buf, *tstr;
551 fpr = gpgsm_fpr_and_name_for_status (cert);
552 if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
554 gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr);
558 gpgsm_status (ctrl, STATUS_GOODSIG, fpr);
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",
570 gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
574 audit_log_ok (ctrl->audit, AUDIT_CHAIN_STATUS, rc);
575 if (rc) /* of validate_chain */
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,
585 gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL,
587 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
591 audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "good");
593 for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
595 log_info (!i? _("Good signature from")
598 gpgsm_es_print_name (log_get_stream (), p);
603 /* Print a note if this is a qualified signature. */
608 rc = ksba_cert_get_user_data (cert, "is_qualified", &qualbuffer,
609 sizeof (qualbuffer), &qualbuflen);
610 if (!rc && qualbuflen)
614 log_info (_("This is a qualified signature\n"));
615 if (!opt.qualsig_approval)
617 (_("Note, that this software is not officially approved "
618 "to create or verify such signatures.\n"));
621 else if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
622 log_error ("get_user_data(is_qualified) failed: %s\n",
626 gpgsm_status (ctrl, STATUS_TRUST_FULLY,
627 (verifyflags & VALIDATE_FLAG_STEED)?
629 (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)?
630 "0 chain": "0 shell");
639 ksba_cert_release (cert);
645 ksba_cms_release (cms);
646 gpgsm_destroy_reader (b64reader);
647 gpgsm_destroy_writer (b64writer);
649 gcry_md_close (data_md);
655 sprintf (numbuf, "%d", rc );
656 gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",