1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-08 23:37:47 +02:00

Implemented PKA trust model

This commit is contained in:
Werner Koch 2005-07-28 18:59:36 +00:00
parent a1cdf3c75f
commit 986a137c58
19 changed files with 576 additions and 62 deletions

View File

@ -1,3 +1,7 @@
2005-07-28 Werner Koch <wk@g10code.com>
* configure.ac (USE_DNS_PKA): Define in addition to USE_DNS_SRV.
2005-07-27 Werner Koch <wk@g10code.com>
Replaced in all directories all calls to m_free, m_alloc,

6
NEWS
View File

@ -10,6 +10,12 @@ Noteworthy changes in version 1.4.3
--enable-old-keyserver-helpers. Note that none of this affects
finger or LDAP support, which are unchanged.
* Implemented Public Key Association (PKA) trust model option.
This is an optional trust model on top of the standard ones. It
make use of of special DNS records and notation data to
associate a mail address with an OpenPGP key. See: XXXX for a
description.
Noteworthy changes in version 1.4.2 (2005-07-26)
------------------------------------------------

View File

@ -563,7 +563,8 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname,
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
[NETLIBS="-lsocket $NETLIBS"]))
dnl Now try for the resolver functions so we can use DNS SRV
dnl Now try for the resolver functions so we can use DNS SRV and our
dnl PKA feature.
AC_ARG_ENABLE(dns-srv,
AC_HELP_STRING([--disable-dns-srv],
@ -597,6 +598,7 @@ if (test x"$try_hkp" = xyes || test x"$try_http" = xyes) && test x"$use_dns_srv"
if test x"$use_dns_srv" = xyes ; then
AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV])
SRVLIBS=$LIBS
AC_DEFINE(USE_DNS_PKA,1,[define to use our experimental DNS PKA])
fi
LIBS=$_srv_save_libs

View File

@ -1,3 +1,23 @@
2005-07-28 Werner Koch <wk@g10code.com>
* Makefile.am (other_libs): Add SRVLIBS.
* parse-packet.c (can_handle_critical_notation): We know about
pka-address@gnupg.org.
* packet.h (PKT_signature): New fields PKA_INFO and PKA_TRIED.
(pka_info_t): New.
* free-packet.c (cp_pka_info): New.
(free_seckey_enc, copy_signature): Support new fields.
* mainproc.c (get_pka_address, pka_uri_from_sig): New.
(check_sig_and_print): Try to get the keyserver from the PKA
record.
* pkclist.c (check_signatures_trust): Adjust the trust based on
the PKA.
* gpgv.c (parse_keyserver_uri): New stub.
* keygen.c (has_invalid_email_chars): Moved to ..
* misc.c (has_invalid_email_chars): .. here and made global.
2005-07-27 Werner Koch <wk@g10code.com>
* export.c (do_export_stream): Make two strings translatable.

View File

@ -28,7 +28,7 @@ if ! HAVE_DOSISH_SYSTEM
AM_CFLAGS = -DGNUPG_LIBEXECDIR="\"$(libexecdir)/@PACKAGE@\""
endif
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS)
other_libs = $(LIBICONV) $(SRVLIBS) $(LIBINTL) $(CAPLIBS)
bin_PROGRAMS = gpg gpgv

View File

@ -1,6 +1,6 @@
/* free-packet.c - cleanup stuff for packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
* Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
* 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -62,10 +62,17 @@ free_seckey_enc( PKT_signature *sig )
mpi_free(sig->data[0]);
for(i=0; i < n; i++ )
mpi_free( sig->data[i] );
xfree(sig->revkey);
xfree(sig->hashed);
xfree(sig->unhashed);
if (sig->pka_info)
{
xfree (sig->pka_info->uri);
xfree (sig->pka_info);
}
xfree(sig);
}
@ -195,6 +202,21 @@ copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
sk->keyid[1] = pk->keyid[1];
}
static pka_info_t *
cp_pka_info (const pka_info_t *s)
{
pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
d->valid = s->valid;
d->checked = s->checked;
d->uri = s->uri? xstrdup (s->uri):NULL;
memcpy (d->fpr, s->fpr, sizeof s->fpr);
strcpy (d->email, s->email);
return d;
}
PKT_signature *
copy_signature( PKT_signature *d, PKT_signature *s )
{
@ -210,6 +232,7 @@ copy_signature( PKT_signature *d, PKT_signature *s )
for(i=0; i < n; i++ )
d->data[i] = mpi_copy( s->data[i] );
}
d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
d->hashed = cp_subpktarea (s->hashed);
d->unhashed = cp_subpktarea (s->unhashed);
if(s->numrevkeys)

View File

@ -333,6 +333,13 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
}
struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig) {return NULL;}
struct keyserver_spec *parse_keyserver_uri(const char *uri,int require_scheme,
const char *configname,
unsigned int configlineno)
{
return NULL;
}
void free_keyserver_spec(struct keyserver_spec *keyserver) {}
/* Stubs to avoid linking to photoid.c */

