Macros | Functions
TLS: Transport Layer Security

This module provides optional support for an encrypted connection to the server. It is intended to follow RFC 2246, RFC 4346, RFC 5246, RFC 7366, RFC 7507, RFC 7627 and RFC 8446 (depending on the underlying OpenSSL library). OpenSSL 1.0.0 is the oldest supported version. For full functionality at least OpenSSL 3.0.0 is required. More...

Macros

#define MAIN_ERR_PREFIX   "TLS: "
 Message prefix for TLS module.
 
#define CFG_USE_TLS_WILDCARD_SUBJECT   1
 Set this to 1 to accept wildcard for left-most component of X.509 certificate subjects. More...
 
#define TLS_CIPHERS_TLS13
 Cipher suite list for TLSv1.3. More...
 
#define TLS_CIPHERS_DEFAULT
 Default (strong) cipher suite list for TLSv1.0 to TLSv1.2 protocols. More...
 
#define TLS_CIPHERS_WEAK
 Optional (weak) cipher suite list for TLSv1.0 to TLSv1.2 protocols. More...
 
#define TLS_SIGALGS_TLS13
 Additional signature algorithms for TLSv1.3 protocol. More...
 
#define TLS_SIGALGS   "RSA+SHA512:RSA+SHA384:RSA+SHA256"
 Signature algorithms for TLSv1.2 protocol. More...
 
#define TLS_ECDHE_GROUPS_TLS13   "X448:X25519:P-256"
 ECDHE groups for TLSv1.3 protocol.
 
#define TLS_FFDHE_GROUPS   "ffdhe8192:ffdhe6144:ffdhe4096:ffdhe3072"
 FFDHE groups for TLSv1.2 and TLSv1.3 protocols. More...
 

Functions

int tls_init (void)
 Init TLS subsystem. More...
 
void tls_exit (void)
 Shutdown TLS subsystem.
 
int tls_vulnerability_check (int check)
 Check TLS subsystem for known vulnerabilities. More...
 
const char * tls_sni (const char *sn)
 Check whether server name used for connection is not an IP address. More...
 
int tls_open (int sd, void **co, int weak, const char *sni)
 Establish TLS encryption layer on top of open network connection. More...
 
int tls_close (void **co)
 Terminate TLS encryption layer on top of network connection. More...
 
int tls_get_ciphersuite (void **co, const char **pv, const char **cs, const char **kx)
 Get protocol and cipher suite name that was negotiated for connection. More...
 
int tls_cert_verify (void **co, void **cert, const char *cn, int weak)
 Check whether server has presented a certificate and verify it. More...
 
int tls_cert_get_string (void *cert, const char **cbuf)
 Print certificate. More...
 
posix_ssize_t tls_send (void *co, const void *buf, size_t len)
 Send data. More...
 
posix_ssize_t tls_recv (void *co, void *buf, size_t len, int peek)
 Receive data. More...
 
int tls_crl_update_check (void)
 Check whether CRL update interval has elapsed. More...
 
void tls_crl_update_control (int crl_upd_disable)
 Enable or disable automatic CRL updates. More...
 
void tls_free (void *p)
 Free an object allocated by TLS module. More...
 

Detailed Description

This module provides optional support for an encrypted connection to the server. It is intended to follow RFC 2246, RFC 4346, RFC 5246, RFC 7366, RFC 7507, RFC 7627 and RFC 8446 (depending on the underlying OpenSSL library). OpenSSL 1.0.0 is the oldest supported version. For full functionality at least OpenSSL 3.0.0 is required.

The server to client authentication based on X.509 certificates should be RFC 1422 and RFC 5280 conformant.

Attention
It is required that 'SSIZE_MAX' is at least 'INT_MAX' (must be checked by build system).
We have no own source for random numbers. OpenSSL must be configured to be able to fetch random numbers itself. If the operating system provides no random number generator (RNG), there must be a separate one installed that OpenSSL can use (consider egd or prngd if your OS provides no such option). If OpenSSL reports there is no RNG available, the program fails to start.

