Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
tls_server_misc.c
Go to the documentation of this file.
00001 /** 00002 * @file tls_server_misc.c 00003 * @brief Helper functions (TLS 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 "tls.h" 00035 #include "tls_cipher_suites.h" 00036 #include "tls_server.h" 00037 #include "tls_server_misc.h" 00038 #include "tls_common.h" 00039 #include "tls_record.h" 00040 #include "tls_cache.h" 00041 #include "tls_misc.h" 00042 #include "pem.h" 00043 #include "debug.h" 00044 00045 //Check SSL library configuration 00046 #if (TLS_SUPPORT == ENABLED && TLS_SERVER_SUPPORT == ENABLED) 00047 00048 00049 /** 00050 * @brief Format PSK identity hint 00051 * @param[in] context Pointer to the TLS context 00052 * @param[in] p Output stream where to write the PSK identity hint 00053 * @param[out] written Total number of bytes that have been written 00054 * @return Error code 00055 **/ 00056 00057 error_t tlsFormatPskIdentityHint(TlsContext *context, 00058 uint8_t *p, size_t *written) 00059 { 00060 size_t n; 00061 TlsPskIdentityHint *pskIdentityHint; 00062 00063 //Point to the PSK identity hint 00064 pskIdentityHint = (TlsPskIdentityHint *) p; 00065 00066 //Initialize length field 00067 n = 0; 00068 00069 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \ 00070 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 00071 //Any PSK identity hint defined? 00072 if(context->pskIdentityHint != NULL) 00073 { 00074 //Determine the length of the PSK identity hint 00075 n = strlen(context->pskIdentityHint); 00076 //Copy PSK identity hint 00077 memcpy(pskIdentityHint->value, context->pskIdentityHint, n); 00078 } 00079 #endif 00080 00081 //The PSK identity hint is preceded by a 2-byte length field 00082 pskIdentityHint->length = htons(n); 00083 00084 //Total number of bytes that have been written 00085 *written = sizeof(TlsPskIdentityHint) + n; 00086 00087 //Successful processing 00088 return NO_ERROR; 00089 } 00090 00091 00092 /** 00093 * @brief Format server's key exchange parameters 00094 * @param[in] context Pointer to the TLS context 00095 * @param[in] p Output stream where to write the PSK identity hint 00096 * @param[out] written Total number of bytes that have been written 00097 * @return Error code 00098 **/ 00099 00100 error_t tlsFormatServerKeyParams(TlsContext *context, 00101 uint8_t *p, size_t *written) 00102 { 00103 error_t error; 00104 00105 //Initialize status code 00106 error = NO_ERROR; 00107 00108 //Total number of bytes that have been written 00109 *written = 0; 00110 00111 #if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \ 00112 TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED) 00113 //Diffie-Hellman key exchange method? 00114 if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON || 00115 context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA || 00116 context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS || 00117 context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK) 00118 { 00119 size_t n; 00120 00121 //Generate an ephemeral key pair 00122 error = dhGenerateKeyPair(&context->dhContext, 00123 context->prngAlgo, context->prngContext); 00124 00125 //Check status code 00126 if(!error) 00127 { 00128 //Debug message 00129 TRACE_DEBUG("Diffie-Hellman parameters:\r\n"); 00130 TRACE_DEBUG(" Prime modulus:\r\n"); 00131 TRACE_DEBUG_MPI(" ", &context->dhContext.params.p); 00132 TRACE_DEBUG(" Generator:\r\n"); 00133 TRACE_DEBUG_MPI(" ", &context->dhContext.params.g); 00134 TRACE_DEBUG(" Server public value:\r\n"); 00135 TRACE_DEBUG_MPI(" ", &context->dhContext.ya); 00136 00137 //Encode the prime modulus to an opaque vector 00138 error = tlsWriteMpi(&context->dhContext.params.p, p, &n); 00139 } 00140 00141 //Check status code 00142 if(!error) 00143 { 00144 //Advance data pointer 00145 p += n; 00146 //Total number of bytes that have been written 00147 *written += n; 00148 00149 //Encode the generator to an opaque vector 00150 error = tlsWriteMpi(&context->dhContext.params.g, p, &n); 00151 } 00152 00153 //Check status code 00154 if(!error) 00155 { 00156 //Advance data pointer 00157 p += n; 00158 //Total number of bytes that have been written 00159 *written += n; 00160 00161 //Encode the server's public value to an opaque vector 00162 error = tlsWriteMpi(&context->dhContext.ya, p, &n); 00163 } 00164 00165 //Check status code 00166 if(!error) 00167 { 00168 //Advance data pointer 00169 p += n; 00170 //Adjust the length of the key exchange parameters 00171 *written += n; 00172 } 00173 } 00174 else 00175 #endif 00176 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ 00177 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 00178 //ECDH key exchange method? 00179 if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON || 00180 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA || 00181 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA || 00182 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK) 00183 { 00184 size_t n; 00185 const EcCurveInfo *curveInfo; 00186 00187 //Retrieve the elliptic curve to be used 00188 curveInfo = tlsGetCurveInfo(context->namedCurve); 00189 00190 //Make sure the elliptic curve is supported 00191 if(curveInfo != NULL) 00192 { 00193 //Load EC domain parameters 00194 error = ecLoadDomainParameters(&context->ecdhContext.params, 00195 curveInfo); 00196 00197 //Check status code 00198 if(!error) 00199 { 00200 //Generate an ephemeral key pair 00201 error = ecdhGenerateKeyPair(&context->ecdhContext, 00202 context->prngAlgo, context->prngContext); 00203 } 00204 00205 //Check status code 00206 if(!error) 00207 { 00208 //Debug message 00209 TRACE_DEBUG(" Server public key X:\r\n"); 00210 TRACE_DEBUG_MPI(" ", &context->ecdhContext.qa.x); 00211 TRACE_DEBUG(" Server public key Y:\r\n"); 00212 TRACE_DEBUG_MPI(" ", &context->ecdhContext.qa.y); 00213 00214 //Set the type of the elliptic curve domain parameters 00215 *p = TLS_EC_CURVE_TYPE_NAMED_CURVE; 00216 00217 //Advance data pointer 00218 p += sizeof(uint8_t); 00219 //Total number of bytes that have been written 00220 *written += sizeof(uint8_t); 00221 00222 //Write elliptic curve identifier 00223 STORE16BE(context->namedCurve, p); 00224 00225 //Advance data pointer 00226 p += sizeof(uint16_t); 00227 //Total number of bytes that have been written 00228 *written += sizeof(uint16_t); 00229 00230 //Write server's public key 00231 error = tlsWriteEcPoint(&context->ecdhContext.params, 00232 &context->ecdhContext.qa, p, &n); 00233 } 00234 00235 //Check status code 00236 if(!error) 00237 { 00238 //Advance data pointer 00239 p +=n; 00240 //Total number of bytes that have been written 00241 *written += n; 00242 } 00243 } 00244 else 00245 { 00246 //The specified elliptic curve is not supported 00247 error = ERROR_FAILURE; 00248 } 00249 } 00250 else 00251 #endif 00252 //Any other exchange method? 00253 { 00254 //It is not legal to send the ServerKeyExchange message when a key 00255 //exchange method other than DHE_DSS, DHE_RSA, DH_anon, ECDHE_RSA, 00256 //ECDHE_ECDSA or ECDH_anon is selected 00257 error = ERROR_FAILURE; 00258 } 00259 00260 //Return status code 00261 return error; 00262 } 00263 00264 00265 /** 00266 * @brief Generate signature over the server's key exchange parameters 00267 * @param[in] context Pointer to the TLS context 00268 * @param[in] p Output stream where to write the PSK identity hint 00269 * @param[in] params Pointer to the server's key exchange parameters 00270 * @param[in] paramsLen Length of the server's key exchange parameters 00271 * @param[out] written Total number of bytes that have been written 00272 * @return Error code 00273 **/ 00274 00275 error_t tlsGenerateServerKeySignature(TlsContext *context, 00276 uint8_t *p, const uint8_t *params, size_t paramsLen, size_t *written) 00277 { 00278 error_t error; 00279 00280 //Initialize status code 00281 error = NO_ERROR; 00282 00283 //Total number of bytes that have been written 00284 *written = 0; 00285 00286 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1) 00287 //SSL 3.0, TLS 1.0 or TLS 1.1 currently selected? 00288 if(context->version <= TLS_VERSION_1_1) 00289 { 00290 TlsDigitalSignature *signature; 00291 00292 //Point to the digitally-signed element 00293 signature = (TlsDigitalSignature *) p; 00294 00295 #if (TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) 00296 //Check whether DHE_RSA or ECDHE_RSA key exchange method is currently used 00297 if(context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA || 00298 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA) 00299 { 00300 Md5Context *md5Context; 00301 Sha1Context *sha1Context; 00302 RsaPrivateKey privateKey; 00303 00304 //Initialize RSA private key 00305 rsaInitPrivateKey(&privateKey); 00306 00307 //Allocate a memory buffer to hold the MD5 context 00308 md5Context = tlsAllocMem(sizeof(Md5Context)); 00309 00310 //Successful memory allocation? 00311 if(md5Context != NULL) 00312 { 00313 //Compute MD5(ClientHello.random + ServerHello.random + ServerDhParams) 00314 md5Init(md5Context); 00315 md5Update(md5Context, context->random, 64); 00316 md5Update(md5Context, params, paramsLen); 00317 md5Final(md5Context, context->verifyData); 00318 00319 //Release previously allocated memory 00320 tlsFreeMem(md5Context); 00321 } 00322 else 00323 { 00324 //Failed to allocate memory 00325 error = ERROR_OUT_OF_MEMORY; 00326 } 00327 00328 //Check status code 00329 if(!error) 00330 { 00331 //Allocate a memory buffer to hold the SHA-1 context 00332 sha1Context = tlsAllocMem(sizeof(Sha1Context)); 00333 00334 //Successful memory allocation? 00335 if(sha1Context != NULL) 00336 { 00337 //Compute SHA(ClientHello.random + ServerHello.random + ServerDhParams) 00338 sha1Init(sha1Context); 00339 sha1Update(sha1Context, context->random, 64); 00340 sha1Update(sha1Context, params, paramsLen); 00341 sha1Final(sha1Context, context->verifyData + MD5_DIGEST_SIZE); 00342 00343 //Release previously allocated memory 00344 tlsFreeMem(sha1Context); 00345 } 00346 else 00347 { 00348 //Failed to allocate memory 00349 error = ERROR_OUT_OF_MEMORY; 00350 } 00351 } 00352 00353 //Check status code 00354 if(!error) 00355 { 00356 //Decode the PEM structure that holds the RSA private key 00357 error = pemReadRsaPrivateKey(context->cert->privateKey, 00358 context->cert->privateKeyLength, &privateKey); 00359 } 00360 00361 //Check status code 00362 if(!error) 00363 { 00364 //Sign the key exchange parameters using RSA 00365 error = tlsGenerateRsaSignature(&privateKey, 00366 context->verifyData, signature->value, written); 00367 } 00368 00369 //Release previously allocated resources 00370 rsaFreePrivateKey(&privateKey); 00371 } 00372 else 00373 #endif 00374 #if (TLS_DHE_DSS_SUPPORT == ENABLED) 00375 //Check whether DHE_DSS key exchange method is currently used 00376 if(context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS) 00377 { 00378 Sha1Context *sha1Context; 00379 DsaPrivateKey privateKey; 00380 00381 //Initialize DSA private key 00382 dsaInitPrivateKey(&privateKey); 00383 00384 //Allocate a memory buffer to hold the SHA-1 context 00385 sha1Context = tlsAllocMem(sizeof(Sha1Context)); 00386 00387 //Successful memory allocation? 00388 if(sha1Context != NULL) 00389 { 00390 //Compute SHA(ClientHello.random + ServerHello.random + ServerDhParams) 00391 sha1Init(sha1Context); 00392 sha1Update(sha1Context, context->random, 64); 00393 sha1Update(sha1Context, params, paramsLen); 00394 sha1Final(sha1Context, context->verifyData); 00395 00396 //Release previously allocated memory 00397 tlsFreeMem(sha1Context); 00398 } 00399 else 00400 { 00401 //Failed to allocate memory 00402 error = ERROR_OUT_OF_MEMORY; 00403 } 00404 00405 //Check status code 00406 if(!error) 00407 { 00408 //Decode the PEM structure that holds the DSA private key 00409 error = pemReadDsaPrivateKey(context->cert->privateKey, 00410 context->cert->privateKeyLength, &privateKey); 00411 } 00412 00413 //Check status code 00414 if(!error) 00415 { 00416 //Sign the key exchange parameters using DSA 00417 error = tlsGenerateDsaSignature(context->prngAlgo, 00418 context->prngContext, &privateKey, context->verifyData, 00419 SHA1_DIGEST_SIZE, signature->value, written); 00420 } 00421 00422 //Release previously allocated resources 00423 dsaFreePrivateKey(&privateKey); 00424 } 00425 else 00426 #endif 00427 #if (TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 00428 //Check whether ECDHE_ECDSA key exchange method is currently used 00429 if(context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA) 00430 { 00431 Sha1Context *sha1Context; 00432 EcDomainParameters ecParams; 00433 Mpi privateKey; 00434 00435 //Initialize EC domain parameters 00436 ecInitDomainParameters(&ecParams); 00437 //Initialize EC private key 00438 mpiInit(&privateKey); 00439 00440 //Allocate a memory buffer to hold the SHA-1 context 00441 sha1Context = tlsAllocMem(sizeof(Sha1Context)); 00442 00443 //Successful memory allocation? 00444 if(sha1Context != NULL) 00445 { 00446 //Compute SHA(ClientHello.random + ServerHello.random + ServerDhParams) 00447 sha1Init(sha1Context); 00448 sha1Update(sha1Context, context->random, 64); 00449 sha1Update(sha1Context, params, paramsLen); 00450 sha1Final(sha1Context, context->verifyData); 00451 00452 //Release previously allocated memory 00453 tlsFreeMem(sha1Context); 00454 } 00455 else 00456 { 00457 //Failed to allocate memory 00458 error = ERROR_OUT_OF_MEMORY; 00459 } 00460 00461 //Check status code 00462 if(!error) 00463 { 00464 //Decode the PEM structure that holds the EC domain parameters 00465 error = pemReadEcParameters(context->cert->privateKey, 00466 context->cert->privateKeyLength, &ecParams); 00467 } 00468 00469 //Check status code 00470 if(!error) 00471 { 00472 //Decode the PEM structure that holds the EC private key 00473 error = pemReadEcPrivateKey(context->cert->privateKey, 00474 context->cert->privateKeyLength, &privateKey); 00475 } 00476 00477 //Check status code 00478 if(!error) 00479 { 00480 //Sign the key exchange parameters using ECDSA 00481 error = tlsGenerateEcdsaSignature(&ecParams, context->prngAlgo, 00482 context->prngContext, &privateKey, context->verifyData, 00483 SHA1_DIGEST_SIZE, signature->value, written); 00484 } 00485 00486 //Release previously allocated resources 00487 ecFreeDomainParameters(&ecParams); 00488 mpiFree(&privateKey); 00489 } 00490 else 00491 #endif 00492 //Invalid signature algorithm? 00493 { 00494 //Report an error 00495 error = ERROR_UNSUPPORTED_SIGNATURE_ALGO; 00496 } 00497 00498 //Fix the length of the digitally-signed element 00499 signature->length = htons(*written); 00500 //Adjust the length of the signature 00501 *written += sizeof(TlsDigitalSignature); 00502 } 00503 else 00504 #endif 00505 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 00506 //TLS 1.2 currently selected? 00507 if(context->version == TLS_VERSION_1_2) 00508 { 00509 TlsDigitalSignature2 *signature; 00510 const HashAlgo *hashAlgo; 00511 HashContext *hashContext; 00512 00513 //Point to the digitally-signed element 00514 signature = (TlsDigitalSignature2 *) p; 00515 00516 //Retrieve the hash algorithm used for signing 00517 hashAlgo = tlsGetHashAlgo(context->signHashAlgo); 00518 00519 //Make sure the hash algorithm is supported 00520 if(hashAlgo != NULL) 00521 { 00522 //Allocate a memory buffer to hold the hash context 00523 hashContext = tlsAllocMem(hashAlgo->contextSize); 00524 00525 //Successful memory allocation? 00526 if(hashContext != NULL) 00527 { 00528 //Compute SHA(ClientHello.random + ServerHello.random + ServerDhParams) 00529 hashAlgo->init(hashContext); 00530 hashAlgo->update(hashContext, context->random, 64); 00531 hashAlgo->update(hashContext, params, paramsLen); 00532 hashAlgo->final(hashContext, NULL); 00533 00534 #if (TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) 00535 //Check whether DHE_RSA or ECDHE_RSA key exchange method is currently used 00536 if(context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA || 00537 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA) 00538 { 00539 RsaPrivateKey privateKey; 00540 00541 //Initialize RSA private key 00542 rsaInitPrivateKey(&privateKey); 00543 00544 //Set the relevant signature algorithm 00545 signature->algorithm.signature = TLS_SIGN_ALGO_RSA; 00546 signature->algorithm.hash = context->signHashAlgo; 00547 00548 //Decode the PEM structure that holds the RSA private key 00549 error = pemReadRsaPrivateKey(context->cert->privateKey, 00550 context->cert->privateKeyLength, &privateKey); 00551 00552 //Check status code 00553 if(!error) 00554 { 00555 //Use the signature algorithm defined in PKCS #1 v1.5 00556 error = rsassaPkcs1v15Sign(&privateKey, hashAlgo, 00557 hashContext->digest, signature->value, written); 00558 } 00559 00560 //Release previously allocated resources 00561 rsaFreePrivateKey(&privateKey); 00562 } 00563 else 00564 #endif 00565 #if (TLS_DHE_DSS_SUPPORT == ENABLED) 00566 //Check whether DHE_DSS key exchange method is currently used 00567 if(context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS) 00568 { 00569 DsaPrivateKey privateKey; 00570 00571 //Initialize DSA private key 00572 dsaInitPrivateKey(&privateKey); 00573 00574 //Set the relevant signature algorithm 00575 signature->algorithm.signature = TLS_SIGN_ALGO_DSA; 00576 signature->algorithm.hash = context->signHashAlgo; 00577 00578 //Decode the PEM structure that holds the DSA private key 00579 error = pemReadDsaPrivateKey(context->cert->privateKey, 00580 context->cert->privateKeyLength, &privateKey); 00581 00582 //Check status code 00583 if(!error) 00584 { 00585 //Sign the key exchange parameters using DSA 00586 error = tlsGenerateDsaSignature(context->prngAlgo, 00587 context->prngContext, &privateKey, hashContext->digest, 00588 hashAlgo->digestSize, signature->value, written); 00589 } 00590 00591 //Release previously allocated resources 00592 dsaFreePrivateKey(&privateKey); 00593 } 00594 else 00595 #endif 00596 #if (TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 00597 //Check whether ECDHE_ECDSA key exchange method is currently used 00598 if(context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA) 00599 { 00600 EcDomainParameters ecParams; 00601 Mpi privateKey; 00602 00603 //Initialize EC domain parameters 00604 ecInitDomainParameters(&ecParams); 00605 //Initialize EC private key 00606 mpiInit(&privateKey); 00607 00608 //Set the relevant signature algorithm 00609 signature->algorithm.signature = TLS_SIGN_ALGO_ECDSA; 00610 signature->algorithm.hash = context->signHashAlgo; 00611 00612 //Decode the PEM structure that holds the EC domain parameters 00613 error = pemReadEcParameters(context->cert->privateKey, 00614 context->cert->privateKeyLength, &ecParams); 00615 00616 //Check status code 00617 if(!error) 00618 { 00619 //Decode the PEM structure that holds the EC private key 00620 error = pemReadEcPrivateKey(context->cert->privateKey, 00621 context->cert->privateKeyLength, &privateKey); 00622 } 00623 00624 //Check status code 00625 if(!error) 00626 { 00627 //Sign the key exchange parameters using ECDSA 00628 error = tlsGenerateEcdsaSignature(&ecParams, context->prngAlgo, 00629 context->prngContext, &privateKey, hashContext->digest, 00630 hashAlgo->digestSize, signature->value, written); 00631 } 00632 00633 //Release previously allocated memory 00634 ecFreeDomainParameters(&ecParams); 00635 mpiFree(&privateKey); 00636 } 00637 else 00638 #endif 00639 //Invalid signature algorithm? 00640 { 00641 //Report an error 00642 error = ERROR_UNSUPPORTED_SIGNATURE_ALGO; 00643 } 00644 00645 //Release previously allocated memory 00646 tlsFreeMem(hashContext); 00647 } 00648 else 00649 { 00650 //Failed to allocate memory 00651 error = ERROR_OUT_OF_MEMORY; 00652 } 00653 } 00654 else 00655 { 00656 //Hash algorithm not supported 00657 error = ERROR_INVALID_SIGNATURE; 00658 } 00659 00660 //Fix the length of the digitally-signed element 00661 signature->length = htons(*written); 00662 //Adjust the length of the message 00663 *written += sizeof(TlsDigitalSignature2); 00664 } 00665 else 00666 #endif 00667 { 00668 //The negotiated TLS version is not valid 00669 error = ERROR_INVALID_VERSION; 00670 } 00671 00672 //Return status code 00673 return error; 00674 } 00675 00676 00677 /** 00678 * @brief Parse PSK identity 00679 * @param[in] context Pointer to the TLS context 00680 * @param[in] p Input stream where to read the PSK identity hint 00681 * @param[in] length Number of bytes available in the input stream 00682 * @param[out] consumed Total number of bytes that have been consumed 00683 * @return Error code 00684 **/ 00685 00686 error_t tlsParsePskIdentity(TlsContext *context, 00687 const uint8_t *p, size_t length, size_t *consumed) 00688 { 00689 size_t n; 00690 TlsPskIdentity *pskIdentity; 00691 00692 //Malformed ClientKeyExchange message? 00693 if(length < sizeof(TlsPskIdentity)) 00694 return ERROR_DECODING_FAILED; 00695 00696 //Point to the PSK identity 00697 pskIdentity = (TlsPskIdentity *) p; 00698 00699 //Retrieve the length of the PSK identity 00700 n = ntohs(pskIdentity->length); 00701 00702 //Make sure the length field is valid 00703 if(length < (sizeof(TlsPskIdentity) + n)) 00704 return ERROR_DECODING_FAILED; 00705 00706 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \ 00707 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 00708 //Check whether the PSK identity has already been configured 00709 if(context->pskIdentity != NULL) 00710 { 00711 //Release memory 00712 tlsFreeMem(context->pskIdentity); 00713 context->pskIdentity = NULL; 00714 } 00715 00716 //Valid PSK identity? 00717 if(n > 0) 00718 { 00719 //Allocate a memory block to hold the PSK identity 00720 context->pskIdentity = tlsAllocMem(n + 1); 00721 //Failed to allocate memory? 00722 if(context->pskIdentity == NULL) 00723 return ERROR_OUT_OF_MEMORY; 00724 00725 //Save the PSK identity 00726 memcpy(context->pskIdentity, pskIdentity->value, n); 00727 //Properly terminate the string 00728 context->pskIdentity[n] = '\0'; 00729 } 00730 00731 //Any registered callback? 00732 if(context->pskCallback != NULL) 00733 { 00734 error_t error; 00735 00736 //Invoke user callback function 00737 if(context->pskIdentity != NULL) 00738 error = context->pskCallback(context, context->pskIdentity); 00739 else 00740 error = context->pskCallback(context, ""); 00741 00742 //Any error to report? 00743 if(error) 00744 return ERROR_UNKNOWN_IDENTITY; 00745 } 00746 #endif 00747 00748 //Total number of bytes that have been consumed 00749 *consumed = sizeof(TlsPskIdentity) + n; 00750 00751 //Successful processing 00752 return NO_ERROR; 00753 } 00754 00755 00756 /** 00757 * @brief Parse client's key exchange parameters 00758 * @param[in] context Pointer to the TLS context 00759 * @param[in] p Input stream where to read the client's key exchange parameters 00760 * @param[in] length Number of bytes available in the input stream 00761 * @param[out] consumed Total number of bytes that have been consumed 00762 * @return Error code 00763 **/ 00764 00765 error_t tlsParseClientKeyParams(TlsContext *context, 00766 const uint8_t *p, size_t length, size_t *consumed) 00767 { 00768 error_t error; 00769 00770 #if (TLS_RSA_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED) 00771 //RSA key exchange method? 00772 if(context->keyExchMethod == TLS_KEY_EXCH_RSA || 00773 context->keyExchMethod == TLS_KEY_EXCH_RSA_PSK) 00774 { 00775 size_t n; 00776 uint16_t version; 00777 RsaPrivateKey privateKey; 00778 00779 //The RSA-encrypted premaster secret in a ClientKeyExchange is preceded by 00780 //two length bytes. SSL 3.0 implementations do not include these bytes 00781 if(context->version > SSL_VERSION_3_0) 00782 { 00783 //Malformed ClientKeyExchange message? 00784 if(length < 2) 00785 return ERROR_DECODING_FAILED; 00786 00787 //Decode the length field 00788 n = LOAD16BE(p); 00789 00790 //Check the length of the RSA-encrypted premaster secret 00791 if(n > (length - 2)) 00792 return ERROR_DECODING_FAILED; 00793 00794 //Save the length of the RSA-encrypted premaster secret 00795 length = n; 00796 //Advance the pointer over the length field 00797 p += 2; 00798 //Total number of bytes that have been consumed 00799 *consumed = length + 2; 00800 } 00801 else 00802 { 00803 //Total number of bytes that have been consumed 00804 *consumed = length; 00805 } 00806 00807 //Initialize RSA private key 00808 rsaInitPrivateKey(&privateKey); 00809 00810 //Decode the PEM structure that holds the RSA private key 00811 error = pemReadRsaPrivateKey(context->cert->privateKey, 00812 context->cert->privateKeyLength, &privateKey); 00813 00814 //Check status code 00815 if(!error) 00816 { 00817 //Decrypt the premaster secret using the server private key 00818 error = rsaesPkcs1v15Decrypt(&privateKey, p, length, context->premasterSecret, 00819 TLS_MAX_PREMASTER_SECRET_SIZE, &context->premasterSecretLen); 00820 } 00821 00822 //Release RSA private key 00823 rsaFreePrivateKey(&privateKey); 00824 00825 //Retrieve the latest version supported by the client. This is used 00826 //to detect version roll-back attacks 00827 version = LOAD16BE(context->premasterSecret); 00828 00829 //The best way to avoid vulnerability to the Bleichenbacher attack is to 00830 //treat incorrectly formatted messages in a manner indistinguishable from 00831 //correctly formatted RSA blocks 00832 if(error || context->premasterSecretLen != 48 || version != context->clientVersion) 00833 { 00834 //When it receives an incorrectly formatted RSA block, the server 00835 //should generate a random 48-byte value and proceed using it as 00836 //the premaster secret 00837 error = context->prngAlgo->read(context->prngContext, context->premasterSecret, 48); 00838 00839 //Fix the length of the premaster secret 00840 context->premasterSecretLen = 48; 00841 } 00842 } 00843 else 00844 #endif 00845 #if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \ 00846 TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED) 00847 //Diffie-Hellman key exchange method? 00848 if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON || 00849 context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA || 00850 context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS || 00851 context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK) 00852 { 00853 size_t n; 00854 00855 //Convert the client's public value to a multiple precision integer 00856 error = tlsReadMpi(&context->dhContext.yb, p, length, &n); 00857 00858 //Check status code 00859 if(!error) 00860 { 00861 //Total number of bytes that have been consumed 00862 *consumed = n; 00863 00864 //Verify client's public value 00865 error = dhCheckPublicKey(&context->dhContext.params, &context->dhContext.yb); 00866 } 00867 00868 //Check status code 00869 if(!error) 00870 { 00871 //Calculate the negotiated key Z 00872 error = dhComputeSharedSecret(&context->dhContext, context->premasterSecret, 00873 TLS_MAX_PREMASTER_SECRET_SIZE, &context->premasterSecretLen); 00874 } 00875 00876 //Check status code 00877 if(!error) 00878 { 00879 //Leading bytes of Z that contain all zero bits are stripped before 00880 //it is used as the premaster secret (RFC 4346, section 8.2.1) 00881 for(n = 0; n < context->premasterSecretLen; n++) 00882 { 00883 if(context->premasterSecret[n] != 0x00) 00884 break; 00885 } 00886 00887 //Any leading zero bytes? 00888 if(n > 0) 00889 { 00890 //Strip leading zero bytes from the negotiated key 00891 memmove(context->premasterSecret, context->premasterSecret + n, 00892 context->premasterSecretLen - n); 00893 00894 //Adjust the length of the premaster secret 00895 context->premasterSecretLen -= n; 00896 } 00897 } 00898 } 00899 else 00900 #endif 00901 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ 00902 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 00903 //ECDH key exchange method? 00904 if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON || 00905 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA || 00906 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA || 00907 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK) 00908 { 00909 size_t n; 00910 00911 //Decode client's public key 00912 error = tlsReadEcPoint(&context->ecdhContext.params, 00913 &context->ecdhContext.qb, p, length, &n); 00914 00915 //Check status code 00916 if(!error) 00917 { 00918 //Total number of bytes that have been consumed 00919 *consumed = n; 00920 00921 //Verify client's public key and make sure that it is on the same 00922 //elliptic curve as the server's ECDH key 00923 error = ecdhCheckPublicKey(&context->ecdhContext.params, 00924 &context->ecdhContext.qb); 00925 } 00926 00927 //Check status code 00928 if(!error) 00929 { 00930 //Calculate the shared secret Z. Leading zeros found in this octet 00931 //string must not be truncated (see RFC 4492, section 5.10) 00932 error = ecdhComputeSharedSecret(&context->ecdhContext, context->premasterSecret, 00933 TLS_MAX_PREMASTER_SECRET_SIZE, &context->premasterSecretLen); 00934 } 00935 } 00936 else 00937 #endif 00938 //Invalid key exchange method? 00939 { 00940 //The specified key exchange method is not supported 00941 error = ERROR_UNSUPPORTED_KEY_EXCH_METHOD; 00942 } 00943 00944 //Return status code 00945 return error; 00946 } 00947 00948 00949 #endif 00950
Generated on Tue Jul 12 2022 17:10:17 by
