/*
 * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (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 <stddef.h>
#include "internal/cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "internal/asn1_int.h"
#include "asn1_locl.h"

/*
 * Print routines.
 */

/* ASN1_PCTX routines */

static ASN1_PCTX default_pctx = {
    ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
    0,                          /* nm_flags */
    0,                          /* cert_flags */
    0,                          /* oid_flags */
    0                           /* str_flags */
};

ASN1_PCTX *ASN1_PCTX_new(void)
{
    ASN1_PCTX *ret;

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL) {
        ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    return ret;
}

void ASN1_PCTX_free(ASN1_PCTX *p)
{
    OPENSSL_free(p);
}

unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p)
{
    return p->flags;
}

void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
{
    p->flags = flags;
}

unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p)
{
    return p->nm_flags;
}

void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
{
    p->nm_flags = flags;
}

unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p)
{
    return p->cert_flags;
}

void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
{
    p->cert_flags = flags;
}

unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p)
{
    return p->oid_flags;
}

void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
{
    p->oid_flags = flags;
}

unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p)
{
    return p->str_flags;
}

void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
{
    p->str_flags = flags;
}

/* Main print routines */

static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                               const ASN1_ITEM *it,
                               const char *fname, const char *sname,
                               int nohdr, const ASN1_PCTX *pctx);

static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);

static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
                                const ASN1_ITEM *it, int indent,
                                const char *fname, const char *sname,
                                const ASN1_PCTX *pctx);

static int asn1_print_fsname(BIO *out, int indent,
                             const char *fname, const char *sname,
                             const ASN1_PCTX *pctx);

int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
                    const ASN1_ITEM *it, const ASN1_PCTX *pctx)
{
    const char *sname;
    if (pctx == NULL)
        pctx = &default_pctx;
    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
        sname = NULL;
    else
        sname = it->sname;
    return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
}

static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                               const ASN1_ITEM *it,
                               const char *fname, const char *sname,
                               int nohdr, const ASN1_PCTX *pctx)
{
    const ASN1_TEMPLATE *tt;
    const ASN1_EXTERN_FUNCS *ef;
    ASN1_VALUE **tmpfld;
    const ASN1_AUX *aux = it->funcs;
    ASN1_aux_cb *asn1_cb;
    ASN1_PRINT_ARG parg;
    int i;
    if (aux && aux->asn1_cb) {
        parg.out = out;
        parg.indent = indent;
        parg.pctx = pctx;
        asn1_cb = aux->asn1_cb;
    } else
        asn1_cb = 0;

   if (((it->itype != ASN1_ITYPE_PRIMITIVE)
       || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
            if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
                return 0;
            if (BIO_puts(out, "<ABSENT>\n") <= 0)
                return 0;
        }
        return 1;
    }

    switch (it->itype) {
    case ASN1_ITYPE_PRIMITIVE:
        if (it->templates) {
            if (!asn1_template_print_ctx(out, fld, indent,
                                         it->templates, pctx))
                return 0;
            break;
        }
        /* fall through */
    case ASN1_ITYPE_MSTRING:
        if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
            return 0;
        break;

    case ASN1_ITYPE_EXTERN:
        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
            return 0;
        /* Use new style print routine if possible */
        ef = it->funcs;
        if (ef && ef->asn1_ex_print) {
            i = ef->asn1_ex_print(out, fld, indent, "", pctx);
            if (!i)
                return 0;
            if ((i == 2) && (BIO_puts(out, "\n") <= 0))
                return 0;
            return 1;
        } else if (sname &&
                   BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
            return 0;
        break;

    case ASN1_ITYPE_CHOICE:
        /* CHOICE type, get selector */
        i = asn1_get_choice_selector(fld, it);
        /* This should never happen... */
        if ((i < 0) || (i >= it->tcount)) {
            if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
                return 0;
            return 1;
        }
        tt = it->templates + i;
        tmpfld = asn1_get_field_ptr(fld, tt);
        if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
            return 0;
        break;

    case ASN1_ITYPE_SEQUENCE:
    case ASN1_ITYPE_NDEF_SEQUENCE:
        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
            return 0;
        if (fname || sname) {
            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
                if (BIO_puts(out, " {\n") <= 0)
                    return 0;
            } else {
                if (BIO_puts(out, "\n") <= 0)
                    return 0;
            }
        }

        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
            if (i == 0)
                return 0;
            if (i == 2)
                return 1;
        }

        /* Print each field entry */
        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
            const ASN1_TEMPLATE *seqtt;
            seqtt = asn1_do_adb(fld, tt, 1);
            if (!seqtt)
                return 0;
            tmpfld = asn1_get_field_ptr(fld, seqtt);
            if (!asn1_template_print_ctx(out, tmpfld,
                                         indent + 2, seqtt, pctx))
                return 0;
        }
        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
            if (BIO_printf(out, "%*s}\n", indent, "") < 0)
                return 0;
        }

        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
            if (i == 0)
                return 0;
        }
        break;

    default:
        BIO_printf(out, "Unprocessed type %d\n", it->itype);
        return 0;
    }

    return 1;
}

