https://wiki.openssl.org/api.php?action=feedcontributions&user=Vdukhovni&feedformat=atomOpenSSLWiki - User contributions [en]2024-03-28T18:28:02ZUser contributionsMediaWiki 1.35.6https://wiki.openssl.org/index.php?title=Hostname_validation&diff=2665Hostname validation2018-04-28T19:15:44Z<p>Vdukhovni: /* Example Usage */</p>
<hr />
<div>OpenSSL 1.1.0 provides built-in functionality for hostname checking and validation. Viktor Dukhovni provided the implementation in January, 2015. Its been available in Master since that time. The code is beginning to see widespread testing as the release of OpenSSL 1.1.0 approaches.<br />
<br />
One [http://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html common mistake] made by users of OpenSSL is to assume that OpenSSL will validate the hostname in the server's certificate. Versions prior to 1.0.2 did not perform hostname validation. Version 1.0.2 and up contain support for hostname validation, but they still require the user to call a few functions to set it up.<br />
<br />
A man page on hostname validation has been available since 1.0.2. Also see the [http://www.openssl.org/docs/crypto/X509_check_host.html '''X509_check_host()'''].<br />
<br />
==Example Usage==<br />
<br />
The following is from [http://mid.gmane.org/20150125175706.GN8034@mournblade.imrryr.org Hostname validation] and shows how you could use OpenSSL's built-in hostname validation.<br />
<br />
<pre>const char servername[] = "www.example.com";<br />
SSL *ssl = NULL;<br />
X509_VERIFY_PARAM *param = NULL;<br />
...<br />
<br />
servername = "www.example.com";<br />
ssl = SSL_new(...);<br />
param = SSL_get0_param(ssl);<br />
<br />
/* Enable automatic hostname checks */<br />
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);<br />
if (!X509_VERIFY_PARAM_set1_host(param, servername, sizeof(servername) - 1)) {<br />
// handle error<br />
return 0;<br />
}<br />
<br />
/* Enable peer verification, (with a non-null callback if desired) */<br />
SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);<br />
<br />
/*<br />
* Establish SSL connection, hostname should be checked<br />
* automatically test with a hostname that should not match,<br />
* the connection will fail (unless you specify a callback<br />
* that returns despite the verification failure. In that<br />
* case SSL_get_verify_status() can expose the problem after<br />
* connection completion.<br />
*/<br />
...</pre><br />
The above works starting with OpenSSL 1.0.2. A simpler interface is available starting with OpenSSL 1.1.0:<br />
<pre><br />
...<br />
SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);<br />
if (!SSL_set1_host(ssl, "www.example.com")) {<br />
/* handle error */<br />
}<br />
/* Enable peer verification (with a non-null callback if desired) */<br />
SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);<br />
...<br />
</pre><br />
documentation at [https://www.openssl.org/docs/man1.1.0/ssl/SSL_set1_host.html SSL_set1_host]<br />
<br />
Wildcard support is configured via the flags documented for X509_check_host(), the two most frequently useful are:<br />
<br />
* '''X509_CHECK_FLAG_NO_WILDCARDS'''<br />
* '''X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS'''<br />
<br />
populate the X509_VERIFY_PARAMS with the desired hostname, and let the OpenSSL code call X509_check_host automatically. <br />
<br />
This makes it easier to some day enable DANE TLSA support, because with DANE, name checks need to be skipped for DANE-EE(3) TLSA records, as the DNSSEC TLSA records provides the requisite name<br />
binding instead.<br />
<br />
Also with the X509_VERIFY_PARAM approach, name checks happen early, and for applications that don't continue handshakes with unauthenticated peers, terminate as early as possible.<br />
<br />
There is an associated new X509 error code: '''X509_V_ERR_HOSTNAME_MISMATCH'''<br />
<br />
== SSL Conservatory and cURL code ==<br />
<br />
This was the original information, might still be valid for < 1.0.2 openssl versions :<br />
<br />
[https://github.com/iSECPartners/ssl-conservatory The ssl-conservatory repository] shows how validating the hostname can be done. However, the ssl-conservatory code does not handle wildcard certificates, so [http://archives.seul.org/libevent/users/Feb-2013/msg00043.html borrowing some code from cURL] might be one way to go instead. [https://github.com/ppelleti/libevent/commit/4db9da6bbf8ade7b126840393173b8bd053b3389 This commit] shows how to graft the wildcard-matching code from cURL into the ssl-conservatory code.<br />
<br />
Below is a copy of [https://github.com/ppelleti/libevent/blob/4db9da6bbf8ade7b126840393173b8bd053b3389/sample/openssl_hostname_validation.c openssl_hostname_validation.c], although to compile it also needs the files [https://github.com/ppelleti/libevent/blob/4db9da6bbf8ade7b126840393173b8bd053b3389/sample/hostcheck.h hostcheck.h], [https://github.com/ppelleti/libevent/blob/4db9da6bbf8ade7b126840393173b8bd053b3389/sample/hostcheck.c hostcheck.c], and [https://github.com/ppelleti/libevent/blob/4db9da6bbf8ade7b126840393173b8bd053b3389/sample/openssl_hostname_validation.h openssl_hostname_validation.h].<br />
<br />
<pre><br />
/* Obtained from: https://github.com/iSECPartners/ssl-conservatory */<br />
<br />
/*<br />
Copyright (C) 2012, iSEC Partners.<br />
<br />
Permission is hereby granted, free of charge, to any person obtaining a copy of<br />
this software and associated documentation files (the "Software"), to deal in<br />
the Software without restriction, including without limitation the rights to<br />
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies<br />
of the Software, and to permit persons to whom the Software is furnished to do<br />
so, subject to the following conditions:<br />
<br />
The above copyright notice and this permission notice shall be included in all<br />
copies or substantial portions of the Software.<br />
<br />
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br />
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br />
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br />
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br />
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br />
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br />
SOFTWARE.<br />
*/<br />
<br />
/*<br />
* Helper functions to perform basic hostname validation using OpenSSL.<br />
*<br />
* Please read "everything-you-wanted-to-know-about-openssl.pdf" before<br />
* attempting to use this code. This whitepaper describes how the code works,<br />
* how it should be used, and what its limitations are.<br />
*<br />
* Author: Alban Diquet<br />
* License: See LICENSE<br />
*<br />
*/<br />
<br />
// Get rid of OSX 10.7 and greater deprecation warnings.<br />
#if defined(__APPLE__) && defined(__clang__)<br />
#pragma clang diagnostic ignored "-Wdeprecated-declarations"<br />
#endif<br />
<br />
#include <openssl/x509v3.h><br />
#include <openssl/ssl.h><br />
<br />
#include "openssl_hostname_validation.h"<br />
#include "hostcheck.h"<br />
<br />
#define HOSTNAME_MAX_SIZE 255<br />
<br />
/**<br />
* Tries to find a match for hostname in the certificate's Common Name field.<br />
*<br />
* Returns MatchFound if a match was found.<br />
* Returns MatchNotFound if no matches were found.<br />
* Returns MalformedCertificate if the Common Name had a NUL character embedded in it.<br />
* Returns Error if the Common Name could not be extracted.<br />
*/<br />
static HostnameValidationResult matches_common_name(const char *hostname, const X509 *server_cert) {<br />
int common_name_loc = -1;<br />
X509_NAME_ENTRY *common_name_entry = NULL;<br />
ASN1_STRING *common_name_asn1 = NULL;<br />
char *common_name_str = NULL;<br />
<br />
// Find the position of the CN field in the Subject field of the certificate<br />
common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), NID_commonName, -1);<br />
if (common_name_loc < 0) {<br />
return Error;<br />
}<br />
<br />
// Extract the CN field<br />
common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *) server_cert), common_name_loc);<br />
if (common_name_entry == NULL) {<br />
return Error;<br />
}<br />
<br />
// Convert the CN field to a C string<br />
common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);<br />
if (common_name_asn1 == NULL) {<br />
return Error;<br />
}<br />
common_name_str = (char *) ASN1_STRING_data(common_name_asn1);<br />
<br />
// Make sure there isn't an embedded NUL character in the CN<br />
if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {<br />
return MalformedCertificate;<br />
}<br />
<br />
// Compare expected hostname with the CN<br />
if (Curl_cert_hostcheck(common_name_str, hostname) == CURL_HOST_MATCH) {<br />
return MatchFound;<br />
}<br />
else {<br />
return MatchNotFound;<br />
}<br />
}<br />
<br />
<br />
/**<br />
* Tries to find a match for hostname in the certificate's Subject Alternative Name extension.<br />
*<br />
* Returns MatchFound if a match was found.<br />
* Returns MatchNotFound if no matches were found.<br />
* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it.<br />
* Returns NoSANPresent if the SAN extension was not present in the certificate.<br />
*/<br />
static HostnameValidationResult matches_subject_alternative_name(const char *hostname, const X509 *server_cert) {<br />
HostnameValidationResult result = MatchNotFound;<br />
int i;<br />
int san_names_nb = -1;<br />
STACK_OF(GENERAL_NAME) *san_names = NULL;<br />
<br />
// Try to extract the names within the SAN extension from the certificate<br />
san_names = X509_get_ext_d2i((X509 *) server_cert, NID_subject_alt_name, NULL, NULL);<br />
if (san_names == NULL) {<br />
return NoSANPresent;<br />
}<br />
san_names_nb = sk_GENERAL_NAME_num(san_names);<br />
<br />
// Check each name within the extension<br />
for (i=0; i<san_names_nb; i++) {<br />
const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);<br />
<br />
if (current_name->type == GEN_DNS) {<br />
// Current name is a DNS name, let's check it<br />
char *dns_name = (char *) ASN1_STRING_data(current_name->d.dNSName);<br />
<br />
// Make sure there isn't an embedded NUL character in the DNS name<br />
if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != strlen(dns_name)) {<br />
result = MalformedCertificate;<br />
break;<br />
}<br />
else { // Compare expected hostname with the DNS name<br />
if (Curl_cert_hostcheck(dns_name, hostname)<br />
== CURL_HOST_MATCH) {<br />
result = MatchFound;<br />
break;<br />
}<br />
}<br />
}<br />
}<br />
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);<br />
<br />
return result;<br />
}<br />
<br />
<br />
/**<br />
* Validates the server's identity by looking for the expected hostname in the<br />
* server's certificate. As described in RFC 6125, it first tries to find a match<br />
* in the Subject Alternative Name extension. If the extension is not present in<br />
* the certificate, it checks the Common Name instead.<br />
*<br />
* Returns MatchFound if a match was found.<br />
* Returns MatchNotFound if no matches were found.<br />
* Returns MalformedCertificate if any of the hostnames had a NUL character embedded in it.<br />
* Returns Error if there was an error.<br />
*/<br />
HostnameValidationResult validate_hostname(const char *hostname, const X509 *server_cert) {<br />
HostnameValidationResult result;<br />
<br />
if((hostname == NULL) || (server_cert == NULL))<br />
return Error;<br />
<br />
// First try the Subject Alternative Names extension<br />
result = matches_subject_alternative_name(hostname, server_cert);<br />
if (result == NoSANPresent) {<br />
// Extension was not found: try the Common Name<br />
result = matches_common_name(hostname, server_cert);<br />
}<br />
<br />
return result;<br />
}<br />
<br />
</pre><br />
<br />
<br />
[[Category:SSL/TLS]]<br />
[[Category:Common Mistake]]<br />
[[Category:Examples]]</div>Vdukhovnihttps://wiki.openssl.org/index.php?title=TLS1.3&diff=2664TLS1.32018-04-28T19:00:37Z<p>Vdukhovni: /* Server Name Indication */</p>
<hr />
<div>The OpenSSL 1.1.1 release includes support for TLSv1.3. The release is binary and API compatible with OpenSSL 1.1.0. In theory, if your application supports OpenSSL 1.1.0, then all you need to do to upgrade is to drop in the new version of OpenSSL and you will automatically start being able to use TLSv1.3. However there are some issues that application developers and deployers need to be aware of.<br />
<br />
== Differences with TLS1.2 and below ==<br />
<br />
TLSv1.3 is a major rewrite of the specification. There was some debate as to whether it should really be called TLSv2.0 - but TLSv1.3 it is. There are major changes and some things work very differently. A brief, incomplete, summary of some things that you are likely to notice follows:<br />
<br />
* There are new ciphersuites that only work in TLSv1.3. The old ciphersuites cannot be used for TLSv1.3 connections and the new ones cannot be used in TLSv1.2 and below.<br />
* The new ciphersuites are defined differently and do not specify the certificate type (e.g. RSA, DSA, ECDSA) or the key exchange mechanism (e.g. DHE or ECHDE). This has implications for ciphersuite configuration.<br />
* Clients provide a “key_share” in the ClientHello. This has consequences for “group” configuration.<br />
* Sessions are not established until after the main handshake has been completed. There may be a gap between the end of the handshake and the establishment of a session (or, in theory, a session may not be established at all). This could have impacts on session resumption code.<br />
* Renegotiation is not possible in a TLSv1.3 connection<br />
* More of the handshake is now encrypted.<br />
* More types of messages can now have extensions (this has an impact on the custom extension APIs and Certificate Transparency)<br />
* DSA certificates are no longer allowed in TLSv1.3 connections<br />
<br />
Note that at this stage only TLSv1.3 is supported. DTLSv1.3 is still in the early days of specification and there is no OpenSSL support for it at this time.<br />
<br />
== Current status of the TLSv1.3 standard ==<br />
<br />
As of the time of writing TLSv1.3 is still in draft. Periodically a new version of the draft standard is published by the TLS Working Group. Implementations of the draft are required to identify the specific draft version that they are using. This means that implementations based on different draft versions do not interoperate with each other.<br />
<br />
OpenSSL 1.1.1 will not be released until (at least) TLSv1.3 is finalised. In the meantime the OpenSSL git master branch contains our development TLSv1.3 code which can be used for testing purposes (i.e. it is not for production use). You can check which draft TLSv1.3 version is implemented in any particular OpenSSL checkout by examining the value of the TLS1_3_VERSION_DRAFT_TXT macro in the tls1.h header file. This macro will be removed when the final version of the standard is released.<br />
<br />
TLSv1.3 is enabled by default in the latest development versions (there is no need to explicitly enable it). To disable it at compile time you must use the “no-tls1_3” option to “config” or “Configure”.<br />
<br />
Currently OpenSSL has implemented the “draft-26” version of TLSv1.3. Other applications that support TLSv1.3 may still be using older draft versions. This is a common source of interoperability problems. If two peers supporting different TLSv1.3 draft versions attempt to communicate then they will fall back to TLSv1.2.<br />
<br />
== Ciphersuites ==<br />
<br />
OpenSSL has implemented support for five TLSv1.3 ciphersuites as follows:<br />
<br />
* TLS13-AES-256-GCM-SHA384<br />
* TLS13-CHACHA20-POLY1305-SHA256<br />
* TLS13-AES-128-GCM-SHA256<br />
* TLS13-AES-128-CCM-8-SHA256<br />
* TLS13-AES-128-CCM-SHA256<br />
<br />
Due to the major differences between the way that ciphersuites for TLSv1.2 and below and ciphersuites for TLSv1.3 work, they are configured in OpenSSL differently too.<br />
<br />
By default the first three of the above ciphersuites are enabled by default. This means that if you have no explicit ciphersuite configuration then you will automatically use those three and will be able to negotiate TLSv1.3. Note that changing the TLSv1.2 and below cipher list has no impact on the TLSv1.3 ciphersuite configuration.<br />
<br />
For the OpenSSL command line applications there is a new "-ciphersuites" option to configure the TLSv1.3 ciphersuite list. This is just a simple colon (":") separated list of TLSv1.3 ciphersuite names in preference order. Note that you cannot use the special characters such as "+", "!", "-" etc, that you can for defining TLSv1.2 ciphersuites. In practice this is not likely to be a problem because there are only a very small number of TLSv1.3 ciphersuites.<br />
<br />
For example:<br />
<br />
$ openssl s_server -cert mycert.pem -key mykey.pem -cipher ECDHE -ciphersuites "TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256"<br />
<br />
This will configure OpenSSL to use any ECDHE based ciphersuites for TLSv1.2 and below. For TLSv1.3 the TLS13-AES-256-GCM-SHA384 and TLS13-CHACHA20-POLY1305-SHA256 ciphersuites will be available.<br />
<br />
Note that all of the above applies to the "ciphers" command line application as well. This can sometimes lead to surprising results. For example this command:<br />
<br />
$ openssl ciphers -s -v ECDHE<br />
<br />
Will list all the ciphersuites for TLSv1.2 and below that support ECDHE '''and''' additionally all of the default TLSv1.3 ciphersuites. Use the "-ciphersuites" option to further configure the TLSv1.3 ciphersuites.<br />
<br />
== Groups ==<br />
<br />
In TLSv1.3 the client selects a “group” that it will use for key exchange. At the time of writing, OpenSSL only supports ECDHE groups for this. The client then sends “key_share” information to the server for its selected group in the ClientHello.<br />
<br />
The list of supported groups is configurable. It is possible for a client to select a group that the server does not support. In this case the server requests that the client sends a new key_share that it does support. While this means a connection will still be established (assuming a mutually supported group exists), it does introduce an extra server round trip - so this has implications for performance. In the ideal scenario the client will select a group that the server supports in the first instance.<br />
<br />
In practice most clients will use X25519 or P-256 for their initial key_share. For maximum performance it is recommended that servers are configured to support at least those two groups and clients use one of those two for its initial key_share. This is the default case (OpenSSL clients will use X25519).<br />
<br />
The group configuration also controls the allowed groups in TLSv1.2 and below. If applications have previously configured their groups in OpenSSL 1.1.0 then you should review that configuration to ensure that it still makes sense for TLSv1.3. The first named (i.e. most preferred group) will be the one used by an OpenSSL client in its intial key_share.<br />
<br />
Applications can configure the group list by using SSL_CTX_set1_groups() or a similar function (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set1_groups.html here] for further details). Alternatively, if applications use SSL_CONF style configuration files then this can be configured using the Groups or Curves command (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html#SUPPORTED-CONFIGURATION-FILE-COMMANDS here]).<br />
<br />
== Sessions ==<br />
<br />
In TLSv1.2 and below a session is established as part of the handshake. This session can then be used in a subsequent connection to achieve an abbreviated handshake. Applications might typically obtain a handle on the session after a handshake has completed using the SSL_get1_session() function (or similar). See [https://www.openssl.org/docs/man1.1.1/man3/SSL_get1_session.html here] for further details.<br />
<br />
In TLSv1.3 sessions are not established until after the main handshake has completed. The server sends a separate post-handshake message to the client containing the session details. Typically this will happen soon after the handshake has completed, but it could be sometime later (or not at all).<br />
<br />
The specification recommends that applications only use a session once (although this may not be enforced). For this reason some servers send multiple session messages to a client. To enforce the “use once” recommendation applications could use SSL_CTX_remove_session() to mark a session as non-resumable (and remove it from the cache) once it has been used. OpenSSL servers that accept "early_data" will automatically enforce singly use sessions. Any attempt to resume with a session that has already been used will fallback to a full handshake.<br />
<br />
The old SSL_get1_session() and similar APIs may not operate as expected for client applications written for TLSv1.2 and below. Specifically if a client application calls SSL_get1_session() before the server message containing session details has been received then an SSL_SESSION object will still be returned, but any attempt to resume with it will not succeed and a full handshake will occur instead. In the case where multiple sessions have been sent by the server then only the last session will be returned by SSL_get1_session().<br />
<br />
Client application developers should consider using the SSL_CTX_sess_set_new_cb() API instead (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_sess_set_new_cb.html here]). This provides a callback mechanism which gets invoked every time a new session is established. This can get invoked multiple times for a single connection if a server sends multiple session messages.<br />
<br />
Note that SSL_CTX_sess_set_new_cb() was also available in OpenSSL 1.1.0. Applications that already used that API will still work, but they may find that the callback is invoked at unexpected times, i.e. post-handshake.<br />
<br />
An OpenSSL server will immediately attempt to send session details to a client after the main handshake has completed. To server applications this post-handshake stage will appear to be part of the main handshake, so calls to SSL_get1_session() should continue to work as before.<br />
<br />
== Custom Extensions and Certificate Transparency ==<br />
<br />
In TLSv1.2 and below the initial ClientHello and ServerHello messages can contain “extensions”. This allows the base specifications to be extended with additional features and capabilities that may not be applicable in all scenarios or could not be foreseen at the time that the base specifications were written. OpenSSL provides support for a number of “built-in” extensions.<br />
<br />
Additionally the custom extensions API provides some basic capabilities for application developers to add support for new extensions that are not built-in to OpenSSL.<br />
<br />
Built on top of the custom extensions API is the “serverinfo” API. This provides an even more basic interface that can be configured at run time. One use case for this is Certificate Transparency. OpenSSL provides built-in support for the client side of Certificate Transparency but there is no built-in server side support. However this can easily be achieved using “serverinfo” files. A serverinfo file containing the Certificate Transparency information can be configured within OpenSSL and it will then be sent back to the client as appropriate.<br />
<br />
In TLSv1.3 the use of extensions is expanded significantly and there are many more messages that can include them. Additionally some extensions that were applicable to TLSv1.2 and below are no longer applicable in TLSv1.3 and some extensions are moved from the ServerHello message to the EncryptedExtensions message. The old custom extensions API does not have the ability to specify which messages the extensions should be associated with. For that reason a new custom extensions API was required.<br />
<br />
The old API will still work, but the custom extensions will only be added where TLSv1.2 or below is negotiated. To add custom extensions that work for all TLS versions application developers will need to update their applications to the new API (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_add_custom_ext.html here] for details).<br />
<br />
The “serverinfo” data format has also been updated to include additional information about which messages the extensions are relevant to. Applications using “serverinfo” files may need to update to the “version 2” file format to be able to operate in TLSv1.3 (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_use_serverinfo.html here] for details).<br />
<br />
== Renegotiation ==<br />
<br />
TLSv1.3 does not have renegotiation so calls to SSL_renegotiate() or SSL_renegotiate_abbreviated() will immediately fail if invoked on a connection that has negotiated TLSv1.3.<br />
<br />
A common use case for renegotiation is to update the connection keys. The function SSL_key_update() can be used for this purpose in TLSv1.3 (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_key_update.html here] for further details).<br />
<br />
Another use case is to request a certificate from the client. This can be achieved by using the SSL_verify_client_post_handshake() function in TLSv1.3 (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_client_post_handshake.html here] for further details).<br />
<br />
== DSA certificates ==<br />
<br />
DSA certificates are no longer allowed in TLSv1.3. If your server application is using a DSA certificate then TLSv1.3 connections will fail with an error message similar to the following:<br />
<br />
<br />
140348850206144:error:14201076:SSL routines:tls_choose_sigalg:no suitable signature algorithm:ssl/t1_lib.c:2308:<br />
<br />
Please use an ECDSA or RSA certificate instead.<br />
<br />
== Middlebox Compatibility Mode ==<br />
<br />
During development of the TLSv1.3 standard it became apparent that in some cases, even if a client and server both support TLSv1.3, connections could sometimes still fail. This is because middleboxes on the network between the two peers do not understand the new protocol and prevent the connection from taking place. In order to work around this problem the TLSv1.3 specification introduced a “middlebox compatibility” mode. This made a few optional changes to the protocol to make it appear more like TLSv1.2 so that middleboxes would let it through. Largely these changes are superficial in nature but do include sending some small but unneccessary messages. OpenSSL has middlebox compatibility mode on by default, so most users should not need to worry about this. However applications may choose to switch it off by calling the function SSL_CTX_clear_options() and passing SSL_OP_ENABLE_MIDDLEBOX_COMPAT as an argument (see [https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_clear_options.html here] for further details).<br />
<br />
If the remote peer is not using middlebox compatibility mode and there are problematic middleboxes on the network path then this could cause spurious connection failures.<br />
<br />
== Server Name Indication ==<br />
<br />
Server Name Indication (SNI) can be used by the client to select one of several sites on the same host, and so a different X.509 certificate can be sent depending on the hostname that was sent in the SNI extension. If the SNI extension is not sent the server's options are to either disconnect or select a default hostname and matching certificate. The default would typically be the main site.<br />
<br />
SNI has been made mandatory to implement in TLS 1.3 but not mandatory to use. Some sites want to encourage the use of SNI and configure a default certificate that fails WebPKI authentication when the client supports TLS 1.3. This is under the assumption that if a hostname is not sent, then it means that the client does not verify the server certificate (unauthenticated opportunistic TLS). For implementation that actually don't send the SNI extension, but do verify the server certificate this can cause connection failures.<br />
<br />
To enable SNI you need to use the [https://www.openssl.org/docs/man1.1.1/man3/SSL_set_tlsext_host_name.html SSL_set_tlsext_host_name()] function. For hostname validation see [[Hostname_validation|Hostname validation]].<br />
<br />
== Conclusion ==<br />
<br />
TLSv1.3 represents a significant step forward and has some exciting new features but there are some hazards for the unwary when upgrading. Mostly these issues have relatively straight forward solutions. Application developers should review their code and consider whether anything should be updated in order to work more effectively with TLSv1.3. Similarly application deployers should review their configuration.</div>Vdukhovni