This is a fork of the mbed port of axTLS

Dependents:   TLS_axTLS-Example HTTPSClientExample

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls1_svr.c Source File

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