Secure Sockets TLS or SSL

If a network security module (such as Mocana - NanoSSL) is available, μC/TCP-IP socket security option APIs can be used to secure sockets. The port layer developed for the network security layer is responsible of securing the sockets and applying the security strategy over typical socket programming functions. From an application point of view, the usage of µC/TCP-IP network security manager is very simple. It requires few simple steps depending if the application is a server or a client. Basically, it provides APIs to install the required keying material and to set the secure flag on a specific socket:

The stack must have been configured to support Transport layer security in  net_cfg.h , see Transport Layer Security Configuration. Obviously TLS or SSL can used only with a TCP connection. Once the socket is configured as secure and the connections is established all the data transferred using standard socket API are automatically encrypted between the client and the server .

Server Sample

In order to achieve secure handshake connections, some keying material must be installed before performing any secure socket operation. The server needs to install a public key certificare / private key pair to send the the clients that wants to connect. Certificate and key can be delivered by a Certificate Authorities or can be generated using a tool such as Open SSL.

The following example demonstrates how to secure a server using a PEM certificate from a constant buffer.

#include  <Source/net_sock.h>
#include  <Source/net_app.h>
#include  <Source/net_util.h>
#include  <Source/net_bsd.h>

#define APP_CFG_SECURE_CERT                                      \
"MIIEEjCCAvqgAwIBAgIBBzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDEw9WYWxp\
Y29yZS1EQzEtQ0EwHhcNMTEwMzE4MTcwMTQyWhcNMjEwMzE1MTcwMTQyWjCBkDEL\
MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxHjAcBgNV\
BAoTFVZhbGljb3JlIFRlY2hub2xvZ2llczEhMB8GA1UEAxMYbGFuLWZ3LTAxLnZh\
bGljb3JlLmxvY2FsMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBsb2NhbGRvbWFpbjCC\
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALwGOahytiwshzz1s/ngxy1+\
+VrXZYjKSEzMYbJCUhK9xA5fz8pGtOZIXI+CasZPSbXv+ZDLGpSpeFnOL49plYRs\
vmTxg2n3AlZbP6pD9OPU8rmufsTvXAmQGxxIkdmWiXYJk0pbj+U698me6DKMV/sy\
3ekQaQC2I2nr8uQw8RhuNhhlkWyjBWdXnS2mLNLSan2Jnt8rumtAi3B+vF5Vf0Fa\
kLJNt45R0f5jjuab+qw4PKMZEQbqe0XTNzkxdD0XNRBdKlajffoZPBJ7xkfuKUA3\
cMjXKzetABoKvsv+ElfvqlrI9RXvTXy52EaQmVhiOyBHrScq4RbwtDQsd59Qmk0C\
AwEAAaOB6zCB6DAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDA0BglghkgB\
hvhCAQ0EJxYlRWFzeS1SU0EgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAd\
BgNVHQ4EFgQUrq5KF11M9rpKm75nAs+MaiK0niYwUQYDVR0jBEowSIAU2Q9eGjzS\
LZhvlRRKO6c4Q5ATtuChHqQcMBoxGDAWBgNVBAMTD1ZhbGljb3JlLURDMS1DQYIQ\
T9aBcT0uXoxJmC0ohp7oSTATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMC\
BaAwDQYJKoZIhvcNAQEFBQADggEBAAUMm/9G+mhxVIYK4anc34FMqu88NQy8lrh0\
loNfHhIEKnerzMz+nQGidf+KBg5K5U2Jo8e9gVnrzz1gh2RtUFvDjgosGIrgYZMN\
yreNUD2I7sWtuWFQyEuewbs8h2MECs2xVktkqp5KPmJGCYGhXbi+zuqi/19cIsly\
yS01kmexwcFMXyX4YOVbG+JFHy1b4zFvWgSDULj14AuKfc8RiZNvMRMWR/Jqlpr5\
xWQRSmkjuzQMFavs7soZ+kHp9vnFtY2D6gF2cailk0sdG0uuyPBVxEJ2meifG6eb\
o3FQzdtIrB6oMFHEU00P38SJq+mrDItPDRXNLa2Nrtc1EJtmjws="

