1 /* $OpenBSD: ca.c,v 1.17 2011/05/27 12:01:02 reyk Exp $ */ 2 /* $vantronix: ca.c,v 1.29 2010/06/02 12:22:58 reyk Exp $ */ 3 4 /* 5 * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/param.h> 21 #include <sys/types.h> 22 #include <sys/queue.h> 23 #include <sys/socket.h> 24 #include <sys/wait.h> 25 #include <sys/uio.h> 26 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <unistd.h> 30 #include <dirent.h> 31 #include <string.h> 32 #include <getopt.h> 33 #include <signal.h> 34 #include <errno.h> 35 #include <err.h> 36 #include <pwd.h> 37 #include <event.h> 38 39 #include <openssl/bio.h> 40 #include <openssl/err.h> 41 #include <openssl/engine.h> 42 #include <openssl/ssl.h> 43 #include <openssl/x509.h> 44 #include <openssl/x509v3.h> 45 #include <openssl/pem.h> 46 #include <openssl/evp.h> 47 #include <openssl/sha.h> 48 49 #include "iked.h" 50 #include "ikev2.h" 51 52 void ca_reset(struct privsep *, void *); 53 int ca_reload(struct iked *); 54 55 int ca_getreq(struct iked *, struct imsg *); 56 int ca_getcert(struct iked *, struct imsg *); 57 int ca_getauth(struct iked *, struct imsg *); 58 X509 *ca_by_subjectpubkey(X509_STORE *, u_int8_t *, size_t); 59 X509 *ca_by_issuer(X509_STORE *, X509_NAME *, struct iked_static_id *); 60 int ca_subjectpubkey_digest(X509 *, u_int8_t *, u_int *); 61 int ca_validate_pubkey(struct iked *, struct iked_static_id *, 62 void *, size_t); 63 int ca_validate_cert(struct iked *, struct iked_static_id *, 64 void *, size_t); 65 struct ibuf * 66 ca_x509_serialize(X509 *); 67 int ca_x509_subjectaltname_cmp(X509 *, struct iked_static_id *); 68 int ca_x509_subjectaltname(X509 *cert, struct iked_id *); 69 int ca_key_serialize(EVP_PKEY *, struct iked_id *); 70 int ca_dispatch_parent(int, struct privsep_proc *, struct imsg *); 71 int ca_dispatch_ikev1(int, struct privsep_proc *, struct imsg *); 72 int ca_dispatch_ikev2(int, struct privsep_proc *, struct imsg *); 73 74 static struct privsep_proc procs[] = { 75 { "parent", PROC_PARENT, ca_dispatch_parent }, 76 { "ikev1", PROC_IKEV1, ca_dispatch_ikev1 }, 77 { "ikev2", PROC_IKEV2, ca_dispatch_ikev2 } 78 }; 79 80 struct ca_store { 81 X509_STORE *ca_cas; 82 X509_LOOKUP *ca_calookup; 83 84 X509_STORE *ca_certs; 85 X509_LOOKUP *ca_certlookup; 86 87 struct iked_id ca_privkey; 88 }; 89 90 pid_t 91 caproc(struct privsep *ps, struct privsep_proc *p) 92 { 93 struct ca_store *store; 94 FILE *fp = NULL; 95 EVP_PKEY *key; 96 97 /* 98 * This function runs code before privsep 99 */ 100 if ((store = calloc(1, sizeof(*store))) == NULL) 101 fatal("ca: failed to allocate cert store"); 102 103 if ((fp = fopen(IKED_PRIVKEY, "r")) == NULL) 104 fatal("ca: failed to open private key"); 105 106 if ((key = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) 107 fatalx("ca: failed to read private key"); 108 fclose(fp); 109 110 if (ca_key_serialize(key, &store->ca_privkey) != 0) 111 fatalx("ca: failed to serialize private key"); 112 113 return (proc_run(ps, p, procs, nitems(procs), ca_reset, store)); 114 } 115 116 void 117 ca_reset(struct privsep *ps, void *arg) 118 { 119 struct iked *env = ps->ps_env; 120 struct ca_store *store = arg; 121 122 if (store->ca_cas != NULL) 123 X509_STORE_free(store->ca_cas); 124 if (store->ca_certs != NULL) 125 X509_STORE_free(store->ca_certs); 126 127 if ((store->ca_cas = X509_STORE_new()) == NULL) 128 fatalx("ca_reset: failed to get ca store"); 129 if ((store->ca_calookup = X509_STORE_add_lookup(store->ca_cas, 130 X509_LOOKUP_file())) == NULL) 131 fatalx("ca_reset: failed to add ca lookup"); 132 133 if ((store->ca_certs = X509_STORE_new()) == NULL) 134 fatalx("ca_reset: failed to get cert store"); 135 if ((store->ca_certlookup = X509_STORE_add_lookup(store->ca_certs, 136 X509_LOOKUP_file())) == NULL) 137 fatalx("ca_reset: failed to add cert lookup"); 138 139 env->sc_priv = store; 140 141 if (ca_reload(env) != 0) 142 fatal("ca_reset: reload"); 143 } 144 145 int 146 ca_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) 147 { 148 struct iked *env = p->p_env; 149 struct ca_store *store = env->sc_priv; 150 u_int mode; 151 152 switch (imsg->hdr.type) { 153 case IMSG_CTL_RESET: 154 IMSG_SIZE_CHECK(imsg, &mode); 155 memcpy(&mode, imsg->data, sizeof(mode)); 156 if (mode == RESET_ALL || mode == RESET_CA) { 157 log_debug("%s: config reload", __func__); 158 ca_reset(&env->sc_ps, store); 159 } 160 break; 161 default: 162 return (-1); 163 } 164 165 return (0); 166 } 167 168 int 169 ca_dispatch_ikev1(int fd, struct privsep_proc *p, struct imsg *imsg) 170 { 171 return (-1); 172 } 173 174 int 175 ca_dispatch_ikev2(int fd, struct privsep_proc *p, struct imsg *imsg) 176 { 177 struct iked *env = p->p_env; 178 179 switch (imsg->hdr.type) { 180 case IMSG_CERTREQ: 181 ca_getreq(env, imsg); 182 break; 183 case IMSG_CERT: 184 ca_getcert(env, imsg); 185 break; 186 case IMSG_AUTH: 187 ca_getauth(env, imsg); 188 break; 189 default: 190 return (-1); 191 } 192 193 return (0); 194 } 195 196 int 197 ca_setcert(struct iked *env, struct iked_sahdr *sh, struct iked_id *id, 198 u_int8_t type, u_int8_t *data, size_t len, enum privsep_procid procid) 199 { 200 struct iovec iov[4]; 201 int iovcnt = 0; 202 struct iked_static_id idb; 203 204 /* Must send the cert and a valid Id to the ca process */ 205 if (procid == PROC_CERT) { 206 if (id == NULL || id->id_type == IKEV2_ID_NONE || 207 ibuf_length(id->id_buf) > IKED_ID_SIZE) 208 return (-1); 209 bzero(&idb, sizeof(idb)); 210 211 /* Convert to a static Id */ 212 idb.id_type = id->id_type; 213 idb.id_offset = id->id_offset; 214 idb.id_length = ibuf_length(id->id_buf); 215 memcpy(&idb.id_data, ibuf_data(id->id_buf), 216 ibuf_length(id->id_buf)); 217 218 iov[iovcnt].iov_base = &idb; 219 iov[iovcnt].iov_len = sizeof(idb); 220 iovcnt++; 221 } 222 223 iov[iovcnt].iov_base = sh; 224 iov[iovcnt].iov_len = sizeof(*sh); 225 iovcnt++; 226 iov[iovcnt].iov_base = &type; 227 iov[iovcnt].iov_len = sizeof(type); 228 iovcnt++; 229 iov[iovcnt].iov_base = data; 230 iov[iovcnt].iov_len = len; 231 iovcnt++; 232 233 if (proc_composev_imsg(env, procid, IMSG_CERT, -1, iov, iovcnt) == -1) 234 return (-1); 235 return (0); 236 } 237 238 int 239 ca_setreq(struct iked *env, struct iked_sahdr *sh, 240 struct iked_static_id *localid, u_int8_t type, u_int8_t *data, 241 size_t len, enum privsep_procid procid) 242 { 243 struct iovec iov[4]; 244 int iovcnt = 0; 245 struct iked_static_id idb; 246 struct iked_id id; 247 int ret = -1; 248 249 /* Convert to a static Id */ 250 bzero(&id, sizeof(id)); 251 if (ikev2_policy2id(localid, &id, 0) != 0) 252 return (-1); 253 254 bzero(&idb, sizeof(idb)); 255 idb.id_type = id.id_type; 256 idb.id_offset = id.id_offset; 257 idb.id_length = ibuf_length(id.id_buf); 258 memcpy(&idb.id_data, ibuf_data(id.id_buf), 259 ibuf_length(id.id_buf)); 260 iov[iovcnt].iov_base = &idb; 261 iov[iovcnt].iov_len = sizeof(idb); 262 iovcnt++; 263 264 iov[iovcnt].iov_base = sh; 265 iov[iovcnt].iov_len = sizeof(*sh); 266 iovcnt++; 267 iov[iovcnt].iov_base = &type; 268 iov[iovcnt].iov_len = sizeof(type); 269 iovcnt++; 270 iov[iovcnt].iov_base = data; 271 iov[iovcnt].iov_len = len; 272 iovcnt++; 273 274 if (proc_composev_imsg(env, procid, 275 IMSG_CERTREQ, -1, iov, iovcnt) == -1) 276 goto done; 277 278 ret = 0; 279 done: 280 ibuf_release(id.id_buf); 281 return (ret); 282 } 283 284 int 285 ca_setauth(struct iked *env, struct iked_sa *sa, 286 struct ibuf *authmsg, enum privsep_procid id) 287 { 288 struct iovec iov[3]; 289 int iovcnt = 3; 290 struct iked_policy *policy = sa->sa_policy; 291 u_int8_t type = policy->pol_auth.auth_method; 292 293 if (type == IKEV2_AUTH_SHARED_KEY_MIC) { 294 sa->sa_stateflags |= IKED_REQ_AUTH; 295 return (ikev2_msg_authsign(env, sa, 296 &policy->pol_auth, authmsg)); 297 } 298 299 iov[0].iov_base = &sa->sa_hdr; 300 iov[0].iov_len = sizeof(sa->sa_hdr); 301 iov[1].iov_base = &type; 302 iov[1].iov_len = sizeof(type); 303 if (type == IKEV2_AUTH_NONE) 304 iovcnt--; 305 else { 306 iov[2].iov_base = ibuf_data(authmsg); 307 iov[2].iov_len = ibuf_size(authmsg); 308 log_debug("%s: auth length %d", __func__, ibuf_size(authmsg)); 309 } 310 311 if (proc_composev_imsg(env, id, IMSG_AUTH, -1, iov, iovcnt) == -1) 312 return (-1); 313 return (0); 314 } 315 316 int 317 ca_getcert(struct iked *env, struct imsg *imsg) 318 { 319 struct iked_sahdr sh; 320 u_int8_t type; 321 u_int8_t *ptr; 322 size_t len; 323 struct iked_static_id id; 324 u_int i; 325 struct iovec iov[2]; 326 int iovcnt = 2, cmd, ret = 0; 327 328 ptr = (u_int8_t *)imsg->data; 329 len = IMSG_DATA_SIZE(imsg); 330 i = sizeof(id) + sizeof(sh) + sizeof(type); 331 if (len <= i) 332 return (-1); 333 334 memcpy(&id, ptr, sizeof(id)); 335 if (id.id_type == IKEV2_ID_NONE) 336 return (-1); 337 memcpy(&sh, ptr + sizeof(id), sizeof(sh)); 338 memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(u_int8_t)); 339 340 ptr += i; 341 len -= i; 342 343 switch (type) { 344 case IKEV2_CERT_X509_CERT: 345 ret = ca_validate_cert(env, &id, ptr, len); 346 break; 347 case IKEV2_CERT_RSA_KEY: 348 ret = ca_validate_pubkey(env, &id, ptr, len); 349 break; 350 default: 351 log_debug("%s: unsupported cert type %d", __func__, type); 352 ret = -1; 353 break; 354 } 355 356 if (ret == 0) 357 cmd = IMSG_CERTVALID; 358 else 359 cmd = IMSG_CERTINVALID; 360 361 iov[0].iov_base = &sh; 362 iov[0].iov_len = sizeof(sh); 363 iov[1].iov_base = &type; 364 iov[1].iov_len = sizeof(type); 365 366 if (proc_composev_imsg(env, PROC_IKEV2, cmd, -1, iov, iovcnt) == -1) 367 return (-1); 368 return (0); 369 } 370 371 int 372 ca_getreq(struct iked *env, struct imsg *imsg) 373 { 374 struct ca_store *store = env->sc_priv; 375 struct iked_sahdr sh; 376 u_int8_t type; 377 u_int8_t *ptr; 378 size_t len; 379 u_int i, n; 380 X509 *ca = NULL, *cert = NULL; 381 struct ibuf *buf; 382 struct iked_static_id id; 383 384 ptr = (u_int8_t *)imsg->data; 385 len = IMSG_DATA_SIZE(imsg); 386 i = sizeof(id) + sizeof(u_int8_t) + sizeof(sh); 387 if (len < i || ((len - i) % SHA_DIGEST_LENGTH) != 0) 388 return (-1); 389 390 memcpy(&id, ptr, sizeof(id)); 391 if (id.id_type == IKEV2_ID_NONE) 392 return (-1); 393 memcpy(&sh, ptr + sizeof(id), sizeof(sh)); 394 memcpy(&type, ptr + sizeof(id) + sizeof(sh), sizeof(u_int8_t)); 395 if (type != IKEV2_CERT_X509_CERT) 396 return (-1); 397 398 for (n = 1; i < len; n++, i += SHA_DIGEST_LENGTH) { 399 if ((ca = ca_by_subjectpubkey(store->ca_cas, 400 ptr + i, SHA_DIGEST_LENGTH)) == NULL) { 401 log_debug("%s: CA %d not found", __func__, n); 402 print_hex(ptr, i, SHA_DIGEST_LENGTH); 403 continue; 404 } 405 406 log_debug("%s: found CA %s", __func__, ca->name); 407 408 if ((cert = ca_by_issuer(store->ca_certs, 409 X509_get_subject_name(ca), &id)) != NULL) { 410 /* XXX should we re-validate our own cert here? */ 411 break; 412 } 413 414 log_debug("%s: no valid certificate for this CA", __func__); 415 } 416 if (ca == NULL || cert == NULL) { 417 log_warnx("%s: no valid local certificate found", __func__); 418 type = IKEV2_CERT_NONE; 419 ca_setcert(env, &sh, NULL, type, NULL, 0, PROC_IKEV2); 420 return (0); 421 } 422 423 log_debug("%s: found local certificate %s", __func__, cert->name); 424 425 if ((buf = ca_x509_serialize(cert)) == NULL) 426 return (-1); 427 428 type = IKEV2_CERT_X509_CERT; 429 ca_setcert(env, &sh, NULL, type, 430 ibuf_data(buf), ibuf_size(buf), PROC_IKEV2); 431 432 return (0); 433 } 434 435 int 436 ca_getauth(struct iked *env, struct imsg *imsg) 437 { 438 struct ca_store *store = env->sc_priv; 439 struct iked_sahdr sh; 440 u_int8_t method; 441 u_int8_t *ptr; 442 size_t len; 443 u_int i; 444 int ret = -1; 445 struct iked_sa sa; 446 struct iked_policy policy; 447 struct iked_id *id; 448 struct ibuf *authmsg; 449 450 ptr = (u_int8_t *)imsg->data; 451 len = IMSG_DATA_SIZE(imsg); 452 i = sizeof(method) + sizeof(sh); 453 if (len <= i) 454 return (-1); 455 456 memcpy(&sh, ptr, sizeof(sh)); 457 memcpy(&method, ptr + sizeof(sh), sizeof(u_int8_t)); 458 if (method == IKEV2_AUTH_SHARED_KEY_MIC) 459 return (-1); 460 461 ptr += i; 462 len -= i; 463 464 if ((authmsg = ibuf_new(ptr, len)) == NULL) 465 return (-1); 466 467 /* 468 * Create fake SA and policy 469 */ 470 bzero(&sa, sizeof(sa)); 471 bzero(&policy, sizeof(policy)); 472 memcpy(&sa.sa_hdr, &sh, sizeof(sh)); 473 sa.sa_policy = &policy; 474 policy.pol_auth.auth_method = method; 475 if (sh.sh_initiator) 476 id = &sa.sa_icert; 477 else 478 id = &sa.sa_rcert; 479 memcpy(id, &store->ca_privkey, sizeof(*id)); 480 481 if (ikev2_msg_authsign(env, &sa, &policy.pol_auth, authmsg) != 0) { 482 log_debug("%s: AUTH sign failed", __func__); 483 policy.pol_auth.auth_method = IKEV2_AUTH_NONE; 484 } 485 486 ret = ca_setauth(env, &sa, sa.sa_localauth.id_buf, PROC_IKEV2); 487 488 ibuf_release(sa.sa_localauth.id_buf); 489 ibuf_release(authmsg); 490 491 return (ret); 492 } 493 494 int 495 ca_reload(struct iked *env) 496 { 497 struct ca_store *store = env->sc_priv; 498 DIR *dir; 499 struct dirent *entry; 500 char file[PATH_MAX]; 501 STACK_OF(X509_OBJECT) *h; 502 X509_OBJECT *xo; 503 X509 *x509; 504 int i, len; 505 u_int8_t md[EVP_MAX_MD_SIZE]; 506 struct iovec iov[2]; 507 int iovcnt = 2; 508 509 /* 510 * Load CAs 511 */ 512 if ((dir = opendir(IKED_CA_DIR)) == NULL) 513 return (-1); 514 515 while ((entry = readdir(dir)) != NULL) { 516 if ((entry->d_type != DT_REG) && 517 (entry->d_type != DT_LNK)) 518 continue; 519 520 if (snprintf(file, sizeof(file), "%s%s", 521 IKED_CA_DIR, entry->d_name) == -1) 522 continue; 523 524 if (!X509_load_cert_file(store->ca_calookup, file, 525 X509_FILETYPE_PEM)) { 526 log_debug("%s: failed to load ca file %s", __func__, 527 entry->d_name); 528 ca_sslerror(); 529 continue; 530 } 531 log_debug("%s: loaded ca file %s", __func__, entry->d_name); 532 } 533 closedir(dir); 534 535 /* 536 * Load CRLs for the CAs 537 */ 538 if ((dir = opendir(IKED_CRL_DIR)) == NULL) 539 return (-1); 540 541 while ((entry = readdir(dir)) != NULL) { 542 if ((entry->d_type != DT_REG) && 543 (entry->d_type != DT_LNK)) 544 continue; 545 546 if (snprintf(file, sizeof(file), "%s%s", 547 IKED_CRL_DIR, entry->d_name) == -1) 548 continue; 549 550 if (!X509_load_crl_file(store->ca_calookup, file, 551 X509_FILETYPE_PEM)) { 552 log_debug("%s: failed to load crl file %s", __func__, 553 entry->d_name); 554 ca_sslerror(); 555 continue; 556 } 557 558 /* Only enable CRL checks if we actually loaded a CRL */ 559 X509_STORE_set_flags(store->ca_cas, X509_V_FLAG_CRL_CHECK); 560 561 log_debug("%s: loaded crl file %s", __func__, entry->d_name); 562 } 563 closedir(dir); 564 565 /* 566 * Save CAs signatures for the IKEv2 CERTREQ 567 */ 568 ibuf_release(env->sc_certreq); 569 if ((env->sc_certreq = ibuf_new(NULL, 0)) == NULL) 570 return (-1); 571 572 h = store->ca_cas->objs; 573 for (i = 0; i < sk_X509_OBJECT_num(h); i++) { 574 xo = sk_X509_OBJECT_value(h, i); 575 if (xo->type != X509_LU_X509) 576 continue; 577 578 x509 = xo->data.x509; 579 len = sizeof(md); 580 ca_subjectpubkey_digest(x509, md, &len); 581 log_debug("%s: %s", __func__, x509->name); 582 583 if (ibuf_add(env->sc_certreq, md, len) != 0) { 584 ibuf_release(env->sc_certreq); 585 return (-1); 586 } 587 } 588 589 if (ibuf_length(env->sc_certreq)) { 590 env->sc_certreqtype = IKEV2_CERT_X509_CERT; 591 iov[0].iov_base = &env->sc_certreqtype; 592 iov[0].iov_len = sizeof(env->sc_certreqtype); 593 iov[1].iov_base = ibuf_data(env->sc_certreq); 594 iov[1].iov_len = ibuf_length(env->sc_certreq); 595 596 log_debug("%s: loaded %d ca certificate%s", __func__, 597 ibuf_length(env->sc_certreq) / SHA_DIGEST_LENGTH, 598 ibuf_length(env->sc_certreq) == SHA_DIGEST_LENGTH ? 599 "" : "s"); 600 601 (void)proc_composev_imsg(env, PROC_IKEV2, IMSG_CERTREQ, -1, 602 iov, iovcnt); 603 } 604 605 /* 606 * Load certificates 607 */ 608 if ((dir = opendir(IKED_CERT_DIR)) == NULL) 609 return (-1); 610 611 while ((entry = readdir(dir)) != NULL) { 612 if ((entry->d_type != DT_REG) && 613 (entry->d_type != DT_LNK)) 614 continue; 615 616 if (snprintf(file, sizeof(file), "%s%s", 617 IKED_CERT_DIR, entry->d_name) == -1) 618 continue; 619 620 if (!X509_load_cert_file(store->ca_certlookup, file, 621 X509_FILETYPE_PEM)) { 622 log_debug("%s: failed to load cert file %s", __func__, 623 entry->d_name); 624 ca_sslerror(); 625 continue; 626 } 627 log_debug("%s: loaded cert file %s", __func__, entry->d_name); 628 } 629 closedir(dir); 630 631 h = store->ca_certs->objs; 632 for (i = 0; i < sk_X509_OBJECT_num(h); i++) { 633 xo = sk_X509_OBJECT_value(h, i); 634 if (xo->type != X509_LU_X509) 635 continue; 636 637 x509 = xo->data.x509; 638 639 (void)ca_validate_cert(env, NULL, x509, 0); 640 } 641 642 return (0); 643 } 644 645 X509 * 646 ca_by_subjectpubkey(X509_STORE *ctx, u_int8_t *sig, size_t siglen) 647 { 648 STACK_OF(X509_OBJECT) *h; 649 X509_OBJECT *xo; 650 X509 *ca; 651 int i; 652 u_int len; 653 u_int8_t md[EVP_MAX_MD_SIZE]; 654 655 h = ctx->objs; 656 657 for (i = 0; i < sk_X509_OBJECT_num(h); i++) { 658 xo = sk_X509_OBJECT_value(h, i); 659 if (xo->type != X509_LU_X509) 660 continue; 661 662 ca = xo->data.x509; 663 len = sizeof(md); 664 ca_subjectpubkey_digest(ca, md, &len); 665 666 if (len == siglen && memcmp(md, sig, len) == 0) 667 return (ca); 668 } 669 670 return (NULL); 671 } 672 673 X509 * 674 ca_by_issuer(X509_STORE *ctx, X509_NAME *subject, struct iked_static_id *id) 675 { 676 STACK_OF(X509_OBJECT) *h; 677 X509_OBJECT *xo; 678 X509 *cert; 679 int i; 680 X509_NAME *issuer; 681 682 if (subject == NULL) 683 return (NULL); 684 685 h = ctx->objs; 686 for (i = 0; i < sk_X509_OBJECT_num(h); i++) { 687 xo = sk_X509_OBJECT_value(h, i); 688 if (xo->type != X509_LU_X509) 689 continue; 690 691 cert = xo->data.x509; 692 if ((issuer = X509_get_issuer_name(cert)) == NULL) 693 continue; 694 else if (X509_NAME_cmp(subject, issuer) == 0) { 695 if (ca_x509_subjectaltname_cmp(cert, id) != 0) 696 continue; 697 return (cert); 698 } 699 } 700 701 return (NULL); 702 } 703 704 int 705 ca_subjectpubkey_digest(X509 *x509, u_int8_t *md, u_int *size) 706 { 707 u_int8_t *buf = NULL; 708 int buflen; 709 710 if (*size < SHA_DIGEST_LENGTH) 711 return (-1); 712 713 /* 714 * Generate a SHA-1 digest of the Subject Public Key Info 715 * element in the X.509 certificate, an ASN.1 sequence 716 * that includes the public key type (eg. RSA) and the 717 * public key value (see 3.7 of RFC4306). 718 */ 719 buflen = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x509), &buf); 720 if (!buflen) 721 return (-1); 722 if (!EVP_Digest(buf, buflen, md, size, EVP_sha1(), NULL)) { 723 free(buf); 724 return (-1); 725 } 726 free(buf); 727 728 return (0); 729 } 730 731 struct ibuf * 732 ca_x509_serialize(X509 *x509) 733 { 734 long len; 735 struct ibuf *buf; 736 u_int8_t *d = NULL; 737 BIO *out; 738 739 if ((out = BIO_new(BIO_s_mem())) == NULL) 740 return (NULL); 741 if (!i2d_X509_bio(out, x509)) { 742 BIO_free(out); 743 return (NULL); 744 } 745 746 len = BIO_get_mem_data(out, &d); 747 buf = ibuf_new(d, len); 748 749 return (buf); 750 } 751 752 int 753 ca_key_serialize(EVP_PKEY *key, struct iked_id *id) 754 { 755 int len; 756 u_int8_t *d; 757 RSA *rsa; 758 759 switch (key->type) { 760 case EVP_PKEY_RSA: 761 id->id_type = 0; 762 id->id_offset = 0; 763 ibuf_release(id->id_buf); 764 765 if ((rsa = EVP_PKEY_get1_RSA(key)) == NULL) 766 return (-1); 767 if ((len = i2d_RSAPrivateKey(rsa, NULL)) <= 0) 768 return (-1); 769 if ((id->id_buf = ibuf_new(NULL, len)) == NULL) 770 return (-1); 771 772 d = ibuf_data(id->id_buf); 773 if (i2d_RSAPrivateKey(rsa, &d) != len) { 774 ibuf_release(id->id_buf); 775 return (-1); 776 } 777 778 id->id_type = IKEV2_CERT_RSA_KEY; 779 break; 780 default: 781 log_debug("%s: unsupported key type %d", __func__, key->type); 782 return (-1); 783 } 784 785 return (0); 786 } 787 788 char * 789 ca_asn1_name(u_int8_t *asn1, size_t len) 790 { 791 X509_NAME *name = NULL; 792 char *str = NULL; 793 const u_int8_t *p; 794 795 p = asn1; 796 if ((name = d2i_X509_NAME(NULL, &p, len)) == NULL) 797 return (NULL); 798 str = ca_x509_name(name); 799 X509_NAME_free(name); 800 801 return (str); 802 } 803 804 char * 805 ca_x509_name(void *ptr) 806 { 807 char buf[BUFSIZ]; 808 X509_NAME *name = ptr; 809 810 bzero(buf, sizeof(buf)); 811 if (!X509_NAME_oneline(name, buf, sizeof(buf) - 1)) 812 return (NULL); 813 814 return (strdup(buf)); 815 } 816 817 int 818 ca_validate_pubkey(struct iked *env, struct iked_static_id *id, 819 void *data, size_t len) 820 { 821 BIO *rawcert = NULL; 822 RSA *rsa = NULL; 823 EVP_PKEY *peerkey = NULL, *localkey = NULL; 824 int ret = -1; 825 FILE *fp = NULL; 826 char idstr[IKED_ID_SIZE]; 827 char file[MAXPATHLEN]; 828 struct iked_id idp; 829 830 if (len == 0 && data == NULL) 831 return (-1); 832 833 switch (id->id_type) { 834 case IKEV2_ID_IPV4: 835 case IKEV2_ID_FQDN: 836 case IKEV2_ID_UFQDN: 837 case IKEV2_ID_IPV6: 838 break; 839 default: 840 /* Some types like ASN1_DN will not be mapped to file names */ 841 return (-1); 842 } 843 844 bzero(&idp, sizeof(idp)); 845 if ((idp.id_buf = ibuf_new(id->id_data, id->id_length)) == NULL) 846 goto done; 847 848 idp.id_type = id->id_type; 849 idp.id_offset = id->id_offset; 850 if (ikev2_print_id(&idp, idstr, sizeof(idstr)) == -1) 851 goto done; 852 853 if (len == 0) { 854 /* Data is already an public key */ 855 peerkey = (EVP_PKEY *)data; 856 } else { 857 if ((rawcert = BIO_new_mem_buf(data, len)) == NULL) 858 goto done; 859 860 if ((rsa = d2i_RSAPublicKey_bio(rawcert, NULL)) == NULL) 861 goto sslerr; 862 if ((peerkey = EVP_PKEY_new()) == NULL) 863 goto sslerr; 864 if (!EVP_PKEY_set1_RSA(peerkey, rsa)) 865 goto sslerr; 866 } 867 868 lc_string(idstr); 869 if (strlcpy(file, IKED_PUBKEY_DIR, sizeof(file)) >= sizeof(file) || 870 strlcpy(file, idstr, sizeof(file)) >= sizeof(file)) 871 goto done; 872 873 log_debug("%s: looking up %s", __func__, file); 874 875 if ((fp = fopen(file, "r")) == NULL) 876 goto done; 877 878 localkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL); 879 fclose(fp); 880 if (localkey == NULL) 881 goto sslerr; 882 883 if (!EVP_PKEY_cmp(peerkey, localkey)) 884 goto done; 885 886 ret = 0; 887 sslerr: 888 if (ret != 0) 889 ca_sslerror(); 890 done: 891 ibuf_release(idp.id_buf); 892 if (peerkey != NULL) 893 EVP_PKEY_free(peerkey); 894 if (rsa != NULL) 895 RSA_free(rsa); 896 if (rawcert != NULL) 897 BIO_free(rawcert); 898 899 return (ret); 900 } 901 902 int 903 ca_validate_cert(struct iked *env, struct iked_static_id *id, 904 void *data, size_t len) 905 { 906 struct ca_store *store = env->sc_priv; 907 X509_STORE_CTX csc; 908 BIO *rawcert = NULL; 909 X509 *cert = NULL; 910 int ret = -1, result, error; 911 size_t idlen, idoff; 912 const u_int8_t *idptr; 913 X509_NAME *idname = NULL, *subject; 914 const char *errstr = "failed"; 915 916 if (len == 0) { 917 /* Data is already an X509 certificate */ 918 cert = (X509 *)data; 919 } else { 920 /* Convert data to X509 certificate */ 921 if ((rawcert = BIO_new_mem_buf(data, len)) == NULL) 922 goto done; 923 if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL) 924 goto done; 925 } 926 927 /* Certificate needs a valid subjectName */ 928 if ((subject = X509_get_subject_name(cert)) == NULL) { 929 errstr = "invalid subject"; 930 goto done; 931 } 932 933 if (id != NULL) { 934 if ((ret = ca_validate_pubkey(env, id, X509_get_pubkey(cert), 935 0)) == 0) { 936 errstr = "public key found, ok"; 937 goto done; 938 } 939 940 switch (id->id_type) { 941 case IKEV2_ID_ASN1_DN: 942 idoff = id->id_offset; 943 if (id->id_length <= idoff) { 944 errstr = "invalid ASN1_DN id length"; 945 goto done; 946 } 947 idlen = id->id_length - idoff; 948 idptr = id->id_data + idoff; 949 950 if ((idname = d2i_X509_NAME(NULL, 951 &idptr, idlen)) == NULL || 952 X509_NAME_cmp(subject, idname) != 0) { 953 errstr = "ASN1_DN identifier mismatch"; 954 goto done; 955 } 956 break; 957 default: 958 if (ca_x509_subjectaltname_cmp(cert, id) != 0) { 959 errstr = "invalid subjectAltName extension"; 960 goto done; 961 } 962 break; 963 } 964 } 965 966 bzero(&csc, sizeof(csc)); 967 X509_STORE_CTX_init(&csc, store->ca_cas, cert, NULL); 968 if (store->ca_cas->param->flags & X509_V_FLAG_CRL_CHECK) { 969 X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK); 970 X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_CRL_CHECK_ALL); 971 } 972 973 result = X509_verify_cert(&csc); 974 error = csc.error; 975 X509_STORE_CTX_cleanup(&csc); 976 if (error != 0) { 977 errstr = X509_verify_cert_error_string(error); 978 goto done; 979 } 980 981 if (!result) { 982 /* XXX should we accept self-signed certificates? */ 983 errstr = "rejecting self-signed certificate"; 984 goto done; 985 } 986 987 /* Success */ 988 ret = 0; 989 990 done: 991 if (cert != NULL) 992 log_debug("%s: %s %.100s", __func__, cert->name, 993 ret == 0 ? "ok" : errstr); 994 995 if (idname != NULL) 996 X509_NAME_free(idname); 997 if (rawcert != NULL) { 998 BIO_free(rawcert); 999 if (cert != NULL) 1000 X509_free(cert); 1001 } 1002 1003 return (ret); 1004 } 1005 1006 int 1007 ca_x509_subjectaltname_cmp(X509 *cert, struct iked_static_id *id) 1008 { 1009 struct iked_id sanid; 1010 char idstr[IKED_ID_SIZE]; 1011 int ret = -1; 1012 1013 bzero(&sanid, sizeof(sanid)); 1014 1015 if (ca_x509_subjectaltname(cert, &sanid) != 0) 1016 return (-1); 1017 1018 ikev2_print_id(&sanid, idstr, sizeof(idstr)); 1019 1020 /* Compare id types, length and data */ 1021 if ((id->id_type != sanid.id_type) || 1022 ((ssize_t)ibuf_size(sanid.id_buf) != 1023 (id->id_length - id->id_offset)) || 1024 (memcmp(id->id_data + id->id_offset, 1025 ibuf_data(sanid.id_buf), 1026 ibuf_size(sanid.id_buf)) != 0)) { 1027 log_debug("%s: %s mismatched", __func__, idstr); 1028 goto done; 1029 } 1030 1031 ret = 0; 1032 done: 1033 ibuf_release(sanid.id_buf); 1034 return (ret); 1035 } 1036 1037 int 1038 ca_x509_subjectaltname(X509 *cert, struct iked_id *id) 1039 { 1040 X509_EXTENSION *san; 1041 u_int8_t sanhdr[4], *data; 1042 int ext, santype, sanlen; 1043 char idstr[IKED_ID_SIZE]; 1044 1045 if ((ext = X509_get_ext_by_NID(cert, 1046 NID_subject_alt_name, -1)) == -1 || 1047 ((san = X509_get_ext(cert, ext)) == NULL)) { 1048 log_debug("%s: did not find subjectAltName in certificate", 1049 __func__); 1050 return (-1); 1051 } 1052 1053 if (san->value == NULL || san->value->data == NULL || 1054 san->value->length < (int)sizeof(sanhdr)) { 1055 log_debug("%s: invalid subjectAltName in certificate", 1056 __func__); 1057 return (-1); 1058 } 1059 1060 /* This is partially based on isakmpd's x509 subjectaltname code */ 1061 data = (u_int8_t *)san->value->data; 1062 memcpy(&sanhdr, data, sizeof(sanhdr)); 1063 santype = sanhdr[2] & 0x3f; 1064 sanlen = sanhdr[3]; 1065 1066 if ((sanlen + (int)sizeof(sanhdr)) > san->value->length) { 1067 log_debug("%s: invalid subjectAltName length", __func__); 1068 return (-1); 1069 } 1070 1071 switch (santype) { 1072 case GEN_DNS: 1073 id->id_type = IKEV2_ID_FQDN; 1074 break; 1075 case GEN_EMAIL: 1076 id->id_type = IKEV2_ID_UFQDN; 1077 break; 1078 case GEN_IPADD: 1079 if (sanlen == 4) 1080 id->id_type = IKEV2_ID_IPV4; 1081 else if (sanlen == 16) 1082 id->id_type = IKEV2_ID_IPV6; 1083 else { 1084 log_debug("%s: invalid subjectAltName IP address", 1085 __func__); 1086 return (-1); 1087 } 1088 break; 1089 default: 1090 log_debug("%s: unsupported subjectAltName type %d", 1091 __func__, santype); 1092 return (-1); 1093 } 1094 1095 ibuf_release(id->id_buf); 1096 if ((id->id_buf = ibuf_new(data + sizeof(sanhdr), sanlen)) == NULL) { 1097 log_debug("%s: failed to get id buffer", __func__); 1098 return (-1); 1099 } 1100 id->id_offset = 0; 1101 1102 ikev2_print_id(id, idstr, sizeof(idstr)); 1103 log_debug("%s: %s", __func__, idstr); 1104 1105 return (0); 1106 } 1107 1108 void 1109 ca_sslinit(void) 1110 { 1111 OpenSSL_add_all_algorithms(); 1112 ERR_load_crypto_strings(); 1113 1114 /* Init hardware crypto engines. */ 1115 ENGINE_load_builtin_engines(); 1116 ENGINE_register_all_complete(); 1117 } 1118 1119 void 1120 ca_sslerror(void) 1121 { 1122 u_long error; 1123 1124 while ((error = ERR_get_error()) != 0) 1125 log_warn("%s: %.100s", __func__, 1126 ERR_error_string(error, NULL)); 1127 } 1128