/*
 * Copyright 2020-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 <string.h>
#include <stdlib.h>

#include "internal/nelem.h"

#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>

#include "../testutil.h"
#include "pkcs12.h" /* from the same directory */

/* Set this to > 0 write test data to file */
static int write_files = 0;

static int legacy = 0;

static OSSL_LIB_CTX *test_ctx = NULL;
static const char *test_propq = NULL;

/* -------------------------------------------------------------------------
 * Local function declarations
 */

static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs);

static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
static int write_p12(PKCS12 *p12, const char *outfile);

static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac);
static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac);
static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac);
static int check_asn1_string(const ASN1_TYPE *av, const char *txt);
static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs);


/* --------------------------------------------------------------------------
 * Global settings
 */

void PKCS12_helper_set_write_files(int enable)
{
    write_files = enable;
}

void PKCS12_helper_set_legacy(int enable)
{
    legacy = enable;
}

void PKCS12_helper_set_libctx(OSSL_LIB_CTX *libctx)
{
    test_ctx = libctx;
}

void PKCS12_helper_set_propq(const char *propq)
{
    test_propq = propq;
}


/* --------------------------------------------------------------------------
 * Test data load functions
 */

static X509 *load_cert_asn1(const unsigned char *bytes, int len)
{
    X509 *cert = NULL;

    cert = d2i_X509(NULL, &bytes, len);
    if (!TEST_ptr(cert))
        goto err;
err:
    return cert;
}

static EVP_PKEY *load_pkey_asn1(const unsigned char *bytes, int len)
{
    EVP_PKEY *pkey = NULL;

    pkey = d2i_AutoPrivateKey(NULL, &bytes, len);
    if (!TEST_ptr(pkey))
        goto err;
err:
    return pkey;
}

/* -------------------------------------------------------------------------
 * PKCS12 builder
 */

PKCS12_BUILDER *new_pkcs12_builder(const char *filename)
{
    PKCS12_BUILDER *pb = OPENSSL_malloc(sizeof(PKCS12_BUILDER));
    if (!TEST_ptr(pb))
        return NULL;

    pb->filename = filename;
    pb->success = 1;
    return pb;
}

int end_pkcs12_builder(PKCS12_BUILDER *pb)
{
    int result = pb->success;

    OPENSSL_free(pb);
    return result;
}


void start_pkcs12(PKCS12_BUILDER *pb)
{
    pb->safes = NULL;
}


void end_pkcs12(PKCS12_BUILDER *pb)
{
    if (!pb->success)
        return;
    generate_p12(pb, NULL);
}


void end_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
    if (!pb->success)
        return;
    generate_p12(pb, mac);
}


/* Generate the PKCS12 encoding and write to memory bio */
static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
    PKCS12 *p12;
    EVP_MD *md = NULL;

    if (!pb->success)
        return;

    pb->p12bio = BIO_new(BIO_s_mem());
    if (!TEST_ptr(pb->p12bio)) {
        pb->success = 0;
        return;
    }
    if (legacy)
        p12 = PKCS12_add_safes(pb->safes, 0);
    else
        p12 = PKCS12_add_safes_ex(pb->safes, 0, test_ctx, test_propq);
    if (!TEST_ptr(p12)) {
        pb->success = 0;
        goto err;
    }
    sk_PKCS7_pop_free(pb->safes, PKCS7_free);

    if (mac != NULL) {
        if (legacy)
            md = (EVP_MD *)EVP_get_digestbynid(mac->nid);
        else
            md = EVP_MD_fetch(test_ctx, OBJ_nid2sn(mac->nid), test_propq);

        if (!TEST_true(PKCS12_set_mac(p12, mac->pass, strlen(mac->pass),
                                      NULL, 0, mac->iter, md))) {
            pb->success = 0;
            goto err;
        }
    }
    i2d_PKCS12_bio(pb->p12bio, p12);

    /* Can write to file here for debug */
    if (write_files)
        write_p12(p12, pb->filename);
err:
    if (!legacy && md != NULL)
        EVP_MD_free(md);
    PKCS12_free(p12);
}


static int write_p12(PKCS12 *p12, const char *outfile)
{
    int ret = 0;
    BIO *out = BIO_new_file(outfile, "w");

    if (out == NULL)
        goto err;

    if (!TEST_int_eq(i2d_PKCS12_bio(out, p12), 1))
        goto err;
    ret = 1;
err:
    BIO_free(out);
    return ret;
}