By default only cipher suites using ephemeral Diffie-Hellman-Merkle key exchange (to provide forward secrecy) and strong symmetric data encryption algorithms are offered to the server. In the past (until RFC 8143 was released), RFC 4642 defined the weak cipher suite RSA-RSA-RC4-MD5 as mandatory. It can still be added to the list together with some other cipher suites that are considered weak (without forward secrecy or based on elliptic curves). This option is selected with a parameter of the tls_open() function. This will also add the weak cipher suite RSA-RSA-AES128-SHA that is defined as mandatory by RFC 5246.

According to RFC 6176 and RFC 7568 the SSL protocol is never negotiated and the TLS protocol used instead.

We never offer anonymous cipher suites to the server. Therefore while the encrypted connection is established, the server must present a certificate. This certificate can optionally be verified for server to client authentication with the function tls_cert_verify() . This will ensure that a trusted CA is the root of the certificate chain and that the subject of the last certificate contains the hostname we have resolved to connect the server.

Macro Definition Documentation

◆ CFG_USE_TLS_WILDCARD_SUBJECT

#define CFG_USE_TLS_WILDCARD_SUBJECT   1

Set this to 1 to accept wildcard for left-most component of X.509 certificate subjects.

Note
RFC 8143 specifies this as valid with regard to the NNTP protocol, therefore the value 1 is the default.

Definition at line 110 of file tls.c.

◆ TLS_CIPHERS_DEFAULT

#define TLS_CIPHERS_DEFAULT
Value:
"!SSLv2:!RC2:!RC4:!DES:!3DES:!MD5:!kEECDH:!aNULL:!aDSS:!aECDSA" \
":kEDH+HIGH@STRENGTH:-SSLv3:kEDH+HIGH:!AESCCM8"

Default (strong) cipher suite list for TLSv1.0 to TLSv1.2 protocols.

This list of cipher suites is the default. It is possible to use weaker cipher suites when a connection is opened. See tls_open() for details.

This list contains only cipher suites that provide forward secrecy by using ephemeral Diffie-Hellman-Merkle key exchange.

TLSv1.2 protocol is preferred (if the OpenSSL library supports it).

Cipher suites that use DSA or ECDSA based authentication are excluded because both are very dependent on a high quality RNG for its nonce and the key length of DSA for TLS is effectively limited to 1024 bit.

ECC-based key exchange is excluded because the DHE group check code currently can't handle it.

Note
The size of the FFDHE group provided by the server is relevant for the strength of the encryption and the forward secrecy. Unfortunately it can't be checked with OpenSSL 1.0 (at least OpenSSL 1.1 API required). If the OpenSSL 3 API is available, the FFDHE groups defined in RFC 7919 are offered for negotiation.
The tag !SSLv2 in the list means the corresponding cipher suites not the SSLv2 protocol.
Attention
Ensure that this list never contains anonymous cipher suites. Otherwise the server doesn't present a certificate and the authenticity check will fail.

Definition at line 153 of file tls.c.

◆ TLS_CIPHERS_TLS13

#define TLS_CIPHERS_TLS13
Value:
"TLS_AES_256_GCM_SHA384" \
":TLS_CHACHA20_POLY1305_SHA256" \
":TLS_AES_128_GCM_SHA256" \
":TLS_AES_128_CCM_SHA256"

Cipher suite list for TLSv1.3.

This list of cipher suites is ignored for older protocol versions.

Definition at line 116 of file tls.c.

◆ TLS_CIPHERS_WEAK

#define TLS_CIPHERS_WEAK
Value:
"!SSLv2:!RC2:!DES:!aNULL:!aDSS:!aECDSA" \
/* Strong symmetric algorithms and forward secrecy first */ \
":kEDH+HIGH:kEECDH+HIGH:-SSLv3:kEDH+HIGH:kEECDH+HIGH" \
":-3DES:kEDH+HIGH:kEECDH+HIGH" \
/* Strong symmetric algorithms and no forward secrecy next */ \
":AES256-GCM-SHA384:CAMELLIA256-SHA:AES128-SHA" \
/* Weak symmetric algorithms and no forward secrecy last */ \
":RC4-MD5"

Optional (weak) cipher suite list for TLSv1.0 to TLSv1.2 protocols.

This list contains cipher suites that are considered weak for better compatibility to existing servers. Some obsolete standards like RFC 4642 defined some of the weak algorithms as mandatory in the past and we support them for backward compatibility.