static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
{
    int i, flags;
    const char *sname, *fname;
    ASN1_VALUE *tfld;
    flags = tt->flags;
    if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
        sname = ASN1_ITEM_ptr(tt->item)->sname;
    else
        sname = NULL;
    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
        fname = NULL;
    else
        fname = tt->field_name;

    /*
     * If field is embedded then fld needs fixing so it is a pointer to
     * a pointer to a field.
     */
    if (flags & ASN1_TFLG_EMBED) {
        tfld = (ASN1_VALUE *)fld;
        fld = &tfld;
    }

    if (flags & ASN1_TFLG_SK_MASK) {
        char *tname;
        ASN1_VALUE *skitem;
        STACK_OF(ASN1_VALUE) *stack;

        /* SET OF, SEQUENCE OF */
        if (fname) {
            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
                if (flags & ASN1_TFLG_SET_OF)
                    tname = "SET";
                else
                    tname = "SEQUENCE";
                if (BIO_printf(out, "%*s%s OF %s {\n",
                               indent, "", tname, tt->field_name) <= 0)
                    return 0;
            } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
                return 0;
        }
        stack = (STACK_OF(ASN1_VALUE) *)*fld;
        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
            if ((i > 0) && (BIO_puts(out, "\n") <= 0))
                return 0;

            skitem = sk_ASN1_VALUE_value(stack, i);
            if (!asn1_item_print_ctx(out, &skitem, indent + 2,
                                     ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
                                     pctx))
                return 0;
        }
        if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
            return 0;
        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
            if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
                return 0;
        }
        return 1;
    }
    return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
                               fname, sname, 0, pctx);
}

static int asn1_print_fsname(BIO *out, int indent,
                             const char *fname, const char *sname,
                             const ASN1_PCTX *pctx)
{
    static const char spaces[] = "                    ";
    static const int nspaces = sizeof(spaces) - 1;

    while (indent > nspaces) {
        if (BIO_write(out, spaces, nspaces) != nspaces)
            return 0;
        indent -= nspaces;
    }
    if (BIO_write(out, spaces, indent) != indent)
        return 0;
    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
        sname = NULL;
    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
        fname = NULL;
    if (!sname && !fname)
        return 1;
    if (fname) {
        if (BIO_puts(out, fname) <= 0)
            return 0;
    }
    if (sname) {
        if (fname) {
            if (BIO_printf(out, " (%s)", sname) <= 0)
                return 0;
        } else {
            if (BIO_puts(out, sname) <= 0)
                return 0;
        }
    }
    if (BIO_write(out, ": ", 2) != 2)
        return 0;
    return 1;
}

