Annotation of embedaddon/ntp/ntpd/ntp_crypto.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * ntp_crypto.c - NTP version 4 public key routines
        !             3:  */
        !             4: #ifdef HAVE_CONFIG_H
        !             5: #include <config.h>
        !             6: #endif
        !             7: 
        !             8: #ifdef OPENSSL
        !             9: #include <stdio.h>
        !            10: #include <sys/types.h>
        !            11: #include <sys/param.h>
        !            12: #include <unistd.h>
        !            13: #include <fcntl.h>
        !            14: 
        !            15: #include "ntpd.h"
        !            16: #include "ntp_stdlib.h"
        !            17: #include "ntp_unixtime.h"
        !            18: #include "ntp_string.h"
        !            19: #include "ntp_random.h"
        !            20: #include "ntp_assert.h"
        !            21: 
        !            22: #include "openssl/asn1_mac.h"
        !            23: #include "openssl/bn.h"
        !            24: #include "openssl/err.h"
        !            25: #include "openssl/evp.h"
        !            26: #include "openssl/pem.h"
        !            27: #include "openssl/rand.h"
        !            28: #include "openssl/x509v3.h"
        !            29: 
        !            30: #ifdef KERNEL_PLL
        !            31: #include "ntp_syscall.h"
        !            32: #endif /* KERNEL_PLL */
        !            33: 
        !            34: /*
        !            35:  * Extension field message format
        !            36:  *
        !            37:  * These are always signed and saved before sending in network byte
        !            38:  * order. They must be converted to and from host byte order for
        !            39:  * processing.
        !            40:  *
        !            41:  * +-------+-------+
        !            42:  * |   op  |  len  | <- extension pointer
        !            43:  * +-------+-------+
        !            44:  * |    associd    |
        !            45:  * +---------------+
        !            46:  * |   timestamp   | <- value pointer
        !            47:  * +---------------+
        !            48:  * |   filestamp   |
        !            49:  * +---------------+
        !            50:  * |   value len   |
        !            51:  * +---------------+
        !            52:  * |               |
        !            53:  * =     value     =
        !            54:  * |               |
        !            55:  * +---------------+
        !            56:  * | signature len |
        !            57:  * +---------------+
        !            58:  * |               |
        !            59:  * =   signature   =
        !            60:  * |               |
        !            61:  * +---------------+
        !            62:  *
        !            63:  * The CRYPTO_RESP bit is set to 0 for requests, 1 for responses.
        !            64:  * Requests carry the association ID of the receiver; responses carry
        !            65:  * the association ID of the sender. Some messages include only the
        !            66:  * operation/length and association ID words and so have length 8
        !            67:  * octets. Ohers include the value structure and associated value and
        !            68:  * signature fields. These messages include the timestamp, filestamp,
        !            69:  * value and signature words and so have length at least 24 octets. The
        !            70:  * signature and/or value fields can be empty, in which case the
        !            71:  * respective length words are zero. An empty value with nonempty
        !            72:  * signature is syntactically valid, but semantically questionable.
        !            73:  *
        !            74:  * The filestamp represents the time when a cryptographic data file such
        !            75:  * as a public/private key pair is created. It follows every reference
        !            76:  * depending on that file and serves as a means to obsolete earlier data
        !            77:  * of the same type. The timestamp represents the time when the
        !            78:  * cryptographic data of the message were last signed. Creation of a
        !            79:  * cryptographic data file or signing a message can occur only when the
        !            80:  * creator or signor is synchronized to an authoritative source and
        !            81:  * proventicated to a trusted authority.
        !            82:  *
        !            83:  * Note there are several conditions required for server trust. First,
        !            84:  * the public key on the server certificate must be verified, which can
        !            85:  * involve a hike along the certificate trail to a trusted host. Next,
        !            86:  * the server trust must be confirmed by one of several identity
        !            87:  * schemes. Valid cryptographic values are signed with attached
        !            88:  * timestamp and filestamp. Individual packet trust is confirmed
        !            89:  * relative to these values by a message digest with keys generated by a
        !            90:  * reverse-order pseudorandom hash.
        !            91:  *
        !            92:  * State decomposition. These flags are lit in the order given. They are
        !            93:  * dim only when the association is demobilized.
        !            94:  *
        !            95:  * CRYPTO_FLAG_ENAB    Lit upon acceptance of a CRYPTO_ASSOC message
        !            96:  * CRYPTO_FLAG_CERT    Lit when a self-digned trusted certificate is
        !            97:  *                     accepted.
        !            98:  * CRYPTO_FLAG_VRFY    Lit when identity is confirmed.
        !            99:  * CRYPTO_FLAG_PROV    Lit when the first signature is verified.
        !           100:  * CRYPTO_FLAG_COOK    Lit when a valid cookie is accepted.
        !           101:  * CRYPTO_FLAG_AUTO    Lit when valid autokey values are accepted.
        !           102:  * CRYPTO_FLAG_SIGN    Lit when the server signed certificate is
        !           103:  *                     accepted.
        !           104:  * CRYPTO_FLAG_LEAP    Lit when the leapsecond values are accepted.
        !           105:  */
        !           106: /*
        !           107:  * Cryptodefines
        !           108:  */
        !           109: #define TAI_1972       10      /* initial TAI offset (s) */
        !           110: #define MAX_LEAP       100     /* max UTC leapseconds (s) */
        !           111: #define VALUE_LEN      (6 * 4) /* min response field length */
        !           112: #define YEAR           (60 * 60 * 24 * 365) /* seconds in year */
        !           113: 
        !           114: /*
        !           115:  * Global cryptodata in host byte order
        !           116:  */
        !           117: u_int32        crypto_flags = 0x0;     /* status word */
        !           118: int    crypto_nid = KEY_TYPE_MD5; /* digest nid */
        !           119: char   *sys_hostname = NULL;   /* host name */
        !           120: char   *sys_groupname = NULL;  /* group name */
        !           121: 
        !           122: /*
        !           123:  * Global cryptodata in network byte order
        !           124:  */
        !           125: struct cert_info *cinfo = NULL;        /* certificate info/value cache */
        !           126: struct cert_info *cert_host = NULL; /* host certificate */
        !           127: struct pkey_info *pkinfo = NULL; /* key info/value cache */
        !           128: struct value hostval;          /* host value */
        !           129: struct value pubkey;           /* public key */
        !           130: struct value tai_leap;         /* leapseconds values */
        !           131: struct pkey_info *iffkey_info = NULL; /* IFF keys */
        !           132: struct pkey_info *gqkey_info = NULL; /* GQ keys */
        !           133: struct pkey_info *mvkey_info = NULL; /* MV keys */
        !           134: 
        !           135: /*
        !           136:  * Private cryptodata in host byte order
        !           137:  */
        !           138: static char *passwd = NULL;    /* private key password */
        !           139: static EVP_PKEY *host_pkey = NULL; /* host key */
        !           140: static EVP_PKEY *sign_pkey = NULL; /* sign key */
        !           141: static const EVP_MD *sign_digest = NULL; /* sign digest */
        !           142: static u_int sign_siglen;      /* sign key length */
        !           143: static char *rand_file = NULL; /* random seed file */
        !           144: 
        !           145: /*
        !           146:  * Cryptotypes
        !           147:  */
        !           148: static int     crypto_verify   (struct exten *, struct value *,
        !           149:                                    struct peer *);
        !           150: static int     crypto_encrypt  (struct exten *, struct value *,
        !           151:                                    keyid_t *);
        !           152: static int     crypto_alice    (struct peer *, struct value *);
        !           153: static int     crypto_alice2   (struct peer *, struct value *);
        !           154: static int     crypto_alice3   (struct peer *, struct value *);
        !           155: static int     crypto_bob      (struct exten *, struct value *);
        !           156: static int     crypto_bob2     (struct exten *, struct value *);
        !           157: static int     crypto_bob3     (struct exten *, struct value *);
        !           158: static int     crypto_iff      (struct exten *, struct peer *);
        !           159: static int     crypto_gq       (struct exten *, struct peer *);
        !           160: static int     crypto_mv       (struct exten *, struct peer *);
        !           161: static int     crypto_send     (struct exten *, struct value *, int);
        !           162: static tstamp_t crypto_time    (void);
        !           163: static u_long  asn2ntp         (ASN1_TIME *);
        !           164: static struct cert_info *cert_parse (u_char *, long, tstamp_t);
        !           165: static int     cert_sign       (struct exten *, struct value *);
        !           166: static struct cert_info *cert_install (struct exten *, struct peer *);
        !           167: static int     cert_hike       (struct peer *, struct cert_info *);
        !           168: static void    cert_free       (struct cert_info *);
        !           169: static struct pkey_info *crypto_key (char *, char *, sockaddr_u *);
        !           170: static void    bighash         (BIGNUM *, BIGNUM *);
        !           171: static struct cert_info *crypto_cert (char *);
        !           172: 
        !           173: #ifdef SYS_WINNT
        !           174: int
        !           175: readlink(char * link, char * file, int len) {
        !           176:        return (-1);
        !           177: }
        !           178: #endif
        !           179: 
        !           180: /*
        !           181:  * session_key - generate session key
        !           182:  *
        !           183:  * This routine generates a session key from the source address,
        !           184:  * destination address, key ID and private value. The value of the
        !           185:  * session key is the MD5 hash of these values, while the next key ID is
        !           186:  * the first four octets of the hash.
        !           187:  *
        !           188:  * Returns the next key ID or 0 if there is no destination address.
        !           189:  */
        !           190: keyid_t
        !           191: session_key(
        !           192:        sockaddr_u *srcadr,     /* source address */
        !           193:        sockaddr_u *dstadr,     /* destination address */
        !           194:        keyid_t keyno,          /* key ID */
        !           195:        keyid_t private,        /* private value */
        !           196:        u_long  lifetime        /* key lifetime */
        !           197:        )
        !           198: {
        !           199:        EVP_MD_CTX ctx;         /* message digest context */
        !           200:        u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
        !           201:        keyid_t keyid;          /* key identifer */
        !           202:        u_int32 header[10];     /* data in network byte order */
        !           203:        u_int   hdlen, len;
        !           204: 
        !           205:        if (!dstadr)
        !           206:                return 0;
        !           207:        
        !           208:        /*
        !           209:         * Generate the session key and key ID. If the lifetime is
        !           210:         * greater than zero, install the key and call it trusted.
        !           211:         */
        !           212:        hdlen = 0;
        !           213:        switch(AF(srcadr)) {
        !           214:        case AF_INET:
        !           215:                header[0] = NSRCADR(srcadr);
        !           216:                header[1] = NSRCADR(dstadr);
        !           217:                header[2] = htonl(keyno);
        !           218:                header[3] = htonl(private);
        !           219:                hdlen = 4 * sizeof(u_int32);
        !           220:                break;
        !           221: 
        !           222:        case AF_INET6:
        !           223:                memcpy(&header[0], PSOCK_ADDR6(srcadr),
        !           224:                    sizeof(struct in6_addr));
        !           225:                memcpy(&header[4], PSOCK_ADDR6(dstadr),
        !           226:                    sizeof(struct in6_addr));
        !           227:                header[8] = htonl(keyno);
        !           228:                header[9] = htonl(private);
        !           229:                hdlen = 10 * sizeof(u_int32);
        !           230:                break;
        !           231:        }
        !           232:        EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid));
        !           233:        EVP_DigestUpdate(&ctx, (u_char *)header, hdlen);
        !           234:        EVP_DigestFinal(&ctx, dgst, &len);
        !           235:        memcpy(&keyid, dgst, 4);
        !           236:        keyid = ntohl(keyid);
        !           237:        if (lifetime != 0) {
        !           238:                MD5auth_setkey(keyno, crypto_nid, dgst, len);
        !           239:                authtrust(keyno, lifetime);
        !           240:        }
        !           241:        DPRINTF(2, ("session_key: %s > %s %08x %08x hash %08x life %lu\n",
        !           242:                    stoa(srcadr), stoa(dstadr), keyno,
        !           243:                    private, keyid, lifetime));
        !           244: 
        !           245:        return (keyid);
        !           246: }
        !           247: 
        !           248: 
        !           249: /*
        !           250:  * make_keylist - generate key list
        !           251:  *
        !           252:  * Returns
        !           253:  * XEVNT_OK    success
        !           254:  * XEVNT_ERR   protocol error
        !           255:  *
        !           256:  * This routine constructs a pseudo-random sequence by repeatedly
        !           257:  * hashing the session key starting from a given source address,
        !           258:  * destination address, private value and the next key ID of the
        !           259:  * preceeding session key. The last entry on the list is saved along
        !           260:  * with its sequence number and public signature.
        !           261:  */
        !           262: int
        !           263: make_keylist(
        !           264:        struct peer *peer,      /* peer structure pointer */
        !           265:        struct interface *dstadr /* interface */
        !           266:        )
        !           267: {
        !           268:        EVP_MD_CTX ctx;         /* signature context */
        !           269:        tstamp_t tstamp;        /* NTP timestamp */
        !           270:        struct autokey *ap;     /* autokey pointer */
        !           271:        struct value *vp;       /* value pointer */
        !           272:        keyid_t keyid = 0;      /* next key ID */
        !           273:        keyid_t cookie;         /* private value */
        !           274:        long    lifetime;
        !           275:        u_int   len, mpoll;
        !           276:        int     i;
        !           277: 
        !           278:        if (!dstadr)
        !           279:                return XEVNT_ERR;
        !           280:        
        !           281:        /*
        !           282:         * Allocate the key list if necessary.
        !           283:         */
        !           284:        tstamp = crypto_time();
        !           285:        if (peer->keylist == NULL)
        !           286:                peer->keylist = emalloc(sizeof(keyid_t) *
        !           287:                    NTP_MAXSESSION);
        !           288: 
        !           289:        /*
        !           290:         * Generate an initial key ID which is unique and greater than
        !           291:         * NTP_MAXKEY.
        !           292:         */
        !           293:        while (1) {
        !           294:                keyid = ntp_random() & 0xffffffff;
        !           295:                if (keyid <= NTP_MAXKEY)
        !           296:                        continue;
        !           297: 
        !           298:                if (authhavekey(keyid))
        !           299:                        continue;
        !           300:                break;
        !           301:        }
        !           302: 
        !           303:        /*
        !           304:         * Generate up to NTP_MAXSESSION session keys. Stop if the
        !           305:         * next one would not be unique or not a session key ID or if
        !           306:         * it would expire before the next poll. The private value
        !           307:         * included in the hash is zero if broadcast mode, the peer
        !           308:         * cookie if client mode or the host cookie if symmetric modes.
        !           309:         */
        !           310:        mpoll = 1 << min(peer->ppoll, peer->hpoll);
        !           311:        lifetime = min(1 << sys_automax, NTP_MAXSESSION * mpoll);
        !           312:        if (peer->hmode == MODE_BROADCAST)
        !           313:                cookie = 0;
        !           314:        else
        !           315:                cookie = peer->pcookie;
        !           316:        for (i = 0; i < NTP_MAXSESSION; i++) {
        !           317:                peer->keylist[i] = keyid;
        !           318:                peer->keynumber = i;
        !           319:                keyid = session_key(&dstadr->sin, &peer->srcadr, keyid,
        !           320:                    cookie, lifetime + mpoll);
        !           321:                lifetime -= mpoll;
        !           322:                if (auth_havekey(keyid) || keyid <= NTP_MAXKEY ||
        !           323:                    lifetime < 0 || tstamp == 0)
        !           324:                        break;
        !           325:        }
        !           326: 
        !           327:        /*
        !           328:         * Save the last session key ID, sequence number and timestamp,
        !           329:         * then sign these values for later retrieval by the clients. Be
        !           330:         * careful not to use invalid key media. Use the public values
        !           331:         * timestamp as filestamp. 
        !           332:         */
        !           333:        vp = &peer->sndval;
        !           334:        if (vp->ptr == NULL)
        !           335:                vp->ptr = emalloc(sizeof(struct autokey));
        !           336:        ap = (struct autokey *)vp->ptr;
        !           337:        ap->seq = htonl(peer->keynumber);
        !           338:        ap->key = htonl(keyid);
        !           339:        vp->tstamp = htonl(tstamp);
        !           340:        vp->fstamp = hostval.tstamp;
        !           341:        vp->vallen = htonl(sizeof(struct autokey));
        !           342:        vp->siglen = 0;
        !           343:        if (tstamp != 0) {
        !           344:                if (vp->sig == NULL)
        !           345:                        vp->sig = emalloc(sign_siglen);
        !           346:                EVP_SignInit(&ctx, sign_digest);
        !           347:                EVP_SignUpdate(&ctx, (u_char *)vp, 12);
        !           348:                EVP_SignUpdate(&ctx, vp->ptr, sizeof(struct autokey));
        !           349:                if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) {
        !           350:                        vp->siglen = htonl(sign_siglen);
        !           351:                        peer->flags |= FLAG_ASSOC;
        !           352:                }
        !           353:        }
        !           354: #ifdef DEBUG
        !           355:        if (debug)
        !           356:                printf("make_keys: %d %08x %08x ts %u fs %u poll %d\n",
        !           357:                    peer->keynumber, keyid, cookie, ntohl(vp->tstamp),
        !           358:                    ntohl(vp->fstamp), peer->hpoll);
        !           359: #endif
        !           360:        return (XEVNT_OK);
        !           361: }
        !           362: 
        !           363: 
        !           364: /*
        !           365:  * crypto_recv - parse extension fields
        !           366:  *
        !           367:  * This routine is called when the packet has been matched to an
        !           368:  * association and passed sanity, format and MAC checks. We believe the
        !           369:  * extension field values only if the field has proper format and
        !           370:  * length, the timestamp and filestamp are valid and the signature has
        !           371:  * valid length and is verified. There are a few cases where some values
        !           372:  * are believed even if the signature fails, but only if the proventic
        !           373:  * bit is not set.
        !           374:  *
        !           375:  * Returns
        !           376:  * XEVNT_OK    success
        !           377:  * XEVNT_ERR   protocol error
        !           378:  * XEVNT_LEN   bad field format or length
        !           379:  */
        !           380: int
        !           381: crypto_recv(
        !           382:        struct peer *peer,      /* peer structure pointer */
        !           383:        struct recvbuf *rbufp   /* packet buffer pointer */
        !           384:        )
        !           385: {
        !           386:        const EVP_MD *dp;       /* message digest algorithm */
        !           387:        u_int32 *pkt;           /* receive packet pointer */
        !           388:        struct autokey *ap, *bp; /* autokey pointer */
        !           389:        struct exten *ep, *fp;  /* extension pointers */
        !           390:        struct cert_info *xinfo; /* certificate info pointer */
        !           391:        int     has_mac;        /* length of MAC field */
        !           392:        int     authlen;        /* offset of MAC field */
        !           393:        associd_t associd;      /* association ID */
        !           394:        tstamp_t tstamp = 0;    /* timestamp */
        !           395:        tstamp_t fstamp = 0;    /* filestamp */
        !           396:        u_int   len;            /* extension field length */
        !           397:        u_int   code;           /* extension field opcode */
        !           398:        u_int   vallen = 0;     /* value length */
        !           399:        X509    *cert;          /* X509 certificate */
        !           400:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !           401:        keyid_t cookie;         /* crumbles */
        !           402:        int     hismode;        /* packet mode */
        !           403:        int     rval = XEVNT_OK;
        !           404:        u_char  *ptr;
        !           405:        u_int32 temp32;
        !           406: 
        !           407:        /*
        !           408:         * Initialize. Note that the packet has already been checked for
        !           409:         * valid format and extension field lengths. First extract the
        !           410:         * field length, command code and association ID in host byte
        !           411:         * order. These are used with all commands and modes. Then check
        !           412:         * the version number, which must be 2, and length, which must
        !           413:         * be at least 8 for requests and VALUE_LEN (24) for responses.
        !           414:         * Packets that fail either test sink without a trace. The
        !           415:         * association ID is saved only if nonzero.
        !           416:         */
        !           417:        authlen = LEN_PKT_NOMAC;
        !           418:        hismode = (int)PKT_MODE((&rbufp->recv_pkt)->li_vn_mode);
        !           419:        while ((has_mac = rbufp->recv_length - authlen) > MAX_MAC_LEN) {
        !           420:                pkt = (u_int32 *)&rbufp->recv_pkt + authlen / 4;
        !           421:                ep = (struct exten *)pkt;
        !           422:                code = ntohl(ep->opcode) & 0xffff0000;
        !           423:                len = ntohl(ep->opcode) & 0x0000ffff;
        !           424:                associd = (associd_t)ntohl(pkt[1]);
        !           425:                rval = XEVNT_OK;
        !           426: #ifdef DEBUG
        !           427:                if (debug)
        !           428:                        printf(
        !           429:                            "crypto_recv: flags 0x%x ext offset %d len %u code 0x%x associd %d\n",
        !           430:                            peer->crypto, authlen, len, code >> 16,
        !           431:                            associd);
        !           432: #endif
        !           433: 
        !           434:                /*
        !           435:                 * Check version number and field length. If bad,
        !           436:                 * quietly ignore the packet.
        !           437:                 */
        !           438:                if (((code >> 24) & 0x3f) != CRYPTO_VN || len < 8) {
        !           439:                        sys_badlength++;
        !           440:                        code |= CRYPTO_ERROR;
        !           441:                }
        !           442: 
        !           443:                if (len >= VALUE_LEN) {
        !           444:                        tstamp = ntohl(ep->tstamp);
        !           445:                        fstamp = ntohl(ep->fstamp);
        !           446:                        vallen = ntohl(ep->vallen);
        !           447:                }
        !           448:                switch (code) {
        !           449: 
        !           450:                /*
        !           451:                 * Install status word, host name, signature scheme and
        !           452:                 * association ID. In OpenSSL the signature algorithm is
        !           453:                 * bound to the digest algorithm, so the NID completely
        !           454:                 * defines the signature scheme. Note the request and
        !           455:                 * response are identical, but neither is validated by
        !           456:                 * signature. The request is processed here only in
        !           457:                 * symmetric modes. The server name field might be
        !           458:                 * useful to implement access controls in future.
        !           459:                 */
        !           460:                case CRYPTO_ASSOC:
        !           461: 
        !           462:                        /*
        !           463:                         * If our state machine is running when this
        !           464:                         * message arrives, the other fellow might have
        !           465:                         * restarted. However, this could be an
        !           466:                         * intruder, so just clamp the poll interval and
        !           467:                         * find out for ourselves. Otherwise, pass the
        !           468:                         * extension field to the transmit side.
        !           469:                         */
        !           470:                        if (peer->crypto & CRYPTO_FLAG_CERT) {
        !           471:                                rval = XEVNT_ERR;
        !           472:                                break;
        !           473:                        }
        !           474:                        if (peer->cmmd) {
        !           475:                                if (peer->assoc != associd) {
        !           476:                                        rval = XEVNT_ERR;
        !           477:                                        break;
        !           478:                                }
        !           479:                        }
        !           480:                        fp = emalloc(len);
        !           481:                        memcpy(fp, ep, len);
        !           482:                        fp->associd = htonl(peer->associd);
        !           483:                        peer->cmmd = fp;
        !           484:                        /* fall through */
        !           485: 
        !           486:                case CRYPTO_ASSOC | CRYPTO_RESP:
        !           487: 
        !           488:                        /*
        !           489:                         * Discard the message if it has already been
        !           490:                         * stored or the message has been amputated.
        !           491:                         */
        !           492:                        if (peer->crypto) {
        !           493:                                if (peer->assoc != associd)
        !           494:                                        rval = XEVNT_ERR;
        !           495:                                break;
        !           496:                        }
        !           497:                        if (vallen == 0 || vallen > MAXHOSTNAME ||
        !           498:                            len < VALUE_LEN + vallen) {
        !           499:                                rval = XEVNT_LEN;
        !           500:                                break;
        !           501:                        }
        !           502: #ifdef DEBUG
        !           503:                        if (debug)
        !           504:                                printf(
        !           505:                                    "crypto_recv: ident host 0x%x %d server 0x%x %d\n",
        !           506:                                    crypto_flags, peer->associd, fstamp,
        !           507:                                    peer->assoc);
        !           508: #endif
        !           509:                        temp32 = crypto_flags & CRYPTO_FLAG_MASK;
        !           510: 
        !           511:                        /*
        !           512:                         * If the client scheme is PC, the server scheme
        !           513:                         * must be PC. The public key and identity are
        !           514:                         * presumed valid, so we skip the certificate
        !           515:                         * and identity exchanges and move immediately
        !           516:                         * to the cookie exchange which confirms the
        !           517:                         * server signature.
        !           518:                         */
        !           519:                        if (crypto_flags & CRYPTO_FLAG_PRIV) {
        !           520:                                if (!(fstamp & CRYPTO_FLAG_PRIV)) {
        !           521:                                        rval = XEVNT_KEY;
        !           522:                                        break;
        !           523:                                }
        !           524:                                fstamp |= CRYPTO_FLAG_CERT |
        !           525:                                    CRYPTO_FLAG_VRFY | CRYPTO_FLAG_SIGN;
        !           526: 
        !           527:                        /*
        !           528:                         * It is an error if either peer supports
        !           529:                         * identity, but the other does not.
        !           530:                         */
        !           531:                        } else if (hismode == MODE_ACTIVE || hismode ==
        !           532:                            MODE_PASSIVE) {
        !           533:                                if ((temp32 && !(fstamp &
        !           534:                                    CRYPTO_FLAG_MASK)) ||
        !           535:                                    (!temp32 && (fstamp &
        !           536:                                    CRYPTO_FLAG_MASK))) {
        !           537:                                        rval = XEVNT_KEY;
        !           538:                                        break;
        !           539:                                }
        !           540:                        }
        !           541: 
        !           542:                        /*
        !           543:                         * Discard the message if the signature digest
        !           544:                         * NID is not supported.
        !           545:                         */
        !           546:                        temp32 = (fstamp >> 16) & 0xffff;
        !           547:                        dp =
        !           548:                            (const EVP_MD *)EVP_get_digestbynid(temp32);
        !           549:                        if (dp == NULL) {
        !           550:                                rval = XEVNT_MD;
        !           551:                                break;
        !           552:                        }
        !           553: 
        !           554:                        /*
        !           555:                         * Save status word, host name and message
        !           556:                         * digest/signature type. If this is from a
        !           557:                         * broadcast and the association ID has changed,
        !           558:                         * request the autokey values.
        !           559:                         */
        !           560:                        peer->assoc = associd;
        !           561:                        if (hismode == MODE_SERVER)
        !           562:                                fstamp |= CRYPTO_FLAG_AUTO;
        !           563:                        if (!(fstamp & CRYPTO_FLAG_TAI))
        !           564:                                fstamp |= CRYPTO_FLAG_LEAP;
        !           565:                        RAND_bytes((u_char *)&peer->hcookie, 4);
        !           566:                        peer->crypto = fstamp;
        !           567:                        peer->digest = dp;
        !           568:                        if (peer->subject != NULL)
        !           569:                                free(peer->subject);
        !           570:                        peer->subject = emalloc(vallen + 1);
        !           571:                        memcpy(peer->subject, ep->pkt, vallen);
        !           572:                        peer->subject[vallen] = '\0';
        !           573:                        if (peer->issuer != NULL)
        !           574:                                free(peer->issuer);
        !           575:                        peer->issuer = emalloc(vallen + 1);
        !           576:                        strcpy(peer->issuer, peer->subject);
        !           577:                        snprintf(statstr, NTP_MAXSTRLEN,
        !           578:                            "assoc %d %d host %s %s", peer->associd,
        !           579:                            peer->assoc, peer->subject,
        !           580:                            OBJ_nid2ln(temp32));
        !           581:                        record_crypto_stats(&peer->srcadr, statstr);
        !           582: #ifdef DEBUG
        !           583:                        if (debug)
        !           584:                                printf("crypto_recv: %s\n", statstr);
        !           585: #endif
        !           586:                        break;
        !           587: 
        !           588:                /*
        !           589:                 * Decode X509 certificate in ASN.1 format and extract
        !           590:                 * the data containing, among other things, subject
        !           591:                 * name and public key. In the default identification
        !           592:                 * scheme, the certificate trail is followed to a self
        !           593:                 * signed trusted certificate.
        !           594:                 */
        !           595:                case CRYPTO_CERT | CRYPTO_RESP:
        !           596: 
        !           597:                        /*
        !           598:                         * Discard the message if empty or invalid.
        !           599:                         */
        !           600:                        if (len < VALUE_LEN)
        !           601:                                break;
        !           602: 
        !           603:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           604:                            XEVNT_OK)
        !           605:                                break;
        !           606: 
        !           607:                        /*
        !           608:                         * Scan the certificate list to delete old
        !           609:                         * versions and link the newest version first on
        !           610:                         * the list. Then, verify the signature. If the
        !           611:                         * certificate is bad or missing, just ignore
        !           612:                         * it.
        !           613:                         */
        !           614:                        if ((xinfo = cert_install(ep, peer)) == NULL) {
        !           615:                                rval = XEVNT_CRT;
        !           616:                                break;
        !           617:                        }
        !           618:                        if ((rval = cert_hike(peer, xinfo)) != XEVNT_OK)
        !           619:                                break;
        !           620: 
        !           621:                        /*
        !           622:                         * We plug in the public key and lifetime from
        !           623:                         * the first certificate received. However, note
        !           624:                         * that this certificate might not be signed by
        !           625:                         * the server, so we can't check the
        !           626:                         * signature/digest NID.
        !           627:                         */
        !           628:                        if (peer->pkey == NULL) {
        !           629:                                ptr = (u_char *)xinfo->cert.ptr;
        !           630:                                cert = d2i_X509(NULL, &ptr,
        !           631:                                    ntohl(xinfo->cert.vallen));
        !           632:                                peer->pkey = X509_get_pubkey(cert);
        !           633:                                X509_free(cert);
        !           634:                        }
        !           635:                        peer->flash &= ~TEST8;
        !           636:                        temp32 = xinfo->nid;
        !           637:                        snprintf(statstr, NTP_MAXSTRLEN,
        !           638:                            "cert %s %s 0x%x %s (%u) fs %u",
        !           639:                            xinfo->subject, xinfo->issuer, xinfo->flags,
        !           640:                            OBJ_nid2ln(temp32), temp32,
        !           641:                            ntohl(ep->fstamp));
        !           642:                        record_crypto_stats(&peer->srcadr, statstr);
        !           643: #ifdef DEBUG
        !           644:                        if (debug)
        !           645:                                printf("crypto_recv: %s\n", statstr);
        !           646: #endif
        !           647:                        break;
        !           648: 
        !           649:                /*
        !           650:                 * Schnorr (IFF) identity scheme. This scheme is
        !           651:                 * designed for use with shared secret server group keys
        !           652:                 * and where the certificate may be generated by a third
        !           653:                 * party. The client sends a challenge to the server,
        !           654:                 * which performs a calculation and returns the result.
        !           655:                 * A positive result is possible only if both client and
        !           656:                 * server contain the same secret group key.
        !           657:                 */
        !           658:                case CRYPTO_IFF | CRYPTO_RESP:
        !           659: 
        !           660:                        /*
        !           661:                         * Discard the message if invalid.
        !           662:                         */
        !           663:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           664:                            XEVNT_OK)
        !           665:                                break;
        !           666: 
        !           667:                        /*
        !           668:                         * If the challenge matches the response, the
        !           669:                         * server public key, signature and identity are
        !           670:                         * all verified at the same time. The server is
        !           671:                         * declared trusted, so we skip further
        !           672:                         * certificate exchanges and move immediately to
        !           673:                         * the cookie exchange.
        !           674:                         */
        !           675:                        if ((rval = crypto_iff(ep, peer)) != XEVNT_OK)
        !           676:                                break;
        !           677: 
        !           678:                        peer->crypto |= CRYPTO_FLAG_VRFY;
        !           679:                        peer->flash &= ~TEST8;
        !           680:                        snprintf(statstr, NTP_MAXSTRLEN, "iff %s fs %u",
        !           681:                            peer->issuer, ntohl(ep->fstamp));
        !           682:                        record_crypto_stats(&peer->srcadr, statstr);
        !           683: #ifdef DEBUG
        !           684:                        if (debug)
        !           685:                                printf("crypto_recv: %s\n", statstr);
        !           686: #endif
        !           687:                        break;
        !           688: 
        !           689:                /*
        !           690:                 * Guillou-Quisquater (GQ) identity scheme. This scheme
        !           691:                 * is designed for use with public certificates carrying
        !           692:                 * the GQ public key in an extension field. The client
        !           693:                 * sends a challenge to the server, which performs a
        !           694:                 * calculation and returns the result. A positive result
        !           695:                 * is possible only if both client and server contain
        !           696:                 * the same group key and the server has the matching GQ
        !           697:                 * private key.
        !           698:                 */
        !           699:                case CRYPTO_GQ | CRYPTO_RESP:
        !           700: 
        !           701:                        /*
        !           702:                         * Discard the message if invalid
        !           703:                         */
        !           704:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           705:                            XEVNT_OK)
        !           706:                                break;
        !           707: 
        !           708:                        /*
        !           709:                         * If the challenge matches the response, the
        !           710:                         * server public key, signature and identity are
        !           711:                         * all verified at the same time. The server is
        !           712:                         * declared trusted, so we skip further
        !           713:                         * certificate exchanges and move immediately to
        !           714:                         * the cookie exchange.
        !           715:                         */
        !           716:                        if ((rval = crypto_gq(ep, peer)) != XEVNT_OK)
        !           717:                                break;
        !           718: 
        !           719:                        peer->crypto |= CRYPTO_FLAG_VRFY;
        !           720:                        peer->flash &= ~TEST8;
        !           721:                        snprintf(statstr, NTP_MAXSTRLEN, "gq %s fs %u",
        !           722:                            peer->issuer, ntohl(ep->fstamp));
        !           723:                        record_crypto_stats(&peer->srcadr, statstr);
        !           724: #ifdef DEBUG
        !           725:                        if (debug)
        !           726:                                printf("crypto_recv: %s\n", statstr);
        !           727: #endif
        !           728:                        break;
        !           729: 
        !           730:                /*
        !           731:                 * Mu-Varadharajan (MV) identity scheme. This scheme is
        !           732:                 * designed for use with three levels of trust, trusted
        !           733:                 * host, server and client. The trusted host key is
        !           734:                 * opaque to servers and clients; the server keys are
        !           735:                 * opaque to clients and each client key is different.
        !           736:                 * Client keys can be revoked without requiring new key
        !           737:                 * generations.
        !           738:                 */
        !           739:                case CRYPTO_MV | CRYPTO_RESP:
        !           740: 
        !           741:                        /*
        !           742:                         * Discard the message if invalid.
        !           743:                         */
        !           744:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           745:                            XEVNT_OK)
        !           746:                                break;
        !           747: 
        !           748:                        /*
        !           749:                         * If the challenge matches the response, the
        !           750:                         * server public key, signature and identity are
        !           751:                         * all verified at the same time. The server is
        !           752:                         * declared trusted, so we skip further
        !           753:                         * certificate exchanges and move immediately to
        !           754:                         * the cookie exchange.
        !           755:                         */
        !           756:                        if ((rval = crypto_mv(ep, peer)) != XEVNT_OK)
        !           757:                                break;
        !           758: 
        !           759:                        peer->crypto |= CRYPTO_FLAG_VRFY;
        !           760:                        peer->flash &= ~TEST8;
        !           761:                        snprintf(statstr, NTP_MAXSTRLEN, "mv %s fs %u",
        !           762:                            peer->issuer, ntohl(ep->fstamp));
        !           763:                        record_crypto_stats(&peer->srcadr, statstr);
        !           764: #ifdef DEBUG
        !           765:                        if (debug)
        !           766:                                printf("crypto_recv: %s\n", statstr);
        !           767: #endif
        !           768:                        break;
        !           769: 
        !           770: 
        !           771:                /*
        !           772:                 * Cookie response in client and symmetric modes. If the
        !           773:                 * cookie bit is set, the working cookie is the EXOR of
        !           774:                 * the current and new values.
        !           775:                 */
        !           776:                case CRYPTO_COOK | CRYPTO_RESP:
        !           777: 
        !           778:                        /*
        !           779:                         * Discard the message if invalid or signature
        !           780:                         * not verified with respect to the cookie
        !           781:                         * values.
        !           782:                         */
        !           783:                        if ((rval = crypto_verify(ep, &peer->cookval,
        !           784:                            peer)) != XEVNT_OK)
        !           785:                                break;
        !           786: 
        !           787:                        /*
        !           788:                         * Decrypt the cookie, hunting all the time for
        !           789:                         * errors.
        !           790:                         */
        !           791:                        if (vallen == (u_int)EVP_PKEY_size(host_pkey)) {
        !           792:                                if (RSA_private_decrypt(vallen,
        !           793:                                    (u_char *)ep->pkt,
        !           794:                                    (u_char *)&temp32,
        !           795:                                    host_pkey->pkey.rsa,
        !           796:                                    RSA_PKCS1_OAEP_PADDING) <= 0) {
        !           797:                                        rval = XEVNT_CKY;
        !           798:                                        break;
        !           799:                                } else {
        !           800:                                        cookie = ntohl(temp32);
        !           801:                                }
        !           802:                        } else {
        !           803:                                rval = XEVNT_CKY;
        !           804:                                break;
        !           805:                        }
        !           806: 
        !           807:                        /*
        !           808:                         * Install cookie values and light the cookie
        !           809:                         * bit. If this is not broadcast client mode, we
        !           810:                         * are done here.
        !           811:                         */
        !           812:                        key_expire(peer);
        !           813:                        if (hismode == MODE_ACTIVE || hismode ==
        !           814:                            MODE_PASSIVE)
        !           815:                                peer->pcookie = peer->hcookie ^ cookie;
        !           816:                        else
        !           817:                                peer->pcookie = cookie;
        !           818:                        peer->crypto |= CRYPTO_FLAG_COOK;
        !           819:                        peer->flash &= ~TEST8;
        !           820:                        snprintf(statstr, NTP_MAXSTRLEN,
        !           821:                            "cook %x ts %u fs %u", peer->pcookie,
        !           822:                            ntohl(ep->tstamp), ntohl(ep->fstamp));
        !           823:                        record_crypto_stats(&peer->srcadr, statstr);
        !           824: #ifdef DEBUG
        !           825:                        if (debug)
        !           826:                                printf("crypto_recv: %s\n", statstr);
        !           827: #endif
        !           828:                        break;
        !           829: 
        !           830:                /*
        !           831:                 * Install autokey values in broadcast client and
        !           832:                 * symmetric modes. We have to do this every time the
        !           833:                 * sever/peer cookie changes or a new keylist is
        !           834:                 * rolled. Ordinarily, this is automatic as this message
        !           835:                 * is piggybacked on the first NTP packet sent upon
        !           836:                 * either of these events. Note that a broadcast client
        !           837:                 * or symmetric peer can receive this response without a
        !           838:                 * matching request.
        !           839:                 */
        !           840:                case CRYPTO_AUTO | CRYPTO_RESP:
        !           841: 
        !           842:                        /*
        !           843:                         * Discard the message if invalid or signature
        !           844:                         * not verified with respect to the receive
        !           845:                         * autokey values.
        !           846:                         */
        !           847:                        if ((rval = crypto_verify(ep, &peer->recval,
        !           848:                            peer)) != XEVNT_OK) 
        !           849:                                break;
        !           850: 
        !           851:                        /*
        !           852:                         * Discard the message if a broadcast client and
        !           853:                         * the association ID does not match. This might
        !           854:                         * happen if a broacast server restarts the
        !           855:                         * protocol. A protocol restart will occur at
        !           856:                         * the next ASSOC message.
        !           857:                         */
        !           858:                        if ((peer->cast_flags & MDF_BCLNT) &&
        !           859:                            peer->assoc != associd)
        !           860:                                break;
        !           861: 
        !           862:                        /*
        !           863:                         * Install autokey values and light the
        !           864:                         * autokey bit. This is not hard.
        !           865:                         */
        !           866:                        if (ep->tstamp == 0)
        !           867:                                break;
        !           868: 
        !           869:                        if (peer->recval.ptr == NULL)
        !           870:                                peer->recval.ptr =
        !           871:                                    emalloc(sizeof(struct autokey));
        !           872:                        bp = (struct autokey *)peer->recval.ptr;
        !           873:                        peer->recval.tstamp = ep->tstamp;
        !           874:                        peer->recval.fstamp = ep->fstamp;
        !           875:                        ap = (struct autokey *)ep->pkt;
        !           876:                        bp->seq = ntohl(ap->seq);
        !           877:                        bp->key = ntohl(ap->key);
        !           878:                        peer->pkeyid = bp->key;
        !           879:                        peer->crypto |= CRYPTO_FLAG_AUTO;
        !           880:                        peer->flash &= ~TEST8;
        !           881:                        snprintf(statstr, NTP_MAXSTRLEN, 
        !           882:                            "auto seq %d key %x ts %u fs %u", bp->seq,
        !           883:                            bp->key, ntohl(ep->tstamp),
        !           884:                            ntohl(ep->fstamp));
        !           885:                        record_crypto_stats(&peer->srcadr, statstr);
        !           886: #ifdef DEBUG
        !           887:                        if (debug)
        !           888:                                printf("crypto_recv: %s\n", statstr);
        !           889: #endif
        !           890:                        break;
        !           891:        
        !           892:                /*
        !           893:                 * X509 certificate sign response. Validate the
        !           894:                 * certificate signed by the server and install. Later
        !           895:                 * this can be provided to clients of this server in
        !           896:                 * lieu of the self signed certificate in order to
        !           897:                 * validate the public key.
        !           898:                 */
        !           899:                case CRYPTO_SIGN | CRYPTO_RESP:
        !           900: 
        !           901:                        /*
        !           902:                         * Discard the message if invalid.
        !           903:                         */
        !           904:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           905:                            XEVNT_OK)
        !           906:                                break;
        !           907: 
        !           908:                        /*
        !           909:                         * Scan the certificate list to delete old
        !           910:                         * versions and link the newest version first on
        !           911:                         * the list.
        !           912:                         */
        !           913:                        if ((xinfo = cert_install(ep, peer)) == NULL) {
        !           914:                                rval = XEVNT_CRT;
        !           915:                                break;
        !           916:                        }
        !           917:                        peer->crypto |= CRYPTO_FLAG_SIGN;
        !           918:                        peer->flash &= ~TEST8;
        !           919:                        temp32 = xinfo->nid;
        !           920:                        snprintf(statstr, NTP_MAXSTRLEN,
        !           921:                            "sign %s %s 0x%x %s (%u) fs %u",
        !           922:                            xinfo->subject, xinfo->issuer, xinfo->flags,
        !           923:                            OBJ_nid2ln(temp32), temp32,
        !           924:                            ntohl(ep->fstamp));
        !           925:                        record_crypto_stats(&peer->srcadr, statstr);
        !           926: #ifdef DEBUG
        !           927:                        if (debug)
        !           928:                                printf("crypto_recv: %s\n", statstr);
        !           929: #endif
        !           930:                        break;
        !           931: 
        !           932:                /*
        !           933:                 * Install leapseconds values. While the leapsecond
        !           934:                 * values epoch, TAI offset and values expiration epoch
        !           935:                 * are retained, only the current TAI offset is provided
        !           936:                 * via the kernel to other applications.
        !           937:                 */
        !           938:                case CRYPTO_LEAP | CRYPTO_RESP:
        !           939: 
        !           940:                        /*
        !           941:                         * Discard the message if invalid. We can't
        !           942:                         * compare the value timestamps here, as they
        !           943:                         * can be updated by different servers.
        !           944:                         */
        !           945:                        if ((rval = crypto_verify(ep, NULL, peer)) !=
        !           946:                            XEVNT_OK)
        !           947:                                break;
        !           948: 
        !           949:                        /*
        !           950:                         * If the packet leap values are more recent
        !           951:                         * than the stored ones, install the new leap
        !           952:                         * values and recompute the signatures.
        !           953:                         */
        !           954:                        if (ntohl(ep->pkt[2]) > leap_expire) {
        !           955:                                char    tbuf[80], str1 [20], str2[20];
        !           956: 
        !           957:                                tai_leap.tstamp = ep->tstamp;
        !           958:                                tai_leap.fstamp = ep->fstamp;
        !           959:                                tai_leap.vallen = ep->vallen;
        !           960:                                leap_tai = ntohl(ep->pkt[0]);
        !           961:                                leap_sec = ntohl(ep->pkt[1]);
        !           962:                                leap_expire = ntohl(ep->pkt[2]);
        !           963:                                crypto_update();
        !           964:                                strcpy(str1, fstostr(leap_sec));
        !           965:                                strcpy(str2, fstostr(leap_expire));
        !           966:                                snprintf(tbuf, sizeof(tbuf),
        !           967:                                    "%d leap %s expire %s", leap_tai, str1,
        !           968:                                    str2);
        !           969:                                    report_event(EVNT_TAI, peer, tbuf);
        !           970:                        }
        !           971:                        peer->crypto |= CRYPTO_FLAG_LEAP;
        !           972:                        peer->flash &= ~TEST8;
        !           973:                        snprintf(statstr, NTP_MAXSTRLEN,
        !           974:                            "leap TAI offset %d at %u expire %u fs %u",
        !           975:                            ntohl(ep->pkt[0]), ntohl(ep->pkt[1]),
        !           976:                            ntohl(ep->pkt[2]), ntohl(ep->fstamp));
        !           977:                        record_crypto_stats(&peer->srcadr, statstr);
        !           978: #ifdef DEBUG
        !           979:                        if (debug)
        !           980:                                printf("crypto_recv: %s\n", statstr);
        !           981: #endif
        !           982:                        break;
        !           983: 
        !           984:                /*
        !           985:                 * We come here in symmetric modes for miscellaneous
        !           986:                 * commands that have value fields but are processed on
        !           987:                 * the transmit side. All we need do here is check for
        !           988:                 * valid field length. Note that ASSOC is handled
        !           989:                 * separately.
        !           990:                 */
        !           991:                case CRYPTO_CERT:
        !           992:                case CRYPTO_IFF:
        !           993:                case CRYPTO_GQ:
        !           994:                case CRYPTO_MV:
        !           995:                case CRYPTO_COOK:
        !           996:                case CRYPTO_SIGN:
        !           997:                        if (len < VALUE_LEN) {
        !           998:                                rval = XEVNT_LEN;
        !           999:                                break;
        !          1000:                        }
        !          1001:                        /* fall through */
        !          1002: 
        !          1003:                /*
        !          1004:                 * We come here in symmetric modes for requests
        !          1005:                 * requiring a response (above plus AUTO and LEAP) and
        !          1006:                 * for responses. If a request, save the extension field
        !          1007:                 * for later; invalid requests will be caught on the
        !          1008:                 * transmit side. If an error or invalid response,
        !          1009:                 * declare a protocol error.
        !          1010:                 */
        !          1011:                default:
        !          1012:                        if (code & (CRYPTO_RESP | CRYPTO_ERROR)) {
        !          1013:                                rval = XEVNT_ERR;
        !          1014:                        } else if (peer->cmmd == NULL) {
        !          1015:                                fp = emalloc(len);
        !          1016:                                memcpy(fp, ep, len);
        !          1017:                                peer->cmmd = fp;
        !          1018:                        }
        !          1019:                }
        !          1020: 
        !          1021:                /*
        !          1022:                 * The first error found terminates the extension field
        !          1023:                 * scan and we return the laundry to the caller.
        !          1024:                 */
        !          1025:                if (rval != XEVNT_OK) {
        !          1026:                        snprintf(statstr, NTP_MAXSTRLEN,
        !          1027:                            "%04x %d %02x %s", htonl(ep->opcode),
        !          1028:                            associd, rval, eventstr(rval));
        !          1029:                        record_crypto_stats(&peer->srcadr, statstr);
        !          1030: #ifdef DEBUG
        !          1031:                        if (debug)
        !          1032:                                printf("crypto_recv: %s\n", statstr);
        !          1033: #endif
        !          1034:                        return (rval);
        !          1035:                }
        !          1036:                authlen += (len + 3) / 4 * 4;
        !          1037:        }
        !          1038:        return (rval);
        !          1039: }
        !          1040: 
        !          1041: 
        !          1042: /*
        !          1043:  * crypto_xmit - construct extension fields
        !          1044:  *
        !          1045:  * This routine is called both when an association is configured and
        !          1046:  * when one is not. The only case where this matters is to retrieve the
        !          1047:  * autokey information, in which case the caller has to provide the
        !          1048:  * association ID to match the association.
        !          1049:  *
        !          1050:  * Side effect: update the packet offset.
        !          1051:  *
        !          1052:  * Errors
        !          1053:  * XEVNT_OK    success
        !          1054:  * XEVNT_CRT   bad or missing certificate
        !          1055:  * XEVNT_ERR   protocol error
        !          1056:  * XEVNT_LEN   bad field format or length
        !          1057:  * XEVNT_PER   host certificate expired
        !          1058:  */
        !          1059: int
        !          1060: crypto_xmit(
        !          1061:        struct peer *peer,      /* peer structure pointer */
        !          1062:        struct pkt *xpkt,       /* transmit packet pointer */
        !          1063:        struct recvbuf *rbufp,  /* receive buffer pointer */
        !          1064:        int     start,          /* offset to extension field */
        !          1065:        struct exten *ep,       /* extension pointer */
        !          1066:        keyid_t cookie          /* session cookie */
        !          1067:        )
        !          1068: {
        !          1069:        struct exten *fp;       /* extension pointers */
        !          1070:        struct cert_info *cp, *xp, *yp; /* cert info/value pointer */
        !          1071:        sockaddr_u *srcadr_sin; /* source address */
        !          1072:        u_int32 *pkt;           /* packet pointer */
        !          1073:        u_int   opcode;         /* extension field opcode */
        !          1074:        char    certname[MAXHOSTNAME + 1]; /* subject name buffer */
        !          1075:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !          1076:        tstamp_t tstamp;
        !          1077:        u_int   vallen;
        !          1078:        struct value vtemp;
        !          1079:        associd_t associd;
        !          1080:        int     rval;
        !          1081:        int     len;
        !          1082:        keyid_t tcookie;
        !          1083: 
        !          1084:        /*
        !          1085:         * Generate the requested extension field request code, length
        !          1086:         * and association ID. If this is a response and the host is not
        !          1087:         * synchronized, light the error bit and go home.
        !          1088:         */
        !          1089:        pkt = (u_int32 *)xpkt + start / 4;
        !          1090:        fp = (struct exten *)pkt;
        !          1091:        opcode = ntohl(ep->opcode);
        !          1092:        if (peer != NULL) {
        !          1093:                srcadr_sin = &peer->srcadr;
        !          1094:                if (!(opcode & CRYPTO_RESP))
        !          1095:                        peer->opcode = ep->opcode;
        !          1096:        } else {
        !          1097:                srcadr_sin = &rbufp->recv_srcadr;
        !          1098:        }
        !          1099:        associd = (associd_t) ntohl(ep->associd);
        !          1100:        len = 8;
        !          1101:        fp->opcode = htonl((opcode & 0xffff0000) | len);
        !          1102:        fp->associd = ep->associd;
        !          1103:        rval = XEVNT_OK;
        !          1104:        tstamp = crypto_time();
        !          1105:        switch (opcode & 0xffff0000) {
        !          1106: 
        !          1107:        /*
        !          1108:         * Send association request and response with status word and
        !          1109:         * host name. Note, this message is not signed and the filestamp
        !          1110:         * contains only the status word.
        !          1111:         */
        !          1112:        case CRYPTO_ASSOC:
        !          1113:        case CRYPTO_ASSOC | CRYPTO_RESP:
        !          1114:                len = crypto_send(fp, &hostval, start);
        !          1115:                fp->fstamp = htonl(crypto_flags);
        !          1116:                break;
        !          1117: 
        !          1118:        /*
        !          1119:         * Send certificate request. Use the values from the extension
        !          1120:         * field.
        !          1121:         */
        !          1122:        case CRYPTO_CERT:
        !          1123:                memset(&vtemp, 0, sizeof(vtemp));
        !          1124:                vtemp.tstamp = ep->tstamp;
        !          1125:                vtemp.fstamp = ep->fstamp;
        !          1126:                vtemp.vallen = ep->vallen;
        !          1127:                vtemp.ptr = (u_char *)ep->pkt;
        !          1128:                len = crypto_send(fp, &vtemp, start);
        !          1129:                break;
        !          1130: 
        !          1131:        /*
        !          1132:         * Send sign request. Use the host certificate, which is self-
        !          1133:         * signed and may or may not be trusted.
        !          1134:         */
        !          1135:        case CRYPTO_SIGN:
        !          1136:                if (tstamp < cert_host->first || tstamp >
        !          1137:                    cert_host->last)
        !          1138:                        rval = XEVNT_PER;
        !          1139:                else
        !          1140:                        len = crypto_send(fp, &cert_host->cert, start);
        !          1141:                break;
        !          1142: 
        !          1143:        /*
        !          1144:         * Send certificate response. Use the name in the extension
        !          1145:         * field to find the certificate in the cache. If the request
        !          1146:         * contains no subject name, assume the name of this host. This
        !          1147:         * is for backwards compatibility. Private certificates are
        !          1148:         * never sent.
        !          1149:         *
        !          1150:         * There may be several certificates matching the request. First
        !          1151:         * choice is a self-signed trusted certificate; second choice is
        !          1152:         * any certificate signed by another host. There is no third
        !          1153:         * choice. 
        !          1154:         */
        !          1155:        case CRYPTO_CERT | CRYPTO_RESP:
        !          1156:                vallen = ntohl(ep->vallen);
        !          1157:                if (vallen == 0 || vallen > MAXHOSTNAME) {
        !          1158:                        rval = XEVNT_LEN;
        !          1159:                        break;
        !          1160: 
        !          1161:                } else {
        !          1162:                        memcpy(certname, ep->pkt, vallen);
        !          1163:                        certname[vallen] = '\0';
        !          1164:                }
        !          1165: 
        !          1166:                /*
        !          1167:                 * Find all public valid certificates with matching
        !          1168:                 * subject. If a self-signed, trusted certificate is
        !          1169:                 * found, use that certificate. If not, use the last non
        !          1170:                 * self-signed certificate.
        !          1171:                 */
        !          1172:                xp = yp = NULL;
        !          1173:                for (cp = cinfo; cp != NULL; cp = cp->link) {
        !          1174:                        if (cp->flags & (CERT_PRIV | CERT_ERROR))
        !          1175:                                continue;
        !          1176: 
        !          1177:                        if (strcmp(certname, cp->subject) != 0)
        !          1178:                                continue;
        !          1179: 
        !          1180:                        if (strcmp(certname, cp->issuer) != 0)
        !          1181:                                yp = cp;
        !          1182:                        else if (cp ->flags & CERT_TRUST)
        !          1183:                                xp = cp;
        !          1184:                        continue;
        !          1185:                }
        !          1186: 
        !          1187:                /*
        !          1188:                 * Be careful who you trust. If the certificate is not
        !          1189:                 * found, return an empty response. Note that we dont
        !          1190:                 * enforce lifetimes here.
        !          1191:                 *
        !          1192:                 * The timestamp and filestamp are taken from the
        !          1193:                 * certificate value structure. For all certificates the
        !          1194:                 * timestamp is the latest signature update time. For
        !          1195:                 * host and imported certificates the filestamp is the
        !          1196:                 * creation epoch. For signed certificates the filestamp
        !          1197:                 * is the creation epoch of the trusted certificate at
        !          1198:                 * the root of the certificate trail. In principle, this
        !          1199:                 * allows strong checking for signature masquerade.
        !          1200:                 */
        !          1201:                if (xp == NULL)
        !          1202:                        xp = yp;
        !          1203:                if (xp == NULL)
        !          1204:                        break;
        !          1205: 
        !          1206:                if (tstamp == 0)
        !          1207:                        break;
        !          1208: 
        !          1209:                len = crypto_send(fp, &xp->cert, start);
        !          1210:                break;
        !          1211: 
        !          1212:        /*
        !          1213:         * Send challenge in Schnorr (IFF) identity scheme.
        !          1214:         */
        !          1215:        case CRYPTO_IFF:
        !          1216:                if (peer == NULL)
        !          1217:                        break;          /* hack attack */
        !          1218: 
        !          1219:                if ((rval = crypto_alice(peer, &vtemp)) == XEVNT_OK) {
        !          1220:                        len = crypto_send(fp, &vtemp, start);
        !          1221:                        value_free(&vtemp);
        !          1222:                }
        !          1223:                break;
        !          1224: 
        !          1225:        /*
        !          1226:         * Send response in Schnorr (IFF) identity scheme.
        !          1227:         */
        !          1228:        case CRYPTO_IFF | CRYPTO_RESP:
        !          1229:                if ((rval = crypto_bob(ep, &vtemp)) == XEVNT_OK) {
        !          1230:                        len = crypto_send(fp, &vtemp, start);
        !          1231:                        value_free(&vtemp);
        !          1232:                }
        !          1233:                break;
        !          1234: 
        !          1235:        /*
        !          1236:         * Send challenge in Guillou-Quisquater (GQ) identity scheme.
        !          1237:         */
        !          1238:        case CRYPTO_GQ:
        !          1239:                if (peer == NULL)
        !          1240:                        break;          /* hack attack */
        !          1241: 
        !          1242:                if ((rval = crypto_alice2(peer, &vtemp)) == XEVNT_OK) {
        !          1243:                        len = crypto_send(fp, &vtemp, start);
        !          1244:                        value_free(&vtemp);
        !          1245:                }
        !          1246:                break;
        !          1247: 
        !          1248:        /*
        !          1249:         * Send response in Guillou-Quisquater (GQ) identity scheme.
        !          1250:         */
        !          1251:        case CRYPTO_GQ | CRYPTO_RESP:
        !          1252:                if ((rval = crypto_bob2(ep, &vtemp)) == XEVNT_OK) {
        !          1253:                        len = crypto_send(fp, &vtemp, start);
        !          1254:                        value_free(&vtemp);
        !          1255:                }
        !          1256:                break;
        !          1257: 
        !          1258:        /*
        !          1259:         * Send challenge in MV identity scheme.
        !          1260:         */
        !          1261:        case CRYPTO_MV:
        !          1262:                if (peer == NULL)
        !          1263:                        break;          /* hack attack */
        !          1264: 
        !          1265:                if ((rval = crypto_alice3(peer, &vtemp)) == XEVNT_OK) {
        !          1266:                        len = crypto_send(fp, &vtemp, start);
        !          1267:                        value_free(&vtemp);
        !          1268:                }
        !          1269:                break;
        !          1270: 
        !          1271:        /*
        !          1272:         * Send response in MV identity scheme.
        !          1273:         */
        !          1274:        case CRYPTO_MV | CRYPTO_RESP:
        !          1275:                if ((rval = crypto_bob3(ep, &vtemp)) == XEVNT_OK) {
        !          1276:                        len = crypto_send(fp, &vtemp, start);
        !          1277:                        value_free(&vtemp);
        !          1278:                }
        !          1279:                break;
        !          1280: 
        !          1281:        /*
        !          1282:         * Send certificate sign response. The integrity of the request
        !          1283:         * certificate has already been verified on the receive side.
        !          1284:         * Sign the response using the local server key. Use the
        !          1285:         * filestamp from the request and use the timestamp as the
        !          1286:         * current time. Light the error bit if the certificate is
        !          1287:         * invalid or contains an unverified signature.
        !          1288:         */
        !          1289:        case CRYPTO_SIGN | CRYPTO_RESP:
        !          1290:                if ((rval = cert_sign(ep, &vtemp)) == XEVNT_OK) {
        !          1291:                        len = crypto_send(fp, &vtemp, start);
        !          1292:                        value_free(&vtemp);
        !          1293:                }
        !          1294:                break;
        !          1295: 
        !          1296:        /*
        !          1297:         * Send public key and signature. Use the values from the public
        !          1298:         * key.
        !          1299:         */
        !          1300:        case CRYPTO_COOK:
        !          1301:                len = crypto_send(fp, &pubkey, start);
        !          1302:                break;
        !          1303: 
        !          1304:        /*
        !          1305:         * Encrypt and send cookie and signature. Light the error bit if
        !          1306:         * anything goes wrong.
        !          1307:         */
        !          1308:        case CRYPTO_COOK | CRYPTO_RESP:
        !          1309:                if ((opcode & 0xffff) < VALUE_LEN) {
        !          1310:                        rval = XEVNT_LEN;
        !          1311:                        break;
        !          1312:                }
        !          1313:                if (peer == NULL)
        !          1314:                        tcookie = cookie;
        !          1315:                else
        !          1316:                        tcookie = peer->hcookie;
        !          1317:                if ((rval = crypto_encrypt(ep, &vtemp, &tcookie)) ==
        !          1318:                    XEVNT_OK) {
        !          1319:                        len = crypto_send(fp, &vtemp, start);
        !          1320:                        value_free(&vtemp);
        !          1321:                }
        !          1322:                break;
        !          1323: 
        !          1324:        /*
        !          1325:         * Find peer and send autokey data and signature in broadcast
        !          1326:         * server and symmetric modes. Use the values in the autokey
        !          1327:         * structure. If no association is found, either the server has
        !          1328:         * restarted with new associations or some perp has replayed an
        !          1329:         * old message, in which case light the error bit.
        !          1330:         */
        !          1331:        case CRYPTO_AUTO | CRYPTO_RESP:
        !          1332:                if (peer == NULL) {
        !          1333:                        if ((peer = findpeerbyassoc(associd)) == NULL) {
        !          1334:                                rval = XEVNT_ERR;
        !          1335:                                break;
        !          1336:                        }
        !          1337:                }
        !          1338:                peer->flags &= ~FLAG_ASSOC;
        !          1339:                len = crypto_send(fp, &peer->sndval, start);
        !          1340:                break;
        !          1341: 
        !          1342:        /*
        !          1343:         * Send leapseconds values and signature. Use the values from
        !          1344:         * the tai structure. If no table has been loaded, just send an
        !          1345:         * empty request.
        !          1346:         */
        !          1347:        case CRYPTO_LEAP | CRYPTO_RESP:
        !          1348:                len = crypto_send(fp, &tai_leap, start);
        !          1349:                break;
        !          1350: 
        !          1351:        /*
        !          1352:         * Default - Send a valid command for unknown requests; send
        !          1353:         * an error response for unknown resonses.
        !          1354:         */
        !          1355:        default:
        !          1356:                if (opcode & CRYPTO_RESP)
        !          1357:                        rval = XEVNT_ERR;
        !          1358:        }
        !          1359: 
        !          1360:        /*
        !          1361:         * In case of error, flame the log. If a request, toss the
        !          1362:         * puppy; if a response, return so the sender can flame, too.
        !          1363:         */
        !          1364:        if (rval != XEVNT_OK) {
        !          1365:                u_int32 uint32;
        !          1366: 
        !          1367:                uint32 = CRYPTO_ERROR;
        !          1368:                opcode |= uint32;
        !          1369:                fp->opcode |= htonl(uint32);
        !          1370:                snprintf(statstr, NTP_MAXSTRLEN,
        !          1371:                    "%04x %d %02x %s", opcode, associd, rval,
        !          1372:                    eventstr(rval));
        !          1373:                record_crypto_stats(srcadr_sin, statstr);
        !          1374: #ifdef DEBUG
        !          1375:                if (debug)
        !          1376:                        printf("crypto_xmit: %s\n", statstr);
        !          1377: #endif
        !          1378:                if (!(opcode & CRYPTO_RESP))
        !          1379:                        return (0);
        !          1380:        }
        !          1381: #ifdef DEBUG
        !          1382:        if (debug)
        !          1383:                printf(
        !          1384:                    "crypto_xmit: flags 0x%x offset %d len %d code 0x%x associd %d\n",
        !          1385:                    crypto_flags, start, len, opcode >> 16, associd);
        !          1386: #endif
        !          1387:        return (len);
        !          1388: }
        !          1389: 
        !          1390: 
        !          1391: /*
        !          1392:  * crypto_verify - verify the extension field value and signature
        !          1393:  *
        !          1394:  * Returns
        !          1395:  * XEVNT_OK    success
        !          1396:  * XEVNT_ERR   protocol error
        !          1397:  * XEVNT_FSP   bad filestamp
        !          1398:  * XEVNT_LEN   bad field format or length
        !          1399:  * XEVNT_PUB   bad or missing public key
        !          1400:  * XEVNT_SGL   bad signature length
        !          1401:  * XEVNT_SIG   signature not verified
        !          1402:  * XEVNT_TSP   bad timestamp
        !          1403:  */
        !          1404: static int
        !          1405: crypto_verify(
        !          1406:        struct exten *ep,       /* extension pointer */
        !          1407:        struct value *vp,       /* value pointer */
        !          1408:        struct peer *peer       /* peer structure pointer */
        !          1409:        )
        !          1410: {
        !          1411:        EVP_PKEY *pkey;         /* server public key */
        !          1412:        EVP_MD_CTX ctx;         /* signature context */
        !          1413:        tstamp_t tstamp, tstamp1 = 0; /* timestamp */
        !          1414:        tstamp_t fstamp, fstamp1 = 0; /* filestamp */
        !          1415:        u_int   vallen;         /* value length */
        !          1416:        u_int   siglen;         /* signature length */
        !          1417:        u_int   opcode, len;
        !          1418:        int     i;
        !          1419: 
        !          1420:        /*
        !          1421:         * We are extremely parannoyed. We require valid opcode, length,
        !          1422:         * association ID, timestamp, filestamp, public key, digest,
        !          1423:         * signature length and signature, where relevant. Note that
        !          1424:         * preliminary length checks are done in the main loop.
        !          1425:         */
        !          1426:        len = ntohl(ep->opcode) & 0x0000ffff;
        !          1427:        opcode = ntohl(ep->opcode) & 0xffff0000;
        !          1428: 
        !          1429:        /*
        !          1430:         * Check for valid value header, association ID and extension
        !          1431:         * field length. Remember, it is not an error to receive an
        !          1432:         * unsolicited response; however, the response ID must match
        !          1433:         * the association ID.
        !          1434:         */
        !          1435:        if (opcode & CRYPTO_ERROR)
        !          1436:                return (XEVNT_ERR);
        !          1437: 
        !          1438:        if (len < VALUE_LEN)
        !          1439:                return (XEVNT_LEN);
        !          1440: 
        !          1441:        if (opcode == (CRYPTO_AUTO | CRYPTO_RESP) && (peer->pmode ==
        !          1442:            MODE_BROADCAST || (peer->cast_flags & MDF_BCLNT))) {
        !          1443:                if (ntohl(ep->associd) != peer->assoc)
        !          1444:                        return (XEVNT_ERR);
        !          1445:        } else {
        !          1446:                if (ntohl(ep->associd) != peer->associd)
        !          1447:                        return (XEVNT_ERR);
        !          1448:        }
        !          1449: 
        !          1450:        /*
        !          1451:         * We have a valid value header. Check for valid value and
        !          1452:         * signature field lengths. The extension field length must be
        !          1453:         * long enough to contain the value header, value and signature.
        !          1454:         * Note both the value and signature field lengths are rounded
        !          1455:         * up to the next word (4 octets).
        !          1456:         */
        !          1457:        vallen = ntohl(ep->vallen);
        !          1458:        if (vallen == 0)
        !          1459:                return (XEVNT_LEN);
        !          1460: 
        !          1461:        i = (vallen + 3) / 4;
        !          1462:        siglen = ntohl(ep->pkt[i++]);
        !          1463:        if (len < VALUE_LEN + ((vallen + 3) / 4) * 4 + ((siglen + 3) /
        !          1464:            4) * 4)
        !          1465:                return (XEVNT_LEN);
        !          1466: 
        !          1467:        /*
        !          1468:         * Check for valid timestamp and filestamp. If the timestamp is
        !          1469:         * zero, the sender is not synchronized and signatures are
        !          1470:         * not possible. If nonzero the timestamp must not precede the
        !          1471:         * filestamp. The timestamp and filestamp must not precede the
        !          1472:         * corresponding values in the value structure, if present.
        !          1473:         */
        !          1474:        tstamp = ntohl(ep->tstamp);
        !          1475:        fstamp = ntohl(ep->fstamp);
        !          1476:        if (tstamp == 0)
        !          1477:                return (XEVNT_TSP);
        !          1478: 
        !          1479:        if (tstamp < fstamp)
        !          1480:                return (XEVNT_TSP);
        !          1481: 
        !          1482:        if (vp != NULL) {
        !          1483:                tstamp1 = ntohl(vp->tstamp);
        !          1484:                fstamp1 = ntohl(vp->fstamp);
        !          1485:                if (tstamp1 != 0 && fstamp1 != 0) {
        !          1486:                        if (tstamp < tstamp1)
        !          1487:                                return (XEVNT_TSP);
        !          1488: 
        !          1489:                        if ((tstamp < fstamp1 || fstamp < fstamp1))
        !          1490:                                return (XEVNT_FSP);
        !          1491:                }
        !          1492:        }
        !          1493: 
        !          1494:        /*
        !          1495:         * At the time the certificate message is validated, the public
        !          1496:         * key in the message is not available. Thus, don't try to
        !          1497:         * verify the signature.
        !          1498:         */
        !          1499:        if (opcode == (CRYPTO_CERT | CRYPTO_RESP))
        !          1500:                return (XEVNT_OK);
        !          1501: 
        !          1502:        /*
        !          1503:         * Check for valid signature length, public key and digest
        !          1504:         * algorithm.
        !          1505:         */
        !          1506:        if (crypto_flags & peer->crypto & CRYPTO_FLAG_PRIV)
        !          1507:                pkey = sign_pkey;
        !          1508:        else
        !          1509:                pkey = peer->pkey;
        !          1510:        if (siglen == 0 || pkey == NULL || peer->digest == NULL)
        !          1511:                return (XEVNT_ERR);
        !          1512: 
        !          1513:        if (siglen != (u_int)EVP_PKEY_size(pkey))
        !          1514:                return (XEVNT_SGL);
        !          1515: 
        !          1516:        /*
        !          1517:         * Darn, I thought we would never get here. Verify the
        !          1518:         * signature. If the identity exchange is verified, light the
        !          1519:         * proventic bit. What a relief.
        !          1520:         */
        !          1521:        EVP_VerifyInit(&ctx, peer->digest);
        !          1522:        EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12);
        !          1523:        if (EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen,
        !          1524:            pkey) <= 0)
        !          1525:                return (XEVNT_SIG);
        !          1526: 
        !          1527:        if (peer->crypto & CRYPTO_FLAG_VRFY)
        !          1528:                peer->crypto |= CRYPTO_FLAG_PROV;
        !          1529:        return (XEVNT_OK);
        !          1530: }
        !          1531: 
        !          1532: 
        !          1533: /*
        !          1534:  * crypto_encrypt - construct encrypted cookie and signature from
        !          1535:  * extension field and cookie
        !          1536:  *
        !          1537:  * Returns
        !          1538:  * XEVNT_OK    success
        !          1539:  * XEVNT_CKY   bad or missing cookie
        !          1540:  * XEVNT_PUB   bad or missing public key
        !          1541:  */
        !          1542: static int
        !          1543: crypto_encrypt(
        !          1544:        struct exten *ep,       /* extension pointer */
        !          1545:        struct value *vp,       /* value pointer */
        !          1546:        keyid_t *cookie         /* server cookie */
        !          1547:        )
        !          1548: {
        !          1549:        EVP_PKEY *pkey;         /* public key */
        !          1550:        EVP_MD_CTX ctx;         /* signature context */
        !          1551:        tstamp_t tstamp;        /* NTP timestamp */
        !          1552:        u_int32 temp32;
        !          1553:        u_int   len;
        !          1554:        u_char  *ptr;
        !          1555: 
        !          1556:        /*
        !          1557:         * Extract the public key from the request.
        !          1558:         */
        !          1559:        len = ntohl(ep->vallen);
        !          1560:        ptr = (u_char *)ep->pkt;
        !          1561:        pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len);
        !          1562:        if (pkey == NULL) {
        !          1563:                msyslog(LOG_ERR, "crypto_encrypt: %s",
        !          1564:                    ERR_error_string(ERR_get_error(), NULL));
        !          1565:                return (XEVNT_PUB);
        !          1566:        }
        !          1567: 
        !          1568:        /*
        !          1569:         * Encrypt the cookie, encode in ASN.1 and sign.
        !          1570:         */
        !          1571:        memset(vp, 0, sizeof(struct value));
        !          1572:        tstamp = crypto_time();
        !          1573:        vp->tstamp = htonl(tstamp);
        !          1574:        vp->fstamp = hostval.tstamp;
        !          1575:        len = EVP_PKEY_size(pkey);
        !          1576:        vp->vallen = htonl(len);
        !          1577:        vp->ptr = emalloc(len);
        !          1578:        ptr = vp->ptr;
        !          1579:        temp32 = htonl(*cookie);
        !          1580:        if (RSA_public_encrypt(4, (u_char *)&temp32, ptr,
        !          1581:            pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING) <= 0) {
        !          1582:                msyslog(LOG_ERR, "crypto_encrypt: %s",
        !          1583:                    ERR_error_string(ERR_get_error(), NULL));
        !          1584:                free(vp->ptr);
        !          1585:                EVP_PKEY_free(pkey);
        !          1586:                return (XEVNT_CKY);
        !          1587:        }
        !          1588:        EVP_PKEY_free(pkey);
        !          1589:        if (tstamp == 0)
        !          1590:                return (XEVNT_OK);
        !          1591: 
        !          1592:        vp->sig = emalloc(sign_siglen);
        !          1593:        EVP_SignInit(&ctx, sign_digest);
        !          1594:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          1595:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          1596:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          1597:                vp->siglen = htonl(sign_siglen);
        !          1598:        return (XEVNT_OK);
        !          1599: }
        !          1600: 
        !          1601: 
        !          1602: /*
        !          1603:  * crypto_ident - construct extension field for identity scheme
        !          1604:  *
        !          1605:  * This routine determines which identity scheme is in use and
        !          1606:  * constructs an extension field for that scheme.
        !          1607:  *
        !          1608:  * Returns
        !          1609:  * CRYTPO_IFF  IFF scheme
        !          1610:  * CRYPTO_GQ   GQ scheme
        !          1611:  * CRYPTO_MV   MV scheme
        !          1612:  * CRYPTO_NULL no available scheme
        !          1613:  */
        !          1614: u_int
        !          1615: crypto_ident(
        !          1616:        struct peer *peer       /* peer structure pointer */
        !          1617:        )
        !          1618: {
        !          1619:        char    filename[MAXFILENAME];
        !          1620: 
        !          1621:        /*
        !          1622:         * We come here after the group trusted host has been found; its
        !          1623:         * name defines the group name. Search the key cache for all
        !          1624:         * keys matching the same group name in order IFF, GQ and MV.
        !          1625:         * Use the first one available.
        !          1626:         */
        !          1627:        if (peer->crypto & CRYPTO_FLAG_IFF) {
        !          1628:                snprintf(filename, MAXFILENAME, "ntpkey_iffpar_%s",
        !          1629:                    peer->issuer);
        !          1630:                peer->ident_pkey = crypto_key(filename, NULL,
        !          1631:                    &peer->srcadr);
        !          1632:                if (peer->ident_pkey != NULL)
        !          1633:                        return (CRYPTO_IFF);
        !          1634:        }
        !          1635:        if (peer->crypto & CRYPTO_FLAG_GQ) {
        !          1636:                snprintf(filename, MAXFILENAME, "ntpkey_gqpar_%s",
        !          1637:                    peer->issuer);
        !          1638:                peer->ident_pkey = crypto_key(filename, NULL,
        !          1639:                    &peer->srcadr);
        !          1640:                if (peer->ident_pkey != NULL)
        !          1641:                        return (CRYPTO_GQ);
        !          1642:        }
        !          1643:        if (peer->crypto & CRYPTO_FLAG_MV) {
        !          1644:                snprintf(filename, MAXFILENAME, "ntpkey_mvpar_%s",
        !          1645:                    peer->issuer);
        !          1646:                peer->ident_pkey = crypto_key(filename, NULL,
        !          1647:                    &peer->srcadr);
        !          1648:                if (peer->ident_pkey != NULL)
        !          1649:                        return (CRYPTO_MV);
        !          1650:        }
        !          1651:        msyslog(LOG_NOTICE,
        !          1652:            "crypto_ident: no identity parameters found for group %s",
        !          1653:            peer->issuer);
        !          1654:        return (CRYPTO_NULL);
        !          1655: }
        !          1656: 
        !          1657: 
        !          1658: /*
        !          1659:  * crypto_args - construct extension field from arguments
        !          1660:  *
        !          1661:  * This routine creates an extension field with current timestamps and
        !          1662:  * specified opcode, association ID and optional string. Note that the
        !          1663:  * extension field is created here, but freed after the crypto_xmit()
        !          1664:  * call in the protocol module.
        !          1665:  *
        !          1666:  * Returns extension field pointer (no errors)
        !          1667:  */
        !          1668: struct exten *
        !          1669: crypto_args(
        !          1670:        struct peer *peer,      /* peer structure pointer */
        !          1671:        u_int   opcode,         /* operation code */
        !          1672:        associd_t associd,      /* association ID */
        !          1673:        char    *str            /* argument string */
        !          1674:        )
        !          1675: {
        !          1676:        tstamp_t tstamp;        /* NTP timestamp */
        !          1677:        struct exten *ep;       /* extension field pointer */
        !          1678:        u_int   len;            /* extension field length */
        !          1679: 
        !          1680:        tstamp = crypto_time();
        !          1681:        len = sizeof(struct exten);
        !          1682:        if (str != NULL)
        !          1683:                len += strlen(str);
        !          1684:        ep = emalloc(len);
        !          1685:        memset(ep, 0, len);
        !          1686:        if (opcode == 0)
        !          1687:                return (ep);
        !          1688: 
        !          1689:        ep->opcode = htonl(opcode + len);
        !          1690:        ep->associd = htonl(associd);
        !          1691:        ep->tstamp = htonl(tstamp);
        !          1692:        ep->fstamp = hostval.tstamp;
        !          1693:        ep->vallen = 0;
        !          1694:        if (str != NULL) {
        !          1695:                ep->vallen = htonl(strlen(str));
        !          1696:                memcpy((char *)ep->pkt, str, strlen(str));
        !          1697:        }
        !          1698:        return (ep);
        !          1699: }
        !          1700: 
        !          1701: 
        !          1702: /*
        !          1703:  * crypto_send - construct extension field from value components
        !          1704:  *
        !          1705:  * The value and signature fields are zero-padded to a word boundary.
        !          1706:  * Note: it is not polite to send a nonempty signature with zero
        !          1707:  * timestamp or a nonzero timestamp with an empty signature, but those
        !          1708:  * rules are not enforced here.
        !          1709:  */
        !          1710: int
        !          1711: crypto_send(
        !          1712:        struct exten *ep,       /* extension field pointer */
        !          1713:        struct value *vp,       /* value pointer */
        !          1714:        int     start           /* buffer offset */
        !          1715:        )
        !          1716: {
        !          1717:        u_int   len, vallen, siglen, opcode;
        !          1718:        int     i, j;
        !          1719: 
        !          1720:        /*
        !          1721:         * Calculate extension field length and check for buffer
        !          1722:         * overflow. Leave room for the MAC.
        !          1723:         */
        !          1724:        len = 16;
        !          1725:        vallen = ntohl(vp->vallen);
        !          1726:        len += ((vallen + 3) / 4 + 1) * 4; 
        !          1727:        siglen = ntohl(vp->siglen);
        !          1728:        len += ((siglen + 3) / 4 + 1) * 4; 
        !          1729:        if (start + len > sizeof(struct pkt) - MAX_MAC_LEN)
        !          1730:                return (0);
        !          1731: 
        !          1732:        /*
        !          1733:         * Copy timestamps.
        !          1734:         */
        !          1735:        ep->tstamp = vp->tstamp;
        !          1736:        ep->fstamp = vp->fstamp;
        !          1737:        ep->vallen = vp->vallen;
        !          1738: 
        !          1739:        /*
        !          1740:         * Copy value. If the data field is empty or zero length,
        !          1741:         * encode an empty value with length zero.
        !          1742:         */
        !          1743:        i = 0;
        !          1744:        if (vallen > 0 && vp->ptr != NULL) {
        !          1745:                j = vallen / 4;
        !          1746:                if (j * 4 < vallen)
        !          1747:                        ep->pkt[i + j++] = 0;
        !          1748:                memcpy(&ep->pkt[i], vp->ptr, vallen);
        !          1749:                i += j;
        !          1750:        }
        !          1751: 
        !          1752:        /*
        !          1753:         * Copy signature. If the signature field is empty or zero
        !          1754:         * length, encode an empty signature with length zero.
        !          1755:         */
        !          1756:        ep->pkt[i++] = vp->siglen;
        !          1757:        if (siglen > 0 && vp->sig != NULL) {
        !          1758:                j = vallen / 4;
        !          1759:                if (j * 4 < siglen)
        !          1760:                        ep->pkt[i + j++] = 0;
        !          1761:                memcpy(&ep->pkt[i], vp->sig, siglen);
        !          1762:                i += j;
        !          1763:        }
        !          1764:        opcode = ntohl(ep->opcode);
        !          1765:        ep->opcode = htonl((opcode & 0xffff0000) | len); 
        !          1766:        return (len);
        !          1767: }
        !          1768: 
        !          1769: 
        !          1770: /*
        !          1771:  * crypto_update - compute new public value and sign extension fields
        !          1772:  *
        !          1773:  * This routine runs periodically, like once a day, and when something
        !          1774:  * changes. It updates the timestamps on three value structures and one
        !          1775:  * value structure list, then signs all the structures:
        !          1776:  *
        !          1777:  * hostval     host name (not signed)
        !          1778:  * pubkey      public key
        !          1779:  * cinfo       certificate info/value list
        !          1780:  * tai_leap    leap values
        !          1781:  *
        !          1782:  * Filestamps are proventic data, so this routine runs only when the
        !          1783:  * host is synchronized to a proventicated source. Thus, the timestamp
        !          1784:  * is proventic and can be used to deflect clogging attacks.
        !          1785:  *
        !          1786:  * Returns void (no errors)
        !          1787:  */
        !          1788: void
        !          1789: crypto_update(void)
        !          1790: {
        !          1791:        EVP_MD_CTX ctx;         /* message digest context */
        !          1792:        struct cert_info *cp;   /* certificate info/value */
        !          1793:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !          1794:        u_int32 *ptr;
        !          1795:        u_int   len;
        !          1796: 
        !          1797:        hostval.tstamp = htonl(crypto_time());
        !          1798:        if (hostval.tstamp == 0)
        !          1799:                return;
        !          1800: 
        !          1801: 
        !          1802:        /*
        !          1803:         * Sign public key and timestamps. The filestamp is derived from
        !          1804:         * the host key file extension from wherever the file was
        !          1805:         * generated. 
        !          1806:         */
        !          1807:        if (pubkey.vallen != 0) {
        !          1808:                pubkey.tstamp = hostval.tstamp;
        !          1809:                pubkey.siglen = 0;
        !          1810:                if (pubkey.sig == NULL)
        !          1811:                        pubkey.sig = emalloc(sign_siglen);
        !          1812:                EVP_SignInit(&ctx, sign_digest);
        !          1813:                EVP_SignUpdate(&ctx, (u_char *)&pubkey, 12);
        !          1814:                EVP_SignUpdate(&ctx, pubkey.ptr, ntohl(pubkey.vallen));
        !          1815:                if (EVP_SignFinal(&ctx, pubkey.sig, &len, sign_pkey))
        !          1816:                        pubkey.siglen = htonl(sign_siglen);
        !          1817:        }
        !          1818: 
        !          1819:        /*
        !          1820:         * Sign certificates and timestamps. The filestamp is derived
        !          1821:         * from the certificate file extension from wherever the file
        !          1822:         * was generated. Note we do not throw expired certificates
        !          1823:         * away; they may have signed younger ones.
        !          1824:         */
        !          1825:        for (cp = cinfo; cp != NULL; cp = cp->link) {
        !          1826:                cp->cert.tstamp = hostval.tstamp;
        !          1827:                cp->cert.siglen = 0;
        !          1828:                if (cp->cert.sig == NULL)
        !          1829:                        cp->cert.sig = emalloc(sign_siglen);
        !          1830:                EVP_SignInit(&ctx, sign_digest);
        !          1831:                EVP_SignUpdate(&ctx, (u_char *)&cp->cert, 12);
        !          1832:                EVP_SignUpdate(&ctx, cp->cert.ptr,
        !          1833:                    ntohl(cp->cert.vallen));
        !          1834:                if (EVP_SignFinal(&ctx, cp->cert.sig, &len, sign_pkey))
        !          1835:                        cp->cert.siglen = htonl(sign_siglen);
        !          1836:        }
        !          1837: 
        !          1838:        /*
        !          1839:         * Sign leapseconds values and timestamps. Note it is not an
        !          1840:         * error to return null values.
        !          1841:         */
        !          1842:        tai_leap.tstamp = hostval.tstamp;
        !          1843:        tai_leap.fstamp = hostval.fstamp;
        !          1844:        len = 3 * sizeof(u_int32);
        !          1845:        if (tai_leap.ptr == NULL)
        !          1846:                tai_leap.ptr = emalloc(len);
        !          1847:        tai_leap.vallen = htonl(len);
        !          1848:        ptr = (u_int32 *)tai_leap.ptr;
        !          1849:        ptr[0] = htonl(leap_tai);
        !          1850:        ptr[1] = htonl(leap_sec);
        !          1851:        ptr[2] = htonl(leap_expire);
        !          1852:        if (tai_leap.sig == NULL)
        !          1853:                tai_leap.sig = emalloc(sign_siglen);
        !          1854:        EVP_SignInit(&ctx, sign_digest);
        !          1855:        EVP_SignUpdate(&ctx, (u_char *)&tai_leap, 12);
        !          1856:        EVP_SignUpdate(&ctx, tai_leap.ptr, len);
        !          1857:        if (EVP_SignFinal(&ctx, tai_leap.sig, &len, sign_pkey))
        !          1858:                tai_leap.siglen = htonl(sign_siglen);
        !          1859:        if (leap_sec > 0)
        !          1860:                crypto_flags |= CRYPTO_FLAG_TAI;
        !          1861:        snprintf(statstr, NTP_MAXSTRLEN, "signature update ts %u",
        !          1862:            ntohl(hostval.tstamp)); 
        !          1863:        record_crypto_stats(NULL, statstr);
        !          1864: #ifdef DEBUG
        !          1865:        if (debug)
        !          1866:                printf("crypto_update: %s\n", statstr);
        !          1867: #endif
        !          1868: }
        !          1869: 
        !          1870: 
        !          1871: /*
        !          1872:  * value_free - free value structure components.
        !          1873:  *
        !          1874:  * Returns void (no errors)
        !          1875:  */
        !          1876: void
        !          1877: value_free(
        !          1878:        struct value *vp        /* value structure */
        !          1879:        )
        !          1880: {
        !          1881:        if (vp->ptr != NULL)
        !          1882:                free(vp->ptr);
        !          1883:        if (vp->sig != NULL)
        !          1884:                free(vp->sig);
        !          1885:        memset(vp, 0, sizeof(struct value));
        !          1886: }
        !          1887: 
        !          1888: 
        !          1889: /*
        !          1890:  * crypto_time - returns current NTP time.
        !          1891:  *
        !          1892:  * Returns NTP seconds if in synch, 0 otherwise
        !          1893:  */
        !          1894: tstamp_t
        !          1895: crypto_time()
        !          1896: {
        !          1897:        l_fp    tstamp;         /* NTP time */
        !          1898: 
        !          1899:        L_CLR(&tstamp);
        !          1900:        if (sys_leap != LEAP_NOTINSYNC)
        !          1901:                get_systime(&tstamp);
        !          1902:        return (tstamp.l_ui);
        !          1903: }
        !          1904: 
        !          1905: 
        !          1906: /*
        !          1907:  * asn2ntp - convert ASN1_TIME time structure to NTP time.
        !          1908:  *
        !          1909:  * Returns NTP seconds (no errors)
        !          1910:  */
        !          1911: u_long
        !          1912: asn2ntp        (
        !          1913:        ASN1_TIME *asn1time     /* pointer to ASN1_TIME structure */
        !          1914:        )
        !          1915: {
        !          1916:        char    *v;             /* pointer to ASN1_TIME string */
        !          1917:        struct  tm tm;          /* used to convert to NTP time */
        !          1918: 
        !          1919:        /*
        !          1920:         * Extract time string YYMMDDHHMMSSZ from ASN1 time structure.
        !          1921:         * Note that the YY, MM, DD fields start with one, the HH, MM,
        !          1922:         * SS fiels start with zero and the Z character is ignored.
        !          1923:         * Also note that years less than 50 map to years greater than
        !          1924:         * 100. Dontcha love ASN.1? Better than MIL-188.
        !          1925:         */
        !          1926:        v = (char *)asn1time->data;
        !          1927:        tm.tm_year = (v[0] - '0') * 10 + v[1] - '0';
        !          1928:        if (tm.tm_year < 50)
        !          1929:                tm.tm_year += 100;
        !          1930:        tm.tm_mon = (v[2] - '0') * 10 + v[3] - '0' - 1;
        !          1931:        tm.tm_mday = (v[4] - '0') * 10 + v[5] - '0';
        !          1932:        tm.tm_hour = (v[6] - '0') * 10 + v[7] - '0';
        !          1933:        tm.tm_min = (v[8] - '0') * 10 + v[9] - '0';
        !          1934:        tm.tm_sec = (v[10] - '0') * 10 + v[11] - '0';
        !          1935:        tm.tm_wday = 0;
        !          1936:        tm.tm_yday = 0;
        !          1937:        tm.tm_isdst = 0;
        !          1938:        return ((u_long)timegm(&tm) + JAN_1970);
        !          1939: }
        !          1940: 
        !          1941: 
        !          1942: /*
        !          1943:  * bigdig() - compute a BIGNUM MD5 hash of a BIGNUM number.
        !          1944:  *
        !          1945:  * Returns void (no errors)
        !          1946:  */
        !          1947: static void
        !          1948: bighash(
        !          1949:        BIGNUM  *bn,            /* BIGNUM * from */
        !          1950:        BIGNUM  *bk             /* BIGNUM * to */
        !          1951:        )
        !          1952: {
        !          1953:        EVP_MD_CTX ctx;         /* message digest context */
        !          1954:        u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
        !          1955:        u_char  *ptr;           /* a BIGNUM as binary string */
        !          1956:        u_int   len;
        !          1957: 
        !          1958:        len = BN_num_bytes(bn);
        !          1959:        ptr = emalloc(len);
        !          1960:        BN_bn2bin(bn, ptr);
        !          1961:        EVP_DigestInit(&ctx, EVP_md5());
        !          1962:        EVP_DigestUpdate(&ctx, ptr, len);
        !          1963:        EVP_DigestFinal(&ctx, dgst, &len);
        !          1964:        BN_bin2bn(dgst, len, bk);
        !          1965:        free(ptr);
        !          1966: }
        !          1967: 
        !          1968: 
        !          1969: /*
        !          1970:  ***********************************************************************
        !          1971:  *                                                                    *
        !          1972:  * The following routines implement the Schnorr (IFF) identity scheme  *
        !          1973:  *                                                                    *
        !          1974:  ***********************************************************************
        !          1975:  *
        !          1976:  * The Schnorr (IFF) identity scheme is intended for use when
        !          1977:  * certificates are generated by some other trusted certificate
        !          1978:  * authority and the certificate cannot be used to convey public
        !          1979:  * parameters. There are two kinds of files: encrypted server files that
        !          1980:  * contain private and public values and nonencrypted client files that
        !          1981:  * contain only public values. New generations of server files must be
        !          1982:  * securely transmitted to all servers of the group; client files can be
        !          1983:  * distributed by any means. The scheme is self contained and
        !          1984:  * independent of new generations of host keys, sign keys and
        !          1985:  * certificates.
        !          1986:  *
        !          1987:  * The IFF values hide in a DSA cuckoo structure which uses the same
        !          1988:  * parameters. The values are used by an identity scheme based on DSA
        !          1989:  * cryptography and described in Stimson p. 285. The p is a 512-bit
        !          1990:  * prime, g a generator of Zp* and q a 160-bit prime that divides p - 1
        !          1991:  * and is a qth root of 1 mod p; that is, g^q = 1 mod p. The TA rolls a
        !          1992:  * private random group key b (0 < b < q) and public key v = g^b, then
        !          1993:  * sends (p, q, g, b) to the servers and (p, q, g, v) to the clients.
        !          1994:  * Alice challenges Bob to confirm identity using the protocol described
        !          1995:  * below.
        !          1996:  *
        !          1997:  * How it works
        !          1998:  *
        !          1999:  * The scheme goes like this. Both Alice and Bob have the public primes
        !          2000:  * p, q and generator g. The TA gives private key b to Bob and public
        !          2001:  * key v to Alice.
        !          2002:  *
        !          2003:  * Alice rolls new random challenge r (o < r < q) and sends to Bob in
        !          2004:  * the IFF request message. Bob rolls new random k (0 < k < q), then
        !          2005:  * computes y = k + b r mod q and x = g^k mod p and sends (y, hash(x))
        !          2006:  * to Alice in the response message. Besides making the response
        !          2007:  * shorter, the hash makes it effectivey impossible for an intruder to
        !          2008:  * solve for b by observing a number of these messages.
        !          2009:  * 
        !          2010:  * Alice receives the response and computes g^y v^r mod p. After a bit
        !          2011:  * of algebra, this simplifies to g^k. If the hash of this result
        !          2012:  * matches hash(x), Alice knows that Bob has the group key b. The signed
        !          2013:  * response binds this knowledge to Bob's private key and the public key
        !          2014:  * previously received in his certificate.
        !          2015:  *
        !          2016:  * crypto_alice - construct Alice's challenge in IFF scheme
        !          2017:  *
        !          2018:  * Returns
        !          2019:  * XEVNT_OK    success
        !          2020:  * XEVNT_ID    bad or missing group key
        !          2021:  * XEVNT_PUB   bad or missing public key
        !          2022:  */
        !          2023: static int
        !          2024: crypto_alice(
        !          2025:        struct peer *peer,      /* peer pointer */
        !          2026:        struct value *vp        /* value pointer */
        !          2027:        )
        !          2028: {
        !          2029:        DSA     *dsa;           /* IFF parameters */
        !          2030:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2031:        EVP_MD_CTX ctx;         /* signature context */
        !          2032:        tstamp_t tstamp;
        !          2033:        u_int   len;
        !          2034: 
        !          2035:        /*
        !          2036:         * The identity parameters must have correct format and content.
        !          2037:         */
        !          2038:        if (peer->ident_pkey == NULL)
        !          2039:                return (XEVNT_ID);
        !          2040: 
        !          2041:        if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
        !          2042:                msyslog(LOG_NOTICE, "crypto_alice: defective key");
        !          2043:                return (XEVNT_PUB);
        !          2044:        }
        !          2045: 
        !          2046:        /*
        !          2047:         * Roll new random r (0 < r < q).
        !          2048:         */
        !          2049:        if (peer->iffval != NULL)
        !          2050:                BN_free(peer->iffval);
        !          2051:        peer->iffval = BN_new();
        !          2052:        len = BN_num_bytes(dsa->q);
        !          2053:        BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod q*/
        !          2054:        bctx = BN_CTX_new();
        !          2055:        BN_mod(peer->iffval, peer->iffval, dsa->q, bctx);
        !          2056:        BN_CTX_free(bctx);
        !          2057: 
        !          2058:        /*
        !          2059:         * Sign and send to Bob. The filestamp is from the local file.
        !          2060:         */
        !          2061:        memset(vp, 0, sizeof(struct value));
        !          2062:        tstamp = crypto_time();
        !          2063:        vp->tstamp = htonl(tstamp);
        !          2064:        vp->fstamp = htonl(peer->ident_pkey->fstamp);
        !          2065:        vp->vallen = htonl(len);
        !          2066:        vp->ptr = emalloc(len);
        !          2067:        BN_bn2bin(peer->iffval, vp->ptr);
        !          2068:        if (tstamp == 0)
        !          2069:                return (XEVNT_OK);
        !          2070: 
        !          2071:        vp->sig = emalloc(sign_siglen);
        !          2072:        EVP_SignInit(&ctx, sign_digest);
        !          2073:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2074:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2075:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2076:                vp->siglen = htonl(sign_siglen);
        !          2077:        return (XEVNT_OK);
        !          2078: }
        !          2079: 
        !          2080: 
        !          2081: /*
        !          2082:  * crypto_bob - construct Bob's response to Alice's challenge
        !          2083:  *
        !          2084:  * Returns
        !          2085:  * XEVNT_OK    success
        !          2086:  * XEVNT_ERR   protocol error
        !          2087:  * XEVNT_ID    bad or missing group key
        !          2088:  */
        !          2089: static int
        !          2090: crypto_bob(
        !          2091:        struct exten *ep,       /* extension pointer */
        !          2092:        struct value *vp        /* value pointer */
        !          2093:        )
        !          2094: {
        !          2095:        DSA     *dsa;           /* IFF parameters */
        !          2096:        DSA_SIG *sdsa;          /* DSA signature context fake */
        !          2097:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2098:        EVP_MD_CTX ctx;         /* signature context */
        !          2099:        tstamp_t tstamp;        /* NTP timestamp */
        !          2100:        BIGNUM  *bn, *bk, *r;
        !          2101:        u_char  *ptr;
        !          2102:        u_int   len;
        !          2103: 
        !          2104:        /*
        !          2105:         * If the IFF parameters are not valid, something awful
        !          2106:         * happened or we are being tormented.
        !          2107:         */
        !          2108:        if (iffkey_info == NULL) {
        !          2109:                msyslog(LOG_NOTICE, "crypto_bob: scheme unavailable");
        !          2110:                return (XEVNT_ID);
        !          2111:        }
        !          2112:        dsa = iffkey_info->pkey->pkey.dsa;
        !          2113: 
        !          2114:        /*
        !          2115:         * Extract r from the challenge.
        !          2116:         */
        !          2117:        len = ntohl(ep->vallen);
        !          2118:        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
        !          2119:                msyslog(LOG_ERR, "crypto_bob: %s",
        !          2120:                    ERR_error_string(ERR_get_error(), NULL));
        !          2121:                return (XEVNT_ERR);
        !          2122:        }
        !          2123: 
        !          2124:        /*
        !          2125:         * Bob rolls random k (0 < k < q), computes y = k + b r mod q
        !          2126:         * and x = g^k mod p, then sends (y, hash(x)) to Alice.
        !          2127:         */
        !          2128:        bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
        !          2129:        sdsa = DSA_SIG_new();
        !          2130:        BN_rand(bk, len * 8, -1, 1);            /* k */
        !          2131:        BN_mod_mul(bn, dsa->priv_key, r, dsa->q, bctx); /* b r mod q */
        !          2132:        BN_add(bn, bn, bk);
        !          2133:        BN_mod(bn, bn, dsa->q, bctx);           /* k + b r mod q */
        !          2134:        sdsa->r = BN_dup(bn);
        !          2135:        BN_mod_exp(bk, dsa->g, bk, dsa->p, bctx); /* g^k mod p */
        !          2136:        bighash(bk, bk);
        !          2137:        sdsa->s = BN_dup(bk);
        !          2138:        BN_CTX_free(bctx);
        !          2139:        BN_free(r); BN_free(bn); BN_free(bk);
        !          2140: #ifdef DEBUG
        !          2141:        if (debug > 1)
        !          2142:                DSA_print_fp(stdout, dsa, 0);
        !          2143: #endif
        !          2144: 
        !          2145:        /*
        !          2146:         * Encode the values in ASN.1 and sign. The filestamp is from
        !          2147:         * the local file.
        !          2148:         */
        !          2149:        len = i2d_DSA_SIG(sdsa, NULL);
        !          2150:        if (len == 0) {
        !          2151:                msyslog(LOG_ERR, "crypto_bob: %s",
        !          2152:                    ERR_error_string(ERR_get_error(), NULL));
        !          2153:                DSA_SIG_free(sdsa);
        !          2154:                return (XEVNT_ERR);
        !          2155:        }
        !          2156:        memset(vp, 0, sizeof(struct value));
        !          2157:        tstamp = crypto_time();
        !          2158:        vp->tstamp = htonl(tstamp);
        !          2159:        vp->fstamp = htonl(iffkey_info->fstamp);
        !          2160:        vp->vallen = htonl(len);
        !          2161:        ptr = emalloc(len);
        !          2162:        vp->ptr = ptr;
        !          2163:        i2d_DSA_SIG(sdsa, &ptr);
        !          2164:        DSA_SIG_free(sdsa);
        !          2165:        if (tstamp == 0)
        !          2166:                return (XEVNT_OK);
        !          2167: 
        !          2168:        vp->sig = emalloc(sign_siglen);
        !          2169:        EVP_SignInit(&ctx, sign_digest);
        !          2170:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2171:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2172:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2173:                vp->siglen = htonl(sign_siglen);
        !          2174:        return (XEVNT_OK);
        !          2175: }
        !          2176: 
        !          2177: 
        !          2178: /*
        !          2179:  * crypto_iff - verify Bob's response to Alice's challenge
        !          2180:  *
        !          2181:  * Returns
        !          2182:  * XEVNT_OK    success
        !          2183:  * XEVNT_FSP   bad filestamp
        !          2184:  * XEVNT_ID    bad or missing group key
        !          2185:  * XEVNT_PUB   bad or missing public key
        !          2186:  */
        !          2187: int
        !          2188: crypto_iff(
        !          2189:        struct exten *ep,       /* extension pointer */
        !          2190:        struct peer *peer       /* peer structure pointer */
        !          2191:        )
        !          2192: {
        !          2193:        DSA     *dsa;           /* IFF parameters */
        !          2194:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2195:        DSA_SIG *sdsa;          /* DSA parameters */
        !          2196:        BIGNUM  *bn, *bk;
        !          2197:        u_int   len;
        !          2198:        const u_char *ptr;
        !          2199:        int     temp;
        !          2200: 
        !          2201:        /*
        !          2202:         * If the IFF parameters are not valid or no challenge was sent,
        !          2203:         * something awful happened or we are being tormented.
        !          2204:         */
        !          2205:        if (peer->ident_pkey == NULL) {
        !          2206:                msyslog(LOG_NOTICE, "crypto_iff: scheme unavailable");
        !          2207:                return (XEVNT_ID);
        !          2208:        }
        !          2209:        if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
        !          2210:                msyslog(LOG_NOTICE, "crypto_iff: invalid filestamp %u",
        !          2211:                    ntohl(ep->fstamp));
        !          2212:                return (XEVNT_FSP);
        !          2213:        }
        !          2214:        if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
        !          2215:                msyslog(LOG_NOTICE, "crypto_iff: defective key");
        !          2216:                return (XEVNT_PUB);
        !          2217:        }
        !          2218:        if (peer->iffval == NULL) {
        !          2219:                msyslog(LOG_NOTICE, "crypto_iff: missing challenge");
        !          2220:                return (XEVNT_ID);
        !          2221:        }
        !          2222: 
        !          2223:        /*
        !          2224:         * Extract the k + b r and g^k values from the response.
        !          2225:         */
        !          2226:        bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
        !          2227:        len = ntohl(ep->vallen);
        !          2228:        ptr = (u_char *)ep->pkt;
        !          2229:        if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
        !          2230:                BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
        !          2231:                msyslog(LOG_ERR, "crypto_iff: %s",
        !          2232:                    ERR_error_string(ERR_get_error(), NULL));
        !          2233:                return (XEVNT_ERR);
        !          2234:        }
        !          2235: 
        !          2236:        /*
        !          2237:         * Compute g^(k + b r) g^(q - b)r mod p.
        !          2238:         */
        !          2239:        BN_mod_exp(bn, dsa->pub_key, peer->iffval, dsa->p, bctx);
        !          2240:        BN_mod_exp(bk, dsa->g, sdsa->r, dsa->p, bctx);
        !          2241:        BN_mod_mul(bn, bn, bk, dsa->p, bctx);
        !          2242: 
        !          2243:        /*
        !          2244:         * Verify the hash of the result matches hash(x).
        !          2245:         */
        !          2246:        bighash(bn, bn);
        !          2247:        temp = BN_cmp(bn, sdsa->s);
        !          2248:        BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
        !          2249:        BN_free(peer->iffval);
        !          2250:        peer->iffval = NULL;
        !          2251:        DSA_SIG_free(sdsa);
        !          2252:        if (temp == 0)
        !          2253:                return (XEVNT_OK);
        !          2254: 
        !          2255:        msyslog(LOG_NOTICE, "crypto_iff: identity not verified");
        !          2256:        return (XEVNT_ID);
        !          2257: }
        !          2258: 
        !          2259: 
        !          2260: /*
        !          2261:  ***********************************************************************
        !          2262:  *                                                                    *
        !          2263:  * The following routines implement the Guillou-Quisquater (GQ)        *
        !          2264:  * identity scheme                                                     *
        !          2265:  *                                                                    *
        !          2266:  ***********************************************************************
        !          2267:  *
        !          2268:  * The Guillou-Quisquater (GQ) identity scheme is intended for use when
        !          2269:  * the certificate can be used to convey public parameters. The scheme
        !          2270:  * uses a X509v3 certificate extension field do convey the public key of
        !          2271:  * a private key known only to servers. There are two kinds of files:
        !          2272:  * encrypted server files that contain private and public values and
        !          2273:  * nonencrypted client files that contain only public values. New
        !          2274:  * generations of server files must be securely transmitted to all
        !          2275:  * servers of the group; client files can be distributed by any means.
        !          2276:  * The scheme is self contained and independent of new generations of
        !          2277:  * host keys and sign keys. The scheme is self contained and independent
        !          2278:  * of new generations of host keys and sign keys.
        !          2279:  *
        !          2280:  * The GQ parameters hide in a RSA cuckoo structure which uses the same
        !          2281:  * parameters. The values are used by an identity scheme based on RSA
        !          2282:  * cryptography and described in Stimson p. 300 (with errors). The 512-
        !          2283:  * bit public modulus is n = p q, where p and q are secret large primes.
        !          2284:  * The TA rolls private random group key b as RSA exponent. These values
        !          2285:  * are known to all group members.
        !          2286:  *
        !          2287:  * When rolling new certificates, a server recomputes the private and
        !          2288:  * public keys. The private key u is a random roll, while the public key
        !          2289:  * is the inverse obscured by the group key v = (u^-1)^b. These values
        !          2290:  * replace the private and public keys normally generated by the RSA
        !          2291:  * scheme. Alice challenges Bob to confirm identity using the protocol
        !          2292:  * described below.
        !          2293:  *
        !          2294:  * How it works
        !          2295:  *
        !          2296:  * The scheme goes like this. Both Alice and Bob have the same modulus n
        !          2297:  * and some random b as the group key. These values are computed and
        !          2298:  * distributed in advance via secret means, although only the group key
        !          2299:  * b is truly secret. Each has a private random private key u and public
        !          2300:  * key (u^-1)^b, although not necessarily the same ones. Bob and Alice
        !          2301:  * can regenerate the key pair from time to time without affecting
        !          2302:  * operations. The public key is conveyed on the certificate in an
        !          2303:  * extension field; the private key is never revealed.
        !          2304:  *
        !          2305:  * Alice rolls new random challenge r and sends to Bob in the GQ
        !          2306:  * request message. Bob rolls new random k, then computes y = k u^r mod
        !          2307:  * n and x = k^b mod n and sends (y, hash(x)) to Alice in the response
        !          2308:  * message. Besides making the response shorter, the hash makes it
        !          2309:  * effectivey impossible for an intruder to solve for b by observing
        !          2310:  * a number of these messages.
        !          2311:  * 
        !          2312:  * Alice receives the response and computes y^b v^r mod n. After a bit
        !          2313:  * of algebra, this simplifies to k^b. If the hash of this result
        !          2314:  * matches hash(x), Alice knows that Bob has the group key b. The signed
        !          2315:  * response binds this knowledge to Bob's private key and the public key
        !          2316:  * previously received in his certificate.
        !          2317:  *
        !          2318:  * crypto_alice2 - construct Alice's challenge in GQ scheme
        !          2319:  *
        !          2320:  * Returns
        !          2321:  * XEVNT_OK    success
        !          2322:  * XEVNT_ID    bad or missing group key
        !          2323:  * XEVNT_PUB   bad or missing public key
        !          2324:  */
        !          2325: static int
        !          2326: crypto_alice2(
        !          2327:        struct peer *peer,      /* peer pointer */
        !          2328:        struct value *vp        /* value pointer */
        !          2329:        )
        !          2330: {
        !          2331:        RSA     *rsa;           /* GQ parameters */
        !          2332:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2333:        EVP_MD_CTX ctx;         /* signature context */
        !          2334:        tstamp_t tstamp;
        !          2335:        u_int   len;
        !          2336: 
        !          2337:        /*
        !          2338:         * The identity parameters must have correct format and content.
        !          2339:         */
        !          2340:        if (peer->ident_pkey == NULL)
        !          2341:                return (XEVNT_ID);
        !          2342: 
        !          2343:        if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) {
        !          2344:                msyslog(LOG_NOTICE, "crypto_alice2: defective key");
        !          2345:                return (XEVNT_PUB);
        !          2346:        }
        !          2347: 
        !          2348:        /*
        !          2349:         * Roll new random r (0 < r < n).
        !          2350:         */
        !          2351:        if (peer->iffval != NULL)
        !          2352:                BN_free(peer->iffval);
        !          2353:        peer->iffval = BN_new();
        !          2354:        len = BN_num_bytes(rsa->n);
        !          2355:        BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod n */
        !          2356:        bctx = BN_CTX_new();
        !          2357:        BN_mod(peer->iffval, peer->iffval, rsa->n, bctx);
        !          2358:        BN_CTX_free(bctx);
        !          2359: 
        !          2360:        /*
        !          2361:         * Sign and send to Bob. The filestamp is from the local file.
        !          2362:         */
        !          2363:        memset(vp, 0, sizeof(struct value));
        !          2364:        tstamp = crypto_time();
        !          2365:        vp->tstamp = htonl(tstamp);
        !          2366:        vp->fstamp = htonl(peer->ident_pkey->fstamp);
        !          2367:        vp->vallen = htonl(len);
        !          2368:        vp->ptr = emalloc(len);
        !          2369:        BN_bn2bin(peer->iffval, vp->ptr);
        !          2370:        if (tstamp == 0)
        !          2371:                return (XEVNT_OK);
        !          2372: 
        !          2373:        vp->sig = emalloc(sign_siglen);
        !          2374:        EVP_SignInit(&ctx, sign_digest);
        !          2375:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2376:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2377:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2378:                vp->siglen = htonl(sign_siglen);
        !          2379:        return (XEVNT_OK);
        !          2380: }
        !          2381: 
        !          2382: 
        !          2383: /*
        !          2384:  * crypto_bob2 - construct Bob's response to Alice's challenge
        !          2385:  *
        !          2386:  * Returns
        !          2387:  * XEVNT_OK    success
        !          2388:  * XEVNT_ERR   protocol error
        !          2389:  * XEVNT_ID    bad or missing group key
        !          2390:  */
        !          2391: static int
        !          2392: crypto_bob2(
        !          2393:        struct exten *ep,       /* extension pointer */
        !          2394:        struct value *vp        /* value pointer */
        !          2395:        )
        !          2396: {
        !          2397:        RSA     *rsa;           /* GQ parameters */
        !          2398:        DSA_SIG *sdsa;          /* DSA parameters */
        !          2399:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2400:        EVP_MD_CTX ctx;         /* signature context */
        !          2401:        tstamp_t tstamp;        /* NTP timestamp */
        !          2402:        BIGNUM  *r, *k, *g, *y;
        !          2403:        u_char  *ptr;
        !          2404:        u_int   len;
        !          2405: 
        !          2406:        /*
        !          2407:         * If the GQ parameters are not valid, something awful
        !          2408:         * happened or we are being tormented.
        !          2409:         */
        !          2410:        if (gqkey_info == NULL) {
        !          2411:                msyslog(LOG_NOTICE, "crypto_bob2: scheme unavailable");
        !          2412:                return (XEVNT_ID);
        !          2413:        }
        !          2414:        rsa = gqkey_info->pkey->pkey.rsa;
        !          2415: 
        !          2416:        /*
        !          2417:         * Extract r from the challenge.
        !          2418:         */
        !          2419:        len = ntohl(ep->vallen);
        !          2420:        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
        !          2421:                msyslog(LOG_ERR, "crypto_bob2: %s",
        !          2422:                    ERR_error_string(ERR_get_error(), NULL));
        !          2423:                return (XEVNT_ERR);
        !          2424:        }
        !          2425: 
        !          2426:        /*
        !          2427:         * Bob rolls random k (0 < k < n), computes y = k u^r mod n and
        !          2428:         * x = k^b mod n, then sends (y, hash(x)) to Alice. 
        !          2429:         */
        !          2430:        bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new();
        !          2431:        sdsa = DSA_SIG_new();
        !          2432:        BN_rand(k, len * 8, -1, 1);             /* k */
        !          2433:        BN_mod(k, k, rsa->n, bctx);
        !          2434:        BN_mod_exp(y, rsa->p, r, rsa->n, bctx); /* u^r mod n */
        !          2435:        BN_mod_mul(y, k, y, rsa->n, bctx);      /* k u^r mod n */
        !          2436:        sdsa->r = BN_dup(y);
        !          2437:        BN_mod_exp(g, k, rsa->e, rsa->n, bctx); /* k^b mod n */
        !          2438:        bighash(g, g);
        !          2439:        sdsa->s = BN_dup(g);
        !          2440:        BN_CTX_free(bctx);
        !          2441:        BN_free(r); BN_free(k); BN_free(g); BN_free(y);
        !          2442: #ifdef DEBUG
        !          2443:        if (debug > 1)
        !          2444:                RSA_print_fp(stdout, rsa, 0);
        !          2445: #endif
        !          2446:  
        !          2447:        /*
        !          2448:         * Encode the values in ASN.1 and sign. The filestamp is from
        !          2449:         * the local file.
        !          2450:         */
        !          2451:        len = i2d_DSA_SIG(sdsa, NULL);
        !          2452:        if (len <= 0) {
        !          2453:                msyslog(LOG_ERR, "crypto_bob2: %s",
        !          2454:                    ERR_error_string(ERR_get_error(), NULL));
        !          2455:                DSA_SIG_free(sdsa);
        !          2456:                return (XEVNT_ERR);
        !          2457:        }
        !          2458:        memset(vp, 0, sizeof(struct value));
        !          2459:        tstamp = crypto_time();
        !          2460:        vp->tstamp = htonl(tstamp);
        !          2461:        vp->fstamp = htonl(gqkey_info->fstamp);
        !          2462:        vp->vallen = htonl(len);
        !          2463:        ptr = emalloc(len);
        !          2464:        vp->ptr = ptr;
        !          2465:        i2d_DSA_SIG(sdsa, &ptr);
        !          2466:        DSA_SIG_free(sdsa);
        !          2467:        if (tstamp == 0)
        !          2468:                return (XEVNT_OK);
        !          2469: 
        !          2470:        vp->sig = emalloc(sign_siglen);
        !          2471:        EVP_SignInit(&ctx, sign_digest);
        !          2472:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2473:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2474:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2475:                vp->siglen = htonl(sign_siglen);
        !          2476:        return (XEVNT_OK);
        !          2477: }
        !          2478: 
        !          2479: 
        !          2480: /*
        !          2481:  * crypto_gq - verify Bob's response to Alice's challenge
        !          2482:  *
        !          2483:  * Returns
        !          2484:  * XEVNT_OK    success
        !          2485:  * XEVNT_ERR   protocol error
        !          2486:  * XEVNT_FSP   bad filestamp
        !          2487:  * XEVNT_ID    bad or missing group keys
        !          2488:  * XEVNT_PUB   bad or missing public key
        !          2489:  */
        !          2490: int
        !          2491: crypto_gq(
        !          2492:        struct exten *ep,       /* extension pointer */
        !          2493:        struct peer *peer       /* peer structure pointer */
        !          2494:        )
        !          2495: {
        !          2496:        RSA     *rsa;           /* GQ parameters */
        !          2497:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2498:        DSA_SIG *sdsa;          /* RSA signature context fake */
        !          2499:        BIGNUM  *y, *v;
        !          2500:        const u_char *ptr;
        !          2501:        long    len;
        !          2502:        u_int   temp;
        !          2503: 
        !          2504:        /*
        !          2505:         * If the GQ parameters are not valid or no challenge was sent,
        !          2506:         * something awful happened or we are being tormented. Note that
        !          2507:         * the filestamp on the local key file can be greater than on
        !          2508:         * the remote parameter file if the keys have been refreshed.
        !          2509:         */
        !          2510:        if (peer->ident_pkey == NULL) {
        !          2511:                msyslog(LOG_NOTICE, "crypto_gq: scheme unavailable");
        !          2512:                return (XEVNT_ID);
        !          2513:        }
        !          2514:        if (ntohl(ep->fstamp) < peer->ident_pkey->fstamp) {
        !          2515:                msyslog(LOG_NOTICE, "crypto_gq: invalid filestamp %u",
        !          2516:                    ntohl(ep->fstamp));
        !          2517:                return (XEVNT_FSP);
        !          2518:        }
        !          2519:        if ((rsa = peer->ident_pkey->pkey->pkey.rsa) == NULL) {
        !          2520:                msyslog(LOG_NOTICE, "crypto_gq: defective key");
        !          2521:                return (XEVNT_PUB);
        !          2522:        }
        !          2523:        if (peer->iffval == NULL) {
        !          2524:                msyslog(LOG_NOTICE, "crypto_gq: missing challenge");
        !          2525:                return (XEVNT_ID);
        !          2526:        }
        !          2527: 
        !          2528:        /*
        !          2529:         * Extract the y = k u^r and hash(x = k^b) values from the
        !          2530:         * response.
        !          2531:         */
        !          2532:        bctx = BN_CTX_new(); y = BN_new(); v = BN_new();
        !          2533:        len = ntohl(ep->vallen);
        !          2534:        ptr = (u_char *)ep->pkt;
        !          2535:        if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
        !          2536:                BN_CTX_free(bctx); BN_free(y); BN_free(v);
        !          2537:                msyslog(LOG_ERR, "crypto_gq: %s",
        !          2538:                    ERR_error_string(ERR_get_error(), NULL));
        !          2539:                return (XEVNT_ERR);
        !          2540:        }
        !          2541: 
        !          2542:        /*
        !          2543:         * Compute v^r y^b mod n.
        !          2544:         */
        !          2545:        if (peer->grpkey == NULL) {
        !          2546:                msyslog(LOG_NOTICE, "crypto_gq: missing group key");
        !          2547:                return (XEVNT_ID);
        !          2548:        }
        !          2549:        BN_mod_exp(v, peer->grpkey, peer->iffval, rsa->n, bctx);
        !          2550:                                                /* v^r mod n */
        !          2551:        BN_mod_exp(y, sdsa->r, rsa->e, rsa->n, bctx); /* y^b mod n */
        !          2552:        BN_mod_mul(y, v, y, rsa->n, bctx);      /* v^r y^b mod n */
        !          2553: 
        !          2554:        /*
        !          2555:         * Verify the hash of the result matches hash(x).
        !          2556:         */
        !          2557:        bighash(y, y);
        !          2558:        temp = BN_cmp(y, sdsa->s);
        !          2559:        BN_CTX_free(bctx); BN_free(y); BN_free(v);
        !          2560:        BN_free(peer->iffval);
        !          2561:        peer->iffval = NULL;
        !          2562:        DSA_SIG_free(sdsa);
        !          2563:        if (temp == 0)
        !          2564:                return (XEVNT_OK);
        !          2565: 
        !          2566:        msyslog(LOG_NOTICE, "crypto_gq: identity not verified");
        !          2567:        return (XEVNT_ID);
        !          2568: }
        !          2569: 
        !          2570: 
        !          2571: /*
        !          2572:  ***********************************************************************
        !          2573:  *                                                                    *
        !          2574:  * The following routines implement the Mu-Varadharajan (MV) identity  *
        !          2575:  * scheme                                                              *
        !          2576:  *                                                                    *
        !          2577:  ***********************************************************************
        !          2578:  *
        !          2579:  * The Mu-Varadharajan (MV) cryptosystem was originally intended when
        !          2580:  * servers broadcast messages to clients, but clients never send
        !          2581:  * messages to servers. There is one encryption key for the server and a
        !          2582:  * separate decryption key for each client. It operated something like a
        !          2583:  * pay-per-view satellite broadcasting system where the session key is
        !          2584:  * encrypted by the broadcaster and the decryption keys are held in a
        !          2585:  * tamperproof set-top box.
        !          2586:  *
        !          2587:  * The MV parameters and private encryption key hide in a DSA cuckoo
        !          2588:  * structure which uses the same parameters, but generated in a
        !          2589:  * different way. The values are used in an encryption scheme similar to
        !          2590:  * El Gamal cryptography and a polynomial formed from the expansion of
        !          2591:  * product terms (x - x[j]), as described in Mu, Y., and V.
        !          2592:  * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001,
        !          2593:  * 223-231. The paper has significant errors and serious omissions.
        !          2594:  *
        !          2595:  * Let q be the product of n distinct primes s1[j] (j = 1...n), where
        !          2596:  * each s1[j] has m significant bits. Let p be a prime p = 2 * q + 1, so
        !          2597:  * that q and each s1[j] divide p - 1 and p has M = n * m + 1
        !          2598:  * significant bits. Let g be a generator of Zp; that is, gcd(g, p - 1)
        !          2599:  * = 1 and g^q = 1 mod p. We do modular arithmetic over Zq and then
        !          2600:  * project into Zp* as exponents of g. Sometimes we have to compute an
        !          2601:  * inverse b^-1 of random b in Zq, but for that purpose we require
        !          2602:  * gcd(b, q) = 1. We expect M to be in the 500-bit range and n
        !          2603:  * relatively small, like 30. These are the parameters of the scheme and
        !          2604:  * they are expensive to compute.
        !          2605:  *
        !          2606:  * We set up an instance of the scheme as follows. A set of random
        !          2607:  * values x[j] mod q (j = 1...n), are generated as the zeros of a
        !          2608:  * polynomial of order n. The product terms (x - x[j]) are expanded to
        !          2609:  * form coefficients a[i] mod q (i = 0...n) in powers of x. These are
        !          2610:  * used as exponents of the generator g mod p to generate the private
        !          2611:  * encryption key A. The pair (gbar, ghat) of public server keys and the
        !          2612:  * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used
        !          2613:  * to construct the decryption keys. The devil is in the details.
        !          2614:  *
        !          2615:  * This routine generates a private server encryption file including the
        !          2616:  * private encryption key E and partial decryption keys gbar and ghat.
        !          2617:  * It then generates public client decryption files including the public
        !          2618:  * keys xbar[j] and xhat[j] for each client j. The partial decryption
        !          2619:  * files are used to compute the inverse of E. These values are suitably
        !          2620:  * blinded so secrets are not revealed.
        !          2621:  *
        !          2622:  * The distinguishing characteristic of this scheme is the capability to
        !          2623:  * revoke keys. Included in the calculation of E, gbar and ghat is the
        !          2624:  * product s = prod(s1[j]) (j = 1...n) above. If the factor s1[j] is
        !          2625:  * subsequently removed from the product and E, gbar and ghat
        !          2626:  * recomputed, the jth client will no longer be able to compute E^-1 and
        !          2627:  * thus unable to decrypt the messageblock.
        !          2628:  *
        !          2629:  * How it works
        !          2630:  *
        !          2631:  * The scheme goes like this. Bob has the server values (p, E, q, gbar,
        !          2632:  * ghat) and Alice has the client values (p, xbar, xhat).
        !          2633:  *
        !          2634:  * Alice rolls new random nonce r mod p and sends to Bob in the MV
        !          2635:  * request message. Bob rolls random nonce k mod q, encrypts y = r E^k
        !          2636:  * mod p and sends (y, gbar^k, ghat^k) to Alice.
        !          2637:  * 
        !          2638:  * Alice receives the response and computes the inverse (E^k)^-1 from
        !          2639:  * the partial decryption keys gbar^k, ghat^k, xbar and xhat. She then
        !          2640:  * decrypts y and verifies it matches the original r. The signed
        !          2641:  * response binds this knowledge to Bob's private key and the public key
        !          2642:  * previously received in his certificate.
        !          2643:  *
        !          2644:  * crypto_alice3 - construct Alice's challenge in MV scheme
        !          2645:  *
        !          2646:  * Returns
        !          2647:  * XEVNT_OK    success
        !          2648:  * XEVNT_ID    bad or missing group key
        !          2649:  * XEVNT_PUB   bad or missing public key
        !          2650:  */
        !          2651: static int
        !          2652: crypto_alice3(
        !          2653:        struct peer *peer,      /* peer pointer */
        !          2654:        struct value *vp        /* value pointer */
        !          2655:        )
        !          2656: {
        !          2657:        DSA     *dsa;           /* MV parameters */
        !          2658:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2659:        EVP_MD_CTX ctx;         /* signature context */
        !          2660:        tstamp_t tstamp;
        !          2661:        u_int   len;
        !          2662: 
        !          2663:        /*
        !          2664:         * The identity parameters must have correct format and content.
        !          2665:         */
        !          2666:        if (peer->ident_pkey == NULL)
        !          2667:                return (XEVNT_ID);
        !          2668: 
        !          2669:        if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
        !          2670:                msyslog(LOG_NOTICE, "crypto_alice3: defective key");
        !          2671:                return (XEVNT_PUB);
        !          2672:        }
        !          2673: 
        !          2674:        /*
        !          2675:         * Roll new random r (0 < r < q).
        !          2676:         */
        !          2677:        if (peer->iffval != NULL)
        !          2678:                BN_free(peer->iffval);
        !          2679:        peer->iffval = BN_new();
        !          2680:        len = BN_num_bytes(dsa->p);
        !          2681:        BN_rand(peer->iffval, len * 8, -1, 1);  /* r mod p */
        !          2682:        bctx = BN_CTX_new();
        !          2683:        BN_mod(peer->iffval, peer->iffval, dsa->p, bctx);
        !          2684:        BN_CTX_free(bctx);
        !          2685: 
        !          2686:        /*
        !          2687:         * Sign and send to Bob. The filestamp is from the local file.
        !          2688:         */
        !          2689:        memset(vp, 0, sizeof(struct value));
        !          2690:        tstamp = crypto_time();
        !          2691:        vp->tstamp = htonl(tstamp);
        !          2692:        vp->fstamp = htonl(peer->ident_pkey->fstamp);
        !          2693:        vp->vallen = htonl(len);
        !          2694:        vp->ptr = emalloc(len);
        !          2695:        BN_bn2bin(peer->iffval, vp->ptr);
        !          2696:        if (tstamp == 0)
        !          2697:                return (XEVNT_OK);
        !          2698: 
        !          2699:        vp->sig = emalloc(sign_siglen);
        !          2700:        EVP_SignInit(&ctx, sign_digest);
        !          2701:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2702:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2703:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2704:                vp->siglen = htonl(sign_siglen);
        !          2705:        return (XEVNT_OK);
        !          2706: }
        !          2707: 
        !          2708: 
        !          2709: /*
        !          2710:  * crypto_bob3 - construct Bob's response to Alice's challenge
        !          2711:  *
        !          2712:  * Returns
        !          2713:  * XEVNT_OK    success
        !          2714:  * XEVNT_ERR   protocol error
        !          2715:  */
        !          2716: static int
        !          2717: crypto_bob3(
        !          2718:        struct exten *ep,       /* extension pointer */
        !          2719:        struct value *vp        /* value pointer */
        !          2720:        )
        !          2721: {
        !          2722:        DSA     *dsa;           /* MV parameters */
        !          2723:        DSA     *sdsa;          /* DSA signature context fake */
        !          2724:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2725:        EVP_MD_CTX ctx;         /* signature context */
        !          2726:        tstamp_t tstamp;        /* NTP timestamp */
        !          2727:        BIGNUM  *r, *k, *u;
        !          2728:        u_char  *ptr;
        !          2729:        u_int   len;
        !          2730: 
        !          2731:        /*
        !          2732:         * If the MV parameters are not valid, something awful
        !          2733:         * happened or we are being tormented.
        !          2734:         */
        !          2735:        if (mvkey_info == NULL) {
        !          2736:                msyslog(LOG_NOTICE, "crypto_bob3: scheme unavailable");
        !          2737:                return (XEVNT_ID);
        !          2738:        }
        !          2739:        dsa = mvkey_info->pkey->pkey.dsa;
        !          2740: 
        !          2741:        /*
        !          2742:         * Extract r from the challenge.
        !          2743:         */
        !          2744:        len = ntohl(ep->vallen);
        !          2745:        if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
        !          2746:                msyslog(LOG_ERR, "crypto_bob3: %s",
        !          2747:                    ERR_error_string(ERR_get_error(), NULL));
        !          2748:                return (XEVNT_ERR);
        !          2749:        }
        !          2750: 
        !          2751:        /*
        !          2752:         * Bob rolls random k (0 < k < q), making sure it is not a
        !          2753:         * factor of q. He then computes y = r A^k and sends (y, gbar^k,
        !          2754:         * and ghat^k) to Alice.
        !          2755:         */
        !          2756:        bctx = BN_CTX_new(); k = BN_new(); u = BN_new();
        !          2757:        sdsa = DSA_new();
        !          2758:        sdsa->p = BN_new(); sdsa->q = BN_new(); sdsa->g = BN_new();
        !          2759:        while (1) {
        !          2760:                BN_rand(k, BN_num_bits(dsa->q), 0, 0);
        !          2761:                BN_mod(k, k, dsa->q, bctx);
        !          2762:                BN_gcd(u, k, dsa->q, bctx);
        !          2763:                if (BN_is_one(u))
        !          2764:                        break;
        !          2765:        }
        !          2766:        BN_mod_exp(u, dsa->g, k, dsa->p, bctx); /* A^k r */
        !          2767:        BN_mod_mul(sdsa->p, u, r, dsa->p, bctx);
        !          2768:        BN_mod_exp(sdsa->q, dsa->priv_key, k, dsa->p, bctx); /* gbar */
        !          2769:        BN_mod_exp(sdsa->g, dsa->pub_key, k, dsa->p, bctx); /* ghat */
        !          2770:        BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u);
        !          2771: #ifdef DEBUG
        !          2772:        if (debug > 1)
        !          2773:                DSA_print_fp(stdout, sdsa, 0);
        !          2774: #endif
        !          2775: 
        !          2776:        /*
        !          2777:         * Encode the values in ASN.1 and sign. The filestamp is from
        !          2778:         * the local file.
        !          2779:         */
        !          2780:        memset(vp, 0, sizeof(struct value));
        !          2781:        tstamp = crypto_time();
        !          2782:        vp->tstamp = htonl(tstamp);
        !          2783:        vp->fstamp = htonl(mvkey_info->fstamp);
        !          2784:        len = i2d_DSAparams(sdsa, NULL);
        !          2785:        if (len == 0) {
        !          2786:                msyslog(LOG_ERR, "crypto_bob3: %s",
        !          2787:                    ERR_error_string(ERR_get_error(), NULL));
        !          2788:                DSA_free(sdsa);
        !          2789:                return (XEVNT_ERR);
        !          2790:        }
        !          2791:        vp->vallen = htonl(len);
        !          2792:        ptr = emalloc(len);
        !          2793:        vp->ptr = ptr;
        !          2794:        i2d_DSAparams(sdsa, &ptr);
        !          2795:        DSA_free(sdsa);
        !          2796:        if (tstamp == 0)
        !          2797:                return (XEVNT_OK);
        !          2798: 
        !          2799:        vp->sig = emalloc(sign_siglen);
        !          2800:        EVP_SignInit(&ctx, sign_digest);
        !          2801:        EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12);
        !          2802:        EVP_SignUpdate(&ctx, vp->ptr, len);
        !          2803:        if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          2804:                vp->siglen = htonl(sign_siglen);
        !          2805:        return (XEVNT_OK);
        !          2806: }
        !          2807: 
        !          2808: 
        !          2809: /*
        !          2810:  * crypto_mv - verify Bob's response to Alice's challenge
        !          2811:  *
        !          2812:  * Returns
        !          2813:  * XEVNT_OK    success
        !          2814:  * XEVNT_ERR   protocol error
        !          2815:  * XEVNT_FSP   bad filestamp
        !          2816:  * XEVNT_ID    bad or missing group key
        !          2817:  * XEVNT_PUB   bad or missing public key
        !          2818:  */
        !          2819: int
        !          2820: crypto_mv(
        !          2821:        struct exten *ep,       /* extension pointer */
        !          2822:        struct peer *peer       /* peer structure pointer */
        !          2823:        )
        !          2824: {
        !          2825:        DSA     *dsa;           /* MV parameters */
        !          2826:        DSA     *sdsa;          /* DSA parameters */
        !          2827:        BN_CTX  *bctx;          /* BIGNUM context */
        !          2828:        BIGNUM  *k, *u, *v;
        !          2829:        u_int   len;
        !          2830:        const u_char *ptr;
        !          2831:        int     temp;
        !          2832: 
        !          2833:        /*
        !          2834:         * If the MV parameters are not valid or no challenge was sent,
        !          2835:         * something awful happened or we are being tormented.
        !          2836:         */
        !          2837:        if (peer->ident_pkey == NULL) {
        !          2838:                msyslog(LOG_NOTICE, "crypto_mv: scheme unavailable");
        !          2839:                return (XEVNT_ID);
        !          2840:        }
        !          2841:        if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
        !          2842:                msyslog(LOG_NOTICE, "crypto_mv: invalid filestamp %u",
        !          2843:                    ntohl(ep->fstamp));
        !          2844:                return (XEVNT_FSP);
        !          2845:        }
        !          2846:        if ((dsa = peer->ident_pkey->pkey->pkey.dsa) == NULL) {
        !          2847:                msyslog(LOG_NOTICE, "crypto_mv: defective key");
        !          2848:                return (XEVNT_PUB);
        !          2849:        }
        !          2850:        if (peer->iffval == NULL) {
        !          2851:                msyslog(LOG_NOTICE, "crypto_mv: missing challenge");
        !          2852:                return (XEVNT_ID);
        !          2853:        }
        !          2854: 
        !          2855:        /*
        !          2856:         * Extract the y, gbar and ghat values from the response.
        !          2857:         */
        !          2858:        bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new();
        !          2859:        len = ntohl(ep->vallen);
        !          2860:        ptr = (u_char *)ep->pkt;
        !          2861:        if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) {
        !          2862:                msyslog(LOG_ERR, "crypto_mv: %s",
        !          2863:                    ERR_error_string(ERR_get_error(), NULL));
        !          2864:                return (XEVNT_ERR);
        !          2865:        }
        !          2866: 
        !          2867:        /*
        !          2868:         * Compute (gbar^xhat ghat^xbar) mod p.
        !          2869:         */
        !          2870:        BN_mod_exp(u, sdsa->q, dsa->pub_key, dsa->p, bctx);
        !          2871:        BN_mod_exp(v, sdsa->g, dsa->priv_key, dsa->p, bctx);
        !          2872:        BN_mod_mul(u, u, v, dsa->p, bctx);
        !          2873:        BN_mod_mul(u, u, sdsa->p, dsa->p, bctx);
        !          2874: 
        !          2875:        /*
        !          2876:         * The result should match r.
        !          2877:         */
        !          2878:        temp = BN_cmp(u, peer->iffval);
        !          2879:        BN_CTX_free(bctx); BN_free(k); BN_free(u); BN_free(v);
        !          2880:        BN_free(peer->iffval);
        !          2881:        peer->iffval = NULL;
        !          2882:        DSA_free(sdsa);
        !          2883:        if (temp == 0)
        !          2884:                return (XEVNT_OK);
        !          2885: 
        !          2886:        msyslog(LOG_NOTICE, "crypto_mv: identity not verified");
        !          2887:        return (XEVNT_ID);
        !          2888: }
        !          2889: 
        !          2890: 
        !          2891: /*
        !          2892:  ***********************************************************************
        !          2893:  *                                                                    *
        !          2894:  * The following routines are used to manipulate certificates          *
        !          2895:  *                                                                    *
        !          2896:  ***********************************************************************
        !          2897:  */
        !          2898: /*
        !          2899:  * cert_sign - sign x509 certificate equest and update value structure.
        !          2900:  *
        !          2901:  * The certificate request includes a copy of the host certificate,
        !          2902:  * which includes the version number, subject name and public key of the
        !          2903:  * host. The resulting certificate includes these values plus the
        !          2904:  * serial number, issuer name and valid interval of the server. The
        !          2905:  * valid interval extends from the current time to the same time one
        !          2906:  * year hence. This may extend the life of the signed certificate beyond
        !          2907:  * that of the signer certificate.
        !          2908:  *
        !          2909:  * It is convenient to use the NTP seconds of the current time as the
        !          2910:  * serial number. In the value structure the timestamp is the current
        !          2911:  * time and the filestamp is taken from the extension field. Note this
        !          2912:  * routine is called only when the client clock is synchronized to a
        !          2913:  * proventic source, so timestamp comparisons are valid.
        !          2914:  *
        !          2915:  * The host certificate is valid from the time it was generated for a
        !          2916:  * period of one year. A signed certificate is valid from the time of
        !          2917:  * signature for a period of one year, but only the host certificate (or
        !          2918:  * sign certificate if used) is actually used to encrypt and decrypt
        !          2919:  * signatures. The signature trail is built from the client via the
        !          2920:  * intermediate servers to the trusted server. Each signature on the
        !          2921:  * trail must be valid at the time of signature, but it could happen
        !          2922:  * that a signer certificate expire before the signed certificate, which
        !          2923:  * remains valid until its expiration. 
        !          2924:  *
        !          2925:  * Returns
        !          2926:  * XEVNT_OK    success
        !          2927:  * XEVNT_CRT   bad or missing certificate
        !          2928:  * XEVNT_PER   host certificate expired
        !          2929:  * XEVNT_PUB   bad or missing public key
        !          2930:  * XEVNT_VFY   certificate not verified
        !          2931:  */
        !          2932: static int
        !          2933: cert_sign(
        !          2934:        struct exten *ep,       /* extension field pointer */
        !          2935:        struct value *vp        /* value pointer */
        !          2936:        )
        !          2937: {
        !          2938:        X509    *req;           /* X509 certificate request */
        !          2939:        X509    *cert;          /* X509 certificate */
        !          2940:        X509_EXTENSION *ext;    /* certificate extension */
        !          2941:        ASN1_INTEGER *serial;   /* serial number */
        !          2942:        X509_NAME *subj;        /* distinguished (common) name */
        !          2943:        EVP_PKEY *pkey;         /* public key */
        !          2944:        EVP_MD_CTX ctx;         /* message digest context */
        !          2945:        tstamp_t tstamp;        /* NTP timestamp */
        !          2946:        u_int   len;
        !          2947:        u_char  *ptr;
        !          2948:        int     i, temp;
        !          2949: 
        !          2950:        /*
        !          2951:         * Decode ASN.1 objects and construct certificate structure.
        !          2952:         * Make sure the system clock is synchronized to a proventic
        !          2953:         * source.
        !          2954:         */
        !          2955:        tstamp = crypto_time();
        !          2956:        if (tstamp == 0)
        !          2957:                return (XEVNT_TSP);
        !          2958: 
        !          2959:        ptr = (u_char *)ep->pkt;
        !          2960:        if ((req = d2i_X509(NULL, &ptr, ntohl(ep->vallen))) == NULL) {
        !          2961:                msyslog(LOG_ERR, "cert_sign: %s",
        !          2962:                    ERR_error_string(ERR_get_error(), NULL));
        !          2963:                return (XEVNT_CRT);
        !          2964:        }
        !          2965:        /*
        !          2966:         * Extract public key and check for errors.
        !          2967:         */
        !          2968:        if ((pkey = X509_get_pubkey(req)) == NULL) {
        !          2969:                msyslog(LOG_ERR, "cert_sign: %s",
        !          2970:                    ERR_error_string(ERR_get_error(), NULL));
        !          2971:                X509_free(req);
        !          2972:                return (XEVNT_PUB);
        !          2973:        }
        !          2974: 
        !          2975:        /*
        !          2976:         * Generate X509 certificate signed by this server. If this is a
        !          2977:         * trusted host, the issuer name is the group name; otherwise,
        !          2978:         * it is the host name. Also copy any extensions that might be
        !          2979:         * present.
        !          2980:         */
        !          2981:        cert = X509_new();
        !          2982:        X509_set_version(cert, X509_get_version(req));
        !          2983:        serial = ASN1_INTEGER_new();
        !          2984:        ASN1_INTEGER_set(serial, tstamp);
        !          2985:        X509_set_serialNumber(cert, serial);
        !          2986:        X509_gmtime_adj(X509_get_notBefore(cert), 0L);
        !          2987:        X509_gmtime_adj(X509_get_notAfter(cert), YEAR);
        !          2988:        subj = X509_get_issuer_name(cert);
        !          2989:        X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
        !          2990:            hostval.ptr, strlen(hostval.ptr), -1, 0);
        !          2991:        subj = X509_get_subject_name(req);
        !          2992:        X509_set_subject_name(cert, subj);
        !          2993:        X509_set_pubkey(cert, pkey);
        !          2994:        ext = X509_get_ext(req, 0);
        !          2995:        temp = X509_get_ext_count(req);
        !          2996:        for (i = 0; i < temp; i++) {
        !          2997:                ext = X509_get_ext(req, i);
        !          2998:                X509_add_ext(cert, ext, -1);
        !          2999:        }
        !          3000:        X509_free(req);
        !          3001: 
        !          3002:        /*
        !          3003:         * Sign and verify the client certificate, but only if the host
        !          3004:         * certificate has not expired.
        !          3005:         */
        !          3006:        if (tstamp < cert_host->first || tstamp > cert_host->last) {
        !          3007:                X509_free(cert);
        !          3008:                return (XEVNT_PER);
        !          3009:        }
        !          3010:        X509_sign(cert, sign_pkey, sign_digest);
        !          3011:        if (X509_verify(cert, sign_pkey) <= 0) {
        !          3012:                msyslog(LOG_ERR, "cert_sign: %s",
        !          3013:                    ERR_error_string(ERR_get_error(), NULL));
        !          3014:                X509_free(cert);
        !          3015:                return (XEVNT_VFY);
        !          3016:        }
        !          3017:        len = i2d_X509(cert, NULL);
        !          3018: 
        !          3019:        /*
        !          3020:         * Build and sign the value structure. We have to sign it here,
        !          3021:         * since the response has to be returned right away. This is a
        !          3022:         * clogging hazard.
        !          3023:         */
        !          3024:        memset(vp, 0, sizeof(struct value));
        !          3025:        vp->tstamp = htonl(tstamp);
        !          3026:        vp->fstamp = ep->fstamp;
        !          3027:        vp->vallen = htonl(len);
        !          3028:        vp->ptr = emalloc(len);
        !          3029:        ptr = vp->ptr;
        !          3030:        i2d_X509(cert, &ptr);
        !          3031:        vp->siglen = 0;
        !          3032:        if (tstamp != 0) {
        !          3033:                vp->sig = emalloc(sign_siglen);
        !          3034:                EVP_SignInit(&ctx, sign_digest);
        !          3035:                EVP_SignUpdate(&ctx, (u_char *)vp, 12);
        !          3036:                EVP_SignUpdate(&ctx, vp->ptr, len);
        !          3037:                if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey))
        !          3038:                        vp->siglen = htonl(sign_siglen);
        !          3039:        }
        !          3040: #ifdef DEBUG
        !          3041:        if (debug > 1)
        !          3042:                X509_print_fp(stdout, cert);
        !          3043: #endif
        !          3044:        X509_free(cert);
        !          3045:        return (XEVNT_OK);
        !          3046: }
        !          3047: 
        !          3048: 
        !          3049: /*
        !          3050:  * cert_install - install certificate in certificate cache
        !          3051:  *
        !          3052:  * This routine encodes an extension field into a certificate info/value
        !          3053:  * structure. It searches the certificate list for duplicates and
        !          3054:  * expunges whichever is older. Finally, it inserts this certificate
        !          3055:  * first on the list.
        !          3056:  *
        !          3057:  * Returns certificate info pointer if valid, NULL if not.
        !          3058:  */
        !          3059: struct cert_info *
        !          3060: cert_install(
        !          3061:        struct exten *ep,       /* cert info/value */
        !          3062:        struct peer *peer       /* peer structure */
        !          3063:        )
        !          3064: {
        !          3065:        struct cert_info *cp, *xp, **zp;
        !          3066: 
        !          3067:        /*
        !          3068:         * Parse and validate the signed certificate. If valid,
        !          3069:         * construct the info/value structure; otherwise, scamper home
        !          3070:         * empty handed.
        !          3071:         */
        !          3072:        if ((cp = cert_parse((u_char *)ep->pkt, (long)ntohl(ep->vallen),
        !          3073:            (tstamp_t)ntohl(ep->fstamp))) == NULL)
        !          3074:                return (NULL);
        !          3075: 
        !          3076:        /*
        !          3077:         * Scan certificate list looking for another certificate with
        !          3078:         * the same subject and issuer. If another is found with the
        !          3079:         * same or older filestamp, unlink it and return the goodies to
        !          3080:         * the heap. If another is found with a later filestamp, discard
        !          3081:         * the new one and leave the building with the old one.
        !          3082:         *
        !          3083:         * Make a note to study this issue again. An earlier certificate
        !          3084:         * with a long lifetime might be overtaken by a later
        !          3085:         * certificate with a short lifetime, thus invalidating the
        !          3086:         * earlier signature. However, we gotta find a way to leak old
        !          3087:         * stuff from the cache, so we do it anyway. 
        !          3088:         */
        !          3089:        zp = &cinfo;
        !          3090:        for (xp = cinfo; xp != NULL; xp = xp->link) {
        !          3091:                if (strcmp(cp->subject, xp->subject) == 0 &&
        !          3092:                    strcmp(cp->issuer, xp->issuer) == 0) {
        !          3093:                        if (ntohl(cp->cert.fstamp) <=
        !          3094:                            ntohl(xp->cert.fstamp)) {
        !          3095:                                cert_free(cp);
        !          3096:                                cp = xp;
        !          3097:                        } else {
        !          3098:                                *zp = xp->link;
        !          3099:                                cert_free(xp);
        !          3100:                                xp = NULL;
        !          3101:                        }
        !          3102:                        break;
        !          3103:                }
        !          3104:                zp = &xp->link;
        !          3105:        }
        !          3106:        if (xp == NULL) {
        !          3107:                cp->link = cinfo;
        !          3108:                cinfo = cp;
        !          3109:        }
        !          3110:        cp->flags |= CERT_VALID;
        !          3111:        crypto_update();
        !          3112:        return (cp);
        !          3113: }
        !          3114: 
        !          3115: 
        !          3116: /*
        !          3117:  * cert_hike - verify the signature using the issuer public key
        !          3118:  *
        !          3119:  * Returns
        !          3120:  * XEVNT_OK    success
        !          3121:  * XEVNT_CRT   bad or missing certificate
        !          3122:  * XEVNT_PER   host certificate expired
        !          3123:  * XEVNT_VFY   certificate not verified
        !          3124:  */
        !          3125: int
        !          3126: cert_hike(
        !          3127:        struct peer *peer,      /* peer structure pointer */
        !          3128:        struct cert_info *yp    /* issuer certificate */
        !          3129:        )
        !          3130: {
        !          3131:        struct cert_info *xp;   /* subject certificate */
        !          3132:        X509    *cert;          /* X509 certificate */
        !          3133:        u_char  *ptr;
        !          3134: 
        !          3135:        /*
        !          3136:         * Save the issuer on the new certificate, but remember the old
        !          3137:         * one.
        !          3138:         */
        !          3139:        if (peer->issuer != NULL)
        !          3140:                free(peer->issuer);
        !          3141:        peer->issuer = emalloc(strlen(yp->issuer) + 1);
        !          3142:        strcpy(peer->issuer, yp->issuer);
        !          3143:        xp = peer->xinfo;
        !          3144:        peer->xinfo = yp;
        !          3145: 
        !          3146:        /*
        !          3147:         * If subject Y matches issuer Y, then the certificate trail is
        !          3148:         * complete. If Y is not trusted, the server certificate has yet
        !          3149:         * been signed, so keep trying. Otherwise, save the group key
        !          3150:         * and light the valid bit. If the host certificate is trusted,
        !          3151:         * do not execute a sign exchange. If no identity scheme is in
        !          3152:         * use, light the identity and proventic bits.
        !          3153:         */
        !          3154:        if (strcmp(yp->subject, yp->issuer) == 0) {
        !          3155:                if (!(yp->flags & CERT_TRUST))
        !          3156:                        return (XEVNT_OK);
        !          3157: 
        !          3158:                peer->grpkey = yp->grpkey;
        !          3159:                peer->crypto |= CRYPTO_FLAG_CERT;
        !          3160:                if (!(peer->crypto & CRYPTO_FLAG_MASK))
        !          3161:                        peer->crypto |= CRYPTO_FLAG_VRFY |
        !          3162:                            CRYPTO_FLAG_PROV;
        !          3163: 
        !          3164:                /*
        !          3165:                 * If the server has an an identity scheme, fetch the
        !          3166:                 * identity credentials. If not, the identity is
        !          3167:                 * verified only by the trusted certificate. The next
        !          3168:                 * signature will set the server proventic.
        !          3169:                 */
        !          3170:                if (!(peer->crypto & CRYPTO_FLAG_MASK) ||
        !          3171:                    sys_groupname == NULL)
        !          3172:                        peer->crypto |= CRYPTO_FLAG_VRFY;
        !          3173:        }
        !          3174: 
        !          3175:        /*
        !          3176:         * If X exists, verify signature X using public key Y.
        !          3177:         */
        !          3178:        if (xp == NULL)
        !          3179:                return (XEVNT_OK);
        !          3180: 
        !          3181:        ptr = (u_char *)xp->cert.ptr;
        !          3182:        cert = d2i_X509(NULL, &ptr, ntohl(xp->cert.vallen));
        !          3183:        if (cert == NULL) {
        !          3184:                xp->flags |= CERT_ERROR;
        !          3185:                return (XEVNT_CRT);
        !          3186:        }
        !          3187:        if (X509_verify(cert, yp->pkey) <= 0) {
        !          3188:                X509_free(cert);
        !          3189:                xp->flags |= CERT_ERROR;
        !          3190:                return (XEVNT_VFY);
        !          3191:        }
        !          3192:        X509_free(cert);
        !          3193: 
        !          3194:        /*
        !          3195:         * Signature X is valid only if it begins during the
        !          3196:         * lifetime of Y. 
        !          3197:         */
        !          3198:        if (xp->first < yp->first || xp->first > yp->last) {
        !          3199:                xp->flags |= CERT_ERROR;
        !          3200:                return (XEVNT_PER);
        !          3201:        }
        !          3202:        xp->flags |= CERT_SIGN;
        !          3203:        return (XEVNT_OK);
        !          3204: }
        !          3205: 
        !          3206: 
        !          3207: /*
        !          3208:  * cert_parse - parse x509 certificate and create info/value structures.
        !          3209:  *
        !          3210:  * The server certificate includes the version number, issuer name,
        !          3211:  * subject name, public key and valid date interval. If the issuer name
        !          3212:  * is the same as the subject name, the certificate is self signed and
        !          3213:  * valid only if the server is configured as trustable. If the names are
        !          3214:  * different, another issuer has signed the server certificate and
        !          3215:  * vouched for it. In this case the server certificate is valid if
        !          3216:  * verified by the issuer public key.
        !          3217:  *
        !          3218:  * Returns certificate info/value pointer if valid, NULL if not.
        !          3219:  */
        !          3220: struct cert_info *             /* certificate information structure */
        !          3221: cert_parse(
        !          3222:        u_char  *asn1cert,      /* X509 certificate */
        !          3223:        long    len,            /* certificate length */
        !          3224:        tstamp_t fstamp         /* filestamp */
        !          3225:        )
        !          3226: {
        !          3227:        X509    *cert;          /* X509 certificate */
        !          3228:        X509_EXTENSION *ext;    /* X509v3 extension */
        !          3229:        struct cert_info *ret;  /* certificate info/value */
        !          3230:        BIO     *bp;
        !          3231:        char    pathbuf[MAXFILENAME];
        !          3232:        u_char  *ptr;
        !          3233:        int     temp, cnt, i;
        !          3234: 
        !          3235:        /*
        !          3236:         * Decode ASN.1 objects and construct certificate structure.
        !          3237:         */
        !          3238:        ptr = asn1cert;
        !          3239:        if ((cert = d2i_X509(NULL, &ptr, len)) == NULL) {
        !          3240:                msyslog(LOG_ERR, "cert_parse: %s",
        !          3241:                    ERR_error_string(ERR_get_error(), NULL));
        !          3242:                return (NULL);
        !          3243:        }
        !          3244: #ifdef DEBUG
        !          3245:        if (debug > 1)
        !          3246:                X509_print_fp(stdout, cert);
        !          3247: #endif
        !          3248: 
        !          3249:        /*
        !          3250:         * Extract version, subject name and public key.
        !          3251:         */
        !          3252:        ret = emalloc(sizeof(struct cert_info));
        !          3253:        memset(ret, 0, sizeof(struct cert_info));
        !          3254:        if ((ret->pkey = X509_get_pubkey(cert)) == NULL) {
        !          3255:                msyslog(LOG_ERR, "cert_parse: %s",
        !          3256:                    ERR_error_string(ERR_get_error(), NULL));
        !          3257:                cert_free(ret);
        !          3258:                X509_free(cert);
        !          3259:                return (NULL);
        !          3260:        }
        !          3261:        ret->version = X509_get_version(cert);
        !          3262:        X509_NAME_oneline(X509_get_subject_name(cert), pathbuf,
        !          3263:            MAXFILENAME);
        !          3264:        ptr = strstr(pathbuf, "CN=");
        !          3265:        if (ptr == NULL) {
        !          3266:                msyslog(LOG_NOTICE, "cert_parse: invalid subject %s",
        !          3267:                    pathbuf);
        !          3268:                cert_free(ret);
        !          3269:                X509_free(cert);
        !          3270:                return (NULL);
        !          3271:        }
        !          3272:        ret->subject = estrdup(ptr + 3);
        !          3273: 
        !          3274:        /*
        !          3275:         * Extract remaining objects. Note that the NTP serial number is
        !          3276:         * the NTP seconds at the time of signing, but this might not be
        !          3277:         * the case for other authority. We don't bother to check the
        !          3278:         * objects at this time, since the real crunch can happen only
        !          3279:         * when the time is valid but not yet certificated.
        !          3280:         */
        !          3281:        ret->nid = OBJ_obj2nid(cert->cert_info->signature->algorithm);
        !          3282:        ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid);
        !          3283:        ret->serial =
        !          3284:            (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert));
        !          3285:        X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf,
        !          3286:            MAXFILENAME);
        !          3287:        if ((ptr = strstr(pathbuf, "CN=")) == NULL) {
        !          3288:                msyslog(LOG_NOTICE, "cert_parse: invalid issuer %s",
        !          3289:                    pathbuf);
        !          3290:                cert_free(ret);
        !          3291:                X509_free(cert);
        !          3292:                return (NULL);
        !          3293:        }
        !          3294:        ret->issuer = estrdup(ptr + 3);
        !          3295:        ret->first = asn2ntp(X509_get_notBefore(cert));
        !          3296:        ret->last = asn2ntp(X509_get_notAfter(cert));
        !          3297: 
        !          3298:        /*
        !          3299:         * Extract extension fields. These are ad hoc ripoffs of
        !          3300:         * currently assigned functions and will certainly be changed
        !          3301:         * before prime time.
        !          3302:         */
        !          3303:        cnt = X509_get_ext_count(cert);
        !          3304:        for (i = 0; i < cnt; i++) {
        !          3305:                ext = X509_get_ext(cert, i);
        !          3306:                temp = OBJ_obj2nid(ext->object);
        !          3307:                switch (temp) {
        !          3308: 
        !          3309:                /*
        !          3310:                 * If a key_usage field is present, we decode whether
        !          3311:                 * this is a trusted or private certificate. This is
        !          3312:                 * dorky; all we want is to compare NIDs, but OpenSSL
        !          3313:                 * insists on BIO text strings.
        !          3314:                 */
        !          3315:                case NID_ext_key_usage:
        !          3316:                        bp = BIO_new(BIO_s_mem());
        !          3317:                        X509V3_EXT_print(bp, ext, 0, 0);
        !          3318:                        BIO_gets(bp, pathbuf, MAXFILENAME);
        !          3319:                        BIO_free(bp);
        !          3320:                        if (strcmp(pathbuf, "Trust Root") == 0)
        !          3321:                                ret->flags |= CERT_TRUST;
        !          3322:                        else if (strcmp(pathbuf, "Private") == 0)
        !          3323:                                ret->flags |= CERT_PRIV;
        !          3324: #if DEBUG
        !          3325:                        if (debug)
        !          3326:                                printf("cert_parse: %s: %s\n",
        !          3327:                                    OBJ_nid2ln(temp), pathbuf);
        !          3328: #endif
        !          3329:                        break;
        !          3330: 
        !          3331:                /*
        !          3332:                 * If a NID_subject_key_identifier field is present, it
        !          3333:                 * contains the GQ public key.
        !          3334:                 */
        !          3335:                case NID_subject_key_identifier:
        !          3336:                        ret->grpkey = BN_bin2bn(&ext->value->data[2],
        !          3337:                            ext->value->length - 2, NULL);
        !          3338:                        /* fall through */
        !          3339: #if DEBUG
        !          3340:                default:
        !          3341:                        if (debug)
        !          3342:                                printf("cert_parse: %s\n",
        !          3343:                                    OBJ_nid2ln(temp));
        !          3344: #endif
        !          3345:                }
        !          3346:        }
        !          3347:        if (strcmp(ret->subject, ret->issuer) == 0) {
        !          3348: 
        !          3349:                /*
        !          3350:                 * If certificate is self signed, verify signature.
        !          3351:                 */
        !          3352:                if (X509_verify(cert, ret->pkey) <= 0) {
        !          3353:                        msyslog(LOG_NOTICE,
        !          3354:                            "cert_parse: signature not verified %s",
        !          3355:                            ret->subject);
        !          3356:                        cert_free(ret);
        !          3357:                        X509_free(cert);
        !          3358:                        return (NULL);
        !          3359:                }
        !          3360:        } else {
        !          3361: 
        !          3362:                /*
        !          3363:                 * Check for a certificate loop.
        !          3364:                 */
        !          3365:                if (strcmp(hostval.ptr, ret->issuer) == 0) {
        !          3366:                        msyslog(LOG_NOTICE,
        !          3367:                            "cert_parse: certificate trail loop %s",
        !          3368:                            ret->subject);
        !          3369:                        cert_free(ret);
        !          3370:                        X509_free(cert);
        !          3371:                        return (NULL);
        !          3372:                }
        !          3373:        }
        !          3374: 
        !          3375:        /*
        !          3376:         * Verify certificate valid times. Note that certificates cannot
        !          3377:         * be retroactive.
        !          3378:         */
        !          3379:        if (ret->first > ret->last || ret->first < fstamp) {
        !          3380:                msyslog(LOG_NOTICE,
        !          3381:                    "cert_parse: invalid times %s first %u last %u fstamp %u",
        !          3382:                    ret->subject, ret->first, ret->last, fstamp);
        !          3383:                cert_free(ret);
        !          3384:                X509_free(cert);
        !          3385:                return (NULL);
        !          3386:        }
        !          3387: 
        !          3388:        /*
        !          3389:         * Build the value structure to sign and send later.
        !          3390:         */
        !          3391:        ret->cert.fstamp = htonl(fstamp);
        !          3392:        ret->cert.vallen = htonl(len);
        !          3393:        ret->cert.ptr = emalloc(len);
        !          3394:        memcpy(ret->cert.ptr, asn1cert, len);
        !          3395:        X509_free(cert);
        !          3396:        return (ret);
        !          3397: }
        !          3398: 
        !          3399: 
        !          3400: /*
        !          3401:  * cert_free - free certificate information structure
        !          3402:  */
        !          3403: void
        !          3404: cert_free(
        !          3405:        struct cert_info *cinf  /* certificate info/value structure */ 
        !          3406:        )
        !          3407: {
        !          3408:        if (cinf->pkey != NULL)
        !          3409:                EVP_PKEY_free(cinf->pkey);
        !          3410:        if (cinf->subject != NULL)
        !          3411:                free(cinf->subject);
        !          3412:        if (cinf->issuer != NULL)
        !          3413:                free(cinf->issuer);
        !          3414:        if (cinf->grpkey != NULL)
        !          3415:                BN_free(cinf->grpkey);
        !          3416:        value_free(&cinf->cert);
        !          3417:        free(cinf);
        !          3418: }
        !          3419: 
        !          3420: 
        !          3421: /*
        !          3422:  * crypto_key - load cryptographic parameters and keys
        !          3423:  *
        !          3424:  * This routine searches the key cache for matching name in the form
        !          3425:  * ntpkey_<key>_<name>, where <key> is one of host, sign, iff, gq, mv,
        !          3426:  * and <name> is the host/group name. If not found, it tries to load a
        !          3427:  * PEM-encoded file of the same name and extracts the filestamp from
        !          3428:  * the first line of the file name. It returns the key pointer if valid,
        !          3429:  * NULL if not.
        !          3430:  */
        !          3431: static struct pkey_info *
        !          3432: crypto_key(
        !          3433:        char    *cp,            /* file name */
        !          3434:        char    *passwd1,       /* password */
        !          3435:        sockaddr_u *addr        /* IP address */
        !          3436:        )
        !          3437: {
        !          3438:        FILE    *str;           /* file handle */
        !          3439:        struct pkey_info *pkp;  /* generic key */
        !          3440:        EVP_PKEY *pkey = NULL;  /* public/private key */
        !          3441:        tstamp_t fstamp;
        !          3442:        char    filename[MAXFILENAME]; /* name of key file */
        !          3443:        char    linkname[MAXFILENAME]; /* filestamp buffer) */
        !          3444:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !          3445:        char    *ptr;
        !          3446: 
        !          3447:        /*
        !          3448:         * Search the key cache for matching key and name.
        !          3449:         */
        !          3450:        for (pkp = pkinfo; pkp != NULL; pkp = pkp->link) {
        !          3451:                if (strcmp(cp, pkp->name) == 0)
        !          3452:                        return (pkp);
        !          3453:        }  
        !          3454: 
        !          3455:        /*
        !          3456:         * Open the key file. If the first character of the file name is
        !          3457:         * not '/', prepend the keys directory string. If something goes
        !          3458:         * wrong, abandon ship.
        !          3459:         */
        !          3460:        if (*cp == '/')
        !          3461:                strcpy(filename, cp);
        !          3462:        else
        !          3463:                snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp);
        !          3464:        str = fopen(filename, "r");
        !          3465:        if (str == NULL)
        !          3466:                return (NULL);
        !          3467: 
        !          3468:        /*
        !          3469:         * Read the filestamp, which is contained in the first line.
        !          3470:         */
        !          3471:        if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) {
        !          3472:                msyslog(LOG_ERR, "crypto_key: empty file %s",
        !          3473:                    filename);
        !          3474:                fclose(str);
        !          3475:                return (NULL);
        !          3476:        }
        !          3477:        if ((ptr = strrchr(ptr, '.')) == NULL) {
        !          3478:                msyslog(LOG_ERR, "crypto_key: no filestamp %s",
        !          3479:                    filename);
        !          3480:                fclose(str);
        !          3481:                return (NULL);
        !          3482:        }
        !          3483:        if (sscanf(++ptr, "%u", &fstamp) != 1) {
        !          3484:                msyslog(LOG_ERR, "crypto_key: invalid filestamp %s",
        !          3485:                    filename);
        !          3486:                fclose(str);
        !          3487:                return (NULL);
        !          3488:        }
        !          3489: 
        !          3490:        /*
        !          3491:         * Read and decrypt PEM-encoded private key. If it fails to
        !          3492:         * decrypt, game over.
        !          3493:         */
        !          3494:        pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd1);
        !          3495:        fclose(str);
        !          3496:        if (pkey == NULL) {
        !          3497:                msyslog(LOG_ERR, "crypto_key: %s",
        !          3498:                    ERR_error_string(ERR_get_error(), NULL));
        !          3499:                exit (-1);
        !          3500:        }
        !          3501: 
        !          3502:        /*
        !          3503:         * Make a new entry in the key cache.
        !          3504:         */
        !          3505:        pkp = emalloc(sizeof(struct pkey_info));
        !          3506:        pkp->link = pkinfo;
        !          3507:        pkinfo = pkp;
        !          3508:        pkp->pkey = pkey;
        !          3509:        pkp->name = emalloc(strlen(cp) + 1);
        !          3510:        pkp->fstamp = fstamp;
        !          3511:        strcpy(pkp->name, cp);
        !          3512: 
        !          3513:        /*
        !          3514:         * Leave tracks in the cryptostats.
        !          3515:         */
        !          3516:        if ((ptr = strrchr(linkname, '\n')) != NULL)
        !          3517:                *ptr = '\0'; 
        !          3518:        snprintf(statstr, NTP_MAXSTRLEN, "%s mod %d", &linkname[2],
        !          3519:            EVP_PKEY_size(pkey) * 8);
        !          3520:        record_crypto_stats(addr, statstr);
        !          3521: #ifdef DEBUG
        !          3522:        if (debug)
        !          3523:                printf("crypto_key: %s\n", statstr);
        !          3524:        if (debug > 1) {
        !          3525:                if (pkey->type == EVP_PKEY_DSA)
        !          3526:                        DSA_print_fp(stdout, pkey->pkey.dsa, 0);
        !          3527:                else if (pkey->type == EVP_PKEY_RSA)
        !          3528:                        RSA_print_fp(stdout, pkey->pkey.rsa, 0);
        !          3529:        }
        !          3530: #endif
        !          3531:        return (pkp);
        !          3532: }
        !          3533: 
        !          3534: 
        !          3535: /*
        !          3536:  ***********************************************************************
        !          3537:  *                                                                    *
        !          3538:  * The following routines are used only at initialization time         *
        !          3539:  *                                                                    *
        !          3540:  ***********************************************************************
        !          3541:  */
        !          3542: /*
        !          3543:  * crypto_cert - load certificate from file
        !          3544:  *
        !          3545:  * This routine loads an X.509 RSA or DSA certificate from a file and
        !          3546:  * constructs a info/cert value structure for this machine. The
        !          3547:  * structure includes a filestamp extracted from the file name. Later
        !          3548:  * the certificate can be sent to another machine on request.
        !          3549:  *
        !          3550:  * Returns certificate info/value pointer if valid, NULL if not.
        !          3551:  */
        !          3552: static struct cert_info *      /* certificate information */
        !          3553: crypto_cert(
        !          3554:        char    *cp             /* file name */
        !          3555:        )
        !          3556: {
        !          3557:        struct cert_info *ret; /* certificate information */
        !          3558:        FILE    *str;           /* file handle */
        !          3559:        char    filename[MAXFILENAME]; /* name of certificate file */
        !          3560:        char    linkname[MAXFILENAME]; /* filestamp buffer */
        !          3561:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !          3562:        tstamp_t fstamp;        /* filestamp */
        !          3563:        long    len;
        !          3564:        char    *ptr;
        !          3565:        char    *name, *header;
        !          3566:        u_char  *data;
        !          3567: 
        !          3568:        /*
        !          3569:         * Open the certificate file. If the first character of the file
        !          3570:         * name is not '/', prepend the keys directory string. If
        !          3571:         * something goes wrong, abandon ship.
        !          3572:         */
        !          3573:        if (*cp == '/')
        !          3574:                strcpy(filename, cp);
        !          3575:        else
        !          3576:                snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp);
        !          3577:        str = fopen(filename, "r");
        !          3578:        if (str == NULL)
        !          3579:                return (NULL);
        !          3580: 
        !          3581:        /*
        !          3582:         * Read the filestamp, which is contained in the first line.
        !          3583:         */
        !          3584:        if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) {
        !          3585:                msyslog(LOG_ERR, "crypto_cert: empty file %s",
        !          3586:                    filename);
        !          3587:                fclose(str);
        !          3588:                return (NULL);
        !          3589:        }
        !          3590:        if ((ptr = strrchr(ptr, '.')) == NULL) {
        !          3591:                msyslog(LOG_ERR, "crypto_cert: no filestamp %s\n",
        !          3592:                    filename);
        !          3593:                fclose(str);
        !          3594:                return (NULL);
        !          3595:        }
        !          3596:        if (sscanf(++ptr, "%u", &fstamp) != 1) {
        !          3597:                msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s\n",
        !          3598:                    filename);
        !          3599:                fclose(str);
        !          3600:                return (NULL);
        !          3601:        }
        !          3602: 
        !          3603:        /*
        !          3604:         * Read PEM-encoded certificate and install.
        !          3605:         */
        !          3606:        if (!PEM_read(str, &name, &header, &data, &len)) {
        !          3607:                msyslog(LOG_ERR, "crypto_cert: %s\n",
        !          3608:                    ERR_error_string(ERR_get_error(), NULL));
        !          3609:                fclose(str);
        !          3610:                return (NULL);
        !          3611:        }
        !          3612:        fclose(str);
        !          3613:        free(header);
        !          3614:        if (strcmp(name, "CERTIFICATE") != 0) {
        !          3615:                msyslog(LOG_NOTICE, "crypto_cert: wrong PEM type %s",
        !          3616:                    name);
        !          3617:                free(name);
        !          3618:                free(data);
        !          3619:                return (NULL);
        !          3620:        }
        !          3621:        free(name);
        !          3622: 
        !          3623:        /*
        !          3624:         * Parse certificate and generate info/value structure. The
        !          3625:         * pointer and copy nonsense is due something broken in Solaris.
        !          3626:         */
        !          3627:        ret = cert_parse(data, len, fstamp);
        !          3628:        free(data);
        !          3629:        if (ret == NULL)
        !          3630:                return (NULL);
        !          3631: 
        !          3632:        if ((ptr = strrchr(linkname, '\n')) != NULL)
        !          3633:                *ptr = '\0'; 
        !          3634:        snprintf(statstr, NTP_MAXSTRLEN, "%s 0x%x len %lu",
        !          3635:            &linkname[2], ret->flags, len);
        !          3636:        record_crypto_stats(NULL, statstr);
        !          3637: #ifdef DEBUG
        !          3638:        if (debug)
        !          3639:                printf("crypto_cert: %s\n", statstr);
        !          3640: #endif
        !          3641:        return (ret);
        !          3642: }
        !          3643: 
        !          3644: 
        !          3645: /*
        !          3646:  * crypto_setup - load keys, certificate and identity parameters
        !          3647:  *
        !          3648:  * This routine loads the public/private host key and certificate. If
        !          3649:  * available, it loads the public/private sign key, which defaults to
        !          3650:  * the host key. The host key must be RSA, but the sign key can be
        !          3651:  * either RSA or DSA. If a trusted certificate, it loads the identity
        !          3652:  * parameters. In either case, the public key on the certificate must
        !          3653:  * agree with the sign key.
        !          3654:  *
        !          3655:  * Required but missing files and inconsistent data and errors are
        !          3656:  * fatal. Allowing configuration to continue would be hazardous and
        !          3657:  * require really messy error checks.
        !          3658:  */
        !          3659: void
        !          3660: crypto_setup(void)
        !          3661: {
        !          3662:        struct pkey_info *pinfo; /* private/public key */
        !          3663:        char    filename[MAXFILENAME]; /* file name buffer */
        !          3664:        char *  randfile;
        !          3665:        char    statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
        !          3666:        l_fp    seed;           /* crypto PRNG seed as NTP timestamp */
        !          3667:        u_int   len;
        !          3668:        int     bytes;
        !          3669:        u_char  *ptr;
        !          3670: 
        !          3671:        /*
        !          3672:         * Check for correct OpenSSL version and avoid initialization in
        !          3673:         * the case of multiple crypto commands.
        !          3674:         */
        !          3675:        if (crypto_flags & CRYPTO_FLAG_ENAB) {
        !          3676:                msyslog(LOG_NOTICE,
        !          3677:                    "crypto_setup: spurious crypto command");
        !          3678:                return;
        !          3679:        }
        !          3680:        ssl_check_version();
        !          3681: 
        !          3682:        /*
        !          3683:         * Load required random seed file and seed the random number
        !          3684:         * generator. Be default, it is found as .rnd in the user home
        !          3685:         * directory. The root home directory may be / or /root,
        !          3686:         * depending on the system. Wiggle the contents a bit and write
        !          3687:         * it back so the sequence does not repeat when we next restart.
        !          3688:         */
        !          3689:        if (!RAND_status()) {
        !          3690:                if (rand_file == NULL) {
        !          3691:                        RAND_file_name(filename, sizeof(filename));
        !          3692:                        randfile = filename;
        !          3693:                } else if (*rand_file != '/') {
        !          3694:                        snprintf(filename, sizeof(filename), "%s/%s",
        !          3695:                            keysdir, rand_file);
        !          3696:                        randfile = filename;
        !          3697:                } else
        !          3698:                        randfile = rand_file;
        !          3699: 
        !          3700:                if ((bytes = RAND_load_file(randfile, -1)) == 0) {
        !          3701:                        msyslog(LOG_ERR,
        !          3702:                            "crypto_setup: random seed file %s missing",
        !          3703:                            randfile);
        !          3704:                        exit (-1);
        !          3705:                }
        !          3706:                get_systime(&seed);
        !          3707:                RAND_seed(&seed, sizeof(l_fp));
        !          3708:                RAND_write_file(randfile);
        !          3709: #ifdef DEBUG
        !          3710:                if (debug)
        !          3711:                        printf(
        !          3712:                            "crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n",
        !          3713:                            SSLeay(), randfile, bytes);
        !          3714: #endif
        !          3715:        }
        !          3716: 
        !          3717:        /*
        !          3718:         * Initialize structures.
        !          3719:         */
        !          3720:        if (sys_hostname == NULL) {
        !          3721:                gethostname(filename, MAXFILENAME);
        !          3722:                sys_hostname = emalloc(strlen(filename) + 1);
        !          3723:                strcpy(sys_hostname, filename);
        !          3724:        }
        !          3725:        if (passwd == NULL)
        !          3726:                passwd = sys_hostname;
        !          3727:        memset(&hostval, 0, sizeof(hostval));
        !          3728:        memset(&pubkey, 0, sizeof(pubkey));
        !          3729:        memset(&tai_leap, 0, sizeof(tai_leap));
        !          3730: 
        !          3731:        /*
        !          3732:         * Load required host key from file "ntpkey_host_<hostname>". If
        !          3733:         * no host key file is not found or has invalid password, life
        !          3734:         * as we know it ends. The host key also becomes the default
        !          3735:         * sign key. 
        !          3736:         */
        !          3737:        snprintf(filename, MAXFILENAME, "ntpkey_host_%s", sys_hostname);
        !          3738:        pinfo = crypto_key(filename, passwd, NULL);
        !          3739:        if (pinfo == NULL) {
        !          3740:                msyslog(LOG_ERR,
        !          3741:                    "crypto_setup: host key file %s not found or corrupt",
        !          3742:                    filename);
        !          3743:                exit (-1);
        !          3744:        }
        !          3745:        if (pinfo->pkey->type != EVP_PKEY_RSA) {
        !          3746:                msyslog(LOG_ERR,
        !          3747:                    "crypto_setup: host key is not RSA key type");
        !          3748:                exit (-1);
        !          3749:        }
        !          3750:        host_pkey = pinfo->pkey;
        !          3751:        sign_pkey = host_pkey;
        !          3752:        hostval.fstamp = htonl(pinfo->fstamp);
        !          3753:        
        !          3754:        /*
        !          3755:         * Construct public key extension field for agreement scheme.
        !          3756:         */
        !          3757:        len = i2d_PublicKey(host_pkey, NULL);
        !          3758:        ptr = emalloc(len);
        !          3759:        pubkey.ptr = ptr;
        !          3760:        i2d_PublicKey(host_pkey, &ptr);
        !          3761:        pubkey.fstamp = hostval.fstamp;
        !          3762:        pubkey.vallen = htonl(len);
        !          3763: 
        !          3764:        /*
        !          3765:         * Load optional sign key from file "ntpkey_sign_<hostname>". If
        !          3766:         * available, it becomes the sign key.
        !          3767:         */
        !          3768:        snprintf(filename, MAXFILENAME, "ntpkey_sign_%s", sys_hostname);
        !          3769:        pinfo = crypto_key(filename, passwd, NULL); if (pinfo != NULL)
        !          3770:                sign_pkey = pinfo->pkey;
        !          3771: 
        !          3772:        /*
        !          3773:         * Load required certificate from file "ntpkey_cert_<hostname>".
        !          3774:         */
        !          3775:        snprintf(filename, MAXFILENAME, "ntpkey_cert_%s", sys_hostname);
        !          3776:        cinfo = crypto_cert(filename);
        !          3777:        if (cinfo == NULL) {
        !          3778:                msyslog(LOG_ERR,
        !          3779:                    "crypto_setup: certificate file %s not found or corrupt",
        !          3780:                    filename);
        !          3781:                exit (-1);
        !          3782:        }
        !          3783:        cert_host = cinfo;
        !          3784:        sign_digest = cinfo->digest;
        !          3785:        sign_siglen = EVP_PKEY_size(sign_pkey);
        !          3786:        if (cinfo->flags & CERT_PRIV)
        !          3787:                crypto_flags |= CRYPTO_FLAG_PRIV;
        !          3788: 
        !          3789:        /*
        !          3790:         * The certificate must be self-signed.
        !          3791:         */
        !          3792:        if (strcmp(cinfo->subject, cinfo->issuer) != 0) {
        !          3793:                msyslog(LOG_ERR,
        !          3794:                    "crypto_setup: certificate %s is not self-signed",
        !          3795:                    filename);
        !          3796:                exit (-1);
        !          3797:        }
        !          3798:        hostval.vallen = htonl(strlen(cinfo->subject));
        !          3799:        hostval.ptr = cinfo->subject;
        !          3800: 
        !          3801:        /*
        !          3802:         * If trusted certificate, the subject name must match the group
        !          3803:         * name.
        !          3804:         */
        !          3805:        if (cinfo->flags & CERT_TRUST) {
        !          3806:                if (sys_groupname == NULL) {
        !          3807:                        sys_groupname = hostval.ptr;
        !          3808:                } else if (strcmp(hostval.ptr, sys_groupname) != 0) {
        !          3809:                        msyslog(LOG_ERR,
        !          3810:                            "crypto_setup: trusted certificate name %s does not match group name %s",
        !          3811:                            hostval.ptr, sys_groupname);
        !          3812:                        exit (-1);
        !          3813:                }
        !          3814:        }
        !          3815:        if (sys_groupname != NULL) {
        !          3816: 
        !          3817:                /*
        !          3818:                 * Load optional IFF parameters from file
        !          3819:                 * "ntpkey_iffkey_<groupname>".
        !          3820:                 */
        !          3821:                snprintf(filename, MAXFILENAME, "ntpkey_iffkey_%s",
        !          3822:                    sys_groupname);
        !          3823:                iffkey_info = crypto_key(filename, passwd, NULL);
        !          3824:                if (iffkey_info != NULL)
        !          3825:                        crypto_flags |= CRYPTO_FLAG_IFF;
        !          3826: 
        !          3827:                /*
        !          3828:                 * Load optional GQ parameters from file
        !          3829:                 * "ntpkey_gqkey_<groupname>".
        !          3830:                 */
        !          3831:                snprintf(filename, MAXFILENAME, "ntpkey_gqkey_%s",
        !          3832:                    sys_groupname);
        !          3833:                gqkey_info = crypto_key(filename, passwd, NULL);
        !          3834:                if (gqkey_info != NULL)
        !          3835:                        crypto_flags |= CRYPTO_FLAG_GQ;
        !          3836: 
        !          3837:                /*
        !          3838:                 * Load optional MV parameters from file
        !          3839:                 * "ntpkey_mvkey_<groupname>".
        !          3840:                 */
        !          3841:                snprintf(filename, MAXFILENAME, "ntpkey_mvkey_%s",
        !          3842:                    sys_groupname);
        !          3843:                mvkey_info = crypto_key(filename, passwd, NULL);
        !          3844:                if (mvkey_info != NULL)
        !          3845:                        crypto_flags |= CRYPTO_FLAG_MV;
        !          3846:        }
        !          3847: 
        !          3848:        /*
        !          3849:         * We met the enemy and he is us. Now strike up the dance.
        !          3850:         */
        !          3851:        crypto_flags |= CRYPTO_FLAG_ENAB | (cinfo->nid << 16);
        !          3852:        snprintf(statstr, NTP_MAXSTRLEN,
        !          3853:            "setup 0x%x host %s %s", crypto_flags, sys_hostname,
        !          3854:            OBJ_nid2ln(cinfo->nid));
        !          3855:        record_crypto_stats(NULL, statstr);
        !          3856: #ifdef DEBUG
        !          3857:        if (debug)
        !          3858:                printf("crypto_setup: %s\n", statstr);
        !          3859: #endif
        !          3860: }
        !          3861: 
        !          3862: 
        !          3863: /*
        !          3864:  * crypto_config - configure data from the crypto command.
        !          3865:  */
        !          3866: void
        !          3867: crypto_config(
        !          3868:        int     item,           /* configuration item */
        !          3869:        char    *cp             /* item name */
        !          3870:        )
        !          3871: {
        !          3872:        int     nid;
        !          3873: 
        !          3874: #ifdef DEBUG
        !          3875:        if (debug > 1)
        !          3876:                printf("crypto_config: item %d %s\n", item, cp);
        !          3877: #endif
        !          3878:        switch (item) {
        !          3879: 
        !          3880:        /*
        !          3881:         * Set host name (host).
        !          3882:         */
        !          3883:        case CRYPTO_CONF_PRIV:
        !          3884:                sys_hostname = emalloc(strlen(cp) + 1);
        !          3885:                strcpy(sys_hostname, cp);
        !          3886:                break;
        !          3887: 
        !          3888:        /*
        !          3889:         * Set group name (ident).
        !          3890:         */
        !          3891:        case CRYPTO_CONF_IDENT:
        !          3892:                sys_groupname = emalloc(strlen(cp) + 1);
        !          3893:                strcpy(sys_groupname, cp);
        !          3894:                break;
        !          3895: 
        !          3896:        /*
        !          3897:         * Set private key password (pw).
        !          3898:         */
        !          3899:        case CRYPTO_CONF_PW:
        !          3900:                passwd = emalloc(strlen(cp) + 1);
        !          3901:                strcpy(passwd, cp);
        !          3902:                break;
        !          3903: 
        !          3904:        /*
        !          3905:         * Set random seed file name (randfile).
        !          3906:         */
        !          3907:        case CRYPTO_CONF_RAND:
        !          3908:                rand_file = emalloc(strlen(cp) + 1);
        !          3909:                strcpy(rand_file, cp);
        !          3910:                break;
        !          3911: 
        !          3912:        /*
        !          3913:         * Set message digest NID.
        !          3914:         */
        !          3915:        case CRYPTO_CONF_NID:
        !          3916:                nid = OBJ_sn2nid(cp);
        !          3917:                if (nid == 0)
        !          3918:                        msyslog(LOG_ERR,
        !          3919:                            "crypto_config: invalid digest name %s", cp);
        !          3920:                else
        !          3921:                        crypto_nid = nid;
        !          3922:                break;
        !          3923:        }
        !          3924: }
        !          3925: # else
        !          3926: int ntp_crypto_bs_pubkey;
        !          3927: # endif /* OPENSSL */

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