diff options
author | Werner Koch <[email protected]> | 2005-07-28 18:59:36 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2005-07-28 18:59:36 +0000 |
commit | 986a137c58cae8dc7210ccf51cdea38ec6e8828f (patch) | |
tree | 4f847f04509fc74a1fa6db4839abd5d41c80eb9c /g10/mainproc.c | |
parent | Converted all m_free to xfree etc. (diff) | |
download | gnupg-986a137c58cae8dc7210ccf51cdea38ec6e8828f.tar.gz gnupg-986a137c58cae8dc7210ccf51cdea38ec6e8828f.zip |
Implemented PKA trust model
Diffstat (limited to '')
-rw-r--r-- | g10/mainproc.c | 115 |
1 files changed, 112 insertions, 3 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c index 5913f9304..afd347cfc 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1296,6 +1296,86 @@ do_proc_packets( CTX c, IOBUF a ) } +/* Helper for pka_uri_from_sig to parse the to-be-verified address out + of the notation data. */ +static pka_info_t * +get_pka_address (PKT_signature *sig) +{ + const unsigned char *p; + size_t len, n1, n2; + int seq = 0; + pka_info_t *pka = NULL; + + while ((p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_NOTATION, + &len, &seq, NULL))) + { + if (len < 8) + continue; /* Notation packet is too short. */ + n1 = (p[4]<<8)|p[5]; + n2 = (p[6]<<8)|p[7]; + if (8 + n1 + n2 != len) + continue; /* Length fields of notation packet are inconsistent. */ + p += 8; + if (n1 != 21 || memcmp (p, "[email protected]", 21)) + continue; /* Not the notation we want. */ + p += n1; + if (n2 < 3) + continue; /* Impossible email address. */ + + if (pka) + break; /* For now we only use the first valid PKA notation. In + future we might want to keep additional PKA + notations in a linked list. */ + + pka = xmalloc (sizeof *pka + n2); + pka->valid = 0; + pka->checked = 0; + pka->uri = NULL; + memcpy (pka->email, p, n2); + pka->email[n2] = 0; + + if (has_invalid_email_chars (pka->email)) + { + /* We don't accept invalid mail addresses. */ + xfree (pka); + pka = NULL; + } + } + + return pka; +} + + +/* Return the URI from a DNS PKA record. If this record has already + be retrieved for the signature we merely return it; if not we go + out and try to get that DNS record. */ +static const char * +pka_uri_from_sig (PKT_signature *sig) +{ + if (!sig->flags.pka_tried) + { + assert (!sig->pka_info); + sig->flags.pka_tried = 1; + sig->pka_info = get_pka_address (sig); + if (sig->pka_info) + { + char *uri; + + uri = get_pka_info (sig->pka_info->email, sig->pka_info->fpr); + if (uri) + { + sig->pka_info->valid = 1; + if (!*uri) + xfree (uri); + else + sig->pka_info->uri = uri; + } + } + } + return sig->pka_info? sig->pka_info->uri : NULL; +} + + static int check_sig_and_print( CTX c, KBNODE node ) { @@ -1419,8 +1499,34 @@ check_sig_and_print( CTX c, KBNODE node ) } } - /* If the preferred keyserver thing above didn't work, this is a - second try. */ + + /* If the preferred keyserver thing above didn't work, our second + try is to use the URI from a DNS PKA record. */ + if ( rc == G10ERR_NO_PUBKEY ) + { + const char *uri = pka_uri_from_sig (sig); + + if (uri) + { + int res; + struct keyserver_spec *spec; + + spec = parse_keyserver_uri (uri, 0, NULL, 0); + if (spec) + { + glo_ctrl.in_auto_key_retrieve++; + res = keyserver_import_keyid (sig->keyid, spec); + glo_ctrl.in_auto_key_retrieve--; + free_keyserver_spec (spec); + if (!res) + rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); + } + } + } + + + /* If the preferred keyserver thing above didn't work and we got + no information from the DNS PKA, this is a third try. */ if( rc == G10ERR_NO_PUBKEY && opt.keyserver && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)) @@ -1673,8 +1779,11 @@ check_sig_and_print( CTX c, KBNODE node ) free_public_key( vpk ); } - if( !rc ) + if (!rc) + { + pka_uri_from_sig (sig); /* Make sure PKA info is available. */ rc = check_signatures_trust( sig ); + } if(sig->flags.expired) { |