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