/*
 * Copyright (C) 2017 Metrological Group B.V.
 * Copyright (C) 2017 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Utilities.h"

#include <mutex>
#include <wtf/Vector.h>

namespace PAL {
namespace TASN1 {

static asn1_node asn1Definitions()
{
    // Generated with `asn1Parser WebCrypto.asn`.

    static asn1_node s_definitions;
    static const asn1_static_node s_WebCryptoASN1[] = {
        { "WebCrypto", 536872976, nullptr },
        { nullptr, 1073741836, nullptr },
        { "SubjectPublicKeyInfo", 1610612741, nullptr },
        { "algorithm", 1073741826, "AlgorithmIdentifier"},
        { "subjectPublicKey", 6, nullptr },
        { "AlgorithmIdentifier", 1610612741, nullptr },
        { "algorithm", 1073741836, nullptr },
        { "parameters", 541081613, nullptr },
        { "algorithm", 1, nullptr },
        { "PrivateKeyInfo", 1610612741, nullptr },
        { "version", 1073741826, "Version"},
        { "privateKeyAlgorithm", 1073741826, "PrivateKeyAlgorithmIdentifier"},
        { "privateKey", 1073741826, "PrivateKey"},
        { "attributes", 536895490, "Attributes"},
        { nullptr, 4104, "0"},
        { "Version", 1073741827, nullptr },
        { "PrivateKeyAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
        { "PrivateKey", 1073741831, nullptr },
        { "Attributes", 1610612751, nullptr },
        { nullptr, 2, "Attribute"},
        { "Attribute", 1610612741, nullptr },
        { "type", 1073741836, nullptr },
        { "values", 2, "AttributeSetValue"},
        { "AttributeSetValue", 1610612751, nullptr },
        { nullptr, 13, nullptr },
        { "ECParameters", 1610612754, nullptr },
        { "namedCurve", 12, nullptr },
        { "ECPrivateKey", 1610612741, nullptr },
        { "version", 1073741827, nullptr },
        { "privateKey", 1073741831, nullptr },
        { "parameters", 1610637314, "ECParameters"},
        { nullptr, 2056, "0"},
        { "publicKey", 536895494, nullptr },
        { nullptr, 2056, "1"},
        { "RSAPublicKey", 1610612741, nullptr },
        { "modulus", 1073741827, nullptr },
        { "publicExponent", 3, nullptr },
        { "RSAPrivateKey", 1610612741, nullptr },
        { "version", 1073741826, "Version"},
        { "modulus", 1073741827, nullptr },
        { "publicExponent", 1073741827, nullptr },
        { "privateExponent", 1073741827, nullptr },
        { "prime1", 1073741827, nullptr },
        { "prime2", 1073741827, nullptr },
        { "exponent1", 1073741827, nullptr },
        { "exponent2", 1073741827, nullptr },
        { "coefficient", 1073741827, nullptr },
        { "otherPrimeInfos", 16386, "OtherPrimeInfos"},
        { "OtherPrimeInfos", 1612709899, nullptr },
        { "MAX", 1074266122, "1"},
        { nullptr, 2, "OtherPrimeInfo"},
        { "OtherPrimeInfo", 536870917, nullptr },
        { "prime", 1073741827, nullptr },
        { "exponent", 1073741827, nullptr },
        { "coefficient", 3, nullptr },
        { nullptr, 0, nullptr }
    };

    static std::once_flag s_onceFlag;
    std::call_once(s_onceFlag, [] { asn1_array2tree(s_WebCryptoASN1, &s_definitions, nullptr); });

    return s_definitions;
}

bool createStructure(const char* elementName, asn1_node* root)
{
    int ret = asn1_create_element(asn1Definitions(), elementName, root);
    return ret == ASN1_SUCCESS;
}

bool decodeStructure(asn1_node* root, const char* elementName, const Vector<uint8_t>& data)
{
    if (!createStructure(elementName, root))
        return false;

    int dataSize = data.size();
    int ret = asn1_der_decoding2(root, data.data(), &dataSize, ASN1_DECODE_FLAG_STRICT_DER, nullptr);
    return ret == ASN1_SUCCESS;
}

std::optional<Vector<uint8_t>> elementData(asn1_node root, const char* elementName)
{
    int length = 0;
    unsigned type = 0;
    int ret = asn1_read_value_type(root, elementName, nullptr, &length, &type);
    if (ret != ASN1_MEM_ERROR)
        return std::nullopt;

    if (type == ASN1_ETYPE_BIT_STRING) {
        if (length % 8)
            return std::nullopt;
        length /= 8;
    }

    Vector<uint8_t> data(length);
    ret = asn1_read_value(root, elementName, data.data(), &length);
    if (ret != ASN1_SUCCESS)
        return std::nullopt;

    return data;
}

std::optional<Vector<uint8_t>> encodedData(asn1_node root, const char* elementName)
{
    int length = 0;
    int ret = asn1_der_coding(root, elementName, nullptr, &length, nullptr);
    if (ret != ASN1_MEM_ERROR)
        return std::nullopt;

    Vector<uint8_t> data(length);
    ret = asn1_der_coding(root, elementName, data.data(), &length, nullptr);
    if (ret != ASN1_SUCCESS)
        return std::nullopt;

    return data;
}

bool writeElement(asn1_node root, const char* elementName, const void* data, size_t dataSize)
{
    int ret = asn1_write_value(root, elementName, data, dataSize);
    return ret == ASN1_SUCCESS;
}

} // namespace TASN1
} // namespace PAL