#define APP_CFG_SECURE_KEY                                       \
"MIIEogIBAAKCAQEAvAY5qHK2LCyHPPWz+eDHLX75WtdliMpITMxhskJSEr3EDl/P\
yka05khcj4Jqxk9Jte/5kMsalKl4Wc4vj2mVhGy+ZPGDafcCVls/qkP049Tyua5+\
xO9cCZAbHEiR2ZaJdgmTSluP5Tr3yZ7oMoxX+zLd6RBpALYjaevy5DDxGG42GGWR\
bKMFZ1edLaYs0tJqfYme3yu6a0CLcH68XlV/QVqQsk23jlHR/mOO5pv6rDg8oxkR\
Bup7RdM3OTF0PRc1EF0qVqN9+hk8EnvGR+4pQDdwyNcrN60AGgq+y/4SV++qWsj1\
Fe9NfLnYRpCZWGI7IEetJyrhFvC0NCx3n1CaTQIDAQABAoIBAEbbqbr7j//RwB2P\
EwZmWWmh4mMDrbYBVYHrvB2rtLZvYYVxQiOexenK92b15TtbAhJYn5qbkCbaPwrJ\
E09eoQRI3u+3vKigd/cHaFTIS2/Y/qhPRGL/OZY5Ap6EEsMHYkJjlWh+XRosQNlw\
01zJWxbFsq90ib3E5k+ypdStRQ7JQ9ntvDAP6MDp3DF2RYf22Tpr9t3Oi2mUirOl\
piOEB55wydSyIhSHusbms3sp2uvQBYJjZP7eENEQz55PebTzl9UF2dgJ0wJFS073\
rvp46fibcch1L7U6v8iUNaS47GTs3MMyO4zda73ufhYwZLU5gL8oEDY3tf/J8zuC\
mNurr0ECgYEA8i1GgstYBFSCH4bhd2mLu39UVsIvHaD38mpJE6avCNOUq3Cyz9qr\
NzewG7RyqR43HsrVqUSQKzlAGWqG7sf+jkiam3v6VW0y05yqDjs+SVW+ZN5CKyn3\
sMZV0ei4MLrfxWneQaKy/EUTJMlz3rLSDM/hpJoA/gOo9BIFRf2HPkkCgYEAxsGq\
LYU+ZEKXKehVesh8rIic4QXwzeDmpMF2wTq6GnFq2D4vWPyVGDWdORcIO2BojDWV\
EZ8e7F2SghbmeTjXGADldYXQiQyt4Wtm+oJ6d+/juKSrQ1HIPzn1qgXDNLPfjd9o\
9lX5lGlRn49Jrx/kKQAPTcnCa1IirIcsmcdiy+UCgYBEbOBwUi3zQ0Fk0QJhb/Po\
LSjSPpl7YKDN4JP3NnBcKRPngLc1HU6lElny6gA/ombmj17hLZsia1GeHMg1LVLS\
NtdgOR5ZBrqGqcwuqzSFGfHqpBXEBl6SludmoL9yHUreh3QhzWuO9aFcEoNnl9Tb\
g9z4Wf8Pxk71byYISYLt6QKBgERActjo3ZD+UPyCHQBp4m45B246ZQO9zFYdXVNj\
gE7eTatuR0IOkoBawN++6gPByoUDTWpcsvjF9S6ZAJH2E97ZR/KAfijh4r/66sTx\
k26mQRPB8FHQvqv/kj3NdsgdUJJeeqPEyEzPkcjyIoJxuB7gN2El/I5wCRon3Qf9\
sQ6FAoGAfVOaROSAtq/bq9JIL60kkhA9sr3KmX52PnOR2hW0caWi96j+2jlmPT93\
4A2LIVUo6hCsHLSCFoWWiyX9pIqyYTn5L1EmeBO0+E8BH9F/te9+ZZ53U+quwc/X\
AZ6Pseyhj7S9wkI5hZ9SO1gcK4rWrAK/UFOIzzlACr5INr723vw="

#define  APP_CFG_SECURE_CERT_LEN      (sizeof(APP_CFG_SECURE_CERT) - 1)
#define  APP_CFG_SECURE_KEY_LEN       (sizeof(APP_CFG_SECURE_KEY)  - 1)

int  AppServerInit (void)
{
    NET_SOCK_ID         sock_id;
    NET_SOCK_ADDR_IPv4  addr_server_ip;
    NET_SOCK_ADDR_LEN   addr_len;
    NET_ERR             err;

                                                                /* -------------------- OPEN SOCK --------------------- */
    sock_id = NetApp_SockOpen(NET_SOCK_ADDR_FAMILY_IP_V4,
                              NET_SOCK_TYPE_STREAM,
                              NET_SOCK_PROTOCOL_TCP,
                              3,
                              5,
                              &err);
    switch (err) {
        case NET_APP_ERR_NONE:
             break;
        default:
             return (-1);
    }
                                                                /* --------------- CFG SOCK SECURE OPT----------------- */
   (void)NetSock_CfgSecure(sock_id,
                           DEF_YES,
                          &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }

   (void)NetSock_CfgSecureServerCertKeyInstall(sock_id,
                                               APP_CFG_SECURE_CERT,
                                               APP_CFG_SECURE_CERT_LEN,
                                               APP_CFG_SECURE_KEY,
                                               APP_CFG_SECURE_KEY_LEN,
                                               NET_SOCK_SECURE_CERT_KEY_FMT_PEM,
                                               DEF_NO,
                                              &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }

                                                                /* -------------------- BIND SOCK --------------------- */
    addr_len = sizeof(addr_server_ip);
    Mem_Set((void     *)&addr_server_ip,
            (CPU_INT08U) 0u,
            (CPU_SIZE_T) addr_len);
    addr_server_ip.AddrFamily = NET_SOCK_ADDR_FAMILY_IP_V4;
    addr_server_ip.Port       = NET_UTIL_HOST_TO_NET_16(12345);
    addr_server_ip.Addr       = NET_UTIL_HOST_TO_NET_32(INADDR_ANY);

   (void)NetApp_SockBind(                  sock_id,
                         (NET_SOCK_ADDR *)&addr_server_ip,
                                           addr_len,
                                           3,
                                           5,
                                          &err);
    switch (err) {
        case NET_APP_ERR_NONE:
            break;
        default:
            NetApp_SockClose(sock_id, 1, &err);
            return (-1);
    }

                                                                /* ------------------- LISTEN SOCK -------------------- */
   (void)NetApp_SockListen(sock_id, 1, &err);
    switch(err) {
        case NET_APP_ERR_NONE:
             break;
        default:
            NetApp_SockClose(sock_id, 1, &err);
            return (-1);
    }
    return (sock_id);
}


