1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

mbedtls: Update to upstream version 2.28.3

Rediff patch from PR 1453, lstrlenW is no longer used upstream so
that part of the patch was dropped.

(cherry picked from commit 1fde2092d0)
This commit is contained in:
Rémi Verschelde
2023-04-18 10:38:24 +02:00
parent 212190ae49
commit ac4daf4147
174 changed files with 36064 additions and 35819 deletions

View File

@@ -36,203 +36,219 @@
/*
* ASN.1 DER decoding routines
*/
int mbedtls_asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len )
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 ((end - *p) < 1) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
if( ( **p & 0x80 ) == 0 )
if ((**p & 0x80) == 0) {
*len = *(*p)++;
else
{
switch( **p & 0x7F )
{
case 1:
if( ( end - *p ) < 2 )
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
} else {
switch (**p & 0x7F) {
case 1:
if ((end - *p) < 2) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
*len = (*p)[1];
(*p) += 2;
break;
*len = (*p)[1];
(*p) += 2;
break;
case 2:
if( ( end - *p ) < 3 )
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
case 2:
if ((end - *p) < 3) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
*len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
(*p) += 3;
break;
*len = ((size_t) (*p)[1] << 8) | (*p)[2];
(*p) += 3;
break;
case 3:
if( ( end - *p ) < 4 )
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
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;
*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 );
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;
*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 );
default:
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
}
}
if( *len > (size_t) ( end - *p ) )
return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
if (*len > (size_t) (end - *p)) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
return( 0 );
return 0;
}
int mbedtls_asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag )
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 ((end - *p) < 1) {
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
}
if( **p != tag )
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
if (**p != tag) {
return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
}
(*p)++;
return( mbedtls_asn1_get_len( p, end, len ) );
return mbedtls_asn1_get_len(p, end, len);
}
int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
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 ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
return ret;
}
if( len != 1 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
if (len != 1) {
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
}
*val = ( **p != 0 ) ? 1 : 0;
*val = (**p != 0) ? 1 : 0;
(*p)++;
return( 0 );
return 0;
}
static int asn1_get_tagged_int( unsigned char **p,
const unsigned char *end,
int tag, int *val )
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 );
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 );
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 );
if ((**p & 0x80) != 0) {
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
}
/* Skip leading zeros. */
while( len > 0 && **p == 0 )
{
++( *p );
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 );
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;
while (len-- > 0) {
*val = (*val << 8) | **p;
(*p)++;
}
return( 0 );
return 0;
}
int mbedtls_asn1_get_int( unsigned char **p,
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 )
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) );
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 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 );
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
return ret;
}
ret = mbedtls_mpi_read_binary( X, *p, len );
ret = mbedtls_mpi_read_binary(X, *p, len);
*p += len;
return( ret );
return ret;
}
#endif /* MBEDTLS_BIGNUM_C */
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs)
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 );
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 );
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 );
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 );
if (*p != end) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
return( 0 );
return 0;
}
/*
@@ -244,105 +260,106 @@ int mbedtls_asn1_traverse_sequence_of(
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 (*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 ((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 );
if (*p + len != end) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
while( *p < end )
{
while (*p < end) {
unsigned char const tag = *(*p)++;
if( ( tag & tag_must_mask ) != tag_must_val )
return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
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 ((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 );
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 );
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 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 ((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 (*len == 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
--(*len);
if( **p != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
++( *p );
if (**p != 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
++(*p);
return( 0 );
return 0;
}
void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
{
while( seq != NULL )
{
while (seq != NULL) {
mbedtls_asn1_sequence *next = seq->next;
mbedtls_platform_zeroize( seq, sizeof( *seq ) );
mbedtls_free( seq );
mbedtls_platform_zeroize(seq, sizeof(*seq));
mbedtls_free(seq);
seq = next;
}
}
typedef struct
{
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 )
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 )
{
if (cur->buf.p != NULL) {
cur->next =
mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
if( cur->next == NULL )
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
if (cur->next == NULL) {
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
}
cur = cur->next;
}
@@ -352,124 +369,128 @@ static int asn1_get_sequence_of_cb( void *ctx,
cur->buf.tag = tag;
cb_ctx->cur = cur;
return( 0 );
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)
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 ) );
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 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 ((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 );
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 );
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 );
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, &params->len ) ) != 0 )
return( ret );
if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
return ret;
}
params->p = *p;
*p += params->len;
if( *p != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
if (*p != end) {
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
}
return( 0 );
return 0;
}
int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg )
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( &params, 0, sizeof(mbedtls_asn1_buf) );
memset(&params, 0, sizeof(mbedtls_asn1_buf));
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
return( ret );
if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
return ret;
}
if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_DATA );
if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
return( 0 );
return 0;
}
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
{
if( cur == NULL )
if (cur == NULL) {
return;
}
mbedtls_free( cur->oid.p );
mbedtls_free( cur->val.p );
mbedtls_free(cur->oid.p);
mbedtls_free(cur->val.p);
mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
}
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
{
mbedtls_asn1_named_data *cur;
while( ( cur = *head ) != NULL )
{
while ((cur = *head) != NULL) {
*head = cur->next;
mbedtls_asn1_free_named_data( cur );
mbedtls_free( cur );
mbedtls_asn1_free_named_data(cur);
mbedtls_free(cur);
}
}
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
const char *oid, size_t len )
mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(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 )
{
while (list != NULL) {
if (list->oid.len == len &&
memcmp(list->oid.p, oid, len) == 0) {
break;
}
list = list->next;
}
return( list );
return list;
}
#endif /* MBEDTLS_ASN1_PARSE_C */