diff options
author | Werner Koch <wk@gnupg.org> | 2006-06-16 13:49:27 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2006-06-16 13:49:27 +0200 |
commit | ff523906988b9eb4eea3ab3857afe29552c53716 (patch) | |
tree | 8a28b2d9d3a2e460b1b754812aad556f332a2bb3 | |
parent | 2006-06-09 Marcus Brinkmann <marcus@g10code.de> (diff) | |
download | gnupg2-ff523906988b9eb4eea3ab3857afe29552c53716.tar.xz gnupg2-ff523906988b9eb4eea3ab3857afe29552c53716.zip |
Added missing files
-rw-r--r-- | common/dns-cert.c | 246 | ||||
-rw-r--r-- | common/dns-cert.h | 28 |
2 files changed, 274 insertions, 0 deletions
diff --git a/common/dns-cert.c b/common/dns-cert.c new file mode 100644 index 000000000..8dfcb9724 --- /dev/null +++ b/common/dns-cert.c @@ -0,0 +1,246 @@ +/* dns-cert.c - DNS CERT code + * Copyright (C) 2005, 2006 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 HAVE_W32_SYSTEM +# include <windows.h> +# else +# include <netinet/in.h> +# include <arpa/nameser.h> +# include <resolv.h> +# endif +#include <string.h> +#endif + +#include "util.h" +#include "iobuf.h" +#include "dns-cert.h" + +/* Not every installation has gotten around to supporting CERTs + yet... */ +#ifndef T_CERT +#define T_CERT 37 +#endif + + +/* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for + IPGP provided. */ +int +get_dns_cert (const char *name,size_t max_size,IOBUF *iobuf, + unsigned char **fpr,size_t *fpr_len,char **url) +{ +#ifdef USE_DNS_CERT + unsigned char *answer; + int r,ret=-1; + u16 count; + + if(fpr) + *fpr=NULL; + + if(url) + *url=NULL; + + 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? 15 bytes takes us to the point where + we start looking at the ctype. */ + if((emsg-pt)<15) + break; + + type=*pt++ << 8; + type|=*pt++; + + 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++; + + /* We asked for CERT and got something else - might be a + CNAME, so loop around again. */ + if(type!=T_CERT) + { + pt+=dlen; + continue; + } + + /* The CERT type */ + ctype=*pt++ << 8; + ctype|=*pt++; + + /* Skip the CERT key tag and algo which we don't need. */ + pt+=3; + + dlen-=5; + + /* 15 bytes takes us to here */ + + if(ctype==3 && iobuf && dlen) + { + /* PGP type */ + *iobuf=iobuf_temp_with_content((char *)pt,dlen); + ret=1; + break; + } + else if(ctype==6 && dlen && dlen<1023 && dlen>=pt[0]+1 + && fpr && fpr_len && url) + { + /* IPGP type */ + *fpr_len=pt[0]; + + if(*fpr_len) + { + *fpr=xmalloc(*fpr_len); + memcpy(*fpr,&pt[1],*fpr_len); + } + else + *fpr=NULL; + + if(dlen>*fpr_len+1) + { + *url=xmalloc(dlen-(*fpr_len+1)+1); + memcpy(*url,&pt[*fpr_len+1],dlen-(*fpr_len+1)); + (*url)[dlen-(*fpr_len+1)]='\0'; + } + else + *url=NULL; + + ret=2; + break; + } + + /* Neither type matches, so go around to the next answer. */ + pt+=dlen; + } + } + + fail: + xfree(answer); + + return ret; +#else /* !USE_DNS_CERT */ + return -1; +#endif +} + + + +/* Test with simon.josefsson.org */ + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + unsigned char *fpr; + size_t fpr_len; + 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_dns_cert (argv[1],16384,&iobuf,&fpr,&fpr_len,&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",(int)iobuf_get_temp_length(iobuf)); + iobuf_close(iobuf); + } + else if(rc==2) + { + if(fpr) + { + size_t i; + printf("Fingerprint found (%d bytes): ",(int)fpr_len); + for(i=0;i<fpr_len;i++) + printf("%02X",fpr[i]); + printf("\n"); + } + else + printf("No fingerprint found\n"); + + if(url) + printf("URL found: %s\n",url); + else + printf("No URL found\n"); + + xfree(fpr); + xfree(url); + } + + return 0; +} +#endif /* TEST */ diff --git a/common/dns-cert.h b/common/dns-cert.h new file mode 100644 index 000000000..47e0d5a2d --- /dev/null +++ b/common/dns-cert.h @@ -0,0 +1,28 @@ +/* dns-cert.h - DNS CERT definition + * Copyright (C) 2006 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. + */ +#ifndef GNUPG_COMMON_DNS_CERT_H +#define GNUPG_COMMON_DNS_CERT_H + +int get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, + unsigned char **fpr, size_t *fpr_len, char **url); + + +#endif /*GNUPG_COMMON_DNS_CERT_H*/ |