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>