getcertsbyname.c revision 0a1907d434839af6a9cb6329bbde60b237bf53dc
10a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* $NetBSD: getcertsbyname.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */ 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $ */ 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h> 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h> 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h> 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/nameser.h> 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if (defined(__APPLE__) && defined(__MACH__)) 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <nameser8_compat.h> 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <resolv.h> 460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LWRES_GETRRSETBYNAME 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <lwres/netdb.h> 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <lwres/lwres.h> 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h> 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h> 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h> 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h> 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h> 580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <strings.h> 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef ANDROID_CHANGES 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/inet.h> 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa_nameser.h> 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "netdb_dnssec.h" 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* XXX should it use ci_errno to hold errno instead of h_errno ? */ 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern int h_errno; 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct certinfo *getnewci __P((int, int, int, int, int, 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *)); 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct certinfo * 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetnewci(qtype, keytag, algorithm, flags, certlen, cert) 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qtype, keytag, algorithm, flags, certlen; 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *cert; 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *res; 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res = malloc(sizeof(*res)); 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!res) 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(res, 0, sizeof(*res)); 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_type = qtype; 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_keytag = keytag; 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_algorithm = algorithm; 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_flags = flags; 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_certlen = certlen; 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_cert = malloc(certlen); 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!res->ci_cert) { 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(res); 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(res->ci_cert, cert, certlen); 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return res; 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfreecertinfo(ci) 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *ci; 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *next; 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang next = ci->ci_next; 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ci->ci_cert) 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(ci->ci_cert); 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(ci); 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ci = next; 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (ci); 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get CERT RR by FQDN and create certinfo structure chain. 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LWRES_GETRRSETBYNAME 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define getrrsetbyname lwres_getrrsetbyname 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define freerrset lwres_freerrset 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define hstrerror lwres_hstrerror 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(AHVE_GETRRSETBYNAME) 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetcertsbyname(name, res) 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *name; 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo **res; 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int rdlength; 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *cp; 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int type, keytag, algorithm; 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo head, *cur; 1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct rrsetinfo *rr = NULL; 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = -1; 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* initialize res */ 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = NULL; 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(&head, 0, sizeof(head)); 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = &head; 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = getrrsetbyname(name, C_IN, T_CERT, 0, &rr); 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) { 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getrrsetbyname: %s\n", hstrerror(error)); 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (rr->rri_rdclass != C_IN 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || rr->rri_rdtype != T_CERT 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || rr->rri_nrdatas == 0) { 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getrrsetbyname: %s", hstrerror(error)); 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!(rr->rri_flags & LWRDATA_VALIDATED)) 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("rr is not valid"); 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 0; i < rr->rri_nrdatas; i++) { 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength = rr->rri_rdatas[i].rdi_length; 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp = rr->rri_rdatas[i].rdi_data; 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(type, cp); /* type */ 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(keytag, cp); /* key tag */ 1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang algorithm = *cp++; /* algorithm */ 1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= 1; 1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("type=%d keytag=%d alg=%d len=%d\n", 1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang type, keytag, algorithm, rdlength); 1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create new certinfo */ 1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur->ci_next = getnewci(type, keytag, algorithm, 1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rr->rri_flags, rdlength, cp); 1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!cur->ci_next) { 1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getnewci: %s", strerror(errno)); 1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = cur->ci_next; 1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = head.ci_next; 1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (rr) 2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freerrset(rr); 2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error && head.ci_next) 2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(head.ci_next); 2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else /*!HAVE_LWRES_GETRRSETBYNAME*/ 2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetcertsbyname(name, res) 2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *name; 2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo **res; 2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *answer = NULL, *p; 2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int buflen, anslen, len; 2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang HEADER *hp; 2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qdcount, ancount, rdlength; 2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *cp, *eom; 2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char hostbuf[1024]; /* XXX */ 2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qtype, qclass, keytag, algorithm; 2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo head, *cur; 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = -1; 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* initialize res */ 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = NULL; 2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(&head, 0, sizeof(head)); 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = &head; 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get CERT RR */ 2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buflen = 512; 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buflen *= 2; 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = realloc(answer, buflen); 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!p) { 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("realloc: %s", strerror(errno)); 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang answer = p; 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang anslen = res_query(name, C_IN, T_CERT, answer, buflen); 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (anslen == -1) 2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (buflen < anslen); 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("get a DNS packet len=%d\n", anslen); 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* parse CERT RR */ 2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eom = answer + anslen; 2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hp = (HEADER *)answer; 2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang qdcount = ntohs(hp->qdcount); 2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ancount = ntohs(hp->ancount); 2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* question section */ 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (qdcount != 1) { 2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("query count is not 1.\n"); 2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp = (unsigned char *)(hp + 1); 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len < 0) { 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("dn_expand failed.\n"); 2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += len; 2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* QTYPE */ 2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qclass, cp); /* QCLASS */ 2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* answer section */ 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (ancount-- && cp < eom) { 2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); 2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len < 0) { 2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("dn_expand failed.\n"); 2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += len; 2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* TYPE */ 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qclass, cp); /* CLASS */ 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += INT32SZ; /* TTL */ 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(rdlength, cp); /* RDLENGTH */ 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* CERT RR */ 2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (qtype != T_CERT) { 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("not T_CERT\n"); 3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* type */ 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(keytag, cp); /* key tag */ 3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang algorithm = *cp++; /* algorithm */ 3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= 1; 3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (cp + rdlength > eom) { 3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("rdlength is too long.\n"); 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("type=%d keytag=%d alg=%d len=%d\n", 3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang qtype, keytag, algorithm, rdlength); 3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create new certinfo */ 3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur->ci_next = getnewci(qtype, keytag, algorithm, 3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 0, rdlength, cp); 3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!cur->ci_next) { 3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getnewci: %s", strerror(errno)); 3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = cur->ci_next; 3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += rdlength; 3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = head.ci_next; 3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (answer) 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(answer); 3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error && head.ci_next) 3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(head.ci_next); 3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangb64encode(p, len) 3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int len; 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang static const char b64t[] = 3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "abcdefghijklmnopqrstuvwxyz" 3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "0123456789+/="; 3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (len > 2) { 3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)]); 3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[1] << 2) & 0x3c) | ((p[2] >> 6) & 0x03)]); 3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[p[2] & 0x3f]); 3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len -= 3; 3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p += 3; 3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len == 2) { 3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30)| ((p[1] >> 4) & 0x0f)]); 3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[1] << 2) & 0x3c)]); 3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else if (len == 1) { 3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30)]); 3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmain(ac, av) 3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int ac; 3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char **av; 3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *res, *p; 3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ac < 2) { 3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("Usage: a.out (FQDN)\n"); 3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i = getcertsbyname(*(av + 1), &res); 3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (i != 0) { 4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang herror("getcertsbyname"); 4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getcertsbyname succeeded.\n"); 4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i = 0; 4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (p = res; p; p = p->ci_next) { 4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("certinfo[%d]:\n", i); 4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_type=%d\n", p->ci_type); 4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_keytag=%d\n", p->ci_keytag); 4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_algorithm=%d\n", p->ci_algorithm); 4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_flags=%d\n", p->ci_flags); 4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_certlen=%d\n", p->ci_certlen); 4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_cert: "); 4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang b64encode(p->ci_cert, p->ci_certlen); 4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\n"); 4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i++; 4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(res); 4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(0); 4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 424