static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac)
{
    PKCS12 *p12 = NULL;

    /* Supply a p12 with library context/propq to the d2i decoder*/
    if (!legacy) {
        p12 = PKCS12_init_ex(NID_pkcs7_data, test_ctx, test_propq);
        if (!TEST_ptr(p12))
            goto err;
    }
    p12 = d2i_PKCS12_bio(bio, &p12);
    BIO_free(bio);
    if (!TEST_ptr(p12))
        goto err;
    if (mac == NULL) {
        if (!TEST_false(PKCS12_mac_present(p12)))
            goto err;
    } else {
        if (!check_p12_mac(p12, mac))
            goto err;
    }
    return p12;
err:
    PKCS12_free(p12);
    return NULL;
}


/* For use with existing files */
static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac)
{
    PKCS12 *p12 = NULL;
    BIO *in = BIO_new_file(infile, "r");

    if (in == NULL)
        goto err;
    p12 = d2i_PKCS12_bio(in, NULL);
    BIO_free(in);
    if (!TEST_ptr(p12))
        goto err;
    if (mac == NULL) {
        if (!TEST_false(PKCS12_mac_present(p12)))
            goto err;
    } else {
        if (!check_p12_mac(p12, mac))
            goto err;
    }
    return p12;
err:
    PKCS12_free(p12);
    return NULL;
}

static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac)
{
    return TEST_true(PKCS12_mac_present(p12))
        && TEST_true(PKCS12_verify_mac(p12, mac->pass, strlen(mac->pass)));
}


/* -------------------------------------------------------------------------
 * PKCS7 content info builder
 */

void start_contentinfo(PKCS12_BUILDER *pb)
{
    pb->bags = NULL;
}


void end_contentinfo(PKCS12_BUILDER *pb)
{
    if (pb->success && pb->bags != NULL) {
        if (!TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, -1, 0, NULL)))
            pb->success = 0;
    }
    sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
    pb->bags = NULL;
}


void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
    if (pb->success && pb->bags != NULL) {
        if (legacy) {
            if (!TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, enc->nid,
                                           enc->iter, enc->pass)))
                pb->success = 0;
        } else {
            if (!TEST_true(PKCS12_add_safe_ex(&pb->safes, pb->bags, enc->nid,
                                              enc->iter, enc->pass, test_ctx,
                                              test_propq)))
                pb->success = 0;
        }
    }
    sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
    pb->bags = NULL;
}


static STACK_OF(PKCS12_SAFEBAG) *decode_contentinfo(STACK_OF(PKCS7) *safes, int idx, const PKCS12_ENC *enc)
{
    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
    int bagnid;
    PKCS7 *p7 = sk_PKCS7_value(safes, idx);

    if (!TEST_ptr(p7))
        goto err;

    bagnid = OBJ_obj2nid(p7->type);
    if (enc) {
        if (!TEST_int_eq(bagnid, NID_pkcs7_encrypted))
            goto err;
        bags = PKCS12_unpack_p7encdata(p7, enc->pass, strlen(enc->pass));
    } else {
        if (!TEST_int_eq(bagnid, NID_pkcs7_data))
            goto err;
        bags = PKCS12_unpack_p7data(p7);
    }
    if (!TEST_ptr(bags))
        goto err;

    return bags;
err:
    return NULL;
}


/* -------------------------------------------------------------------------
 * PKCS12 safeBag/attribute builder
 */

static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs)
{
    int ret = 0;
    int attr_nid;
    const PKCS12_ATTR *p_attr = attrs;

    if (attrs == NULL)
        return 1;

    while (p_attr->oid != NULL) {
        TEST_info("Adding attribute %s = %s", p_attr->oid, p_attr->value);
        attr_nid = OBJ_txt2nid(p_attr->oid);

        if (attr_nid == NID_friendlyName) {
            if (!TEST_true(PKCS12_add_friendlyname(bag, p_attr->value, -1)))
                goto err;
        } else if (attr_nid == NID_localKeyID) {
            if (!TEST_true(PKCS12_add_localkeyid(bag, (unsigned char *)p_attr->value,
                                                 strlen(p_attr->value))))
                goto err;
        } else {
            /* Custom attribute values limited to ASCII in these tests */
            if (!TEST_true(PKCS12_add1_attr_by_txt(bag, p_attr->oid, MBSTRING_ASC,
                                                   (unsigned char *)p_attr->value,
                                                   strlen(p_attr->value))))
                goto err;
        }
        p_attr++;
    }
    ret = 1;
err:
    return ret;
}

void add_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
                 const PKCS12_ATTR *attrs)
{
    PKCS12_SAFEBAG *bag = NULL;
    X509 *cert = NULL;
    char *name;

    if (!pb->success)
        return;

    cert = load_cert_asn1(bytes, len);
    if (!TEST_ptr(cert)) {
        pb->success = 0;
        return;
    }

    name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
    TEST_info("Adding certificate <%s>", name);
    OPENSSL_free(name);

    bag = PKCS12_add_cert(&pb->bags, cert);
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        goto err;
    }

    if (!TEST_true(add_attributes(bag, attrs))) {
        pb->success = 0;
        goto err;
    }
