Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_TLS.c Source File

pal_TLS.c

00001 /*******************************************************************************
00002  * Copyright 2016, 2017 ARM Ltd.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *******************************************************************************/
00016 
00017 
00018 #include "pal.h"
00019 #include "pal_plat_TLS.h"
00020 #include "sotp.h"
00021 
00022 PAL_PRIVATE uint8_t g_storedCertSerial[PAL_CERT_ID_SIZE] __attribute__ ((aligned(4))) = {0};
00023 PAL_PRIVATE bool g_trustedServerValid = false;
00024 PAL_PRIVATE palMutexID_t g_palTLSHandshakeMutex = NULLPTR;
00025 
00026 typedef struct palTLSService
00027 {
00028     bool retryHandShake;
00029     uint64_t serverTime;
00030     palTLSHandle_t platTlsHandle;
00031 }palTLSService_t;
00032 
00033 typedef struct palTLSConfService
00034 {
00035     bool trustedTimeServer;
00036     palTLSConfHandle_t platTlsConfHandle;
00037 }palTLSConfService_t;
00038 
00039 palStatus_t pal_initTLSLibrary(void)
00040 {
00041     palStatus_t status = PAL_SUCCESS;
00042     status = pal_osMutexCreate(&g_palTLSHandshakeMutex);
00043     if(PAL_SUCCESS != status)
00044     {
00045         PAL_LOG(ERR, "Failed to Create TLS handshake Mutex error: %" PRId32 ".", status);
00046     }
00047     else
00048     {
00049         status = pal_plat_initTLSLibrary ();
00050     }
00051     return status;
00052 }
00053 
00054 palStatus_t pal_cleanupTLS(void)
00055 {
00056     palStatus_t status = PAL_SUCCESS;
00057     status = pal_osMutexDelete(&g_palTLSHandshakeMutex);
00058     if(PAL_SUCCESS != status)
00059     {
00060         PAL_LOG(ERR, "Failed to Delete TLS handshake Mutex error: %" PRId32 ".", status);
00061     }
00062     status = pal_plat_cleanupTLS ();
00063     return status;
00064 }
00065 
00066 
00067 palStatus_t pal_initTLS(palTLSConfHandle_t palTLSConf, palTLSHandle_t* palTLSHandle)
00068 {
00069     palStatus_t status = PAL_SUCCESS;
00070     palStatus_t mutexStatus = PAL_SUCCESS;
00071     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00072     palTLSService_t* palTLSCtx = NULL;
00073 
00074     PAL_VALIDATE_ARGUMENTS ((NULLPTR == palTLSConf || NULLPTR == palTLSHandle));
00075 
00076     mutexStatus = pal_osMutexWait(g_palTLSHandshakeMutex, PAL_RTOS_WAIT_FOREVER);
00077     if (PAL_SUCCESS != mutexStatus)
00078     {
00079         PAL_LOG(ERR, "Failed to get TLS context init Mutex error: %" PRId32 ".", mutexStatus);
00080         goto finish;
00081     }
00082 
00083     palTLSCtx = (palTLSService_t*)malloc(sizeof(palTLSService_t));
00084     if (NULL == palTLSCtx)
00085     {
00086         status = PAL_ERR_NO_MEMORY ;
00087         goto finish;
00088     }
00089     status = pal_plat_initTLS (palTLSConfCtx->platTlsConfHandle, &palTLSCtx->platTlsHandle);
00090     if (PAL_SUCCESS == status)
00091     {
00092         *palTLSHandle = (palTLSHandle_t)palTLSCtx;
00093     }
00094     
00095     memset(g_storedCertSerial, 0, sizeof(g_storedCertSerial));
00096     g_trustedServerValid = false;
00097     palTLSCtx->retryHandShake = false;
00098 
00099 finish:
00100     if (PAL_SUCCESS == mutexStatus)
00101     {
00102         mutexStatus = pal_osMutexRelease(g_palTLSHandshakeMutex);
00103         if (PAL_SUCCESS != mutexStatus)
00104         {
00105             PAL_LOG(ERR, "Failed to release TLS context init Mutex error: %" PRId32 ".", mutexStatus);
00106         }
00107     }
00108     
00109     if (PAL_SUCCESS == status)
00110     {
00111         status = mutexStatus;
00112     }
00113 
00114     if (PAL_SUCCESS != status)
00115     {
00116         free(palTLSCtx);
00117     }
00118     return status;
00119 }
00120 
00121 
00122 palStatus_t pal_freeTLS(palTLSHandle_t* palTLSHandle)
00123 {
00124     palStatus_t status = PAL_SUCCESS;
00125     palStatus_t mutexStatus = PAL_SUCCESS;
00126 
00127     palTLSService_t* palTLSCtx = NULL;
00128 
00129     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSHandle || NULLPTR == *palTLSHandle);
00130 
00131     mutexStatus = pal_osMutexWait(g_palTLSHandshakeMutex, PAL_RTOS_WAIT_FOREVER);
00132     if (PAL_SUCCESS != mutexStatus)
00133     {
00134         PAL_LOG(ERR, "Failed to get TLS context init Mutex error: %" PRId32 ".", mutexStatus);
00135         goto finish;
00136     }
00137 
00138     palTLSCtx = (palTLSService_t*)*palTLSHandle;
00139     status = pal_plat_freeTLS (&palTLSCtx->platTlsHandle);
00140     if (PAL_SUCCESS == status)
00141     {
00142         free(palTLSCtx);
00143         *palTLSHandle = NULLPTR;
00144     }
00145 
00146     mutexStatus = pal_osMutexRelease(g_palTLSHandshakeMutex);
00147     if (PAL_SUCCESS != mutexStatus)
00148     {
00149         PAL_LOG(ERR, "Failed to release TLS context init Mutex error: %" PRId32 ".", mutexStatus);
00150     }
00151 finish:
00152     if (PAL_SUCCESS == status)
00153     {
00154         status = mutexStatus;
00155     }
00156     return status;
00157 }
00158 
00159 
00160 palStatus_t pal_initTLSConfiguration(palTLSConfHandle_t* palTLSConf, palTLSTransportMode_t transportationMode)
00161 {
00162     palStatus_t status = PAL_SUCCESS;
00163     palTLSConfService_t* palTLSConfCtx = NULL;
00164 
00165     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00166 
00167 
00168     palTLSConfCtx = (palTLSConfService_t*)malloc(sizeof(palTLSConfService_t));
00169     if (NULL == palTLSConfCtx)
00170     {
00171         status = PAL_ERR_NO_MEMORY ;
00172         goto finish;
00173     }
00174     status = pal_plat_initTLSConf (&palTLSConfCtx->platTlsConfHandle, transportationMode, PAL_TLS_IS_CLIENT);
00175     if (PAL_SUCCESS != status)
00176     {
00177         goto finish;
00178     }
00179     
00180     status = pal_plat_setAuthenticationMode (palTLSConfCtx->platTlsConfHandle, PAL_TLS_VERIFY_OPTIONAL);
00181     if (PAL_SUCCESS != status)
00182     {
00183         goto finish;
00184     }
00185 #if (PAL_TLS_CIPHER_SUITE & PAL_TLS_PSK_WITH_AES_128_CBC_SHA256_SUITE)
00186     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_PSK_WITH_AES_128_CBC_SHA256);
00187 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_PSK_WITH_AES_128_CCM_8_SUITE)
00188     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_PSK_WITH_AES_128_CCM_8);
00189 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_PSK_WITH_AES_256_CCM_8_SUITE)
00190     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_PSK_WITH_AES_256_CCM_8);
00191 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_SUITE)
00192     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
00193 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_SUITE)
00194     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
00195 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_SUITE)
00196     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
00197 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256_SUITE)
00198     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256);
00199 #elif (PAL_TLS_CIPHER_SUITE & PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256_SUITE)
00200     status = pal_plat_setCipherSuites (palTLSConfCtx->platTlsConfHandle, PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256);
00201 #else
00202     #error : No CipherSuite was defined!
00203 #endif
00204     if (PAL_SUCCESS != status)
00205     {
00206         goto finish;
00207     }
00208     palTLSConfCtx->trustedTimeServer = false;
00209     *palTLSConf = (palTLSHandle_t)palTLSConfCtx;
00210 finish:
00211     if (PAL_SUCCESS != status)
00212     {
00213         free(palTLSConfCtx);
00214     }
00215     return status;
00216 }
00217 
00218 
00219 palStatus_t pal_tlsConfigurationFree(palTLSConfHandle_t* palTLSConf)
00220 {
00221     palStatus_t status = PAL_SUCCESS;
00222     palTLSConfService_t* palTLSConfCtx = NULL;
00223 
00224     PAL_VALIDATE_ARGUMENTS ((NULLPTR == palTLSConf || NULLPTR == *palTLSConf));
00225 
00226     palTLSConfCtx = (palTLSConfService_t*)*palTLSConf;
00227     status = pal_plat_tlsConfigurationFree (&palTLSConfCtx->platTlsConfHandle);
00228     if (PAL_SUCCESS == status)
00229     {
00230         free(palTLSConfCtx);
00231         *palTLSConf = NULLPTR;
00232     }
00233     return status;
00234 }
00235 
00236 
00237 palStatus_t pal_addEntropySource(palEntropySource_f entropyCallback)
00238 {
00239     palStatus_t status = PAL_SUCCESS;
00240     status = pal_plat_addEntropySource (entropyCallback);
00241     return status;
00242 }
00243 
00244 palStatus_t pal_setOwnCertAndPrivateKey(palTLSConfHandle_t palTLSConf, palX509_t* ownCert, palPrivateKey_t* privateKey)
00245 {
00246 #if (PAL_ENABLE_X509 == 1)
00247     palStatus_t status = PAL_SUCCESS;
00248     palTLSConfService_t* palTLSConfCtx =  (palTLSConfService_t*)palTLSConf;
00249 
00250     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00251     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == ownCert || NULL == privateKey);
00252 
00253     status = pal_plat_setOwnCertAndPrivateKey (palTLSConfCtx->platTlsConfHandle, ownCert, privateKey);    
00254     return status;
00255 #else
00256     return PAL_ERR_NOT_SUPPORTED ;
00257 #endif
00258 }
00259 
00260 palStatus_t pal_setOwnCertChain(palTLSConfHandle_t palTLSConf, palX509_t* ownCert)
00261 {
00262 #if (PAL_ENABLE_X509 == 1)
00263     palStatus_t status = PAL_SUCCESS;
00264     palTLSConfService_t* palTLSConfCtx =  (palTLSConfService_t*)palTLSConf;
00265 
00266     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00267     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == ownCert);
00268 
00269     status = pal_plat_setOwnCertChain (palTLSConfCtx->platTlsConfHandle, ownCert);
00270     return status;
00271 #else
00272     return PAL_ERR_NOT_SUPPORTED ;
00273 #endif
00274 }
00275 
00276 palStatus_t pal_setOwnPrivateKey(palTLSConfHandle_t palTLSConf, palPrivateKey_t* privateKey)
00277 {
00278 #if (PAL_ENABLE_X509 == 1)
00279     palStatus_t status = PAL_SUCCESS;
00280     palTLSConfService_t* palTLSConfCtx =  (palTLSConfService_t*)palTLSConf;
00281 
00282     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00283     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == privateKey);
00284 
00285     status = pal_plat_setOwnPrivateKey (palTLSConfCtx->platTlsConfHandle, privateKey);
00286     return status;
00287 #else
00288     return PAL_ERR_NOT_SUPPORTED ;
00289 #endif
00290 }
00291 
00292 palStatus_t pal_setCAChain(palTLSConfHandle_t palTLSConf, palX509_t* caChain, palX509CRL_t* caCRL)
00293 {
00294 #if (PAL_ENABLE_X509 == 1)
00295     palStatus_t status = PAL_SUCCESS;
00296     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00297     palX509Handle_t x509Ctx = NULLPTR;
00298 
00299     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00300     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == caChain);
00301 
00302 
00303     status = pal_plat_setCAChain (palTLSConfCtx->platTlsConfHandle, caChain, caCRL);
00304 #if PAL_USE_SECURE_TIME
00305     if (PAL_SUCCESS == status)
00306     {
00307         uint8_t certID[PAL_CERT_ID_SIZE] = {0}; 
00308         size_t actualCertIDLen = 0;
00309         
00310         status = pal_x509Initiate(&x509Ctx);
00311         if (PAL_SUCCESS != status)
00312         {
00313             goto finish;
00314         }
00315         
00316         status = pal_x509CertParse(x509Ctx, caChain->buffer, caChain->size);
00317         if (PAL_SUCCESS != status)
00318         {
00319             goto finish;
00320         }
00321         
00322         status = pal_x509CertGetAttribute(x509Ctx, PAL_X509_CERT_ID_ATTR, certID, sizeof(certID), &actualCertIDLen);
00323         if (PAL_SUCCESS != status)
00324         {
00325             goto finish;
00326         }
00327 
00328         if (!g_trustedServerValid)
00329         {
00330             sotp_result_e sotpRes;
00331             uint16_t actualLenBytes = 0;
00332             
00333             sotpRes = sotp_get(SOTP_TYPE_TRUSTED_TIME_SRV_ID, (uint16_t)sizeof(g_storedCertSerial), (uint32_t*)g_storedCertSerial, &actualLenBytes);
00334             if (SOTP_SUCCESS == sotpRes)
00335             {
00336                 g_trustedServerValid = true;
00337             }
00338         }
00339 
00340         if ( (sizeof(g_storedCertSerial) == actualCertIDLen) && (0 == memcmp(certID, g_storedCertSerial, sizeof(g_storedCertSerial))))
00341         {
00342             palTLSConfCtx->trustedTimeServer = true;
00343         }
00344     }
00345     finish:
00346 #endif //PAL_USE_SECURE_TIME
00347     if (NULLPTR != x509Ctx)
00348     {
00349         pal_x509Free(&x509Ctx);
00350     }
00351     return status;
00352 #else
00353     return PAL_ERR_NOT_SUPPORTED ;
00354 #endif
00355 }
00356 
00357 
00358 palStatus_t pal_setPSK(palTLSConfHandle_t palTLSConf, const unsigned char *identity, uint32_t maxIdentityLenInBytes, const unsigned char *psk, uint32_t maxPskLenInBytes)
00359 {
00360 #if (PAL_ENABLE_PSK == 1)
00361     palStatus_t status = PAL_SUCCESS;
00362     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00363 
00364     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00365     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == identity || NULL == psk);
00366 
00367 
00368     status = pal_plat_setPSK (palTLSConfCtx->platTlsConfHandle, identity, maxIdentityLenInBytes, psk, maxPskLenInBytes);
00369     return status;
00370 #else
00371     return PAL_ERR_NOT_SUPPORTED ;
00372 #endif
00373 }
00374 
00375 
00376 palStatus_t pal_tlsSetSocket(palTLSConfHandle_t palTLSConf, palTLSSocket_t* socket)
00377 {   //palSocket_t depend on the library (socket or bio pointer)
00378     palStatus_t status = PAL_SUCCESS;
00379     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00380 
00381     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConf);
00382     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx->platTlsConfHandle || NULL == socket);
00383 
00384     status = pal_plat_tlsSetSocket (palTLSConfCtx->platTlsConfHandle, socket);
00385     return status;
00386 }
00387 
00388 #if PAL_USE_SECURE_TIME
00389 PAL_PRIVATE palStatus_t pal_updateTime(uint64_t serverTime, bool trustedTimeServer)
00390 {
00391     palStatus_t status = PAL_SUCCESS;
00392     if (trustedTimeServer)
00393     {
00394         status = pal_osSetStrongTime(serverTime);
00395         if (PAL_SUCCESS != status)
00396         {
00397             PAL_LOG(DBG, "Setting strong time failed! return code %" PRId32 ".", status);
00398         }
00399     }
00400     else
00401     {
00402         status = pal_osSetWeakTime(serverTime);
00403         if (PAL_SUCCESS != status)
00404         {
00405             PAL_LOG(DBG, "Setting weak time failed! return code %" PRId32 ".", status);
00406         }
00407     }
00408     return status;
00409 }
00410 #endif //PAL_USE_SECURE_TIME
00411 
00412 palStatus_t pal_handShake(palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf)
00413 {
00414     palStatus_t status = PAL_SUCCESS;
00415     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00416     palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
00417 
00418     PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSConfCtx || NULLPTR == palTLSCtx));
00419     PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSCtx->platTlsHandle || NULLPTR == palTLSConfCtx->platTlsConfHandle));
00420 
00421     status = pal_plat_sslSetup (palTLSCtx->platTlsHandle, palTLSConfCtx->platTlsConfHandle);
00422     if (PAL_SUCCESS != status)
00423     {
00424         goto finish;
00425     }
00426 
00427     if (!palTLSCtx->retryHandShake)
00428     {
00429         status = pal_plat_handShake (palTLSCtx->platTlsHandle, &palTLSCtx->serverTime);
00430         if (PAL_SUCCESS == status)
00431         {
00432             int32_t verifyResult = 0;
00433             status = pal_sslGetVerifyResultExtended(palTLSHandle, &verifyResult);
00434 #if PAL_USE_SECURE_TIME
00435             if (PAL_ERR_X509_CERT_VERIFY_FAILED == status)
00436             {
00437                 if ((PAL_ERR_X509_BADCERT_FUTURE & verifyResult) || ((true == palTLSConfCtx->trustedTimeServer) && (PAL_ERR_X509_BADCERT_EXPIRED & verifyResult)))
00438                 {
00439                     PAL_LOG(DBG, "SSL EXPIRED OR FUTURE - retry");
00440                     palTLSCtx->retryHandShake = true;
00441                     status = PAL_SUCCESS;
00442                 }
00443                 else if (PAL_SUCCESS != status)
00444                 {
00445                     status = PAL_ERR_X509_CERT_VERIFY_FAILED;
00446                     palTLSCtx->serverTime = 0;
00447                 }
00448             }
00449 #else 
00450             if (PAL_SUCCESS != status)
00451             {
00452                 status = PAL_ERR_X509_CERT_VERIFY_FAILED;
00453                 palTLSCtx->serverTime = 0;
00454             }
00455 #endif //PAL_USE_SECURE_TIME
00456         }
00457     }
00458 #if PAL_USE_SECURE_TIME
00459     if ((PAL_SUCCESS == status) && (palTLSCtx->retryHandShake))
00460     {
00461         PAL_LOG(DBG, "SSL START RENEGOTIATE");
00462         if (!palTLSConfCtx->trustedTimeServer) //! if we are not proccessing handshake with the time trusted server we 
00463         {                                     //! will use PAL_TLS_VERIFY_REQUIRED authentication mode
00464             status = pal_plat_setAuthenticationMode (palTLSConfCtx->platTlsConfHandle, PAL_TLS_VERIFY_REQUIRED);
00465             if (PAL_SUCCESS != status)
00466             {
00467                 goto finish;
00468             }
00469         }
00470         status = pal_plat_renegotiate (palTLSCtx->platTlsHandle, palTLSCtx->serverTime);
00471         if (PAL_SUCCESS == status)
00472         {
00473             int32_t verifyResult = 0;
00474             status = pal_sslGetVerifyResultExtended(palTLSHandle, &verifyResult);
00475             if ((palTLSConfCtx->trustedTimeServer) && 
00476                 ((PAL_ERR_X509_CERT_VERIFY_FAILED == status) && ((PAL_ERR_X509_BADCERT_EXPIRED & verifyResult) || (PAL_ERR_X509_BADCERT_FUTURE & verifyResult))))
00477             {
00478                 status = PAL_SUCCESS;
00479             }
00480         }
00481     }
00482 
00483     if (PAL_SUCCESS == status)
00484     {
00485         //! We ignore the pal_updateTime() result, because it should not cause a failure to the handshake process.
00486         //! Logs are printed in the pal_updateTime() function in case of failure.
00487         pal_updateTime(palTLSCtx->serverTime, palTLSConfCtx->trustedTimeServer);
00488     }
00489 #endif //PAL_USE_SECURE_TIME
00490 finish:
00491     return status;
00492 }
00493 
00494 
00495 palStatus_t pal_sslGetVerifyResultExtended(palTLSHandle_t palTLSHandle, int32_t* verifyResult)
00496 {
00497     palStatus_t status = PAL_SUCCESS;
00498     palTLSService_t* palTLSCtx = NULL;
00499     
00500     PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSHandle) || (NULL == verifyResult));
00501 
00502     palTLSCtx = (palTLSService_t*)palTLSHandle;
00503     PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSCtx->platTlsHandle);
00504 
00505     status = pal_plat_sslGetVerifyResultExtended (palTLSCtx->platTlsHandle, verifyResult);
00506     if (0 != *verifyResult)
00507     {
00508         status = PAL_ERR_X509_CERT_VERIFY_FAILED;
00509         *verifyResult = *verifyResult ^ PAL_ERR_MODULE_BITMASK_BASE; //! in order to turn off the MSB bit.
00510     }
00511 
00512     return status;
00513 }
00514 
00515 
00516 palStatus_t pal_sslGetVerifyResult(palTLSHandle_t palTLSHandle)
00517 {
00518     palStatus_t status = PAL_SUCCESS;
00519     palTLSService_t* palTLSCtx = NULL;
00520     int32_t verifyResult = 0;
00521 
00522     PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSHandle);
00523 
00524     palTLSCtx = (palTLSService_t*)palTLSHandle;
00525     PAL_VALIDATE_ARGUMENTS(NULLPTR == palTLSCtx->platTlsHandle);
00526 
00527     status = pal_plat_sslGetVerifyResultExtended (palTLSCtx->platTlsHandle, &verifyResult);
00528     return status;
00529 }
00530 
00531 
00532 palStatus_t pal_setHandShakeTimeOut(palTLSConfHandle_t palTLSConf, uint32_t timeoutInMilliSec)
00533 {
00534     palStatus_t status = PAL_SUCCESS;
00535     palTLSConfService_t* palTLSConfCtx =  (palTLSConfService_t*)palTLSConf;
00536 
00537     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSConfCtx || 0 == timeoutInMilliSec);
00538 
00539     status = pal_plat_setHandShakeTimeOut (palTLSConfCtx->platTlsConfHandle, timeoutInMilliSec);
00540     return status;
00541 }
00542 
00543 
00544 palStatus_t pal_sslRead(palTLSHandle_t palTLSHandle, void *buffer, uint32_t len, uint32_t* actualLen)
00545 {
00546     palStatus_t status = PAL_SUCCESS;
00547     palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
00548     
00549     PAL_VALIDATE_ARGUMENTS (NULLPTR == palTLSHandle);
00550     PAL_VALIDATE_ARGUMENTS ((NULLPTR == palTLSCtx->platTlsHandle || NULL == buffer || NULL == actualLen));
00551 
00552     status = pal_plat_sslRead (palTLSCtx->platTlsHandle, buffer, len, actualLen);
00553     return status;
00554 }
00555 
00556 
00557 palStatus_t pal_sslWrite(palTLSHandle_t palTLSHandle, const void *buffer, uint32_t len, uint32_t *bytesWritten)
00558 {
00559     palStatus_t status = PAL_SUCCESS;
00560     palTLSService_t* palTLSCtx = (palTLSService_t*)palTLSHandle;
00561     
00562     PAL_VALIDATE_ARGUMENTS((NULLPTR == palTLSHandle || NULL == buffer || NULL == bytesWritten));
00563 
00564     status = pal_plat_sslWrite (palTLSCtx->platTlsHandle, buffer, len, bytesWritten);
00565     return status;
00566 }
00567 
00568 palStatus_t pal_sslDebugging(uint8_t turnOn)
00569 {
00570     return PAL_ERR_NOT_SUPPORTED ;
00571 }
00572 
00573 
00574 /*! Turn on/off the TLS library debugging for the given configuration handle. The logs are sent via the mbedTrace.
00575 *   In case of release mode, an error will be returned.
00576 *
00577 * @param[in] palTLSConf : the TLS confuguraiton to modify
00578 * @param[in] turnOn: if greater than 0 turn on debugging, otherwise turn it off
00579 *
00580 \return PAL_SUCCESS on success. A negative value indicating a specific error code in case of failure.
00581 */
00582 palStatus_t pal_sslSetDebugging(palTLSConfHandle_t palTLSConf, uint8_t turnOn)
00583 {
00584     palStatus_t status = PAL_SUCCESS;
00585 
00586     palTLSConfService_t* palTLSConfCtx = (palTLSConfService_t*)palTLSConf;
00587 
00588     status = pal_plat_sslSetDebugging (palTLSConfCtx->platTlsConfHandle, turnOn);
00589     return status;
00590 }
00591