1 /* dns-cert.c - DNS CERT code
2 * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4 * This file is part of GNUPG.
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.
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.
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,
23 #include <sys/types.h>
25 # ifdef HAVE_W32_SYSTEM
28 # include <netinet/in.h>
29 # include <arpa/nameser.h>
39 /* Not every installation has gotten around to supporting CERTs
46 /* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for
49 get_dns_cert (const char *name
,size_t max_size
,IOBUF
*iobuf
,
50 unsigned char **fpr
,size_t *fpr_len
,char **url
)
53 unsigned char *answer
;
63 answer
=xmalloc(max_size
);
65 r
=res_query(name
,C_IN
,T_CERT
,answer
,max_size
);
66 /* Not too big, not too small, no errors and at least 1 answer. */
67 if(r
>=sizeof(HEADER
) && r
<=max_size
68 && (((HEADER
*)answer
)->rcode
)==NOERROR
69 && (count
=ntohs(((HEADER
*)answer
)->ancount
)))
72 unsigned char *pt
,*emsg
;
76 pt
=&answer
[sizeof(HEADER
)];
78 /* Skip over the query */
80 rc
=dn_skipname(pt
,emsg
);
86 /* There are several possible response types for a CERT request.
87 We're interested in the PGP (a key) and IPGP (a URI) types.
88 Skip all others. TODO: A key is better than a URI since
89 we've gone through all this bother to fetch it, so favor that
90 if we have both PGP and IPGP? */
92 while(count
-->0 && pt
<emsg
)
94 u16 type
,class,dlen
,ctype
;
96 rc
=dn_skipname(pt
,emsg
); /* the name we just queried for */
102 /* Truncated message? 15 bytes takes us to the point where
103 we start looking at the ctype. */
112 /* We asked for IN and got something else !? */
123 /* We asked for CERT and got something else - might be a
124 CNAME, so loop around again. */
135 /* Skip the CERT key tag and algo which we don't need. */
140 /* 15 bytes takes us to here */
142 if(ctype
==3 && iobuf
&& dlen
)
145 *iobuf
=iobuf_temp_with_content((char *)pt
,dlen
);
149 else if(ctype
==6 && dlen
&& dlen
<1023 && dlen
>=pt
[0]+1
150 && fpr
&& fpr_len
&& url
)
157 *fpr
=xmalloc(*fpr_len
);
158 memcpy(*fpr
,&pt
[1],*fpr_len
);
165 *url
=xmalloc(dlen
-(*fpr_len
+1)+1);
166 memcpy(*url
,&pt
[*fpr_len
+1],dlen
-(*fpr_len
+1));
167 (*url
)[dlen
-(*fpr_len
+1)]='\0';
176 /* Neither type matches, so go around to the next answer. */
185 #else /* !USE_DNS_CERT */
192 /* Test with simon.josefsson.org */
196 main(int argc
,char *argv
[])
206 printf("cert-test [name]\n");
210 printf("CERT lookup on %s\n",argv
[1]);
212 rc
=get_dns_cert (argv
[1],16384,&iobuf
,&fpr
,&fpr_len
,&url
);
216 printf("no answer\n");
219 printf("key found: %d bytes\n",(int)iobuf_get_temp_length(iobuf
));
227 printf("Fingerprint found (%d bytes): ",(int)fpr_len
);
228 for(i
=0;i
<fpr_len
;i
++)
229 printf("%02X",fpr
[i
]);
233 printf("No fingerprint found\n");
236 printf("URL found: %s\n",url
);
238 printf("No URL found\n");