SWRU455M February 2017 – October 2020 CC3120 , CC3120MOD , CC3130 , CC3135 , CC3135MOD , CC3220MOD , CC3220MODA , CC3220R , CC3220S , CC3220SF , CC3230S , CC3230SF , CC3235MODAS , CC3235MODASF , CC3235MODS , CC3235MODSF , CC3235S , CC3235SF
When connecting a regular TCP socket to a peer, the TCP socket can be upgraded to a TLS socket by using the STARTTLS option, depending on the application layer of the other peer. To use STARTTLS, the other peer also must support such an upgrade. The upgrade is basically the initialization of a TLS handshake between the peers, while in a connected session.
The most common use case is the SMTP protocol, on port 587. The client connects to an SMTP server, several packets may transact unencrypted, and then the client initiates a STARTTLS request to the server (each application protocol has its own STARTTLS byte string, and therefore it should be sent by the host application). At this point the handshake starts with a GO AHEAD message sent by the server, responded to by a HELLO message from the client.
Calling sl_SetSockOpt with the STARTTLS option triggers the NWP, in client mode, to send the client HELLO message, and in server mode to wait until the client HELLO message is received. When the handshake is finished, the user gets a socket asynchronous event which indicates success or failure, and in case of failure, a specific error code.
Example:
void slcbSockEvtHdlr(SlSockEvent_t* pSlSockEvent)
{
char *CAname;
if(SL_SOCKET_ASYNC_EVENT == pSlSockEvent->Event)
{
/* debug print "an event received on socket %d\n",
pSlSockEvent->SocketAsyncEvent.SockAsyncData.Sd */switch(pSlSockEvent->SocketAsyncEvent.SockAsyncData.Type)
{
case SL_SSL_NOTIFICATION_CONNECTED_SECURED:
/* indicate handshake successful ok */break;
case SL_SSL_NOTIFICATION_HANDSHAKE_FAILED:
/* retrieve an error from pSlSockEvent->SocketAsyncEvent.SockAsyncData.Val; */break;
default:
break;
}
}
}
void ClientSTARTTLSExample()
{
SlSockAddrIn_t Addr;
SlSockSecureMethod_t method;
_i32 sd,len,dummyVar;
_i16 status;
_u32 DestinationIP = SL_IPV4_VAL(192,168,1,31); /* An SMTP server's IP */
_i16 AddrSize;
_i8 buf[100];
Addr.sin_family = SL_AF_INET;
Addr.sin_port = sl_Htons(587);
Addr.sin_addr.s_addr = sl_Htonl(DestinationIP);
AddrSize = sizeof(SlSockAddrIn_t);
/* Open TLS socket */
sd = sl_Socket(SL_AF_INET,SL_SOCK_STREAM,0);
if(sd < 0)
{
/* error... */
}
method.SecureMethod = SL_SO_SEC_METHOD_SSLv3_TLSV1_2;
status = sl_SetSockOpt(sd,SL_SOL_SOCKET,SL_SO_SECMETHOD,&method,sizeof(SlSockSecureMethod_t));
if(status < 0)
{
/* error... */
}
/* set a CA filename to be used to verify the SMTP server
certificate when the handshake will take place */
status = sl_SetSockOpt(sd,SL_SOL_SOCKET,SL_SO_SECURE_FILES_CA_FILE_NAME,
"smtpCa.der",strlen("smtpCa.der"));
if(status < 0)
{
/* error... */
}
status = sl_Connect(sd, ( SlSockAddr_t *)&Addr, AddrSize);
if(status < 0)
{
/* error... */
}
/* unsecured transaction */
len = sl_Recv(sd,buf,100,0);
if(len < 0)
{
/* error... */
}
len = sl_Send(sd,"Hello server",strlen("HELLO server"),0);
if(len < 0)
{
/* error... */
}
/*...
...
... */
len = sl_Send(sd,"STARTTLS",strlen("STARTTLS"),0);
if(len < 0)
{
/* error... */
}
len = sl_Recv(sd,buf,100,0);
if(len < 0)
{
/* error... */
}
if(strcmp(buf,"GO AHEAD") == 0)
{
/* we got a green light, we can start the TLS handshake */
status = sl_SetSockOpt(sd,SL_SOL_SOCKET,SL_SO_STARTTLS,&dummyVar,sizeof(dummyVar));
if(status < 0)
{
/* error... */
}
/* wait for the flag to update from slcbSockEvtHdlr async event
and handle it, if an error occurs
...
...
... */
}
/*...
...
... */
status = sl_Close(sd);
if(status < 0)
{
/* error... */
}
}