diff options
Diffstat (limited to 'g10/sig-check.c')
-rw-r--r-- | g10/sig-check.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/g10/sig-check.c b/g10/sig-check.c index 334add785..4d39e0925 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -84,23 +84,29 @@ check_signature (PKT_signature *sig, gcry_md_hd_t digest) * revoked (0 otherwise). Note: PK being revoked does not cause this * function to fail. * - * If PK is not NULL, the public key is saved in *PK on success. + * If R_PK is not NULL, the public key is stored at that address if it + * was found; other wise NULL is stored. * * Returns 0 on success. An error code otherwise. */ -int +gpg_error_t check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, - int *r_expired, int *r_revoked, PKT_public_key *pk ) + int *r_expired, int *r_revoked, PKT_public_key **r_pk) { int rc=0; - int pk_internal; + PKT_public_key *pk; - if (pk) - pk_internal = 0; - else - { - pk_internal = 1; - pk = xmalloc_clear( sizeof *pk ); - } + if (r_expiredate) + *r_expiredate = 0; + if (r_expired) + *r_expired = 0; + if (r_revoked) + *r_revoked = 0; + if (r_pk) + *r_pk = NULL; + + pk = xtrycalloc (1, sizeof *pk); + if (!pk) + return gpg_error_from_syserror (); if ( (rc=openpgp_md_test_algo(sig->digest_algo)) ) ; /* We don't have this digest. */ @@ -114,14 +120,14 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, header is missing or does not match the actual sig. */ log_info(_("WARNING: signature digest conflict in message\n")); - rc = GPG_ERR_GENERAL; + rc = gpg_error (GPG_ERR_GENERAL); } else if( get_pubkey( pk, sig->keyid ) ) - rc = GPG_ERR_NO_PUBKEY; + rc = gpg_error (GPG_ERR_NO_PUBKEY); else if(!pk->flags.valid) { /* You cannot have a good sig from an invalid key. */ - rc = GPG_ERR_BAD_PUBKEY; + rc = gpg_error (GPG_ERR_BAD_PUBKEY); } else { @@ -136,7 +142,7 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, them as their own. The attacker couldn't actually use the subkey, but they could try and claim ownership of any signatures issued by it. */ - if(rc==0 && !pk->flags.primary && pk->flags.backsig < 2) + if (!rc && !pk->flags.primary && pk->flags.backsig < 2) { if (!pk->flags.backsig) { @@ -148,27 +154,17 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, error. TODO: change the default to require this after more keys have backsigs. */ if(opt.flags.require_cross_cert) - rc = GPG_ERR_GENERAL; + rc = gpg_error (GPG_ERR_GENERAL); } else if(pk->flags.backsig == 1) { log_info(_("WARNING: signing subkey %s has an invalid" " cross-certification\n"),keystr_from_pk(pk)); - rc = GPG_ERR_GENERAL; + rc = gpg_error (GPG_ERR_GENERAL); } } } - if (pk_internal || rc) - { - release_public_key_parts (pk); - if (pk_internal) - xfree (pk); - else - /* Be very sure that the caller doesn't try to use *PK. */ - memset (pk, 0, sizeof (*pk)); - } - if( !rc && sig->sig_class < 2 && is_status_enabled() ) { /* This signature id works best with DLP algorithms because * they use a random parameter for every signature. Instead of @@ -235,6 +231,14 @@ check_signature2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate, xfree (buffer); } + if (r_pk) + *r_pk = pk; + else + { + release_public_key_parts (pk); + xfree (pk); + } + return rc; } |