Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:10:17 by
