1 /* 2 * Copyright (c) 2014 Markus Friedl 3 * Copyright (c) 2005 Marco Pfatschbacher 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <sys/param.h> 18 #include <sys/queue.h> 19 #include <sys/socket.h> 20 #include <sys/uio.h> 21 #include <sys/stat.h> 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <unistd.h> 29 #include <netdb.h> 30 31 #include <openssl/pem.h> 32 #include <openssl/ocsp.h> 33 #include <openssl/err.h> 34 #include <openssl/ssl.h> 35 36 #include <event.h> 37 38 #include "iked.h" 39 40 struct iked_ocsp { 41 struct iked *ocsp_env; /* back pointer to env */ 42 struct iked_sahdr ocsp_sh; /* ike sa */ 43 u_int8_t ocsp_type; /* auth type */ 44 struct iked_socket *ocsp_sock; /* socket to ocsp responder */ 45 BIO *ocsp_cbio; /* matching OpenSSL obj */ 46 OCSP_CERTID *ocsp_id; /* ocsp-id for cert */ 47 OCSP_REQUEST *ocsp_req; /* ocsp-request */ 48 OCSP_REQ_CTX *ocsp_req_ctx; /* async ocsp-request */ 49 }; 50 51 struct ocsp_connect { 52 struct iked_socket oc_sock; 53 char *oc_path; 54 }; 55 56 /* priv */ 57 void ocsp_connect_cb(int, short, void *); 58 int ocsp_connect_finish(struct iked *, int, struct ocsp_connect *); 59 60 /* unpriv */ 61 void ocsp_free(struct iked_ocsp *); 62 void ocsp_callback(int, short, void *); 63 void ocsp_parse_response(struct iked_ocsp *, OCSP_RESPONSE *); 64 STACK_OF(X509) *ocsp_load_certs(const char *); 65 int ocsp_validate_finish(struct iked_ocsp *, int); 66 67 68 /* priv */ 69 70 /* async connect to configure ocsp-responder */ 71 int 72 ocsp_connect(struct iked *env) 73 { 74 struct ocsp_connect *oc = NULL; 75 struct addrinfo hints, *res0 = NULL, *res; 76 char *host = NULL, *port = NULL, *path = NULL; 77 int use_ssl, fd = -1, ret = -1, error; 78 79 if (env->sc_ocsp_url == 0) { 80 log_warnx("%s: no ocsp url", __func__); 81 goto done; 82 } 83 if (!OCSP_parse_url(env->sc_ocsp_url, &host, &port, &path, &use_ssl)) { 84 log_warnx("%s: error parsing OCSP-request-URL: %s", __func__, 85 env->sc_ocsp_url); 86 goto done; 87 } 88 89 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 90 log_debug("%s: socket failed", __func__); 91 goto done; 92 } 93 if ((oc = calloc(1, sizeof(*oc))) == NULL) { 94 log_debug("%s: calloc failed", __func__); 95 goto done; 96 } 97 98 bzero(&hints, sizeof(struct addrinfo)); 99 hints.ai_family = PF_UNSPEC; 100 hints.ai_socktype = SOCK_STREAM; 101 error = getaddrinfo(host, port, &hints, &res0); 102 if (error) { 103 log_debug("%s: getaddrinfo(%s, %s) failed", 104 __func__, host, port); 105 goto done; 106 } 107 /* XXX just pick the first answer. we could loop instead */ 108 for (res = res0; res; res = res->ai_next) 109 if (res->ai_family == AF_INET) 110 break; 111 if (res == NULL) { 112 log_debug("%s: no addr to connect to for %s:%s", 113 __func__, host, port); 114 goto done; 115 } 116 117 oc->oc_sock.sock_fd = fd; 118 oc->oc_sock.sock_env = env; 119 oc->oc_path = path; 120 path = NULL; 121 122 log_debug("%s: connect(%s, %s)", __func__, host, port); 123 socket_set_blockmode(fd, BM_NONBLOCK); 124 if (connect(fd, res->ai_addr, res->ai_addrlen) == -1) { 125 /* register callback for ansync connect */ 126 if (errno == EINPROGRESS) { 127 event_set(&oc->oc_sock.sock_ev, fd, EV_WRITE, 128 ocsp_connect_cb, oc); 129 event_add(&oc->oc_sock.sock_ev, NULL); 130 ret = 0; 131 } else 132 log_debug("%s: error while connecting: %s", __func__, 133 strerror(errno)); 134 } else { 135 ocsp_connect_finish(env, fd, oc); 136 ret = 0; 137 } 138 done: 139 if (res0) 140 freeaddrinfo(res0); 141 free(host); 142 free(port); 143 free(path); 144 if (ret == -1) { 145 ocsp_connect_finish(env, -1, oc); 146 if (fd >= 0) 147 close(fd); 148 } 149 return (ret); 150 } 151 152 /* callback triggered if connection to ocsp-responder completes/fails */ 153 void 154 ocsp_connect_cb(int fd, short event, void *arg) 155 { 156 struct ocsp_connect *oc = arg; 157 int error, send_fd = -1; 158 socklen_t len; 159 160 len = sizeof(error); 161 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 162 log_warn("%s: getsockopt SOL_SOCKET SO_ERROR", __func__); 163 } else if (error) { 164 log_debug("%s: error while connecting: %s", __func__, 165 strerror(error)); 166 } else { 167 send_fd = fd; 168 } 169 ocsp_connect_finish(oc->oc_sock.sock_env, send_fd, oc); 170 171 /* if we did not send the fd, we need to close it ourself */ 172 if (send_fd == -1) 173 close(fd); 174 } 175 176 /* send FD+path or error back to CA process */ 177 int 178 ocsp_connect_finish(struct iked *env, int fd, struct ocsp_connect *oc) 179 { 180 struct iovec iov[1]; 181 int iovcnt = 1, ret; 182 183 if (oc && fd >= 0) { 184 /* the imsg framework will close the FD after send */ 185 iov[0].iov_base = oc->oc_path; 186 iov[0].iov_len = strlen(oc->oc_path); 187 ret = proc_composev_imsg(&env->sc_ps, PROC_CERT, -1, 188 IMSG_OCSP_FD, fd, iov, iovcnt); 189 } else { 190 ret = proc_compose_imsg(&env->sc_ps, PROC_CERT, -1, 191 IMSG_OCSP_FD, -1, NULL, 0); 192 if (fd >= 0) 193 close(fd); 194 } 195 if (oc) { 196 free(oc->oc_path); 197 free(oc); 198 } 199 return (ret); 200 } 201 202 203 /* unpriv */ 204 205 /* validate the certifcate stored in 'data' by querying the ocsp-responder */ 206 int 207 ocsp_validate_cert(struct iked *env, struct iked_static_id *id, 208 void *data, size_t len, struct iked_sahdr sh, u_int8_t type) 209 { 210 struct iked_ocsp_entry *ioe; 211 struct iked_ocsp *ocsp; 212 BIO *rawcert = NULL, *bissuer = NULL; 213 X509 *cert = NULL, *issuer = NULL; 214 215 if ((ioe = calloc(1, sizeof(*ioe))) == NULL) 216 return (-1); 217 if ((ocsp = calloc(1, sizeof(*ocsp))) == NULL) { 218 free(ioe); 219 return (-1); 220 } 221 222 ocsp->ocsp_env = env; 223 ocsp->ocsp_sh = sh; 224 ocsp->ocsp_type = type; 225 226 if ((rawcert = BIO_new_mem_buf(data, len)) == NULL || 227 (cert = d2i_X509_bio(rawcert, NULL)) == NULL || 228 (bissuer = BIO_new_file(IKED_OCSP_ISSUER, "r")) == NULL || 229 (issuer = PEM_read_bio_X509(bissuer, NULL, NULL, NULL)) == NULL || 230 (ocsp->ocsp_cbio = BIO_new(BIO_s_socket())) == NULL || 231 (ocsp->ocsp_req = OCSP_REQUEST_new()) == NULL || 232 !(ocsp->ocsp_id = OCSP_cert_to_id(NULL, cert, issuer)) || 233 !OCSP_request_add0_id(ocsp->ocsp_req, ocsp->ocsp_id)) 234 goto err; 235 236 BIO_free(rawcert); 237 BIO_free(bissuer); 238 X509_free(cert); 239 X509_free(issuer); 240 241 ioe->ioe_ocsp = ocsp; 242 TAILQ_INSERT_TAIL(&env->sc_ocsp, ioe, ioe_entry); 243 244 /* request connection to ocsp-responder */ 245 proc_compose_imsg(&env->sc_ps, PROC_PARENT, -1, 246 IMSG_OCSP_FD, -1, NULL, 0); 247 return (0); 248 249 err: 250 ca_sslerror(__func__); 251 free(ioe); 252 if (rawcert != NULL) 253 BIO_free(rawcert); 254 if (cert != NULL) 255 X509_free(cert); 256 if (bissuer != NULL) 257 BIO_free(bissuer); 258 if (issuer != NULL) 259 X509_free(issuer); 260 ocsp_validate_finish(ocsp, 0); /* failed */ 261 return (-1); 262 } 263 264 /* free ocsp query context */ 265 void 266 ocsp_free(struct iked_ocsp *ocsp) 267 { 268 if (ocsp != NULL) { 269 if (ocsp->ocsp_sock != NULL) { 270 close(ocsp->ocsp_sock->sock_fd); 271 free(ocsp->ocsp_sock); 272 } 273 if (ocsp->ocsp_cbio != NULL) 274 BIO_free_all(ocsp->ocsp_cbio); 275 if (ocsp->ocsp_id != NULL) 276 OCSP_CERTID_free(ocsp->ocsp_id); 277 278 /* XXX not sure about ownership XXX */ 279 if (ocsp->ocsp_req_ctx != NULL) 280 OCSP_REQ_CTX_free(ocsp->ocsp_req_ctx); 281 else if (ocsp->ocsp_req != NULL) 282 OCSP_REQUEST_free(ocsp->ocsp_req); 283 284 free(ocsp); 285 } 286 } 287 288 /* we got a connection to the ocsp responder */ 289 int 290 ocsp_receive_fd(struct iked *env, struct imsg *imsg) 291 { 292 struct iked_ocsp_entry *ioe = NULL; 293 struct iked_ocsp *ocsp = NULL; 294 struct iked_socket *sock; 295 char *path = NULL; 296 int ret = -1; 297 298 log_debug("%s: received socket fd %d", __func__, imsg->fd); 299 if ((ioe = TAILQ_FIRST(&env->sc_ocsp)) == NULL) { 300 log_debug("%s: oops, no request for", __func__); 301 close(imsg->fd); 302 return (-1); 303 } 304 TAILQ_REMOVE(&env->sc_ocsp, ioe, ioe_entry); 305 ocsp = ioe->ioe_ocsp; 306 free(ioe); 307 308 if ((sock = calloc(1, sizeof(*sock))) == NULL) 309 fatal("ocsp_receive_fd: calloc sock"); 310 311 /* note that sock_addr is not set */ 312 sock->sock_fd = imsg->fd; 313 sock->sock_env = env; 314 ocsp->ocsp_sock = sock; 315 316 /* fetch 'path' and 'fd' from imsg */ 317 if ((path = get_string(imsg->data, IMSG_DATA_SIZE(imsg))) == NULL) 318 goto done; 319 320 BIO_set_fd(ocsp->ocsp_cbio, imsg->fd, BIO_NOCLOSE); 321 322 if ((ocsp->ocsp_req_ctx = OCSP_sendreq_new(ocsp->ocsp_cbio, 323 path, NULL, -1)) == NULL) 324 goto done; 325 if (!OCSP_REQ_CTX_set1_req(ocsp->ocsp_req_ctx, ocsp->ocsp_req)) 326 goto done; 327 328 event_set(&sock->sock_ev, sock->sock_fd, EV_WRITE, ocsp_callback, ocsp); 329 event_add(&sock->sock_ev, NULL); 330 ret = 0; 331 done: 332 if (ret == -1) 333 ocsp_validate_finish(ocsp, 0); /* failed */ 334 free(path); 335 return (ret); 336 } 337 338 /* load a stack of x509 certificates */ 339 STACK_OF(X509)* 340 ocsp_load_certs(const char *file) 341 { 342 BIO *bio = NULL; 343 STACK_OF(X509) *certs = NULL; 344 STACK_OF(X509_INFO) *xis = NULL; 345 X509_INFO *xi; 346 int i; 347 348 if ((bio = BIO_new_file(file, "r")) == NULL) { 349 log_warn("%s: BIO_new_file failed for %s", 350 __func__, file); 351 return (NULL); 352 } 353 if ((xis = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)) == NULL) { 354 ca_sslerror(__func__); 355 goto done; 356 } 357 if ((certs = sk_X509_new_null()) == NULL) { 358 log_debug("%s: sk_X509_new_null failed for %s", __func__, file); 359 goto done; 360 } 361 for (i = 0; i < sk_X509_INFO_num(xis); i++) { 362 xi = sk_X509_INFO_value(xis, i); 363 if (xi->x509) { 364 if (!sk_X509_push(certs, xi->x509)) 365 goto done; 366 xi->x509 = NULL; 367 } 368 } 369 370 done: 371 if (bio) 372 BIO_free(bio); 373 if (xis) 374 sk_X509_INFO_pop_free(xis, X509_INFO_free); 375 if (certs && sk_X509_num(certs) <= 0) { 376 sk_X509_pop_free(certs, X509_free); 377 certs = NULL; 378 } 379 return (certs); 380 } 381 382 /* read/write callback that sends the requests and reads the ocsp response */ 383 void 384 ocsp_callback(int fd, short event, void *arg) 385 { 386 struct iked_ocsp *ocsp = arg; 387 struct iked_socket *sock = ocsp->ocsp_sock; 388 OCSP_RESPONSE *resp = NULL; 389 390 /* 391 * Only call OCSP_sendreq_nbio() if should_read/write is 392 * either not requested or read/write can be called. 393 */ 394 if ((!BIO_should_read(ocsp->ocsp_cbio) || (event & EV_READ)) && 395 (!BIO_should_write(ocsp->ocsp_cbio) || (event & EV_WRITE)) && 396 OCSP_sendreq_nbio(&resp, ocsp->ocsp_req_ctx) != -1 ) { 397 ocsp_parse_response(ocsp, resp); 398 return; 399 } 400 if (BIO_should_read(ocsp->ocsp_cbio)) 401 event_set(&sock->sock_ev, sock->sock_fd, EV_READ, 402 ocsp_callback, ocsp); 403 else if (BIO_should_write(ocsp->ocsp_cbio)) 404 event_set(&sock->sock_ev, sock->sock_fd, EV_WRITE, 405 ocsp_callback, ocsp); 406 event_add(&sock->sock_ev, NULL); 407 } 408 409 /* parse the actual OCSP response */ 410 void 411 ocsp_parse_response(struct iked_ocsp *ocsp, OCSP_RESPONSE *resp) 412 { 413 int status; 414 X509_STORE *store = NULL; 415 STACK_OF(X509) *verify_other = NULL; 416 OCSP_BASICRESP *bs = NULL; 417 int verify_flags = 0; 418 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 419 int reason = 0; 420 int error = 1; 421 422 if (!resp) { 423 log_warnx("%s: error querying OCSP responder", __func__); 424 goto done; 425 } 426 427 status = OCSP_response_status(resp); 428 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 429 log_warnx("%s: responder error: %s (%i)\n", __func__, 430 OCSP_response_status_str(status), status); 431 goto done; 432 } 433 434 verify_other = ocsp_load_certs(IKED_OCSP_RESPCERT); 435 verify_flags |= OCSP_TRUSTOTHER; 436 if (!verify_other) 437 goto done; 438 439 bs = OCSP_response_get1_basic(resp); 440 if (!bs) { 441 log_warnx("%s: error parsing response", __func__); 442 goto done; 443 } 444 445 status = OCSP_check_nonce(ocsp->ocsp_req, bs); 446 if (status <= 0) { 447 if (status == -1) 448 log_warnx("%s: no nonce in response", __func__); 449 else { 450 log_warnx("%s: nonce verify error", __func__); 451 goto done; 452 } 453 } 454 455 store = X509_STORE_new(); 456 status = OCSP_basic_verify(bs, verify_other, store, verify_flags); 457 if (status < 0) 458 status = OCSP_basic_verify(bs, NULL, store, 0); 459 460 if (status <= 0) { 461 ca_sslerror(__func__); 462 log_warnx("%s: response verify failure", __func__); 463 goto done; 464 } else 465 log_debug("%s: response verify ok", __func__); 466 467 if (!OCSP_resp_find_status(bs, ocsp->ocsp_id, &status, &reason, 468 &rev, &thisupd, &nextupd)) { 469 log_warnx("%s: no status found", __func__); 470 goto done; 471 } 472 log_debug("%s: status: %s", __func__, OCSP_cert_status_str(status)); 473 474 if (status == V_OCSP_CERTSTATUS_GOOD) 475 error = 0; 476 477 done: 478 if (store) 479 X509_STORE_free(store); 480 if (verify_other) 481 sk_X509_pop_free(verify_other, X509_free); 482 if (resp) 483 OCSP_RESPONSE_free(resp); 484 if (bs) 485 OCSP_BASICRESP_free(bs); 486 487 ocsp_validate_finish(ocsp, error == 0); 488 } 489 490 /* 491 * finish the ocsp_validate_cert() RPC by sending the appropriate 492 * message back to the IKEv2 process 493 */ 494 int 495 ocsp_validate_finish(struct iked_ocsp *ocsp, int valid) 496 { 497 struct iked *env = ocsp->ocsp_env; 498 struct iovec iov[2]; 499 int iovcnt = 2, ret, cmd; 500 501 iov[0].iov_base = &ocsp->ocsp_sh; 502 iov[0].iov_len = sizeof(ocsp->ocsp_sh); 503 iov[1].iov_base = &ocsp->ocsp_type; 504 iov[1].iov_len = sizeof(ocsp->ocsp_type); 505 506 cmd = valid ? IMSG_CERTVALID : IMSG_CERTINVALID; 507 ret = proc_composev_imsg(&env->sc_ps, PROC_IKEV2, -1, 508 cmd, -1, iov, iovcnt); 509 510 ocsp_free(ocsp); 511 return (ret); 512 } 513