- Timestamp:
- Apr 21, 2005, 1:15:56 PM (18 years ago)
- Branches:
- asyncio, debian/master, debian/stretch-backports, jessie-backports, master, msva, proxy-ticket, upstream
- Children:
- e924ddd
- Parents:
- 0475f1bc
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_io.c
r0475f1bc r31645b2 354 354 } 355 355 356 357 static void gnutls_do_handshake(mod_gnutls_handle_t * ctxt) 356 static int gnutls_do_handshake(mod_gnutls_handle_t * ctxt) 358 357 { 359 358 int ret; 360 359 int errcode; 361 360 if (ctxt->status != 0) { 362 return ;361 return 0; 363 362 } 364 363 … … 389 388 gnutls_error_to_alert(ret, NULL)); 390 389 gnutls_deinit(ctxt->session); 391 return ;390 return ret; 392 391 } 393 392 else { 393 /* all done with the handshake */ 394 394 ctxt->status = 1; 395 return; /* all done with the handshake */ 395 return ret; 396 } 397 } 398 399 int mod_gnutls_rehandshake(mod_gnutls_handle_t * ctxt) 400 { 401 int rv; 402 403 rv = gnutls_rehandshake(ctxt->session); 404 405 if (rv != 0) { 406 /* the client did not want to rehandshake. goodbye */ 407 ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server, 408 "GnuTLS: Client Refused Rehandshake request."); 409 return -1; 410 } 411 412 ctxt->status = 0; 413 414 gnutls_do_handshake(ctxt); 415 416 if (ctxt->status == 1) { 417 return 0; 418 } 419 else { 420 return -1; 396 421 } 397 422 } … … 415 440 416 441 if (ctxt->status == 0) { 417 char* server_name;418 int server_type;419 int data_len = 256;420 421 442 gnutls_do_handshake(ctxt); 422 423 /**424 * Due to issues inside the GnuTLS API, we cannot currently do TLS 1.1425 * Server Name Indication.426 */427 server_name = apr_palloc(ctxt->c->pool, data_len);428 if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) {429 if (server_type == GNUTLS_NAME_DNS) {430 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,431 ctxt->c->base_server,432 "GnuTLS: TLS 1.1 Server Name: "433 "%s", server_name);434 435 }436 }437 443 } 438 444 -
src/mod_gnutls.c
r0475f1bc r31645b2 18 18 #include "mod_gnutls.h" 19 19 20 extern server_rec *ap_server_conf; 21 20 22 #if APR_HAS_THREADS 21 23 GCRY_THREAD_OPTION_PTHREAD_IMPL; … … 98 100 return ret; 99 101 } 100 102 apr_file_close(fp); 101 103 ret.data[br] = '\0'; 102 104 ret.size = br; … … 128 130 129 131 130 if (!first_run){132 { 131 133 gnutls_datum pdata; 132 134 apr_pool_t* tpool; … … 195 197 sc->cache_config = sc_base->cache_config; 196 198 197 if (sc->cert_file != NULL && sc->key_file != NULL) { 198 199 rv = gnutls_certificate_set_x509_key_file(sc->certs, sc->cert_file, 200 sc->key_file, 201 GNUTLS_X509_FMT_PEM); 202 if (rv != 0) { 203 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 204 "[GnuTLS] - Host '%s:%d' has an invalid key or certificate:" 205 "(%s,%s) (%d) %s", 206 s->server_hostname, s->port, sc->cert_file, sc->key_file, 207 rv, gnutls_strerror(rv)); 208 } 209 else { 210 gnutls_certificate_set_rsa_export_params(sc->certs, 199 gnutls_certificate_set_rsa_export_params(sc->certs, 211 200 rsa_params); 212 gnutls_certificate_set_dh_params(sc->certs, dh_params); 213 } 214 } 215 else if (sc->enabled == GNUTLS_ENABLED_TRUE) { 201 gnutls_certificate_set_dh_params(sc->certs, dh_params); 202 203 if (sc->cert_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 216 204 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 217 205 "[GnuTLS] - Host '%s:%d' is missing a " 218 "Cert and KeyFile!",206 "Certificate File!", 219 207 s->server_hostname, s->port); 208 exit(-1); 209 } 210 211 if (sc->privkey_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 212 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 213 "[GnuTLS] - Host '%s:%d' is missing a " 214 "Private Key File!", 215 s->server_hostname, s->port); 216 exit(-1); 217 } 218 { 219 int rv; 220 int data_len = 255; 221 char crt_name[255]; 222 for (rv = 0; rv < data_len; rv++) { 223 crt_name[rv] = '\0'; 224 } 225 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 226 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 227 crt_name, &data_len); 228 229 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 230 s, 231 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X sc: 0x%08X", crt_name, rv, 232 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(sc->privkey_x509)), 233 (unsigned int)s, (unsigned int)sc); 220 234 } 221 235 } 222 } /* first_run */236 } 223 237 224 238 ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION); … … 274 288 } 275 289 276 /* TODO: Complete support for Server Name Indication */ 290 #define MAX_HOST_LEN 255 277 291 static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) 278 292 { 279 char* server_name; 280 int server_type; 281 int data_len = 256; 282 mod_gnutls_handle_t *ctxt; 293 int rv; 294 int sni_type; 295 int data_len = MAX_HOST_LEN; 296 char sni_name[MAX_HOST_LEN]; 297 char crt_name[MAX_HOST_LEN]; 298 mod_gnutls_handle_t *ctxt; 299 mod_gnutls_srvconf_rec *tsc; 300 server_rec* s; 301 283 302 ctxt = gnutls_transport_get_ptr(session); 303 304 sni_type = gnutls_certificate_type_get(session); 305 if (sni_type != GNUTLS_CRT_X509) { 306 /* In theory, we could support OpenPGP Certificates. Theory != code. */ 307 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, 308 ctxt->c->base_server, 309 "GnuTLS: Only x509 Certificates are currently supported."); 310 return -1; 311 } 284 312 285 313 ret->type = GNUTLS_CRT_X509; 286 314 ret->ncerts = 1; 287 server_name = apr_palloc(ctxt->c->pool, data_len); 288 if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) { 289 if (server_type == GNUTLS_NAME_DNS) { 290 ap_log_error(APLOG_MARK, APLOG_INFO, 0, 315 ret->deinit_all = 0; 316 317 rv = gnutls_server_name_get(ctxt->session, sni_name, 318 &data_len, &sni_type, 0); 319 320 if (rv != 0) { 321 goto use_default_crt; 322 } 323 324 if (sni_type != GNUTLS_NAME_DNS) { 325 ap_log_error(APLOG_MARK, APLOG_CRIT, 0, 326 ctxt->c->base_server, 327 "GnuTLS: Unknown type '%d' for SNI: " 328 "'%s'", sni_type, sni_name); 329 goto use_default_crt; 330 } 331 332 /** 333 * Code in the Core already sets up the c->base_server as the base 334 * for this IP/Port combo. Trust that the core did the 'right' thing. 335 */ 336 for (s = ap_server_conf; s; s = s->next) { 337 338 tsc = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config, 339 &gnutls_module); 340 if (tsc->enabled != GNUTLS_ENABLED_TRUE) { 341 continue; 342 } 343 344 data_len = MAX_HOST_LEN; 345 rv = gnutls_x509_crt_get_dn_by_oid(tsc->cert_x509, 346 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 347 crt_name, &data_len); 348 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 349 ctxt->c->base_server, 350 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", crt_name, rv, 351 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)), 352 (unsigned int)s, (unsigned int)s->next, (unsigned int)tsc); 353 354 if (rv != 0) { 355 continue; 356 } 357 358 /* The CN can contain a * -- this will match those too. */ 359 if (ap_strcasecmp_match(sni_name, crt_name) == 0) { 360 /* found a match */ 361 ret->cert.x509 = &tsc->cert_x509; 362 ret->key.x509 = tsc->privkey_x509; 363 #if MOD_GNUTLS_DEBUG 364 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 291 365 ctxt->c->base_server, 292 366 "GnuTLS: Virtual Host: " 293 "%s", server_name); 367 "'%s' == '%s'", crt_name, sni_name); 368 #endif 369 return 0; 294 370 } 295 371 } 296 372 373 374 /** 375 * If the client does not support the Server Name Indication, give the default 376 * certificate for this server. 377 */ 378 use_default_crt: 379 data_len = MAX_HOST_LEN; 380 rv = gnutls_x509_crt_get_dn_by_oid(ctxt->sc->cert_x509, 381 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 382 crt_name, &data_len); 383 384 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 385 ctxt->c->base_server, 386 "GnuTLS: x509 cn: %s/%d pk: %s", crt_name, rv, 387 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509))); 388 389 ret->cert.x509 = &ctxt->sc->cert_x509; 390 ret->key.x509 = ctxt->sc->privkey_x509; 391 #if MOD_GNUTLS_DEBUG 392 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 393 ctxt->c->base_server, 394 "GnuTLS: Using Default Certificate."); 395 #endif 297 396 return 0; 298 397 } … … 331 430 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs); 332 431 333 gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE);432 gnutls_certificate_server_set_request(ctxt->session, sc->client_verify_mode); 334 433 335 434 mod_gnutls_cache_session_init(ctxt); 336 435 337 436 /* TODO: Finish Support for Server Name Indication */ 338 /* gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); */437 gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); 339 438 return ctxt; 340 439 } … … 413 512 } 414 513 514 static int load_datum_from_file(apr_pool_t* pool, 515 const char* file, 516 gnutls_datum_t* data) 517 { 518 apr_file_t* fp; 519 apr_finfo_t finfo; 520 apr_status_t rv; 521 apr_size_t br = 0; 522 523 rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT, 524 pool); 525 if (rv != APR_SUCCESS) { 526 return rv; 527 } 528 529 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); 530 531 if (rv != APR_SUCCESS) { 532 return rv; 533 } 534 535 data->data = apr_palloc(pool, finfo.size+1); 536 rv = apr_file_read_full(fp, data->data, finfo.size, &br); 537 538 if (rv != APR_SUCCESS) { 539 return rv; 540 } 541 apr_file_close(fp); 542 543 data->data[br] = '\0'; 544 data->size = br; 545 546 return 0; 547 } 548 415 549 static const char *gnutls_set_cert_file(cmd_parms * parms, void *dummy, 416 550 const char *arg) 417 551 { 552 int ret; 553 gnutls_datum_t data; 554 const char* file; 555 apr_pool_t* spool; 418 556 mod_gnutls_srvconf_rec *sc = 419 557 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> 420 558 module_config, 421 559 &gnutls_module); 422 sc->cert_file = ap_server_root_relative(parms->pool, arg); 560 apr_pool_create(&spool, parms->pool); 561 562 file = ap_server_root_relative(spool, arg); 563 564 if (load_datum_from_file(spool, file, &data) != 0) { 565 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 566 "Certificate '%s'", file); 567 } 568 569 gnutls_x509_crt_init(&sc->cert_x509); 570 ret = gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM); 571 if (ret != 0) { 572 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 573 "Certificate'%s': (%d) %s", file, ret, 574 gnutls_strerror(ret)); 575 } 576 577 //apr_pool_destroy(spool); 423 578 return NULL; 424 579 } … … 427 582 const char *arg) 428 583 { 584 int ret; 585 gnutls_datum_t data; 586 const char* file; 587 apr_pool_t* spool; 429 588 mod_gnutls_srvconf_rec *sc = 430 589 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> 431 590 module_config, 432 591 &gnutls_module); 433 434 sc->key_file = ap_server_root_relative(parms->pool, arg); 592 apr_pool_create(&spool, parms->pool); 593 594 file = ap_server_root_relative(spool, arg); 595 596 if (load_datum_from_file(spool, file, &data) != 0) { 597 return apr_psprintf(parms->pool, "GnuTLS: Error Reading " 598 "Private Key '%s'", file); 599 } 600 601 gnutls_x509_privkey_init(&sc->privkey_x509); 602 ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM); 603 if (ret != 0) { 604 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 605 "Private Key '%s': (%d) %s", file, ret, 606 gnutls_strerror(ret)); 607 } 608 //apr_pool_destroy(spool); 435 609 return NULL; 436 610 } … … 472 646 } 473 647 648 static const char *gnutls_set_cache_timeout(cmd_parms * parms, void *dummy, 649 const char *arg) 650 { 651 int argint; 652 mod_gnutls_srvconf_rec *sc = 653 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> 654 module_config, 655 &gnutls_module); 656 657 argint = atoi(arg); 658 659 if (argint < 0) { 660 return "GnuTLSCacheTimeout: Invalid argument"; 661 } 662 else if (argint == 0) { 663 sc->cache_timeout = 0; 664 } 665 else { 666 sc->cache_timeout = apr_time_from_sec(argint); 667 } 668 669 return NULL; 670 } 671 672 673 static const char *gnutls_set_client_verify(cmd_parms * parms, void *dummy, 674 const char *arg) 675 { 676 gnutls_certificate_request_t mode; 677 678 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { 679 mode = GNUTLS_CERT_IGNORE; 680 } 681 else if (strcasecmp("optional", arg) == 0 || strcasecmp("request", arg) == 0) { 682 mode = GNUTLS_CERT_REQUEST; 683 } 684 else if (strcasecmp("optional", arg) == 0) { 685 mode = GNUTLS_CERT_REQUIRE; 686 } 687 else { 688 return "GnuTLSClientVerify: Invalid argument"; 689 } 690 691 /* This was set from a directory context */ 692 if (parms->path) { 693 mod_gnutls_dirconf_rec *dc = (mod_gnutls_dirconf_rec *)dummy; 694 dc->client_verify_mode = mode; 695 } 696 else { 697 mod_gnutls_srvconf_rec *sc = 698 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> 699 module_config, 700 &gnutls_module); 701 sc->client_verify_mode = mode; 702 } 703 704 return NULL; 705 } 474 706 static const char *gnutls_set_enabled(cmd_parms * parms, void *dummy, 475 707 const char *arg) … … 493 725 494 726 static const command_rec gnutls_cmds[] = { 727 AP_INIT_TAKE1("GnuTLSClientVerify", gnutls_set_client_verify, 728 NULL, 729 RSRC_CONF|OR_AUTHCFG, 730 "Set Verification Requirements of the Client Certificate"), 495 731 AP_INIT_TAKE1("GnuTLSCertificateFile", gnutls_set_cert_file, 496 732 NULL, … … 501 737 RSRC_CONF, 502 738 "SSL Server Certificate file"), 739 AP_INIT_TAKE1("GnuTLSCacheTimeout", gnutls_set_cache_timeout, 740 NULL, 741 RSRC_CONF, 742 "Cache Timeout"), 503 743 AP_INIT_TAKE2("GnuTLSCache", gnutls_set_cache, 504 744 NULL, … … 518 758 * "CA"), 519 759 */ 760 761 int mod_gnutls_hook_authz(request_rec *r) 762 { 763 return OK; 764 #if 0 765 mod_gnutls_handle_t *ctxt; 766 mod_gnutls_dirconf_rec *dc = ap_get_module_config(r->per_dir_config, 767 &gnutls_module); 768 769 ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module); 770 771 if (dc->client_verify_mode == -1 || 772 dc->client_verify_mode == GNUTLS_CERT_IGNORE || 773 ctxt->sc->client_verify_mode > dc->client_verify_mode) { 774 return DECLINED; 775 } 776 777 gnutls_certificate_server_set_request(ctxt->session, dc->client_verify_mode); 778 if (mod_gnutls_rehandshake(ctxt) != 0) { 779 return HTTP_FORBIDDEN; 780 } 781 #endif 782 } 520 783 521 784 static void gnutls_hooks(apr_pool_t * p) … … 538 801 ap_hook_pre_config(mod_gnutls_hook_pre_config, NULL, NULL, 539 802 APR_HOOK_MIDDLE); 540 541 ap_hook_fixups(mod_gnutls_hook_fixups, NULL, NULL, APR_HOOK_MIDDLE); 803 804 ap_hook_auth_checker(mod_gnutls_hook_authz, NULL, NULL, APR_HOOK_MIDDLE); 805 806 ap_hook_fixups(mod_gnutls_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST); 542 807 543 808 /* TODO: HTTP Upgrade Filter */ … … 561 826 562 827 gnutls_certificate_allocate_credentials(&sc->certs); 563 sc-> key_file= NULL;564 sc->cert_ file= NULL;565 sc->cache_timeout = apr_time_from_sec(3 600);828 sc->privkey_x509 = NULL; 829 sc->cert_x509 = NULL; 830 sc->cache_timeout = apr_time_from_sec(300); 566 831 sc->cache_type = mod_gnutls_cache_dbm; 567 832 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); 568 833 569 /* TODO: Make this Configurable !*/834 /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */ 570 835 sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile"); 571 836 sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile"); 572 837 838 /* Finish SSL Client Certificate Support */ 839 sc->client_verify_mode = GNUTLS_CERT_IGNORE; 840 573 841 /* TODO: Make this Configurable ! */ 574 /* m eh. mod_ssl uses a flex based parser for this part.. sigh */842 /* mod_ssl uses a flex based parser for this part.. sigh */ 575 843 i = 0; 576 844 sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC; … … 617 885 } 618 886 619 887 void *gnutls_config_dir_create(apr_pool_t *p, char *dir) 888 { 889 mod_gnutls_dirconf_rec *dc = apr_palloc(p, sizeof(*dc)); 890 891 dc->client_verify_mode = -1; 892 893 return dc; 894 } 620 895 621 896 module AP_MODULE_DECLARE_DATA gnutls_module = { 622 897 STANDARD20_MODULE_STUFF, 623 NULL,898 gnutls_config_dir_create, 624 899 NULL, 625 900 gnutls_config_server_create,
Note: See TracChangeset
for help on using the changeset viewer.