- Timestamp:
- Apr 21, 2015, 8:09:54 AM (4 years ago)
- Branches:
- debian/master, debian/stretch-backports, jessie-backports, master, upstream
- Children:
- 4133f2d
- Parents:
- 73f6f12 (diff), d04f7da (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Thomas Klute <thomas2.klute@…> (04/21/15 06:25:30)
- git-committer:
- Thomas Klute <thomas2.klute@…> (04/21/15 08:09:54)
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_config.c
r73f6f12 r2cde026d 20 20 #include "mod_gnutls.h" 21 21 #include "apr_lib.h" 22 #include <gnutls/abstract.h> 23 24 #define INIT_CA_SIZE 128 22 25 23 26 #ifdef APLOG_USE_MODULE … … 25 28 #endif 26 29 30 static int pin_callback(void *user, int attempt __attribute__((unused)), 31 const char *token_url __attribute__((unused)), 32 const char *token_label, unsigned int flags, 33 char *pin, size_t pin_max) 34 { 35 mgs_srvconf_rec *sc = user; 36 37 if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY || 38 flags & GNUTLS_PIN_WRONG) { 39 return -1; 40 } 41 42 if (token_label && strcmp(token_label, "SRK") == 0) { 43 snprintf(pin, pin_max, "%s", sc->srk_pin); 44 } else { 45 snprintf(pin, pin_max, "%s", sc->pin); 46 } 47 return 0; 48 } 49 27 50 static int load_datum_from_file(apr_pool_t * pool, 28 const char *file, gnutls_datum_t * data) { 51 const char *file, gnutls_datum_t * data) 52 { 29 53 apr_file_t *fp; 30 54 apr_finfo_t finfo; … … 33 57 34 58 rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, 35 59 APR_OS_DEFAULT, pool); 36 60 if (rv != APR_SUCCESS) { 37 61 return rv; 38 62 } 39 63 … … 41 65 42 66 if (rv != APR_SUCCESS) { 43 67 return rv; 44 68 } 45 69 … … 48 72 49 73 if (rv != APR_SUCCESS) { 50 74 return rv; 51 75 } 52 76 apr_file_close(fp); … … 58 82 } 59 83 84 /* 2048-bit group parameters from SRP specification */ 85 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" 86 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" 87 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" 88 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n" 89 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n" 90 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n" 91 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n" 92 "-----END DH PARAMETERS-----\n"; 93 94 int mgs_load_files(apr_pool_t * p, server_rec * s) 95 { 96 apr_pool_t *spool; 97 const char *file; 98 gnutls_datum_t data; 99 int ret; 100 mgs_srvconf_rec *sc = 101 (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 102 &gnutls_module); 103 104 apr_pool_create(&spool, p); 105 106 sc->cert_pgp = apr_pcalloc(p, sizeof(sc->cert_pgp[0])); 107 sc->cert_crt_pgp = apr_pcalloc(p, sizeof(sc->cert_crt_pgp[0])); 108 sc->certs_x509_chain = 109 apr_pcalloc(p, MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0])); 110 sc->certs_x509_crt_chain = 111 apr_pcalloc(p, 112 MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0])); 113 114 ret = gnutls_certificate_allocate_credentials(&sc->certs); 115 if (ret < 0) { 116 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 117 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 118 gnutls_strerror(ret)); 119 ret = -1; 120 goto cleanup; 121 } 122 123 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds); 124 if (ret < 0) { 125 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 126 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 127 gnutls_strerror(ret)); 128 ret = -1; 129 goto cleanup; 130 } 131 132 /* Load SRP parameters */ 133 #ifdef ENABLE_SRP 134 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds); 135 if (ret < 0) { 136 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 137 "GnuTLS: Failed to initialize" ": (%d) %s", ret, 138 gnutls_strerror(ret)); 139 ret = -1; 140 goto cleanup; 141 } 142 143 if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) { 144 ret = gnutls_srp_set_server_credentials_file 145 (sc->srp_creds, sc->srp_tpasswd_file, 146 sc->srp_tpasswd_conf_file); 147 148 if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 149 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, 150 s, 151 "GnuTLS: Host '%s:%d' is missing a " 152 "SRP password or conf File!", 153 s->server_hostname, s->port); 154 ret = -1; 155 goto cleanup; 156 } 157 } 158 #endif 159 160 ret = gnutls_dh_params_init(&sc->dh_params); 161 if (ret < 0) { 162 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 163 "GnuTLS: Failed to initialize" 164 ": (%d) %s", ret, gnutls_strerror(ret)); 165 ret = -1; 166 goto cleanup; 167 } 168 169 /* Load DH parameters */ 170 if (sc->dh_file) { 171 if (load_datum_from_file(spool, sc->dh_file, &data) != 0) { 172 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 173 "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file); 174 ret = -1; 175 goto cleanup; 176 } 177 178 ret = 179 gnutls_dh_params_import_pkcs3(sc->dh_params, &data, 180 GNUTLS_X509_FMT_PEM); 181 if (ret < 0) { 182 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 183 "GnuTLS: Failed to Import " 184 "DH params '%s': (%d) %s", sc->dh_file, ret, 185 gnutls_strerror(ret)); 186 ret = -1; 187 goto cleanup; 188 } 189 } else { 190 gnutls_datum_t pdata = { 191 (void *) static_dh_params, 192 sizeof(static_dh_params) 193 }; 194 195 ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM); 196 if (ret < 0) { 197 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 198 "GnuTLS: Unable to generate or load DH Params: (%d) %s", 199 ret, gnutls_strerror(ret)); 200 ret = -1; 201 goto cleanup; 202 } 203 } 204 205 if (sc->x509_cert_file != NULL) { 206 unsigned int chain_num, i; 207 unsigned format = GNUTLS_X509_FMT_PEM; 208 209 /* Load X.509 certificate */ 210 if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) { 211 gnutls_pkcs11_obj_t obj; 212 213 file = sc->x509_cert_file; 214 215 ret = gnutls_pkcs11_obj_init(&obj); 216 if (ret < 0) { 217 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 218 "GnuTLS: Error Initializing PKCS #11 object"); 219 ret = -1; 220 goto cleanup; 221 } 222 223 gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc); 224 225 ret = gnutls_pkcs11_obj_import_url(obj, file, GNUTLS_PKCS11_OBJ_FLAG_LOGIN); 226 if (ret < 0) { 227 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 228 "GnuTLS: Error Importing PKCS #11 object: '%s': %s", 229 file, gnutls_strerror(ret)); 230 ret = -1; 231 goto cleanup; 232 } 233 234 format = GNUTLS_X509_FMT_DER; 235 ret = gnutls_pkcs11_obj_export2(obj, &data); 236 if (ret < 0) { 237 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 238 "GnuTLS: Error Exporting a PKCS #11 object: '%s': %s", 239 file, gnutls_strerror(ret)); 240 ret = -1; 241 goto cleanup; 242 } 243 244 gnutls_pkcs11_obj_deinit(obj); 245 } else { 246 file = ap_server_root_relative(spool, sc->x509_cert_file); 247 248 ret = gnutls_load_file(file, &data); 249 if (ret < 0) { 250 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 251 "GnuTLS: Error Reading Certificate '%s': %s", 252 file, gnutls_strerror(ret)); 253 ret = -1; 254 goto cleanup; 255 } 256 } 257 258 ret = 259 gnutls_x509_crt_list_import2(&sc->certs_x509_crt_chain, 260 &chain_num, &data, format, 261 GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); 262 gnutls_free(data.data); 263 sc->certs_x509_chain_num = chain_num; 264 265 if (ret < 0) { 266 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 267 "GnuTLS: Failed to Import Certificate Chain '%s': (%d) %s", 268 file, ret, gnutls_strerror(ret)); 269 ret = -1; 270 goto cleanup; 271 } 272 273 for (i = 0; i < chain_num; i++) { 274 ret = 275 gnutls_pcert_import_x509(&sc->certs_x509_chain[i], 276 sc->certs_x509_crt_chain[i], 0); 277 if (ret < 0) { 278 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 279 "GnuTLS: Failed to Import pCertificate '%s': (%d) %s", 280 file, ret, gnutls_strerror(ret)); 281 ret = -1; 282 goto cleanup; 283 } 284 } 285 sc->certs_x509_chain_num = chain_num; 286 } 287 288 if (sc->x509_key_file) { 289 ret = gnutls_privkey_init(&sc->privkey_x509); 290 if (ret < 0) { 291 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 292 "GnuTLS: Failed to initialize: (%d) %s", ret, 293 gnutls_strerror(ret)); 294 ret = -1; 295 goto cleanup; 296 } 297 298 if (gnutls_url_is_supported(sc->x509_key_file) != 0) { 299 file = sc->x509_key_file; 300 301 gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, 302 sc); 303 304 ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0); 305 306 if (ret < 0) { 307 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 308 "GnuTLS: Failed to Import Private Key URL '%s': (%d) %s", 309 file, ret, gnutls_strerror(ret)); 310 ret = -1; 311 goto cleanup; 312 } 313 } else { 314 file = ap_server_root_relative(spool, sc->x509_key_file); 315 316 if (load_datum_from_file(spool, file, &data) != 0) { 317 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 318 "GnuTLS: Error Reading Private Key '%s'", 319 file); 320 ret = -1; 321 goto cleanup; 322 } 323 324 ret = 325 gnutls_privkey_import_x509_raw(sc->privkey_x509, &data, 326 GNUTLS_X509_FMT_PEM, sc->pin, 327 0); 328 329 if (ret < 0) { 330 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 331 "GnuTLS: Failed to Import Private Key '%s': (%d) %s", 332 file, ret, gnutls_strerror(ret)); 333 ret = -1; 334 goto cleanup; 335 } 336 } 337 } 338 339 /* Load the X.509 CA file */ 340 if (sc->x509_ca_file) { 341 if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) { 342 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 343 "GnuTLS: Error Reading " "Client CA File '%s'", 344 sc->x509_ca_file); 345 ret = -1; 346 goto cleanup; 347 } 348 349 ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size, 350 &data, GNUTLS_X509_FMT_PEM, 0); 351 if (ret < 0) { 352 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 353 "GnuTLS: Failed to load " 354 "Client CA File '%s': (%d) %s", sc->x509_ca_file, 355 ret, gnutls_strerror(ret)); 356 ret = -1; 357 goto cleanup; 358 } 359 } 360 361 if (sc->pgp_cert_file) { 362 if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) { 363 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 364 "GnuTLS: Error Reading " "Certificate '%s'", 365 sc->pgp_cert_file); 366 ret = -1; 367 goto cleanup; 368 } 369 370 ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]); 371 if (ret < 0) { 372 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 373 "GnuTLS: Failed to Init " 374 "PGP Certificate: (%d) %s", ret, 375 gnutls_strerror(ret)); 376 ret = -1; 377 goto cleanup; 378 } 379 380 ret = 381 gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data, 382 GNUTLS_OPENPGP_FMT_BASE64); 383 if (ret < 0) { 384 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 385 "GnuTLS: Failed to Import " 386 "PGP Certificate: (%d) %s", ret, 387 gnutls_strerror(ret)); 388 ret = -1; 389 goto cleanup; 390 } 391 392 ret = 393 gnutls_pcert_import_openpgp(sc->cert_pgp, sc->cert_crt_pgp[0], 394 0); 395 if (ret < 0) { 396 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 397 "GnuTLS: Failed to Import " 398 "PGP pCertificate: (%d) %s", ret, 399 gnutls_strerror(ret)); 400 ret = -1; 401 goto cleanup; 402 } 403 } 404 405 /* Load the PGP key file */ 406 if (sc->pgp_key_file) { 407 if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) { 408 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 409 "GnuTLS: Error Reading " "Private Key '%s'", 410 sc->pgp_key_file); 411 ret = -1; 412 goto cleanup; 413 } 414 415 ret = gnutls_privkey_init(&sc->privkey_pgp); 416 if (ret < 0) { 417 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 418 "GnuTLS: Failed to initialize" 419 ": (%d) %s", ret, gnutls_strerror(ret)); 420 ret = -1; 421 goto cleanup; 422 } 423 424 #if GNUTLS_VERSION_NUMBER < 0x030312 425 /* GnuTLS versions before 3.3.12 contain a bug in 426 * gnutls_privkey_import_openpgp_raw which frees data that is 427 * accessed when the key is used, leading to segfault. Loading 428 * the key into a gnutls_openpgp_privkey_t and then assigning 429 * it to the gnutls_privkey_t works around the bug, hence this 430 * chain of gnutls_openpgp_privkey_init, 431 * gnutls_openpgp_privkey_import and 432 * gnutls_privkey_import_openpgp. */ 433 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal); 434 if (ret != 0) { 435 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 436 "GnuTLS: Failed to initialize " 437 "PGP Private Key '%s': (%d) %s", 438 sc->pgp_key_file, ret, gnutls_strerror(ret)); 439 ret = -1; 440 goto cleanup; 441 } 442 443 ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data, 444 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); 445 if (ret != 0) { 446 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 447 "GnuTLS: Failed to Import " 448 "PGP Private Key '%s': (%d) %s", 449 sc->pgp_key_file, ret, gnutls_strerror(ret)); 450 ret = -1; 451 goto cleanup; 452 } 453 454 ret = gnutls_privkey_import_openpgp(sc->privkey_pgp, 455 sc->privkey_pgp_internal, 0); 456 if (ret != 0) 457 { 458 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 459 "GnuTLS: Failed to assign PGP Private Key '%s' " 460 "to gnutls_privkey_t structure: (%d) %s", 461 sc->pgp_key_file, ret, gnutls_strerror(ret)); 462 ret = -1; 463 goto cleanup; 464 } 465 #else 466 ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data, 467 GNUTLS_OPENPGP_FMT_BASE64, 468 NULL, NULL); 469 if (ret != 0) 470 { 471 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 472 "GnuTLS: Failed to Import " 473 "PGP Private Key '%s': (%d) %s", 474 sc->pgp_key_file, ret, gnutls_strerror(ret)); 475 ret = -1; 476 goto cleanup; 477 } 478 #endif 479 } 480 481 /* Load the keyring file */ 482 if (sc->pgp_ring_file) { 483 if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) { 484 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 485 "GnuTLS: Error Reading " "Keyring File '%s'", 486 sc->pgp_ring_file); 487 ret = -1; 488 goto cleanup; 489 } 490 491 ret = gnutls_openpgp_keyring_init(&sc->pgp_list); 492 if (ret < 0) { 493 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 494 "GnuTLS: Failed to initialize" 495 "keyring: (%d) %s", ret, gnutls_strerror(ret)); 496 ret = -1; 497 goto cleanup; 498 } 499 500 ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data, 501 GNUTLS_OPENPGP_FMT_BASE64); 502 if (ret < 0) { 503 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 504 "GnuTLS: Failed to load " 505 "Keyring File '%s': (%d) %s", sc->pgp_ring_file, 506 ret, gnutls_strerror(ret)); 507 ret = -1; 508 goto cleanup; 509 } 510 } 511 512 if (sc->priorities_str) { 513 const char *err; 514 ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err); 515 516 if (ret < 0) { 517 if (ret == GNUTLS_E_INVALID_REQUEST) { 518 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 519 "GnuTLS: Syntax error parsing priorities string at: %s", 520 err); 521 } else { 522 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 523 "GnuTLS: error parsing priorities string"); 524 525 } 526 ret = -1; 527 goto cleanup; 528 } 529 } 530 531 ret = 0; 532 cleanup: 533 apr_pool_destroy(spool); 534 535 return ret; 536 } 537 538 int mgs_pkcs11_reinit(server_rec * base_server) 539 { 540 int ret; 541 server_rec *s; 542 mgs_srvconf_rec *sc; 543 544 gnutls_pkcs11_reinit(); 545 546 for (s = base_server; s; s = s->next) { 547 sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 548 549 /* gnutls caches the session in a private key, so we need to open 550 * a new one */ 551 if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) { 552 gnutls_privkey_deinit(sc->privkey_x509); 553 554 ret = gnutls_privkey_init(&sc->privkey_x509); 555 if (ret < 0) { 556 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 557 "GnuTLS: Failed to initialize: (%d) %s", ret, 558 gnutls_strerror(ret)); 559 goto fail; 560 } 561 562 gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc); 563 564 ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0); 565 if (ret < 0) { 566 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 567 "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s", 568 sc->x509_key_file, ret, gnutls_strerror(ret)); 569 goto fail; 570 } 571 } 572 } 573 574 return 0; 575 576 fail: 577 gnutls_privkey_deinit(sc->privkey_x509); 578 return -1; 579 } 580 60 581 const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)), 61 582 const char *arg) { 62 int ret; 63 gnutls_datum_t data; 64 const char *file; 65 apr_pool_t *spool; 66 mgs_srvconf_rec *sc = 67 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 68 module_config, 69 &gnutls_module); 70 71 apr_pool_create(&spool, parms->pool); 72 73 file = ap_server_root_relative(spool, arg); 74 75 if (load_datum_from_file(spool, file, &data) != 0) { 76 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 77 "DH params '%s'", file); 78 } 79 80 ret = gnutls_dh_params_init(&sc->dh_params); 81 if (ret < 0) { 82 return apr_psprintf(parms->pool, 83 "GnuTLS: Failed to initialize" 84 ": (%d) %s", ret, 85 gnutls_strerror(ret)); 86 } 87 88 ret = 89 gnutls_dh_params_import_pkcs3(sc->dh_params, &data, 90 GNUTLS_X509_FMT_PEM); 91 if (ret < 0) { 92 return apr_psprintf(parms->pool, 93 "GnuTLS: Failed to Import " 94 "DH params '%s': (%d) %s", file, ret, 95 gnutls_strerror(ret)); 96 } 97 98 apr_pool_destroy(spool); 99 100 return NULL; 101 } 102 103 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) 583 mgs_srvconf_rec *sc = 584 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 585 module_config, 586 &gnutls_module); 587 588 sc->dh_file = ap_server_root_relative(parms->pool, arg); 589 590 return NULL; 591 } 592 593 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 594 595 mgs_srvconf_rec *sc = 596 (mgs_srvconf_rec *) ap_get_module_config(parms-> 597 server->module_config, 598 &gnutls_module); 599 600 sc->x509_cert_file = apr_pstrdup(parms->pool, arg); 601 602 return NULL; 603 604 } 605 606 const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 607 608 mgs_srvconf_rec *sc = 609 (mgs_srvconf_rec *) ap_get_module_config(parms-> 610 server->module_config, 611 &gnutls_module); 612 613 sc->x509_key_file = apr_pstrdup(parms->pool, arg); 614 615 return NULL; 616 } 617 618 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)), 619 const char *arg) 104 620 { 105 int ret; 106 gnutls_datum_t data; 107 const char *file; 108 apr_pool_t *spool; 109 110 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 111 apr_pool_create(&spool, parms->pool); 112 113 file = ap_server_root_relative(spool, arg); 114 115 if (load_datum_from_file(spool, file, &data) != 0) { 116 apr_pool_destroy(spool); 117 return apr_psprintf(parms->pool, "GnuTLS: Error Reading Certificate '%s'", file); 118 } 119 120 sc->certs_x509_chain_num = MAX_CHAIN_SIZE; 121 ret = gnutls_x509_crt_list_import(sc->certs_x509_chain, &sc->certs_x509_chain_num, &data, GNUTLS_X509_FMT_PEM, 0); 122 if (ret < 0) { 123 apr_pool_destroy(spool); 124 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret)); 125 } 126 127 apr_pool_destroy(spool); 128 return NULL; 129 130 } 131 132 const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) { 133 134 int ret; 135 gnutls_datum_t data; 136 const char *file; 137 apr_pool_t *spool; 138 const char *out; 139 140 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 141 142 apr_pool_create(&spool, parms->pool); 143 144 file = ap_server_root_relative(spool, arg); 145 146 if (load_datum_from_file(spool, file, &data) != 0) { 147 out = apr_psprintf(parms->pool, "GnuTLS: Error Reading Private Key '%s'", file); 148 apr_pool_destroy(spool); 149 return out; 150 } 151 152 ret = gnutls_x509_privkey_init(&sc->privkey_x509); 153 154 if (ret < 0) { 155 apr_pool_destroy(spool); 156 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize: (%d) %s", ret, gnutls_strerror(ret)); 157 } 158 159 ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM); 160 161 if (ret < 0) { 162 ret = gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN); 163 } 164 165 if (ret < 0) { 166 out = apr_psprintf(parms->pool, "GnuTLS: Failed to Import Private Key '%s': (%d) %s", file, ret, gnutls_strerror(ret)); 167 apr_pool_destroy(spool); 168 return out; 169 } 170 171 apr_pool_destroy(spool); 172 173 return NULL; 174 } 175 176 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)), 177 const char *arg) { 178 int ret; 179 gnutls_datum_t data; 180 const char *file; 181 apr_pool_t *spool; 182 mgs_srvconf_rec *sc = 183 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 184 module_config, 185 &gnutls_module); 186 apr_pool_create(&spool, parms->pool); 187 188 file = ap_server_root_relative(spool, arg); 189 190 if (load_datum_from_file(spool, file, &data) != 0) { 191 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 192 "Certificate '%s'", file); 193 } 194 195 ret = gnutls_openpgp_crt_init(&sc->cert_pgp); 196 if (ret < 0) { 197 return apr_psprintf(parms->pool, "GnuTLS: Failed to Init " 198 "PGP Certificate: (%d) %s", ret, 199 gnutls_strerror(ret)); 200 } 201 202 ret = 203 gnutls_openpgp_crt_import(sc->cert_pgp, &data, 204 GNUTLS_OPENPGP_FMT_BASE64); 205 if (ret < 0) { 206 return apr_psprintf(parms->pool, 207 "GnuTLS: Failed to Import " 208 "PGP Certificate '%s': (%d) %s", file, 209 ret, gnutls_strerror(ret)); 210 } 211 212 apr_pool_destroy(spool); 621 mgs_srvconf_rec *sc = 622 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 623 module_config, 624 &gnutls_module); 625 626 sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg); 627 213 628 return NULL; 214 629 } … … 216 631 const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)), 217 632 const char *arg) { 218 int ret; 219 gnutls_datum_t data; 220 const char *file; 221 apr_pool_t *spool; 222 mgs_srvconf_rec *sc = 223 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 224 module_config, 225 &gnutls_module); 226 apr_pool_create(&spool, parms->pool); 227 228 file = ap_server_root_relative(spool, arg); 229 230 if (load_datum_from_file(spool, file, &data) != 0) { 231 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 232 "Private Key '%s'", file); 233 } 234 235 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp); 236 if (ret < 0) { 237 return apr_psprintf(parms->pool, 238 "GnuTLS: Failed to initialize" 239 ": (%d) %s", ret, 240 gnutls_strerror(ret)); 241 } 242 243 ret = 244 gnutls_openpgp_privkey_import(sc->privkey_pgp, &data, 245 GNUTLS_OPENPGP_FMT_BASE64, NULL, 246 0); 247 if (ret != 0) { 248 return apr_psprintf(parms->pool, 249 "GnuTLS: Failed to Import " 250 "PGP Private Key '%s': (%d) %s", file, 251 ret, gnutls_strerror(ret)); 252 } 253 apr_pool_destroy(spool); 633 mgs_srvconf_rec *sc = 634 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 635 module_config, 636 &gnutls_module); 637 638 sc->pgp_key_file = ap_server_root_relative(parms->pool, arg); 639 254 640 return NULL; 255 641 } … … 258 644 const char *arg) { 259 645 mgs_srvconf_rec *sc = 260 261 262 646 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 647 module_config, 648 &gnutls_module); 263 649 264 650 sc->tickets = 0; 265 651 if (strcasecmp("on", arg) == 0) { 266 652 sc->tickets = 1; 267 653 } 268 654 … … 276 662 const char *arg) { 277 663 mgs_srvconf_rec *sc = 278 279 280 664 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 665 module_config, 666 &gnutls_module); 281 667 282 668 sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg); … … 288 674 const char *arg) { 289 675 mgs_srvconf_rec *sc = 290 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 291 module_config, 292 &gnutls_module); 293 294 sc->srp_tpasswd_conf_file = 295 ap_server_root_relative(parms->pool, arg); 676 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 677 module_config, 678 &gnutls_module); 679 680 sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg); 296 681 297 682 return NULL; … … 304 689 const char *err; 305 690 mgs_srvconf_rec *sc = 306 307 691 ap_get_module_config(parms->server->module_config, 692 &gnutls_module); 308 693 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { 309 694 return err; 310 695 } 311 696 312 697 if (strcasecmp("none", type) == 0) { 313 314 315 698 sc->cache_type = mgs_cache_none; 699 sc->cache_config = NULL; 700 return NULL; 316 701 } else if (strcasecmp("dbm", type) == 0) { 317 702 sc->cache_type = mgs_cache_dbm; 318 703 } else if (strcasecmp("gdbm", type) == 0) { 319 704 sc->cache_type = mgs_cache_gdbm; 320 705 } 321 706 #if HAVE_APR_MEMCACHE 322 707 else if (strcasecmp("memcache", type) == 0) { 323 708 sc->cache_type = mgs_cache_memcache; 324 709 } 325 710 #endif 326 711 else { 327 712 return "Invalid Type for GnuTLSCache!"; 328 713 } 329 714 330 715 if (arg == NULL) 331 716 return "Invalid argument 2 for GnuTLSCache!"; 332 717 333 718 if (sc->cache_type == mgs_cache_dbm 334 || sc->cache_type == mgs_cache_gdbm) { 335 sc->cache_config = 336 ap_server_root_relative(parms->pool, arg); 719 || sc->cache_type == mgs_cache_gdbm) { 720 sc->cache_config = ap_server_root_relative(parms->pool, arg); 337 721 } else { 338 722 sc->cache_config = apr_pstrdup(parms->pool, arg); 339 723 } 340 724 … … 347 731 const char *err; 348 732 mgs_srvconf_rec *sc = 349 350 351 733 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 734 module_config, 735 &gnutls_module); 352 736 353 737 if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { 354 738 return err; 355 739 } 356 740 … … 358 742 359 743 if (argint < 0) { 360 744 return "GnuTLSCacheTimeout: Invalid argument"; 361 745 } else if (argint == 0) { 362 746 sc->cache_timeout = 0; 363 747 } else { 364 748 sc->cache_timeout = apr_time_from_sec(argint); 365 749 } 366 750 … … 373 757 374 758 if (strcasecmp("cartel", arg) == 0) { 375 759 sc->client_verify_method = mgs_cvm_cartel; 376 760 } else if (strcasecmp("msva", arg) == 0) { 377 761 #ifdef ENABLE_MSVA 378 762 sc->client_verify_method = mgs_cvm_msva; 379 763 #else 380 764 return "GnuTLSClientVerifyMethod: msva is not supported"; 381 765 #endif 382 766 } else { 383 767 return "GnuTLSClientVerifyMethod: Invalid argument"; 384 768 } 385 769 … … 393 777 394 778 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { 395 779 mode = GNUTLS_CERT_IGNORE; 396 780 } else if (strcasecmp("optional", arg) == 0 397 398 781 || strcasecmp("request", arg) == 0) { 782 mode = GNUTLS_CERT_REQUEST; 399 783 } else if (strcasecmp("require", arg) == 0) { 400 784 mode = GNUTLS_CERT_REQUIRE; 401 785 } else { 402 786 return "GnuTLSClientVerify: Invalid argument"; 403 787 } 404 788 … … 408 792 dc->client_verify_mode = mode; 409 793 } else { 410 mgs_srvconf_rec *sc = 411 (mgs_srvconf_rec *) 412 ap_get_module_config(parms->server->module_config, 413 &gnutls_module); 414 sc->client_verify_mode = mode; 415 } 416 417 return NULL; 418 } 419 420 #define INIT_CA_SIZE 128 794 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 795 ap_get_module_config(parms->server->module_config, 796 &gnutls_module); 797 sc->client_verify_mode = mode; 798 } 799 800 return NULL; 801 } 421 802 422 803 const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy __attribute__((unused)), 423 804 const char *arg) { 424 int rv; 425 const char *file; 426 apr_pool_t *spool; 427 gnutls_datum_t data; 428 429 mgs_srvconf_rec *sc = 430 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 431 module_config, 432 &gnutls_module); 433 apr_pool_create(&spool, parms->pool); 434 435 file = ap_server_root_relative(spool, arg); 436 437 if (load_datum_from_file(spool, file, &data) != 0) { 438 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 439 "Client CA File '%s'", file); 440 } 441 442 sc->ca_list_size = INIT_CA_SIZE; 443 sc->ca_list = malloc(sc->ca_list_size * sizeof (*sc->ca_list)); 444 if (sc->ca_list == NULL) { 445 return apr_psprintf(parms->pool, 446 "mod_gnutls: Memory allocation error"); 447 } 448 449 rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, 450 &data, GNUTLS_X509_FMT_PEM, 451 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); 452 if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) { 453 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 454 "Client CA File '%s': (%d) %s", file, 455 rv, gnutls_strerror(rv)); 456 } 457 458 if (INIT_CA_SIZE < sc->ca_list_size) { 459 sc->ca_list = 460 realloc(sc->ca_list, 461 sc->ca_list_size * sizeof (*sc->ca_list)); 462 if (sc->ca_list == NULL) { 463 return apr_psprintf(parms->pool, 464 "mod_gnutls: Memory allocation error"); 465 } 466 467 /* re-read */ 468 rv = gnutls_x509_crt_list_import(sc->ca_list, 469 &sc->ca_list_size, &data, 470 GNUTLS_X509_FMT_PEM, 0); 471 472 if (rv < 0) { 473 return apr_psprintf(parms->pool, 474 "GnuTLS: Failed to load " 475 "Client CA File '%s': (%d) %s", 476 file, rv, gnutls_strerror(rv)); 477 } 478 } 479 480 apr_pool_destroy(spool); 805 mgs_srvconf_rec *sc = 806 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 807 module_config, 808 &gnutls_module); 809 810 sc->x509_ca_file = ap_server_root_relative(parms->pool, arg); 811 481 812 return NULL; 482 813 } … … 484 815 const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy __attribute__((unused)), 485 816 const char *arg) { 486 int rv; 487 const char *file; 488 apr_pool_t *spool; 489 gnutls_datum_t data; 490 491 mgs_srvconf_rec *sc = 492 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 493 module_config, 494 &gnutls_module); 495 apr_pool_create(&spool, parms->pool); 496 497 file = ap_server_root_relative(spool, arg); 498 499 if (load_datum_from_file(spool, file, &data) != 0) { 500 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 501 "Keyring File '%s'", file); 502 } 503 504 rv = gnutls_openpgp_keyring_init(&sc->pgp_list); 505 if (rv < 0) { 506 return apr_psprintf(parms->pool, 507 "GnuTLS: Failed to initialize" 508 "keyring: (%d) %s", rv, 509 gnutls_strerror(rv)); 510 } 511 512 rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, 513 GNUTLS_OPENPGP_FMT_BASE64); 514 if (rv < 0) { 515 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 516 "Keyring File '%s': (%d) %s", file, rv, 517 gnutls_strerror(rv)); 518 } 519 520 apr_pool_destroy(spool); 817 mgs_srvconf_rec *sc = 818 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 819 module_config, 820 &gnutls_module); 821 822 sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg); 823 521 824 return NULL; 522 825 } … … 525 828 const char *arg) { 526 829 527 mgs_srvconf_rec *sc = (mgs_srvconf_rec *)528 830 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 831 ap_get_module_config(parms->server->module_config, &gnutls_module); 529 832 530 833 if (!strcasecmp(arg, "On")) { 531 834 sc->proxy_enabled = GNUTLS_ENABLED_TRUE; 532 835 } else if (!strcasecmp(arg, "Off")) { 533 836 sc->proxy_enabled = GNUTLS_ENABLED_FALSE; 534 837 } else { 535 838 return "SSLProxyEngine must be set to 'On' or 'Off'"; 536 839 } 537 840 … … 542 845 const char *arg) { 543 846 mgs_srvconf_rec *sc = 544 545 546 847 (mgs_srvconf_rec *) ap_get_module_config(parms->server-> 848 module_config, 849 &gnutls_module); 547 850 if (!strcasecmp(arg, "On")) { 548 851 sc->enabled = GNUTLS_ENABLED_TRUE; 549 852 } else if (!strcasecmp(arg, "Off")) { 550 853 sc->enabled = GNUTLS_ENABLED_FALSE; 551 854 } else { 552 855 return "GnuTLSEnable must be set to 'On' or 'Off'"; 553 856 } 554 857 … … 559 862 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module); 560 863 if (!strcasecmp(arg, "On")) { 561 864 sc->export_certificates_size = 16 * 1024; 562 865 } else if (!strcasecmp(arg, "Off")) { 563 866 sc->export_certificates_size = 0; 564 867 } else { 565 char* endptr; 566 sc->export_certificates_size = strtol(arg, &endptr, 10); 567 while (apr_isspace(*endptr)) endptr++; 568 if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') { 569 ; 570 } else if (*endptr == 'k' || *endptr == 'K') { 571 sc->export_certificates_size *= 1024; 572 } else { 573 return "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'"; 574 } 868 char *endptr; 869 sc->export_certificates_size = strtol(arg, &endptr, 10); 870 while (apr_isspace(*endptr)) 871 endptr++; 872 if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') { 873 ; 874 } else if (*endptr == 'k' || *endptr == 'K') { 875 sc->export_certificates_size *= 1024; 876 } else { 877 return 878 "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'"; 879 } 575 880 } 576 881 … … 598 903 gnutls_priority_t *prio = NULL; 599 904 if (!strcasecmp(parms->directive->directive, "GnuTLSPriorities")) 600 prio = &sc->priorities; 905 { 906 /* save string to be handled in mgs_load_files 907 * 908 * TODO: return to one wany of handling priorities for front 909 * end and proxy connections */ 910 sc->priorities_str = apr_pstrdup(parms->pool, arg); 911 return NULL; 912 /* prio = &sc->priorities; */ 913 } 601 914 else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyPriorities")) 602 915 prio = &sc->proxy_priorities; … … 623 936 } 624 937 625 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, char** err) { 626 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof (*sc)); 627 int ret; 938 939 940 const char *mgs_set_pin(cmd_parms * parms, void *dummy __attribute__((unused)), 941 const char *arg) 942 { 943 944 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 945 ap_get_module_config(parms->server->module_config, &gnutls_module); 946 947 sc->pin = apr_pstrdup(parms->pool, arg); 948 949 return NULL; 950 } 951 952 const char *mgs_set_srk_pin(cmd_parms * parms, 953 void *dummy __attribute__((unused)), 954 const char *arg) 955 { 956 957 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 958 ap_get_module_config(parms->server->module_config, &gnutls_module); 959 960 sc->srk_pin = apr_pstrdup(parms->pool, arg); 961 962 return NULL; 963 } 964 965 966 967 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, 968 char **err __attribute__((unused))) 969 { 970 mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); 628 971 629 972 sc->enabled = GNUTLS_ENABLED_UNSET; 630 973 631 ret = gnutls_certificate_allocate_credentials(&sc->certs);632 if (ret < 0) {633 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"634 ": (%d) %s", ret,635 gnutls_strerror(ret));636 return NULL;637 }638 639 ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);640 if (ret < 0) {641 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"642 ": (%d) %s", ret,643 gnutls_strerror(ret));644 return NULL;645 }646 647 /* FIXME: not ideal, should be called only if SSLProxyEngine is648 * enabled */649 ret = gnutls_anon_allocate_client_credentials(&sc->anon_client_creds);650 if (ret < 0)651 {652 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"653 ": (%d) %s", ret,654 gnutls_strerror(ret));655 return NULL;656 }657 658 sc->proxy_x509_key_file = NULL;659 sc->proxy_x509_cert_file = NULL;660 sc->proxy_x509_ca_file = NULL;661 sc->proxy_x509_crl_file = NULL;662 sc->proxy_priorities = NULL;663 ret = gnutls_certificate_allocate_credentials(&sc->proxy_x509_creds);664 if (ret < 0)665 {666 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"667 ": (%d) %s", ret,668 gnutls_strerror(ret));669 return NULL;670 }671 672 #ifdef ENABLE_SRP673 ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);674 if (ret < 0) {675 *err = apr_psprintf(p, "GnuTLS: Failed to initialize"676 ": (%d) %s", ret,677 gnutls_strerror(ret));678 return NULL;679 }680 681 sc->srp_tpasswd_conf_file = NULL;682 sc->srp_tpasswd_file = NULL;683 #endif684 685 974 sc->privkey_x509 = NULL; 686 /* Initialize all Certificate Chains */ 687 /* FIXME: how do we indicate that this is unset for a merge? (that 688 * is, how can a subordinate server override the chain by setting 689 * an empty one? what would that even look like in the 690 * configuration?) */ 691 sc->certs_x509_chain = malloc(MAX_CHAIN_SIZE * sizeof (*sc->certs_x509_chain)); 975 sc->privkey_pgp = NULL; 692 976 sc->certs_x509_chain_num = 0; 693 sc->cache_timeout = -1; /* -1 means "unset" */ 977 sc->pin = NULL; 978 sc->priorities_str = NULL; 979 sc->cache_timeout = -1; /* -1 means "unset" */ 694 980 sc->cache_type = mgs_cache_unset; 695 981 sc->cache_config = NULL; … … 701 987 sc->client_verify_method = mgs_cvm_unset; 702 988 989 sc->proxy_x509_key_file = NULL; 990 sc->proxy_x509_cert_file = NULL; 991 sc->proxy_x509_ca_file = NULL; 992 sc->proxy_x509_crl_file = NULL; 993 sc->proxy_priorities = NULL; 994 703 995 /* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */ 704 996 sc->client_verify_mode = -1; … … 711 1003 char *err = NULL; 712 1004 mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err); 713 if (sc) return sc; else return err; 1005 if (sc) 1006 return sc; 1007 else 1008 return err; 714 1009 } 715 1010 … … 717 1012 #define gnutls_srvconf_assign(t) sc->t = add->t 718 1013 719 void *mgs_config_server_merge(apr_pool_t *p, void *BASE, void *ADD) { 1014 void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD) 1015 { 720 1016 int i; 721 1017 char *err = NULL; 722 mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;723 mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;1018 mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE; 1019 mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD; 724 1020 mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err); 725 if (NULL == sc) return err; 1021 if (NULL == sc) 1022 return err; 726 1023 727 1024 gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET); … … 733 1030 gnutls_srvconf_merge(srp_tpasswd_file, NULL); 734 1031 gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL); 735 gnutls_srvconf_merge(privkey_x509, NULL); 736 gnutls_srvconf_merge(priorities, NULL); 737 gnutls_srvconf_merge(dh_params, NULL); 1032 gnutls_srvconf_merge(x509_cert_file, NULL); 1033 1034 gnutls_srvconf_merge(x509_key_file, NULL); 1035 gnutls_srvconf_merge(x509_ca_file, NULL); 1036 gnutls_srvconf_merge(pin, NULL); 1037 gnutls_srvconf_merge(pgp_cert_file, NULL); 1038 gnutls_srvconf_merge(pgp_key_file, NULL); 1039 gnutls_srvconf_merge(pgp_ring_file, NULL); 1040 gnutls_srvconf_merge(dh_file, NULL); 1041 gnutls_srvconf_merge(priorities_str, NULL); 738 1042 739 1043 gnutls_srvconf_merge(proxy_x509_key_file, NULL); … … 746 1050 * properly disposed of before assigning in order to avoid leaks; 747 1051 * so at the moment, we can't actually have them in the config. 748 * what happens during de-allocation? 749 750 * This is probably leaky. 751 */ 1052 * what happens during de-allocation? */ 1053 /* TODO: mgs_load_files takes care of most of these now, verify 1054 * and clean up the following lines */ 1055 gnutls_srvconf_assign(ca_list); 1056 gnutls_srvconf_assign(ca_list_size); 1057 gnutls_srvconf_assign(cert_pgp); 1058 gnutls_srvconf_assign(cert_crt_pgp); 1059 gnutls_srvconf_assign(pgp_list); 752 1060 gnutls_srvconf_assign(certs); 753 1061 gnutls_srvconf_assign(anon_creds); 754 gnutls_srvconf_assign(anon_client_creds);755 1062 gnutls_srvconf_assign(srp_creds); 756 1063 gnutls_srvconf_assign(certs_x509_chain); 1064 gnutls_srvconf_assign(certs_x509_crt_chain); 757 1065 gnutls_srvconf_assign(certs_x509_chain_num); 758 1066 … … 761 1069 gnutls_srvconf_assign(cert_cn); 762 1070 for (i = 0; i < MAX_CERT_SAN; i++) 763 gnutls_srvconf_assign(cert_san[i]); 764 gnutls_srvconf_assign(ca_list); 765 gnutls_srvconf_assign(ca_list_size); 766 gnutls_srvconf_assign(cert_pgp); 767 gnutls_srvconf_assign(pgp_list); 768 gnutls_srvconf_assign(privkey_pgp); 1071 gnutls_srvconf_assign(cert_san[i]); 769 1072 770 1073 return sc; … … 781 1084 mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv; 782 1085 783 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof 1086 new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec)); 784 1087 new->client_verify_mode = add->client_verify_mode; 785 1088 return new; … … 792 1095 return dc; 793 1096 } 1097 1098 794 1099 795 1100 /* -
src/gnutls_hooks.c
r73f6f12 r2cde026d 175 175 176 176 static int cert_retrieve_fn(gnutls_session_t session, 177 const gnutls_datum_t * req_ca_rdn __attribute__((unused)), int nreqs __attribute__((unused)), 178 const gnutls_pk_algorithm_t * pk_algos __attribute__((unused)), int pk_algos_length __attribute__((unused)), 179 gnutls_retr2_st *ret) { 180 181 182 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 183 184 mgs_handle_t *ctxt; 177 const gnutls_datum_t * req_ca_rdn __attribute__((unused)), 178 int nreqs __attribute__((unused)), 179 const gnutls_pk_algorithm_t * pk_algos __attribute__((unused)), 180 int pk_algos_length __attribute__((unused)), 181 gnutls_pcert_st **pcerts, 182 unsigned int *pcert_length, 183 gnutls_privkey_t *privkey) 184 { 185 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 186 187 mgs_handle_t *ctxt; 185 188 186 189 if (session == NULL) { 187 190 // ERROR INVALID SESSION 188 ret->ncerts = 0;189 ret->deinit_all = 1;190 191 return -1; 191 } 192 } 193 192 194 ctxt = gnutls_transport_get_ptr(session); 193 195 194 196 if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { 195 197 // X509 CERTIFICATE 196 ret->cert_type = GNUTLS_CRT_X509; 197 ret->key_type = GNUTLS_PRIVKEY_X509; 198 ret->ncerts = ctxt->sc->certs_x509_chain_num; 199 ret->deinit_all = 0; 200 ret->cert.x509 = ctxt->sc->certs_x509_chain; 201 ret->key.x509 = ctxt->sc->privkey_x509; 198 *pcerts = ctxt->sc->certs_x509_chain; 199 *pcert_length = ctxt->sc->certs_x509_chain_num; 200 *privkey = ctxt->sc->privkey_x509; 202 201 return 0; 203 202 } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) { 204 203 // OPENPGP CERTIFICATE 205 ret->cert_type = GNUTLS_CRT_OPENPGP; 206 ret->key_type = GNUTLS_PRIVKEY_OPENPGP; 207 ret->ncerts = 1; 208 ret->deinit_all = 0; 209 ret->cert.pgp = ctxt->sc->cert_pgp; 210 ret->key.pgp = ctxt->sc->privkey_pgp; 204 *pcerts = ctxt->sc->cert_pgp; 205 *pcert_length = 1; 206 *privkey = ctxt->sc->privkey_pgp; 211 207 return 0; 212 208 } else { 213 209 // UNKNOWN CERTIFICATE 214 ret->ncerts = 0;215 ret->deinit_all = 1;216 210 return -1; 217 211 } 218 212 } 219 220 /* 2048-bit group parameters from SRP specification */221 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"222 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"223 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"224 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"225 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"226 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"227 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"228 "-----END DH PARAMETERS-----\n";229 213 230 214 /* Read the common name or the alternative name of the certificate. … … 326 310 } 327 311 328 329 312 s = base_server; 330 313 sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 331 314 332 gnutls_dh_params_init(&dh_params);333 334 if (sc_base->dh_params == NULL) {335 gnutls_datum_t pdata = {336 (void *) static_dh_params,337 sizeof(static_dh_params)338 };339 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM);340 /* Generate DH Params341 int dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,342 GNUTLS_SEC_PARAM_NORMAL);343 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,344 "GnuTLS: Generating DH Params of %i bits. "345 "To avoid this use GnuTLSDHFile to specify DH Params for this host",346 dh_bits);347 #if MOD_GNUTLS_DEBUG348 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,349 "GnuTLS: Generated DH Params of %i bits",dh_bits);350 #endif351 rv = gnutls_dh_params_generate2 (dh_params,dh_bits);352 */353 if (rv < 0) {354 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,355 "GnuTLS: Unable to generate or load DH Params: (%d) %s",356 rv, gnutls_strerror(rv));357 exit(rv);358 }359 } else {360 dh_params = sc_base->dh_params;361 }362 315 363 316 rv = mgs_cache_post_config(p, s, sc_base); … … 374 327 sc->cache_config = sc_base->cache_config; 375 328 sc->cache_timeout = sc_base->cache_timeout; 329 330 rv = mgs_load_files(p, s); 331 if (rv != 0) { 332 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 333 "GnuTLS: Loading required files failed." 334 " Shutting Down."); 335 exit(-1); 336 } 376 337 377 338 /* defaults for unset values: */ … … 387 348 sc->client_verify_method = mgs_cvm_cartel; 388 349 389 390 350 /* Check if the priorities have been set */ 391 351 if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { … … 405 365 } 406 366 407 gnutls_certificate_set_retrieve_function(sc->certs, cert_retrieve_fn); 408 409 #ifdef ENABLE_SRP 410 if (sc->srp_tpasswd_conf_file != NULL 411 && sc->srp_tpasswd_file != NULL) { 412 rv = gnutls_srp_set_server_credentials_file 413 (sc->srp_creds, sc->srp_tpasswd_file, 414 sc->srp_tpasswd_conf_file); 415 416 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 417 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, 418 s, 419 "[GnuTLS] - Host '%s:%d' is missing a " 420 "SRP password or conf File!", 421 s->server_hostname, s->port); 422 exit(-1); 423 } 424 } 367 /* The call after this comment is a workaround for bug in 368 * gnutls_certificate_set_retrieve_function2 that ignores 369 * supported certificate types. Should be fixed in GnuTLS 370 * 3.3.12. 371 * 372 * Details: 373 * https://lists.gnupg.org/pipermail/gnutls-devel/2015-January/007377.html 374 * Workaround from: 375 * https://github.com/vanrein/tlspool/commit/4938102d3d1b086491d147e6c8e4e2a02825fc12 */ 376 #if GNUTLS_VERSION_NUMBER < 0x030312 377 gnutls_certificate_set_retrieve_function(sc->certs, (void *) exit); 425 378 #endif 379 380 gnutls_certificate_set_retrieve_function2(sc->certs, cert_retrieve_fn); 426 381 427 382 if ((sc->certs_x509_chain == NULL || sc->certs_x509_chain_num < 1) && 428 383 sc->cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 429 384 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 430 " [GnuTLS] -Host '%s:%d' is missing a Certificate File!",385 "GnuTLS: Host '%s:%d' is missing a Certificate File!", 431 386 s->server_hostname, s->port); 432 387 exit(-1); 433 388 } 434 435 389 if (sc->enabled == GNUTLS_ENABLED_TRUE && 436 ((sc->certs_x509_chain != NULL && sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||437 (sc->cert_ pgp!= NULL && sc->privkey_pgp == NULL))) {390 ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) || 391 (sc->cert_crt_pgp[0] != NULL && sc->privkey_pgp == NULL))) { 438 392 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 439 " [GnuTLS] -Host '%s:%d' is missing a Private Key File!",393 "GnuTLS: Host '%s:%d' is missing a Private Key File!", 440 394 s->server_hostname, s->port); 441 395 exit(-1); … … 445 399 rv = -1; 446 400 if (sc->certs_x509_chain_num > 0) { 447 rv = read_crt_cn(s, p, sc->certs_x509_c hain[0], &sc->cert_cn);401 rv = read_crt_cn(s, p, sc->certs_x509_crt_chain[0], &sc->cert_cn); 448 402 } 449 403 if (rv < 0 && sc->cert_pgp != NULL) { 450 rv = read_pgpcrt_cn(s, p, sc->cert_ pgp, &sc->cert_cn);404 rv = read_pgpcrt_cn(s, p, sc->cert_crt_pgp[0], &sc->cert_cn); 451 405 } 452 406 453 407 if (rv < 0) { 454 408 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 455 " [GnuTLS] -Cannot find a certificate for host '%s:%d'!",409 "GnuTLS: Cannot find a certificate for host '%s:%d'!", 456 410 s->server_hostname, s->port); 457 411 sc->cert_cn = NULL; … … 494 448 } 495 449 496 void mgs_hook_child_init(apr_pool_t * p, server_rec * 450 void mgs_hook_child_init(apr_pool_t * p, server_rec *s) { 497 451 apr_status_t rv = APR_SUCCESS; 498 mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,499 452 mgs_srvconf_rec *sc = 453 (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module); 500 454 501 455 _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); 456 /* if we use PKCS #11 reinitialize it */ 457 458 if (mgs_pkcs11_reinit(s) < 0) { 459 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 460 "GnuTLS: Failed to reinitialize PKCS #11"); 461 exit(-1); 462 } 463 502 464 if (sc->cache_type != mgs_cache_none) { 503 465 rv = mgs_cache_child_init(p, s, sc); 504 466 if (rv != APR_SUCCESS) { 505 467 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, 506 " [GnuTLS] -Failed to run Cache Init");468 "GnuTLS: Failed to run Cache Init"); 507 469 } 508 470 } … … 625 587 626 588 if (tsc->certs_x509_chain_num > 0) { 627 /* why are we doing this check? */ 628 ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_chain[0], s->server_hostname); 589 /* this check is there to warn administrator of any missing hostname 590 * in the certificate. */ 591 ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_crt_chain[0], s->server_hostname); 629 592 if (0 == ret) 630 ap_log_error(APLOG_MARK, APLOG_ INFO, 0, s,631 "GnuTLS: Error checking certificate forhostname "593 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 594 "GnuTLS: the certificate doesn't match requested hostname " 632 595 "'%s'", s->server_hostname); 633 596 } else { … … 956 919 957 920 if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) { 958 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_chain[0], 0, ctxt->sc->export_certificates_size);959 960 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_ pgp, 0, ctxt->sc->export_certificates_size);961 921 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, ctxt->sc->export_certificates_size); 922 } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) { 923 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_crt_pgp[0], 0, ctxt->sc->export_certificates_size); 924 } 962 925 963 926 return rv; … … 1775 1738 } 1776 1739 1740 /* allocate credentials structures */ 1741 err = gnutls_certificate_allocate_credentials(&sc->proxy_x509_creds); 1742 if (err != GNUTLS_E_SUCCESS) 1743 { 1744 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1745 "%s: Failed to initialize proxy credentials: (%d) %s", 1746 __func__, err, gnutls_strerror(err)); 1747 return APR_EGENERAL; 1748 } 1749 err = gnutls_anon_allocate_client_credentials(&sc->anon_client_creds); 1750 if (err != GNUTLS_E_SUCCESS) 1751 { 1752 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 1753 "%s: Failed to initialize anon credentials for proxy: " 1754 "(%d) %s", __func__, err, gnutls_strerror(err)); 1755 return APR_EGENERAL; 1756 } 1757 1777 1758 /* load certificate and key for client auth, if configured */ 1778 1759 if (sc->proxy_x509_key_file && sc->proxy_x509_cert_file) -
src/mod_gnutls.c
r73f6f12 r2cde026d 140 140 RSRC_CONF | OR_AUTHCFG, 141 141 "Enable SSL Proxy Engine"), 142 AP_INIT_RAW_ARGS("GnuTLSPIN", mgs_set_pin, 143 NULL, 144 RSRC_CONF, 145 "The PIN to use in case of encrypted keys or PKCS #11 tokens."), 146 AP_INIT_RAW_ARGS("GnuTLSSRKPIN", mgs_set_srk_pin, 147 NULL, 148 RSRC_CONF, 149 "The SRK PIN to use in case of TPM keys."), 142 150 AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify, 143 151 NULL,
Note: See TracChangeset
for help on using the changeset viewer.