Establishing a Secure Connection

Before creating a secure link, you must first establish a regular outgoing TCP connection:

** Tibbo Basic **


sock.protocol=PL_SOCK_PROTOCOL_TCP     'Tibbo programmable devices do not support TLS over UDP
sock.targetip="192.168.1.1"            'Replace "192.168.1.1" with the target server's IP address
sock.targetport=443                    'Replace 443 with the desired port
sock.txbuffrq(2)                       'While not strictly necessary, increasing the TX and RX 
sock.rxbuffrq(2)                       'buffers to 2 significantly improves performance
sys.buffalloc                          'Only needed if manually setting buffer sizes,
                                       'including sock.tlsbuffrq
sock.connect()

Before proceeding, it's a good idea to verify that your normal, unencrypted connection has been established. For more details, see Checking Connection Status. Creating a secure link will fail if you're not already connected.

Next, call sock.tlsinit to initialize the TLS connection (you can also do this before establishing an outgoing TCP connection). This is where the encryption certificate you added to the project comes into play — sock.tlsinit parses the certificate and, if the offset is correct, loads it into memory.

** Tibbo Basic **


romfile.open("example.cer")     'Replace "example.cer" with the name of the certificate 
                                'included in your project
sock.tlsinit(romfile.offset) 

As only one encrypted connection can be maintained at any given time, attempting to establish a new secure connection while one is already in progress will fail. The sock.tlscurrentnum read-only property can tell you on which socket, if any, TLS has been initialized (i.e., sock.tlsinit has been called successfully). This property will return 255 if no socket is currently configured for TLS.

To make sure that sock.tlsinit is executed, examine the status code returned by this method:

** Tibbo Basic **


select case sock.tlsinit(romfile.offset)
     case PL_TLS_SUCCESS:
          'Initialization was completed successfully
     case PL_TLS_REJECTED
          'Initialization attempt was rejected 
          '(TLS has already been initialized on the current socket)
     case PL_TLS_ERROR_IN_USE
          'TLS resources tied to another socket
     case PL_TLS_ERROR_CERT
          'Certificate error
          '(not a X.509 certificate or not a supported cypher suite)
     case PL_TLS_ERROR_NO_BUFF
          'Insufficient memory
     case PL_TLS_ERROR_INTERNAL 
          'Unspecified internal error — please contact Tibbo support
end select

Once TLS has been initialized and an outgoing TCP connection has been established, you can call sock.tlshandshake to enable the encryption on the selected socket. This method takes a single parameter, a string that should contain the fully qualified domain name of your desired remote server (i.e., everything after "https://" up to the first forward slash). If you do not want to verify the server name against the certificate, pass an empty string — this is useful when connecting directly to an IP address.

Attempting to call sock.tlshandshake on a socket other than the one on which sock.tlsinit was executed will fail, with a return of PL_TLS_ERROR_IN_USE.

Additionally, calling sock.tlshandshake will result in PL_TLS_REJECTED in the following scenarios:

  • The selected protocol is not TCP (sock.protocol <> PL_SOCK_PROTOCOL_TCP)
  • The TCP connection is not an outgoing connection (sock.state <> PL_SST_EST_AOPENED)
  • sock.tlsinit has not been executed on any socket (sock.tlscurrentnum = 255)

** Tibbo Basic **


select case sock.tlshandshake("your.example.com")
          'Replace "your.example.com" with the domain name of the desired server
     case PL_TLS_SUCCESS:
          'All good!
     case PL_TLS_REJECTED:
          'Many possible reasons (see above)
     case PL_TLS_ERROR_IN_USE:
          'TLS is already happening on some other socket
end select

Even if sock.tlshandshake returns PL_TLS_SUCCESS, the creation of the secure connection may still fail due to a number of reasons described below. The final and definitive indicator of the successful establishment of the TLS link is the transition of sock.state into PL_SST_EST_TLS. As always, sock.state transitions are asynchronous, so respond within the on_sock_event handler while also anticipating a possible timeout (for example, by counting the elapsed time in the on_sys_timer event handler).

Troubleshooting the handshake

The following reasons may be the cause of the TLS link establishment failure after sock.tlshandshake returns PL_TLS_SUCCESS:

Possible issue

Troubleshooting steps

An invalid domain was passed as the parameter for sock.tlshandshake

  • Verify that you are using the correct certificate for the domain being passed
  • Try passing an empty string (bypassing internal verification of the certificate)

There is something wrong with the certificate presented to the remote host

There is something wrong with the data received from the remote host during the handshake

  • Clear the TX and RX buffers before attempting to initiate a handshake

Additional considerations

note_tip-wtAfter sock.tlshandshake is executed, your code must refrain from using sock.setdata, sock.getdata, and sock.rxclear on this socket (sock.txclear is not listed because it doesn't work when the socket is not idle). When in TLS mode, TiOS manipulates the data flowing through TX and RX buffers automatically. Attempting to "manually" extract anything from (or clear) the RX buffer or put anything into the TX buffer will disturb the flow of data as directed by TiOS' built-in TLS mechanism. Doing so will render your secure connection unusable.

To avoid interfering with the TLS operation, also DO NOT enable:

Additionally, after you switch into secure communications, a few sock. object properties and methods will "stop making sense." Again, this is because of the automated handling of TX and RX buffers in the TLS mode and because the encrypted data is sent and received in blocks. As an example of the implications of this, consider that a single data byte placed into the TLS TX buffer may result in a 2048-byte block of encrypted data appearing in the TX buffer! The properties and methods that will "stop making sense" are: sock.newtxlen, sock.peekdata, sock.rxlen, sock.txfree, and sock.txlen.

After a successful handshake, the device will enter the PL_SST_EST_TLS state of the sock.state property, signifying that a link has been established. You can now send and receive encrypted data.