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#include "netdb_dnssec.h" 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* XXX should it use ci_errno to hold errno instead of h_errno ? */ 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangextern int h_errno; 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct certinfo *getnewci __P((int, int, int, int, int, 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *)); 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct certinfo * 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetnewci(qtype, keytag, algorithm, flags, certlen, cert) 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qtype, keytag, algorithm, flags, certlen; 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *cert; 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *res; 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res = malloc(sizeof(*res)); 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!res) 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(res, 0, sizeof(*res)); 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_type = qtype; 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_keytag = keytag; 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_algorithm = algorithm; 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_flags = flags; 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_certlen = certlen; 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang res->ci_cert = malloc(certlen); 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!res->ci_cert) { 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(res); 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(res->ci_cert, cert, certlen); 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return res; 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangfreecertinfo(ci) 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *ci; 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *next; 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang next = ci->ci_next; 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ci->ci_cert) 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(ci->ci_cert); 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(ci); 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ci = next; 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (ci); 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * get CERT RR by FQDN and create certinfo structure chain. 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LWRES_GETRRSETBYNAME 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define getrrsetbyname lwres_getrrsetbyname 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define freerrset lwres_freerrset 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#define hstrerror lwres_hstrerror 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(AHVE_GETRRSETBYNAME) 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetcertsbyname(name, res) 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *name; 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo **res; 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int rdlength; 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *cp; 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int type, keytag, algorithm; 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo head, *cur; 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct rrsetinfo *rr = NULL; 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = -1; 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* initialize res */ 1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = NULL; 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(&head, 0, sizeof(head)); 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = &head; 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = getrrsetbyname(name, C_IN, T_CERT, 0, &rr); 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error) { 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getrrsetbyname: %s\n", hstrerror(error)); 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (rr->rri_rdclass != C_IN 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || rr->rri_rdtype != T_CERT 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang || rr->rri_nrdatas == 0) { 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getrrsetbyname: %s", hstrerror(error)); 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!(rr->rri_flags & LWRDATA_VALIDATED)) 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("rr is not valid"); 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 0; i < rr->rri_nrdatas; i++) { 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength = rr->rri_rdatas[i].rdi_length; 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp = rr->rri_rdatas[i].rdi_data; 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(type, cp); /* type */ 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(keytag, cp); /* key tag */ 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang algorithm = *cp++; /* algorithm */ 1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= 1; 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("type=%d keytag=%d alg=%d len=%d\n", 1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang type, keytag, algorithm, rdlength); 1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create new certinfo */ 1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur->ci_next = getnewci(type, keytag, algorithm, 1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rr->rri_flags, rdlength, cp); 1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!cur->ci_next) { 1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getnewci: %s", strerror(errno)); 1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = cur->ci_next; 1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = head.ci_next; 1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (rr) 1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freerrset(rr); 1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error && head.ci_next) 1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(head.ci_next); 1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else /*!HAVE_LWRES_GETRRSETBYNAME*/ 2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggetcertsbyname(name, res) 2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *name; 2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo **res; 2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *answer = NULL, *p; 2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int buflen, anslen, len; 2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang HEADER *hp; 2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qdcount, ancount, rdlength; 2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned char *cp, *eom; 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char hostbuf[1024]; /* XXX */ 2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int qtype, qclass, keytag, algorithm; 2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo head, *cur; 2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int error = -1; 2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* initialize res */ 2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = NULL; 2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memset(&head, 0, sizeof(head)); 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = &head; 2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* get CERT RR */ 2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buflen = 512; 2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buflen *= 2; 2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p = realloc(answer, buflen); 2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!p) { 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("realloc: %s", strerror(errno)); 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang answer = p; 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang anslen = res_query(name, C_IN, T_CERT, answer, buflen); 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (anslen == -1) 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (buflen < anslen); 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("get a DNS packet len=%d\n", anslen); 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* parse CERT RR */ 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang eom = answer + anslen; 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hp = (HEADER *)answer; 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang qdcount = ntohs(hp->qdcount); 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang ancount = ntohs(hp->ancount); 2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* question section */ 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (qdcount != 1) { 2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("query count is not 1.\n"); 2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp = (unsigned char *)(hp + 1); 2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len < 0) { 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("dn_expand failed.\n"); 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += len; 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* QTYPE */ 2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qclass, cp); /* QCLASS */ 2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* answer section */ 2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (ancount-- && cp < eom) { 2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf)); 2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len < 0) { 2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("dn_expand failed.\n"); 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += len; 2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* TYPE */ 2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qclass, cp); /* CLASS */ 2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += INT32SZ; /* TTL */ 2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(rdlength, cp); /* RDLENGTH */ 2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* CERT RR */ 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (qtype != T_CERT) { 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("not T_CERT\n"); 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(qtype, cp); /* type */ 3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang GETSHORT(keytag, cp); /* key tag */ 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= INT16SZ; 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang algorithm = *cp++; /* algorithm */ 3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang rdlength -= 1; 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (cp + rdlength > eom) { 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("rdlength is too long.\n"); 3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("type=%d keytag=%d alg=%d len=%d\n", 3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang qtype, keytag, algorithm, rdlength); 3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* create new certinfo */ 3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur->ci_next = getnewci(qtype, keytag, algorithm, 3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 0, rdlength, cp); 3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (!cur->ci_next) { 3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getnewci: %s", strerror(errno)); 3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang h_errno = NO_RECOVERY; 3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto end; 3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cur = cur->ci_next; 3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang cp += rdlength; 3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *res = head.ci_next; 3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang error = 0; 3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangend: 3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (answer) 3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang free(answer); 3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (error && head.ci_next) 3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(head.ci_next); 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return error; 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef DNSSEC_DEBUG 3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangb64encode(p, len) 3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *p; 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int len; 3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang static const char b64t[] = 3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "abcdefghijklmnopqrstuvwxyz" 3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "0123456789+/="; 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (len > 2) { 3570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)]); 3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[1] << 2) & 0x3c) | ((p[2] >> 6) & 0x03)]); 3600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[p[2] & 0x3f]); 3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len -= 3; 3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang p += 3; 3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len == 2) { 3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30)| ((p[1] >> 4) & 0x0f)]); 3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[1] << 2) & 0x3c)]); 3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else if (len == 1) { 3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[(p[0] >> 2) & 0x3f]); 3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", b64t[((p[0] << 4) & 0x30)]); 3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("%c", '='); 3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangmain(ac, av) 3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int ac; 3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char **av; 3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct certinfo *res, *p; 3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (ac < 2) { 3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("Usage: a.out (FQDN)\n"); 3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i = getcertsbyname(*(av + 1), &res); 3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (i != 0) { 3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang herror("getcertsbyname"); 3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(1); 3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("getcertsbyname succeeded.\n"); 3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i = 0; 4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (p = res; p; p = p->ci_next) { 4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("certinfo[%d]:\n", i); 4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_type=%d\n", p->ci_type); 4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_keytag=%d\n", p->ci_keytag); 4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_algorithm=%d\n", p->ci_algorithm); 4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_flags=%d\n", p->ci_flags); 4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_certlen=%d\n", p->ci_certlen); 4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\tci_cert: "); 4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang b64encode(p->ci_cert, p->ci_certlen); 4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang printf("\n"); 4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang i++; 4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang freecertinfo(res); 4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang exit(0); 4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 419