wolf SSL
/
Example-TLSClient
Simple TLS Client with wolfSSL
client-tls.cpp
- Committer:
- wolfSSL
- Date:
- 2020-06-05
- Revision:
- 108:85c8df586bdf
- Parent:
- 107:b989df522437
File content as of revision 108:85c8df586bdf:
/* client-tcp.c * * Copyright (C) 2006-2017 wolfSSL Inc. * * This file is part of wolfSSL. (formerly known as CyaSSL) * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "mbed.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <wolfssl/ssl.h> /* wolfSSL security library */ #include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/certs_test.h> /* memory image test certs */ #include <user_settings.h> #define MAXDATASIZE (1024*4) static int SocketReceive(WOLFSSL* ssl, char *buf, int sz, void *sock) { int recvd; recvd = ((TCPSocket *)sock)->recv(buf, sz) ; if(recvd > 0)return recvd; else if (recvd == 0) { return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else if (recvd == EWOULDBLOCK) /* for non-blocing */ return WOLFSSL_CBIO_ERR_WANT_READ; else return WOLFSSL_CBIO_ERR_GENERAL; } static int SocketSend(WOLFSSL* ssl, char *buf, int sz, void *sock) { int sent; sent = ((TCPSocket *)sock)->send(buf, sz); if(sent > 0)return sent; else if (sent == 0) { return WOLFSSL_CBIO_ERR_CONN_CLOSE; } else if (sent == EWOULDBLOCK) /* for non-blocing */ return WOLFSSL_CBIO_ERR_WANT_WRITE; else return WOLFSSL_CBIO_ERR_GENERAL; } static int getline(char *prompt, char *buff, int size) { int sz ; printf("%s", prompt) ; for(sz = 0 ; (sz < size) && ((*buff = getchar()) != '\r'); sz++, buff++) { putchar(*buff) ; if(*buff == '\\') { if(++sz >= size)break ; *buff = getchar() ; putchar(*buff) ; switch(*buff) { case 'n' : *buff = '\n' ; break ; case 'r' : *buff = '\r' ; break ; case 't' : *buff = '\t' ; break ; case '\\': *buff = '\\' ; break ; default: buff[1] = buff[0] ; buff[0] = '\\' ; buff++ ; } } else if(*buff == '\b') { if(sz >= 2) { buff-=2 ; sz-=2; } } } ; putchar('\n') ; *buff = '\0' ; return sz ; } /* * clients initial contact with server. Socket to connect to: sock */ int ClientGreet(TCPSocket *socket, WOLFSSL *ssl) { /* data to send to the server, data recieved from the server */ char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0}; int ret ; ret = getline("Message for server: ", sendBuff, MAXDATASIZE); printf("Send[%d]:\n%s\n", ret, sendBuff) ; if (wolfSSL_write(ssl, sendBuff, strlen(sendBuff)) < 0) { /* the message is not able to send, or error trying */ ret = wolfSSL_get_error(ssl, 0); printf("Write error[%d]\n", ret, wc_GetErrorString(ret)); return EXIT_FAILURE; } if ((ret = wolfSSL_read(ssl, rcvBuff, sizeof(rcvBuff)-1)) < 0) { /* the server failed to send data, or error trying */ ret = wolfSSL_get_error(ssl, 0); printf("Read error[%d], %s\n", ret, wc_GetErrorString(ret)); return EXIT_FAILURE; } rcvBuff[ret] = '\0' ; printf("Recieved: %s\n", rcvBuff); return ret; } /* * applies TLS 1.2 security layer to data being sent. */ int Security(TCPSocket *socket) { WOLFSSL_METHOD* method = 0; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; /* create WOLFSSL object */ int ret = 0; const unsigned char *cert = ca_cert_der_2048; int sizeof_cert = sizeof_ca_cert_der_2048; #ifdef WOLFSSL_TLS13 char tls_version[2]; int tlsVer = 0 ; while((tlsVer != 2) && (tlsVer != 3)){ getline("TLS ver(2/3): ", tls_version, sizeof(tls_version)) ; tlsVer = atoi(tls_version); } if(tlsVer == 3)method = wolfTLSv1_3_client_method(); else method = wolfTLSv1_2_client_method(); #else method = wolfTLSv1_2_client_method(); #endif /* create and initiLize WOLFSSL_CTX structure */ if ((ctx = wolfSSL_CTX_new(method)) == NULL) { printf("SSL_CTX_new error.\n"); return EXIT_FAILURE; } wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); wolfSSL_SetIORecv(ctx, SocketReceive) ; wolfSSL_SetIOSend(ctx, SocketSend) ; if ((ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1))!= WOLFSSL_SUCCESS){ printf("can't load buffer ca file(%d)\n", ret); return EXIT_FAILURE; } if ((ssl = wolfSSL_new(ctx)) == NULL) { printf("wolfSSL_new error.\n"); return EXIT_FAILURE; } wolfSSL_SetIOReadCtx(ssl, (void *)socket) ; wolfSSL_SetIOWriteCtx(ssl, (void *)socket) ; ret = wolfSSL_connect(ssl); if (ret == SSL_SUCCESS) { printf("TLS Connected\n") ; ret = ClientGreet(socket, ssl); } else { ret = wolfSSL_get_error(ssl, 0); printf("TLS Connect error[%d], %s\n", ret, wc_GetErrorString(ret)); return EXIT_FAILURE; } /* frees all data before client termination */ wolfSSL_shutdown(ssl); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); wolfSSL_Cleanup(); return ret; } /* * command line argumentCount and argumentValues */ void net_main(const void *av) { char server_addr[40] ; char server_port[10] ; NetworkInterface *net; SocketAddress a; TCPSocket socket; int port; printf("Starting TLS Client,...\n") ; wolfSSL_Init(); /* initialize wolfSSL */ /* wolfSSL_Debugging_ON(); */ net = NetworkInterface::get_default_instance(); if (!net) { printf("Error! No network inteface found.\n"); return; } while(1) { if(net->connect() == 0)break; printf("Retry Init\n") ; } net->get_ip_address(&a); printf("Client Addr: %s\n", a.get_ip_address() ? a.get_ip_address() : "None"); getline((char *)"Server Addr: ", server_addr, sizeof(server_addr)) ; getline((char *)"Server Port: ", server_port, sizeof(server_port)) ; if (socket.open(net) != 0) { printf("Error! socket.open()\n"); } port = atoi(server_port); while (socket.connect(server_addr, port) < 0) { printf("Unable to connect to (%s) on port (%s)\n", server_addr, server_port); wait(1.0); } printf("TCP Connected\n") ; Security(&socket); return ; } int main(void) { DigitalOut myled(LED1); #define STACK_SIZE 24000 Thread t(net_main, NULL, osPriorityNormal, STACK_SIZE); while(1){ myled = 1; wait(0.5) ; myled = 0; wait(0.5) ; } }