This is a fork of the mbed port of axTLS
Dependents: TLS_axTLS-Example HTTPSClientExample
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_remaining_bytes = 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 /* 00170 * Send the initial client hello. 00171 */ 00172 static int send_client_hello(SSL *ssl) 00173 { 00174 uint8_t *buf = ssl->bm_data; 00175 time_t tm = time(NULL); 00176 uint8_t *tm_ptr = &buf[6]; /* time will go here */ 00177 int i, offset; 00178 00179 buf[0] = HS_CLIENT_HELLO; 00180 buf[1] = 0; 00181 buf[2] = 0; 00182 /* byte 3 is calculated later */ 00183 buf[4] = 0x03; 00184 buf[5] = ssl->version & 0x0f; 00185 00186 /* client random value - spec says that 1st 4 bytes are big endian time */ 00187 *tm_ptr++ = (uint8_t)(((long)tm & 0xff000000) >> 24); 00188 *tm_ptr++ = (uint8_t)(((long)tm & 0x00ff0000) >> 16); 00189 *tm_ptr++ = (uint8_t)(((long)tm & 0x0000ff00) >> 8); 00190 *tm_ptr++ = (uint8_t)(((long)tm & 0x000000ff)); 00191 get_random(SSL_RANDOM_SIZE-4, &buf[10]); 00192 memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); 00193 offset = 6 + SSL_RANDOM_SIZE; 00194 00195 /* give session resumption a go */ 00196 if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) /* set initially by user */ 00197 { 00198 buf[offset++] = ssl->sess_id_size; 00199 memcpy(&buf[offset], ssl->session_id, ssl->sess_id_size); 00200 offset += ssl->sess_id_size; 00201 CLR_SSL_FLAG(SSL_SESSION_RESUME); /* clear so we can set later */ 00202 } 00203 else 00204 { 00205 /* no session id - because no session resumption just yet */ 00206 buf[offset++] = 0; 00207 } 00208 00209 buf[offset++] = 0; /* number of ciphers */ 00210 buf[offset++] = NUM_PROTOCOLS*2;/* number of ciphers */ 00211 00212 /* put all our supported protocols in our request */ 00213 for (i = 0; i < NUM_PROTOCOLS; i++) 00214 { 00215 buf[offset++] = 0; /* cipher we are using */ 00216 buf[offset++] = ssl_prot_prefs[i]; 00217 } 00218 00219 buf[offset++] = 1; /* no compression */ 00220 buf[offset++] = 0; 00221 buf[3] = offset - 4; /* handshake size */ 00222 00223 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); 00224 } 00225 00226 /* 00227 * Process the server hello. 00228 */ 00229 static int process_server_hello(SSL *ssl) 00230 { 00231 uint8_t *buf = ssl->bm_data; 00232 int pkt_size = ssl->bm_index; 00233 int num_sessions = ssl->ssl_ctx->num_sessions; 00234 uint8_t sess_id_size; 00235 int offset, ret = SSL_OK; 00236 00237 /* check that we are talking to a TLSv1 server */ 00238 uint8_t version = (buf[0] << 4) + buf[1]; 00239 if (version > SSL_PROTOCOL_VERSION_MAX) 00240 { 00241 version = SSL_PROTOCOL_VERSION_MAX; 00242 } 00243 else if (ssl->version < SSL_PROTOCOL_MIN_VERSION) 00244 { 00245 ret = SSL_ERROR_INVALID_VERSION; 00246 ssl_display_error(ret); 00247 goto error; 00248 } 00249 00250 ssl->version = version; 00251 00252 /* get the server random value */ 00253 memcpy(ssl->dc->server_random, &buf[2], SSL_RANDOM_SIZE); 00254 offset = 2 + SSL_RANDOM_SIZE; /* skip of session id size */ 00255 sess_id_size = buf[offset++]; 00256 00257 if (sess_id_size > SSL_SESSION_ID_SIZE) 00258 { 00259 ret = SSL_ERROR_INVALID_SESSION; 00260 goto error; 00261 } 00262 00263 if (num_sessions) 00264 { 00265 ssl->session = ssl_session_update(num_sessions, 00266 ssl->ssl_ctx->ssl_sessions, ssl, &buf[offset]); 00267 memcpy(ssl->session->session_id, &buf[offset], sess_id_size); 00268 00269 /* pad the rest with 0's */ 00270 if (sess_id_size < SSL_SESSION_ID_SIZE) 00271 { 00272 memset(&ssl->session->session_id[sess_id_size], 0, 00273 SSL_SESSION_ID_SIZE-sess_id_size); 00274 } 00275 } 00276 00277 memcpy(ssl->session_id, &buf[offset], sess_id_size); 00278 ssl->sess_id_size = sess_id_size; 00279 offset += sess_id_size; 00280 00281 /* get the real cipher we are using */ 00282 ssl->cipher = buf[++offset]; 00283 ssl->next_state = IS_SET_SSL_FLAG(SSL_SESSION_RESUME) ? 00284 HS_FINISHED : HS_CERTIFICATE; 00285 00286 offset++; // skip the compr 00287 PARANOIA_CHECK(pkt_size, offset); 00288 ssl->dc->bm_proc_index = offset+1; 00289 00290 error: 00291 return ret; 00292 } 00293 00294 /** 00295 * Process the server hello done message. 00296 */ 00297 static int process_server_hello_done(SSL *ssl) 00298 { 00299 ssl->next_state = HS_FINISHED; 00300 return SSL_OK; 00301 } 00302 00303 /* 00304 * Send a client key exchange message. 00305 */ 00306 static int send_client_key_xchg(SSL *ssl) 00307 { 00308 uint8_t *buf = ssl->bm_data; 00309 uint8_t premaster_secret[SSL_SECRET_SIZE]; 00310 int enc_secret_size = -1; 00311 00312 buf[0] = HS_CLIENT_KEY_XCHG; 00313 buf[1] = 0; 00314 00315 premaster_secret[0] = 0x03; /* encode the version number */ 00316 premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ 00317 get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]); 00318 DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); 00319 00320 /* rsa_ctx->bi_ctx is not thread-safe */ 00321 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00322 enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret, 00323 SSL_SECRET_SIZE, &buf[6], 0); 00324 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00325 00326 buf[2] = (enc_secret_size + 2) >> 8; 00327 buf[3] = (enc_secret_size + 2) & 0xff; 00328 buf[4] = enc_secret_size >> 8; 00329 buf[5] = enc_secret_size & 0xff; 00330 00331 generate_master_secret(ssl, premaster_secret); 00332 00333 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6); 00334 } 00335 00336 /* 00337 * Process the certificate request. 00338 */ 00339 static int process_cert_req(SSL *ssl) 00340 { 00341 uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; 00342 int ret = SSL_OK; 00343 int offset = (buf[2] << 4) + buf[3]; 00344 int pkt_size = ssl->bm_index; 00345 00346 /* don't do any processing - we will send back an RSA certificate anyway */ 00347 ssl->next_state = HS_SERVER_HELLO_DONE; 00348 SET_SSL_FLAG(SSL_HAS_CERT_REQ); 00349 ssl->dc->bm_proc_index += offset; 00350 PARANOIA_CHECK(pkt_size, offset); 00351 error: 00352 return ret; 00353 } 00354 00355 /* 00356 * Send a certificate verify message. 00357 */ 00358 static int send_cert_verify(SSL *ssl) 00359 { 00360 uint8_t *buf = ssl->bm_data; 00361 uint8_t dgst[MD5_SIZE+SHA1_SIZE]; 00362 RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; 00363 int n = 0, ret; 00364 00365 DISPLAY_RSA(ssl, rsa_ctx); 00366 00367 buf[0] = HS_CERT_VERIFY; 00368 buf[1] = 0; 00369 00370 finished_digest(ssl, NULL, dgst); /* calculate the digest */ 00371 00372 /* rsa_ctx->bi_ctx is not thread-safe */ 00373 if (rsa_ctx) 00374 { 00375 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00376 n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1); 00377 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00378 00379 if (n == 0) 00380 { 00381 ret = SSL_ERROR_INVALID_KEY; 00382 goto error; 00383 } 00384 } 00385 00386 buf[4] = n >> 8; /* add the RSA size (not officially documented) */ 00387 buf[5] = n & 0xff; 00388 n += 2; 00389 buf[2] = n >> 8; 00390 buf[3] = n & 0xff; 00391 ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4); 00392 00393 error: 00394 return ret; 00395 } 00396 00397 #endif /* CONFIG_SSL_ENABLE_CLIENT */ 00398 00399
Generated on Wed Jul 13 2022 19:30:08 by 1.7.2