/*
 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include "asn1_local.h"

/*
 * Custom primitive types for handling int32_t, int64_t, uint32_t, uint64_t.
 * This converts between an ASN1_INTEGER and those types directly.
 * This is preferred to using the LONG / ZLONG primitives.
 */

/*
 * We abuse the ASN1_ITEM fields |size| as a flags field
 */
#define INTxx_FLAG_ZERO_DEFAULT (1<<0)
#define INTxx_FLAG_SIGNED       (1<<1)

static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t))) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    return 1;
}

static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    OPENSSL_free(*pval);
    *pval = NULL;
}

static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    **(uint64_t **)pval = 0;
}

static int uint64_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                      const ASN1_ITEM *it)
{
    uint64_t utmp;
    int neg = 0;
    /* this exists to bypass broken gcc optimization */
    char *cp = (char *)*pval;

    /* use memcpy, because we may not be uint64_t aligned */
    memcpy(&utmp, cp, sizeof(utmp));

    if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
        && utmp == 0)
        return -1;
    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
        && (int64_t)utmp < 0) {
        /* ossl_i2c_uint64_int() assumes positive values */
        utmp = 0 - utmp;
        neg = 1;
    }

    return ossl_i2c_uint64_int(cont, utmp, neg);
}

static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                      int utype, char *free_cont, const ASN1_ITEM *it)
{
    uint64_t utmp = 0;
    char *cp;
    int neg = 0;

    if (*pval == NULL && !uint64_new(pval, it))
        return 0;

    cp = (char *)*pval;

    /*
     * Strictly speaking, zero length is malformed.  However, long_c2i
     * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course),
     * so for the sake of backward compatibility, we still decode zero
     * length INTEGERs as the number zero.
     */
    if (len == 0)
        goto long_compat;

    if (!ossl_c2i_uint64_int(&utmp, &neg, &cont, len))
        return 0;
    if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
        ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
        return 0;
    }
    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
            && !neg && utmp > INT64_MAX) {
        ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE);
        return 0;
    }
    if (neg)
        /* ossl_c2i_uint64_int() returns positive values */
        utmp = 0 - utmp;

 long_compat:
    memcpy(cp, &utmp, sizeof(utmp));
    return 1;
}

static int uint64_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                        int indent, const ASN1_PCTX *pctx)
{
    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
        return BIO_printf(out, "%jd\n", **(int64_t **)pval);
    return BIO_printf(out, "%ju\n", **(uint64_t **)pval);
}

/* 32-bit variants */

static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    if ((*pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t))) == NULL) {
        ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    return 1;
}

static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    OPENSSL_free(*pval);
    *pval = NULL;
}

static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    **(uint32_t **)pval = 0;
}

static int uint32_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
                      const ASN1_ITEM *it)
{
    uint32_t utmp;
    int neg = 0;
    /* this exists to bypass broken gcc optimization */
    char *cp = (char *)*pval;

    /* use memcpy, because we may not be uint32_t aligned */
    memcpy(&utmp, cp, sizeof(utmp));

    if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
        && utmp == 0)
        return -1;
    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
        && (int32_t)utmp < 0) {
        /* ossl_i2c_uint64_int() assumes positive values */
        utmp = 0 - utmp;
        neg = 1;
    }

    return ossl_i2c_uint64_int(cont, (uint64_t)utmp, neg);
}

/*
 * Absolute value of INT32_MIN: we can't just use -INT32_MIN as it produces
 * overflow warnings.
 */

#define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1)

static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
                      int utype, char *free_cont, const ASN1_ITEM *it)
{
    uint64_t utmp = 0;
    uint32_t utmp2 = 0;
    char *cp;
    int neg = 0;

    if (*pval == NULL && !uint64_new(pval, it))
        return 0;

    cp = (char *)*pval;

    /*
     * Strictly speaking, zero length is malformed.  However, long_c2i
     * (x_long.c) encodes 0 as a zero length INTEGER (wrongly, of course),
     * so for the sake of backward compatibility, we still decode zero
     * length INTEGERs as the number zero.
     */
    if (len == 0)
        goto long_compat;

    if (!ossl_c2i_uint64_int(&utmp, &neg, &cont, len))
        return 0;
    if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
        ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
        return 0;
    }
    if (neg) {
        if (utmp > ABS_INT32_MIN) {
            ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
            return 0;
        }
        utmp = 0 - utmp;
    } else {
        if (((it->size & INTxx_FLAG_SIGNED) != 0 && utmp > INT32_MAX)
            || ((it->size & INTxx_FLAG_SIGNED) == 0 && utmp > UINT32_MAX)) {
            ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE);
            return 0;
        }
    }

 long_compat:
    utmp2 = (uint32_t)utmp;
    memcpy(cp, &utmp2, sizeof(utmp2));
    return 1;
}

static int uint32_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
                        int indent, const ASN1_PCTX *pctx)
{
    if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
        return BIO_printf(out, "%d\n", **(int32_t **)pval);
    return BIO_printf(out, "%u\n", **(uint32_t **)pval);
}


/* Define the primitives themselves */

static ASN1_PRIMITIVE_FUNCS uint32_pf = {
    NULL, 0,
    uint32_new,
    uint32_free,
    uint32_clear,
    uint32_c2i,
    uint32_i2c,
    uint32_print
};

static ASN1_PRIMITIVE_FUNCS uint64_pf = {
    NULL, 0,
    uint64_new,
    uint64_free,
    uint64_clear,
    uint64_c2i,
    uint64_i2c,
    uint64_print
};

ASN1_ITEM_start(INT32)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
    INTxx_FLAG_SIGNED, "INT32"
ASN1_ITEM_end(INT32)

ASN1_ITEM_start(UINT32)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32"
ASN1_ITEM_end(UINT32)

ASN1_ITEM_start(INT64)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
    INTxx_FLAG_SIGNED, "INT64"
ASN1_ITEM_end(INT64)

ASN1_ITEM_start(UINT64)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64"
ASN1_ITEM_end(UINT64)

ASN1_ITEM_start(ZINT32)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
    INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32"
ASN1_ITEM_end(ZINT32)

ASN1_ITEM_start(ZUINT32)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
    INTxx_FLAG_ZERO_DEFAULT, "ZUINT32"
ASN1_ITEM_end(ZUINT32)

ASN1_ITEM_start(ZINT64)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
    INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64"
ASN1_ITEM_end(ZINT64)

ASN1_ITEM_start(ZUINT64)
    ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
    INTxx_FLAG_ZERO_DEFAULT, "ZUINT64"
ASN1_ITEM_end(ZUINT64)