Client Sample

In order to achieve secure handshake connections, some keying material must be installed before performing any secure socket operation. The client side needs to install certificates authorities to validate the identity of the public key certificate sent by the server side. Certificates authorities can be found on the web site of Certificate authorities who delivered the Server's certificate ad key. As for the server's certificate it's possible to generate the CA certificate when generating self sign certificate-key pair using a tool such as OpenSSL. 


#include  <Secure/Mocana/net_secure_mocana.h>
#include  <Source/net_sock.h>
#include  <Source/net_app.h>
#include  <Source/net_ascii.h>
#include  <Source/net_util.h>
#include  <lib_str.h>
 
CPU_CHAR *p_cert =
                "MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT"
                "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
                "YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG"
                "EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg"
                "R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9"
                "9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq"
                "fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv"
                "iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU"
                "1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+"
                "bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW"
                "MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA"
                "ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l"
                "uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn"
                "Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS"
                "tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF"
                "PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un"
                "hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV"
                "5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==";
 
CPU_BOOLEAN  AppClientCertTrustCallBackFnct (void                             *p_cert_dn,
                                             NET_SOCK_SECURE_UNTRUSTED_REASON  reason);
 
int  AppClientConnect (void)
{
    NET_SOCK_ID         sock_id;
    NET_SOCK_ADDR_IPv4  addr_server;
    CPU_INT32U          len_addr_server;
    CPU_INT32U          len;
    NET_ERR             err;
                                                                /* -------------- INSTALL CA CERTIFICATE -------------- */
    len = Str_Len(p_cert);
    NetSecure_CA_CertIntall(p_cert, len, NET_SOCK_SECURE_CERT_KEY_FMT_PEM, &err);

    															/* ------------------ OPEN THE SOCKET ----------------- */
    sock_id = NetApp_SockOpen(NET_SOCK_ADDR_FAMILY_IP_V4,
                              NET_SOCK_TYPE_STREAM,
                              NET_SOCK_PROTOCOL_TCP,
                              3,
                              5,
                              &err);
    switch (err) {
        case NET_APP_ERR_NONE:
             break;
        default:
             return (-1);
    }
 
																/* --------------- CFG SOCK SECURE OPT----------------- */
   (void)NetSock_CfgSecure(sock_id,
                           DEF_YES,
                          &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }

    (void)NetSock_CfgSecureClientCommonName(sock_id,
                                           "domain_name.com",
                                           &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }

   (void)NetSock_CfgSecureClientTrustCallBack(sock_id,
                                             &AppClientCertTrustCallBackFnct,
                                             &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }
 
                                                                /* ------------- ESTABLISH TCP CONNECTION ------------- */
    Mem_Clr((void *)&addr_server, NET_SOCK_ADDR_SIZE);

    addr_server.AddrFamily = NetASCII_Str_to_IP((CPU_CHAR  *)"98.139.211.125",
                                                (void      *)addr_server.Addr,
                                                (CPU_INT08U )sizeof(addr_server.Addr),
                                                            &err);
    addr_server.Port       = NET_UTIL_HOST_TO_NET_16(12345);
    len_addr_server        = sizeof(addr_server);
    (void)NetApp_SockConn(                  sock_id,
                          (NET_SOCK_ADDR *)&addr_server,
                                            len_addr_server,
                                            3,
                                            5,
                                            5,
                                           &err);
    switch (err) {
        case NET_SOCK_ERR_NONE:
             break;
        default:
             NetApp_SockClose(sock_id, 1, &err);
             return (-1);
    }
    return (sock_id);
}
 
CPU_BOOLEAN  AppClientCertTrustCallBackFnct (void                             *p_cert_dn,
                                             NET_SOCK_SECURE_UNTRUSTED_REASON  reason)
{
    return (DEF_YES);
}