static int asn1_print_boolean(BIO *out, int boolval)
{
    const char *str;
    switch (boolval) {
    case -1:
        str = "BOOL ABSENT";
        break;

    case 0:
        str = "FALSE";
        break;

    default:
        str = "TRUE";
        break;

    }

    if (BIO_puts(out, str) <= 0)
        return 0;
    return 1;

}

static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str)
{
    char *s;
    int ret = 1;
    s = i2s_ASN1_INTEGER(NULL, str);
    if (s == NULL)
        return 0;
    if (BIO_puts(out, s) <= 0)
        ret = 0;
    OPENSSL_free(s);
    return ret;
}

static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid)
{
    char objbuf[80];
    const char *ln;
    ln = OBJ_nid2ln(OBJ_obj2nid(oid));
    if (!ln)
        ln = "";
    OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
    if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
        return 0;
    return 1;
}

static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
{
    if (str->type == V_ASN1_BIT_STRING) {
        if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
            return 0;
    } else if (BIO_puts(out, "\n") <= 0)
        return 0;
    if ((str->length > 0)
        && BIO_dump_indent(out, (const char *)str->data, str->length,
                           indent + 2) <= 0)
        return 0;
    return 1;
}

static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
                                const ASN1_ITEM *it, int indent,
                                const char *fname, const char *sname,
                                const ASN1_PCTX *pctx)
{
    long utype;
    ASN1_STRING *str;
    int ret = 1, needlf = 1;
    const char *pname;
    const ASN1_PRIMITIVE_FUNCS *pf;
    pf = it->funcs;
    if (!asn1_print_fsname(out, indent, fname, sname, pctx))
        return 0;
    if (pf && pf->prim_print)
        return pf->prim_print(out, fld, it, indent, pctx);
    if (it->itype == ASN1_ITYPE_MSTRING) {
        str = (ASN1_STRING *)*fld;
        utype = str->type & ~V_ASN1_NEG;
    } else {
        utype = it->utype;
        if (utype == V_ASN1_BOOLEAN)
            str = NULL;
        else
            str = (ASN1_STRING *)*fld;
    }
    if (utype == V_ASN1_ANY) {
        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
        utype = atype->type;
        fld = &atype->value.asn1_value;
        str = (ASN1_STRING *)*fld;
        if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
            pname = NULL;
        else
            pname = ASN1_tag2str(utype);
    } else {
        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
            pname = ASN1_tag2str(utype);
        else
            pname = NULL;
    }

    if (utype == V_ASN1_NULL) {
        if (BIO_puts(out, "NULL\n") <= 0)
            return 0;
        return 1;
    }

    if (pname) {
        if (BIO_puts(out, pname) <= 0)
            return 0;
        if (BIO_puts(out, ":") <= 0)
            return 0;
    }

    switch (utype) {
    case V_ASN1_BOOLEAN:
        {
            int boolval = *(int *)fld;
            if (boolval == -1)
                boolval = it->size;
            ret = asn1_print_boolean(out, boolval);
        }
        break;

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED:
        ret = asn1_print_integer(out, str);
        break;

    case V_ASN1_UTCTIME:
        ret = ASN1_UTCTIME_print(out, str);
        break;

    case V_ASN1_GENERALIZEDTIME:
        ret = ASN1_GENERALIZEDTIME_print(out, str);
        break;

    case V_ASN1_OBJECT:
        ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld);
        break;

    case V_ASN1_OCTET_STRING:
    case V_ASN1_BIT_STRING:
        ret = asn1_print_obstring(out, str, indent);
        needlf = 0;
        break;

    case V_ASN1_SEQUENCE:
    case V_ASN1_SET:
    case V_ASN1_OTHER:
        if (BIO_puts(out, "\n") <= 0)
            return 0;
        if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
            ret = 0;
        needlf = 0;
        break;

    default:
        ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);

    }
    if (!ret)
        return 0;
    if (needlf && BIO_puts(out, "\n") <= 0)
        return 0;
    return 1;
}
