1/* $OpenBSD: x509.c,v 1.126 2024/04/28 16:43:42 florian Exp $ */ 2/* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $ */ 3 4/* 5 * Copyright (c) 1998, 1999 Niels Provos. All rights reserved. 6 * Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. 7 * Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * This code was written under funding by Ericsson Radio Systems. 32 */ 33 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <dirent.h> 37#include <errno.h> 38#include <fcntl.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43#include <limits.h> 44 45#include <regex.h> 46#include <keynote.h> 47 48#include "cert.h" 49#include "conf.h" 50#include "exchange.h" 51#include "hash.h" 52#include "ike_auth.h" 53#include "ipsec.h" 54#include "log.h" 55#include "dh.h" 56#include "monitor.h" 57#include "policy.h" 58#include "sa.h" 59#include "util.h" 60#include "x509.h" 61 62static u_int16_t x509_hash(u_int8_t *, size_t); 63static void x509_hash_init(void); 64static X509 *x509_hash_find(u_int8_t *, size_t); 65static int x509_hash_enter(X509 *); 66 67/* 68 * X509_STOREs do not support subjectAltNames, so we have to build 69 * our own hash table. 70 */ 71 72/* 73 * XXX Actually this store is not really useful, we never use it as we have 74 * our own hash table. It also gets collisions if we have several certificates 75 * only differing in subjectAltName. 76 */ 77static X509_STORE *x509_certs = 0; 78static X509_STORE *x509_cas = 0; 79 80static int n_x509_cas = 0; 81 82/* Initial number of bits used as hash. */ 83#define INITIAL_BUCKET_BITS 6 84 85struct x509_hash { 86 LIST_ENTRY(x509_hash) link; 87 88 X509 *cert; 89}; 90 91static LIST_HEAD(x509_list, x509_hash) *x509_tab = 0; 92 93/* Works both as a maximum index and a mask. */ 94static int bucket_mask; 95 96/* 97 * Given an X509 certificate, create a KeyNote assertion where 98 * Issuer/Subject -> Authorizer/Licensees. 99 * XXX RSA-specific. 100 */ 101int 102x509_generate_kn(int id, X509 *cert) 103{ 104 static const char fmt[] = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s" 105 "\"\nConditions: %s >= \"%s\" && %s <= \"%s\";\n"; 106 char *ikey = NULL, *skey = NULL, *buf = NULL; 107 char isname[256], subname[256]; 108 static const char fmt2[] = "Authorizer: \"DN:%s\"\nLicensees: \"DN:%s\"\n" 109 "Conditions: %s >= \"%s\" && %s <= \"%s\";\n"; 110 X509_NAME *issuer, *subject; 111 struct keynote_deckey dc; 112 X509_STORE_CTX *csc = NULL; 113 X509_OBJECT *obj = NULL; 114 X509 *icert; 115 RSA *key = NULL; 116 time_t tt; 117 char before[15], after[15], *timecomp, *timecomp2; 118 ASN1_TIME *tm; 119 int i; 120 121 LOG_DBG((LOG_POLICY, 90, 122 "x509_generate_kn: generating KeyNote policy for certificate %p", 123 cert)); 124 125 issuer = X509_get_issuer_name(cert); 126 subject = X509_get_subject_name(cert); 127 128 /* Missing or self-signed, ignore cert but don't report failure. */ 129 if (!issuer || !subject || !X509_NAME_cmp(issuer, subject)) 130 return 1; 131 132 if (!x509_cert_get_key(cert, &key)) { 133 LOG_DBG((LOG_POLICY, 30, 134 "x509_generate_kn: failed to get public key from cert")); 135 return 0; 136 } 137 dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA; 138 dc.dec_key = key; 139 ikey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX, 140 KEYNOTE_PUBLIC_KEY); 141 if (keynote_errno == ERROR_MEMORY) { 142 log_print("x509_generate_kn: failed to get memory for " 143 "public key"); 144 LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get " 145 "subject key")); 146 goto fail; 147 } 148 if (!ikey) { 149 LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get " 150 "subject key")); 151 goto fail; 152 } 153 154 RSA_free(key); 155 key = NULL; 156 157 csc = X509_STORE_CTX_new(); 158 if (csc == NULL) { 159 log_print("x509_generate_kn: failed to get memory for " 160 "certificate store"); 161 goto fail; 162 } 163 obj = X509_OBJECT_new(); 164 if (obj == NULL) { 165 log_print("x509_generate_kn: failed to get memory for " 166 "certificate object"); 167 goto fail; 168 } 169 170 /* Now find issuer's certificate so we can get the public key. */ 171 X509_STORE_CTX_init(csc, x509_cas, cert, NULL); 172 if (X509_STORE_get_by_subject(csc, X509_LU_X509, issuer, obj) != 173 X509_LU_X509) { 174 X509_STORE_CTX_cleanup(csc); 175 X509_STORE_CTX_init(csc, x509_certs, cert, NULL); 176 if (X509_STORE_get_by_subject(csc, X509_LU_X509, issuer, obj) 177 != X509_LU_X509) { 178 X509_STORE_CTX_cleanup(csc); 179 LOG_DBG((LOG_POLICY, 30, 180 "x509_generate_kn: no certificate found for " 181 "issuer")); 182 goto fail; 183 } 184 } 185 X509_STORE_CTX_free(csc); 186 csc = NULL; 187 188 icert = X509_OBJECT_get0_X509(obj); 189 if (icert == NULL) { 190 LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: " 191 "missing certificates, cannot construct X509 chain")); 192 goto fail; 193 } 194 if (!x509_cert_get_key(icert, &key)) { 195 LOG_DBG((LOG_POLICY, 30, 196 "x509_generate_kn: failed to get public key from cert")); 197 goto fail; 198 } 199 X509_OBJECT_free(obj); 200 obj = NULL; 201 202 dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA; 203 dc.dec_key = key; 204 skey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX, 205 KEYNOTE_PUBLIC_KEY); 206 if (keynote_errno == ERROR_MEMORY) { 207 log_error("x509_generate_kn: failed to get memory for public " 208 "key"); 209 LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer " 210 "key")); 211 goto fail; 212 } 213 if (!skey) { 214 LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer " 215 "key")); 216 goto fail; 217 } 218 219 RSA_free(key); 220 key = NULL; 221 222 if (((tm = X509_get_notBefore(cert)) == NULL) || 223 (tm->type != V_ASN1_UTCTIME && 224 tm->type != V_ASN1_GENERALIZEDTIME)) { 225 struct tm *ltm; 226 227 tt = time(NULL); 228 if ((ltm = localtime(&tt)) == NULL) { 229 LOG_DBG((LOG_POLICY, 30, 230 "x509_generate_kn: invalid local time")); 231 goto fail; 232 } 233 strftime(before, 14, "%Y%m%d%H%M%S", ltm); 234 timecomp = "LocalTimeOfDay"; 235 } else { 236 if (tm->data[tm->length - 1] == 'Z') { 237 timecomp = "GMTTimeOfDay"; 238 i = tm->length - 2; 239 } else { 240 timecomp = "LocalTimeOfDay"; 241 i = tm->length - 1; 242 } 243 244 for (; i >= 0; i--) { 245 if (tm->data[i] < '0' || tm->data[i] > '9') { 246 LOG_DBG((LOG_POLICY, 30, 247 "x509_generate_kn: invalid data in " 248 "NotValidBefore time field")); 249 goto fail; 250 } 251 } 252 253 if (tm->type == V_ASN1_UTCTIME) { 254 if ((tm->length < 10) || (tm->length > 13)) { 255 LOG_DBG((LOG_POLICY, 30, 256 "x509_generate_kn: invalid length " 257 "of NotValidBefore time field (%d)", 258 tm->length)); 259 goto fail; 260 } 261 /* Validity checks. */ 262 if ((tm->data[2] != '0' && tm->data[2] != '1') || 263 (tm->data[2] == '0' && tm->data[3] == '0') || 264 (tm->data[2] == '1' && tm->data[3] > '2') || 265 (tm->data[4] > '3') || 266 (tm->data[4] == '0' && tm->data[5] == '0') || 267 (tm->data[4] == '3' && tm->data[5] > '1') || 268 (tm->data[6] > '2') || 269 (tm->data[6] == '2' && tm->data[7] > '3') || 270 (tm->data[8] > '5')) { 271 LOG_DBG((LOG_POLICY, 30, 272 "x509_generate_kn: invalid value in " 273 "NotValidBefore time field")); 274 goto fail; 275 } 276 /* Stupid UTC tricks. */ 277 if (tm->data[0] < '5') 278 snprintf(before, sizeof before, "20%s", 279 tm->data); 280 else 281 snprintf(before, sizeof before, "19%s", 282 tm->data); 283 } else { /* V_ASN1_GENERICTIME */ 284 if ((tm->length < 12) || (tm->length > 15)) { 285 LOG_DBG((LOG_POLICY, 30, 286 "x509_generate_kn: invalid length of " 287 "NotValidBefore time field (%d)", 288 tm->length)); 289 goto fail; 290 } 291 /* Validity checks. */ 292 if ((tm->data[4] != '0' && tm->data[4] != '1') || 293 (tm->data[4] == '0' && tm->data[5] == '0') || 294 (tm->data[4] == '1' && tm->data[5] > '2') || 295 (tm->data[6] > '3') || 296 (tm->data[6] == '0' && tm->data[7] == '0') || 297 (tm->data[6] == '3' && tm->data[7] > '1') || 298 (tm->data[8] > '2') || 299 (tm->data[8] == '2' && tm->data[9] > '3') || 300 (tm->data[10] > '5')) { 301 LOG_DBG((LOG_POLICY, 30, 302 "x509_generate_kn: invalid value in " 303 "NotValidBefore time field")); 304 goto fail; 305 } 306 snprintf(before, sizeof before, "%s", tm->data); 307 } 308 309 /* Fix missing seconds. */ 310 if (tm->length < 12) { 311 before[12] = '0'; 312 before[13] = '0'; 313 } 314 /* This will overwrite trailing 'Z'. */ 315 before[14] = '\0'; 316 } 317 318 tm = X509_get_notAfter(cert); 319 if (tm == NULL || 320 (tm->type != V_ASN1_UTCTIME && 321 tm->type != V_ASN1_GENERALIZEDTIME)) { 322 struct tm *ltm; 323 324 tt = time(0); 325 if ((ltm = localtime(&tt)) == NULL) { 326 LOG_DBG((LOG_POLICY, 30, 327 "x509_generate_kn: invalid local time")); 328 goto fail; 329 } 330 strftime(after, 14, "%Y%m%d%H%M%S", ltm); 331 timecomp2 = "LocalTimeOfDay"; 332 } else { 333 if (tm->data[tm->length - 1] == 'Z') { 334 timecomp2 = "GMTTimeOfDay"; 335 i = tm->length - 2; 336 } else { 337 timecomp2 = "LocalTimeOfDay"; 338 i = tm->length - 1; 339 } 340 341 for (; i >= 0; i--) { 342 if (tm->data[i] < '0' || tm->data[i] > '9') { 343 LOG_DBG((LOG_POLICY, 30, 344 "x509_generate_kn: invalid data in " 345 "NotValidAfter time field")); 346 goto fail; 347 } 348 } 349 350 if (tm->type == V_ASN1_UTCTIME) { 351 if ((tm->length < 10) || (tm->length > 13)) { 352 LOG_DBG((LOG_POLICY, 30, 353 "x509_generate_kn: invalid length of " 354 "NotValidAfter time field (%d)", 355 tm->length)); 356 goto fail; 357 } 358 /* Validity checks. */ 359 if ((tm->data[2] != '0' && tm->data[2] != '1') || 360 (tm->data[2] == '0' && tm->data[3] == '0') || 361 (tm->data[2] == '1' && tm->data[3] > '2') || 362 (tm->data[4] > '3') || 363 (tm->data[4] == '0' && tm->data[5] == '0') || 364 (tm->data[4] == '3' && tm->data[5] > '1') || 365 (tm->data[6] > '2') || 366 (tm->data[6] == '2' && tm->data[7] > '3') || 367 (tm->data[8] > '5')) { 368 LOG_DBG((LOG_POLICY, 30, 369 "x509_generate_kn: invalid value in " 370 "NotValidAfter time field")); 371 goto fail; 372 } 373 /* Stupid UTC tricks. */ 374 if (tm->data[0] < '5') 375 snprintf(after, sizeof after, "20%s", 376 tm->data); 377 else 378 snprintf(after, sizeof after, "19%s", 379 tm->data); 380 } else { /* V_ASN1_GENERICTIME */ 381 if ((tm->length < 12) || (tm->length > 15)) { 382 LOG_DBG((LOG_POLICY, 30, 383 "x509_generate_kn: invalid length of " 384 "NotValidAfter time field (%d)", 385 tm->length)); 386 goto fail; 387 } 388 /* Validity checks. */ 389 if ((tm->data[4] != '0' && tm->data[4] != '1') || 390 (tm->data[4] == '0' && tm->data[5] == '0') || 391 (tm->data[4] == '1' && tm->data[5] > '2') || 392 (tm->data[6] > '3') || 393 (tm->data[6] == '0' && tm->data[7] == '0') || 394 (tm->data[6] == '3' && tm->data[7] > '1') || 395 (tm->data[8] > '2') || 396 (tm->data[8] == '2' && tm->data[9] > '3') || 397 (tm->data[10] > '5')) { 398 LOG_DBG((LOG_POLICY, 30, 399 "x509_generate_kn: invalid value in " 400 "NotValidAfter time field")); 401 goto fail; 402 } 403 snprintf(after, sizeof after, "%s", tm->data); 404 } 405 406 /* Fix missing seconds. */ 407 if (tm->length < 12) { 408 after[12] = '0'; 409 after[13] = '0'; 410 } 411 after[14] = '\0'; /* This will overwrite trailing 'Z' */ 412 } 413 414 if (asprintf(&buf, fmt, skey, ikey, timecomp, before, timecomp2, 415 after) == -1) { 416 log_error("x509_generate_kn: " 417 "failed to allocate memory for KeyNote credential"); 418 goto fail; 419 } 420 421 free(ikey); 422 ikey = NULL; 423 free(skey); 424 skey = NULL; 425 426 if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) { 427 LOG_DBG((LOG_POLICY, 30, 428 "x509_generate_kn: failed to add new KeyNote credential")); 429 goto fail; 430 } 431 /* We could print the assertion here, but log_print() truncates... */ 432 LOG_DBG((LOG_POLICY, 60, "x509_generate_kn: added credential")); 433 434 free(buf); 435 buf = NULL; 436 437 if (!X509_NAME_oneline(issuer, isname, 256)) { 438 LOG_DBG((LOG_POLICY, 50, 439 "x509_generate_kn: " 440 "X509_NAME_oneline (issuer, ...) failed")); 441 goto fail; 442 } 443 if (!X509_NAME_oneline(subject, subname, 256)) { 444 LOG_DBG((LOG_POLICY, 50, 445 "x509_generate_kn: " 446 "X509_NAME_oneline (subject, ...) failed")); 447 goto fail; 448 } 449 if (asprintf(&buf, fmt2, isname, subname, timecomp, before, 450 timecomp2, after) == -1) { 451 log_error("x509_generate_kn: malloc failed"); 452 return 0; 453 } 454 455 if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) { 456 LOG_DBG((LOG_POLICY, 30, 457 "x509_generate_kn: failed to add new KeyNote credential")); 458 goto fail; 459 } 460 LOG_DBG((LOG_POLICY, 80, "x509_generate_kn: added credential:\n%s", 461 buf)); 462 463 free(buf); 464 return 1; 465 466fail: 467 X509_STORE_CTX_free(csc); 468 X509_OBJECT_free(obj); 469 free(buf); 470 free(skey); 471 free(ikey); 472 if (key) 473 RSA_free(key); 474 475 return 0; 476} 477 478static u_int16_t 479x509_hash(u_int8_t *id, size_t len) 480{ 481 u_int16_t bucket = 0; 482 size_t i; 483 484 /* XXX We might resize if we are crossing a certain threshold. */ 485 for (i = 4; i < (len & ~1); i += 2) { 486 /* Doing it this way avoids alignment problems. */ 487 bucket ^= (id[i] + 1) * (id[i + 1] + 257); 488 } 489 /* Hash in the last character of odd length IDs too. */ 490 if (i < len) 491 bucket ^= (id[i] + 1) * (id[i] + 257); 492 493 bucket &= bucket_mask; 494 return bucket; 495} 496 497static void 498x509_hash_init(void) 499{ 500 struct x509_hash *certh; 501 int i; 502 503 bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1; 504 505 /* If reinitializing, free existing entries. */ 506 if (x509_tab) { 507 for (i = 0; i <= bucket_mask; i++) 508 for (certh = LIST_FIRST(&x509_tab[i]); certh; 509 certh = LIST_FIRST(&x509_tab[i])) { 510 LIST_REMOVE(certh, link); 511 free(certh); 512 } 513 free(x509_tab); 514 } 515 x509_tab = calloc(bucket_mask + 1, sizeof(struct x509_list)); 516 if (!x509_tab) 517 log_fatal("x509_hash_init: malloc (%lu) failed", 518 (bucket_mask + 1) * 519 (unsigned long)sizeof(struct x509_list)); 520 for (i = 0; i <= bucket_mask; i++) { 521 LIST_INIT(&x509_tab[i]); 522 } 523} 524 525/* Lookup a certificate by an ID blob. */ 526static X509 * 527x509_hash_find(u_int8_t *id, size_t len) 528{ 529 struct x509_hash *cert; 530 u_int8_t **cid; 531 u_int32_t *clen; 532 int n, i, id_found; 533 534 for (cert = LIST_FIRST(&x509_tab[x509_hash(id, len)]); cert; 535 cert = LIST_NEXT(cert, link)) { 536 if (!x509_cert_get_subjects(cert->cert, &n, &cid, &clen)) 537 continue; 538 539 id_found = 0; 540 for (i = 0; i < n; i++) { 541 LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", id, len)); 542 LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", cid[i], 543 clen[i])); 544 /* 545 * XXX This identity predicate needs to be 546 * understood. 547 */ 548 if (clen[i] == len && id[0] == cid[i][0] && 549 memcmp(id + 4, cid[i] + 4, len - 4) == 0) { 550 id_found++; 551 break; 552 } 553 } 554 cert_free_subjects(n, cid, clen); 555 if (!id_found) 556 continue; 557 558 LOG_DBG((LOG_CRYPTO, 70, "x509_hash_find: return X509 %p", 559 cert->cert)); 560 return cert->cert; 561 } 562 563 LOG_DBG((LOG_CRYPTO, 70, 564 "x509_hash_find: no certificate matched query")); 565 return 0; 566} 567 568static int 569x509_hash_enter(X509 *cert) 570{ 571 u_int16_t bucket = 0; 572 u_int8_t **id; 573 u_int32_t *len; 574 struct x509_hash *certh; 575 int n, i; 576 577 if (!x509_cert_get_subjects(cert, &n, &id, &len)) { 578 log_print("x509_hash_enter: cannot retrieve subjects"); 579 return 0; 580 } 581 for (i = 0; i < n; i++) { 582 certh = calloc(1, sizeof *certh); 583 if (!certh) { 584 cert_free_subjects(n, id, len); 585 log_error("x509_hash_enter: calloc (1, %lu) failed", 586 (unsigned long)sizeof *certh); 587 return 0; 588 } 589 certh->cert = cert; 590 591 bucket = x509_hash(id[i], len[i]); 592 593 LIST_INSERT_HEAD(&x509_tab[bucket], certh, link); 594 LOG_DBG((LOG_CRYPTO, 70, 595 "x509_hash_enter: cert %p added to bucket %d", 596 cert, bucket)); 597 } 598 cert_free_subjects(n, id, len); 599 600 return 1; 601} 602 603/* X509 Certificate Handling functions. */ 604 605int 606x509_read_from_dir(X509_STORE *ctx, char *name, int hash, int *pcount) 607{ 608 FILE *certfp; 609 X509 *cert; 610 struct stat sb; 611 char fullname[PATH_MAX]; 612 char file[PATH_MAX]; 613 int fd; 614 615 if (strlen(name) >= sizeof fullname - 1) { 616 log_print("x509_read_from_dir: directory name too long"); 617 return 0; 618 } 619 LOG_DBG((LOG_CRYPTO, 40, "x509_read_from_dir: reading certs from %s", 620 name)); 621 622 if (monitor_req_readdir(name) == -1) { 623 LOG_DBG((LOG_CRYPTO, 10, 624 "x509_read_from_dir: opendir (\"%s\") failed: %s", 625 name, strerror(errno))); 626 return 0; 627 } 628 629 while ((fd = monitor_readdir(file, sizeof file)) != -1) { 630 LOG_DBG((LOG_CRYPTO, 60, 631 "x509_read_from_dir: reading certificate %s", 632 file)); 633 634 if (fstat(fd, &sb) == -1) { 635 log_error("x509_read_from_dir: fstat failed"); 636 close(fd); 637 continue; 638 } 639 640 if (!S_ISREG(sb.st_mode)) { 641 close(fd); 642 continue; 643 } 644 645 if ((certfp = fdopen(fd, "r")) == NULL) { 646 log_error("x509_read_from_dir: fdopen failed"); 647 close(fd); 648 continue; 649 } 650 651#if SSLEAY_VERSION_NUMBER >= 0x00904100L 652 cert = PEM_read_X509(certfp, NULL, NULL, NULL); 653#else 654 cert = PEM_read_X509(certfp, NULL, NULL); 655#endif 656 fclose(certfp); 657 658 if (cert == NULL) { 659 log_print("x509_read_from_dir: PEM_read_X509 " 660 "failed for %s", file); 661 continue; 662 } 663 664 if (pcount != NULL) 665 (*pcount)++; 666 667 if (!X509_STORE_add_cert(ctx, cert)) { 668 /* 669 * This is actually expected if we have several 670 * certificates only differing in subjectAltName, 671 * which is not an something that is strange. 672 * Consider multi-homed machines. 673 */ 674 LOG_DBG((LOG_CRYPTO, 50, 675 "x509_read_from_dir: X509_STORE_add_cert failed " 676 "for %s", file)); 677 } 678 if (hash) 679 if (!x509_hash_enter(cert)) 680 log_print("x509_read_from_dir: " 681 "x509_hash_enter (%s) failed", 682 file); 683 } 684 685 return 1; 686} 687 688/* XXX share code with x509_read_from_dir() ? */ 689int 690x509_read_crls_from_dir(X509_STORE *ctx, char *name) 691{ 692 FILE *crlfp; 693 X509_CRL *crl; 694 struct stat sb; 695 char fullname[PATH_MAX]; 696 char file[PATH_MAX]; 697 int fd; 698 699 if (strlen(name) >= sizeof fullname - 1) { 700 log_print("x509_read_crls_from_dir: directory name too long"); 701 return 0; 702 } 703 LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs " 704 "from %s", name)); 705 706 if (monitor_req_readdir(name) == -1) { 707 LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir " 708 "(\"%s\") failed: %s", name, strerror(errno))); 709 return 0; 710 } 711 strlcpy(fullname, name, sizeof fullname); 712 713 while ((fd = monitor_readdir(file, sizeof file)) != -1) { 714 LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading " 715 "CRL %s", file)); 716 717 if (fstat(fd, &sb) == -1) { 718 log_error("x509_read_crls_from_dir: fstat failed"); 719 close(fd); 720 continue; 721 } 722 723 if (!S_ISREG(sb.st_mode)) { 724 close(fd); 725 continue; 726 } 727 728 if ((crlfp = fdopen(fd, "r")) == NULL) { 729 log_error("x509_read_crls_from_dir: fdopen failed"); 730 close(fd); 731 continue; 732 } 733 734 crl = PEM_read_X509_CRL(crlfp, NULL, NULL, NULL); 735 736 fclose(crlfp); 737 738 if (crl == NULL) { 739 log_print("x509_read_crls_from_dir: " 740 "PEM_read_X509_CRL failed for %s", 741 file); 742 continue; 743 } 744 if (!X509_STORE_add_crl(ctx, crl)) { 745 LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: " 746 "X509_STORE_add_crl failed for %s", file)); 747 continue; 748 } 749 /* 750 * XXX This is to make x509_cert_validate set this (and 751 * XXX another) flag when validating certificates. Currently, 752 * XXX OpenSSL defaults to reject an otherwise valid 753 * XXX certificate (chain) if these flags are set but there 754 * XXX are no CRLs to check. The current workaround is to only 755 * XXX set the flags if we actually loaded some CRL data. 756 */ 757 X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK); 758 } 759 760 return 1; 761} 762 763/* Initialize our databases and load our own certificates. */ 764int 765x509_cert_init(void) 766{ 767 char *dirname; 768 769 x509_hash_init(); 770 771 /* Process CA certificates we will trust. */ 772 dirname = conf_get_str("X509-certificates", "CA-directory"); 773 if (!dirname) { 774 log_print("x509_cert_init: no CA-directory"); 775 return 0; 776 } 777 /* Free if already initialized. */ 778 if (x509_cas) 779 X509_STORE_free(x509_cas); 780 781 x509_cas = X509_STORE_new(); 782 if (!x509_cas) { 783 log_print("x509_cert_init: creating new X509_STORE failed"); 784 return 0; 785 } 786 if (!x509_read_from_dir(x509_cas, dirname, 0, &n_x509_cas)) { 787 log_print("x509_cert_init: x509_read_from_dir failed"); 788 return 0; 789 } 790 /* Process client certificates we will accept. */ 791 dirname = conf_get_str("X509-certificates", "Cert-directory"); 792 if (!dirname) { 793 log_print("x509_cert_init: no Cert-directory"); 794 return 0; 795 } 796 /* Free if already initialized. */ 797 if (x509_certs) 798 X509_STORE_free(x509_certs); 799 800 x509_certs = X509_STORE_new(); 801 if (!x509_certs) { 802 log_print("x509_cert_init: creating new X509_STORE failed"); 803 return 0; 804 } 805 if (!x509_read_from_dir(x509_certs, dirname, 1, NULL)) { 806 log_print("x509_cert_init: x509_read_from_dir failed"); 807 return 0; 808 } 809 return 1; 810} 811 812int 813x509_crl_init(void) 814{ 815 /* 816 * XXX I'm not sure if the method to use CRLs in certificate validation 817 * is valid for OpenSSL versions prior to 0.9.7. For now, simply do not 818 * support it. 819 */ 820 char *dirname; 821 dirname = conf_get_str("X509-certificates", "CRL-directory"); 822 if (!dirname) { 823 log_print("x509_crl_init: no CRL-directory"); 824 return 0; 825 } 826 if (!x509_read_crls_from_dir(x509_cas, dirname)) { 827 LOG_DBG((LOG_MISC, 10, 828 "x509_crl_init: x509_read_crls_from_dir failed")); 829 return 0; 830 } 831 832 return 1; 833} 834 835void * 836x509_cert_get(u_int8_t *asn, u_int32_t len) 837{ 838 return x509_from_asn(asn, len); 839} 840 841int 842x509_cert_validate(void *scert) 843{ 844 X509_STORE_CTX *csc; 845 X509_NAME *issuer, *subject; 846 X509 *cert = (X509 *) scert; 847 EVP_PKEY *key; 848 int res, err, flags; 849 850 /* 851 * Validate the peer certificate by checking with the CA certificates 852 * we trust. 853 */ 854 csc = X509_STORE_CTX_new(); 855 if (csc == NULL) { 856 log_print("x509_cert_validate: failed to get memory for " 857 "certificate store"); 858 return 0; 859 } 860 X509_STORE_CTX_init(csc, x509_cas, cert, NULL); 861 /* XXX See comment in x509_read_crls_from_dir. */ 862 flags = X509_VERIFY_PARAM_get_flags(X509_STORE_get0_param(x509_cas)); 863 if (flags & X509_V_FLAG_CRL_CHECK) { 864 X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK); 865 X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK_ALL); 866 } 867 res = X509_verify_cert(csc); 868 err = X509_STORE_CTX_get_error(csc); 869 X509_STORE_CTX_free(csc); 870 871 /* 872 * Return if validation succeeded or self-signed certs are not 873 * accepted. 874 * 875 * XXX X509_verify_cert seems to return -1 if the validation should be 876 * retried somehow. We take this as an error and give up. 877 */ 878 if (res > 0) 879 return 1; 880 else if (res < 0 || 881 (res == 0 && err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) { 882 if (err) 883 log_print("x509_cert_validate: %.100s", 884 X509_verify_cert_error_string(err)); 885 return 0; 886 } else if (!conf_get_str("X509-certificates", "Accept-self-signed")) { 887 if (err) 888 log_print("x509_cert_validate: %.100s", 889 X509_verify_cert_error_string(err)); 890 return 0; 891 } 892 issuer = X509_get_issuer_name(cert); 893 subject = X509_get_subject_name(cert); 894 895 if (!issuer || !subject || X509_NAME_cmp(issuer, subject)) 896 return 0; 897 898 key = X509_get_pubkey(cert); 899 if (!key) { 900 log_print("x509_cert_validate: could not get public key from " 901 "self-signed cert"); 902 return 0; 903 } 904 if (X509_verify(cert, key) == -1) { 905 log_print("x509_cert_validate: self-signed cert is bad"); 906 return 0; 907 } 908 return 1; 909} 910 911int 912x509_cert_insert(int id, void *scert) 913{ 914 X509 *cert; 915 int res; 916 917 cert = X509_dup((X509 *)scert); 918 if (!cert) { 919 log_print("x509_cert_insert: X509_dup failed"); 920 return 0; 921 } 922 if (x509_generate_kn(id, cert) == 0) { 923 LOG_DBG((LOG_POLICY, 50, 924 "x509_cert_insert: x509_generate_kn failed")); 925 X509_free(cert); 926 return 0; 927 } 928 929 res = x509_hash_enter(cert); 930 if (!res) 931 X509_free(cert); 932 933 return res; 934} 935 936static struct x509_hash * 937x509_hash_lookup(X509 *cert) 938{ 939 struct x509_hash *certh; 940 int i; 941 942 for (i = 0; i <= bucket_mask; i++) 943 for (certh = LIST_FIRST(&x509_tab[i]); certh; 944 certh = LIST_NEXT(certh, link)) 945 if (certh->cert == cert) 946 return certh; 947 return 0; 948} 949 950void 951x509_cert_free(void *cert) 952{ 953 struct x509_hash *certh = x509_hash_lookup((X509 *) cert); 954 955 if (certh) 956 LIST_REMOVE(certh, link); 957 X509_free((X509 *) cert); 958} 959 960/* Validate the BER Encoding of a RDNSequence in the CERT_REQ payload. */ 961int 962x509_certreq_validate(u_int8_t *asn, u_int32_t len) 963{ 964 int res = 1; 965#if 0 966 struct norm_type name = SEQOF("issuer", RDNSequence); 967 968 if (!asn_template_clone(&name, 1) || 969 (asn = asn_decode_sequence(asn, len, &name)) == 0) { 970 log_print("x509_certreq_validate: can not decode 'acceptable " 971 "CA' info"); 972 res = 0; 973 } 974 asn_free(&name); 975#endif 976 977 /* XXX - not supported directly in SSL - later. */ 978 979 return res; 980} 981 982/* Decode the BER Encoding of a RDNSequence in the CERT_REQ payload. */ 983int 984x509_certreq_decode(void **pdata, u_int8_t *asn, u_int32_t len) 985{ 986#if 0 987 /* XXX This needs to be done later. */ 988 struct norm_type aca = SEQOF("aca", RDNSequence); 989 struct norm_type *tmp; 990 struct x509_aca naca, *ret; 991 992 if (!asn_template_clone(&aca, 1) || 993 (asn = asn_decode_sequence(asn, len, &aca)) == 0) { 994 log_print("x509_certreq_decode: can not decode 'acceptable " 995 "CA' info"); 996 goto fail; 997 } 998 bzero(&naca, sizeof(naca)); 999 1000 tmp = asn_decompose("aca.RelativeDistinguishedName." 1001 "AttributeValueAssertion", &aca); 1002 if (!tmp) 1003 goto fail; 1004 x509_get_attribval(tmp, &naca.name1); 1005 1006 tmp = asn_decompose("aca.RelativeDistinguishedName[1]" 1007 ".AttributeValueAssertion", &aca); 1008 if (tmp) 1009 x509_get_attribval(tmp, &naca.name2); 1010 1011 asn_free(&aca); 1012 1013 ret = malloc(sizeof(struct x509_aca)); 1014 if (ret) 1015 memcpy(ret, &naca, sizeof(struct x509_aca)); 1016 else { 1017 log_error("x509_certreq_decode: malloc (%lu) failed", 1018 (unsigned long) sizeof(struct x509_aca)); 1019 x509_free_aca(&aca); 1020 } 1021 1022 return ret; 1023 1024fail: 1025 asn_free(&aca); 1026#endif 1027 return 1; 1028} 1029 1030void 1031x509_free_aca(void *blob) 1032{ 1033 struct x509_aca *aca = blob; 1034 1035 if (aca != NULL) { 1036 free(aca->name1.type); 1037 free(aca->name1.val); 1038 1039 free(aca->name2.type); 1040 free(aca->name2.val); 1041 } 1042} 1043 1044X509 * 1045x509_from_asn(u_char *asn, u_int len) 1046{ 1047 BIO *certh; 1048 X509 *scert = 0; 1049 1050 certh = BIO_new(BIO_s_mem()); 1051 if (!certh) { 1052 log_error("x509_from_asn: BIO_new (BIO_s_mem ()) failed"); 1053 return 0; 1054 } 1055 if (BIO_write(certh, asn, len) == -1) { 1056 log_error("x509_from_asn: BIO_write failed\n"); 1057 goto end; 1058 } 1059 scert = d2i_X509_bio(certh, NULL); 1060 if (!scert) { 1061 log_print("x509_from_asn: d2i_X509_bio failed\n"); 1062 goto end; 1063 } 1064end: 1065 BIO_free(certh); 1066 return scert; 1067} 1068 1069/* 1070 * Obtain a certificate from an acceptable CA. 1071 * XXX We don't check if the certificate we find is from an accepted CA. 1072 */ 1073int 1074x509_cert_obtain(u_int8_t *id, size_t id_len, void *data, u_int8_t **cert, 1075 u_int32_t *certlen) 1076{ 1077 struct x509_aca *aca = data; 1078 X509 *scert; 1079 1080 if (aca) 1081 LOG_DBG((LOG_CRYPTO, 60, "x509_cert_obtain: " 1082 "acceptable certificate authorities here")); 1083 1084 /* We need our ID to find a certificate. */ 1085 if (!id) { 1086 log_print("x509_cert_obtain: ID is missing"); 1087 return 0; 1088 } 1089 scert = x509_hash_find(id, id_len); 1090 if (!scert) 1091 return 0; 1092 1093 x509_serialize(scert, cert, certlen); 1094 if (!*cert) 1095 return 0; 1096 return 1; 1097} 1098 1099/* Returns a pointer to the subjectAltName information of X509 certificate. */ 1100int 1101x509_cert_subjectaltname(X509 *scert, u_int8_t **altname, u_int32_t *len) 1102{ 1103 X509_EXTENSION *subjectaltname; 1104 ASN1_OCTET_STRING *sanasn1data; 1105 u_int8_t *sandata; 1106 int extpos, santype, sanlen; 1107 1108 extpos = X509_get_ext_by_NID(scert, NID_subject_alt_name, -1); 1109 if (extpos == -1) { 1110 log_print("x509_cert_subjectaltname: " 1111 "certificate does not contain subjectAltName"); 1112 return 0; 1113 } 1114 subjectaltname = X509_get_ext(scert, extpos); 1115 sanasn1data = X509_EXTENSION_get_data(subjectaltname); 1116 1117 if (!subjectaltname || !sanasn1data || !sanasn1data->data || 1118 sanasn1data->length < 4) { 1119 log_print("x509_cert_subjectaltname: invalid " 1120 "subjectaltname extension"); 1121 return 0; 1122 } 1123 /* SSL does not handle unknown ASN stuff well, do it by hand. */ 1124 sandata = sanasn1data->data; 1125 santype = sandata[2] & 0x3f; 1126 sanlen = sandata[3]; 1127 sandata += 4; 1128 1129 /* 1130 * The test here used to be !=, but some certificates can include 1131 * extra stuff in subjectAltName, so we will just take the first 1132 * salen bytes, and not worry about what follows. 1133 */ 1134 if (sanlen + 4 > sanasn1data->length) { 1135 log_print("x509_cert_subjectaltname: subjectaltname invalid " 1136 "length"); 1137 return 0; 1138 } 1139 *len = sanlen; 1140 *altname = sandata; 1141 return santype; 1142} 1143 1144int 1145x509_cert_get_subjects(void *scert, int *cnt, u_int8_t ***id, 1146 u_int32_t **id_len) 1147{ 1148 X509 *cert = scert; 1149 X509_NAME *subject; 1150 int type; 1151 u_int8_t *altname; 1152 u_int32_t altlen; 1153 u_int8_t *buf = 0; 1154 unsigned char *ubuf; 1155 int i; 1156 1157 *id = 0; 1158 *id_len = 0; 1159 1160 /* 1161 * XXX There can be a collection of subjectAltNames, but for now I 1162 * only return the subjectName and a single subjectAltName, if 1163 * present. 1164 */ 1165 type = x509_cert_subjectaltname(cert, &altname, &altlen); 1166 if (!type) { 1167 *cnt = 1; 1168 altlen = 0; 1169 } else 1170 *cnt = 2; 1171 1172 *id = calloc(*cnt, sizeof **id); 1173 if (!*id) { 1174 log_print("x509_cert_get_subject: malloc (%lu) failed", 1175 *cnt * (unsigned long)sizeof **id); 1176 *cnt = 0; 1177 goto fail; 1178 } 1179 *id_len = calloc(*cnt, sizeof **id_len); 1180 if (!*id_len) { 1181 log_print("x509_cert_get_subject: malloc (%lu) failed", 1182 *cnt * (unsigned long)sizeof **id_len); 1183 goto fail; 1184 } 1185 /* Stash the subjectName into the first slot. */ 1186 subject = X509_get_subject_name(cert); 1187 if (!subject) 1188 goto fail; 1189 1190 (*id_len)[0] = 1191 ISAKMP_ID_DATA_OFF + i2d_X509_NAME(subject, NULL) - 1192 ISAKMP_GEN_SZ; 1193 (*id)[0] = malloc((*id_len)[0]); 1194 if (!(*id)[0]) { 1195 log_print("x509_cert_get_subject: malloc (%d) failed", 1196 (*id_len)[0]); 1197 goto fail; 1198 } 1199 SET_ISAKMP_ID_TYPE((*id)[0] - ISAKMP_GEN_SZ, IPSEC_ID_DER_ASN1_DN); 1200 ubuf = (*id)[0] + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ; 1201 i2d_X509_NAME(subject, &ubuf); 1202 1203 if (altlen) { 1204 /* Stash the subjectAltName into the second slot. */ 1205 buf = malloc(altlen + ISAKMP_ID_DATA_OFF); 1206 if (!buf) { 1207 log_print("x509_cert_get_subject: malloc (%d) failed", 1208 altlen + ISAKMP_ID_DATA_OFF); 1209 goto fail; 1210 } 1211 switch (type) { 1212 case X509v3_DNS_NAME: 1213 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_FQDN); 1214 break; 1215 1216 case X509v3_RFC_NAME: 1217 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_USER_FQDN); 1218 break; 1219 1220 case X509v3_IP_ADDR: 1221 /* 1222 * XXX I dislike the numeric constants, but I don't 1223 * know what we should use otherwise. 1224 */ 1225 switch (altlen) { 1226 case 4: 1227 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV4_ADDR); 1228 break; 1229 1230 case 16: 1231 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV6_ADDR); 1232 break; 1233 1234 default: 1235 log_print("x509_cert_get_subject: invalid " 1236 "subjectAltName IPaddress length %d ", 1237 altlen); 1238 goto fail; 1239 } 1240 break; 1241 } 1242 1243 SET_IPSEC_ID_PROTO(buf + ISAKMP_ID_DOI_DATA_OFF, 0); 1244 SET_IPSEC_ID_PORT(buf + ISAKMP_ID_DOI_DATA_OFF, 0); 1245 memcpy(buf + ISAKMP_ID_DATA_OFF, altname, altlen); 1246 1247 (*id_len)[1] = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ; 1248 (*id)[1] = malloc((*id_len)[1]); 1249 if (!(*id)[1]) { 1250 log_print("x509_cert_get_subject: malloc (%d) failed", 1251 (*id_len)[1]); 1252 goto fail; 1253 } 1254 memcpy((*id)[1], buf + ISAKMP_GEN_SZ, (*id_len)[1]); 1255 1256 free(buf); 1257 buf = 0; 1258 } 1259 return 1; 1260 1261fail: 1262 for (i = 0; i < *cnt; i++) 1263 free((*id)[i]); 1264 free(*id); 1265 free(*id_len); 1266 free(buf); 1267 return 0; 1268} 1269 1270int 1271x509_cert_get_key(void *scert, void *keyp) 1272{ 1273 X509 *cert = scert; 1274 EVP_PKEY *key; 1275 1276 key = X509_get_pubkey(cert); 1277 1278 /* Check if we got the right key type. */ 1279 if (EVP_PKEY_id(key) != EVP_PKEY_RSA) { 1280 log_print("x509_cert_get_key: public key is not a RSA key"); 1281 X509_free(cert); 1282 return 0; 1283 } 1284 *(RSA **)keyp = RSAPublicKey_dup(EVP_PKEY_get0_RSA(key)); 1285 1286 return *(RSA **)keyp == NULL ? 0 : 1; 1287} 1288 1289void * 1290x509_cert_dup(void *scert) 1291{ 1292 return X509_dup(scert); 1293} 1294 1295void 1296x509_serialize(void *scert, u_int8_t **data, u_int32_t *datalen) 1297{ 1298 u_int8_t *p; 1299 1300 *datalen = i2d_X509((X509 *)scert, NULL); 1301 *data = p = malloc(*datalen); 1302 if (!p) { 1303 log_error("x509_serialize: malloc (%d) failed", *datalen); 1304 return; 1305 } 1306 *datalen = i2d_X509((X509 *)scert, &p); 1307} 1308 1309/* From cert to printable */ 1310char * 1311x509_printable(void *cert) 1312{ 1313 char *s; 1314 u_int8_t *data; 1315 u_int32_t datalen; 1316 1317 x509_serialize(cert, &data, &datalen); 1318 if (!data) 1319 return 0; 1320 1321 s = raw2hex(data, datalen); 1322 free(data); 1323 return s; 1324} 1325 1326/* From printable to cert */ 1327void * 1328x509_from_printable(char *cert) 1329{ 1330 u_int8_t *buf; 1331 int plen, ret; 1332 void *foo; 1333 1334 plen = (strlen(cert) + 1) / 2; 1335 buf = malloc(plen); 1336 if (!buf) { 1337 log_error("x509_from_printable: malloc (%d) failed", plen); 1338 return 0; 1339 } 1340 ret = hex2raw(cert, buf, plen); 1341 if (ret == -1) { 1342 free(buf); 1343 log_print("x509_from_printable: badly formatted cert"); 1344 return 0; 1345 } 1346 foo = x509_cert_get(buf, plen); 1347 free(buf); 1348 if (!foo) 1349 log_print("x509_from_printable: " 1350 "could not retrieve certificate"); 1351 return foo; 1352} 1353 1354char * 1355x509_DN_string(u_int8_t *asn1, size_t sz) 1356{ 1357 X509_NAME *name; 1358 const u_int8_t *p = asn1; 1359 char buf[256]; /* XXX Just a guess at a maximum length. */ 1360 long len = sz; 1361 1362 name = d2i_X509_NAME(NULL, &p, len); 1363 if (!name) { 1364 log_print("x509_DN_string: d2i_X509_NAME failed"); 1365 return 0; 1366 } 1367 if (!X509_NAME_oneline(name, buf, sizeof buf - 1)) { 1368 log_print("x509_DN_string: X509_NAME_oneline failed"); 1369 X509_NAME_free(name); 1370 return 0; 1371 } 1372 X509_NAME_free(name); 1373 buf[sizeof buf - 1] = '\0'; 1374 return strdup(buf); 1375} 1376 1377/* Number of CAs we trust (to decide whether we can send CERT_REQ) */ 1378int 1379x509_ca_count(void) 1380{ 1381 return n_x509_cas; 1382} 1383