err:
    X509_free(cert);
}

void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
                const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
{
    PKCS12_SAFEBAG *bag = NULL;
    EVP_PKEY *pkey = NULL;

    if (!pb->success)
        return;

    TEST_info("Adding key");

    pkey = load_pkey_asn1(bytes, len);
    if (!TEST_ptr(pkey)) {
        pb->success = 0;
        return;
    }

    if (legacy)
        bag = PKCS12_add_key(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass);
    else
        bag = PKCS12_add_key_ex(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass,
                                test_ctx, test_propq);
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        goto err;
    }
    if (!add_attributes(bag, attrs))
        pb->success = 0;
err:
    EVP_PKEY_free(pkey);
}

void add_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret,
                               const PKCS12_ATTR *attrs)
{
    PKCS12_SAFEBAG *bag = NULL;

    if (!pb->success)
        return;

    TEST_info("Adding secret <%s>", secret);

    bag = PKCS12_add_secret(&pb->bags, secret_nid, (const unsigned char *)secret, strlen(secret));
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        return;
    }
    if (!add_attributes(bag, attrs))
        pb->success = 0;
}


/* -------------------------------------------------------------------------
 * PKCS12 structure checking
 */

static int check_asn1_string(const ASN1_TYPE *av, const char *txt)
{
    int ret = 0;
    char *value = NULL;

    if (!TEST_ptr(av))
        goto err;

    switch (av->type) {
    case V_ASN1_BMPSTRING:
        value = OPENSSL_uni2asc(av->value.bmpstring->data,
                                av->value.bmpstring->length);
        if (!TEST_str_eq(txt, (char *)value))
            goto err;
        break;

    case V_ASN1_UTF8STRING:
        if (!TEST_mem_eq(txt, strlen(txt), (char *)av->value.utf8string->data,
                         av->value.utf8string->length))
            goto err;
        break;

    case V_ASN1_OCTET_STRING:
        if (!TEST_mem_eq(txt, strlen(txt),
                         (char *)av->value.octet_string->data,
                         av->value.octet_string->length))
            goto err;
        break;

    default:
        /* Tests do not support other attribute types currently */
        goto err;
    }
    ret = 1;
err:
    OPENSSL_free(value);
    return ret;
}

static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs)
{
    int ret = 0;
    X509_ATTRIBUTE *attr;
    ASN1_TYPE *av;
    int i, j;
    char attr_txt[100];

    for (i = 0; i < sk_X509_ATTRIBUTE_num(bag_attrs); i++) {
        const PKCS12_ATTR *p_attr = attrs;
        ASN1_OBJECT *attr_obj;

        attr = sk_X509_ATTRIBUTE_value(bag_attrs, i);
        attr_obj = X509_ATTRIBUTE_get0_object(attr);
        OBJ_obj2txt(attr_txt, 100, attr_obj, 0);

        while (p_attr->oid != NULL) {
            /* Find a matching attribute type */
            if (strcmp(p_attr->oid, attr_txt) == 0) {
                if (!TEST_int_eq(X509_ATTRIBUTE_count(attr), 1))
                    goto err;

                for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
                {
                    av = X509_ATTRIBUTE_get0_type(attr, j);
                    if (!TEST_true(check_asn1_string(av, p_attr->value)))
                        goto err;
                }
                break;
            }
            p_attr++;
        }
    }
    ret = 1;
err:
    return ret;
}

void check_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
                   const PKCS12_ATTR *attrs)
{
    X509 *x509 = NULL;
    X509 *ref_x509 = NULL;
    const PKCS12_SAFEBAG *bag;

    if (!pb->success)
        return;

    bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        return;
    }
    if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
        || !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_certBag)
        || !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), NID_x509Certificate)) {
        pb->success = 0;
        return;
    }
    x509 = PKCS12_SAFEBAG_get1_cert(bag);
    if (!TEST_ptr(x509)) {
        pb->success = 0;
        goto err;
    }
    ref_x509 = load_cert_asn1(bytes, len);
    if (!TEST_false(X509_cmp(x509, ref_x509)))
        pb->success = 0;
err:
    X509_free(x509);
    X509_free(ref_x509);
}