View File

@ -1609,27 +1609,6 @@ ask_expiredate()
return x? make_timestamp() + x : 0;
}
static int
has_invalid_email_chars( const char *s )
{
int at_seen=0;
static char valid_chars[] = "01234567890_-."
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for( ; *s; s++ ) {
if( *s & 0x80 )
return 1;
if( *s == '@' )
at_seen=1;
else if( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
return 1;
else if( at_seen && !strchr( valid_chars, *s ) )
return 1;
}
return 0;
}
static char *
ask_user_id( int mode )

View File

@ -125,6 +125,7 @@ char *argsplit(char *string);
int parse_options(char *str,unsigned int *options,
struct parse_options *opts,int noisy);
char *unescape_percent_string (const unsigned char *s);
int has_invalid_email_chars (const char *s);
char *default_homedir (void);
const char *get_libexecdir (void);

View File

@ -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, "pka-address@gnupg.org", 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)
{

View File

@ -1065,6 +1065,31 @@ unescape_percent_string (const unsigned char *s)
int
has_invalid_email_chars (const char *s)
{
int at_seen=0;
static char valid_chars[] = ("01234567890_-."
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
for ( ; *s; s++ )
{
if ( *s & 0x80 )
return 1;
if ( *s == '@' )
at_seen=1;
else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
return 1;
else if ( at_seen && !strchr( valid_chars, *s ) )
return 1;
}
return 0;
}
/* This is a helper function to load a Windows function from either of
one DLLs. */
#ifdef HAVE_W32_SYSTEM

View File

@ -122,36 +122,56 @@ struct revocation_key {
byte fpr[MAX_FINGERPRINT_LEN];
};
typedef struct {
struct {
unsigned checked:1; /* signature has been checked */
unsigned valid:1; /* signature is good (if checked is set) */
unsigned chosen_selfsig:1; /* a selfsig that is the chosen one */
unsigned unknown_critical:1;
unsigned exportable:1;
unsigned revocable:1;
unsigned policy_url:1; /* At least one policy URL is present */
unsigned notation:1; /* At least one notation is present */
unsigned pref_ks:1; /* At least one preferred keyserver is present */
unsigned expired:1;
} flags;
u32 keyid[2]; /* 64 bit keyid */
u32 timestamp; /* signature made */
u32 expiredate; /* expires at this date or 0 if not at all */
byte version;
byte sig_class; /* sig classification, append for MD calculation*/
byte pubkey_algo; /* algorithm used for public key scheme */
/* (PUBKEY_ALGO_xxx) */
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
byte trust_depth;
byte trust_value;
const byte *trust_regexp;
struct revocation_key **revkey;
int numrevkeys;
subpktarea_t *hashed; /* all subpackets with hashed data (v4 only) */
subpktarea_t *unhashed; /* ditto for unhashed data */
byte digest_start[2]; /* first 2 bytes of the digest */
MPI data[PUBKEY_MAX_NSIG];
/* Object to keep information about a PKA DNS record. */
typedef struct
{
int valid; /* An actual PKA record exists for EMAIL. */
int checked; /* Set to true if the FPR has been checked against the
actual key. */
char *uri; /* Malloced string with the URI. NULL if the URI is
not available.*/
unsigned char fpr[20]; /* The fingerprint as stored in the PKA RR. */
char email[1];/* The email address from the notation data. */
} pka_info_t;
/* Object to keep information pertaining to a signature. */
typedef struct
{
struct
{
unsigned checked:1; /* Signature has been checked. */
unsigned valid:1; /* Signature is good (if checked is set). */
unsigned chosen_selfsig:1; /* A selfsig that is the chosen one. */
unsigned unknown_critical:1;
unsigned exportable:1;
unsigned revocable:1;
unsigned policy_url:1; /* At least one policy URL is present */
unsigned notation:1; /* At least one notation is present */
unsigned pref_ks:1; /* At least one preferred keyserver is present */
unsigned expired:1;
unsigned pka_tried:1; /* Set if we tried to retrieve the PKA record. */
} flags;
u32 keyid[2]; /* 64 bit keyid */
u32 timestamp; /* Signature made (seconds since Epoch). */
u32 expiredate; /* Expires at this date or 0 if not at all. */
byte version;
byte sig_class; /* Sig classification, append for MD calculation. */
byte pubkey_algo; /* Algorithm used for public key scheme */
/* (PUBKEY_ALGO_xxx) */
byte digest_algo; /* Algorithm used for digest (DIGEST_ALGO_xxxx). */
byte trust_depth;
byte trust_value;
const byte *trust_regexp;
struct revocation_key **revkey;
int numrevkeys;
pka_info_t *pka_info; /* Malloced PKA data or NULL if not
available. See also flags.pka_tried. */
subpktarea_t *hashed; /* All subpackets with hashed data (v4 only). */
subpktarea_t *unhashed; /* Ditto for unhashed data. */
byte digest_start[2]; /* First 2 bytes of the digest. */
MPI data[PUBKEY_MAX_NSIG];
} PKT_signature;
#define ATTRIB_IMAGE 1

View File

@ -1042,6 +1042,8 @@ can_handle_critical_notation(const byte *name,size_t len)
{
if(len==32 && memcmp(name,"preferred-email-encoding@pgp.com",32)==0)
return 1;
if(len==21 && memcmp(name,"pka-address@gnupg.org",21)==0)
return 1;
return 0;
}

View File

@ -532,6 +532,48 @@ check_signatures_trust( PKT_signature *sig )
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;
log_info (_("Note: Verified address is `%s'\n"), sig->pka_info->email);
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;
else
okay = 0;
switch ( (trustlevel & TRUST_MASK) )
{
case TRUST_UNKNOWN:
case TRUST_UNDEFINED:
case TRUST_MARGINAL:
if (okay)
{
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:

View File

@ -253,6 +253,10 @@ int vasprintf (char **result, const char *format, va_list args);
int asprintf (char **buf, const char *fmt, ...);
#endif /*_WIN32*/
/*-- pka.c --*/
char *get_pka_info (const char *address, unsigned char *fpr);
/**** other missing stuff ****/
#ifndef HAVE_ATEXIT /* For SunOS */

View File

@ -1,3 +1,8 @@
2005-07-28 Werner Koch <wk@g10code.com>
* pka.c: New.
* Makefile.am (pka-test): new.
2005-07-27 Werner Koch <wk@g10code.com>
* memory.c (FNAMEX, FNAMEXM): New macros to cope with the now used

View File

@ -38,7 +38,7 @@ endif
#libutil_a_LDFLAGS =
libutil_a_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c \
dotlock.c http.c srv.h srv.c simple-gettext.c \
dotlock.c http.c srv.h srv.c pka.c simple-gettext.c \
membuf.c w32reg.c $(assuan_source)
libutil_a_DEPENDENCIES = @LIBOBJS@ @REGEX_O@
@ -46,9 +46,14 @@ libutil_a_DEPENDENCIES = @LIBOBJS@ @REGEX_O@
libutil_a_LIBADD = @LIBOBJS@ @REGEX_O@
http-test: http.c
gcc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \
cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \
-DTEST -o http-test http.c libutil.a @LIBINTL@ @SRVLIBS@ @CAPLIBS@
srv-test: srv.c
gcc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \
cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \
-DTEST -o srv-test srv.c libutil.a @LIBINTL@ @SRVLIBS@ @CAPLIBS@
pka-test: pka.c
cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \
-DTEST -o pka-test pka.c libutil.a @LIBINTL@ @SRVLIBS@ @CAPLIBS@

254
util/pka.c Normal file
View File

@ -0,0 +1,254 @@
/* pka.c - DNS Public Key Association RR access
* Copyright (C) 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef USE_DNS_PKA
#include <sys/types.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#endif
#endif /* USE_DNS_PKA */
#include "memory.h"
#include "types.h"
#include "util.h"
#ifdef USE_DNS_PKA
/* Parse the TXT resource record. Format is:
v=1;fpr=a4d94e92b0986ab5ee9dcd755de249965b0358a2;uri=string
For simplicity white spaces are not allowed. Because we expect to
use a new RRTYPE for this in the future we define the TXT really
strict for simplicity: No white spaces, case sensitivity of the
names, order must be as given above. Only URI is optional.
This function modifies BUFFER. On success 0 is returned, the 20
byte fingerprint stored at FPR and BUFFER contains the URI or an
empty string.
*/
static int
parse_txt_record (char *buffer, unsigned char *fpr)
{
char *p, *pend;
int i;
p = buffer;
pend = strchr (p, ';');
if (!pend)
return -1;
*pend++ = 0;
if (strcmp (p, "v=1"))
return -1; /* Wrong or missing version. */
p = pend;
pend = strchr (p, ';');
if (pend)
*pend++ = 0;
if (strncmp (p, "fpr=", 4))
return -1; /* Missing fingerprint part. */
p += 4;
for (i=0; i < 20 && hexdigitp (p) && hexdigitp (p+1); i++, p += 2)
fpr[i] = xtoi_2 (p);
if (i != 20)
return -1; /* Fingerprint consists not of exactly 40 hexbytes. */
p = pend;
if (!p || !*p)
{
*buffer = 0;
return 0; /* Success (no URI given). */
}
if (strncmp (p, "uri=", 4))
return -1; /* Unknown part. */
p += 4;
/* There is an URI, copy it to the start of the buffer. */
while (*p)
*buffer++ = *p++;
*buffer = 0;
return 0;
}
/* For the given email ADDRESS lookup the PKA information in the DNS.
On success the 20 byte SHA-1 fingerprint is stored at FPR and the
URI will be returned in an allocated buffer. Note that the URI
might be an zero length string as this information is optiobnal.
Caller must xfree the returned string.
On error NULL is returned and the 20 bytes at FPR are not
defined. */
char *
get_pka_info (const char *address, unsigned char *fpr)
{
unsigned char answer[PACKETSZ];
int anslen;
int qdcount, ancount, nscount, arcount;
int rc;
unsigned char *p, *pend;
const char *domain;
char *name;
domain = strrchr (address, '@');
if (!domain || domain == address || !domain[1])
return NULL; /* invalid mail address given. */
name = malloc (strlen (address) + 5 + 1);
memcpy (name, address, domain - address);
strcpy (stpcpy (name + (domain-address), "._pka."), domain+1);
anslen = res_query (name, C_IN, T_TXT, answer, PACKETSZ);
xfree (name);
if (anslen < sizeof(HEADER))
return NULL; /* DNS resolver returned a too short answer. */
if ( (rc=((HEADER*)answer)->rcode) != NOERROR )
return NULL; /* DNS resolver returned an error. */
/* We assume that PACKETSZ is large enough and don't do dynmically
expansion of the buffer. */
if (anslen > PACKETSZ)
return NULL; /* DNS resolver returned a too long answer */
qdcount = ntohs (((HEADER*)answer)->qdcount);
ancount = ntohs (((HEADER*)answer)->ancount);
nscount = ntohs (((HEADER*)answer)->nscount);
arcount = ntohs (((HEADER*)answer)->arcount);
if (!ancount)
return NULL; /* Got no answer. */
p = answer + sizeof (HEADER);
pend = answer + anslen; /* Actually points directly behind the buffer. */
while (qdcount-- && p < pend)
{
rc = dn_skipname (p, pend);
if (rc == -1)
return NULL;
p += rc + QFIXEDSZ;
}
if (ancount > 1)
return NULL; /* more than one possible gpg trustdns record - none used. */
while (ancount-- && p <= pend)
{
unsigned int type, class, txtlen, n;
char *buffer, *bufp;
rc = dn_skipname (p, pend);
if (rc == -1)
return NULL;
p += rc;
if (p >= pend - 10)
return NULL; /* RR too short. */
type = *p++ << 8;
type |= *p++;
class = *p++ << 8;
class |= *p++;
p += 4;
txtlen = *p++ << 8;
txtlen |= *p++;
if (type != T_TXT || class != C_IN)
return NULL; /* Answer does not match the query. */
buffer = bufp = xmalloc (txtlen + 1);
while (txtlen && p < pend)
{
for (n = *p++, txtlen--; txtlen && n && p < pend; txtlen--, n--)
*bufp++ = *p++;
}
*bufp = 0;
if (parse_txt_record (buffer, fpr))
{
xfree (buffer);
return NULL; /* Not a valid gpg trustdns RR. */
}
return buffer;
}
return NULL;
}
#else /* !USE_DNS_PKA */
/* Dummy version of the function if we can't use the resolver
functions. */
char *
get_pka_info (const char *address, unsigned char *fpr)
{
return NULL;
}
#endif /* !USE_DNS_PKA */
#ifdef TEST
int
main(int argc,char *argv[])
{
unsigned char fpr[20];
char *uri;
int i;
if (argc < 2)
{
fprintf (stderr, "usage: pka mail-addresses\n");
return 1;
}
argc--;
argv++;
for (; argc; argc--, argv++)
{
uri = get_pka_info ( *argv, fpr );
printf ("%s", *argv);
if (uri)
{
putchar (' ');
for (i=0; i < 20; i++)
printf ("%02X", fpr[i]);
if (*uri)
printf (" %s", uri);
xfree (uri);
}
putchar ('\n');
}
return 0;
}
#endif /* TEST */
/*
Local Variables:
compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv libutil.a"
End:
*/

View File

@ -251,3 +251,9 @@ main(int argc,char *argv[])
return 0;
}
#endif /* TEST */
/*
Local Variables:
compile-command: "cc -DTEST -I.. -I../include -Wall -g -o srv srv.c -lresolv libutil.a"
End:
*/