Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MiniTLS-HTTPS-Example
tls_socket.c
00001 /* 00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices 00003 Author: Donatien Garnier 00004 Copyright (C) 2013-2014 AppNearMe Ltd 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 *//** 00020 * \file tls_socket.c 00021 * \copyright Copyright (c) AppNearMe Ltd 2013 00022 * \author Donatien Garnier 00023 */ 00024 00025 #define __DEBUG__ 4 00026 #ifndef __MODULE__ 00027 #define __MODULE__ "tls_socket.c" 00028 #endif 00029 00030 00031 #include "core/fwk.h" 00032 #include "inc/minitls_errors.h" 00033 00034 #include "tls_socket.h" 00035 00036 minitls_err_t tls_socket_init(tls_socket_t* socket, minitls_t* minitls, 00037 uint8_t* write_buffer, size_t write_buffer_size, uint8_t* read_buffer, size_t read_buffer_size) 00038 { 00039 socket->minitls = minitls; 00040 00041 socket->events = NULL; 00042 00043 socket->read_buffer = NULL; 00044 buffer_init(&socket->write_buffer, write_buffer, write_buffer_size); 00045 00046 socket->session.session_id_length = 0; 00047 00048 minitls_err_t ret = tls_record_init(&socket->record, socket, read_buffer, read_buffer_size); 00049 if(ret) 00050 { 00051 return ret; 00052 } 00053 00054 ret = tls_handshake_init(&socket->handshake, socket); 00055 if(ret) 00056 { 00057 return ret; 00058 } 00059 00060 return MINITLS_OK; 00061 } 00062 00063 minitls_err_t tls_socket_connect(tls_socket_t* socket, const char* hostname, uint16_t port, int timeout) 00064 { 00065 minitls_err_t ret = tls_record_connect(&socket->record, hostname, port); 00066 if(ret) 00067 { 00068 ERR("Could not connect"); 00069 return ret; 00070 } 00071 00072 //TODO we could allocate the handshake structure here to save memory 00073 00074 ret = tls_handshake_start(&socket->handshake); 00075 if(ret) 00076 { 00077 ERR("Could not start handshake"); 00078 return ret; 00079 } 00080 00081 //Now wait for handshake to finish processing (or fail) 00082 while(!tls_handshake_is_done(&socket->handshake)) 00083 { 00084 DBG("Handshaking..."); 00085 ret = tls_record_process(&socket->record); 00086 if(ret) 00087 { 00088 ERR("Processing error"); 00089 return ret; 00090 } 00091 } 00092 00093 DBG("Connected"); 00094 00095 return MINITLS_OK; 00096 } 00097 00098 void tls_socket_copy_session(tls_socket_t* to, tls_socket_t* from) 00099 { 00100 memcpy(&to->session, &from->session, sizeof(tls_session_t)); 00101 } 00102 00103 //Events API -- select like 00104 minitls_err_t tls_socket_event_list_init(tls_socket_event_list_t* list) 00105 { 00106 list->head = NULL; 00107 00108 //Create semaphore 00109 /* list->sem = rtos_sem_create(1, 0);*/ 00110 /*if(list->sem == NULL) 00111 { 00112 return TLS_ERR_MEMORY; 00113 }*/ //FIXME 00114 00115 return MINITLS_OK; 00116 } 00117 00118 minitls_err_t tls_socket_event_init_and_register(tls_socket_event_t* event, tls_socket_event_list_t* list, tls_socket_t* socket, bool read, bool write) 00119 { 00120 //Init event 00121 event->socket = socket; 00122 event->read = read; 00123 event->write = write; 00124 event->list = list; 00125 event->socket_list_next = NULL; 00126 event->event_list_next = NULL; 00127 00128 //Add to select list (tail) 00129 if(list->head != NULL) 00130 { 00131 tls_socket_event_t* previous_event = list->head; 00132 while( previous_event->event_list_next != NULL ) 00133 { 00134 previous_event = previous_event->event_list_next; 00135 } 00136 previous_event->event_list_next = event; 00137 } 00138 else 00139 { 00140 list->head = event; 00141 } 00142 00143 //Add to socket's event list (tail) 00144 if(socket->events != NULL) 00145 { 00146 tls_socket_event_t* previous_event = socket->events; 00147 while( previous_event->socket_list_next != NULL ) 00148 { 00149 previous_event = previous_event->socket_list_next; 00150 } 00151 previous_event->socket_list_next = event; 00152 } 00153 else 00154 { 00155 socket->events = event; 00156 } 00157 00158 return MINITLS_OK; 00159 } 00160 00161 minitls_err_t tls_socket_event_list_wait(tls_socket_event_list_t* list, int timeout) //All events unregistered at the end of wait, timeout in ms, -1 for infinite timeout 00162 {/* 00163 if( rtos_sem_get(list->sem, timeout) ) //FIXME 00164 {*/ 00165 return MINITLS_OK; 00166 /*} 00167 else 00168 { 00169 return TLS_ERR_TIMEOUT; 00170 }*/ 00171 } 00172 00173 //These calls are non-blocking 00174 minitls_err_t tls_socket_read(tls_socket_t* socket, uint8_t* bytes, size_t max_size, size_t* read_size) 00175 { 00176 DBG("Reading at most %d bytes", max_size); 00177 if(socket->read_buffer == NULL) //Socket is not ready 00178 { 00179 WARN("Socket is not ready or has been closed"); 00180 *read_size = 0; 00181 return MINITLS_OK; 00182 } 00183 00184 size_t length = buffer_length(socket->read_buffer); 00185 *read_size = MIN(max_size, length); 00186 00187 buffer_nbytes_read(socket->read_buffer, bytes, *read_size); 00188 00189 DBG("%d bytes read", *read_size); 00190 00191 //If buffer has been fully read, invalidate read_buffer 00192 if( buffer_length(socket->read_buffer) == 0 ) 00193 { 00194 socket->read_buffer = NULL; 00195 } 00196 00197 return MINITLS_OK; 00198 } 00199 00200 minitls_err_t tls_socket_write(tls_socket_t* socket, uint8_t* bytes, size_t size, size_t* written_size) 00201 { 00202 size_t length = buffer_space(&socket->write_buffer); 00203 *written_size = MIN(size, length); 00204 00205 buffer_nbytes_write(&socket->write_buffer, bytes, *written_size); 00206 00207 return MINITLS_OK; 00208 } 00209 00210 minitls_err_t tls_socket_flush_read(tls_socket_t* socket, int timeout) 00211 { 00212 DBG("Get new bytes"); 00213 if( socket->read_buffer != NULL ) //No need to read more bytes 00214 { 00215 WARN("Buffer is already non-empty"); 00216 return MINITLS_OK; 00217 } 00218 00219 tls_record_set_read_timeout(&socket->record, timeout); 00220 00221 int ret; 00222 do 00223 { 00224 DBG("Processing TLS packet"); 00225 ret = tls_record_process(&socket->record); 00226 if(ret) 00227 { 00228 return ret; 00229 } 00230 } while( socket->read_buffer == NULL ); 00231 00232 DBG("Buffer has been filled"); 00233 return MINITLS_OK; 00234 } 00235 00236 minitls_err_t tls_socket_flush_write(tls_socket_t* socket, int timeout) 00237 { 00238 if(buffer_length(&socket->write_buffer) == 0) 00239 { 00240 return MINITLS_OK; //Useless to flush 00241 } 00242 00243 tls_record_set_write_timeout(&socket->record, timeout); 00244 00245 //Pass buffer to record layer 00246 minitls_err_t ret = tls_record_send(&socket->record, TLS_APPLICATION_DATA, &socket->write_buffer); 00247 00248 //TODO: Advertise writeable here 00249 00250 if(ret) 00251 { 00252 return ret; 00253 } 00254 00255 return MINITLS_OK; 00256 } 00257 00258 //Called from record layer 00259 minitls_err_t tls_socket_readable_callback(tls_socket_t* socket, buffer_t* buffer) 00260 { 00261 socket->read_buffer = buffer; 00262 00263 //Process events 00264 00265 return MINITLS_OK; 00266 } 00267 00268 minitls_err_t tls_socket_close(tls_socket_t* socket) 00269 { 00270 minitls_err_t ret = tls_record_close(&socket->record); 00271 if(ret) 00272 { 00273 return ret; 00274 } 00275 return MINITLS_OK; 00276 }
Generated on Wed Jul 13 2022 00:22:55 by
1.7.2
