]>
git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/getcertsbyname.c
1 /* $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #if ENABLE_DNSSEC_CERTS
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/nameser_compat.h>
43 // Note: this is currently compiled out because ENABLE_DNSSEC_CERTS=0
44 // TODO: switch to DNSServiceRef APIs before enabling
45 #error "Need to switch to DNSServiceRef APIs before enabling"
48 #ifdef HAVE_LWRES_GETRRSETBYNAME
49 #include <lwres/netdb.h>
50 #include <lwres/lwres.h>
64 #include "netdb_dnssec.h"
66 /* XXX should it use ci_errno to hold errno instead of h_errno ? */
69 static struct certinfo
*getnewci (int, int, int, int, int,
72 static struct certinfo
*
73 getnewci(qtype
, keytag
, algorithm
, flags
, certlen
, cert
)
74 int qtype
, keytag
, algorithm
, flags
, certlen
;
79 res
= malloc(sizeof(*res
));
83 memset(res
, 0, sizeof(*res
));
85 res
->ci_keytag
= keytag
;
86 res
->ci_algorithm
= algorithm
;
87 res
->ci_flags
= flags
;
88 res
->ci_certlen
= certlen
;
89 res
->ci_cert
= malloc(certlen
);
94 memcpy(res
->ci_cert
, cert
, certlen
);
103 struct certinfo
*next
;
115 * get CERT RR by FQDN and create certinfo structure chain.
117 #ifdef HAVE_LWRES_GETRRSETBYNAME
118 #define getrrsetbyname lwres_getrrsetbyname
119 #define freerrset lwres_freerrset
120 #define hstrerror lwres_hstrerror
122 #if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(HAVE_GETRRSETBYNAME) //%%% BUG FIX - HAVE misspelled
124 getcertsbyname(name
, res
)
126 struct certinfo
**res
;
130 int type
, keytag
, algorithm
;
131 struct certinfo head
, *cur
;
132 struct rrsetinfo
*rr
= NULL
;
139 memset(&head
, 0, sizeof(head
));
142 error
= getrrsetbyname(name
, C_IN
, T_CERT
, 0, &rr
);
145 printf("getrrsetbyname: %s\n", hstrerror(error
));
147 h_errno
= NO_RECOVERY
;
151 if (rr
->rri_rdclass
!= C_IN
152 || rr
->rri_rdtype
!= T_CERT
153 || rr
->rri_nrdatas
== 0) {
155 printf("getrrsetbyname: %s", hstrerror(error
));
157 h_errno
= NO_RECOVERY
;
161 if (!(rr
->rri_flags
& LWRDATA_VALIDATED
))
162 printf("rr is not valid");
165 for (i
= 0; i
< rr
->rri_nrdatas
; i
++) {
166 rdlength
= rr
->rri_rdatas
[i
].rdi_length
;
167 cp
= rr
->rri_rdatas
[i
].rdi_data
;
169 GETSHORT(type
, cp
); /* type */
171 GETSHORT(keytag
, cp
); /* key tag */
173 algorithm
= *cp
++; /* algorithm */
177 printf("type=%d keytag=%d alg=%d len=%d\n",
178 type
, keytag
, algorithm
, rdlength
);
181 /* create new certinfo */
182 cur
->ci_next
= getnewci(type
, keytag
, algorithm
,
183 rr
->rri_flags
, rdlength
, cp
);
186 printf("getnewci: %s", strerror(errno
));
188 h_errno
= NO_RECOVERY
;
200 if (error
&& head
.ci_next
)
201 freecertinfo(head
.ci_next
);
205 #else /*!HAVE_LWRES_GETRRSETBYNAME*/
207 getcertsbyname(name
, res
)
209 struct certinfo
**res
;
211 unsigned char *answer
= NULL
, *p
;
212 int buflen
, anslen
, len
;
214 int qdcount
, ancount
, rdlength
;
215 unsigned char *cp
, *eom
;
216 char hostbuf
[1024]; /* XXX */
217 int qtype
, qclass
, keytag
, algorithm
;
218 struct certinfo head
, *cur
;
224 memset(&head
, 0, sizeof(head
));
232 p
= realloc(answer
, buflen
);
235 printf("realloc: %s", strerror(errno
));
237 h_errno
= NO_RECOVERY
;
242 // Note: this is currently compiled out because ENABLE_DNSSEC_CERTS=0
243 // TODO: switch to DNSServiceRef APIs before enabling
244 #error "Need to switch to DNSServiceRef APIs before enabling"
246 anslen
= res_query(name
, C_IN
, T_CERT
, answer
, buflen
);
250 } while (buflen
< anslen
);
253 printf("get a DNS packet len=%d\n", anslen
);
257 eom
= answer
+ anslen
;
259 hp
= ALIGNED_CAST(HEADER
*)answer
;
260 qdcount
= ntohs(hp
->qdcount
);
261 ancount
= ntohs(hp
->ancount
);
263 /* question section */
266 printf("query count is not 1.\n");
268 h_errno
= NO_RECOVERY
;
271 cp
= (unsigned char *)(hp
+ 1);
272 len
= dn_expand(answer
, eom
, cp
, hostbuf
, sizeof(hostbuf
));
275 printf("dn_expand failed.\n");
280 GETSHORT(qtype
, cp
); /* QTYPE */
281 GETSHORT(qclass
, cp
); /* QCLASS */
284 while (ancount
-- && cp
< eom
) {
285 len
= dn_expand(answer
, eom
, cp
, hostbuf
, sizeof(hostbuf
));
288 printf("dn_expand failed.\n");
293 GETSHORT(qtype
, cp
); /* TYPE */
294 GETSHORT(qclass
, cp
); /* CLASS */
295 cp
+= INT32SZ
; /* TTL */
296 GETSHORT(rdlength
, cp
); /* RDLENGTH */
299 if (qtype
!= T_CERT
) {
301 printf("not T_CERT\n");
303 h_errno
= NO_RECOVERY
;
306 GETSHORT(qtype
, cp
); /* type */
308 GETSHORT(keytag
, cp
); /* key tag */
310 algorithm
= *cp
++; /* algorithm */
312 if (cp
+ rdlength
> eom
) {
314 printf("rdlength is too long.\n");
316 h_errno
= NO_RECOVERY
;
320 printf("type=%d keytag=%d alg=%d len=%d\n",
321 qtype
, keytag
, algorithm
, rdlength
);
324 /* create new certinfo */
325 cur
->ci_next
= getnewci(qtype
, keytag
, algorithm
,
329 printf("getnewci: %s", strerror(errno
));
331 h_errno
= NO_RECOVERY
;
345 if (error
&& head
.ci_next
)
346 freecertinfo(head
.ci_next
);
358 static const char b64t
[] =
359 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
360 "abcdefghijklmnopqrstuvwxyz"
364 printf("%c", b64t
[(p
[0] >> 2) & 0x3f]);
365 printf("%c", b64t
[((p
[0] << 4) & 0x30) | ((p
[1] >> 4) & 0x0f)]);
366 printf("%c", b64t
[((p
[1] << 2) & 0x3c) | ((p
[2] >> 6) & 0x03)]);
367 printf("%c", b64t
[p
[2] & 0x3f]);
373 printf("%c", b64t
[(p
[0] >> 2) & 0x3f]);
374 printf("%c", b64t
[((p
[0] << 4) & 0x30)| ((p
[1] >> 4) & 0x0f)]);
375 printf("%c", b64t
[((p
[1] << 2) & 0x3c)]);
377 } else if (len
== 1) {
378 printf("%c", b64t
[(p
[0] >> 2) & 0x3f]);
379 printf("%c", b64t
[((p
[0] << 4) & 0x30)]);
392 struct certinfo
*res
, *p
;
396 printf("Usage: a.out (FQDN)\n");
400 i
= getcertsbyname(*(av
+ 1), &res
);
402 herror("getcertsbyname");
405 printf("getcertsbyname succeeded.\n");
408 for (p
= res
; p
; p
= p
->ci_next
) {
409 printf("certinfo[%d]:\n", i
);
410 printf("\tci_type=%d\n", p
->ci_type
);
411 printf("\tci_keytag=%d\n", p
->ci_keytag
);
412 printf("\tci_algorithm=%d\n", p
->ci_algorithm
);
413 printf("\tci_flags=%d\n", p
->ci_flags
);
414 printf("\tci_certlen=%d\n", p
->ci_certlen
);
415 printf("\tci_cert: ");
416 b64encode(p
->ci_cert
, p
->ci_certlen
);
427 #endif /* ENABLE_DNSSEC_CERTS */