Note
The tag !SSLv2 in the list means the corresponding cipher suites not the SSLv2 protocol.
Attention
Ensure that this list never contains anonymous cipher suites. Otherwise the server doesn't present a certificate and the authenticity check will fail.

Definition at line 172 of file tls.c.

◆ TLS_FFDHE_GROUPS

#define TLS_FFDHE_GROUPS   "ffdhe8192:ffdhe6144:ffdhe4096:ffdhe3072"

FFDHE groups for TLSv1.2 and TLSv1.3 protocols.

Attention
This list must not contain ECDHE groups because the group check code for TLSv1.2 currently doesn't support ECC!

Definition at line 234 of file tls.c.

◆ TLS_SIGALGS

#define TLS_SIGALGS   "RSA+SHA512:RSA+SHA384:RSA+SHA256"

Signature algorithms for TLSv1.2 protocol.

This list contains the signature algorithms offered in order of decreasing preference.

The signature algorithm cannot be negotiated with the TLSv1.0 and TLSv1.1 protocols. This algorithm list is intended for all signatures in the TLSv1.2 protocol (including key exchange and signatures in certificates).

We only offer hash algorithms from the SHA-2 family (this means MD5 and SHA-1 are not used for negotiation).

Attention
The asymmetric cipher must always be RSA because certificates with DSA or ECDSA keys are not supported for TLSv1.2 in strong mode.

Definition at line 223 of file tls.c.

◆ TLS_SIGALGS_TLS13

#define TLS_SIGALGS_TLS13
Value:
"rsa_pss_rsae_sha512:rsa_pss_rsae_sha384:rsa_pss_rsae_sha256" \
/* Offer ECC-based signatures for TLSv1.3 only */ \
":ecdsa_secp521r1_sha512:ecdsa_secp256r1_sha256"

Additional signature algorithms for TLSv1.3 protocol.

This list contains the signature algorithms offered in order of decreasing preference.

For TLSv1.3 the signature scheme names as defined in RFC 8446 (Section 4.2.3) are supported by OpenSSL. We use them here to make it obvious which codes will be offered in the Client Hello message.

Attention
RFC 8446 defines the algorithm ecdsa_secp256r1_sha256 as mandatory for the TLSv1.3 protocol. Avoiding ECC is no longer allowed!
Note
The algorithms for TLSv1.2 above use RSASSA-PKCS1-v1_5. For TLSv1.3 they are no longer allowed except for certificates. We omit the separate negotiation for the certificate signature algorithms. The old algorithms below are appended to the end of this list (with lowest preference).

Definition at line 201 of file tls.c.

Function Documentation

◆ tls_cert_get_string()

int tls_cert_get_string ( void *  cert,
const char **  cbuf 
)

Print certificate.

Parameters
[in]certPointer to cerificate
[out]cbufPointer buffer pointer

On success, a memory block is allocated for the certificate and a pointer to it is written to cbuf. The caller is responsible to free the memory block allocated for the certificate.

Returns
  • 0 on success
  • -1 on error

Definition at line 2706 of file tls.c.

◆ tls_cert_verify()

int tls_cert_verify ( void **  co,
void **  cert,
const char *  cn,
int  weak 
)

Check whether server has presented a certificate and verify it.

Parameters
[in]coPointer to connection object pointer
[out]certPointer to cerificate pointer
[in]cnCommon name string the certificate should contain
[in]weakDisable some checks for better compatibility
Attention
The parameter weak must be set to the same value that was used for the call to tls_open() .

The verification executes the following steps:

  • Ensure that the server has presented a certificate (chain)
  • Optional: Check the signature algorithms and key lengths used in the certificate chain (Setting weak to a nonzero value disables this step)
  • Follow certificate chain back to the anchor and verify that it is trusted
  • Optional: Verify that none of the certificates in the chain was revoked (The CRLs for the revocation checks are downloaded automatically)
  • Verify that the subject of the certificate contain cn

According to RFC 8143 the following rules are applied:

  • The matching of hostname cn must be case-insensitive => We do so.
  • Wildcard * is allowed as left-most name component => We accept this.
  • Hostnames listed via subjectAltName extension should be checked first => We do so.
  • If the certificate contains multiple names (e.g., more than one dNSName field), then a match with any one of the fields is considered acceptable => We accept any match.

