Annotation of embedaddon/ipsec-tools/src/racoon/getcertsbyname.c, revision 1.1

1.1     ! misho       1: /*     $NetBSD: getcertsbyname.c,v 1.4 2006/09/09 16:22:09 manu Exp $  */
        !             2: 
        !             3: /*     $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $  */
        !             4: 
        !             5: /*
        !             6:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
        !             7:  * All rights reserved.
        !             8:  * 
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. Neither the name of the project nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  * 
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33: 
        !            34: #include "config.h"
        !            35: 
        !            36: #include <sys/types.h>
        !            37: #include <sys/param.h>
        !            38: #include <sys/socket.h>
        !            39: 
        !            40: #include <netinet/in.h>
        !            41: #include <arpa/nameser.h>
        !            42: #if (defined(__APPLE__) && defined(__MACH__))
        !            43: # include <nameser8_compat.h>
        !            44: #endif
        !            45: #include <resolv.h>
        !            46: #ifdef HAVE_LWRES_GETRRSETBYNAME
        !            47: #include <lwres/netdb.h>
        !            48: #include <lwres/lwres.h>
        !            49: #else
        !            50: #include <netdb.h>
        !            51: #endif
        !            52: #include <stdlib.h>
        !            53: #include <string.h>
        !            54: #include <errno.h>
        !            55: 
        !            56: #ifdef DNSSEC_DEBUG
        !            57: #include <stdio.h>
        !            58: #include <strings.h>
        !            59: #endif
        !            60: 
        !            61: #include "netdb_dnssec.h"
        !            62: 
        !            63: /* XXX should it use ci_errno to hold errno instead of h_errno ? */
        !            64: extern int h_errno;
        !            65: 
        !            66: static struct certinfo *getnewci __P((int, int, int, int, int, 
        !            67:                        unsigned char *));
        !            68: 
        !            69: static struct certinfo *
        !            70: getnewci(qtype, keytag, algorithm, flags, certlen, cert)
        !            71:        int qtype, keytag, algorithm, flags, certlen;
        !            72:        unsigned char *cert;
        !            73: {
        !            74:        struct certinfo *res;
        !            75: 
        !            76:        res = malloc(sizeof(*res));
        !            77:        if (!res)
        !            78:                return NULL;
        !            79: 
        !            80:        memset(res, 0, sizeof(*res));
        !            81:        res->ci_type = qtype;
        !            82:        res->ci_keytag = keytag;
        !            83:        res->ci_algorithm = algorithm;
        !            84:        res->ci_flags = flags;
        !            85:        res->ci_certlen = certlen;
        !            86:        res->ci_cert = malloc(certlen);
        !            87:        if (!res->ci_cert) {
        !            88:                free(res);
        !            89:                return NULL;
        !            90:        }
        !            91:        memcpy(res->ci_cert, cert, certlen);
        !            92: 
        !            93:        return res;
        !            94: }
        !            95: 
        !            96: void
        !            97: freecertinfo(ci)
        !            98:        struct certinfo *ci;
        !            99: {
        !           100:        struct certinfo *next;
        !           101: 
        !           102:        do {
        !           103:                next = ci->ci_next;
        !           104:                if (ci->ci_cert)
        !           105:                        free(ci->ci_cert);
        !           106:                free(ci);
        !           107:                ci = next;
        !           108:        } while (ci);
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * get CERT RR by FQDN and create certinfo structure chain.
        !           113:  */
        !           114: #ifdef HAVE_LWRES_GETRRSETBYNAME
        !           115: #define getrrsetbyname lwres_getrrsetbyname
        !           116: #define freerrset lwres_freerrset
        !           117: #define hstrerror lwres_hstrerror
        !           118: #endif
        !           119: #if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(AHVE_GETRRSETBYNAME)
        !           120: int
        !           121: getcertsbyname(name, res)
        !           122:        char *name;
        !           123:        struct certinfo **res;
        !           124: {
        !           125:        int rdlength;
        !           126:        char *cp;
        !           127:        int type, keytag, algorithm;
        !           128:        struct certinfo head, *cur;
        !           129:        struct rrsetinfo *rr = NULL;
        !           130:        int i;
        !           131:        int error = -1;
        !           132: 
        !           133:        /* initialize res */
        !           134:        *res = NULL;
        !           135: 
        !           136:        memset(&head, 0, sizeof(head));
        !           137:        cur = &head;
        !           138: 
        !           139:        error = getrrsetbyname(name, C_IN, T_CERT, 0, &rr);
        !           140:        if (error) {
        !           141: #ifdef DNSSEC_DEBUG
        !           142:                printf("getrrsetbyname: %s\n", hstrerror(error));
        !           143: #endif
        !           144:                h_errno = NO_RECOVERY;
        !           145:                goto end;
        !           146:        }
        !           147: 
        !           148:        if (rr->rri_rdclass != C_IN
        !           149:         || rr->rri_rdtype != T_CERT
        !           150:         || rr->rri_nrdatas == 0) {
        !           151: #ifdef DNSSEC_DEBUG
        !           152:                printf("getrrsetbyname: %s", hstrerror(error));
        !           153: #endif
        !           154:                h_errno = NO_RECOVERY;
        !           155:                goto end;
        !           156:        }
        !           157: #ifdef DNSSEC_DEBUG
        !           158:        if (!(rr->rri_flags & LWRDATA_VALIDATED))
        !           159:                printf("rr is not valid");
        !           160: #endif
        !           161: 
        !           162:        for (i = 0; i < rr->rri_nrdatas; i++) {
        !           163:                rdlength = rr->rri_rdatas[i].rdi_length;
        !           164:                cp = rr->rri_rdatas[i].rdi_data;
        !           165: 
        !           166:                GETSHORT(type, cp);     /* type */
        !           167:                rdlength -= INT16SZ;
        !           168:                GETSHORT(keytag, cp);   /* key tag */
        !           169:                rdlength -= INT16SZ;
        !           170:                algorithm = *cp++;      /* algorithm */
        !           171:                rdlength -= 1;
        !           172: 
        !           173: #ifdef DNSSEC_DEBUG
        !           174:                printf("type=%d keytag=%d alg=%d len=%d\n",
        !           175:                        type, keytag, algorithm, rdlength);
        !           176: #endif
        !           177: 
        !           178:                /* create new certinfo */
        !           179:                cur->ci_next = getnewci(type, keytag, algorithm,
        !           180:                                        rr->rri_flags, rdlength, cp);
        !           181:                if (!cur->ci_next) {
        !           182: #ifdef DNSSEC_DEBUG
        !           183:                        printf("getnewci: %s", strerror(errno));
        !           184: #endif
        !           185:                        h_errno = NO_RECOVERY;
        !           186:                        goto end;
        !           187:                }
        !           188:                cur = cur->ci_next;
        !           189:        }
        !           190: 
        !           191:        *res = head.ci_next;
        !           192:        error = 0;
        !           193: 
        !           194: end:
        !           195:        if (rr)
        !           196:                freerrset(rr);
        !           197:        if (error && head.ci_next)
        !           198:                freecertinfo(head.ci_next);
        !           199: 
        !           200:        return error;
        !           201: }
        !           202: #else  /*!HAVE_LWRES_GETRRSETBYNAME*/
        !           203: int
        !           204: getcertsbyname(name, res)
        !           205:        char *name;
        !           206:        struct certinfo **res;
        !           207: {
        !           208:        unsigned char *answer = NULL, *p;
        !           209:        int buflen, anslen, len;
        !           210:        HEADER *hp;
        !           211:        int qdcount, ancount, rdlength;
        !           212:        unsigned char *cp, *eom;
        !           213:        char hostbuf[1024];     /* XXX */
        !           214:        int qtype, qclass, keytag, algorithm;
        !           215:        struct certinfo head, *cur;
        !           216:        int error = -1;
        !           217: 
        !           218:        /* initialize res */
        !           219:        *res = NULL;
        !           220: 
        !           221:        memset(&head, 0, sizeof(head));
        !           222:        cur = &head;
        !           223: 
        !           224:        /* get CERT RR */
        !           225:        buflen = 512;
        !           226:        do {
        !           227: 
        !           228:                buflen *= 2;
        !           229:                p = realloc(answer, buflen);
        !           230:                if (!p) {
        !           231: #ifdef DNSSEC_DEBUG
        !           232:                        printf("realloc: %s", strerror(errno));
        !           233: #endif
        !           234:                        h_errno = NO_RECOVERY;
        !           235:                        goto end;
        !           236:                }
        !           237:                answer = p;
        !           238: 
        !           239:                anslen = res_query(name,  C_IN, T_CERT, answer, buflen);
        !           240:                if (anslen == -1)
        !           241:                        goto end;
        !           242: 
        !           243:        } while (buflen < anslen);
        !           244: 
        !           245: #ifdef DNSSEC_DEBUG
        !           246:        printf("get a DNS packet len=%d\n", anslen);
        !           247: #endif
        !           248: 
        !           249:        /* parse CERT RR */
        !           250:        eom = answer + anslen;
        !           251: 
        !           252:        hp = (HEADER *)answer;
        !           253:        qdcount = ntohs(hp->qdcount);
        !           254:        ancount = ntohs(hp->ancount);
        !           255: 
        !           256:        /* question section */
        !           257:        if (qdcount != 1) {
        !           258: #ifdef DNSSEC_DEBUG
        !           259:                printf("query count is not 1.\n");
        !           260: #endif
        !           261:                h_errno = NO_RECOVERY;
        !           262:                goto end;
        !           263:        }
        !           264:        cp = (unsigned char *)(hp + 1);
        !           265:        len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf));
        !           266:        if (len < 0) {
        !           267: #ifdef DNSSEC_DEBUG
        !           268:                printf("dn_expand failed.\n");
        !           269: #endif
        !           270:                goto end;
        !           271:        }
        !           272:        cp += len;
        !           273:        GETSHORT(qtype, cp);            /* QTYPE */
        !           274:        GETSHORT(qclass, cp);           /* QCLASS */
        !           275: 
        !           276:        /* answer section */
        !           277:        while (ancount-- && cp < eom) {
        !           278:                len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf));
        !           279:                if (len < 0) {
        !           280: #ifdef DNSSEC_DEBUG
        !           281:                        printf("dn_expand failed.\n");
        !           282: #endif
        !           283:                        goto end;
        !           284:                }
        !           285:                cp += len;
        !           286:                GETSHORT(qtype, cp);    /* TYPE */
        !           287:                GETSHORT(qclass, cp);   /* CLASS */
        !           288:                cp += INT32SZ;          /* TTL */
        !           289:                GETSHORT(rdlength, cp); /* RDLENGTH */
        !           290: 
        !           291:                /* CERT RR */
        !           292:                if (qtype != T_CERT) {
        !           293: #ifdef DNSSEC_DEBUG
        !           294:                        printf("not T_CERT\n");
        !           295: #endif
        !           296:                        h_errno = NO_RECOVERY;
        !           297:                        goto end;
        !           298:                }
        !           299:                GETSHORT(qtype, cp);    /* type */
        !           300:                rdlength -= INT16SZ;
        !           301:                GETSHORT(keytag, cp);   /* key tag */
        !           302:                rdlength -= INT16SZ;
        !           303:                algorithm = *cp++;      /* algorithm */
        !           304:                rdlength -= 1;
        !           305:                if (cp + rdlength > eom) {
        !           306: #ifdef DNSSEC_DEBUG
        !           307:                        printf("rdlength is too long.\n");
        !           308: #endif
        !           309:                        h_errno = NO_RECOVERY;
        !           310:                        goto end;
        !           311:                }
        !           312: #ifdef DNSSEC_DEBUG
        !           313:                printf("type=%d keytag=%d alg=%d len=%d\n",
        !           314:                        qtype, keytag, algorithm, rdlength);
        !           315: #endif
        !           316: 
        !           317:                /* create new certinfo */
        !           318:                cur->ci_next = getnewci(qtype, keytag, algorithm,
        !           319:                                        0, rdlength, cp);
        !           320:                if (!cur->ci_next) {
        !           321: #ifdef DNSSEC_DEBUG
        !           322:                        printf("getnewci: %s", strerror(errno));
        !           323: #endif
        !           324:                        h_errno = NO_RECOVERY;
        !           325:                        goto end;
        !           326:                }
        !           327:                cur = cur->ci_next;
        !           328: 
        !           329:                cp += rdlength;
        !           330:        }
        !           331: 
        !           332:        *res = head.ci_next;
        !           333:        error = 0;
        !           334: 
        !           335: end:
        !           336:        if (answer)
        !           337:                free(answer);
        !           338:        if (error && head.ci_next)
        !           339:                freecertinfo(head.ci_next);
        !           340: 
        !           341:        return error;
        !           342: }
        !           343: #endif
        !           344: 
        !           345: #ifdef DNSSEC_DEBUG
        !           346: int
        !           347: b64encode(p, len)
        !           348:        char *p;
        !           349:        int len;
        !           350: {
        !           351:        static const char b64t[] =
        !           352:                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        !           353:                "abcdefghijklmnopqrstuvwxyz"
        !           354:                "0123456789+/=";
        !           355: 
        !           356:        while (len > 2) {
        !           357:                 printf("%c", b64t[(p[0] >> 2) & 0x3f]);
        !           358:                 printf("%c", b64t[((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)]);
        !           359:                 printf("%c", b64t[((p[1] << 2) & 0x3c) | ((p[2] >> 6) & 0x03)]);
        !           360:                 printf("%c", b64t[p[2] & 0x3f]);
        !           361:                len -= 3;
        !           362:                p += 3;
        !           363:        }
        !           364: 
        !           365:        if (len == 2) {
        !           366:                 printf("%c", b64t[(p[0] >> 2) & 0x3f]);
        !           367:                 printf("%c", b64t[((p[0] << 4) & 0x30)| ((p[1] >> 4) & 0x0f)]);
        !           368:                 printf("%c", b64t[((p[1] << 2) & 0x3c)]);
        !           369:                 printf("%c", '=');
        !           370:         } else if (len == 1) {
        !           371:                 printf("%c", b64t[(p[0] >> 2) & 0x3f]);
        !           372:                 printf("%c", b64t[((p[0] << 4) & 0x30)]);
        !           373:                 printf("%c", '=');
        !           374:                 printf("%c", '=');
        !           375:        }
        !           376: 
        !           377:        return 0;
        !           378: }
        !           379: 
        !           380: int
        !           381: main(ac, av)
        !           382:        int ac;
        !           383:        char **av;
        !           384: {
        !           385:        struct certinfo *res, *p;
        !           386:        int i;
        !           387: 
        !           388:        if (ac < 2) {
        !           389:                printf("Usage: a.out (FQDN)\n");
        !           390:                exit(1);
        !           391:        }
        !           392: 
        !           393:        i = getcertsbyname(*(av + 1), &res);
        !           394:        if (i != 0) {
        !           395:                herror("getcertsbyname");
        !           396:                exit(1);
        !           397:        }
        !           398:        printf("getcertsbyname succeeded.\n");
        !           399: 
        !           400:        i = 0;
        !           401:        for (p = res; p; p = p->ci_next) {
        !           402:                printf("certinfo[%d]:\n", i);
        !           403:                printf("\tci_type=%d\n", p->ci_type);
        !           404:                printf("\tci_keytag=%d\n", p->ci_keytag);
        !           405:                printf("\tci_algorithm=%d\n", p->ci_algorithm);
        !           406:                printf("\tci_flags=%d\n", p->ci_flags);
        !           407:                printf("\tci_certlen=%d\n", p->ci_certlen);
        !           408:                printf("\tci_cert: ");
        !           409:                b64encode(p->ci_cert, p->ci_certlen);
        !           410:                printf("\n");
        !           411:                i++;
        !           412:        }
        !           413: 
        !           414:        freecertinfo(res);
        !           415: 
        !           416:        exit(0);
        !           417: }
        !           418: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>