/*
 *  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

#include "mbedtls/platform.h"

/*
 * 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_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, &params->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( &params, 0, sizeof(mbedtls_asn1_buf) );

    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 );

    return( 0 );
}

#if !defined(MBEDTLS_DEPRECATED_REMOVED)
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 ) );
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */

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_free( cur->oid.p );
        mbedtls_free( cur->val.p );
        mbedtls_free( cur );
    }
}

void mbedtls_asn1_free_named_data_list_shallow( mbedtls_asn1_named_data *name )
{
    for( mbedtls_asn1_named_data *next; name != NULL; name = next )
    {
        next = name->next;
        mbedtls_free( name );
    }
}

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 */
