Check-in [f7b84d671a]
Overview
Comment:Added Next Protocol Negotiation (NPN) for TLS 1.0 to TLS 1.2.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | errors_and_callbacks
Files: files | file ages | folders
SHA3-256: f7b84d671ab40c58415240b69b4a6552f09e836c5adfc7a9cc8e504b99b444aa
User & Date: bohagan on 2023-07-16 18:41:20
Other Links: branch diff | manifest | tags
Context
2023-07-21
23:01
Added new option -validatecommand to handle callbacks that require a return value. Consolidated evaluate callback commands into one function EvalCallback. Return alert codes for callbacks. Added more comments to callback functions. check-in: 91ff651d51 user: bohagan tags: errors_and_callbacks
2023-07-16
18:41
Added Next Protocol Negotiation (NPN) for TLS 1.0 to TLS 1.2. check-in: f7b84d671a user: bohagan tags: errors_and_callbacks
17:26
Added alert type to info callback parameters and refactored code. check-in: 0aa8ad9487 user: bohagan tags: errors_and_callbacks
Changes

Modified generic/tls.c from [a232f29e3c] to [6f8aac6c9a].

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    Tcl_Release((ClientData) statePtr);
    Tcl_Release((ClientData) interp);    return 0;
}

/*
 *-------------------------------------------------------------------
 *
 * ALPN Callback for Servers --
 *
 *	Perform server-side protocol (http/1.1, h2, h3, etc.) selection for the
 *	incoming connection. Called after Hello and server callbacks
 *	Where 'out' is selected protocol and 'in' is the peer advertised list.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Calls callback (if defined)







|

|
|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
    Tcl_Release((ClientData) statePtr);
    Tcl_Release((ClientData) interp);    return 0;
}

/*
 *-------------------------------------------------------------------
 *
 * ALPN Callback for Servers and Clients --
 *
 *	Perform protocol (http/1.1, h2, h3, etc.) selection for the
 *	incoming connection. Called after Hello and server callbacks.
 *	Where 'out' is selected protocol and 'in' is the peer advertised list.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Calls callback (if defined)
566
567
568
569
570
571
572











































573
574
575
576
577
578
579
    Tcl_DecrRefCount(cmdPtr);

    Tcl_Release((ClientData) statePtr);
    Tcl_Release((ClientData) interp);
    return res;
}












































/*
 *-------------------------------------------------------------------
 *
 * SNI Callback for Servers --
 *
 *	Perform server-side SNI hostname selection after receiving SNI header.
 *	Called after hello callback but before ALPN callback.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
    Tcl_DecrRefCount(cmdPtr);

    Tcl_Release((ClientData) statePtr);
    Tcl_Release((ClientData) interp);
    return res;
}

/*
 *-------------------------------------------------------------------
 *
 * Advertise Protocols Callback for Servers Next Protocol Negotiation --
 *
 *	called when a TLS server needs a list of supported protocols for Next
 *	Protocol Negotiation.
 *
 * Results:
 *	None
 *
 * Side effects:
 *
 * Return codes:
 *	SSL_TLSEXT_ERR_OK: NPN protocol selected. The connection continues.
 *	SSL_TLSEXT_ERR_NOACK: NPN protocol not selected. The connection continues.
 *
 *-------------------------------------------------------------------
 */
#ifdef USE_NPN
static int
NPNCallback(const SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) {
    State *statePtr = (State*)arg;

    dprintf("Called");

    if (ssl == NULL || arg == NULL) {
	return SSL_TLSEXT_ERR_NOACK;
    }

    /* Set protocols list */
    if (statePtr->protos != NULL) {
	*out = statePtr->protos;
	*outlen = statePtr->protos_len;
    } else {
	*out = NULL;
	*outlen = 0;
	return SSL_TLSEXT_ERR_NOACK;
    }
    return SSL_TLSEXT_ERR_OK;
}
#endif