void check_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
                  const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
{
    EVP_PKEY *pkey = NULL;
    EVP_PKEY *ref_pkey = NULL;
    PKCS8_PRIV_KEY_INFO *p8;
    const PKCS8_PRIV_KEY_INFO *p8c;
    const PKCS12_SAFEBAG *bag;

    if (!pb->success)
        return;

    bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        return;
    }

    if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)) {
        pb->success = 0;
        return;
    }

    switch (PKCS12_SAFEBAG_get_nid(bag)) {
    case NID_keyBag:
        p8c = PKCS12_SAFEBAG_get0_p8inf(bag);
        if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8c))) {
            pb->success = 0;
            goto err;
        }
        break;

    case NID_pkcs8ShroudedKeyBag:
        if (legacy)
            p8 = PKCS12_decrypt_skey(bag, enc->pass, strlen(enc->pass));
        else
            p8 = PKCS12_decrypt_skey_ex(bag, enc->pass, strlen(enc->pass), test_ctx, test_propq);
        if (!TEST_ptr(p8)) {
            pb->success = 0;
            goto err;
        }
        if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8))) {
            PKCS8_PRIV_KEY_INFO_free(p8);
            pb->success = 0;
            goto err;
        }
        PKCS8_PRIV_KEY_INFO_free(p8);
        break;

    default:
        pb->success = 0;
        goto err;
    }

    /* PKEY compare returns 1 for match */
    ref_pkey = load_pkey_asn1(bytes, len);
    if (!TEST_true(EVP_PKEY_eq(pkey, ref_pkey)))
        pb->success = 0;
err:
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(ref_pkey);
}

void check_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret, const PKCS12_ATTR *attrs)
{
    const PKCS12_SAFEBAG *bag;

    if (!pb->success)
        return;

    bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
    if (!TEST_ptr(bag)) {
        pb->success = 0;
        return;
    }

    if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
        || !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_secretBag)
        || !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), secret_nid)
        || !TEST_true(check_asn1_string(PKCS12_SAFEBAG_get0_bag_obj(bag), secret)))
        pb->success = 0;
}


void start_check_pkcs12(PKCS12_BUILDER *pb)
{
    PKCS12 *p12;

    if (!pb->success)
        return;

    p12 = from_bio_p12(pb->p12bio, NULL);
    if (!TEST_ptr(p12)) {
        pb->success = 0;
        return;
    }
    pb->safes = PKCS12_unpack_authsafes(p12);
    if (!TEST_ptr(pb->safes))
        pb->success = 0;

    pb->safe_idx = 0;
    PKCS12_free(p12);
}

void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
    PKCS12 *p12;

    if (!pb->success)
        return;

    p12 = from_bio_p12(pb->p12bio, mac);
    if (!TEST_ptr(p12)) {
        pb->success = 0;
        return;
    }
    pb->safes = PKCS12_unpack_authsafes(p12);
    if (!TEST_ptr(pb->safes))
        pb->success = 0;

    pb->safe_idx = 0;
    PKCS12_free(p12);
}

void start_check_pkcs12_file(PKCS12_BUILDER *pb)
{
    PKCS12 *p12;

    if (!pb->success)
        return;

    p12 = read_p12(pb->filename, NULL);
    if (!TEST_ptr(p12)) {
        pb->success = 0;
        return;
    }
    pb->safes = PKCS12_unpack_authsafes(p12);
    if (!TEST_ptr(pb->safes))
        pb->success = 0;

    pb->safe_idx = 0;
    PKCS12_free(p12);
}

void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
    PKCS12 *p12;

    if (!pb->success)
        return;

    p12 = read_p12(pb->filename, mac);
    if (!TEST_ptr(p12)) {
        pb->success = 0;
        return;
    }
    pb->safes = PKCS12_unpack_authsafes(p12);
    if (!TEST_ptr(pb->safes))
        pb->success = 0;

    pb->safe_idx = 0;
    PKCS12_free(p12);
}

void end_check_pkcs12(PKCS12_BUILDER *pb)
{
    if (!pb->success)
        return;

    sk_PKCS7_pop_free(pb->safes, PKCS7_free);
}


void start_check_contentinfo(PKCS12_BUILDER *pb)
{
    if (!pb->success)
        return;

    pb->bag_idx = 0;
    pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, NULL);
    if (!TEST_ptr(pb->bags)) {
        pb->success = 0;
        return;
    }
    TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
}

void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
    if (!pb->success)
        return;

    pb->bag_idx = 0;
    pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, enc);
    if (!TEST_ptr(pb->bags)) {
        pb->success = 0;
        return;
    }
    TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
}


void end_check_contentinfo(PKCS12_BUILDER *pb)
{
    if (!pb->success)
        return;

    if (!TEST_int_eq(sk_PKCS12_SAFEBAG_num(pb->bags), pb->bag_idx))
        pb->success = 0;
    sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
    pb->bags = NULL;
}


