/*
 * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
 *
 * 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 "CryptoKeyEC.h"

#if ENABLE(WEB_CRYPTO)

#include "CommonCryptoDERUtilities.h"
#include "JsonWebKey.h"
#include <wtf/text/Base64.h>

namespace WebCore {

static const unsigned char InitialOctetEC = 0x04; // Per Section 2.3.3 of http://www.secg.org/sec1-v2.pdf
// OID id-ecPublicKey 1.2.840.10045.2.1.
static const unsigned char IdEcPublicKey[] = {0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
// OID secp256r1 1.2.840.10045.3.1.7.
static constexpr unsigned char Secp256r1[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
// OID secp384r1 1.3.132.0.34
static constexpr unsigned char Secp384r1[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22};
// OID secp521r1 1.3.132.0.35
static constexpr unsigned char Secp521r1[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23};

// Version 1. Per https://tools.ietf.org/html/rfc5915#section-3
static const unsigned char PrivateKeyVersion[] = {0x02, 0x01, 0x01};
// Tagged type [1]
static const unsigned char TaggedType1 = 0xa1;

static constexpr size_t sizeCeil(float f)
{
    auto s = static_cast<size_t>(f);
    return f > s ? s + 1 : s;
}

static constexpr size_t keySizeInBitsFromNamedCurve(CryptoKeyEC::NamedCurve curve)
{
    switch (curve) {
    case CryptoKeyEC::NamedCurve::P256:
        return 256;
    case CryptoKeyEC::NamedCurve::P384:
        return 384;
    case CryptoKeyEC::NamedCurve::P521:
        return 521;
    }

    ASSERT_NOT_REACHED();
    return 0;
}

static constexpr size_t keySizeInBytesFromNamedCurve(CryptoKeyEC::NamedCurve curve)
{
    return sizeCeil(keySizeInBitsFromNamedCurve(curve) / 8.);
}

// Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
// We only support uncompressed point format.
static constexpr bool doesUncompressedPointMatchNamedCurve(CryptoKeyEC::NamedCurve curve, size_t size)
{
    return (keySizeInBytesFromNamedCurve(curve) * 2 + 1) == size;
}

// Per Section 2.3.5 of http://www.secg.org/sec1-v2.pdf
static constexpr bool doesFieldElementMatchNamedCurve(CryptoKeyEC::NamedCurve curve, size_t size)
{
    return keySizeInBytesFromNamedCurve(curve) == size;
}

size_t CryptoKeyEC::keySizeInBits() const
{
    int result = CCECGetKeySize(m_platformKey.get());
    return result ? result : 0;
}

bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
{
    return curve == NamedCurve::P256 || curve == NamedCurve::P384 || curve == NamedCurve::P521;
}

std::optional<CryptoKeyPair> CryptoKeyEC::platformGeneratePair(CryptoAlgorithmIdentifier identifier, NamedCurve curve, bool extractable, CryptoKeyUsageBitmap usages)
{
    size_t size = keySizeInBitsFromNamedCurve(curve);
    CCECCryptorRef ccPublicKey = nullptr;
    CCECCryptorRef ccPrivateKey = nullptr;
    if (CCECCryptorGeneratePair(size, &ccPublicKey, &ccPrivateKey))
        return std::nullopt;

    auto publicKey = CryptoKeyEC::create(identifier, curve, CryptoKeyType::Public, PlatformECKeyContainer(ccPublicKey), true, usages);
    auto privateKey = CryptoKeyEC::create(identifier, curve, CryptoKeyType::Private, PlatformECKeyContainer(ccPrivateKey), extractable, usages);
    return CryptoKeyPair { WTFMove(publicKey), WTFMove(privateKey) };
}

RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportRaw(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
{
    if (!doesUncompressedPointMatchNamedCurve(curve, keyData.size()))
        return nullptr;

    CCECCryptorRef ccPublicKey = nullptr;
    if (CCECCryptorImportKey(kCCImportKeyBinary, keyData.data(), keyData.size(), ccECKeyPublic, &ccPublicKey))
        return nullptr;

    return create(identifier, curve, CryptoKeyType::Public, PlatformECKeyContainer(ccPublicKey), extractable, usages);
}

Vector<uint8_t> CryptoKeyEC::platformExportRaw() const
{
    size_t expectedSize = 2 * keySizeInBytes() + 1; // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
    Vector<uint8_t> result(expectedSize);
    size_t size = result.size();
    if (UNLIKELY(CCECCryptorExportKey(kCCImportKeyBinary, result.data(), &size, ccECKeyPublic, m_platformKey.get()) || size != expectedSize))
        return { };
    return result;
}

RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportJWKPublic(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap usages)
{
    if (!doesFieldElementMatchNamedCurve(curve, x.size()) || !doesFieldElementMatchNamedCurve(curve, y.size()))
        return nullptr;

    size_t size = keySizeInBitsFromNamedCurve(curve);
    CCECCryptorRef ccPublicKey = nullptr;
    if (CCECCryptorCreateFromData(size, x.data(), x.size(), y.data(), y.size(), &ccPublicKey))
        return nullptr;

    return create(identifier, curve, CryptoKeyType::Public, PlatformECKeyContainer(ccPublicKey), extractable, usages);
}

RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportJWKPrivate(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, Vector<uint8_t>&& d, bool extractable, CryptoKeyUsageBitmap usages)
{
    if (!doesFieldElementMatchNamedCurve(curve, x.size()) || !doesFieldElementMatchNamedCurve(curve, y.size()) || !doesFieldElementMatchNamedCurve(curve, d.size()))
        return nullptr;

    // A hack to CommonCrypto since it doesn't provide API for creating private keys directly from x, y, d.
    // BinaryInput = InitialOctetEC + X + Y + D
    Vector<uint8_t> binaryInput;
    binaryInput.append(InitialOctetEC);
    binaryInput.appendVector(x);
    binaryInput.appendVector(y);
    binaryInput.appendVector(d);

    CCECCryptorRef ccPrivateKey = nullptr;
    if (CCECCryptorImportKey(kCCImportKeyBinary, binaryInput.data(), binaryInput.size(), ccECKeyPrivate, &ccPrivateKey))
        return nullptr;

    return create(identifier, curve, CryptoKeyType::Private, PlatformECKeyContainer(ccPrivateKey), extractable, usages);
}

bool CryptoKeyEC::platformAddFieldElements(JsonWebKey& jwk) const
{
    size_t keySizeInBytes = this->keySizeInBytes();
    size_t publicKeySize = keySizeInBytes * 2 + 1; // 04 + X + Y per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
    size_t privateKeySize = keySizeInBytes * 3 + 1; // 04 + X + Y + D

    Vector<uint8_t> result(privateKeySize);
    size_t size = result.size();
    switch (type()) {
    case CryptoKeyType::Public:
        if (UNLIKELY(CCECCryptorExportKey(kCCImportKeyBinary, result.data(), &size, ccECKeyPublic, m_platformKey.get())))
            return false;
        break;
    case CryptoKeyType::Private:
        if (UNLIKELY(CCECCryptorExportKey(kCCImportKeyBinary, result.data(), &size, ccECKeyPrivate, m_platformKey.get())))
            return false;
        break;
    default:
        ASSERT_NOT_REACHED();
        return false;
    }

    if (UNLIKELY((size != publicKeySize) && (size != privateKeySize)))
        return false;
    jwk.x = base64URLEncodeToString(result.data() + 1, keySizeInBytes);
    jwk.y = base64URLEncodeToString(result.data() + keySizeInBytes + 1, keySizeInBytes);
    if (size > publicKeySize)
        jwk.d = base64URLEncodeToString(result.data() + publicKeySize, keySizeInBytes);
    return true;
}

static size_t getOID(CryptoKeyEC::NamedCurve curve, const uint8_t*& oid)
{
    size_t oidSize;
    switch (curve) {
    case CryptoKeyEC::NamedCurve::P256:
        oid = Secp256r1;
        oidSize = sizeof(Secp256r1);
        break;
    case CryptoKeyEC::NamedCurve::P384:
        oid = Secp384r1;
        oidSize = sizeof(Secp384r1);
        break;
    case CryptoKeyEC::NamedCurve::P521:
        oid = Secp521r1;
        oidSize = sizeof(Secp521r1);
        break;
    }
    return oidSize;
}

// Per https://www.ietf.org/rfc/rfc5280.txt
// SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }
// AlgorithmIdentifier  ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL }
// Per https://www.ietf.org/rfc/rfc5480.txt
// id-ecPublicKey OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
// secp256r1 OBJECT IDENTIFIER      ::= { iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 }
// secp384r1 OBJECT IDENTIFIER      ::= { iso(1) identified-organization(3) certicom(132) curve(0) 34 }
// secp521r1 OBJECT IDENTIFIER      ::= { iso(1) identified-organization(3) certicom(132) curve(0) 35 }
RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportSpki(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
{
    // The following is a loose check on the provided SPKI key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
    // Once the underlying crypto library is updated to accept SPKI EC Key, we should remove this hack.
    // <rdar://problem/30987628>
    size_t index = 1; // Read SEQUENCE
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]); // Read length
    if (keyData.size() < index + sizeof(IdEcPublicKey))
        return nullptr;
    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
        return nullptr;
    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
    const uint8_t* oid;
    size_t oidSize = getOID(curve, oid);
    if (keyData.size() < index + oidSize)
        return nullptr;
    if (memcmp(keyData.data() + index, oid, oidSize))
        return nullptr;
    index += oidSize + 1; // Read named curve OID, BIT STRING
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet

    if (!doesUncompressedPointMatchNamedCurve(curve, keyData.size() - index))
        return nullptr;

    CCECCryptorRef ccPublicKey = nullptr;
    if (CCECCryptorImportKey(kCCImportKeyBinary, keyData.data() + index, keyData.size() - index, ccECKeyPublic, &ccPublicKey))
        return nullptr;

    return create(identifier, curve, CryptoKeyType::Public, PlatformECKeyContainer(ccPublicKey), extractable, usages);
}

Vector<uint8_t> CryptoKeyEC::platformExportSpki() const
{
    size_t expectedKeySize = 2 * keySizeInBytes() + 1; // Per Section 2.3.4 of http://www.secg.org/sec1-v2.pdf
    Vector<uint8_t> keyBytes(expectedKeySize);
    size_t keySize = keyBytes.size();
    if (UNLIKELY(CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &keySize, ccECKeyPublic, m_platformKey.get()) || keySize != expectedKeySize))
        return { };

    // The following addes SPKI header to a raw EC public key.
    // Once the underlying crypto library is updated to output SPKI EC Key, we should remove this hack.
    // <rdar://problem/30987628>
    const uint8_t* oid;
    size_t oidSize = getOID(namedCurve(), oid);

    // SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1/OID secp521r1 + BIT STRING + length(?) + InitialOctet + Key size
    size_t totalSize = sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(keySize + 1) + keySize + 4;

    Vector<uint8_t> result;
    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
    result.append(SequenceMark);
    addEncodedASN1Length(result, totalSize);
    result.append(SequenceMark);
    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
    result.append(oid, oidSize);
    result.append(BitStringMark);
    addEncodedASN1Length(result, keySize + 1);
    result.append(InitialOctet);
    result.append(keyBytes.data(), keyBytes.size());

    return result;
}

// Per https://www.ietf.org/rfc/rfc5208.txt
// PrivateKeyInfo ::= SEQUENCE { version INTEGER, privateKeyAlgorithm AlgorithmIdentifier, privateKey OCTET STRING { ECPrivateKey } }
// Per https://www.ietf.org/rfc/rfc5915.txt
// ECPrivateKey ::= SEQUENCE { version INTEGER { ecPrivkeyVer1(1) }, privateKey OCTET STRING, parameters CustomECParameters, publicKey BIT STRING }
// OpenSSL uses custom ECParameters. We follow OpenSSL as a compatibility concern.
RefPtr<CryptoKeyEC> CryptoKeyEC::platformImportPkcs8(CryptoAlgorithmIdentifier identifier, NamedCurve curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
{
    // The following is a loose check on the provided PKCS8 key, it aims to extract AlgorithmIdentifier, ECParameters, and Key.
    // Once the underlying crypto library is updated to accept PKCS8 EC Key, we should remove this hack.
    // <rdar://problem/30987628>
    size_t index = 1; // Read SEQUENCE
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, SEQUENCE
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]); // Read length
    if (keyData.size() < index + sizeof(IdEcPublicKey))
        return nullptr;
    if (memcmp(keyData.data() + index, IdEcPublicKey, sizeof(IdEcPublicKey)))
        return nullptr;
    index += sizeof(IdEcPublicKey); // Read id-ecPublicKey
    const uint8_t* oid;
    size_t oidSize = getOID(curve, oid);
    if (keyData.size() < index + oidSize)
        return nullptr;
    if (memcmp(keyData.data() + index, oid, oidSize))
        return nullptr;
    index += oidSize + 1; // Read named curve OID, OCTET STRING
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, SEQUENCE
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 4; // Read length, version, OCTET STRING
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]); // Read length

    size_t privateKeySize = keySizeInBytesFromNamedCurve(curve);
    if (keyData.size() < index + privateKeySize)
        return nullptr;
    size_t privateKeyPos = index;
    index += privateKeySize + 1; // Read privateKey, TaggedType1
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, BIT STRING
    if (keyData.size() < index + 1)
        return nullptr;
    index += bytesUsedToEncodedLength(keyData[index]) + 1; // Read length, InitialOctet

    // KeyBinary = uncompressed point + private key
    Vector<uint8_t> keyBinary { keyData.data() + index, keyData.size() - index };
    if (!doesUncompressedPointMatchNamedCurve(curve, keyBinary.size()))
        return nullptr;
    keyBinary.append(keyData.data() + privateKeyPos, privateKeySize);

    CCECCryptorRef ccPrivateKey = nullptr;
    if (CCECCryptorImportKey(kCCImportKeyBinary, keyBinary.data(), keyBinary.size(), ccECKeyPrivate, &ccPrivateKey))
        return nullptr;

    return create(identifier, curve, CryptoKeyType::Private, PlatformECKeyContainer(ccPrivateKey), extractable, usages);
}

Vector<uint8_t> CryptoKeyEC::platformExportPkcs8() const
{
    size_t keySizeInBytes = this->keySizeInBytes();
    size_t expectedKeySize = keySizeInBytes * 3 + 1; // 04 + X + Y + D
    Vector<uint8_t> keyBytes(expectedKeySize);
    size_t keySize = keyBytes.size();
    if (UNLIKELY(CCECCryptorExportKey(kCCImportKeyBinary, keyBytes.data(), &keySize, ccECKeyPrivate, m_platformKey.get()) || keySize != expectedKeySize))
        return { };

    // The following addes PKCS8 header to a raw EC private key.
    // Once the underlying crypto library is updated to output PKCS8 EC Key, we should remove this hack.
    // <rdar://problem/30987628>
    const uint8_t* oid;
    size_t oidSize = getOID(namedCurve(), oid);

    // InitialOctet + 04 + X + Y
    size_t publicKeySize = keySizeInBytes * 2 + 2;
    // BIT STRING + length(?) + publicKeySize
    size_t taggedTypeSize = bytesNeededForEncodedLength(publicKeySize) + publicKeySize + 1;
    // VERSION + OCTET STRING + length(1) + private key + TaggedType1(1) + length(?) + BIT STRING + length(?) + publicKeySize
    size_t ecPrivateKeySize = sizeof(Version) + keySizeInBytes + bytesNeededForEncodedLength(taggedTypeSize) + bytesNeededForEncodedLength(publicKeySize) + publicKeySize + 4;
    // SEQUENCE + length(?) + ecPrivateKeySize
    size_t privateKeySize = bytesNeededForEncodedLength(ecPrivateKeySize) + ecPrivateKeySize + 1;
    // VERSION + SEQUENCE + length(1) + OID id-ecPublicKey + OID secp256r1/OID secp384r1/OID secp521r1 + OCTET STRING + length(?) + privateKeySize
    size_t totalSize = sizeof(Version) + sizeof(IdEcPublicKey) + oidSize + bytesNeededForEncodedLength(privateKeySize) + privateKeySize + 3;

    Vector<uint8_t> result;
    result.reserveCapacity(totalSize + bytesNeededForEncodedLength(totalSize) + 1);
    result.append(SequenceMark);
    addEncodedASN1Length(result, totalSize);
    result.append(Version, sizeof(Version));
    result.append(SequenceMark);
    addEncodedASN1Length(result, sizeof(IdEcPublicKey) + oidSize);
    result.append(IdEcPublicKey, sizeof(IdEcPublicKey));
    result.append(oid, oidSize);
    result.append(OctetStringMark);
    addEncodedASN1Length(result, privateKeySize);
    result.append(SequenceMark);
    addEncodedASN1Length(result, ecPrivateKeySize);
    result.append(PrivateKeyVersion, sizeof(PrivateKeyVersion));
    result.append(OctetStringMark);
    addEncodedASN1Length(result, keySizeInBytes);
    result.append(keyBytes.data() + publicKeySize - 1, keySizeInBytes);
    result.append(TaggedType1);
    addEncodedASN1Length(result, taggedTypeSize);
    result.append(BitStringMark);
    addEncodedASN1Length(result, publicKeySize);
    result.append(InitialOctet);
    result.append(keyBytes.data(), publicKeySize - 1);

    return result;
}

} // namespace WebCore

#endif // ENABLE(WEB_CRYPTO)