If the return value is not negative, the server has presented a certificate and a pointer to it was written to cert .

Note
The returned value for cert stay in memory until the connection object co is destroyed.

The return value -2 should be interpreted as a request to close the connection and re-establish it again (and then using the new CRLs).

Returns
  • 0 on success (Certificate was presented, is valid and trusted)
  • 1 if the certificate is not trusted
  • -1 on error
  • -2 if the verification was not executed because CRLs have been updated

Definition at line 2468 of file tls.c.

References CONF_CRL_CHECK, config, MAIN_ERR_PREFIX, PRINT_ERROR, and tls_get_ciphersuite().

◆ tls_close()

int tls_close ( void **  co)

Terminate TLS encryption layer on top of network connection.

Parameters
[in,out]coPointer to connection object pointer
Note
This function also destroys the TLS context that contains the certificate CRLs. After CRLs are updated, it is not required to shutdown the whole module via tls_exit() . Calling this function is sufficient to invalidate any CRLs in memory.
Returns
  • 1 on success
  • Negative value on error

Definition at line 2311 of file tls.c.

References PRINT_ERROR.

◆ tls_crl_update_check()

int tls_crl_update_check ( void  )

Check whether CRL update interval has elapsed.

This function is exported for the UI module to check the CRL update interval and give the user a choice to delay the CRL updates. The function tls_crl_update_control() is intended to enable and disable the automatic CRL updates.

Note
The update choice can be disabled with configuration option CONF_CRL_UPD_C (if configured to zero, this function will alays return zero).
Returns
  • 0 Do nothing
  • 1 CRL update interval elapsed. Give user a choice to suppress update
  • -1 on error

Definition at line 2838 of file tls.c.

References CONF_CRL_CHECK, CONF_CRL_UPD_C, config, conf_entry_val::i, and conf::val.

◆ tls_crl_update_control()

void tls_crl_update_control ( int  crl_upd_disable)

Enable or disable automatic CRL updates.

Parameters
[in]crl_upd_disableDisable automatic CRL updates if nonzero
Attention
If CRLs are used, they need to be present and valid! With this function the update of CRLs can only be suppressed until they expire. After expiration of the CRLs a TLS connection can no longer be established (if a certificate chain is used for authentication).
Note
When disabled, the CRL updates can be reenabled on the fly at any time by calling this function again with crl_upd_disable set to zero.

Definition at line 2869 of file tls.c.

◆ tls_free()

void tls_free ( void *  p)

Free an object allocated by TLS module.

Use this function to release dynamic memory that was allocated by the TLS module.

Parameters
[in]pPointer to object

Release the memory for the object pointed to by p.

Note
The pointer p is allowed to be NULL and no operation is performed in this case.

Definition at line 2893 of file tls.c.

◆ tls_get_ciphersuite()

int tls_get_ciphersuite ( void **  co,
const char **  pv,
const char **  cs,
const char **  kx 
)

Get protocol and cipher suite name that was negotiated for connection.

Parameters
[in]coPointer to connection object pointer
[out]pvPointer to protocol version string
[out]csPointer to cipher suite string
[out]kxPointer to key exchange algorithm
Attention
The value returned for kx is only valid when the protocol version returned for pv is TLSv1.3 (for older protocol versions the key exchange algorithm is negotiated as part of the cipher suite).
Note
If the caller is not interested in the information, the parameters pv and cs it is allowed to pass NULL .
Returns
  • 0 on success
  • -1 on error

Definition at line 2360 of file tls.c.

References PRINT_ERROR.

Referenced by tls_cert_verify().

◆ tls_init()

int tls_init ( void  )

Init TLS subsystem.

Returns
  • 0 on success
  • Negative value on error

Definition at line 1762 of file tls.c.

◆ tls_open()

int tls_open ( int  sd,
void **  co,
int  weak,
const char *  sni 
)

Establish TLS encryption layer on top of open network connection.

Parameters
[in]sdSocket descriptor
[out]coPointer to connection object pointer
[in]weakOffer weak cipher suite(s) to server
[in]sniHostname for SNI extension (or NULL )

