mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-01-30 06:33:06 +00:00
a9f64006ea
Problem ------- mbedtls_strerror is a utility function which converts an mbedTLS error code into a human readable string. It requires the caller to allocate a buffer every time an error code needs to be converted to a string. It is an overkill and a waste of RAM for resource constrained microcontrollers - where the most common use case is to use these strings for logging. Solution -------- The proposed commit adds two functions: * const char * mbedtls_high_level_strerr( int error_code ); * const char * mbedtls_low_level_strerr( int error_code ); The above two functions convert the high level and low level parts of an mbedTLS error code to human readable strings. They return a const pointer to an unmodifiable string which is not supposed to be modified by the caller and only to be used for logging purposes. The caller no longer needs to allocate a buffer. Backward Compatibility ---------------------- The proposed change is completely backward compatible as it does not change the existing mbedtls_strerror function and ensures that it continues to behave the same way. Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
180 lines
4.2 KiB
Plaintext
180 lines
4.2 KiB
Plaintext
/*
|
|
* Error message information
|
|
*
|
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
* not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
|
#include "mbedtls/config.h"
|
|
#else
|
|
#include MBEDTLS_CONFIG_FILE
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_PLATFORM_C)
|
|
#include "mbedtls/platform.h"
|
|
#else
|
|
#define mbedtls_snprintf snprintf
|
|
#define mbedtls_time_t time_t
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_ERROR_C)
|
|
|
|
#include <stdio.h>
|
|
|
|
HEADER_INCLUDED
|
|
|
|
typedef struct mbedtls_error
|
|
{
|
|
int code; /* Error code. */
|
|
const char * description; /* Error description. */
|
|
} mbedtls_error_t;
|
|
|
|
static mbedtls_error_t high_level_errors[] =
|
|
{
|
|
HIGH_LEVEL_CODE_CHECKS
|
|
};
|
|
|
|
#define NUM_HIGH_LEVEL_ERRORS ( sizeof(high_level_errors)/sizeof(mbedtls_error_t) )
|
|
|
|
static mbedtls_error_t low_level_errors[] =
|
|
{
|
|
LOW_LEVEL_CODE_CHECKS
|
|
};
|
|
|
|
#define NUM_LOW_LEVEL_ERRORS ( sizeof(low_level_errors)/sizeof(mbedtls_error_t) )
|
|
|
|
const char * mbedtls_high_level_strerr( int error_code )
|
|
{
|
|
size_t i;
|
|
const char *error_description = NULL;
|
|
|
|
for(i = 0; i < NUM_HIGH_LEVEL_ERRORS; i++ )
|
|
{
|
|
if( high_level_errors[i].code == error_code )
|
|
{
|
|
error_description = high_level_errors[i].description;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return error_description;
|
|
}
|
|
|
|
const char * mbedtls_low_level_strerr( int error_code )
|
|
{
|
|
size_t i;
|
|
const char *error_description = NULL;
|
|
|
|
for(i = 0; i < NUM_LOW_LEVEL_ERRORS; i++ )
|
|
{
|
|
if( low_level_errors[i].code == error_code )
|
|
{
|
|
error_description = low_level_errors[i].description;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return error_description;
|
|
}
|
|
|
|
void mbedtls_strerror( int ret, char *buf, size_t buflen )
|
|
{
|
|
size_t len;
|
|
int use_ret;
|
|
const char * high_level_error_description = NULL;
|
|
const char * low_level_error_description = NULL;
|
|
|
|
if( buflen == 0 )
|
|
return;
|
|
|
|
memset( buf, 0x00, buflen );
|
|
|
|
if( ret < 0 )
|
|
ret = -ret;
|
|
|
|
if( ret & 0xFF80 )
|
|
{
|
|
use_ret = ret & 0xFF80;
|
|
|
|
// Translate high level error code.
|
|
high_level_error_description = mbedtls_high_level_strerr(use_ret);
|
|
|
|
if( high_level_error_description == NULL )
|
|
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
|
else
|
|
mbedtls_snprintf( buf, buflen, "%s", high_level_error_description );
|
|
|
|
// Early return in case of a fatal error - do not try to translate low
|
|
// level code.
|
|
if(use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE))
|
|
return;
|
|
}
|
|
|
|
use_ret = ret & ~0xFF80;
|
|
|
|
if( use_ret == 0 )
|
|
return;
|
|
|
|
// If high level code is present, make a concatenation between both
|
|
// error strings.
|
|
//
|
|
len = strlen( buf );
|
|
|
|
if( len > 0 )
|
|
{
|
|
if( buflen - len < 5 )
|
|
return;
|
|
|
|
mbedtls_snprintf( buf + len, buflen - len, " : " );
|
|
|
|
buf += len + 3;
|
|
buflen -= len + 3;
|
|
}
|
|
|
|
// Translate low level error code.
|
|
low_level_error_description = mbedtls_low_level_strerr( use_ret );
|
|
|
|
if( low_level_error_description == NULL )
|
|
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
|
|
else
|
|
mbedtls_snprintf( buf, buflen, "%s", low_level_error_description );
|
|
}
|
|
|
|
#else /* MBEDTLS_ERROR_C */
|
|
|
|
#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
|
|
|
|
/*
|
|
* Provide an non-function in case MBEDTLS_ERROR_C is not defined
|
|
*/
|
|
void mbedtls_strerror( int ret, char *buf, size_t buflen )
|
|
{
|
|
((void) ret);
|
|
|
|
if( buflen > 0 )
|
|
buf[0] = '\0';
|
|
}
|
|
|
|
#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
|
|
|
|
#endif /* MBEDTLS_ERROR_C */
|