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.
Fork of mbed-os by
tls1_clnt.c
00001 /* 00002 * Copyright (c) 2007, Cameron Rich 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * * Neither the name of the axTLS project nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00025 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00026 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00031 #include <stdlib.h> 00032 #include <string.h> 00033 #include <time.h> 00034 #include <stdio.h> 00035 #include "os_port.h" 00036 #include "ssl.h" 00037 00038 #ifdef CONFIG_SSL_ENABLE_CLIENT /* all commented out if no client */ 00039 00040 static int send_client_hello(SSL *ssl); 00041 static int process_server_hello(SSL *ssl); 00042 static int process_server_hello_done(SSL *ssl); 00043 static int send_client_key_xchg(SSL *ssl); 00044 static int process_cert_req(SSL *ssl); 00045 static int send_cert_verify(SSL *ssl); 00046 00047 /* 00048 * Establish a new SSL connection to an SSL server. 00049 */ 00050 EXP_FUNC SSL * STDCALL ssl_client_new(SSL *ssl, int client_fd, const 00051 uint8_t *session_id, uint8_t sess_id_size) 00052 { 00053 SSL_CTX *ssl_ctx = ssl->ssl_ctx; 00054 ssl_new(ssl, client_fd); 00055 ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */ 00056 00057 if (session_id && ssl_ctx->num_sessions) 00058 { 00059 if (sess_id_size > SSL_SESSION_ID_SIZE) /* validity check */ 00060 { 00061 ssl_free(ssl); 00062 return NULL; 00063 } 00064 00065 memcpy(ssl->session_id, session_id, sess_id_size); 00066 ssl->sess_id_size = sess_id_size; 00067 SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */ 00068 } 00069 00070 SET_SSL_FLAG(SSL_IS_CLIENT); 00071 do_client_connect(ssl); 00072 return ssl; 00073 } 00074 00075 /* 00076 * Process the handshake record. 00077 */ 00078 int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) 00079 { 00080 int ret; 00081 00082 /* To get here the state must be valid */ 00083 switch (handshake_type) 00084 { 00085 case HS_SERVER_HELLO: 00086 ret = process_server_hello(ssl); 00087 break; 00088 00089 case HS_CERTIFICATE: 00090 ret = process_certificate(ssl, &ssl->x509_ctx); 00091 break; 00092 00093 case HS_SERVER_HELLO_DONE: 00094 if ((ret = process_server_hello_done(ssl)) == SSL_OK) 00095 { 00096 if (IS_SET_SSL_FLAG(SSL_HAS_CERT_REQ)) 00097 { 00098 if ((ret = send_certificate(ssl)) == SSL_OK && 00099 (ret = send_client_key_xchg(ssl)) == SSL_OK) 00100 { 00101 send_cert_verify(ssl); 00102 } 00103 } 00104 else 00105 { 00106 ret = send_client_key_xchg(ssl); 00107 } 00108 00109 if (ret == SSL_OK && 00110 (ret = send_change_cipher_spec(ssl)) == SSL_OK) 00111 { 00112 ret = send_finished(ssl); 00113 } 00114 } 00115 break; 00116 00117 case HS_CERT_REQ: 00118 ret = process_cert_req(ssl); 00119 break; 00120 00121 case HS_FINISHED: 00122 ret = process_finished(ssl, buf, hs_len); 00123 disposable_free(ssl); /* free up some memory */ 00124 /* note: client renegotiation is not allowed after this */ 00125 break; 00126 00127 case HS_HELLO_REQUEST: 00128 disposable_new(ssl); 00129 ret = do_client_connect(ssl); 00130 break; 00131 00132 default: 00133 ret = SSL_ERROR_INVALID_HANDSHAKE; 00134 break; 00135 } 00136 00137 return ret; 00138 } 00139 00140 /* 00141 * Do the handshaking from the beginning. 00142 */ 00143 int do_client_connect(SSL *ssl) 00144 { 00145 int ret = SSL_OK; 00146 00147 send_client_hello(ssl); /* send the client hello */ 00148 ssl->bm_read_index = 0; 00149 ssl->next_state = HS_SERVER_HELLO; 00150 ssl->hs_status = SSL_NOT_OK; /* not connected */ 00151 00152 /* sit in a loop until it all looks good */ 00153 if (!IS_SET_SSL_FLAG(SSL_CONNECT_IN_PARTS)) 00154 { 00155 while (ssl->hs_status != SSL_OK) 00156 { 00157 ret = read_record(ssl); 00158 if (ret < SSL_OK) 00159 break; 00160 ret = process_data(ssl, NULL, 0); 00161 if (ret < SSL_OK) 00162 break; 00163 } 00164 ssl->hs_status = ret; /* connected? */ 00165 } 00166 return ret; 00167 } 00168 00169 static int compute_size_send_client_hello(SSL *ssl) 00170 { 00171 int size = 6 + SSL_RANDOM_SIZE; 00172 size++; 00173 if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) 00174 { 00175 00176 size += ssl->sess_id_size; 00177 } 00178 size += 2; 00179 int i; 00180 for (i = 0; i < NUM_PROTOCOLS; i++) 00181 size += 2; 00182 size += 2; 00183 return size+BM_RECORD_OFFSET; 00184 } 00185 00186 /* 00187 * Send the initial client hello. 00188 */ 00189 static int send_client_hello(SSL *ssl) 00190 { 00191 uint8_t *buf = ssl->bm_data; 00192 time_t tm = time(NULL); 00193 uint8_t *tm_ptr = &buf[6]; /* time will go here */ 00194 int i, offset; 00195 00196 buf[0] = HS_CLIENT_HELLO; 00197 buf[1] = 0; 00198 buf[2] = 0; 00199 /* byte 3 is calculated later */ 00200 buf[4] = 0x03; 00201 buf[5] = ssl->version & 0x0f; 00202 00203 /* client random value - spec says that 1st 4 bytes are big endian time */ 00204 *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24); 00205 *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); 00206 *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); 00207 *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); 00208 get_random(SSL_RANDOM_SIZE-4, &buf[10]); 00209 memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); 00210 offset = 6 + SSL_RANDOM_SIZE; 00211 00212 /* give session resumption a go */ 00213 if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */ 00214 { 00215 buf[offset++] = ssl->sess_id_size; 00216 memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size); 00217 offset += ssl->sess_id_size; 00218 CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */ 00219 } 00220 else 00221 { 00222 /* no session id - because no session resumption just yet */ 00223 buf[offset++] = 0; 00224 } 00225 00226 buf[offset++] = 0; /* number of ciphers */ 00227 buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */ 00228 00229 /* put all our supported protocols in our request */ 00230 for (i = 0; i < NUM_PROTOCOLS; i++) 00231 { 00232 buf[offset++] = 0; /* cipher we are using */ 00233 buf[offset++] = ssl_prot_prefs[i]; 00234 } 00235 00236 buf[offset++] = 1; /* no compression */ 00237 buf[offset++] = 0; 00238 buf[3] = offset - 4; /* handshake size */ 00239 00240 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); 00241 } 00242 00243 /* 00244 * Process the server hello. 00245 */ 00246 static int process_server_hello(SSL *ssl) 00247 { 00248 uint8_t *buf = ssl->bm_data; 00249 int pkt_size = ssl->bm_index; 00250 int num_sessions = ssl->ssl_ctx->num_sessions; 00251 uint8_t sess_id_size; 00252 int offset, ret = SSL_OK; 00253 00254 /* check that we are talking to a TLSv1 server */ 00255 uint8_t version = (buf[0] << 4) + buf[1]; 00256 if (version > SSL_PROTOCOL_VERSION_MAX) 00257 { 00258 version = SSL_PROTOCOL_VERSION_MAX; 00259 } 00260 else if (ssl->version < SSL_PROTOCOL_MIN_VERSION) 00261 { 00262 ret = SSL_ERROR_INVALID_VERSION; 00263 ssl_display_error(ret); 00264 goto error; 00265 } 00266 00267 ssl->version = version; 00268 00269 /* get the server random value */ 00270 memcpy(ssl->dc->server_random, &buf[2], SSL_RANDOM_SIZE); 00271 offset = 2 + SSL_RANDOM_SIZE; /* skip of session id size */ 00272 sess_id_size = buf[offset++]; 00273 00274 if (sess_id_size > SSL_SESSION_ID_SIZE) 00275 { 00276 ret = SSL_ERROR_INVALID_SESSION; 00277 goto error; 00278 } 00279 00280 if (num_sessions) 00281 { 00282 ssl->session = ssl_session_update(num_sessions, 00283 ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]); 00284 memcpy(ssl->session->session_id, &buf[offset], sess_id_size); 00285 00286 /* pad the rest with 0's */ 00287 if (sess_id_size < SSL_SESSION_ID_SIZE) 00288 { 00289 memset(&ssl->session->session_id[sess_id_size], 0, 00290 SSL_SESSION_ID_SIZE-sess_id_size); 00291 } 00292 } 00293 00294 memcpy(ssl->session_id, &buf[offset], sess_id_size); 00295 ssl->sess_id_size = sess_id_size; 00296 offset += sess_id_size; 00297 00298 /* get the real cipher we are using */ 00299 ssl->cipher = buf[++offset]; 00300 ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? 00301 HS_FINISHED : HS_CERTIFICATE; 00302 00303 offset++; // skip the compr 00304 PARANOIA_CHECK(pkt_size, offset); 00305 ssl->dc->bm_proc_index = offset+1; 00306 00307 error: 00308 return ret; 00309 } 00310 00311 /** 00312 * Process the server hello done message. 00313 */ 00314 static int process_server_hello_done(SSL *ssl) 00315 { 00316 ssl->next_state = HS_FINISHED; 00317 return SSL_OK; 00318 } 00319 00320 /* 00321 * Send a client key exchange message. 00322 */ 00323 static int send_client_key_xchg(SSL *ssl) 00324 { 00325 uint8_t *buf = ssl->bm_data; 00326 uint8_t premaster_secret[SSL_SECRET_SIZE]; 00327 int enc_secret_size = -1; 00328 00329 buf[0] = HS_CLIENT_KEY_XCHG; 00330 buf[1] = 0; 00331 00332 premaster_secret[0] = 0x03; /* encode the version number */ 00333 premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ 00334 get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]); 00335 DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); 00336 00337 /* rsa_ctx->bi_ctx is not thread-safe */ 00338 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00339 enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret, 00340 SSL_SECRET_SIZE, &buf[6], 0); 00341 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00342 00343 buf[2] = (enc_secret_size + 2) >> 8; 00344 buf[3] = (enc_secret_size + 2) & 0xff; 00345 buf[4] = enc_secret_size >> 8; 00346 buf[5] = enc_secret_size & 0xff; 00347 00348 generate_master_secret(ssl, premaster_secret); 00349 00350 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6); 00351 } 00352 00353 /* 00354 * Process the certificate request. 00355 */ 00356 static int process_cert_req(SSL *ssl) 00357 { 00358 uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; 00359 int ret = SSL_OK; 00360 int offset = (buf[2] << 4) + buf[3]; 00361 int pkt_size = ssl->bm_index; 00362 00363 /* don't do any processing - we will send back an RSA certificate anyway */ 00364 ssl->next_state = HS_SERVER_HELLO_DONE; 00365 SET_SSL_FLAG(SSL_HAS_CERT_REQ); 00366 ssl->dc->bm_proc_index += offset; 00367 PARANOIA_CHECK(pkt_size, offset); 00368 error: 00369 return ret; 00370 } 00371 00372 /* 00373 * Send a certificate verify message. 00374 */ 00375 static int send_cert_verify(SSL *ssl) 00376 { 00377 uint8_t *buf = ssl->bm_data; 00378 uint8_t dgst[MD5_SIZE+SHA1_SIZE]; 00379 RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; 00380 int n = 0, ret; 00381 00382 DISPLAY_RSA(ssl, rsa_ctx); 00383 00384 buf[0] = HS_CERT_VERIFY; 00385 buf[1] = 0; 00386 00387 finished_digest(ssl, NULL, dgst); /* calculate the digest */ 00388 00389 /* rsa_ctx->bi_ctx is not thread-safe */ 00390 if (rsa_ctx) 00391 { 00392 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00393 n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1); 00394 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00395 00396 if (n == 0) 00397 { 00398 ret = SSL_ERROR_INVALID_KEY; 00399 goto error; 00400 } 00401 } 00402 00403 buf[4] = n >> 8; /* add the RSA size (not officially documented) */ 00404 buf[5] = n & 0xff; 00405 n += 2; 00406 buf[2] = n >> 8; 00407 buf[3] = n & 0xff; 00408 ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4); 00409 00410 error: 00411 return ret; 00412 } 00413 00414 #endif /* CONFIG_SSL_ENABLE_CLIENT */
Generated on Tue Jul 12 2022 13:16:17 by
