Line data Source code
1 : /* make-dns-cert.c - An OpenPGP-to-DNS CERT conversion tool
2 : * Copyright (C) 2006, 2008 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 3 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, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #ifdef HAVE_CONFIG_H
21 : # include <config.h>
22 : #endif
23 :
24 : #include <unistd.h>
25 : #ifdef HAVE_GETOPT_H
26 : #include <getopt.h>
27 : #endif
28 : #include <stdio.h>
29 : #include <stdlib.h>
30 : #include <string.h>
31 : #include <errno.h>
32 : #include <unistd.h>
33 : #include <sys/types.h>
34 : #include <sys/stat.h>
35 : #include <fcntl.h>
36 :
37 : /* We use TYPE37 instead of CERT since not all nameservers can handle
38 : CERT yet... */
39 :
40 : static int
41 0 : cert_key(const char *name,const char *keyfile)
42 : {
43 0 : int fd,ret=1,err,i;
44 : struct stat statbuf;
45 :
46 0 : fd=open(keyfile,O_RDONLY);
47 0 : if(fd==-1)
48 : {
49 0 : fprintf(stderr,"Cannot open key file %s: %s\n",keyfile,strerror(errno));
50 0 : return 1;
51 : }
52 :
53 0 : err=fstat(fd,&statbuf);
54 0 : if(err==-1)
55 : {
56 0 : fprintf(stderr,"Unable to stat key file %s: %s\n",
57 0 : keyfile,strerror(errno));
58 0 : goto fail;
59 : }
60 :
61 0 : if(statbuf.st_size>65536)
62 : {
63 0 : fprintf(stderr,"Key %s too large for CERT encoding\n",keyfile);
64 0 : goto fail;
65 : }
66 :
67 0 : if(statbuf.st_size>16384)
68 0 : fprintf(stderr,"Warning: key file %s is larger than the default"
69 : " GnuPG max-cert-size\n",keyfile);
70 :
71 0 : printf("%s\tTYPE37\t\\# %u 0003 0000 00 ",
72 0 : name,(unsigned int)statbuf.st_size+5);
73 :
74 0 : err=1;
75 0 : while(err!=0)
76 : {
77 : unsigned char buffer[1024];
78 :
79 : do
80 0 : err = read (fd,buffer,1024);
81 0 : while (err == -1 && errno == EINTR);
82 0 : if(err==-1)
83 : {
84 0 : fprintf(stderr,"Unable to read key file %s: %s\n",
85 0 : keyfile,strerror(errno));
86 0 : goto fail;
87 : }
88 :
89 0 : for(i=0;i<err;i++)
90 0 : printf("%02X",buffer[i]);
91 : }
92 :
93 0 : printf("\n");
94 :
95 0 : ret=0;
96 :
97 : fail:
98 0 : close(fd);
99 :
100 0 : return ret;
101 : }
102 :
103 : static int
104 0 : url_key(const char *name,const char *fpr,const char *url)
105 : {
106 0 : int len=6,fprlen=0;
107 :
108 0 : if(fpr)
109 : {
110 0 : const char *tmp = fpr;
111 0 : while (*tmp)
112 : {
113 0 : if ((*tmp >= 'A' && *tmp <= 'F') ||
114 0 : (*tmp >= 'a' && *tmp <= 'f') ||
115 0 : (*tmp >= '0' && *tmp <= '9'))
116 : {
117 0 : fprlen++;
118 : }
119 0 : else if (*tmp != ' ' && *tmp != '\t')
120 : {
121 0 : fprintf(stderr,"Fingerprint must consist of only hex digits"
122 : " and whitespace\n");
123 0 : return 1;
124 : }
125 :
126 0 : tmp++;
127 : }
128 :
129 0 : if(fprlen%2)
130 : {
131 0 : fprintf(stderr,"Fingerprint must be an even number of characters\n");
132 0 : return 1;
133 : }
134 :
135 0 : fprlen/=2;
136 0 : len+=fprlen;
137 : }
138 :
139 0 : if(url)
140 0 : len+=strlen(url);
141 :
142 0 : if(!fpr && !url)
143 : {
144 0 : fprintf(stderr,
145 : "Cannot generate a CERT without either a fingerprint or URL\n");
146 0 : return 1;
147 : }
148 :
149 0 : printf("%s\tTYPE37\t\\# %d 0006 0000 00 %02X",name,len,fprlen);
150 :
151 0 : if(fpr)
152 0 : printf(" %s",fpr);
153 :
154 0 : if(url)
155 : {
156 : const char *c;
157 0 : printf(" ");
158 0 : for(c=url;*c;c++)
159 0 : printf("%02X",*c);
160 : }
161 :
162 0 : printf("\n");
163 :
164 0 : return 0;
165 : }
166 :
167 : static void
168 0 : usage(FILE *stream)
169 : {
170 0 : fprintf(stream,"make-dns-cert\n");
171 0 : fprintf(stream,"\t-f\tfingerprint\n");
172 0 : fprintf(stream,"\t-u\tURL\n");
173 0 : fprintf(stream,"\t-k\tkey file\n");
174 0 : fprintf(stream,"\t-n\tDNS name\n");
175 0 : }
176 :
177 : int
178 0 : main(int argc,char *argv[])
179 : {
180 0 : int arg,err=1;
181 0 : char *fpr=NULL,*url=NULL,*keyfile=NULL,*name=NULL;
182 :
183 0 : if(argc==1)
184 : {
185 0 : usage(stderr);
186 0 : return 1;
187 : }
188 0 : else if(argc>1 && strcmp(argv[1],"--version")==0)
189 : {
190 : #if defined(HAVE_CONFIG_H) && defined(VERSION)
191 0 : printf ("make-dns-cert (GnuPG) " VERSION "\n");
192 : #else
193 : printf ("make-dns-cert gnupg-svn%d\n", atoi (10+"$Revision$"));
194 : #endif
195 0 : return 0;
196 : }
197 0 : else if(argc>1 && strcmp(argv[1],"--help")==0)
198 : {
199 0 : usage(stdout);
200 0 : return 0;
201 : }
202 :
203 0 : while((arg=getopt(argc,argv,"hf:u:k:n:"))!=-1)
204 0 : switch(arg)
205 : {
206 : default:
207 : case 'h':
208 0 : usage(stdout);
209 0 : exit(0);
210 :
211 : case 'f':
212 0 : fpr=optarg;
213 0 : break;
214 :
215 : case 'u':
216 0 : url=optarg;
217 0 : break;
218 :
219 : case 'k':
220 0 : keyfile=optarg;
221 0 : break;
222 :
223 : case 'n':
224 0 : name=optarg;
225 0 : break;
226 : }
227 :
228 0 : if(!name)
229 : {
230 0 : fprintf(stderr,"No name provided\n");
231 0 : return 1;
232 : }
233 :
234 0 : if(keyfile && (fpr || url))
235 : {
236 0 : fprintf(stderr,"Cannot generate a CERT record with both a keyfile and"
237 : " a fingerprint or URL\n");
238 0 : return 1;
239 : }
240 :
241 0 : if(keyfile)
242 0 : err=cert_key(name,keyfile);
243 : else
244 0 : err=url_key(name,fpr,url);
245 :
246 0 : return err;
247 : }
|