Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls_common.c Source File

tls_common.c

Go to the documentation of this file.
00001 /**
00002  * @file tls_common.c
00003  * @brief Handshake message processing (TLS client and server)
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneSSL Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL TLS_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include <string.h>
00034 #include <ctype.h>
00035 #include "tls.h"
00036 #include "tls_cipher_suites.h"
00037 #include "tls_client.h"
00038 #include "tls_server.h"
00039 #include "tls_common.h"
00040 #include "tls_record.h"
00041 #include "tls_cache.h"
00042 #include "tls_misc.h"
00043 #include "asn1.h"
00044 #include "oid.h"
00045 #include "x509.h"
00046 #include "pem.h"
00047 #include "debug.h"
00048 
00049 //Check SSL library configuration
00050 #if (TLS_SUPPORT == ENABLED)
00051 
00052 
00053 /**
00054  * @brief Perform TLS handshake
00055  * @param[in] context Pointer to the TLS context
00056  * @return Error code
00057  **/
00058 
00059 error_t tlsHandshake(TlsContext *context)
00060 {
00061    error_t error;
00062 
00063 #if (TLS_CLIENT_SUPPORT == ENABLED)
00064    //TLS operates as a client?
00065    if(context->entity == TLS_CONNECTION_END_CLIENT)
00066    {
00067       //Initiate TLS handshake with the remote server
00068       error = tlsClientHandshake(context);
00069    }
00070    else
00071 #endif
00072 #if (TLS_SERVER_SUPPORT == ENABLED)
00073    //TLS operates as a server?
00074    if(context->entity == TLS_CONNECTION_END_SERVER)
00075    {
00076       //Initiate TLS handshake with the remote client
00077       error = tlsServerHandshake(context);
00078    }
00079    else
00080 #endif
00081    //Unsupported mode of operation?
00082    {
00083       //Cannot establish a secure session between the server and the client
00084       error = ERROR_INVALID_PARAMETER;
00085    }
00086 
00087    //Return status code
00088    return error;
00089 }
00090 
00091 
00092 /**
00093  * @brief Send Certificate message
00094  * @param[in] context Pointer to the TLS context
00095  * @return Error code
00096  **/
00097 
00098 error_t tlsSendCertificate(TlsContext *context)
00099 {
00100    error_t error;
00101    size_t length;
00102    void *message;
00103 
00104    //Initialize status code
00105    error = NO_ERROR;
00106 
00107    //Point to the buffer where to format the message
00108    message = (void *) context->txBuffer;
00109 
00110 #if (TLS_CLIENT_SUPPORT == ENABLED)
00111    //TLS operates as a client?
00112    if(context->entity == TLS_CONNECTION_END_CLIENT)
00113    {
00114       //The client must send a Certificate message if the server requests it
00115       if(context->clientCertRequested)
00116       {
00117 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
00118          //No suitable certificate available?
00119          if(context->cert == NULL && context->version == SSL_VERSION_3_0)
00120          {
00121             //The client should send a no_certificate alert instead
00122             error = tlsFormatAlert(context, TLS_ALERT_LEVEL_WARNING,
00123                TLS_ALERT_NO_CERTIFICATE, message, &length);
00124 
00125             //Check status code
00126             if(!error)
00127             {
00128                //Debug message
00129                TRACE_INFO("Sending Alert message (%" PRIuSIZE " bytes)...\r\n", length);
00130                TRACE_INFO_ARRAY("  ", message, length);
00131 
00132                //Send Alert message
00133                error = tlsWriteProtocolData(context, message, length, TLS_TYPE_ALERT);
00134             }
00135          }
00136          else
00137 #endif
00138          {
00139             //Format Certificate message
00140             error = tlsFormatCertificate(context, message, &length);
00141 
00142             //Check status code
00143             if(!error)
00144             {
00145                //Debug message
00146                TRACE_INFO("Sending Certificate message (%" PRIuSIZE " bytes)...\r\n", length);
00147                TRACE_DEBUG_ARRAY("  ", message, length);
00148 
00149                //Send handshake message
00150                error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
00151             }
00152          }
00153       }
00154    }
00155    else
00156 #endif
00157 #if (TLS_SERVER_SUPPORT == ENABLED)
00158    //TLS operates as a server?
00159    if(context->entity == TLS_CONNECTION_END_SERVER)
00160    {
00161       //The server must send a Certificate message whenever the agreed-upon
00162       //key exchange method uses certificates for authentication
00163       if(context->cert != NULL)
00164       {
00165          //Format Certificate message
00166          error = tlsFormatCertificate(context, message, &length);
00167 
00168          //Check status code
00169          if(!error)
00170          {
00171             //Debug message
00172             TRACE_INFO("Sending Certificate message (%" PRIuSIZE " bytes)...\r\n", length);
00173             TRACE_DEBUG_ARRAY("  ", message, length);
00174 
00175             //Send handshake message
00176             error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
00177          }
00178       }
00179    }
00180    else
00181 #endif
00182    //Unsupported mode of operation?
00183    {
00184       //Report an error
00185       error = ERROR_FAILURE;
00186    }
00187 
00188    //Check status code
00189    if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
00190    {
00191       //Update FSM state
00192       if(context->entity == TLS_CONNECTION_END_CLIENT)
00193          context->state = TLS_STATE_CLIENT_KEY_EXCHANGE;
00194       else
00195          context->state = TLS_STATE_SERVER_KEY_EXCHANGE;
00196    }
00197 
00198    //Return status code
00199    return error;
00200 }
00201 
00202 
00203 /**
00204  * @brief Send ChangeCipherSpec message
00205  *
00206  * The change cipher spec message is sent by both the client and the
00207  * server to notify the receiving party that subsequent records will be
00208  * protected under the newly negotiated CipherSpec and keys
00209  *
00210  * @param[in] context Pointer to the TLS context
00211  * @return Error code
00212  **/
00213 
00214 error_t tlsSendChangeCipherSpec(TlsContext *context)
00215 {
00216    error_t error;
00217    size_t length;
00218    TlsChangeCipherSpec *message;
00219 
00220    //Point to the buffer where to format the message
00221    message = (TlsChangeCipherSpec *) context->txBuffer;
00222 
00223    //Format ChangeCipherSpec message
00224    error = tlsFormatChangeCipherSpec(context, message, &length);
00225 
00226    //Check status code
00227    if(!error)
00228    {
00229       //Debug message
00230       TRACE_INFO("Sending ChangeCipherSpec message (%" PRIuSIZE " bytes)...\r\n", length);
00231       TRACE_DEBUG_ARRAY("  ", message, length);
00232 
00233       //Send ChangeCipherSpec message
00234       error = tlsWriteProtocolData(context, message, length, TLS_TYPE_CHANGE_CIPHER_SPEC);
00235    }
00236 
00237    //Check status code
00238    if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
00239    {
00240       //Initialize encryption engine
00241       error = tlsInitEncryptionEngine(context);
00242    }
00243 
00244    //Check status code
00245    if(!error)
00246    {
00247       //Inform the record layer that subsequent records will be protected
00248       //under the newly negotiated encryption algorithm
00249       context->changeCipherSpecSent = TRUE;
00250 
00251       //Prepare to send a Finished message to the peer...
00252       if(context->entity == TLS_CONNECTION_END_CLIENT)
00253          context->state = TLS_STATE_CLIENT_FINISHED;
00254       else
00255          context->state = TLS_STATE_SERVER_FINISHED;
00256    }
00257 
00258    //Return status code
00259    return error;
00260 }
00261 
00262 
00263 /**
00264  * @brief Send Finished message
00265  *
00266  * A Finished message is always sent immediately after a change
00267  * cipher spec message to verify that the key exchange and
00268  * authentication processes were successful. It is essential that a
00269  * change cipher spec message be received between the other handshake
00270  * messages and the Finished message
00271  *
00272  * @param[in] context Pointer to the TLS context
00273  * @return Error code
00274  **/
00275 
00276 error_t tlsSendFinished(TlsContext *context)
00277 {
00278    error_t error;
00279    size_t length;
00280    TlsFinished *message;
00281 
00282    //Point to the buffer where to format the message
00283    message = (TlsFinished *) context->txBuffer;
00284 
00285    //The verify data is generated from all messages in this handshake
00286    //up to but not including the Finished message
00287    error = tlsComputeVerifyData(context, context->entity);
00288 
00289    //Check status code
00290    if(!error)
00291    {
00292       //Format Finished message
00293       error = tlsFormatFinished(context, message, &length);
00294    }
00295 
00296    //Check status code
00297    if(!error)
00298    {
00299       //Debug message
00300       TRACE_INFO("Sending Finished message (%" PRIuSIZE " bytes)...\r\n", length);
00301       TRACE_DEBUG_ARRAY("  ", message, length);
00302 
00303       //Send handshake message
00304       error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
00305    }
00306 
00307    //Check status code
00308    if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
00309    {
00310       //TLS operates as a client or a server?
00311       if(context->entity == TLS_CONNECTION_END_CLIENT)
00312       {
00313          //Use abbreviated or full handshake?
00314          if(context->resume)
00315             context->state = TLS_STATE_APPLICATION_DATA;
00316          else
00317             context->state = TLS_STATE_SERVER_CHANGE_CIPHER_SPEC;
00318       }
00319       else
00320       {
00321          //Use abbreviated or full handshake?
00322          if(context->resume)
00323             context->state = TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC;
00324          else
00325             context->state = TLS_STATE_APPLICATION_DATA;
00326       }
00327    }
00328 
00329    //Return status code
00330    return error;
00331 }
00332 
00333 
00334 /**
00335  * @brief Send Alert message
00336  * @param[in] context Pointer to the TLS context
00337  * @param[in] level Severity of the message (warning or fatal)
00338  * @param[in] description Description of the alert
00339  * @return Error code
00340  **/
00341 
00342 error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description)
00343 {
00344    error_t error;
00345    size_t length;
00346    TlsAlert *message;
00347 
00348    //Point to the buffer where to format the message
00349    message = (TlsAlert *) context->txBuffer;
00350 
00351    //Format Alert message
00352    error = tlsFormatAlert(context, level, description, message, &length);
00353 
00354    //Check status code
00355    if(!error)
00356    {
00357       //Debug message
00358       TRACE_INFO("Sending Alert message (%" PRIuSIZE " bytes)...\r\n", length);
00359       TRACE_INFO_ARRAY("  ", message, length);
00360 
00361       //Send Alert message
00362       error = tlsWriteProtocolData(context, message, length, TLS_TYPE_ALERT);
00363    }
00364 
00365    //Alert messages convey the severity of the message
00366    if(level == TLS_ALERT_LEVEL_WARNING)
00367    {
00368       //If an alert with a level of warning is sent, generally the
00369       //connection can continue normally
00370       if(description == TLS_ALERT_CLOSE_NOTIFY)
00371       {
00372          //Either party may initiate a close by sending a close_notify alert
00373          context->closeNotifySent = TRUE;
00374 
00375          //Update FSM state
00376          context->state = TLS_STATE_CLOSING;
00377       }
00378    }
00379    else if(level == TLS_ALERT_LEVEL_FATAL)
00380    {
00381       //Alert messages with a level of fatal result in the immediate
00382       //termination of the connection
00383       context->fatalAlertSent = TRUE;
00384 
00385       //Any connection terminated with a fatal alert must not be resumed
00386       if(context->entity == TLS_CONNECTION_END_SERVER)
00387          tlsRemoveFromCache(context);
00388 
00389       //Servers and clients must forget any session identifiers
00390       memset(context->sessionId, 0, 32);
00391       context->sessionIdLen = 0;
00392 
00393       //Update FSM state
00394       context->state = TLS_STATE_CLOSING;
00395    }
00396 
00397    //Return status code
00398    return error;
00399 }
00400 
00401 
00402 /**
00403  * @brief Format Certificate message
00404  * @param[in] context Pointer to the TLS context
00405  * @param[out] message Buffer where to format the Certificate message
00406  * @param[out] length Length of the resulting Certificate message
00407  * @return Error code
00408  **/
00409 
00410 error_t tlsFormatCertificate(TlsContext *context,
00411    TlsCertificate *message, size_t *length)
00412 {
00413    error_t error;
00414    uint8_t *p;
00415    const char_t *pemCert;
00416    size_t pemCertLength;
00417    uint8_t *derCert;
00418    size_t derCertSize;
00419    size_t derCertLength;
00420 
00421    //Initialize status code
00422    error = NO_ERROR;
00423 
00424    //Handshake message type
00425    message->msgType = TLS_TYPE_CERTIFICATE;
00426 
00427    //Point to the first certificate of the list
00428    p = message->certificateList;
00429    //Length of the certificate list in bytes
00430    *length = 0;
00431 
00432    //Check whether a certificate is available
00433    if(context->cert != NULL)
00434    {
00435       //Point to the certificate chain
00436       pemCert = context->cert->certChain;
00437       //Get the total length, in bytes, of the certificate chain
00438       pemCertLength = context->cert->certChainLength;
00439    }
00440    else
00441    {
00442       //If no suitable certificate is available, the message
00443       //contains an empty certificate list
00444       pemCert = NULL;
00445       pemCertLength = 0;
00446    }
00447 
00448    //DER encoded certificate
00449    derCert = NULL;
00450    derCertSize = 0;
00451    derCertLength = 0;
00452 
00453    //Parse the certificate chain
00454    while(pemCertLength > 0)
00455    {
00456       //Decode PEM certificate
00457       error = pemReadCertificate(&pemCert, &pemCertLength,
00458          &derCert, &derCertSize, &derCertLength);
00459 
00460       //Any error to report?
00461       if(error)
00462       {
00463          //End of file detected
00464          error = NO_ERROR;
00465          break;
00466       }
00467 
00468       //Total length of the certificate list
00469       *length += derCertLength + 3;
00470 
00471       //Prevent the buffer from overflowing
00472       if((*length + sizeof(TlsCertificate)) > context->txRecordMaxLen)
00473       {
00474          //Report an error
00475          error = ERROR_MESSAGE_TOO_LONG;
00476          break;
00477       }
00478 
00479       //Each certificate is preceded by a 3-byte length field
00480       STORE24BE(derCertLength, p);
00481       //Copy the current certificate
00482       memcpy(p + 3, derCert, derCertLength);
00483 
00484       //Advance data pointer
00485       p += derCertLength + 3;
00486    }
00487 
00488    //Free previously allocated memory
00489    tlsFreeMem(derCert);
00490 
00491    //A 3-byte length field shall precede the certificate list
00492    STORE24BE(*length, message->certificateListLength);
00493    //Consider the 3-byte length field
00494    *length += 3;
00495 
00496    //Fix the length field
00497    STORE24BE(*length, message->length);
00498    //Length of the complete handshake message
00499    *length += sizeof(TlsHandshake);
00500 
00501    //Return status code
00502    return error;
00503 }
00504 
00505 
00506 /**
00507  * @brief Format ChangeCipherSpec message
00508  * @param[in] context Pointer to the TLS context
00509  * @param[out] message Buffer where to format the ChangeCipherSpec message
00510  * @param[out] length Length of the resulting ChangeCipherSpec message
00511  * @return Error code
00512  **/
00513 
00514 error_t tlsFormatChangeCipherSpec(TlsContext *context,
00515    TlsChangeCipherSpec *message, size_t *length)
00516 {
00517    //The ChangeCipherSpec message consists of a single byte of value 1
00518    message->type = 1;
00519 
00520    //Length of the ChangeCipherSpec message
00521    *length = sizeof(TlsChangeCipherSpec);
00522 
00523    //Successful processing
00524    return NO_ERROR;
00525 }
00526 
00527 
00528 /**
00529  * @brief Format Finished message
00530  * @param[in] context Pointer to the TLS context
00531  * @param[out] message Buffer where to format the Finished message
00532  * @param[out] length Length of the resulting Finished message
00533  * @return Error code
00534  **/
00535 
00536 error_t tlsFormatFinished(TlsContext *context,
00537    TlsFinished *message, size_t *length)
00538 {
00539    //Handshake message type
00540    message->msgType = TLS_TYPE_FINISHED;
00541 
00542    //The length of the verify data depends on the cipher suite
00543    STORE24BE(context->verifyDataLen, message->length);
00544 
00545    //Copy the verify data
00546    memcpy(message->verifyData, context->verifyData, context->verifyDataLen);
00547 
00548    //Length of the complete handshake message
00549    *length = context->verifyDataLen + sizeof(TlsHandshake);
00550 
00551    //Successful processing
00552    return NO_ERROR;
00553 }
00554 
00555 
00556 /**
00557  * @brief Format Alert message
00558  * @param[in] context Pointer to the TLS context
00559  * @param[in] level Severity of the message (warning or fatal)
00560  * @param[in] description Description of the alert
00561  * @param[out] message Buffer where to format the Alert message
00562  * @param[out] length Length of the resulting Alert message
00563  * @return Error code
00564  **/
00565 
00566 error_t tlsFormatAlert(TlsContext *context, uint8_t level,
00567    uint8_t description, TlsAlert *message, size_t *length)
00568 {
00569    //Severity of the message
00570    message->level = level;
00571    //Description of the alert
00572    message->description = description;
00573 
00574    //Length of the Alert message
00575    *length = sizeof(TlsAlert);
00576 
00577    //Successful processing
00578    return NO_ERROR;
00579 }
00580 
00581 
00582 /**
00583  * @brief Parse Certificate message
00584  * @param[in] context Pointer to the TLS context
00585  * @param[in] message Incoming Certificate message to parse
00586  * @param[in] length Message length
00587  * @return Error code
00588  **/
00589 
00590 error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
00591 {
00592    error_t error;
00593    const uint8_t *p;
00594    size_t n;
00595    const char_t *pemCert;
00596    size_t pemCertLength;
00597    uint8_t *derCert;
00598    size_t derCertSize;
00599    size_t derCertLength;
00600 
00601    //X.509 certificates
00602    X509CertificateInfo *certInfo = NULL;
00603    X509CertificateInfo *issuerCertInfo = NULL;
00604 
00605    //Debug message
00606    TRACE_INFO("Certificate message received (%" PRIuSIZE " bytes)...\r\n", length);
00607    TRACE_DEBUG_ARRAY("  ", message, length);
00608 
00609    //Check the length of the Certificate message
00610    if(length < sizeof(TlsCertificate))
00611       return ERROR_DECODING_FAILED;
00612 
00613    //TLS operates as a client or a server?
00614    if(context->entity == TLS_CONNECTION_END_CLIENT)
00615    {
00616       //Check current state
00617       if(context->state != TLS_STATE_SERVER_CERTIFICATE)
00618          return ERROR_UNEXPECTED_MESSAGE;
00619    }
00620    else
00621    {
00622       //Check current state
00623       if(context->state != TLS_STATE_CLIENT_CERTIFICATE)
00624          return ERROR_UNEXPECTED_MESSAGE;
00625    }
00626 
00627    //Update the hash value with the incoming handshake message
00628    tlsUpdateHandshakeHash(context, message, length);
00629 
00630    //Get the size occupied by the certificate list
00631    n = LOAD24BE(message->certificateListLength);
00632    //Remaining bytes to process
00633    length -= sizeof(TlsCertificate);
00634 
00635    //Ensure that the chain of certificates is valid
00636    if(n > length)
00637       return ERROR_DECODING_FAILED;
00638 
00639    //Compute the length of the certificate list
00640    length = n;
00641 
00642    //The sender's certificate must come first in the list
00643    p = message->certificateList;
00644 
00645    //Start of exception handling block
00646    do
00647    {
00648       //Assume an error...
00649       error = ERROR_OUT_OF_MEMORY;
00650 
00651       //Allocate a memory buffer to store X.509 certificate info
00652       certInfo = tlsAllocMem(sizeof(X509CertificateInfo));
00653       //Failed to allocate memory?
00654       if(certInfo == NULL)
00655          break;
00656 
00657       //Allocate a memory buffer to store the parent certificate
00658       issuerCertInfo = tlsAllocMem(sizeof(X509CertificateInfo));
00659       //Failed to allocate memory?
00660       if(issuerCertInfo == NULL)
00661          break;
00662 
00663       //TLS operates as a server?
00664       if(context->entity == TLS_CONNECTION_END_SERVER)
00665       {
00666          //Empty certificate list?
00667          if(!length)
00668          {
00669             //Check whether mutual authentication is required
00670             if(context->clientAuthMode == TLS_CLIENT_AUTH_REQUIRED)
00671             {
00672                //If client authentication is required by the server for the handshake
00673                //to continue, it may respond with a fatal handshake failure alert
00674                error = ERROR_HANDSHAKE_FAILED;
00675                break;
00676             }
00677             else
00678             {
00679                //Client authentication is optional
00680                context->peerCertType = TLS_CERT_NONE;
00681                //Exit immediately
00682                error = NO_ERROR;
00683                break;
00684             }
00685          }
00686       }
00687 
00688       //Each certificate is preceded by a 3-byte length field
00689       if(length < 3)
00690       {
00691          //Report an error
00692          error = ERROR_DECODING_FAILED;
00693          break;
00694       }
00695 
00696       //Get the size occupied by the certificate
00697       n = LOAD24BE(p);
00698       //Jump to the beginning of the DER encoded certificate
00699       p += 3;
00700       length -= 3;
00701 
00702       //Make sure that the certificate is valid
00703       if(n > length)
00704       {
00705          //Report an error
00706          error = ERROR_DECODING_FAILED;
00707          break;
00708       }
00709 
00710       //Display ASN.1 structure
00711       error = asn1DumpObject(p, n, 0);
00712       //Any error to report?
00713       if(error)
00714          break;
00715 
00716       //Parse X.509 certificate
00717       error = x509ParseCertificate(p, n, certInfo);
00718       //Failed to parse the X.509 certificate?
00719       if(error)
00720          break;
00721 
00722 #if (TLS_CLIENT_SUPPORT == ENABLED)
00723       //TLS operates as a client?
00724       if(context->entity == TLS_CONNECTION_END_CLIENT)
00725       {
00726          //Check if the hostname must be verified
00727          if(context->serverName != NULL)
00728          {
00729             int_t i;
00730             int_t j;
00731 
00732             //Point to the last character of the common name
00733             i = certInfo->subject.commonNameLen - 1;
00734             //Point to the last character of the hostname
00735             j = strlen(context->serverName) - 1;
00736 
00737             //Check the common name in the server certificate against
00738             //the actual hostname that is being requested
00739             while(i >= 0 && j >= 0)
00740             {
00741                //Wildcard certificate found?
00742                if(certInfo->subject.commonName[i] == '*' && i == 0)
00743                {
00744                   //The CN is acceptable
00745                   j = 0;
00746                }
00747                //Perform case insensitive character comparison
00748                else if(tolower((uint8_t) certInfo->subject.commonName[i]) != context->serverName[j])
00749                {
00750                   break;
00751                }
00752 
00753                //Compare previous characters
00754                i--;
00755                j--;
00756             }
00757 
00758             //If the host names do not match, reject the certificate
00759             if(i >= 0 || j >= 0)
00760             {
00761                //Debug message
00762                TRACE_WARNING("Server name mismatch!\r\n");
00763                //Report an error
00764                error = ERROR_BAD_CERTIFICATE;
00765                break;
00766             }
00767          }
00768       }
00769 #endif
00770 
00771 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
00772    TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
00773       //The certificate contains a valid RSA public key?
00774       if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
00775          RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)))
00776       {
00777          uint_t k;
00778 
00779          //Retrieve the RSA public key
00780          error = x509ReadRsaPublicKey(certInfo, &context->peerRsaPublicKey);
00781          //Any error to report
00782          if(error)
00783             break;
00784 
00785          //Get the length of the modulus, in bits
00786          k = mpiGetBitLength(&context->peerRsaPublicKey.n);
00787 
00788          //Make sure the modulus is acceptable
00789          if(k < TLS_MIN_RSA_MODULUS_SIZE || k > TLS_MAX_RSA_MODULUS_SIZE)
00790          {
00791             //Report an error
00792             error = ERROR_BAD_CERTIFICATE;
00793             break;
00794          }
00795 
00796          //Save the certificate type
00797          context->peerCertType = TLS_CERT_RSA_SIGN;
00798       }
00799       else
00800 #endif
00801 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
00802       //The certificate contains a valid DSA public key?
00803       if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
00804          DSA_OID, sizeof(DSA_OID)))
00805       {
00806          uint_t k;
00807 
00808          //Retrieve the DSA public key
00809          error = x509ReadDsaPublicKey(certInfo, &context->peerDsaPublicKey);
00810          //Any error to report
00811          if(error)
00812             break;
00813 
00814          //Get the length of the prime modulus, in bits
00815          k = mpiGetBitLength(&context->peerDsaPublicKey.p);
00816 
00817          //Make sure the prime modulus is acceptable
00818          if(k < TLS_MIN_DSA_MODULUS_SIZE || k > TLS_MAX_DSA_MODULUS_SIZE)
00819          {
00820             //Report an error
00821             error = ERROR_BAD_CERTIFICATE;
00822             break;
00823          }
00824 
00825          //Save the certificate type
00826          context->peerCertType = TLS_CERT_DSS_SIGN;
00827       }
00828       else
00829 #endif
00830 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
00831       //The certificate contains a valid EC public key?
00832       if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
00833          EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
00834       {
00835          const EcCurveInfo *curveInfo;
00836 
00837          //Retrieve EC domain parameters
00838          curveInfo = ecGetCurveInfo(certInfo->subjectPublicKeyInfo.ecParams.namedCurve,
00839             certInfo->subjectPublicKeyInfo.ecParams.namedCurveLen);
00840 
00841          //Make sure the specified elliptic curve is supported
00842          if(curveInfo == NULL)
00843          {
00844             //Report an error
00845             error = ERROR_BAD_CERTIFICATE;
00846             //Exit immediately
00847             break;
00848          }
00849 
00850          //Load EC domain parameters
00851          error = ecLoadDomainParameters(&context->peerEcParams, curveInfo);
00852          //Any error to report?
00853          if(error)
00854             break;
00855 
00856          //Retrieve the EC public key
00857          error = ecImport(&context->peerEcParams, &context->peerEcPublicKey,
00858             certInfo->subjectPublicKeyInfo.ecPublicKey.q, certInfo->subjectPublicKeyInfo.ecPublicKey.qLen);
00859          //Any error to report
00860          if(error)
00861             break;
00862 
00863          //Save the certificate type
00864          context->peerCertType = TLS_CERT_ECDSA_SIGN;
00865       }
00866       else
00867 #endif
00868       //The certificate does not contain any valid public key?
00869       {
00870          //Report an error
00871          error = ERROR_BAD_CERTIFICATE;
00872          break;
00873       }
00874 
00875       //Next certificate
00876       p += n;
00877       length -= n;
00878 
00879       //PKIX path validation
00880       while(length > 0)
00881       {
00882          //Each certificate is preceded by a 3-byte length field
00883          if(length < 3)
00884          {
00885             //Report an error
00886             error = ERROR_DECODING_FAILED;
00887             break;
00888          }
00889 
00890          //Get the size occupied by the certificate
00891          n = LOAD24BE(p);
00892          //Jump to the beginning of the DER encoded certificate
00893          p += 3;
00894          length -= 3;
00895 
00896          //Ensure that the certificate is valid
00897          if(n > length)
00898          {
00899             //Report an error
00900             error = ERROR_DECODING_FAILED;
00901             break;
00902          }
00903 
00904          //Display ASN.1 structure
00905          error = asn1DumpObject(p, n, 0);
00906          //Any error to report?
00907          if(error)
00908             break;
00909 
00910          //Parse X.509 certificate
00911          error = x509ParseCertificate(p, n, issuerCertInfo);
00912          //Failed to parse the X.509 certificate?
00913          if(error)
00914             break;
00915 
00916          //Valid trusted CA list?
00917          if(context->trustedCaListLen > 0)
00918          {
00919             //Validate current certificate
00920             error = x509ValidateCertificate(certInfo, issuerCertInfo);
00921             //Certificate validation failed?
00922             if(error)
00923                break;
00924          }
00925 
00926          //Keep track of the issuer certificate
00927          memcpy(certInfo, issuerCertInfo, sizeof(X509CertificateInfo));
00928 
00929          //Next certificate
00930          p += n;
00931          length -= n;
00932       }
00933 
00934       //Propagate exception if necessary...
00935       if(error)
00936          break;
00937 
00938       //Point to the first trusted CA certificate
00939       pemCert = context->trustedCaList;
00940       //Get the total length, in bytes, of the trusted CA list
00941       pemCertLength = context->trustedCaListLen;
00942 
00943       //DER encoded certificate
00944       derCert = NULL;
00945       derCertSize = 0;
00946       derCertLength = 0;
00947 
00948       //Loop through the list
00949       while(pemCertLength > 0)
00950       {
00951          //Decode PEM certificate
00952          error = pemReadCertificate(&pemCert, &pemCertLength,
00953             &derCert, &derCertSize, &derCertLength);
00954          //Any error to report?
00955          if(error)
00956             break;
00957 
00958          //Parse X.509 certificate
00959          error = x509ParseCertificate(derCert, derCertLength, issuerCertInfo);
00960          //Failed to parse the X.509 certificate?
00961          if(error)
00962             break;
00963 
00964          //Validate the certificate with the current trusted CA
00965          error = x509ValidateCertificate(certInfo, issuerCertInfo);
00966          //Certificate validation succeeded?
00967          if(!error)
00968             break;
00969       }
00970 
00971       //The certificate could not be matched with a known, trusted CA?
00972       if(error == ERROR_END_OF_FILE)
00973          error = ERROR_UNKNOWN_CA;
00974 
00975       //Free previously allocated memory
00976       tlsFreeMem(derCert);
00977 
00978       //End of exception handling block
00979    } while(0);
00980 
00981    //Free previously allocated memory
00982    tlsFreeMem(certInfo);
00983    tlsFreeMem(issuerCertInfo);
00984 
00985    //Clean up side effects
00986    if(error)
00987    {
00988 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
00989    TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
00990       //Release peer's RSA public key
00991       rsaFreePublicKey(&context->peerRsaPublicKey);
00992 #endif
00993 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
00994       //Release peer's DSA public key
00995       dsaFreePublicKey(&context->peerDsaPublicKey);
00996 #endif
00997 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
00998       //Release peer's EC domain parameters
00999       ecFreeDomainParameters(&context->peerEcParams);
01000       //Release peer's EC public key
01001       ecFree(&context->peerEcPublicKey);
01002 #endif
01003    }
01004 
01005    //TLS operates as a client or a server?
01006    if(context->entity == TLS_CONNECTION_END_CLIENT)
01007    {
01008       //Update FSM state
01009       if(context->keyExchMethod == TLS_KEY_EXCH_RSA)
01010          context->state = TLS_STATE_CERTIFICATE_REQUEST;
01011       else
01012          context->state = TLS_STATE_SERVER_KEY_EXCHANGE;
01013    }
01014    else
01015    {
01016       //Prepare to receive ClientKeyExchange message...
01017       context->state = TLS_STATE_CLIENT_KEY_EXCHANGE;
01018    }
01019 
01020    //Return status code
01021    return error;
01022 }
01023 
01024 
01025 /**
01026  * @brief Parse ChangeCipherSpec message
01027  * @param[in] context Pointer to the TLS context
01028  * @param[in] message Incoming ChangeCipherSpec message to parse
01029  * @param[in] length Message length
01030  * @return Error code
01031  **/
01032 
01033 error_t tlsParseChangeCipherSpec(TlsContext *context, const TlsChangeCipherSpec *message, size_t length)
01034 {
01035    error_t error;
01036 
01037    //Debug message
01038    TRACE_INFO("ChangeCipherSpec message received (%" PRIuSIZE " bytes)...\r\n", length);
01039    TRACE_DEBUG_ARRAY("  ", message, length);
01040 
01041    //Check the length of the ChangeCipherSpec message
01042    if(length < sizeof(TlsChangeCipherSpec))
01043       return ERROR_DECODING_FAILED;
01044 
01045    //TLS operates as a client or a server?
01046    if(context->entity == TLS_CONNECTION_END_CLIENT)
01047    {
01048       //Check current state
01049       if(context->state != TLS_STATE_SERVER_CHANGE_CIPHER_SPEC)
01050          return ERROR_UNEXPECTED_MESSAGE;
01051    }
01052    else
01053    {
01054       //Check current state
01055       if(context->state != TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC)
01056          return ERROR_UNEXPECTED_MESSAGE;
01057    }
01058 
01059    //Initialize decryption engine
01060    error = tlsInitDecryptionEngine(context);
01061    //Any error to report?
01062    if(error)
01063       return error;
01064 
01065    //Inform the record layer that subsequent records will be protected
01066    //under the newly negotiated encryption algorithm
01067    context->changeCipherSpecReceived = TRUE;
01068 
01069    //Prepare to receive a Finished message from the peer...
01070    if(context->entity == TLS_CONNECTION_END_CLIENT)
01071       context->state = TLS_STATE_SERVER_FINISHED;
01072    else
01073       context->state = TLS_STATE_CLIENT_FINISHED;
01074 
01075    //Successful processing
01076    return NO_ERROR;
01077 }
01078 
01079 
01080 /**
01081  * @brief Parse Finished message
01082  * @param[in] context Pointer to the TLS context
01083  * @param[in] message Incoming Finished message to parse
01084  * @param[in] length Message length
01085  * @return Error code
01086  **/
01087 
01088 error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
01089 {
01090    error_t error;
01091 
01092    //Debug message
01093    TRACE_INFO("Finished message received (%" PRIuSIZE " bytes)...\r\n", length);
01094    TRACE_DEBUG_ARRAY("  ", message, length);
01095 
01096    //Check the length of the Finished message
01097    if(length < sizeof(TlsFinished))
01098       return ERROR_DECODING_FAILED;
01099 
01100    //TLS operates as a client or a server?
01101    if(context->entity == TLS_CONNECTION_END_CLIENT)
01102    {
01103       //Check current state
01104       if(context->state != TLS_STATE_SERVER_FINISHED)
01105          return ERROR_UNEXPECTED_MESSAGE;
01106 
01107       //The verify data is generated from all messages in this
01108       //handshake up to but not including the Finished message
01109       error = tlsComputeVerifyData(context, TLS_CONNECTION_END_SERVER);
01110    }
01111    else
01112    {
01113       //Check current state
01114       if(context->state != TLS_STATE_CLIENT_FINISHED)
01115          return ERROR_UNEXPECTED_MESSAGE;
01116 
01117       //The verify data is generated from all messages in this
01118       //handshake up to but not including the Finished message
01119       error = tlsComputeVerifyData(context, TLS_CONNECTION_END_CLIENT);
01120    }
01121 
01122    //Unable to generate the verify data?
01123    if(error)
01124       return error;
01125 
01126    //Check message length
01127    if(LOAD24BE(message->length) != context->verifyDataLen)
01128       return ERROR_DECODING_FAILED;
01129 
01130    //Check the resulting verify data
01131    if(memcmp(message->verifyData, context->verifyData, context->verifyDataLen))
01132       return ERROR_INVALID_SIGNATURE;
01133 
01134    //Update the hash value with the incoming handshake message
01135    tlsUpdateHandshakeHash(context, message, length);
01136 
01137    //TLS operates as a client or a server?
01138    if(context->entity == TLS_CONNECTION_END_CLIENT)
01139    {
01140       //Use abbreviated or full handshake?
01141       if(context->resume)
01142          context->state = TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC;
01143       else
01144          context->state = TLS_STATE_APPLICATION_DATA;
01145    }
01146    else
01147    {
01148       //Use abbreviated or full handshake?
01149       if(context->resume)
01150          context->state = TLS_STATE_APPLICATION_DATA;
01151       else
01152          context->state = TLS_STATE_SERVER_CHANGE_CIPHER_SPEC;
01153    }
01154 
01155    //Successful processing
01156    return NO_ERROR;
01157 }
01158 
01159 
01160 /**
01161  * @brief Parse Alert message
01162  * @param[in] context Pointer to the TLS context
01163  * @param[in] message Incoming Alert message to parse
01164  * @param[in] length Message length
01165  * @return Error code
01166  **/
01167 
01168 error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, size_t length)
01169 {
01170    //Debug message
01171    TRACE_INFO("Alert message received (%" PRIuSIZE " bytes)...\r\n", length);
01172    TRACE_INFO_ARRAY("  ", message, length);
01173 
01174    //Check message length
01175    if(length != sizeof(TlsAlert))
01176       return ERROR_INVALID_LENGTH;
01177 
01178    //Debug message
01179    TRACE_DEBUG("  Level = %" PRIu8 "\r\n", message->level);
01180    TRACE_DEBUG("  Description = %" PRIu8 "\r\n", message->description);
01181 
01182    //Alert messages convey the severity of the message
01183    if(message->level == TLS_ALERT_LEVEL_WARNING)
01184    {
01185       //Closure alert received?
01186       if(message->description == TLS_ALERT_CLOSE_NOTIFY)
01187       {
01188          //A closure alert has been received
01189          context->closeNotifyReceived = TRUE;
01190 
01191          //Close down the connection immediately
01192          if(context->state == TLS_STATE_APPLICATION_DATA)
01193             context->state = TLS_STATE_CLOSING;
01194       }
01195    }
01196    else if(message->level == TLS_ALERT_LEVEL_FATAL)
01197    {
01198       //A fatal alert message has been received
01199       context->fatalAlertReceived = TRUE;
01200 
01201       //Any connection terminated with a fatal alert must not be resumed
01202       if(context->entity == TLS_CONNECTION_END_SERVER)
01203          tlsRemoveFromCache(context);
01204 
01205       //Servers and clients must forget any session identifiers
01206       memset(context->sessionId, 0, 32);
01207       context->sessionIdLen = 0;
01208 
01209       //Alert messages with a level of fatal result in the immediate
01210       //termination of the connection
01211       context->state = TLS_STATE_CLOSED;
01212    }
01213    else
01214    {
01215       //Report an error
01216       return ERROR_ILLEGAL_PARAMETER;
01217    }
01218 
01219    //Successful processing
01220    return NO_ERROR;
01221 }
01222 
01223 #endif
01224