This package includes the SharkSSL lite library and header files.
Dependents: WebSocket-Client-Example SharkMQ-LED-Demo
SharkSSL-Lite
Description: SharkSSL is an SSL v3.0 TLS v1.0/1.1/1.2 implementation of the TLS and SSL protocol standard. With its array of compile-time options and Raycrypto proprietary cryptographic algorithms, SharkSSL can be fine-tuned to a footprint that occupies less than 20 kB, while maintaining full x.509 authentication. The SharkSSL-Lite download includes a subset of SharkSSL and header files made for use in non-commercial and for evaluation purposes.
Features
- SSL|TLS v1.2
- Size: 21kB
- Encryption: Elliptic Curve Cryptography (ECC) | ChaCha20/Poly1305
- SharkSSL Online Documentation
- SMQ (Simple Message Queues) Client and SMQ Documentation
- Secure WebSocket Client
- Secure MQTT Client
Examples
- SharkMQ LED Demo: Secure control of LEDs on your mbed board using a browser.
- WebSocket Client: Connect to ELIZA the Psychotherapist
Limitations
SharkSSL-Lite includes a limited set of ciphers. To use SharkSSL-Lite, the peer side must support Elliptic Curve Cryptography (ECC) and you must use ECC certificates. The peer side must also support the new ChaCha20/Poly1305 cipher combination.
ChaCha20 and Poly1305 for TLS is published RFC 7905. The development of this new cipher was a response to many attacks discovered against other widely used TLS cipher suites. ChaCha20 is the cipher and Poly1305 is an authenticated encryption mode.
SharkSSL-Lite occupies less than 20kB, while maintaining full x.509 authentication. The ChaCha20/Poly1305 cipher software implementation is equally as fast as many hardware accelerated AES engines.
Creating ECC Certificates for SharkSSL-Lite
The following video shows how to create an Elliptic Curve Cryptography (ECC) certificate for a server, how to install the certificate in the server, and how to make the mbed clients connecting to the server trust this certificate. The server in this video is installed on a private/personal computer on a private network for test purposes. The video was produced for the embedded.com article How to run your own secure IoT cloud server.
Diff: inc/SharkMQ.h
- Revision:
- 0:e0adec41ad6b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/SharkMQ.h Wed Apr 06 00:46:36 2016 +0000 @@ -0,0 +1,422 @@ +/* + * ____ _________ __ _ + * / __ \___ ____ _/ /_ __(_)___ ___ ___ / / ____ ____ _(_)____ + * / /_/ / _ \/ __ `/ / / / / / __ `__ \/ _ \/ / / __ \/ __ `/ / ___/ + * / _, _/ __/ /_/ / / / / / / / / / / / __/ /___/ /_/ / /_/ / / /__ + * /_/ |_|\___/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_____/\____/\__, /_/\___/ + * /____/ + * + **************************************************************************** + * HEADER + * + * This file is part of SharkMQ: + * https://realtimelogic.com/products/simplemq/ + * + * $Id: SharkMQ.h 3635 2014-12-31 03:39:41Z wini $ + * + * COPYRIGHT: Real Time Logic LLC, 2014 + * + * This software is copyrighted by and is the sole property of Real + * Time Logic LLC. All rights, title, ownership, or other interests in + * the software remain the property of Real Time Logic LLC. This + * software may only be used in accordance with the terms and + * conditions stipulated in the corresponding license agreement under + * which the software has been supplied. Any unauthorized use, + * duplication, transmission, distribution, or disclosure of this + * software is expressly forbidden. + * + * This Copyright notice may not be removed or modified without prior + * written consent of Real Time Logic LLC. + * + * Real Time Logic LLC. reserves the right to modify this software + * without notice. + * + * http://sharkssl.com + **************************************************************************** + * + */ + +#ifndef __SharkMQ_h +#define __SharkMQ_h + +#include "selib.h" + +/** @addtogroup SMQLib +@{ +*/ + +/** \defgroup SharkMQErrorCodes Error codes returned by function SharkMQ_getMessage +\ingroup SharkMQ +\anchor SharkMQErrorCodes Error codes returned by function #SharkMQ_getMessage +@{ +*/ + +/** The buffer provided in SharkMQ_constructor is not sufficiently large. + */ +#define SMQE_BUF_OVERFLOW -10000 + +/** The URL provided is invalid. + */ +#define SMQE_INVALID_URL -10002 + +/** TCP connection error + */ +#define SMQE_PROTOCOL_ERROR -10003 + +/** Server sent a disconnect message + */ +#define SMQE_DISCONNECT -10004 + + +/** No PONG response to PING: timeout + */ +#define SMQE_PONGTIMEOUT -10005 + + +/** The SharkMQ_getMessage call timed out. + */ +#define SMQE_TIMEOUT -10100 + + +/** @} */ /* end SharkMQErrorCodes */ + + +/** \defgroup SharkMQRespCodes Response codes returned by function SharkMQ_getMessage +\ingroup SharkMQ +\anchor SharkMQRespCodes Response codes returned by function #SharkMQ_getMessage +@{ +*/ + +/** Asynchronous #SharkMQ_subscribe response message received via + #SharkMQ_getMessage. + + \li SharkMQ::ptid is set to the subscribed Topic ID. + \li SharkMQ::status is set to zero (0) if the request was accepted and + a negative value if the request was denied. + \li the 'msg' out parameter in #SharkMQ_getMessage is set to the optional + server's authentication response message if the request was + denied. + */ +#define SMQ_SUBACK -20000 + +/** Asynchronous #SharkMQ_create response message received via + #SharkMQ_getMessage. + + \li SharkMQ::ptid is set to the created Topic ID. + \li SharkMQ::status is set to zero (0) if the request was accepted and + a negative value if the request was denied. + \li the 'msg' out parameter in #SharkMQ_getMessage is set to the optional + server's authentication response message if the request was + denied. + */ +#define SMQ_CREATEACK -20001 + +/** Asynchronous #SharkMQ_createsub response message received via + #SharkMQ_getMessage. + + \li SharkMQ::ptid is set to the created Sub Topic ID. + \li SharkMQ::status is set to zero (0) if the request was accepted and + a negative value if the request was denied. + */ +#define SMQ_CREATESUBACK -20002 + +/** Change notification event (from observed tid). Observe events are + * initiated via #SharkMQ_observe. + + \li SharkMQ::ptid is set to the observed Topic ID. + \li SharkMQ::status is set to the number of clients subscribed to the topic. + */ +#define SMQ_SUBCHANGE -20003 + +/** @} */ /* end SharkMQRespCodes */ + + +#define SMQSTR(str) str, (sizeof(str)-1) + +/** SharkMQ structure. + */ +typedef struct +{ + SOCKET sock; + SharkSslCon* scon; + + U8* sharkBuf; /* SharkSSL read buffer is set when we have data from Shark */ + U16 sharkBufLen; /* Received payload len */ + U16 sharkBufIx; /* Current read index in sharkBuf */ + + U8* recBuf; /*Buffer provided by the application and set in the constructor*/ + /* 'buf' is managed internally and is either the internal Shark + recv-buf or (recBuf). + */ + U8* buf; /**< The buffer provides an [out] param for a few methods. */ + + /** Timeout in milliseconds to wait in functions waiting for server + data + */ + U32 timeout; + S32 pingTmoCounter,pingTmo; + U32 clientTid; /**< Client's unique topic ID */ + U32 tid; /**< Topic: set when receiving MSG_PUBLISH from broker */ + U32 ptid; /**< Publisher's tid: Set when receiving MSG_PUBLISH from broker */ + U32 subtid; /**< Sub-tid: set when receiving MSG_PUBLISH from broker */ + int status; /**< Last known error code */ + U16 recBufLen; + U16 sendBufIx; + U16 frameLen; /**< The SimpleMQ frame size for the incomming data */ + /** Read frame data using SharkMQ_getMessage until: frameLen-bytesRead = 0 */ + U16 bytesRead; +} SharkMQ; + +/** Create a SimpleMQ client instance. + \param o Uninitialized data of size sizeof(SharkMQ). + \param buf is used for internal management and must not be less + than 127 bytes and not smaller than the largest control + frame. Function SharkMQ_getMessage will return #SMQE_BUF_OVERFLOW if + the buffer is not sufficiently large. + \param bufLen buffer length. + */ +void SharkMQ_constructor(SharkMQ* o, U8* buf, U16 bufLen); + +/** Bare metal configuration. This macro must be called immediately + after calling the constructor on bare metal systems. + \param o the #SharkMQ instance. + \param ctx an #SeCtx instance. + */ +#define SharkMQ_setCtx(o, ctx) SOCKET_constructor(&(o)->sock, ctx) + +/** Initiate the SharkMQ server connection. The connection phase is + divided into two steps: (1) initiating and (2) connecting via + SharkMQ_connect. + \param o the SharkMQ instance. + \param scon SharkSslCon instance created by calling #SharkSsl_createCon. + \param url is a URL that starts with http:// and this URL + must be to a server resource that initiates a SimpleMQ connection. + \param rnd (out param) a random number created by the server. This + number can be used for securing hash based password encryption. + \return + + - The return value is #SharkSslConTrust for any return value + greater than zero. + - A negative return value is one of: an error code from #se_connect, or + a [SimpleMQ error code](\ref SharkMQErrorCodes). + + A return value greater than zero means that a connection is + established, but the connection is not trusted unless the return + value is #SharkSslConTrust_CertCn. + + On success, SharkMQ::buf is set to the IP address of the client as + seen by the broker. + */ +int SharkMQ_init(SharkMQ* o, SharkSslCon* scon, const char* url, U32* rnd); + +/** Connect/establish a persistent SimpleMQ connection. The connection + phase is divided into two steps: (1) initiating via SharkMQ_init and (2) + connecting. + \param o the SharkMQ instance. + \param uid a universally unique client identifier (uid) must be + unique across all clients connecting to the same broker + instance. The uid is preferably a stringified version of the + client's Ethernet MAC address. + \param uidLen the uid length. + \param credentials provide credentials if required by the broker instance. + \param credLen credentials length. + \param info a string that provides information to optional server + code interacting with the broker. This string is also passed into + the optional broker's authentication callback function. + \param infoLen length of info. + \returns 0 on success, error code from TCP/IP stack, + [SimpleMQ error code](\ref SharkMQErrorCodes), or one of the + following error codes from the broker: + + \li 0x01 Connection Refused: unacceptable protocol version + \li 0x02 Connection Refused: server unavailable + \li 0x03 Connection Refused: Incorrect credentials + \li 0x04 Connection Refused: Client certificate required + \li 0x05 Connection Refused: Client certificate not accepted + \li 0x06 Connection Refused: Access denied + + The broker may optionally send a human readable string in addition + to the above broker produced error codes. This string is avaiable + via SharkMQ::buf. + */ +int SharkMQ_connect(SharkMQ* o, const char* uid, int uidLen, + const char* credentials, U8 credLen, + const char* info, int infoLen); + + +/** Gracefully close the connection. You cannot publish any messages + after calling this method. + \param o the SharkMQ instance. + */ +void SharkMQ_disconnect(SharkMQ* o); + + +/** Terminate a SimpleMQ instance. + \param o the SharkMQ instance. + */ +void SharkMQ_destructor(SharkMQ* o); + + +/** Create a topic an fetch the topic ID (tid). The SharkMQ protocol is + optimized and does not directly use a string when publishing, but a + number. The server randomly a creates 32 bit number and + persistently stores the topic name and number. + + The response to SharkMQ_create is asynchronous and returned as status + #SMQ_CREATEACK via #SharkMQ_getMessage. + + \param o the SharkMQ instance. + \param topic the topic name where you plan on publishing messages. + */ +int SharkMQ_create(SharkMQ* o, const char* topic); + + +/** Create a sub-topic and fetch the subtopic ID. + + The response to SharkMQ_subscribe is asynchronous and returned as status + #SMQ_CREATESUBACK via #SharkMQ_getMessage. + + \param o the SharkMQ instance. + \param subtopic the sub-topic name you want registered. + */ +int SharkMQ_createsub(SharkMQ* o, const char* subtopic); + + +/** Subscribe to topic. + + The response to SharkMQ_subscribe is asynchronous and returned as status + #SMQ_SUBACK via #SharkMQ_getMessage. + + \param o the SharkMQ instance. + \param topic the topic name to subscribe to. + */ +int SharkMQ_subscribe(SharkMQ* o, const char* topic); + + +/** Requests the broker to unsubscribe the client from a topic. + \param o the SharkMQ instance. + \param tid the topic name's Topic ID. + */ +int SharkMQ_unsubscribe(SharkMQ* o, U32 tid); + + +/** Publish messages to a topic and optionally to a sub-topic. Topic + name must have previosly been been resolved by #SharkMQ_create and + sub-topic should preferably have been created by #SharkMQ_createsub. + \param o the SharkMQ instance. + \param data message payload. + \param len payload length. + \param tid the topic ID (created with SharkMQ_create). + \param subtid optional sub-topic ID preferably created with SharkMQ_createsub. + */ +int SharkMQ_publish(SharkMQ* o, const void* data, int len, U32 tid, U32 subtid); + + +/** Publish a message in chunks and request the broker to assemble the + message before publishing to the subscriber(s). This method uses + the internal SharkSSL send buffer and sends the message as a chunk + when the internal buffer is full, thus sending the message as an + incomplete message to the broker. The message is assembled by the + broker when you flush the remaining bytes in the buffer by calling + #SharkMQ_pubflush. + + \param o the SharkMQ instance. + \param str a string. + */ +int SharkMQ_wrtstr(SharkMQ* o, const char* str); + +/** Publish a message in chunks and request the broker to assemble the + message before publishing to the subscriber(s). This method uses + the internal SharkSSL send buffer and sends the message as a chunk + when the internal buffer is full, thus sending the message as an + incomplete message to the broker. The message is assembled by the + broker when you flush the remaining bytes in the buffer by calling + #SharkMQ_pubflush. + + + \param o the SharkMQ instance. + \param data message payload. + \param len payload length. + */ +int SharkMQ_write(SharkMQ* o, const void* data, int len); + +/** Flush the internal buffer and request the broker to assemble all + stored fragments as one message. This message is then published to + topic 'tid', and sub-topic 'subtid'. + + \param o the SharkMQ instance. + \param tid the topic ID (created with SharkMQ_create). + \param subtid optional sub-topic ID preferably created with SharkMQ_createsub. + + Example: + \code + SharkMQ_wrtstr(smq, "Hello"); + SharkMQ_wrtstr(smq, " "); + SharkMQ_wrtstr(smq, "World"); + SharkMQ_pubflush(smq,tid,subtid); + \endcode + + */ +int SharkMQ_pubflush(SharkMQ* o, U32 tid, U32 subtid); + + +/** Request the broker to provide change notification events when the + number of subscribers to a specific topic changes. Ephemeral topic + IDs can also be observed. The number of connected subscribers for + an ephemeral ID can only be one, which means the client is + connected. Receiving a change notification for an ephemeral ID + means the client has disconnected and that you no longer will get + any change notifications for the observed topic ID. + + Change notification events are received as #SMQ_SUBCHANGE via + #SharkMQ_getMessage. + + \param o the SharkMQ instance. + \param tid the Topic ID you which to observe. + */ +int SharkMQ_observe(SharkMQ* o, U32 tid); + + +/** Stop receiving change notifications for a topic ID or ephemeral topic ID. + \param o the SharkMQ instance. + \param tid the Topic ID you no longer want to observe. + */ +int SharkMQ_unobserve(SharkMQ* o, U32 tid); + + +/** Wait for messages sent from the broker. + \param o the SharkMQ instance. + \param msg a pointer to the response data (out param) + \returns + \li a negative value signals an + [error code](\ref SharkMQErrorCodes) or an + [asynchronous response code](\ref SharkMQRespCodes). + \li zero signals timeout. + \li a value greater than zero signals the reception of a full + message or a message fragment. See receiving large frames for details. + + <b>Receiving large frames:</b><br> + The SimpleMQ protocol is frame based, but the function can return + a fragment before the complete SimpleMQ frame is received if the + frame sent by the peer is larger than the provided buffer. The + frame length is returned in SharkMQ::frameLen and the data consumed + thus far is returned in SharkMQ::bytesRead. The complete frame is + consumed when frameLen == bytesRead. + + <b>Note:</b> the default timeout value is set to one minute. You + can set the timeout value by setting SharkMQ::timeout to the + number of milliseconds you want to wait for incoming messages + before the timeout triggers. Note: Setting a long timeout may + interfere with the built in PING timer. + */ +int SharkMQ_getMessage(SharkMQ* o, U8** msg); + + +/** Returns the message size, which is SharkMQ::frameLen - 15. + \param o the SharkMQ instance. + */ +#define SMQ_getMsgSize(o) + +/** @} */ /* end group SMQLib */ + +#endif