This is a fork of the mbed port of axTLS
Dependents: TLS_axTLS-Example HTTPSClientExample
tls1_svr.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 <stdio.h> 00034 #include "os_port.h" 00035 #include "ssl.h" 00036 00037 static const uint8_t g_hello_done[] = { HS_SERVER_HELLO_DONE, 0, 0, 0 }; 00038 00039 static int process_client_hello(SSL *ssl); 00040 static int send_server_hello_sequence(SSL *ssl); 00041 static int send_server_hello(SSL *ssl); 00042 static int send_server_hello_done(SSL *ssl); 00043 static int process_client_key_xchg(SSL *ssl); 00044 #ifdef CONFIG_SSL_CERT_VERIFICATION 00045 static int send_certificate_request(SSL *ssl); 00046 static int process_cert_verify(SSL *ssl); 00047 #endif 00048 00049 /* 00050 * Establish a new SSL connection to an SSL client. 00051 */ 00052 EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd) 00053 { 00054 SSL *ssl; 00055 00056 ssl = ssl_new(ssl, client_fd); 00057 ssl->next_state = HS_CLIENT_HELLO; 00058 00059 #ifdef CONFIG_SSL_FULL_MODE 00060 if (ssl_ctx->chain_length == 0) 00061 printf("Warning - no server certificate defined\n"); TTY_FLUSH(); 00062 #endif 00063 00064 return ssl; 00065 } 00066 00067 /* 00068 * Process the handshake record. 00069 */ 00070 int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len) 00071 { 00072 int ret = SSL_OK; 00073 ssl->hs_status = SSL_NOT_OK; /* not connected */ 00074 00075 /* To get here the state must be valid */ 00076 switch (handshake_type) 00077 { 00078 case HS_CLIENT_HELLO: 00079 if ((ret = process_client_hello(ssl)) == SSL_OK) 00080 ret = send_server_hello_sequence(ssl); 00081 break; 00082 00083 #ifdef CONFIG_SSL_CERT_VERIFICATION 00084 case HS_CERTIFICATE:/* the client sends its cert */ 00085 ret = process_certificate(ssl, &ssl->x509_ctx); 00086 00087 if (ret == SSL_OK) /* verify the cert */ 00088 { 00089 int cert_res = 0; 00090 00091 /* cert_res = x509_verify( 00092 ssl->x509_ctx);*/ 00093 ret = (cert_res == 0) ? SSL_OK : SSL_X509_ERROR(cert_res); 00094 } 00095 break; 00096 00097 case HS_CERT_VERIFY: 00098 ret = process_cert_verify(ssl); 00099 add_packet(ssl, buf, hs_len); /* needs to be done after */ 00100 break; 00101 #endif 00102 case HS_CLIENT_KEY_XCHG: 00103 ret = process_client_key_xchg(ssl); 00104 break; 00105 00106 case HS_FINISHED: 00107 ret = process_finished(ssl, buf, hs_len); 00108 disposable_free(ssl); /* free up some memory */ 00109 break; 00110 } 00111 00112 return ret; 00113 } 00114 00115 /* 00116 * Process a client hello message. 00117 */ 00118 static int process_client_hello(SSL *ssl) 00119 { 00120 uint8_t *buf = ssl->bm_data; 00121 int pkt_size = ssl->bm_index; 00122 int i, j, cs_len, id_len, offset = 6 + SSL_RANDOM_SIZE; 00123 int ret = SSL_OK; 00124 00125 uint8_t version = (buf[4] << 4) + buf[5]; 00126 ssl->version = ssl->client_version = version; 00127 00128 if (version > SSL_PROTOCOL_VERSION_MAX) 00129 { 00130 /* use client's version instead */ 00131 ssl->version = SSL_PROTOCOL_VERSION_MAX; 00132 } 00133 else if (version < SSL_PROTOCOL_MIN_VERSION) /* old version supported? */ 00134 { 00135 ret = SSL_ERROR_INVALID_VERSION; 00136 ssl_display_error(ret); 00137 goto error; 00138 } 00139 00140 memcpy(ssl->dc->client_random, &buf[6], SSL_RANDOM_SIZE); 00141 00142 /* process the session id */ 00143 id_len = buf[offset++]; 00144 if (id_len > SSL_SESSION_ID_SIZE) 00145 { 00146 return SSL_ERROR_INVALID_SESSION; 00147 } 00148 00149 #ifndef CONFIG_SSL_SKELETON_MODE 00150 ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, 00151 ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); 00152 #endif 00153 00154 offset += id_len; 00155 cs_len = (buf[offset]<<8) + buf[offset+1]; 00156 offset += 3; /* add 1 due to all cipher suites being 8 bit */ 00157 00158 PARANOIA_CHECK(pkt_size, offset); 00159 00160 /* work out what cipher suite we are going to use - client defines 00161 the preference */ 00162 for (i = 0; i < cs_len; i += 2) 00163 { 00164 for (j = 0; j < NUM_PROTOCOLS; j++) 00165 { 00166 if (ssl_prot_prefs[j] == buf[offset+i]) /* got a match? */ 00167 { 00168 ssl->cipher = ssl_prot_prefs[j]; 00169 goto do_state; 00170 } 00171 } 00172 } 00173 00174 /* ouch! protocol is not supported */ 00175 ret = SSL_ERROR_NO_CIPHER; 00176 00177 do_state: 00178 error: 00179 return ret; 00180 } 00181 00182 #ifdef CONFIG_SSL_ENABLE_V23_HANDSHAKE 00183 /* 00184 * Some browsers use a hybrid SSLv2 "client hello" 00185 */ 00186 int process_sslv23_client_hello(SSL *ssl) 00187 { 00188 uint8_t *buf = ssl->bm_data; 00189 int bytes_needed = ((buf[0] & 0x7f) << 8) + buf[1]; 00190 int ret = SSL_OK; 00191 00192 /* we have already read 3 extra bytes so far */ 00193 int read_len = SOCKET_READ(ssl->client_fd, buf, bytes_needed-3); 00194 int cs_len = buf[1]; 00195 int id_len = buf[3]; 00196 int ch_len = buf[5]; 00197 int i, j, offset = 8; /* start at first cipher */ 00198 int random_offset = 0; 00199 00200 DISPLAY_BYTES(ssl, "received %d bytes", buf, read_len, read_len); 00201 00202 add_packet(ssl, buf, read_len); 00203 00204 /* connection has gone, so die */ 00205 if (bytes_needed < 0) 00206 { 00207 return SSL_ERROR_CONN_LOST; 00208 } 00209 00210 /* now work out what cipher suite we are going to use */ 00211 for (j = 0; j < NUM_PROTOCOLS; j++) 00212 { 00213 for (i = 0; i < cs_len; i += 3) 00214 { 00215 if (ssl_prot_prefs[j] == buf[offset+i]) 00216 { 00217 ssl->cipher = ssl_prot_prefs[j]; 00218 goto server_hello; 00219 } 00220 } 00221 } 00222 00223 /* ouch! protocol is not supported */ 00224 ret = SSL_ERROR_NO_CIPHER; 00225 goto error; 00226 00227 server_hello: 00228 /* get the session id */ 00229 offset += cs_len - 2; /* we've gone 2 bytes past the end */ 00230 #ifndef CONFIG_SSL_SKELETON_MODE 00231 ssl->session = ssl_session_update(ssl->ssl_ctx->num_sessions, 00232 ssl->ssl_ctx->ssl_sessions, ssl, id_len ? &buf[offset] : NULL); 00233 #endif 00234 00235 /* get the client random data */ 00236 offset += id_len; 00237 00238 /* random can be anywhere between 16 and 32 bytes long - so it is padded 00239 * with 0's to the left */ 00240 if (ch_len == 0x10) 00241 { 00242 random_offset += 0x10; 00243 } 00244 00245 memcpy(&ssl->dc->client_random[random_offset], &buf[offset], ch_len); 00246 ret = send_server_hello_sequence(ssl); 00247 00248 error: 00249 return ret; 00250 } 00251 #endif 00252 00253 /* 00254 * Send the entire server hello sequence 00255 */ 00256 static int send_server_hello_sequence(SSL *ssl) 00257 { 00258 int ret; 00259 00260 if ((ret = send_server_hello(ssl)) == SSL_OK) 00261 { 00262 #ifndef CONFIG_SSL_SKELETON_MODE 00263 /* resume handshake? */ 00264 if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) 00265 { 00266 if ((ret = send_change_cipher_spec(ssl)) == SSL_OK) 00267 { 00268 ret = send_finished(ssl); 00269 ssl->next_state = HS_FINISHED; 00270 } 00271 } 00272 else 00273 #endif 00274 if ((ret = send_certificate(ssl)) == SSL_OK) 00275 { 00276 #ifdef CONFIG_SSL_CERT_VERIFICATION 00277 /* ask the client for its certificate */ 00278 if (IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION)) 00279 { 00280 if ((ret = send_certificate_request(ssl)) == SSL_OK) 00281 { 00282 ret = send_server_hello_done(ssl); 00283 ssl->next_state = HS_CERTIFICATE; 00284 } 00285 } 00286 else 00287 #endif 00288 { 00289 ret = send_server_hello_done(ssl); 00290 ssl->next_state = HS_CLIENT_KEY_XCHG; 00291 } 00292 } 00293 } 00294 00295 return ret; 00296 } 00297 00298 /* 00299 * Send a server hello message. 00300 */ 00301 static int send_server_hello(SSL *ssl) 00302 { 00303 uint8_t *buf = ssl->bm_data; 00304 int offset = 0; 00305 00306 buf[0] = HS_SERVER_HELLO; 00307 buf[1] = 0; 00308 buf[2] = 0; 00309 /* byte 3 is calculated later */ 00310 buf[4] = 0x03; 00311 buf[5] = ssl->version & 0x0f; 00312 00313 /* server random value */ 00314 get_random(SSL_RANDOM_SIZE, &buf[6]); 00315 memcpy(ssl->dc->server_random, &buf[6], SSL_RANDOM_SIZE); 00316 offset = 6 + SSL_RANDOM_SIZE; 00317 00318 #ifndef CONFIG_SSL_SKELETON_MODE 00319 if (IS_SET_SSL_FLAG(SSL_SESSION_RESUME)) 00320 { 00321 /* retrieve id from session cache */ 00322 buf[offset++] = SSL_SESSION_ID_SIZE; 00323 memcpy(&buf[offset], ssl->session->session_id, SSL_SESSION_ID_SIZE); 00324 memcpy(ssl->session_id, ssl->session->session_id, SSL_SESSION_ID_SIZE); 00325 ssl->sess_id_size = SSL_SESSION_ID_SIZE; 00326 offset += SSL_SESSION_ID_SIZE; 00327 } 00328 else /* generate our own session id */ 00329 #endif 00330 { 00331 #ifndef CONFIG_SSL_SKELETON_MODE 00332 buf[offset++] = SSL_SESSION_ID_SIZE; 00333 get_random(SSL_SESSION_ID_SIZE, &buf[offset]); 00334 memcpy(ssl->session_id, &buf[offset], SSL_SESSION_ID_SIZE); 00335 ssl->sess_id_size = SSL_SESSION_ID_SIZE; 00336 00337 /* store id in session cache */ 00338 if (ssl->ssl_ctx->num_sessions) 00339 { 00340 memcpy(ssl->session->session_id, 00341 ssl->session_id, SSL_SESSION_ID_SIZE); 00342 } 00343 00344 offset += SSL_SESSION_ID_SIZE; 00345 #else 00346 buf[offset++] = 0; /* don't bother with session id in skelton mode */ 00347 #endif 00348 } 00349 00350 buf[offset++] = 0; /* cipher we are using */ 00351 buf[offset++] = ssl->cipher; 00352 buf[offset++] = 0; /* no compression */ 00353 buf[3] = offset - 4; /* handshake size */ 00354 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, offset); 00355 } 00356 00357 /* 00358 * Send the server hello done message. 00359 */ 00360 static int send_server_hello_done(SSL *ssl) 00361 { 00362 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, 00363 g_hello_done, sizeof(g_hello_done)); 00364 } 00365 00366 /* 00367 * Pull apart a client key exchange message. Decrypt the pre-master key (using 00368 * our RSA private key) and then work out the master key. Initialise the 00369 * ciphers. 00370 */ 00371 static int process_client_key_xchg(SSL *ssl) 00372 { 00373 uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; 00374 int pkt_size = ssl->bm_index; 00375 int premaster_size, secret_length = (buf[2] << 8) + buf[3]; 00376 uint8_t premaster_secret[MAX_KEY_BYTE_SIZE]; 00377 RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; 00378 int offset = 4; 00379 int ret = SSL_OK; 00380 00381 if (rsa_ctx == NULL) 00382 { 00383 ret = SSL_ERROR_NO_CERT_DEFINED; 00384 goto error; 00385 } 00386 00387 /* is there an extra size field? */ 00388 if ((secret_length - 2) == rsa_ctx->num_octets) 00389 offset += 2; 00390 00391 PARANOIA_CHECK(pkt_size, rsa_ctx->num_octets+offset); 00392 00393 /* rsa_ctx->bi_ctx is not thread-safe */ 00394 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00395 premaster_size = RSA_decrypt(rsa_ctx, &buf[offset], premaster_secret, 1); 00396 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00397 00398 if (premaster_size != SSL_SECRET_SIZE || 00399 premaster_secret[0] != 0x03 || /* must be the same as client 00400 offered version */ 00401 premaster_secret[1] != (ssl->client_version & 0x0f)) 00402 { 00403 /* guard against a Bleichenbacher attack */ 00404 get_random(SSL_SECRET_SIZE, premaster_secret); 00405 /* and continue - will die eventually when checking the mac */ 00406 } 00407 00408 #if 0 00409 print_blob("pre-master", premaster_secret, SSL_SECRET_SIZE); 00410 #endif 00411 00412 generate_master_secret(ssl, premaster_secret); 00413 00414 #ifdef CONFIG_SSL_CERT_VERIFICATION 00415 ssl->next_state = IS_SET_SSL_FLAG(SSL_CLIENT_AUTHENTICATION) ? 00416 HS_CERT_VERIFY : HS_FINISHED; 00417 #else 00418 ssl->next_state = HS_FINISHED; 00419 #endif 00420 00421 ssl->dc->bm_proc_index += rsa_ctx->num_octets+offset; 00422 error: 00423 return ret; 00424 } 00425 00426 #ifdef CONFIG_SSL_CERT_VERIFICATION 00427 static const uint8_t g_cert_request[] = { HS_CERT_REQ, 0, 0, 4, 1, 0, 0, 0 }; 00428 00429 /* 00430 * Send the certificate request message. 00431 */ 00432 static int send_certificate_request(SSL *ssl) 00433 { 00434 return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, 00435 g_cert_request, sizeof(g_cert_request)); 00436 } 00437 00438 /* 00439 * Ensure the client has the private key by first decrypting the packet and 00440 * then checking the packet digests. 00441 */ 00442 static int process_cert_verify(SSL *ssl) 00443 { 00444 uint8_t *buf = &ssl->bm_data[ssl->dc->bm_proc_index]; 00445 int pkt_size = ssl->bm_index; 00446 uint8_t dgst_buf[MAX_KEY_BYTE_SIZE]; 00447 uint8_t dgst[MD5_SIZE+SHA1_SIZE]; 00448 X509_CTX *x509_ctx = ssl->x509_ctx; 00449 int ret = SSL_OK; 00450 int n; 00451 00452 PARANOIA_CHECK(pkt_size, x509_ctx->rsa_ctx->num_octets+6); 00453 DISPLAY_RSA(ssl, x509_ctx->rsa_ctx); 00454 00455 /* rsa_ctx->bi_ctx is not thread-safe */ 00456 SSL_CTX_LOCK(ssl->ssl_ctx->mutex); 00457 n = RSA_decrypt(x509_ctx->rsa_ctx, &buf[6], dgst_buf, 0); 00458 SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); 00459 00460 if (n != SHA1_SIZE + MD5_SIZE) 00461 { 00462 ret = SSL_ERROR_INVALID_KEY; 00463 goto end_cert_vfy; 00464 } 00465 00466 finished_digest(ssl, NULL, dgst); /* calculate the digest */ 00467 if (memcmp(dgst_buf, dgst, MD5_SIZE + SHA1_SIZE)) 00468 { 00469 ret = SSL_ERROR_INVALID_KEY; 00470 } 00471 00472 end_cert_vfy: 00473 ssl->next_state = HS_FINISHED; 00474 error: 00475 return ret; 00476 } 00477 00478 #endif 00479 00480
Generated on Wed Jul 13 2022 19:30:08 by 1.7.2