1 /* verify.c - Verify a messages signature
2 * Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
37 strtimestamp_r (ksba_isotime_t atime
)
39 char *buffer
= xmalloc (15);
41 if (!atime
|| !*atime
)
42 strcpy (buffer
, "none");
44 sprintf (buffer
, "%.4s-%.2s-%.2s", atime
, atime
+4, atime
+6);
50 /* Hash the data for a detached signature. Returns 0 on success. */
52 hash_data (int fd
, gcry_md_hd_t md
)
59 fp
= fdopen ( dup (fd
), "rb");
62 err
= gpg_error_from_syserror ();
63 log_error ("fdopen(%d) failed: %s\n", fd
, gpg_strerror (err
));
69 nread
= fread (buffer
, 1, DIM(buffer
), fp
);
70 gcry_md_write (md
, buffer
, nread
);
75 err
= gpg_error_from_syserror ();
76 log_error ("read error on fd %d: %s\n", fd
, gpg_strerror (err
));
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. */
89 gpgsm_verify (ctrl_t ctrl
, int in_fd
, int data_fd
, FILE *out_fp
)
92 Base64Context b64reader
= NULL
;
93 Base64Context b64writer
= NULL
;
95 ksba_writer_t writer
= NULL
;
96 ksba_cms_t cms
= NULL
;
97 ksba_stop_reason_t stopreason
;
100 gcry_md_hd_t data_md
= NULL
;
108 audit_set_type (ctrl
->audit
, AUDIT_TYPE_VERIFY
);
113 log_error (_("failed to allocated keyDB handle\n"));
114 rc
= gpg_error (GPG_ERR_GENERAL
);
119 fp
= fdopen ( dup (in_fd
), "rb");
122 rc
= gpg_error (gpg_err_code_from_errno (errno
));
123 log_error ("fdopen() failed: %s\n", strerror (errno
));
127 rc
= gpgsm_create_reader (&b64reader
, ctrl
, fp
, 0, &reader
);
130 log_error ("can't create reader: %s\n", gpg_strerror (rc
));
136 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, NULL
, &writer
);
139 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
144 rc
= ksba_cms_new (&cms
);
148 rc
= ksba_cms_set_reader_writer (cms
, reader
, writer
);
151 log_error ("ksba_cms_set_reader_writer failed: %s\n",
156 rc
= gcry_md_open (&data_md
, 0, 0);
159 log_error ("md_open failed: %s\n", gpg_strerror (rc
));
163 gcry_md_start_debug (data_md
, "vrfy.data");
165 audit_log (ctrl
->audit
, AUDIT_SETUP_READY
);
170 rc
= ksba_cms_parse (cms
, &stopreason
);
173 log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc
));
177 if (stopreason
== KSBA_SR_NEED_HASH
)
180 audit_log (ctrl
->audit
, AUDIT_DETACHED_SIGNATURE
);
182 log_info ("detached signature\n");
185 if (stopreason
== KSBA_SR_NEED_HASH
186 || stopreason
== KSBA_SR_BEGIN_DATA
)
188 audit_log (ctrl
->audit
, AUDIT_GOT_DATA
);
190 /* We are now able to enable the hash algorithms */
191 for (i
=0; (algoid
=ksba_cms_get_digest_algo_list (cms
, i
)); i
++)
193 algo
= gcry_md_map_name (algoid
);
196 log_error ("unknown hash algorithm `%s'\n",
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
);
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
);
213 if (opt
.extra_digest_algo
)
216 log_debug ("enabling extra hash algorithm %d\n",
217 opt
.extra_digest_algo
);
218 gcry_md_enable (data_md
, opt
.extra_digest_algo
);
224 log_info ("detached signature w/o data "
225 "- assuming certs-only\n");
226 audit_log (ctrl
->audit
, AUDIT_CERT_ONLY_SIG
);
229 audit_log_ok (ctrl
->audit
, AUDIT_DATA_HASHING
,
230 hash_data (data_fd
, data_md
));
234 ksba_cms_set_hash_function (cms
, HASH_FNC
, data_md
);
237 else if (stopreason
== KSBA_SR_END_DATA
)
238 { /* The data bas been hashed */
242 while (stopreason
!= KSBA_SR_READY
);
246 rc
= gpgsm_finish_writer (b64writer
);
249 log_error ("write failed: %s\n", gpg_strerror (rc
));
250 audit_log_ok (ctrl
->audit
, AUDIT_WRITE_ERROR
, rc
);
255 if (data_fd
!= -1 && !is_detached
)
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
);
263 for (i
=0; (cert
=ksba_cms_get_cert (cms
, i
)); i
++)
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
269 audit_log_cert (ctrl
->audit
, AUDIT_SAVE_CERT
, cert
,
270 keydb_store_cert (cert
, 0, NULL
));
271 ksba_cert_release (cert
);
275 for (signer
=0; ; signer
++)
278 ksba_sexp_t sigval
= NULL
;
279 ksba_isotime_t sigtime
, keyexptime
;
281 char *msgdigest
= NULL
;
284 int sigval_hash_algo
;
286 unsigned int verifyflags
;
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
)
292 log_info ("certs-only message accepted\n");
298 if (signer
&& rc
== -1)
303 gpgsm_status (ctrl
, STATUS_NEWSIG
, NULL
);
304 audit_log_i (ctrl
->audit
, AUDIT_NEW_SIG
, signer
);
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
);
316 char *tmpstr
= gpgsm_format_sn_issuer (serial
, issuer
);
317 audit_log_s (ctrl
->audit
, AUDIT_SIG_NAME
, tmpstr
);
321 rc
= ksba_cms_get_signing_time (cms
, signer
, sigtime
);
322 if (gpg_err_code (rc
) == GPG_ERR_NO_DATA
)
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.) */
330 rc
= ksba_cms_get_message_digest (cms
, signer
,
331 &msgdigest
, &msgdigestlen
);
336 algoid
= ksba_cms_get_digest_algo (cms
, signer
);
337 algo
= gcry_md_map_name (algoid
);
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
,
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");
351 else if (gpg_err_code (rc
) == GPG_ERR_NO_DATA
)
358 else /* real error */
360 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "error");
364 rc
= ksba_cms_get_sigattr_oids (cms
, signer
,
365 "1.2.840.113549.1.9.3", &ctattr
);
371 log_debug ("signer %d - content-type attribute: %s",
374 s
= ksba_cms_get_content_oid (cms
, 1);
375 if (!s
|| strcmp (ctattr
, s
))
377 log_error ("content-type attribute does not match "
378 "actual content-type\n");
381 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
389 log_error ("error getting content-type attribute: %s\n",
391 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
397 sigval
= ksba_cms_get_sig_val (cms
, signer
);
400 log_error ("no signature value available\n");
401 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
404 sigval_hash_algo
= hash_algo_from_sigval (sigval
);
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)); */
412 if (!sigval_hash_algo
)
413 sigval_hash_algo
= algo
; /* Fallback used e.g. with old libksba. */
415 /* Find the certificate of the signer */
416 keydb_search_reset (kh
);
417 rc
= keydb_search_issuer_sn (kh
, issuer
, serial
);
422 log_error ("certificate not found\n");
423 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
426 log_error ("failed to find the certificate: %s\n",
430 sprintf (numbuf
, "%d", rc
);
432 gpgsm_status2 (ctrl
, STATUS_ERROR
, "verify.findkey",
435 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "no-cert");
439 rc
= keydb_get_cert (kh
, &cert
);
442 log_error ("failed to get cert: %s\n", gpg_strerror (rc
));
443 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "error");
447 log_info (_("Signature made "));
449 dump_isotime (sigtime
);
451 log_printf (_("[date not given]"));
452 log_printf (_(" using certificate ID 0x%08lX\n"),
453 gpgsm_get_short_fingerprint (cert
, NULL
));
457 { /* Signed attributes are available. */
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
) )
470 log_error (_("invalid signature: message digest attribute "
471 "does not match computed one\n"));
475 log_printhex ("message: ", msgdigest
, msgdigestlen
);
477 log_printhex ("computed: ",
478 s
, gcry_md_get_algo_dlen (algo
));
480 fpr
= gpgsm_fpr_and_name_for_status (cert
);
481 gpgsm_status (ctrl
, STATUS_BADSIG
, fpr
);
483 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
487 rc
= gcry_md_open (&md
, sigval_hash_algo
, 0);
490 log_error ("md_open failed: %s\n", gpg_strerror (rc
));
491 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "error");
495 gcry_md_start_debug (md
, "vrfy.attr");
497 ksba_cms_set_hash_function (cms
, HASH_FNC
, md
);
498 rc
= ksba_cms_hash_signed_attrs (cms
, signer
);
501 log_error ("hashing signed attrs failed: %s\n",
504 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "error");
507 rc
= gpgsm_check_cms_signature (cert
, sigval
, md
,
508 sigval_hash_algo
, &info_pkalgo
);
513 rc
= gpgsm_check_cms_signature (cert
, sigval
, data_md
,
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
);
525 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
528 rc
= gpgsm_cert_use_verify_p (cert
); /*(this displays an info message)*/
531 gpgsm_status_with_err_code (ctrl
, STATUS_ERROR
, "verify.keyusage",
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",
542 NULL
, 0, &verifyflags
);
544 char *fpr
, *buf
, *tstr
;
546 fpr
= gpgsm_fpr_and_name_for_status (cert
);
547 if (gpg_err_code (rc
) == GPG_ERR_CERT_EXPIRED
)
549 gpgsm_status (ctrl
, STATUS_EXPKEYSIG
, fpr
);
553 gpgsm_status (ctrl
, STATUS_GOODSIG
, fpr
);
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",
565 gpgsm_status (ctrl
, STATUS_VALIDSIG
, buf
);
569 audit_log_ok (ctrl
->audit
, AUDIT_CHAIN_STATUS
, rc
);
570 if (rc
) /* of validate_chain */
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
,
580 gpgsm_status_with_err_code (ctrl
, STATUS_TRUST_UNDEFINED
, NULL
,
582 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "bad");
586 audit_log_s (ctrl
->audit
, AUDIT_SIG_STATUS
, "good");
588 for (i
=0; (p
= ksba_cert_get_subject (cert
, i
)); i
++)
590 log_info (!i
? _("Good signature from")
593 gpgsm_print_name (log_get_stream (), p
);
598 /* Print a note if this is a qualified signature. */
603 rc
= ksba_cert_get_user_data (cert
, "is_qualified", &qualbuffer
,
604 sizeof (qualbuffer
), &qualbuflen
);
605 if (!rc
&& qualbuflen
)
609 log_info (_("This is a qualified signature\n"));
610 if (!opt
.qualsig_approval
)
612 (_("Note, that this software is not officially approved "
613 "to create or verify such signatures.\n"));
616 else if (gpg_err_code (rc
) != GPG_ERR_NOT_FOUND
)
617 log_error ("get_user_data(is_qualified) failed: %s\n",
621 gpgsm_status (ctrl
, STATUS_TRUST_FULLY
,
622 (verifyflags
& VALIDATE_FLAG_CHAIN_MODEL
)?
623 "0 chain": "0 shell");
632 ksba_cert_release (cert
);
638 ksba_cms_release (cms
);
639 gpgsm_destroy_reader (b64reader
);
640 gpgsm_destroy_writer (b64writer
);
642 gcry_md_close (data_md
);
649 sprintf (numbuf
, "%d", rc
);
650 gpgsm_status2 (ctrl
, STATUS_ERROR
, "verify.leave",