1 /* verify.c - Signature verification.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
5 This file is part of GPGME.
7 GPGME is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of
10 the License, or (at your option) any later version.
12 GPGME is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
38 struct _gpgme_op_verify_result result;
40 gpgme_signature_t current_sig;
41 int did_prepare_new_sig;
48 release_op_data (void *hook)
50 op_data_t opd = (op_data_t) hook;
51 gpgme_signature_t sig = opd->result.signatures;
55 gpgme_signature_t next = sig->next;
56 gpgme_sig_notation_t notation = sig->notations;
60 gpgme_sig_notation_t next_nota = notation->next;
62 _gpgme_sig_notation_free (notation);
69 free (sig->pka_address);
74 if (opd->result.file_name)
75 free (opd->result.file_name);
80 gpgme_op_verify_result (gpgme_ctx_t ctx)
86 err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL);
95 /* Build a summary vector from RESULT. */
97 calc_sig_summary (gpgme_signature_t sig)
99 unsigned long sum = 0;
101 /* Calculate the red/green flag. */
102 if (sig->validity == GPGME_VALIDITY_FULL
103 || sig->validity == GPGME_VALIDITY_ULTIMATE)
105 if (gpg_err_code (sig->status) == GPG_ERR_NO_ERROR
106 || gpg_err_code (sig->status) == GPG_ERR_SIG_EXPIRED
107 || gpg_err_code (sig->status) == GPG_ERR_KEY_EXPIRED)
108 sum |= GPGME_SIGSUM_GREEN;
110 else if (sig->validity == GPGME_VALIDITY_NEVER)
112 if (gpg_err_code (sig->status) == GPG_ERR_NO_ERROR
113 || gpg_err_code (sig->status) == GPG_ERR_SIG_EXPIRED
114 || gpg_err_code (sig->status) == GPG_ERR_KEY_EXPIRED)
115 sum |= GPGME_SIGSUM_RED;
117 else if (gpg_err_code (sig->status) == GPG_ERR_BAD_SIGNATURE)
118 sum |= GPGME_SIGSUM_RED;
121 /* FIXME: handle the case when key and message are expired. */
122 switch (gpg_err_code (sig->status))
124 case GPG_ERR_SIG_EXPIRED:
125 sum |= GPGME_SIGSUM_SIG_EXPIRED;
128 case GPG_ERR_KEY_EXPIRED:
129 sum |= GPGME_SIGSUM_KEY_EXPIRED;
132 case GPG_ERR_NO_PUBKEY:
133 sum |= GPGME_SIGSUM_KEY_MISSING;
136 case GPG_ERR_BAD_SIGNATURE:
137 case GPG_ERR_NO_ERROR:
141 sum |= GPGME_SIGSUM_SYS_ERROR;
145 /* Now look at the certain reason codes. */
146 switch (gpg_err_code (sig->validity_reason))
148 case GPG_ERR_CRL_TOO_OLD:
149 if (sig->validity == GPGME_VALIDITY_UNKNOWN)
150 sum |= GPGME_SIGSUM_CRL_TOO_OLD;
153 case GPG_ERR_CERT_REVOKED:
154 sum |= GPGME_SIGSUM_KEY_REVOKED;
161 /* Check other flags. */
162 if (sig->wrong_key_usage)
163 sum |= GPGME_SIGSUM_BAD_POLICY;
165 /* Set the valid flag when the signature is unquestionable
167 if ((sum & GPGME_SIGSUM_GREEN) && !(sum & ~GPGME_SIGSUM_GREEN))
168 sum |= GPGME_SIGSUM_VALID;
175 prepare_new_sig (op_data_t opd)
177 gpgme_signature_t sig;
179 if (opd->only_newsig_seen && opd->current_sig)
181 /* We have only seen the NEWSIG status and nothing else - we
182 better skip this signature therefore and reuse it for the
183 next possible signature. */
184 sig = opd->current_sig;
185 memset (sig, 0, sizeof *sig);
186 assert (opd->result.signatures == sig);
190 sig = calloc (1, sizeof (*sig));
192 return gpg_error_from_errno (errno);
193 if (!opd->result.signatures)
194 opd->result.signatures = sig;
195 if (opd->current_sig)
196 opd->current_sig->next = sig;
197 opd->current_sig = sig;
199 opd->did_prepare_new_sig = 1;
200 opd->only_newsig_seen = 0;
205 parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
207 gpgme_signature_t sig;
208 char *end = strchr (args, ' ');
217 if (!opd->did_prepare_new_sig)
221 err = prepare_new_sig (opd);
225 assert (opd->did_prepare_new_sig);
226 opd->did_prepare_new_sig = 0;
228 assert (opd->current_sig);
229 sig = opd->current_sig;
231 /* FIXME: We should set the source of the state. */
234 case GPGME_STATUS_GOODSIG:
235 sig->status = gpg_error (GPG_ERR_NO_ERROR);
238 case GPGME_STATUS_EXPSIG:
239 sig->status = gpg_error (GPG_ERR_SIG_EXPIRED);
242 case GPGME_STATUS_EXPKEYSIG:
243 sig->status = gpg_error (GPG_ERR_KEY_EXPIRED);
246 case GPGME_STATUS_BADSIG:
247 sig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
250 case GPGME_STATUS_REVKEYSIG:
251 sig->status = gpg_error (GPG_ERR_CERT_REVOKED);
254 case GPGME_STATUS_ERRSIG:
255 /* Parse the pubkey algo. */
257 goto parse_err_sig_fail;
259 sig->pubkey_algo = strtol (end, &tail, 0);
260 if (errno || end == tail || *tail != ' ')
261 goto parse_err_sig_fail;
266 /* Parse the hash algo. */
268 goto parse_err_sig_fail;
270 sig->hash_algo = strtol (end, &tail, 0);
271 if (errno || end == tail || *tail != ' ')
272 goto parse_err_sig_fail;
277 /* Skip the sig class. */
278 end = strchr (end, ' ');
280 goto parse_err_sig_fail;
284 /* Parse the timestamp. */
285 sig->timestamp = _gpgme_parse_timestamp (end, &tail);
286 if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' '))
287 return gpg_error (GPG_ERR_INV_ENGINE);
292 /* Parse the return code. */
293 if (end[0] && (!end[1] || end[1] == ' '))
298 sig->status = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
302 sig->status = gpg_error (GPG_ERR_NO_PUBKEY);
306 sig->status = gpg_error (GPG_ERR_GENERAL);
310 goto parse_err_sig_fail;
312 goto parse_err_sig_ok;
315 sig->status = gpg_error (GPG_ERR_GENERAL);
320 return gpg_error (GPG_ERR_GENERAL);
325 sig->fpr = strdup (args);
327 return gpg_error_from_errno (errno);
334 parse_valid_sig (gpgme_signature_t sig, char *args)
336 char *end = strchr (args, ' ');
344 /* We require at least the fingerprint. */
345 return gpg_error (GPG_ERR_GENERAL);
349 sig->fpr = strdup (args);
351 return gpg_error_from_errno (errno);
353 /* Skip the creation date. */
354 end = strchr (end, ' ');
359 sig->timestamp = _gpgme_parse_timestamp (end, &tail);
360 if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' '))
361 return gpg_error (GPG_ERR_INV_ENGINE);
364 sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail);
365 if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' '))
366 return gpg_error (GPG_ERR_INV_ENGINE);
371 /* Skip the signature version. */
372 end = strchr (end, ' ');
378 /* Skip the reserved field. */
379 end = strchr (end, ' ');
382 /* Parse the pubkey algo. */
384 sig->pubkey_algo = strtol (end, &tail, 0);
385 if (errno || end == tail || *tail != ' ')
386 return gpg_error (GPG_ERR_INV_ENGINE);
394 /* Parse the hash algo. */
397 sig->hash_algo = strtol (end, &tail, 0);
398 if (errno || end == tail || *tail != ' ')
399 return gpg_error (GPG_ERR_INV_ENGINE);
410 parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
413 gpgme_sig_notation_t *lastp = &sig->notations;
414 gpgme_sig_notation_t notation = sig->notations;
415 char *end = strchr (args, ' ');
420 if (code == GPGME_STATUS_NOTATION_NAME || code == GPGME_STATUS_POLICY_URL)
422 /* FIXME: We could keep a pointer to the last notation in the list. */
423 while (notation && notation->value)
425 lastp = ¬ation->next;
426 notation = notation->next;
430 /* There is another notation name without data for the
431 previous one. The crypto backend misbehaves. */
432 return gpg_error (GPG_ERR_INV_ENGINE);
434 err = _gpgme_sig_notation_create (¬ation, NULL, 0, NULL, 0, 0);
438 if (code == GPGME_STATUS_NOTATION_NAME)
440 err = _gpgme_decode_percent_string (args, ¬ation->name, 0, 0);
443 _gpgme_sig_notation_free (notation);
447 notation->name_len = strlen (notation->name);
449 /* FIXME: For now we fake the human-readable flag. The
450 critical flag can not be reported as it is not
452 notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE;
453 notation->human_readable = 1;
457 /* This is a policy URL. */
459 err = _gpgme_decode_percent_string (args, ¬ation->value, 0, 0);
462 _gpgme_sig_notation_free (notation);
466 notation->value_len = strlen (notation->value);
470 else if (code == GPGME_STATUS_NOTATION_DATA)
472 int len = strlen (args) + 1;
475 /* FIXME: We could keep a pointer to the last notation in the list. */
476 while (notation && notation->next)
478 lastp = ¬ation->next;
479 notation = notation->next;
482 if (!notation || !notation->name)
483 /* There is notation data without a previous notation
484 name. The crypto backend misbehaves. */
485 return gpg_error (GPG_ERR_INV_ENGINE);
487 if (!notation->value)
489 dest = notation->value = malloc (len);
491 return gpg_error_from_errno (errno);
495 int cur_len = strlen (notation->value);
496 dest = realloc (notation->value, len + strlen (notation->value));
498 return gpg_error_from_errno (errno);
499 notation->value = dest;
503 err = _gpgme_decode_percent_string (args, &dest, len, 0);
507 notation->value_len += strlen (dest);
510 return gpg_error (GPG_ERR_INV_ENGINE);
516 parse_trust (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
518 char *end = strchr (args, ' ');
525 case GPGME_STATUS_TRUST_UNDEFINED:
527 sig->validity = GPGME_VALIDITY_UNKNOWN;
530 case GPGME_STATUS_TRUST_NEVER:
531 sig->validity = GPGME_VALIDITY_NEVER;
534 case GPGME_STATUS_TRUST_MARGINAL:
535 sig->validity = GPGME_VALIDITY_MARGINAL;
538 case GPGME_STATUS_TRUST_FULLY:
539 case GPGME_STATUS_TRUST_ULTIMATE:
540 sig->validity = GPGME_VALIDITY_FULL;
544 sig->validity_reason = 0;
545 sig->chain_model = 0;
548 sig->validity_reason = atoi (args);
549 while (*args && *args != ' ')
555 if (!strncmp (args, "chain", 2) && (args[2] == ' ' || !args[2]))
556 sig->chain_model = 1;
564 /* Parse an error status line and if SET_STATUS is true update the
565 result status as appropriate. With SET_STATUS being false, only
566 check for an error. */
568 parse_error (gpgme_signature_t sig, char *args, int set_status)
571 char *where = strchr (args, ' ');
579 where = strchr (which, ' ');
586 return gpg_error (GPG_ERR_INV_ENGINE);
590 if (!strcmp (where, "proc_pkt.plaintext")
591 && gpg_err_code (err) == GPG_ERR_BAD_DATA)
593 /* This indicates a double plaintext. The only solid way to
594 handle this is by failing the oepration. */
595 return gpg_error (GPG_ERR_BAD_DATA);
597 else if (!set_status)
599 else if (!strcmp (where, "verify.findkey"))
601 else if (!strcmp (where, "verify.keyusage")
602 && gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE)
603 sig->wrong_key_usage = 1;
610 _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
612 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
616 gpgme_signature_t sig;
619 err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL);
624 sig = opd->current_sig;
628 case GPGME_STATUS_NEWSIG:
630 calc_sig_summary (sig);
631 err = prepare_new_sig (opd);
632 opd->only_newsig_seen = 1;
635 case GPGME_STATUS_GOODSIG:
636 case GPGME_STATUS_EXPSIG:
637 case GPGME_STATUS_EXPKEYSIG:
638 case GPGME_STATUS_BADSIG:
639 case GPGME_STATUS_ERRSIG:
640 case GPGME_STATUS_REVKEYSIG:
641 if (sig && !opd->did_prepare_new_sig)
642 calc_sig_summary (sig);
643 opd->only_newsig_seen = 0;
644 return parse_new_sig (opd, code, args);
646 case GPGME_STATUS_VALIDSIG:
647 opd->only_newsig_seen = 0;
648 return sig ? parse_valid_sig (sig, args)
649 : gpg_error (GPG_ERR_INV_ENGINE);
651 case GPGME_STATUS_NODATA:
652 opd->only_newsig_seen = 0;
654 return gpg_error (GPG_ERR_NO_DATA);
655 sig->status = gpg_error (GPG_ERR_NO_DATA);
658 case GPGME_STATUS_UNEXPECTED:
659 opd->only_newsig_seen = 0;
661 return gpg_error (GPG_ERR_GENERAL);
662 sig->status = gpg_error (GPG_ERR_NO_DATA);
665 case GPGME_STATUS_NOTATION_NAME:
666 case GPGME_STATUS_NOTATION_DATA:
667 case GPGME_STATUS_POLICY_URL:
668 opd->only_newsig_seen = 0;
669 return sig ? parse_notation (sig, code, args)
670 : gpg_error (GPG_ERR_INV_ENGINE);
672 case GPGME_STATUS_TRUST_UNDEFINED:
673 case GPGME_STATUS_TRUST_NEVER:
674 case GPGME_STATUS_TRUST_MARGINAL:
675 case GPGME_STATUS_TRUST_FULLY:
676 case GPGME_STATUS_TRUST_ULTIMATE:
677 opd->only_newsig_seen = 0;
678 return sig ? parse_trust (sig, code, args)
679 : gpg_error (GPG_ERR_INV_ENGINE);
681 case GPGME_STATUS_PKA_TRUST_BAD:
682 case GPGME_STATUS_PKA_TRUST_GOOD:
683 opd->only_newsig_seen = 0;
684 /* Check that we only get one of these status codes per
685 signature; if not the crypto backend misbehaves. */
686 if (!sig || sig->pka_trust || sig->pka_address)
687 return gpg_error (GPG_ERR_INV_ENGINE);
688 sig->pka_trust = code == GPGME_STATUS_PKA_TRUST_GOOD? 2 : 1;
689 end = strchr (args, ' ');
692 sig->pka_address = strdup (args);
695 case GPGME_STATUS_ERROR:
696 opd->only_newsig_seen = 0;
697 /* Some error stati are informational, so we don't return an
698 error code if we are not ready to process this status. */
699 return parse_error (sig, args, !!sig );
701 case GPGME_STATUS_EOF:
702 if (sig && !opd->did_prepare_new_sig)
703 calc_sig_summary (sig);
704 if (opd->only_newsig_seen && sig)
706 gpgme_signature_t sig2;
707 /* The last signature has no valid information - remove it
710 if (sig == opd->result.signatures)
711 opd->result.signatures = NULL;
714 for (sig2 = opd->result.signatures; sig2; sig2 = sig2->next)
715 if (sig2->next == sig)
721 /* Note that there is no need to release the members of SIG
722 because we won't be here if they have been set. */
724 opd->current_sig = NULL;
726 opd->only_newsig_seen = 0;
729 case GPGME_STATUS_PLAINTEXT:
730 if (++opd->plaintext_seen > 1)
731 return gpg_error (GPG_ERR_BAD_DATA);
732 err = _gpgme_parse_plaintext (args, &opd->result.file_name);
744 verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
748 err = _gpgme_progress_status_handler (priv, code, args);
750 err = _gpgme_verify_status_handler (priv, code, args);
756 _gpgme_op_verify_init_result (gpgme_ctx_t ctx)
761 return _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook,
762 sizeof (*opd), release_op_data);
767 verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
768 gpgme_data_t signed_text, gpgme_data_t plaintext)
772 err = _gpgme_op_reset (ctx, synchronous);
776 err = _gpgme_op_verify_init_result (ctx);
780 _gpgme_engine_set_status_handler (ctx->engine, verify_status_handler, ctx);
783 return gpg_error (GPG_ERR_NO_DATA);
784 if (!signed_text && !plaintext)
785 return gpg_error (GPG_ERR_INV_VALUE);
787 return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
791 /* Decrypt ciphertext CIPHER and make a signature verification within
792 CTX and store the resulting plaintext in PLAIN. */
794 gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig,
795 gpgme_data_t signed_text, gpgme_data_t plaintext)
797 return verify_start (ctx, 0, sig, signed_text, plaintext);
801 /* Decrypt ciphertext CIPHER and make a signature verification within
802 CTX and store the resulting plaintext in PLAIN. */
804 gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text,
805 gpgme_data_t plaintext)
809 err = verify_start (ctx, 1, sig, signed_text, plaintext);
811 err = _gpgme_wait_one (ctx);
816 /* Compatibility interfaces. */
818 /* Get the key used to create signature IDX in CTX and return it in
821 gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
823 gpgme_verify_result_t result;
824 gpgme_signature_t sig;
826 result = gpgme_op_verify_result (ctx);
827 sig = result->signatures;
835 return gpg_error (GPG_ERR_EOF);
837 return gpgme_get_key (ctx, sig->fpr, r_key, 0);
841 /* Retrieve the signature status of signature IDX in CTX after a
842 successful verify operation in R_STAT (if non-null). The creation
843 time stamp of the signature is returned in R_CREATED (if non-null).
844 The function returns a string containing the fingerprint. */
846 gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
847 _gpgme_sig_stat_t *r_stat, time_t *r_created)
849 gpgme_verify_result_t result;
850 gpgme_signature_t sig;
852 result = gpgme_op_verify_result (ctx);
853 sig = result->signatures;
865 switch (gpg_err_code (sig->status))
867 case GPG_ERR_NO_ERROR:
868 *r_stat = GPGME_SIG_STAT_GOOD;
871 case GPG_ERR_BAD_SIGNATURE:
872 *r_stat = GPGME_SIG_STAT_BAD;
875 case GPG_ERR_NO_PUBKEY:
876 *r_stat = GPGME_SIG_STAT_NOKEY;
879 case GPG_ERR_NO_DATA:
880 *r_stat = GPGME_SIG_STAT_NOSIG;
883 case GPG_ERR_SIG_EXPIRED:
884 *r_stat = GPGME_SIG_STAT_GOOD_EXP;
887 case GPG_ERR_KEY_EXPIRED:
888 *r_stat = GPGME_SIG_STAT_GOOD_EXPKEY;
892 *r_stat = GPGME_SIG_STAT_ERROR;
897 *r_created = sig->timestamp;
902 /* Retrieve certain attributes of a signature. IDX is the index
903 number of the signature after a successful verify operation. WHAT
904 is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
905 one. WHATIDX is to be passed as 0 for most attributes . */
907 gpgme_get_sig_ulong_attr (gpgme_ctx_t ctx, int idx,
908 _gpgme_attr_t what, int whatidx)
910 gpgme_verify_result_t result;
911 gpgme_signature_t sig;
913 result = gpgme_op_verify_result (ctx);
914 sig = result->signatures;
926 case GPGME_ATTR_CREATED:
927 return sig->timestamp;
929 case GPGME_ATTR_EXPIRE:
930 return sig->exp_timestamp;
932 case GPGME_ATTR_VALIDITY:
933 return (unsigned long) sig->validity;
935 case GPGME_ATTR_SIG_STATUS:
936 switch (gpg_err_code (sig->status))
938 case GPG_ERR_NO_ERROR:
939 return GPGME_SIG_STAT_GOOD;
941 case GPG_ERR_BAD_SIGNATURE:
942 return GPGME_SIG_STAT_BAD;
944 case GPG_ERR_NO_PUBKEY:
945 return GPGME_SIG_STAT_NOKEY;
947 case GPG_ERR_NO_DATA:
948 return GPGME_SIG_STAT_NOSIG;
950 case GPG_ERR_SIG_EXPIRED:
951 return GPGME_SIG_STAT_GOOD_EXP;
953 case GPG_ERR_KEY_EXPIRED:
954 return GPGME_SIG_STAT_GOOD_EXPKEY;
957 return GPGME_SIG_STAT_ERROR;
960 case GPGME_ATTR_SIG_SUMMARY:
971 gpgme_get_sig_string_attr (gpgme_ctx_t ctx, int idx,
972 _gpgme_attr_t what, int whatidx)
974 gpgme_verify_result_t result;
975 gpgme_signature_t sig;
977 result = gpgme_op_verify_result (ctx);
978 sig = result->signatures;
993 case GPGME_ATTR_ERRTOK:
995 return sig->wrong_key_usage ? "Wrong_Key_Usage" : "";