ThingWorx Edge C SDK > How to Set Up Security > Setting Up Secure Connections
Setting Up Secure Connections
By default the C SDK is set up to ensure the most secure connection possible, using the OpenSSL libraries. As of release 2.2.5, the C SDK upgraded to OpenSSL 1.1.1. Version 2.2.12 of the C SDK upgrades to OpenSSL 1.1.1j. OpenSSL 1.1.1 does not support FIPS mode, and is not backwards compatible to OpenSSL 1.0.2. FIPS mode requires OpenSSL 1.0.2 or earlier. For more information, refer to the ThingWorx Edge SDKs Support Matrix.
For the most secure connection, set the issuer and subject fields of your server certificates before starting the connection by using the twApi_SetX509Fields() function. These settings mean that the server will attempt to validate certificates and reject self-signed certificates.
Several functions are available to modify the default behavior and may provide some level of convenience during development, such as allowing self-signed certificates. The source file, twApi.h, defines these functions; they are as follows:
int twApi_SetProxyInfo(char * proxyHost, uint16_t proxyPort,
char * proxyUser, twPasswdCallbackFunction proxyPassCallback);
void twApi_SetSelfSignedOk();
void twApi_DisableCertValidation();
void twApi_DisableEncryption();
int twApi_SetX509Fields(char * subject_cn, char * subject_o, char * subject_ou,
char * issuer_cn, char * issuer_o, char * issuer_ou);
int twApi_LoadCACert(const char *file, int type);
int twApi_LoadClientCert(char *file);
int twApi_SetClientKey(const char *file, twPasswdCallbackFunction passphraseCallback, int type);
* 
The twApi_LoadCACert() function has a type argument that is NOT used. If you have used it, be aware that it is ignored at runtime.
In the twApi_SetProxyInfo() function, note that this function no longer takes a variable for the proxy password. Instead, it uses the output of the twPasswdCallbackFunction(). .In the twApi_SetClientKey() function, note that this function no longer takes a variable for the passphrase. Instead it uses the output of the twPasswdCallbackFunction(). For details, refer to Password Callback Functions (C SDK 2.2.0 and later).
* 
Although you may want to enable self-signed certificates for development purposes, it is a security best practice to disable self-signed certificates and set up the proper certificates before putting your application into production.
Enabling self-signed certificates using twApi_setSelfSignedOk() does not add a certificate to the certificate chain used for validation. Rather, it accepts self-signed certificate notification codes from OpenSSL.
TLS Host Name Validation 
As of v.2.2.9 of the C SDK, support is provided for TLS host name validation. This security feature compares the requested host name with subject identifiers in the server certificate, such as the subject common name (CN) and subject alternative names. If they do not match exactly, the TLS handshake will fail.
* 
Partial wildcards in the CN field of the host certificate are not currently supported in TLS host name validation. The host certificate must match the destination host name exactly. For example, a host certificate with CN=platform.domain.com can be validated, but CN=*.domain.com cannot. If your host is using certificates with wildcards, host name validation must be disabled.
TLS host name validation occurs during the TLS Handshake. With enable_tls_hostname_validation set to TRUE, if the host name on the server certificate does not match the host provided in twApi_Initialize() or twApi_InitializeWithProxy(), the TLS handshake fails, and the connection (twApi_Connect()) fails with the error, TW_SOCKET_INIT_ERROR. Check the logs of your application for an ERROR-level log message that notes the cause as host name validation failed.
twConfig
As of v.2.2.9 of the C SDK, the twConfig data structure in the file, twDefaultSettings.h, has a setting, called enable_tls_hostname_validation. Setting this to TRUE enables TLS host name validation. Setting it to FALSE disables host name validation. The default value is TRUE. Note that setting his value in the twDefaultSettings.h file means that the setting will be used for all applications written with the C DSDK, unless you change that value in your application before calling twApi_Initialize() or twApi_InitializeWithProxy(). The interfaces for making this change are described next.
twTlsClient
Two interfaces for twTlsClient allow you to override the twConfig setting, if you use twTlsClient separately from the C SDK public API. These interfaces are as follows:
twTlsClient_EnableTlsHostnameValidation(twTlsClient * t, char enabled) allows you to enable or disable TLS host name validation for the twTlsClient t.
twTlsClient_IsTlsHostnameValidationEnabled(twTlsClient * t) allows you to query the TLS host name validation setting for the twTlsClient t.
Structures and Functions Defined in twTLS.h 
The functions defined in twTLS.h can be used for any SSL/TLS connections that your application needs to make. These functions are the abstracted interfaces that sit on top of the underlying TLS implementation.
Consistent with the OpenSSL APIs, the C SDK uses a structure for an SSL/TLS context that manages all the SSL/TLS sessions, as well as a structure for an SSL/TLS session. In addition, the APIs expose several functions for operations. The definitions and functions are exposed with preprocessor definitions. For these details, refer to the Doxygen documentation provided with the SDK. The following table describes the structures and functions defined in twTLS.h.
Item
Description
TW_SSL_CTX
The SSL context structure as defined by the implementation.
TW_SSL
The SSL session structure as defined by the implementation.
TW_SSL_SESSION_ID_SIZE
The SSL session structure as defined by the implementation.
TW_SSL_SESSION_ID_SIZE
The size of an SSL session ID as defined by the implementation. This ID is used for session resumption.
TW_GET_CERT_SIZE
Returns the maximum number of certificates allowed by the implementation.
TW_GET_CA_CERT_SIZE
Returns the maximum number of CA certificates allowed by the implementation.
TW_NEW_SSL_CTX
Creates and initializes new instance of an SSL_CTX.
TW_NEW_SSL_CLIENT(a,b,c,d)
Creates and initializes a new instance of an SSL structure within the provided SSL_CTX.
Parameters:
a — pointer to a TW_SSL_CTX structure.
b — a TW_SOCKET_TYPE value that is the descriptor of the socket to be used. The underlying socket should not be opened before calling this function.
c — session id. The session ID if session resumption is being used. The SDK does not use session resumption and sets this to NULL.
d — size of the session ID that was passed in.
TW_HANDSHAKE_SUCCEEDED
Returns a Boolean (char) value, TRUE if the SSL handshake succeeded and data can be securely exchanged, FALSE if otherwise.
TW_SSL_FREE(a)
Close any socket and free up any memory associated with an SSL session.
Parameter:
a — pointer to the TW_SSL structure to free.
TW_SSL_CTX_FREE(a)
Free up any memory associated with an SSL context.
Parameter:
a — pointer to the TW_SSL_CTX structure to free.
TW_SSL_WRITE(a,b,c)
Writes data to the secure connection.
Parameters:
a — pointer to the TW_SSL structure to write to.
b — pointer to the buffer containing the data to write.
c — the amount of data to write.
This result of this macro should contain the number of bytes sent, or a negative number if an error occurred.
TW_SSL_READ(a, b, c, d)
Reads data from the secure connection.
Parameters:
a — pointer to the TW_SSL structure to read from.
b — pointer to the buffer that the data should be placed in.
c — the amount of data to read.
d — the number of milliseconds to wait while trying to read the desired amount of data.
This result of this macro should contain the number of bytes read, or a negative number if an error occurred.
TW_USE_CERT_FILE(a,b,c)
Loads an X509 certificate in PEM or DER format from the file specified.
Parameters:
a — pointer to the TW_SSL_CTX structure load the certificate into.
b — name of the file containing the certificate.
c — a password to access the certificate (if required).
TW_USE_KEY_FILE(a,b,c,d)
Loads an encrypted key in PEM or DER format from the file specified.
Parameters:
a — pointer to the TW_SSL_CTX structure to read from
b — name of the file containing the key
c — the type of key
d — a password to access the key.
TW_USE_CERT_CHAIN_FILE(a,b,c)
Loads a certificate chain in PEM or DER format from the file specified.
Parameters:
a — pointer to the TW_SSL_CTX structure load the certificate into.
b — name of the file containing the certificate chain.
c — a password to access the certificate (if required).
TW_SET_CLIENT_CA_LIST(a,b)
Sets the list of supported CAs from the file specified.
Parameters:
a — pointer to the TW_SSL_CTX structure load the certificate into.
b — pointer to the CA list.
TW_VALIDATE_CERT(TW_SSL * ssl, char selfSignedOk)
Inline function that validates the received certificate.
Parameters:
ssl — pointer to the TW_SSL structure that has received the certificate
selfSignedOk — boolean, set to TRUE if self-signed certificates are allowed, FALSE if not. Default is FALSE.
Returns zero if the certificate is valid, non-zero if not.
TW_GET_X509_FIELD(TW_SSL * ssl, char field)
Inline function that gets the value of a field in the certificate.
Parameters:
ssl — pointer to the TW_SSL structure that has received the certificate
fieldchar, the field to retrieve. Fields supported must be SUBJECT_CN, SUBJECT_O, SUBJECT_OU, ISSUER CN, ISSUER_O, ISSUER_OU
Returns the value of the field, or NULL if the field is not found.
Was this helpful?