/*
 *-------------------------------------------------------------------
 *
 * SNI Callback for Servers --
 *
 *	Perform server-side SNI hostname selection after receiving SNI header.
 *	Called after hello callback but before ALPN callback.
1362
1363
1364
1365
1366
1367
1368



1369
1370
1371
1372
1373
1374
1375
1376
1377
1378






1379
1380
1381
1382
1383
1384
1385
    if (server) {
	/* Server callbacks */
	SSL_CTX_set_tlsext_servername_arg(statePtr->ctx, (void *)statePtr);
	SSL_CTX_set_tlsext_servername_callback(statePtr->ctx, SNICallback);
	SSL_CTX_set_client_hello_cb(statePtr->ctx, HelloCallback, (void *)statePtr);
	if (statePtr->protos != NULL) {
	    SSL_CTX_set_alpn_select_cb(statePtr->ctx, ALPNCallback, (void *)statePtr);



	}

	/* Enable server to send cert request after handshake (TLS 1.3 only) */
	if (request && post_handshake) {
	    SSL_verify_client_post_handshake(statePtr->ssl);
	}

	statePtr->flags |= TLS_TCL_SERVER;
	SSL_set_accept_state(statePtr->ssl);
    } else {






	/* Session caching */
	SSL_CTX_set_session_cache_mode(statePtr->ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
	SSL_CTX_sess_set_new_cb(statePtr->ctx, SessionCallback);

	/* Enable post handshake Authentication extension. TLS 1.3 only, not http/2. */
	if (request && post_handshake) {
	    SSL_set_post_handshake_auth(statePtr->ssl, 1);







>
>
>










>
>
>
>
>
>







1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
    if (server) {
	/* Server callbacks */
	SSL_CTX_set_tlsext_servername_arg(statePtr->ctx, (void *)statePtr);
	SSL_CTX_set_tlsext_servername_callback(statePtr->ctx, SNICallback);
	SSL_CTX_set_client_hello_cb(statePtr->ctx, HelloCallback, (void *)statePtr);
	if (statePtr->protos != NULL) {
	    SSL_CTX_set_alpn_select_cb(statePtr->ctx, ALPNCallback, (void *)statePtr);
#ifdef USE_NPN
	    SSL_CTX_set_next_protos_advertised_cb(statePtr->ctx, NPNCallback, (void *)statePtr);
#endif
	}

	/* Enable server to send cert request after handshake (TLS 1.3 only) */
	if (request && post_handshake) {
	    SSL_verify_client_post_handshake(statePtr->ssl);
	}

	statePtr->flags |= TLS_TCL_SERVER;
	SSL_set_accept_state(statePtr->ssl);
    } else {
	/* Client callbacks */
	if (statePtr->protos != NULL) {
#ifdef USE_NPN
	    SSL_CTX_set_next_proto_select_cb(statePtr->ctx, ALPNCallback, (void *)statePtr);
#endif
	}
	/* Session caching */
	SSL_CTX_set_session_cache_mode(statePtr->ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
	SSL_CTX_sess_set_new_cb(statePtr->ctx, SessionCallback);

	/* Enable post handshake Authentication extension. TLS 1.3 only, not http/2. */
	if (request && post_handshake) {
	    SSL_set_post_handshake_auth(statePtr->ssl, 1);
2007
2008
2009
2010
2011
2012
2013







2014
2015
2016
2017
2018
2019
2020
	const unsigned char *session_id;
	char buffer[SSL_MAX_MASTER_KEY_LENGTH];

	/* Report the selected protocol as a result of the ALPN negotiation */
	SSL_SESSION_get0_alpn_selected(session, &proto, &len2);
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len2));








	/* Resumable session */
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("resumable", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_SESSION_is_resumable(session)));

	/* Session start time (seconds since epoch) */
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("start_time", -1));







>
>
>
>
>
>
>







2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
	const unsigned char *session_id;
	char buffer[SSL_MAX_MASTER_KEY_LENGTH];

	/* Report the selected protocol as a result of the ALPN negotiation */
	SSL_SESSION_get0_alpn_selected(session, &proto, &len2);
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len2));

	/* Report the selected protocol as a result of the NPN negotiation */
#ifdef USE_NPN
	SSL_get0_next_proto_negotiated(ssl, &proto, &ulen);
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("npn", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) ulen));
#endif

	/* Resumable session */
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("resumable", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewIntObj(SSL_SESSION_is_resumable(session)));

	/* Session start time (seconds since epoch) */
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("start_time", -1));