The socket descriptor sd must be assigned to an open connection.

If sni is NULL, the SNI extension is not used (but this is forbidden by RFC 8143). If the caller wants to use the SNI extension, sni must point to the hostname string used for DNS resolution when the connection associated with sd was established.

On success, a pointer to the connection object is stored at the location pointed by co .

Attention
RFC 5246 specifies the cipher suite RSA-RSA-AES128-SHA (0x00, 0x2F) as mandatory. RFC 4642 specified the cipher suite RSA-RSA-RC4-MD5 (0x00, 0x04) as mandatory in the past (it is preserved for backward compatibility). Both will provide no forward secrecy and the latter one in addition use the weak RC4 symmetric encryption algorithm. Therefore they are not included in the default list of ciphers we offer to the server.

To comply with RFC 5246 and nevertheless offer the disabled cipher suites, or if the server doesn't support FFDHE key exchange, weak must be set to a nonzero value.

If OpenSSL API 1.1 is available, the FFDHE group from the server are verified to be at least 1024 bits in size for FFDHE key exchange (if weak is set to zero).

If OpenSSL API 1.1 is available and at least TLSv1.2 is used, the signature algorithm to use for TLS protocol is negotiated with the server. The algorithms we offer are defined with TLS_SIGALGS for TLSv1.2. The algorithms we offer are defined with TLS_SIGALGS_TLS13 for TLSv1.3.

Note
TLSv1.3 allows to offer a separate list of signature algorithms for certificates. We do not use this feature and the certificates must use signature algorithms listed in TLS_SIGALGS_TLS13 .
Returns
  • 0 on success
  • Negative value on error

Definition at line 2077 of file tls.c.

◆ tls_recv()

posix_ssize_t tls_recv ( void *  co,
void *  buf,
size_t  len,
int  peek 
)

Receive data.

Parameters
[in]coPointer to connection object pointer
[out]bufPointer to data buffer
[in]lenNumber of octets to receive
[in]peekData should stay available for reading if nonzero
Attention
The peek flag doesn't work anymore since OpenSSL 1.1.0 and must be zero in this case (otherwise a deadlock will occur). This bug was fixed before OpenSSL 1.1.1 (works again now).
Returns
  • Number of bytes received
  • -1 on error

Definition at line 2791 of file tls.c.

References PRINT_ERROR.

◆ tls_send()

posix_ssize_t tls_send ( void *  co,
const void *  buf,
size_t  len 
)

Send data.

Parameters
[in]coPointer to connection object pointer
[in]bufPointer to data buffer
[in]lenNumber of octets to send
Returns
  • Number of bytes sent
  • -1 on error

Definition at line 2754 of file tls.c.

References PRINT_ERROR.

◆ tls_sni()

const char* tls_sni ( const char *  sn)

Check whether server name used for connection is not an IP address.

Parameters
[in]snPointer to server name string

An IP address cannot be used for the SNI extension. This function should be called to determine whether a TCP connection was established based on DNS name or IP address.

The result can be used as parameter sni for the function tls_open() .

Returns
  • sn on success
  • NULL if sn is a valid ASCII representation of an IP address

Definition at line 2004 of file tls.c.

◆ tls_vulnerability_check()

int tls_vulnerability_check ( int  check)

Check TLS subsystem for known vulnerabilities.

Parameters
[in]checkExecute vulnerability checks

If check is zero, only the library name and version number is printed

Attention
Because the TLS subsystem may use dynamically linked OpenSSL libraries, this check can't be done at compile time!

OpenSSL version numbers since 0.9.5 are composed as follows:

0xMNNFFPPS (Major miNor Fix Patch Status)


0x00906023 (0.9.6b beta 3)
0x1000107F (1.0.1g release)
0x20000000 (2.0.0 dev, reported by LibreSSL)
0x30000000 (3.0.0 dev, reported by OpenSSL Alpha versions)

Note
LibreSSL always reports the same OpenSSL version.
Returns
  • 0 on success
  • Negative value if TLS subsystem may use code with known vulnerabilities

Definition at line 1859 of file tls.c.

References MAIN_ERR_PREFIX.


Generated at 2024-04-27 using  doxygen