SharkSSL™ Embedded SSL/TLS Stack
The SharkSSL API

Connect your application with TLS

SharkSSL is a C library for adding Transport Layer Security (TLS) to embedded clients and servers. Use it to protect the connection between a device and a service, or between a browser and a device. TLS encrypts application data, detects changes made in transit, and supports checking who is at the other end of the connection.

You keep control of the network interface. SharkSSL processes TLS data; your application sends and receives the bytes through its TCP/IP stack or another reliable, ordered transport. This separation lets you use blocking sockets, an event-driven network stack, or a bare-metal system.

Start here

Your next task Read
Run a client or server example Example programs
Use a supported socket interface SharkSSL Example Library (selib)
Integrate a callback-based network stack Transport-independent API
Choose certificates and trusted authorities Certificate management
Connect devices to a service you control Certificate management for IoT
Reduce code and memory use Build configuration
Select processor-specific crypto code Ports

What happens when you connect?

A TLS connection begins with a handshake. The peers agree on protocol settings and establish shared traffic keys. In a certificate-based connection, the server also proves that it holds the private key for its certificate. The client checks whether it trusts that identity. A server can request a client certificate when the application needs mutual authentication.

After the handshake, TLS protects application data in records. A record is a unit of encrypted data with integrity protection. Your application still uses its own protocol, such as HTTP or MQTT, inside the TLS connection.

Encryption and trust are separate checks. Before sending sensitive data, a client must accept the server's certificate and verify the expected server name. A completed handshake alone does not establish that the application has connected to the intended service. See SharkSslCon_trusted and certificate management.

The API retains SSL in its names. This guide uses TLS for the protocol; the current configuration provides TLS 1.2 and TLS 1.3 through SHARKSSL_TLS_1_2 and SHARKSSL_TLS_1_3.

Example Socket Library

Start with selib when its socket interface fits your platform. It connects the SharkSSL core to the network stack and provides seSec_handshake, seSec_read, and seSec_write. Study a complete example to see how the application handles trust results and connection errors.

Bare-Metal Environments

An operating system is not required by the SharkSSL core. With a callback-based network stack, keep one TLS connection object and its pending input/output state for each network connection.

The normal selib socket path uses blocking calls. Bare-metal systems can also use a suitable selib port together with the Socket Context Manager SeCtx. See the bare-metal API, the arch directory, and the raw lwIP port for that integration model.

Transport Agnostic API

(How to use the SharkSSL Transport Agnostic API)

SharkSSL is implemented in standard ANSI C; however, the SharkSSL API uses an object oriented design inherited from the Barracuda Web Server. An introduction to how this API works can be found in our online Barracuda Web Server manual. The API is designed such that it maps easily to C++, and the SharkSSL header files include an inline wrapper API for C++, which is activated when you include the SharkSSL headers in a C++ file.

A typical SharkSSL powered application starts by creating one SharkSsl instance (object). The SharkSsl instance is used as a place holder for SharkSslCon objects and includes information such as if the instance is used as an SSL server or an SSL client. The SharkSsl instance also includes information on the certificates you have loaded. A SharkSslCon object is created, by calling function SharkSsl_createCon, for each network (socket) connection created by your client or server network program.

Figure 1 shows the relation between one SharkSsl object and three spawned SharksslCon objects.

A SharkSslCon object provides an input buffer and an output buffer. These buffers can be used for creating a zero copy API for your network program. The size of the input and output buffer is specified when you create the SharkSsl instance. The input buffer is designed such that it can dynamically grow if it is not sufficiently large enough for the incoming message. TLS record processing needs sufficient buffer space for the incoming record. Small application messages do not imply that the handshake or received records will be equally small. In addition, the input buffer must be able to store the received certificate received from the peer side. Certificates can be large, especially chained certificates.

The following code snippet shows how to create a SharkSslCon instance after you have created a new socket connection. Function createNewSocket is a fictitious function that creates a handle to some type of network connection, either a client or server connection.

/* Illustration only: check both allocations before using the connection. */
int sock = createNewSocket();
SharkSslCon *s = SharkSsl_createCon(ssl); /* ssl is a SharkSsl instance */
SharkSslCon * SharkSsl_createCon(SharkSsl *o)
Create a SharkSslCon object.
struct SharkSslCon SharkSslCon
SharkSslCon is an opaque handle returned by function SharkSsl_createCon.
Definition: SharkSSL.h:493

Some protocols such as HTTPS start directly with secure communication, and others are upgraded after some initial handshaking. SharkSSL supports both methods. You start using the SharkSSL API when you are ready to start a secure communication link.

The handshake establishes the keys used to protect application data; private keys are not sent across the connection. SharkSSL maintains the handshake and record-processing state in SharkSslCon.

Drive the connection from the returned state

Call SharkSslCon_decrypt with the number of new bytes placed in its input buffer. Its return value tells your application what to do next.

State Application action
SharkSslCon_NeedMoreData Receive bytes into SharkSslCon_getBuf, within the capacity returned by SharkSslCon_getBufLen. Handle network closure and errors before passing a length to SharkSSL.
SharkSslCon_Handshake Send pending handshake data obtained from SharkSslCon_getHandshakeData and SharkSslCon_getHandshakeDataLen. Report the actual bytes sent with SharkSslCon_setHandshakeDataSent. Continue processing with no new input.
SharkSslCon_Decrypted Consume the application data using the documented decrypted-data API. Check SharkSslCon_decryptMore before waiting for another network read.

This table describes the main data path, not every return value. Handle alerts, allocation failures, and the remaining states documented in the core API. Network writes can be partial, so retain unsent output until the transport accepts it.

For complete control-flow examples, read the implementations of seSec_handshake, seSec_read, and seSec_write in selib.c. Use these functions directly when selib fits your platform. If you write an adapter, keep the same error handling and trust checks rather than copying a shortened handshake loop.

Event Driven TCP/IP Stack

If you are using an event driven TCP/IP stack that is callback based, keep state between callbacks. Retain the SharkSslCon object, the number of newly received bytes, and any pending output in your connection state. Resume processing when the network callback reports that input or output can proceed.

See the SharkSSL core API for details.