Changeset 1893
- Timestamp:
- 08/22/08 01:17:09 (3 months ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/socket.c (modified) (3 diffs)
- cherokee/trunk/cherokee/virtual_server.c (modified) (8 diffs)
- cherokee/trunk/cherokee/virtual_server.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r1890 r1893 1 1 2008-08-21 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 3 * cherokee/virtual_server.c, cherokee/virtual_server.h, 4 cherokee/socket.c: Adds TLS SNI support to the GNUTLS backend. 2 5 3 6 * cherokee/virtual_server.c, cherokee/socket.c, cherokee/socket.h, cherokee/trunk/cherokee/socket.c
r1890 r1893 344 344 345 345 static ret_t 346 initialize_tls_session (cherokee_socket_t *socket, cherokee_virtual_server_t *vserver) 347 { 346 initialize_tls_session (cherokee_socket_t *socket, 347 cherokee_virtual_server_t *vserver) 348 { 349 # if defined(HAVE_GNUTLS) 348 350 int re; 349 351 350 352 /* Set the virtual server object reference 351 353 */ 352 354 socket->vserver_ref = vserver; 353 355 354 # if defined(HAVE_GNUTLS)355 356 /* Init the TLS session 356 357 */ 357 358 re = gnutls_init (&socket->session, GNUTLS_SERVER); 358 if (unlikely (re != GNUTLS_E_SUCCESS)) return ret_error; 359 if (unlikely (re != GNUTLS_E_SUCCESS)) 360 return ret_error; 361 362 gnutls_session_set_ptr (socket->session, socket); 359 363 360 364 /* Set the socket file descriptor 361 365 */ 362 gnutls_transport_set_ptr (socket->session, (gnutls_transport_ptr)socket->socket);366 gnutls_transport_set_ptr (socket->session, (gnutls_transport_ptr)socket->socket); 363 367 364 368 /* Load the credentials … … 380 384 gnutls_credentials_set (socket->session, GNUTLS_CRD_CERTIFICATE, vserver->credentials); 381 385 382 /* Request client certificate if any.383 */384 gnutls_certificate_server_set_request (socket->session, GNUTLS_CERT_REQUEST);385 386 386 /* Set the number of bits, for use in an Diffie Hellman key 387 387 * exchange: minimum size of the prime that will be used for … … 397 397 gnutls_db_set_ptr (socket->session, socket); 398 398 399 /* Request client certificate if any. 400 */ 401 gnutls_certificate_server_set_request (socket->session, GNUTLS_CERT_REQUEST); 402 gnutls_handshake_set_private_extensions (socket->session, 1); 403 399 404 # elif defined (HAVE_OPENSSL) 405 int re; 406 407 /* Set the virtual server object reference 408 */ 409 socket->vserver_ref = vserver; 400 410 401 411 /* New session cherokee/trunk/cherokee/virtual_server.c
r1890 r1893 36 36 37 37 #define ENTRIES "vserver" 38 #define MAX_HOST_LEN 255 38 39 39 40 … … 84 85 # ifdef HAVE_GNUTLS 85 86 n->credentials = NULL; 87 n->privkey_x509 = NULL; 88 n->certs_x509 = NULL; 86 89 # endif 87 90 # ifdef HAVE_OPENSSL … … 137 140 vserver->credentials = NULL; 138 141 } 142 if (vserver->privkey_x509 != NULL) { 143 gnutls_x509_privkey_deinit (vserver->privkey_x509); 144 } 145 if (vserver->certs_x509 != NULL) { 146 gnutls_x509_crt_deinit (vserver->certs_x509); 147 } 148 139 149 # endif 140 150 # ifdef HAVE_OPENSSL … … 220 230 221 231 222 #if ndef OPENSSL_NO_TLSEXT232 #if defined(HAVE_OPENSSL) && !defined(OPENSSL_NO_TLSEXT) 223 233 static int 224 234 openssl_sni_servername_cb (SSL *ssl, int *ad, void *arg) … … 274 284 275 285 286 #ifdef HAVE_TLS 287 static int 288 gnutls_sni_servername_cb (gnutls_session_t session, 289 gnutls_retr_st *retr) 290 { 291 int re; 292 ret_t ret; 293 cherokee_buffer_t tmp; 294 cherokee_socket_t *socket; 295 cherokee_server_t *srv; 296 char name[MAX_HOST_LEN]; 297 size_t data_len = MAX_HOST_LEN; 298 unsigned int type = 0; 299 cherokee_virtual_server_t *vsrv = NULL; 300 301 re = gnutls_server_name_get (session, name, &data_len, &type, 0); 302 if (re != 0) { 303 TRACE (ENTRIES, "No SNI: Did not provide a server name%s", "\n"); 304 return 0; 305 } 306 307 if (type != GNUTLS_NAME_DNS) { 308 TRACE (ENTRIES, "SNI: Not a name entry: '%s'\n", name); 309 return 0; 310 } 311 312 TRACE (ENTRIES, "SNI: Switching to servername='%s'\n", name); 313 314 socket = gnutls_session_get_ptr (session); 315 if (socket == NULL) { 316 PRINT_ERROR ("Could not access the socket struct: %s\n", name); 317 return -1; 318 } 319 320 srv = VSERVER_SRV(socket->vserver_ref); 321 322 cherokee_buffer_fake (&tmp, name, data_len); 323 ret = cherokee_server_get_vserver (srv, &tmp, &vsrv); 324 if ((ret != ret_ok) || (vsrv == NULL)) { 325 PRINT_ERROR ("Servername did not match: '%s'\n", name); 326 return -1; 327 } 328 329 TRACE (ENTRIES, "SNI: Setting new TLS context. Virtual host='%s'\n", 330 vsrv->name.buf); 331 332 retr->deinit_all = 0; 333 retr->type = GNUTLS_CRT_X509; 334 retr->ncerts = 1; 335 retr->cert.x509 = &vsrv->certs_x509; 336 retr->key.x509 = vsrv->privkey_x509; 337 338 return 0; 339 } 340 #endif 341 342 # ifdef HAVE_GNUTLS 343 static int 344 set_x509_key_file (cherokee_virtual_server_t *vsrv) 345 { 346 int rc; 347 gnutls_datum_t data; 348 unsigned int max = 1; 349 cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; 350 351 /* This function does basically the same as the previous call to: 352 * 353 * rc = gnutls_certificate_set_x509_key_file (vsrv->credentials, 354 * vsrv->server_cert.buf, 355 * vsrv->server_key.buf, 356 * GNUTLS_X509_FMT_PEM); 357 * 358 * but it keeps pointers to the X509 certs and privkey, which 359 * was needed for the SNI callback function. 360 */ 361 362 /* X509 private key 363 */ 364 cherokee_buffer_read_file (&tmp, vsrv->server_key.buf); 365 data.data = (unsigned char *)tmp.buf; 366 data.size = tmp.len; 367 368 rc = gnutls_x509_privkey_init (&vsrv->privkey_x509); 369 if (rc < 0) 370 goto error; 371 372 rc = gnutls_x509_privkey_import (vsrv->privkey_x509, &data, GNUTLS_X509_FMT_PEM); 373 if (rc < 0) 374 goto error; 375 376 /* X509 Certificate 377 */ 378 cherokee_buffer_clean (&tmp); 379 cherokee_buffer_read_file (&tmp, vsrv->server_cert.buf); 380 data.data = (unsigned char *)tmp.buf; 381 data.size = tmp.len; 382 383 gnutls_x509_crt_list_import (&vsrv->certs_x509, &max, &data, GNUTLS_X509_FMT_PEM, 0); 384 385 /* Update the credentials 386 */ 387 rc = gnutls_certificate_set_x509_key (vsrv->credentials, 388 &vsrv->certs_x509, 1, 389 vsrv->privkey_x509); 390 if (rc < 0) 391 goto error; 392 393 /* Clean up 394 */ 395 cherokee_buffer_mrproper (&tmp); 396 return 0; 397 398 error: 399 cherokee_buffer_mrproper (&tmp); 400 return rc; 401 } 402 #endif 403 404 276 405 ret_t 277 406 cherokee_virtual_server_init_tls (cherokee_virtual_server_t *vsrv) … … 290 419 /* Check one or more are empty 291 420 */ 292 if (cherokee_buffer_is_empty (&vsrv->ca_cert) || 293 cherokee_buffer_is_empty (&vsrv->server_key) || 421 if (cherokee_buffer_is_empty (&vsrv->server_key) || 294 422 cherokee_buffer_is_empty (&vsrv->server_cert)) 295 423 return ret_error; … … 304 432 /* CA file 305 433 */ 306 rc = gnutls_certificate_set_x509_trust_file (vsrv->credentials, 307 vsrv->ca_cert.buf, 308 GNUTLS_X509_FMT_PEM); 309 if (rc < 0) { 310 PRINT_ERROR ("ERROR: reading X.509 CA Certificate: '%s'\n", vsrv->ca_cert.buf); 311 return ret_error; 434 if (! cherokee_buffer_is_empty (&vsrv->ca_cert)) 435 { 436 rc = gnutls_certificate_set_x509_trust_file (vsrv->credentials, 437 vsrv->ca_cert.buf, 438 GNUTLS_X509_FMT_PEM); 439 if (rc < 0) { 440 PRINT_ERROR ("ERROR: reading X.509 CA Certificate: '%s'\n", 441 vsrv->ca_cert.buf); 442 return ret_error; 443 } 312 444 } 313 445 314 446 /* Key file 315 447 */ 316 rc = gnutls_certificate_set_x509_key_file (vsrv->credentials, 317 vsrv->server_cert.buf, 318 vsrv->server_key.buf, 319 GNUTLS_X509_FMT_PEM); 448 rc = set_x509_key_file (vsrv); 320 449 if (rc < 0) { 321 450 PRINT_ERROR ("ERROR: reading X.509 key '%s' or certificate '%s' file\n", … … 324 453 } 325 454 455 /* SNI 456 */ 457 gnutls_certificate_server_set_retrieve_function (vsrv->credentials, 458 gnutls_sni_servername_cb); 459 460 461 /* Ciphers 462 */ 326 463 generate_dh_params (&vsrv->dh_params); 327 464 generate_rsa_params (&vsrv->rsa_params); cherokee/trunk/cherokee/virtual_server.h
r1715 r1893 32 32 # include <gnutls/extra.h> 33 33 # include <gnutls/gnutls.h> 34 # include <gnutls/x509.h> 34 35 #endif 35 36 … … 83 84 cherokee_avl_r_t session_cache; 84 85 85 # ifdef HAVE_GNUTLS 86 # ifdef HAVE_GNUTLS 86 87 gnutls_certificate_server_credentials credentials; 88 gnutls_x509_privkey_t privkey_x509; 89 gnutls_x509_crt_t certs_x509; 90 87 91 gnutls_dh_params dh_params; 88 92 gnutls_rsa_params rsa_params;