diff options
author | David Shaw <[email protected]> | 2005-12-23 18:15:24 +0000 |
---|---|---|
committer | David Shaw <[email protected]> | 2005-12-23 18:15:24 +0000 |
commit | 7f13d486b00da75254e46b728dc7434fecc23fd9 (patch) | |
tree | a45c0b42f8901074e0d2c01d6eadd5ccb0493d82 | |
parent | * srv.c, Makefile.am: Only build srv.c if we need to. (diff) | |
download | gnupg-7f13d486b00da75254e46b728dc7434fecc23fd9.tar.gz gnupg-7f13d486b00da75254e46b728dc7434fecc23fd9.zip |
New code to do DNS CERT queries.
Diffstat (limited to '')
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | include/ChangeLog | 4 | ||||
-rw-r--r-- | include/util.h | 3 | ||||
-rw-r--r-- | util/ChangeLog | 4 | ||||
-rw-r--r-- | util/Makefile.am | 6 | ||||
-rw-r--r-- | util/cert.c | 200 |
7 files changed, 232 insertions, 5 deletions
@@ -1,3 +1,7 @@ +2005-12-23 David Shaw <[email protected]> + + * configure.ac: Add switch for DNS CERT. + 2005-12-22 David Shaw <[email protected]> * configure.ac: Split PKA checking off from DNS SRV checking. diff --git a/configure.ac b/configure.ac index f88a986c6..ea6428721 100644 --- a/configure.ac +++ b/configure.ac @@ -555,8 +555,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 and our -dnl PKA feature. +dnl Now try for the resolver functions so we can use DNS for SRV, PKA, +dnl and CERT. if test x"$try_hkp" = xyes || test x"$try_http" = xyes ; then AC_ARG_ENABLE(dns-srv, @@ -570,7 +570,12 @@ AC_ARG_ENABLE(dns-pka, [disable the use of PKA records in DNS]), use_dns_pka=$enableval,use_dns_pka=yes) -if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes ; then +AC_ARG_ENABLE(dns-cert, + AC_HELP_STRING([--disable-dns-cert], + [disable the use of CERT records in DNS]), + use_dns_cert=$enableval,use_dns_cert=yes) + +if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then _srv_save_libs=$LIBS LIBS="" # the double underscore thing is a glibc-ism? @@ -601,9 +606,14 @@ if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes ; then if test x"$use_dns_pka" = xyes ; then AC_DEFINE(USE_DNS_PKA,1,[define to use our experimental DNS PKA]) fi + + if test x"$use_dns_cert" = xyes ; then + AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT]) + fi else use_dns_srv=no use_dns_pka=no + use_dns_cert=no fi LIBS=$_srv_save_libs diff --git a/include/ChangeLog b/include/ChangeLog index 0f748a992..c7442a681 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2005-12-23 David Shaw <[email protected]> + + * util.h: Prototype get_cert(). + 2005-07-27 Werner Koch <[email protected]> * memory.h (m_free, m_alloc, m_realloc, m_strdup): Removed and diff --git a/include/util.h b/include/util.h index 77b2b66f2..eba1c84f0 100644 --- a/include/util.h +++ b/include/util.h @@ -256,7 +256,8 @@ int asprintf (char **buf, const char *fmt, ...); /*-- pka.c --*/ char *get_pka_info (const char *address, unsigned char *fpr); - +/*-- cert.c --*/ +int get_cert(const char *name,size_t max_size,IOBUF *iobuf,char **url); /**** other missing stuff ****/ #ifndef HAVE_ATEXIT /* For SunOS */ diff --git a/util/ChangeLog b/util/ChangeLog index 16c2338ce..c8e151b3a 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,7 @@ +2005-12-23 David Shaw <[email protected]> + + * cert.c, Makefile.am: New code to do DNS CERT queries. + 2005-12-22 David Shaw <[email protected]> * srv.c, Makefile.am: Only build srv.c if we need to. diff --git a/util/Makefile.am b/util/Makefile.am index 15b3617bc..2a3f07c9e 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -24,7 +24,7 @@ noinst_LIBRARIES = libutil.a 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 pka.c membuf.c + dotlock.c http.c pka.c membuf.c cert.c if USE_SIMPLE_GETTEXT libutil_a_SOURCES+=simple-gettext.c @@ -67,3 +67,7 @@ srv-test: srv.c 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@ + +cert-test: cert.c + cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ + -DTEST -o cert-test cert.c libutil.a @LIBINTL@ @SRVLIBS@ @CAPLIBS@ diff --git a/util/cert.c b/util/cert.c new file mode 100644 index 000000000..94e6bed64 --- /dev/null +++ b/util/cert.c @@ -0,0 +1,200 @@ +/* cert.c - DNS CERT code + * 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 <sys/types.h> +#ifdef USE_DNS_CERT +#ifdef _WIN32 +#include <windows.h> +#else +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#endif +#include <string.h> +#include "memory.h" +#endif +#include "iobuf.h" + +/* Not every installation has gotten around to supporting CERTs + yet... */ +#ifndef T_CERT +#define T_CERT 37 +#endif + +#ifdef USE_DNS_CERT + +/* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for + IPGP provided. */ +int +get_cert(const char *name,size_t max_size,IOBUF *iobuf,char **url) +{ + unsigned char *answer; + int r,ret=-1; + u16 count; + + answer=xmalloc(max_size); + + r=res_query(name,C_IN,T_CERT,answer,max_size); + /* Not too big, not too small, no errors and at least 1 answer. */ + if(r>=sizeof(HEADER) && r<=max_size + && (((HEADER *)answer)->rcode)==NOERROR + && (count=ntohs(((HEADER *)answer)->ancount))) + { + int rc; + unsigned char *pt,*emsg; + + emsg=&answer[r]; + + pt=&answer[sizeof(HEADER)]; + + /* Skip over the query */ + + rc=dn_skipname(pt,emsg); + if(rc==-1) + goto fail; + + pt+=rc+QFIXEDSZ; + + /* There are several possible response types for a CERT request. + We're interested in the PGP (a key) and IPGP (a URI) types. + Skip all others. TODO: A key is better than a URI since + we've gone through all this bother to fetch it, so favor that + if we have both PGP and IPGP? */ + + while(count-->0 && pt<emsg) + { + u16 type,class,dlen,ctype; + + rc=dn_skipname(pt,emsg); /* the name we just queried for */ + if(rc==-1) + break; + + pt+=rc; + + /* Truncated message? */ + if((emsg-pt)<15) + break; + + type=*pt++ << 8; + type|=*pt++; + /* We asked for CERT and got something else !? */ + if(type!=T_CERT) + break; + + class=*pt++ << 8; + class|=*pt++; + /* We asked for IN and got something else !? */ + if(class!=C_IN) + break; + + /* ttl */ + pt+=4; + + /* data length */ + dlen=*pt++ << 8; + dlen|=*pt++; + + /* The CERT type */ + ctype=*pt++ << 8; + ctype|=*pt++; + + /* Skip the CERT key tag and algo which we don't need. */ + pt+=3; + + dlen-=5; + + if(ctype==3 && iobuf) + { + /* PGP type */ + *iobuf=iobuf_temp_with_content(pt,dlen); + ret=1; + break; + } + else if(ctype==6 && dlen<1023 && url) + { + /* Sanity check the IPGP URL type that the URL isn't too + long */ + + *url=xmalloc(dlen+1); + memcpy(*url,pt,dlen); + ret=2; + break; + } + + /* Neither type matches, so go around to the next answer. */ + pt+=dlen; + } + } + + fail: + xfree(answer); + + return ret; +} + +#else /* !USE_DNS_CERT */ + +int +get_cert(const char *name,size_t max_size,IOBUF *iobuf,char **url) +{ + return -1; +} + +#endif + +/* Test with simon.josefsson.org */ + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + char *url; + int rc; + IOBUF iobuf; + + if(argc!=2) + { + printf("cert-test [name]\n"); + return 1; + } + + printf("CERT lookup on %s\n",argv[1]); + + rc=get_cert(argv[1],16384,&iobuf,&url); + if(rc==-1) + printf("error\n"); + else if(rc==0) + printf("no answer\n"); + else if(rc==1) + { + printf("key found: %d bytes\n",iobuf_get_temp_length(iobuf)); + iobuf_close(iobuf); + } + else if(rc==2) + { + printf("URL found: %s\n",url); + xfree(url); + } + + return 0; +} +#endif /* TEST */ |