-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use gmtime() when neither gmtime_r nor gmtime_s are available #1927
Changes from all commits
ce6eebb
824dfb3
97f3ecb
d717743
1abb368
a7b9f15
248e27c
c99b12b
a658d7d
c2f948b
e9b10b2
2099606
8c9a620
ca04a01
193fe89
3c9733a
c29c34c
e58088e
433f911
45e3020
94b540a
cfeb70c
272675f
5f95c79
be2e4bd
6a73978
651d586
48a816f
4e67cca
acef292
9a51d01
921b76d
c946888
9fbbf1c
5a7fe14
7dd82b4
c52ef40
6f70581
a50fed9
03b2bd4
323d801
f5106d5
d2ef254
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,17 @@ | |
#ifndef MBEDTLS_PLATFORM_UTIL_H | ||
#define MBEDTLS_PLATFORM_UTIL_H | ||
|
||
#if !defined(MBEDTLS_CONFIG_FILE) | ||
#include "mbedtls/config.h" | ||
#else | ||
#include MBEDTLS_CONFIG_FILE | ||
#endif | ||
|
||
#include <stddef.h> | ||
#if defined(MBEDTLS_HAVE_TIME_DATE) | ||
#include "mbedtls/platform_time.h" | ||
#include <time.h> | ||
#endif /* MBEDTLS_HAVE_TIME_DATE */ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
|
@@ -55,6 +65,37 @@ extern "C" { | |
*/ | ||
void mbedtls_platform_zeroize( void *buf, size_t len ); | ||
|
||
#if defined(MBEDTLS_HAVE_TIME_DATE) | ||
/** | ||
* \brief Platform-specific implementation of gmtime_r() | ||
* | ||
* The function is a thread-safe abstraction that behaves | ||
* similarly to the gmtime_r() function from Unix/POSIX. | ||
* | ||
* Mbed TLS will try to identify the underlying platform and | ||
* make use of an appropriate underlying implementation (e.g. | ||
* gmtime_r() for POSIX and gmtime_s() for Windows). If this is | ||
* not possible, then gmtime() will be used. In this case, calls | ||
* from the library to gmtime() will be guarded by the mutex | ||
* mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is | ||
* enabled. It is recommended that calls from outside the library | ||
* are also guarded by this mutex. | ||
* | ||
* If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will | ||
* unconditionally use the alternative implementation for | ||
* mbedtls_platform_gmtime_r() supplied by the user at compile time. | ||
* | ||
* \param tt Pointer to an object containing time (in seconds) since the | ||
* epoch to be converted | ||
* \param tm_buf Pointer to an object where the results will be stored | ||
* | ||
* \return Pointer to an object of type struct tm on success, otherwise | ||
* NULL | ||
*/ | ||
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the Unix/POSIX There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I stuck to |
||
struct tm *tm_buf ); | ||
#endif /* MBEDTLS_HAVE_TIME_DATE */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,13 +20,22 @@ | |
* This file is part of Mbed TLS (https://tls.mbed.org) | ||
*/ | ||
|
||
/* | ||
* Ensure gmtime_r is available even with -std=c99; must be defined before | ||
* config.h, which pulls in glibc's features.h. Harmless on other platforms. | ||
*/ | ||
#if !defined(_POSIX_C_SOURCE) | ||
#define _POSIX_C_SOURCE 200112L | ||
#endif | ||
|
||
#if !defined(MBEDTLS_CONFIG_FILE) | ||
#include "mbedtls/config.h" | ||
#else | ||
#include MBEDTLS_CONFIG_FILE | ||
#endif | ||
|
||
#include "mbedtls/platform_util.h" | ||
#include "mbedtls/threading.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be surrounded by #if defined(MBEDTLS_THREADING_C)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could, but then we should also guard it by the other flags determining whether we call back to our default There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this include is not used otherwise, but I'll leave the decision up to you. |
||
|
||
#include <stddef.h> | ||
#include <string.h> | ||
|
@@ -65,3 +74,62 @@ void mbedtls_platform_zeroize( void *buf, size_t len ) | |
memset_func( buf, 0, len ); | ||
} | ||
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ | ||
|
||
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) | ||
#include <time.h> | ||
#if !defined(_WIN32) && (defined(unix) || \ | ||
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ | ||
defined(__MACH__))) | ||
#include <unistd.h> | ||
#endif /* !_WIN32 && (unix || __unix || __unix__ || | ||
* (__APPLE__ && __MACH__)) */ | ||
|
||
#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ | ||
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ | ||
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) | ||
/* | ||
* This is a convenience shorthand macro to avoid checking the long | ||
* preprocessor conditions above. Ideally, we could expose this macro in | ||
* platform_util.h and simply use it in platform_util.c, threading.c and | ||
* threading.h. However, this macro is not part of the Mbed TLS public API, so | ||
* we keep it private by only defining it in this file | ||
*/ | ||
#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two complex defines one after another here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree these are complex, but I believe this was removed with d2ef254 |
||
#define PLATFORM_UTIL_USE_GMTIME | ||
#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ | ||
|
||
#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ | ||
( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ | ||
_POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ | ||
|
||
struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, | ||
struct tm *tm_buf ) | ||
{ | ||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) | ||
return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); | ||
#elif !defined(PLATFORM_UTIL_USE_GMTIME) | ||
return( gmtime_r( tt, tm_buf ) ); | ||
#else | ||
struct tm *lt; | ||
|
||
#if defined(MBEDTLS_THREADING_C) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this check for Better in my view, to remove them and add to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While in principle I agree with this view. Forcing MBEDTLS_HAVE_TIME_DATE to depend on MBEDTLS_THREADING_C changes the API. Also, consider that not every platform that uses MBEDTLS_HAVE_TIME_DATE will be multithreaded. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the code is fine as it is: as Andres said, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've changed my mind on this, because we do run on some single threaded systems that don't have |
||
if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) | ||
return( NULL ); | ||
#endif /* MBEDTLS_THREADING_C */ | ||
|
||
lt = gmtime( tt ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What shall we do if the platform doesn't support /Maybe/ we should assume if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this PR already accommodates for those situations There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO, for armcc we would define There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with Andres, I think the documentation for |
||
|
||
if( lt != NULL ) | ||
{ | ||
memcpy( tm_buf, lt, sizeof( struct tm ) ); | ||
} | ||
|
||
#if defined(MBEDTLS_THREADING_C) | ||
if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) | ||
return( NULL ); | ||
#endif /* MBEDTLS_THREADING_C */ | ||
|
||
return( ( lt == NULL ) ? NULL : tm_buf ); | ||
#endif /* _WIN32 && !EFIX64 && !EFI32 */ | ||
} | ||
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd at least put an asterisk after "thread-safe", that points to the explanation below, regarding the necessity of respecting of the critical section that we define. "Thread-safe" is an extremely strict term, and race conditions are difficult to detect and debug, so I think we may consider being extra careful about the multi-threading related wording here.