static int sel_validity(str* res, select_t* s, sip_msg_t* msg) { int local, bound; switch(s->params[s->n - 2].v.i) { case CERT_PEER: local = 0; break; case CERT_LOCAL: local = 1; break; default: BUG("Could not determine certificate\n"); return -1; } switch (s->params[s->n - 1].v.i) { case CERT_NOTBEFORE: bound = NOT_BEFORE; break; case CERT_NOTAFTER: bound = NOT_AFTER; break; default: BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i); return -1; } return get_validity(res, local, bound, msg); }
static int pv_validity(sip_msg_t* msg, pv_param_t* param, pv_value_t* res) { int bound; switch (param->pvn.u.isname.name.n) { case PV_CERT_NOTBEFORE: bound = NOT_BEFORE; break; case PV_CERT_NOTAFTER: bound = NOT_AFTER; break; default: BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n); return pv_get_null(msg, param, res); } if (get_validity(&res->rs, 0, bound, msg) < 0) { return pv_get_null(msg, param, res); } res->flags = PV_VAL_STR; return 0; }
static int get_player(char **tab, int nb_col) { char *line; int ret; line = ""; ret = get_next_line(0, &line); if (ret <= 0 || ((ret = get_validity(nb_col, line)) <= 0)) { if (ret == 0) free(line); ft_printf("%rBad input, just put the number of the column\n"); get_player(tab, nb_col); return (0); } free(line); if (place_col(tab, ret, P1) < 0) { ft_printf("%rBad input, this place is not empty\n"); get_player(tab, nb_col); return (0); } return (1); }
/* This is the central function to collect the keys for recipients. It is thus used to prepare a public key encryption. encrypt-to keys, default keys and the keys for the actual recipients are all collected here. When not in batch mode and no recipient has been passed on the commandline, the function will also ask for recipients. RCPTS is a string list with the recipients; NULL is an allowed value but not very useful. Group expansion is done on these names; they may be in any of the user Id formats we can handle. The flags bits for each string in the string list are used for: Bit 0: This is an encrypt-to recipient. Bit 1: This is a hidden recipient. USE is the desired use for the key - usually PUBKEY_USAGE_ENC. RET_PK_LIST. On success a list of keys is stored at the address RET_PK_LIST; the caller must free this list. On error the value at this address is not changed. */ int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) { PK_LIST pk_list = NULL; PKT_public_key *pk=NULL; int rc=0; int any_recipients=0; STRLIST rov,remusr; char *def_rec = NULL; /* Try to expand groups if any have been defined. */ if (opt.grouplist) remusr = expand_group (rcpts); else remusr = rcpts; /* Check whether there are any recipients in the list and build the * list of the encrypt-to ones (we always trust them). */ for ( rov = remusr; rov; rov = rov->next ) { if ( !(rov->flags & 1) ) { /* This is a regular recipient; i.e. not an encrypt-to one. */ any_recipients = 1; /* Hidden recipients are not allowed while in PGP mode, issue a warning and switch into GnuPG mode. */ if ((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8)) { log_info(_("you may not use %s while in %s mode\n"), "--hidden-recipient", compliance_option_string()); compliance_failure(); } } else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { /* Encryption has been requested and --encrypt-to has not been disabled. Check this encrypt-to key. */ pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; /* We explicitly allow encrypt-to to an disabled key; thus we pass 1 as last argument. */ if ( (rc = get_pubkey_byname ( pk, rov->d, NULL, NULL, 1 )) ) { free_public_key ( pk ); pk = NULL; log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", rov->d, strlen (rov->d), -1); goto fail; } else if ( !(rc=check_pubkey_algo2 (pk->pubkey_algo, use )) ) { /* Skip the actual key if the key is already present * in the list. Add it to our list if not. */ if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key (pk); pk = NULL; log_info (_("%s: skipped: public key already present\n"), rov->d); } else { PK_LIST r; r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; r->flags = (rov->flags&2)?1:0; pk_list = r; /* Hidden encrypt-to recipients are not allowed while in PGP mode, issue a warning and switch into GnuPG mode. */ if ((r->flags&1) && (PGP2 || PGP6 || PGP7 || PGP8)) { log_info(_("you may not use %s while in %s mode\n"), "--hidden-encrypt-to", compliance_option_string()); compliance_failure(); } } } else { /* The public key is not usable for encryption or not available. */ free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", rov->d, strlen (rov->d), -1); goto fail; } } } /* If we don't have any recipients yet and we are not in batch mode drop into interactive selection mode. */ if ( !any_recipients && !opt.batch ) { int have_def_rec; char *answer = NULL; STRLIST backlog = NULL; if (pk_list) any_recipients = 1; def_rec = default_recipient(); have_def_rec = !!def_rec; if ( !have_def_rec ) tty_printf(_("You did not specify a user ID. (you may use \"-r\")\n")); for (;;) { rc = 0; xfree(answer); if ( have_def_rec ) { /* A default recipient is taken as the first entry. */ answer = def_rec; def_rec = NULL; } else if (backlog) { /* This is part of our trick to expand and display groups. */ answer = pop_strlist (&backlog); } else { /* Show the list of already collected recipients and ask for more. */ PK_LIST iter; tty_printf("\n"); tty_printf(_("Current recipients:\n")); for (iter=pk_list;iter;iter=iter->next) { u32 keyid[2]; keyid_from_pk(iter->pk,keyid); tty_printf("%4u%c/%s %s \"", nbits_from_pk(iter->pk), pubkey_letter(iter->pk->pubkey_algo), keystr(keyid), datestr_from_pk(iter->pk)); if (iter->pk->user_id) tty_print_utf8_string(iter->pk->user_id->name, iter->pk->user_id->len); else { size_t n; char *p = get_user_id( keyid, &n ); tty_print_utf8_string( p, n ); xfree(p); } tty_printf("\"\n"); } answer = cpr_get_utf8("pklist.user_id.enter", _("\nEnter the user ID. " "End with an empty line: ")); trim_spaces(answer); cpr_kill_prompt(); } if ( !answer || !*answer ) { xfree(answer); break; /* No more recipients entered - get out of loop. */ } /* Do group expand here too. The trick here is to continue the loop if any expansion occured. The code above will then list all expanded keys. */ if (expand_id(answer,&backlog,0)) continue; /* Get and check key for the current name. */ if (pk) free_public_key (pk); pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 ); if (rc) tty_printf(_("No such user ID.\n")); else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { if ( have_def_rec ) { /* No validation for a default recipient. */ if (!key_present_in_pk_list(pk_list, pk)) { free_public_key (pk); pk = NULL; log_info (_("skipped: public key " "already set as default recipient\n") ); } else { PK_LIST r = xmalloc (sizeof *r); r->pk = pk; pk = NULL; r->next = pk_list; r->flags = 0; /* No throwing default ids. */ pk_list = r; } any_recipients = 1; continue; } else { /* Check validity of this key. */ int trustlevel; trustlevel = get_validity (pk, pk->user_id); if ( (trustlevel & TRUST_FLAG_DISABLED) ) { tty_printf (_("Public key is disabled.\n") ); } else if ( do_we_trust_pre (pk, trustlevel) ) { /* Skip the actual key if the key is already * present in the list */ if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; log_info(_("skipped: public key already set\n") ); } else { PK_LIST r; r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; r->flags = 0; /* No throwing interactive ids. */ pk_list = r; } any_recipients = 1; continue; } } } xfree(def_rec); def_rec = NULL; have_def_rec = 0; } if ( pk ) { free_public_key( pk ); pk = NULL; } } else if ( !any_recipients && (def_rec = default_recipient()) ) { /* We are in batch mode and have only a default recipient. */ pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; /* The default recipient is allowed to be disabled; thus pass 1 as last argument. */ rc = get_pubkey_byname (pk, def_rec, NULL, NULL, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { /* Mark any_recipients here since the default recipient would have been used if it wasn't already there. It doesn't really matter if we got this key from the default recipient or an encrypt-to. */ any_recipients = 1; if (!key_present_in_pk_list(pk_list, pk)) log_info (_("skipped: public key already set " "as default recipient\n")); else { PK_LIST r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; r->flags = 0; /* No throwing default ids. */ pk_list = r; } } if ( pk ) { free_public_key( pk ); pk = NULL; } xfree(def_rec); def_rec = NULL; } else { /* General case: Check all keys. */ any_recipients = 0; for (; remusr; remusr = remusr->next ) { if ( (remusr->flags & 1) ) continue; /* encrypt-to keys are already handled. */ pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; if ( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) { /* Key not found or other error. */ free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", remusr->d, strlen (remusr->d), -1); goto fail; } else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { /* Key found and usable. Check validity. */ int trustlevel; trustlevel = get_validity (pk, pk->user_id); if ( (trustlevel & TRUST_FLAG_DISABLED) ) { /*Key has been disabled. */ free_public_key(pk); pk = NULL; log_info(_("%s: skipped: public key is disabled\n"), remusr->d); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", remusr->d, strlen (remusr->d), -1); rc=G10ERR_UNU_PUBKEY; goto fail; } else if ( do_we_trust_pre( pk, trustlevel ) ) { /* Note: do_we_trust may have changed the trustlevel */ /* We have at least one valid recipient. It doesn't * matters if this recipient is already present. */ any_recipients = 1; /* Skip the actual key if the key is already present * in the list */ if (!key_present_in_pk_list(pk_list, pk)) { free_public_key(pk); pk = NULL; log_info(_("%s: skipped: public key already present\n"), remusr->d); } else { PK_LIST r; r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; r->flags = (remusr->flags&2)?1:0; pk_list = r; } } else { /* We don't trust this key. */ free_public_key( pk ); pk = NULL; write_status_text_and_buffer (STATUS_INV_RECP, "10 ", remusr->d, strlen (remusr->d), -1); rc=G10ERR_UNU_PUBKEY; goto fail; } } else { /* Key found but not usable for us (e.g. sign-only key). */ free_public_key( pk ); pk = NULL; write_status_text_and_buffer (STATUS_INV_RECP, "0 ", remusr->d, strlen (remusr->d), -1); log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); goto fail; } } } if ( !rc && !any_recipients ) { log_error(_("no valid addressees\n")); write_status_text (STATUS_NO_RECP, "0"); rc = G10ERR_NO_USER_ID; } fail: if ( rc ) release_pk_list( pk_list ); else *ret_pk_list = pk_list; if (opt.grouplist) free_strlist(remusr); return rc; }
/**************** * Check whether we can trust this signature. * Returns: Error if we shall not trust this signatures. */ int check_signatures_trust( PKT_signature *sig ) { PKT_public_key *pk = xmalloc_clear( sizeof *pk ); unsigned int trustlevel; int rc=0; rc = get_pubkey( pk, sig->keyid ); if (rc) { /* this should not happen */ log_error("Ooops; the key vanished - can't check the trust\n"); rc = G10ERR_NO_PUBKEY; goto leave; } if ( opt.trust_model==TM_ALWAYS ) { if( !opt.quiet ) log_info(_("WARNING: Using untrusted key!\n")); if (opt.with_fingerprint) print_fingerprint (pk, NULL, 1); goto leave; } if(pk->maybe_revoked && !pk->is_revoked) log_info(_("WARNING: this key might be revoked (revocation key" " not present)\n")); trustlevel = get_validity (pk, NULL); if ( (trustlevel & TRUST_FLAG_REVOKED) ) { write_status( STATUS_KEYREVOKED ); if(pk->is_revoked==2) log_info(_("WARNING: This key has been revoked by its" " designated revoker!\n")); else log_info(_("WARNING: This key has been revoked by its owner!\n")); log_info(_(" This could mean that the signature is forged.\n")); show_revocation_reason( pk, 0 ); } else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) ) { write_status( STATUS_KEYREVOKED ); log_info(_("WARNING: This subkey has been revoked by its owner!\n")); show_revocation_reason( pk, 0 ); } if ((trustlevel & TRUST_FLAG_DISABLED)) log_info (_("Note: This key has been disabled.\n")); /* If we have PKA information adjust the trustlevel. */ if (sig->pka_info && sig->pka_info->valid) { unsigned char fpr[MAX_FINGERPRINT_LEN]; PKT_public_key *primary_pk; size_t fprlen; int okay; primary_pk = xmalloc_clear (sizeof *primary_pk); get_pubkey (primary_pk, pk->main_keyid); fingerprint_from_pk (primary_pk, fpr, &fprlen); free_public_key (primary_pk); if ( fprlen == 20 && !memcmp (sig->pka_info->fpr, fpr, 20) ) { okay = 1; write_status_text (STATUS_PKA_TRUST_GOOD, sig->pka_info->email); log_info (_("Note: Verified signer's address is `%s'\n"), sig->pka_info->email); } else { okay = 0; write_status_text (STATUS_PKA_TRUST_BAD, sig->pka_info->email); log_info (_("Note: Signer's address `%s' " "does not match DNS entry\n"), sig->pka_info->email); } switch ( (trustlevel & TRUST_MASK) ) { case TRUST_UNKNOWN: case TRUST_UNDEFINED: case TRUST_MARGINAL: if (okay && opt.verify_options&VERIFY_PKA_TRUST_INCREASE) { trustlevel = ((trustlevel & ~TRUST_MASK) | TRUST_FULLY); log_info (_("trustlevel adjusted to FULL" " due to valid PKA info\n")); } /* (fall through) */ case TRUST_FULLY: if (!okay) { trustlevel = ((trustlevel & ~TRUST_MASK) | TRUST_NEVER); log_info (_("trustlevel adjusted to NEVER" " due to bad PKA info\n")); } break; } } /* Now let the user know what up with the trustlevel. */ switch ( (trustlevel & TRUST_MASK) ) { case TRUST_EXPIRED: log_info(_("Note: This key has expired!\n")); print_fingerprint (pk, NULL, 1); break; default: log_error ("invalid trustlevel %u returned from validation layer\n", trustlevel); /* fall thru */ case TRUST_UNKNOWN: case TRUST_UNDEFINED: write_status( STATUS_TRUST_UNDEFINED ); log_info(_("WARNING: This key is not certified with" " a trusted signature!\n")); log_info(_(" There is no indication that the " "signature belongs to the owner.\n" )); print_fingerprint (pk, NULL, 1); break; case TRUST_NEVER: /* currently we won't get that status */ write_status( STATUS_TRUST_NEVER ); log_info(_("WARNING: We do NOT trust this key!\n")); log_info(_(" The signature is probably a FORGERY.\n")); if (opt.with_fingerprint) print_fingerprint (pk, NULL, 1); rc = G10ERR_BAD_SIGN; break; case TRUST_MARGINAL: write_status( STATUS_TRUST_MARGINAL ); log_info(_("WARNING: This key is not certified with" " sufficiently trusted signatures!\n")); log_info(_(" It is not certain that the" " signature belongs to the owner.\n" )); print_fingerprint (pk, NULL, 1); break; case TRUST_FULLY: write_status( STATUS_TRUST_FULLY ); if (opt.with_fingerprint) print_fingerprint (pk, NULL, 1); break; case TRUST_ULTIMATE: write_status( STATUS_TRUST_ULTIMATE ); if (opt.with_fingerprint) print_fingerprint (pk, NULL, 1); break; } leave: free_public_key( pk ); return rc; }
/* Helper for build_pk_list to find and check one key. This helper is also used directly in server mode by the RECIPIENTS command. On success the new key is added to PK_LIST_ADDR. NAME is the user id of the key. USE the requested usage and a set MARK_HIDDEN will mark the key in the updated list as a hidden recipient. */ gpg_error_t find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, int mark_hidden, pk_list_t *pk_list_addr) { int rc; PKT_public_key *pk; int trustlevel; if (!name || !*name) return gpg_error (GPG_ERR_INV_USER_ID); pk = xtrycalloc (1, sizeof *pk); if (!pk) return gpg_error_from_syserror (); pk->req_usage = use; rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0); if (rc) { /* Key not found or other error. */ log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) ); send_status_inv_recp (0, name); free_public_key (pk); return rc; } rc = openpgp_pk_test_algo2 (pk->pubkey_algo, use); if (rc) { /* Key found but not usable for us (e.g. sign-only key). */ send_status_inv_recp (0, name); log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) ); free_public_key (pk); return rc; } /* Key found and usable. Check validity. */ trustlevel = get_validity (pk, pk->user_id); if ( (trustlevel & TRUST_FLAG_DISABLED) ) { /* Key has been disabled. */ send_status_inv_recp (0, name); log_info (_("%s: skipped: public key is disabled\n"), name); free_public_key (pk); return G10ERR_UNU_PUBKEY; } if ( !do_we_trust_pre (pk, trustlevel) ) { /* We don't trust this key. */ send_status_inv_recp (10, name); free_public_key (pk); return G10ERR_UNU_PUBKEY; } /* Note: do_we_trust may have changed the trustlevel. */ /* Skip the actual key if the key is already present in the list. */ if (!key_present_in_pk_list (*pk_list_addr, pk)) { log_info (_("%s: skipped: public key already present\n"), name); free_public_key (pk); } else { pk_list_t r; r = xtrymalloc (sizeof *r); if (!r) { rc = gpg_error_from_syserror (); free_public_key (pk); return rc; } r->pk = pk; r->next = *pk_list_addr; r->flags = mark_hidden? 1:0; *pk_list_addr = r; } return 0; }