diff --git a/tools/ChangeLog b/tools/ChangeLog index 5cfb4440a..090f2ec27 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2006-04-04 David Shaw <dshaw@jabberwocky.com> + + * make-dns-cert.c: New program to generate properly formatted CERT + records so people don't have to do it manually. + 2006-02-14 Werner Koch <wk@gnupg.org> * mk-tdata.c (main): Implement option --char. diff --git a/tools/Makefile.am b/tools/Makefile.am index f244a7484..5efe2c1a6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -25,7 +25,7 @@ needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a other_libs = $(LIBICONV) $(LIBINTL) $(CAPLIBS) bin_PROGRAMS = gpgsplit -noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest +noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest make-dns-cert if HAVE_USTAR bin_SCRIPTS = gpg-zip diff --git a/tools/make-dns-cert.c b/tools/make-dns-cert.c new file mode 100644 index 000000000..6cf92645d --- /dev/null +++ b/tools/make-dns-cert.c @@ -0,0 +1,214 @@ +/* make-dns-cert.c - An OpenPGP-to-DNS CERT conversion tool + * 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. + */ + +#include <config.h> +#include <unistd.h> +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +/* We use TYPE37 instead of CERT since not all nameservers can handle + CERT yet... */ + +static int +cert_key(const char *name,const char *keyfile) +{ + int fd,ret=1,err,i; + struct stat statbuf; + + fd=open(keyfile,O_RDONLY); + if(fd==-1) + { + printf("Cannot open key file %s: %s\n",keyfile,strerror(errno)); + return 1; + } + + err=fstat(fd,&statbuf); + if(err==-1) + { + printf("Unable to stat key file %s: %s\n",keyfile,strerror(errno)); + goto fail; + } + + if(statbuf.st_size>32768) + { + printf("Key %s too large for CERT encoding\n",keyfile); + goto fail; + } + + printf("%s\tTYPE37\t\\# %u 0003 0000 00 ", + name,(unsigned int)statbuf.st_size+5); + + err=1; + while(err!=0) + { + unsigned char buffer[1024]; + + err=read(fd,buffer,1024); + if(err==-1) + { + printf("Unable to read key file %s: %s\n",keyfile,strerror(errno)); + goto fail; + } + + for(i=0;i<err;i++) + printf("%02X",buffer[i]); + } + + printf("\n"); + + ret=0; + + fail: + close(fd); + + return ret; +} + +static int +url_key(const char *name,const char *fpr,const char *url) +{ + int len=6,fprlen=0; + + if(fpr) + { + fprlen=strlen(fpr); + if(fprlen%2) + { + printf("Fingerprint must be an even number of characters\n"); + return 1; + } + + fprlen/=2; + len+=fprlen; + } + + if(url) + len+=strlen(url); + + if(!fpr && !url) + { + printf("Cannot generate a CERT without either a fingerprint or URL\n"); + return 1; + } + + printf("%s\tTYPE37\t\\# %d 0006 0000 00 %02X",name,len,fprlen); + + if(fpr) + printf(" %s",fpr); + + if(url) + { + const char *c; + printf(" "); + for(c=url;*c;c++) + printf("%02X",*c); + } + + printf("\n"); + + return 0; +} + +static void +usage(void) +{ + printf("make-dns-cert\n"); + printf("\t-f\tfingerprint\n"); + printf("\t-u\tURL\n"); + printf("\t-k\tkey file\n"); + printf("\t-n\tDNS name\n"); +} + +int +main(int argc,char *argv[]) +{ + int arg,err=1; + char *fpr=NULL,*url=NULL,*keyfile=NULL,*name=NULL; + + if(argc==1) + { + usage(); + return 0; + } + else if(argc>1 && strcmp(argv[1],"--version")==0) + { + printf("make-dns-cert (GnuPG) " VERSION "\n"); + return 0; + } + else if(argc>1 && strcmp(argv[1],"--help")==0) + { + usage(); + return 0; + } + + while((arg=getopt(argc,argv,"hf:u:k:n:"))!=-1) + switch(arg) + { + default: + case 'h': + usage(); + exit(0); + + case 'f': + fpr=optarg; + break; + + case 'u': + url=optarg; + break; + + case 'k': + keyfile=optarg; + break; + + case 'n': + name=optarg; + break; + } + + if(!name) + { + printf("No name provided\n"); + return 1; + } + + if(keyfile && (fpr || url)) + { + printf("Cannot generate a CERT record with both a keyfile and" + " a fingerprint or URL\n"); + return 1; + } + + if(keyfile) + err=cert_key(name,keyfile); + else + err=url_key(name,fpr,url); + + return err; +}