/*
 *  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_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, &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;
}

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

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) {
            break;
        }

        list = list->next;
    }

    return list;
}

#endif /* MBEDTLS_ASN1_PARSE_C */
