6cf92645d76a754a91c280f4856603695661b37c
[gnupg.git] / tools / make-dns-cert.c
1 /* make-dns-cert.c - An OpenPGP-to-DNS CERT conversion tool
2  * Copyright (C) 2006 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <unistd.h>
24 #ifdef HAVE_GETOPT_H
25 #include <getopt.h>
26 #endif
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34
35 /* We use TYPE37 instead of CERT since not all nameservers can handle
36    CERT yet... */
37
38 static int
39 cert_key(const char *name,const char *keyfile)
40 {
41   int fd,ret=1,err,i;
42   struct stat statbuf;
43
44   fd=open(keyfile,O_RDONLY);
45   if(fd==-1)
46     {
47       printf("Cannot open key file %s: %s\n",keyfile,strerror(errno));
48       return 1;
49     }
50
51   err=fstat(fd,&statbuf);
52   if(err==-1)
53     {
54       printf("Unable to stat key file %s: %s\n",keyfile,strerror(errno));
55       goto fail;
56     }
57
58   if(statbuf.st_size>32768)
59     {
60       printf("Key %s too large for CERT encoding\n",keyfile);
61       goto fail;
62     }
63
64   printf("%s\tTYPE37\t\\# %u 0003 0000 00 ",
65          name,(unsigned int)statbuf.st_size+5);
66
67   err=1;
68   while(err!=0)
69     {
70       unsigned char buffer[1024];
71
72       err=read(fd,buffer,1024);
73       if(err==-1)
74         {
75           printf("Unable to read key file %s: %s\n",keyfile,strerror(errno));
76           goto fail;
77         }
78
79       for(i=0;i<err;i++)
80         printf("%02X",buffer[i]);
81     }
82
83   printf("\n");
84
85   ret=0;
86
87  fail:
88   close(fd);
89
90   return ret;
91 }
92
93 static int
94 url_key(const char *name,const char *fpr,const char *url)
95 {
96   int len=6,fprlen=0;
97
98   if(fpr)
99     {
100       fprlen=strlen(fpr);
101       if(fprlen%2)
102         {
103           printf("Fingerprint must be an even number of characters\n");
104           return 1;
105         }
106
107       fprlen/=2;
108       len+=fprlen;
109     }
110
111   if(url)
112     len+=strlen(url);
113
114   if(!fpr && !url)
115     {
116       printf("Cannot generate a CERT without either a fingerprint or URL\n");
117       return 1;
118     }
119
120   printf("%s\tTYPE37\t\\# %d 0006 0000 00 %02X",name,len,fprlen);
121
122   if(fpr)
123     printf(" %s",fpr);
124
125   if(url)
126     {
127       const char *c;
128       printf(" ");
129       for(c=url;*c;c++)
130         printf("%02X",*c);
131     }
132
133   printf("\n");
134
135   return 0;
136 }
137
138 static void
139 usage(void)
140 {
141   printf("make-dns-cert\n");
142   printf("\t-f\tfingerprint\n");
143   printf("\t-u\tURL\n");
144   printf("\t-k\tkey file\n");
145   printf("\t-n\tDNS name\n");
146 }
147
148 int
149 main(int argc,char *argv[])
150 {
151   int arg,err=1;
152   char *fpr=NULL,*url=NULL,*keyfile=NULL,*name=NULL;
153
154   if(argc==1)
155     {
156       usage();
157       return 0;
158     }
159   else if(argc>1 && strcmp(argv[1],"--version")==0)
160     {
161       printf("make-dns-cert (GnuPG) " VERSION "\n");
162       return 0;
163     }
164   else if(argc>1 && strcmp(argv[1],"--help")==0)
165     {
166       usage();
167       return 0;
168     }
169
170   while((arg=getopt(argc,argv,"hf:u:k:n:"))!=-1)
171     switch(arg)
172       {
173       default:
174       case 'h':
175         usage();
176         exit(0);
177
178       case 'f':
179         fpr=optarg;
180         break;
181
182       case 'u':
183         url=optarg;
184         break;
185
186       case 'k':
187         keyfile=optarg;
188         break;
189
190       case 'n':
191         name=optarg;
192         break;
193       }
194
195   if(!name)
196     {
197       printf("No name provided\n");
198       return 1;
199     }
200
201   if(keyfile && (fpr || url))
202     {
203       printf("Cannot generate a CERT record with both a keyfile and"
204              " a fingerprint or URL\n");
205       return 1;
206     }
207
208   if(keyfile)
209     err=cert_key(name,keyfile);
210   else
211     err=url_key(name,fpr,url);
212
213   return err;
214 }