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

Examples

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.

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