Initial commit
Initial commit.
This commit is contained in:
481
bootloader/mcuboot/ext/mbedtls-asn1/src/asn1parse.c
Normal file
481
bootloader/mcuboot/ext/mbedtls-asn1/src/asn1parse.c
Normal file
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Generic ASN.1 parsing
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ASN.1 DER decoding routines
|
||||
*/
|
||||
int mbedtls_asn1_get_len( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len )
|
||||
{
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( ( **p & 0x80 ) == 0 )
|
||||
*len = *(*p)++;
|
||||
else
|
||||
{
|
||||
switch( **p & 0x7F )
|
||||
{
|
||||
case 1:
|
||||
if( ( end - *p ) < 2 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = (*p)[1];
|
||||
(*p) += 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if( ( end - *p ) < 3 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
|
||||
(*p) += 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if( ( end - *p ) < 4 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (size_t)(*p)[1] << 16 ) |
|
||||
( (size_t)(*p)[2] << 8 ) | (*p)[3];
|
||||
(*p) += 4;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if( ( end - *p ) < 5 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
*len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
|
||||
( (size_t)(*p)[3] << 8 ) | (*p)[4];
|
||||
(*p) += 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
}
|
||||
}
|
||||
|
||||
if( *len > (size_t) ( end - *p ) )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_tag( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len, int tag )
|
||||
{
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
if( **p != tag )
|
||||
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
(*p)++;
|
||||
|
||||
return( mbedtls_asn1_get_len( p, end, len ) );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_bool( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( len != 1 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
*val = ( **p != 0 ) ? 1 : 0;
|
||||
(*p)++;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int asn1_get_tagged_int( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int tag, int *val )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/*
|
||||
* len==0 is malformed (0 must be represented as 020100 for INTEGER,
|
||||
* or 0A0100 for ENUMERATED tags
|
||||
*/
|
||||
if( len == 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
/* This is a cryptography library. Reject negative integers. */
|
||||
if( ( **p & 0x80 ) != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
/* Skip leading zeros. */
|
||||
while( len > 0 && **p == 0 )
|
||||
{
|
||||
++( *p );
|
||||
--len;
|
||||
}
|
||||
|
||||
/* Reject integers that don't fit in an int. This code assumes that
|
||||
* the int type has no padding bit. */
|
||||
if( len > sizeof( int ) )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
|
||||
*val = 0;
|
||||
while( len-- > 0 )
|
||||
{
|
||||
*val = ( *val << 8 ) | **p;
|
||||
(*p)++;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_int( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val )
|
||||
{
|
||||
return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_enum( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val )
|
||||
{
|
||||
return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
int mbedtls_asn1_get_mpi( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_mpi *X )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_mpi_read_binary( X, *p, len );
|
||||
|
||||
*p += len;
|
||||
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
|
||||
mbedtls_asn1_bitstring *bs)
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
/* Certificate type is a single byte bitstring */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Check length, subtract one for actual bit string length */
|
||||
if( bs->len < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
bs->len -= 1;
|
||||
|
||||
/* Get number of unused bits, ensure unused bits <= 7 */
|
||||
bs->unused_bits = **p;
|
||||
if( bs->unused_bits > 7 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
||||
(*p)++;
|
||||
|
||||
/* Get actual bitstring */
|
||||
bs->p = *p;
|
||||
*p += bs->len;
|
||||
|
||||
if( *p != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse an ASN.1 "SEQUENCE OF <tag>"
|
||||
* and call a callback for each entry found.
|
||||
*/
|
||||
int mbedtls_asn1_traverse_sequence_of(
|
||||
unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char tag_must_mask, unsigned char tag_must_val,
|
||||
unsigned char tag_may_mask, unsigned char tag_may_val,
|
||||
int (*cb)( void *ctx, int tag,
|
||||
unsigned char *start, size_t len ),
|
||||
void *ctx )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/* Get main sequence tag */
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( *p + len != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
while( *p < end )
|
||||
{
|
||||
unsigned char const tag = *(*p)++;
|
||||
|
||||
if( ( tag & tag_must_mask ) != tag_must_val )
|
||||
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( tag & tag_may_mask ) == tag_may_val )
|
||||
{
|
||||
if( cb != NULL )
|
||||
{
|
||||
ret = cb( ctx, tag, *p, len );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
|
||||
*p += len;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a bit string without unused bits
|
||||
*/
|
||||
int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
|
||||
size_t *len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( *len == 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||
--( *len );
|
||||
|
||||
if( **p != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||
++( *p );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
|
||||
{
|
||||
while( seq != NULL )
|
||||
{
|
||||
mbedtls_asn1_sequence *next = seq->next;
|
||||
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
|
||||
mbedtls_free( seq );
|
||||
seq = next;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int tag;
|
||||
mbedtls_asn1_sequence *cur;
|
||||
} asn1_get_sequence_of_cb_ctx_t;
|
||||
|
||||
static int asn1_get_sequence_of_cb( void *ctx,
|
||||
int tag,
|
||||
unsigned char *start,
|
||||
size_t len )
|
||||
{
|
||||
asn1_get_sequence_of_cb_ctx_t *cb_ctx =
|
||||
(asn1_get_sequence_of_cb_ctx_t *) ctx;
|
||||
mbedtls_asn1_sequence *cur =
|
||||
cb_ctx->cur;
|
||||
|
||||
if( cur->buf.p != NULL )
|
||||
{
|
||||
cur->next =
|
||||
mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
|
||||
|
||||
if( cur->next == NULL )
|
||||
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
cur->buf.p = start;
|
||||
cur->buf.len = len;
|
||||
cur->buf.tag = tag;
|
||||
|
||||
cb_ctx->cur = cur;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
|
||||
*/
|
||||
int mbedtls_asn1_get_sequence_of( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_sequence *cur,
|
||||
int tag)
|
||||
{
|
||||
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
|
||||
memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
|
||||
return( mbedtls_asn1_traverse_sequence_of(
|
||||
p, end, 0xFF, tag, 0, 0,
|
||||
asn1_get_sequence_of_cb, &cb_ctx ) );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_alg( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( end - *p ) < 1 )
|
||||
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
|
||||
|
||||
alg->tag = **p;
|
||||
end = *p + len;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
alg->p = *p;
|
||||
*p += alg->len;
|
||||
|
||||
if( *p == end )
|
||||
{
|
||||
mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
params->tag = **p;
|
||||
(*p)++;
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
params->p = *p;
|
||||
*p += params->len;
|
||||
|
||||
if( *p != end )
|
||||
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int mbedtls_asn1_get_alg_null( unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_asn1_buf params;
|
||||
|
||||
memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) );
|
||||
|
||||
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
|
||||
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
|
||||
{
|
||||
if( cur == NULL )
|
||||
return;
|
||||
|
||||
mbedtls_free( cur->oid.p );
|
||||
mbedtls_free( cur->val.p );
|
||||
|
||||
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
|
||||
}
|
||||
|
||||
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
|
||||
{
|
||||
mbedtls_asn1_named_data *cur;
|
||||
|
||||
while( ( cur = *head ) != NULL )
|
||||
{
|
||||
*head = cur->next;
|
||||
mbedtls_asn1_free_named_data( cur );
|
||||
mbedtls_free( cur );
|
||||
}
|
||||
}
|
||||
|
||||
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( const mbedtls_asn1_named_data *list,
|
||||
const char *oid, size_t len )
|
||||
{
|
||||
while( list != NULL )
|
||||
{
|
||||
if( list->oid.len == len &&
|
||||
memcmp( list->oid.p, oid, len ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return( list );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
133
bootloader/mcuboot/ext/mbedtls-asn1/src/platform_util.c
Normal file
133
bootloader/mcuboot/ext/mbedtls-asn1/src/platform_util.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Common and shared functions used by multiple modules in the Mbed TLS
|
||||
* library.
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure gmtime_r is available even with -std=c99; must be defined before
|
||||
* mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms.
|
||||
*/
|
||||
#if !defined(_POSIX_C_SOURCE)
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/threading.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
|
||||
/*
|
||||
* This implementation should never be optimized out by the compiler
|
||||
*
|
||||
* This implementation for mbedtls_platform_zeroize() was inspired from Colin
|
||||
* Percival's blog article at:
|
||||
*
|
||||
* http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
|
||||
*
|
||||
* It uses a volatile function pointer to the standard memset(). Because the
|
||||
* pointer is volatile the compiler expects it to change at
|
||||
* any time and will not optimize out the call that could potentially perform
|
||||
* other operations on the input buffer instead of just setting it to 0.
|
||||
* Nevertheless, as pointed out by davidtgoldblatt on Hacker News
|
||||
* (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
|
||||
* details), optimizations of the following form are still possible:
|
||||
*
|
||||
* if( memset_func != memset )
|
||||
* memset_func( buf, 0, len );
|
||||
*
|
||||
* Note that it is extremely difficult to guarantee that
|
||||
* mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
|
||||
* in a portable way. For this reason, Mbed TLS also provides the configuration
|
||||
* option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
|
||||
* mbedtls_platform_zeroize() to use a suitable implementation for their
|
||||
* platform and needs.
|
||||
*/
|
||||
static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
|
||||
|
||||
void mbedtls_platform_zeroize( void *buf, size_t len )
|
||||
{
|
||||
MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
|
||||
|
||||
if( len > 0 )
|
||||
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 >= 200112L ) )
|
||||
/*
|
||||
* 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) )
|
||||
#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 >= 200112L ) ) */
|
||||
|
||||
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)
|
||||
if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
|
||||
return( NULL );
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
|
||||
lt = gmtime( tt );
|
||||
|
||||
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 */
|
||||
Reference in New Issue
Block a user