|
20 | 20 | * This file is part of Mbed TLS (https://tls.mbed.org)
|
21 | 21 | */
|
22 | 22 |
|
| 23 | +/* |
| 24 | + * Ensure gmtime_r is available even with -std=c99; must be defined before |
| 25 | + * config.h, which pulls in glibc's features.h. Harmless on other platforms. |
| 26 | + */ |
| 27 | +#if !defined(_POSIX_C_SOURCE) |
| 28 | +#define _POSIX_C_SOURCE 200112L |
| 29 | +#endif |
| 30 | + |
23 | 31 | #if !defined(MBEDTLS_CONFIG_FILE)
|
24 | 32 | #include "mbedtls/config.h"
|
25 | 33 | #else
|
26 | 34 | #include MBEDTLS_CONFIG_FILE
|
27 | 35 | #endif
|
28 | 36 |
|
29 | 37 | #include "mbedtls/platform_util.h"
|
| 38 | +#include "mbedtls/threading.h" |
30 | 39 |
|
31 | 40 | #include <stddef.h>
|
32 | 41 | #include <string.h>
|
@@ -65,3 +74,62 @@ void mbedtls_platform_zeroize( void *buf, size_t len )
|
65 | 74 | memset_func( buf, 0, len );
|
66 | 75 | }
|
67 | 76 | #endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
|
| 77 | + |
| 78 | +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) |
| 79 | +#include <time.h> |
| 80 | +#if !defined(_WIN32) && (defined(unix) || \ |
| 81 | + defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ |
| 82 | + defined(__MACH__))) |
| 83 | +#include <unistd.h> |
| 84 | +#endif /* !_WIN32 && (unix || __unix || __unix__ || |
| 85 | + * (__APPLE__ && __MACH__)) */ |
| 86 | + |
| 87 | +#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
| 88 | + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
| 89 | + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) |
| 90 | +/* |
| 91 | + * This is a convenience shorthand macro to avoid checking the long |
| 92 | + * preprocessor conditions above. Ideally, we could expose this macro in |
| 93 | + * platform_util.h and simply use it in platform_util.c, threading.c and |
| 94 | + * threading.h. However, this macro is not part of the Mbed TLS public API, so |
| 95 | + * we keep it private by only defining it in this file |
| 96 | + */ |
| 97 | +#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) |
| 98 | +#define PLATFORM_UTIL_USE_GMTIME |
| 99 | +#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ |
| 100 | + |
| 101 | +#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
| 102 | + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
| 103 | + _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ |
| 104 | + |
| 105 | +struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, |
| 106 | + struct tm *tm_buf ) |
| 107 | +{ |
| 108 | +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) |
| 109 | + return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL ); |
| 110 | +#elif !defined(PLATFORM_UTIL_USE_GMTIME) |
| 111 | + return( gmtime_r( tt, tm_buf ) ); |
| 112 | +#else |
| 113 | + struct tm *lt; |
| 114 | + |
| 115 | +#if defined(MBEDTLS_THREADING_C) |
| 116 | + if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) |
| 117 | + return( NULL ); |
| 118 | +#endif /* MBEDTLS_THREADING_C */ |
| 119 | + |
| 120 | + lt = gmtime( tt ); |
| 121 | + |
| 122 | + if( lt != NULL ) |
| 123 | + { |
| 124 | + memcpy( tm_buf, lt, sizeof( struct tm ) ); |
| 125 | + } |
| 126 | + |
| 127 | +#if defined(MBEDTLS_THREADING_C) |
| 128 | + if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) |
| 129 | + return( NULL ); |
| 130 | +#endif /* MBEDTLS_THREADING_C */ |
| 131 | + |
| 132 | + return( ( lt == NULL ) ? NULL : tm_buf ); |
| 133 | +#endif /* _WIN32 && !EFIX64 && !EFI32 */ |
| 134 | +} |
| 135 | +#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
0 commit comments