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 3 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, see <http://www.gnu.org/licenses/>.
21 #include <sys/types.h>
23 # ifdef HAVE_W32_SYSTEM
26 # include <netinet/in.h>
27 # include <arpa/nameser.h>
37 /* Not every installation has gotten around to supporting CERTs
44 /* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for
47 get_dns_cert (const char *name
,size_t max_size
,IOBUF
*iobuf
,
48 unsigned char **fpr
,size_t *fpr_len
,char **url
)
51 unsigned char *answer
;
61 answer
=xmalloc(max_size
);
63 r
=res_query(name
,C_IN
,T_CERT
,answer
,max_size
);
64 /* Not too big, not too small, no errors and at least 1 answer. */
65 if(r
>=sizeof(HEADER
) && r
<=max_size
66 && (((HEADER
*)answer
)->rcode
)==NOERROR
67 && (count
=ntohs(((HEADER
*)answer
)->ancount
)))
70 unsigned char *pt
,*emsg
;
74 pt
=&answer
[sizeof(HEADER
)];
76 /* Skip over the query */
78 rc
=dn_skipname(pt
,emsg
);
84 /* There are several possible response types for a CERT request.
85 We're interested in the PGP (a key) and IPGP (a URI) types.
86 Skip all others. TODO: A key is better than a URI since
87 we've gone through all this bother to fetch it, so favor that
88 if we have both PGP and IPGP? */
90 while(count
-->0 && pt
<emsg
)
92 u16 type
,class,dlen
,ctype
;
94 rc
=dn_skipname(pt
,emsg
); /* the name we just queried for */
100 /* Truncated message? 15 bytes takes us to the point where
101 we start looking at the ctype. */
110 /* We asked for IN and got something else !? */
121 /* We asked for CERT and got something else - might be a
122 CNAME, so loop around again. */
133 /* Skip the CERT key tag and algo which we don't need. */
138 /* 15 bytes takes us to here */
140 if(ctype
==3 && iobuf
&& dlen
)
143 *iobuf
=iobuf_temp_with_content((char *)pt
,dlen
);
147 else if(ctype
==6 && dlen
&& dlen
<1023 && dlen
>=pt
[0]+1
148 && fpr
&& fpr_len
&& url
)
155 *fpr
=xmalloc(*fpr_len
);
156 memcpy(*fpr
,&pt
[1],*fpr_len
);
163 *url
=xmalloc(dlen
-(*fpr_len
+1)+1);
164 memcpy(*url
,&pt
[*fpr_len
+1],dlen
-(*fpr_len
+1));
165 (*url
)[dlen
-(*fpr_len
+1)]='\0';
174 /* Neither type matches, so go around to the next answer. */
183 #else /* !USE_DNS_CERT */
190 /* Test with simon.josefsson.org */
194 main(int argc
,char *argv
[])
204 printf("cert-test [name]\n");
208 printf("CERT lookup on %s\n",argv
[1]);
210 rc
=get_dns_cert (argv
[1],16384,&iobuf
,&fpr
,&fpr_len
,&url
);
214 printf("no answer\n");
217 printf("key found: %d bytes\n",(int)iobuf_get_temp_length(iobuf
));
225 printf("Fingerprint found (%d bytes): ",(int)fpr_len
);
226 for(i
=0;i
<fpr_len
;i
++)
227 printf("%02X",fpr
[i
]);
231 printf("No fingerprint found\n");
234 printf("URL found: %s\n",url
);
236 printf("No URL found\n");