/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <webrtc/STUNMessage.h>

#include "Utils.h"

#include <https/Support.h>
#include <android-base/logging.h>

#include <arpa/inet.h>

#include <cstring>
#include <iostream>
#include <unordered_map>

#include <openssl/hmac.h>

static constexpr uint8_t kMagicCookie[4] = { 0x21, 0x12, 0xa4, 0x42 };

STUNMessage::STUNMessage(uint16_t type, const uint8_t transactionID[12])
    : mIsValid(true),
      mData(20),
      mAddedMessageIntegrity(false) {
    CHECK((type >> 14) == 0);

    mData[0] = (type >> 8) & 0x3f;
    mData[1] = type & 0xff;
    mData[2] = 0;
    mData[3] = 0;

    memcpy(&mData[4], kMagicCookie, sizeof(kMagicCookie));

    memcpy(&mData[8], transactionID, 12);
}

STUNMessage::STUNMessage(const void *data, size_t size)
    : mIsValid(false),
      mData(size) {
    memcpy(mData.data(), data, size);

    validate();
}

bool STUNMessage::isValid() const {
    return mIsValid;
}

static uint16_t UINT16_AT(const void *_data) {
    const uint8_t *data = static_cast<const uint8_t *>(_data);
    return static_cast<uint16_t>(data[0]) << 8 | data[1];
}

uint16_t STUNMessage::type() const {
    return UINT16_AT(mData.data());
}

void STUNMessage::addAttribute(uint16_t type, const void *data, size_t size) {
    CHECK(!mAddedMessageIntegrity || type == 0x8028);

    size_t alignedSize = (size + 3) & ~3;
    CHECK_LE(alignedSize, 0xffffu);

    size_t offset = mData.size();
    mData.resize(mData.size() + 4 + alignedSize);

    uint8_t *ptr = mData.data() + offset;
    ptr[0] = type >> 8;
    ptr[1] = type & 0xff;
    ptr[2] = (size >> 8) & 0xff;
    ptr[3] = size & 0xff;

    if (size > 0) {
        memcpy(&ptr[4], data, size);
    }
}

void STUNMessage::addMessageIntegrityAttribute(std::string_view password) {
    size_t offset = mData.size();

    uint16_t truncatedLength = offset + 4;
    mData[2] = (truncatedLength >> 8);
    mData[3] = (truncatedLength & 0xff);

    uint8_t digest[20];
    unsigned int digestLen = sizeof(digest);

    HMAC(EVP_sha1(),
         password.data(),
         password.size(),
         mData.data(),
         offset,
         digest,
         &digestLen);

    CHECK_EQ(digestLen, 20);
    addAttribute(0x0008 /* MESSAGE-INTEGRITY */, digest, digestLen);

    mAddedMessageIntegrity = true;
}

const uint8_t *STUNMessage::data() {
    size_t size = mData.size() - 20;
    CHECK_LE(size, 0xffffu);

    mData[2] = (size >> 8) & 0xff;
    mData[3] = size & 0xff;

    return mData.data();
}

size_t STUNMessage::size() const {
    return mData.size();
}

void STUNMessage::validate() {
    if (mData.size() < 20) {
        return;
    }

    const uint8_t *data = mData.data();

    auto messageLength = UINT16_AT(data + 2);
    if (messageLength != mData.size() - 20) {
        return;
    }

    if (memcmp(kMagicCookie, &data[4], sizeof(kMagicCookie))) {
        return;
    }

    bool sawMessageIntegrity = false;

    data += 20;
    size_t offset = 0;
    while (offset + 4 <= messageLength) {
        auto attrType = UINT16_AT(&data[offset]);

        if (sawMessageIntegrity && attrType != 0x8028 /* FINGERPRINT */) {
            return;
        }

        sawMessageIntegrity = (attrType == 0x0008 /* MESSAGE-INTEGRITY */);

        auto attrLength = UINT16_AT(&data[offset + 2]);

        if (offset + 4 + attrLength > messageLength) {
            return;
        }

        offset += 4 + attrLength;
        if (offset & 3) {
            offset += 4 - (offset & 3);
        }
    }

    if (offset != messageLength) {
        return;
    }

    mAddedMessageIntegrity = sawMessageIntegrity;
    mIsValid = true;
}

void STUNMessage::dump(std::optional<std::string_view> password) const {
    CHECK(mIsValid);

    const uint8_t *data = mData.data();

    auto messageType = UINT16_AT(data);
    auto messageLength = mData.size() - 20;

    if (messageType == 0x0001) {
        std::cout << "Binding Request";
    } else if (messageType == 0x0101) {
        std::cout << "Binding Response";
    } else {
        std::cout
            << "Unknown message type "
            << StringPrintf("0x%04x", messageType);
    }

    std::cout << std::endl;

    data += 20;
    size_t offset = 0;
    while (offset + 4 <= messageLength) {
        auto attrType = UINT16_AT(&data[offset]);
        auto attrLength = UINT16_AT(&data[offset + 2]);

        static const std::unordered_map<uint16_t, std::string> kAttrName {
            { 0x0001, "MAPPED-ADDRESS" },
            { 0x0006, "USERNAME" },
            { 0x0008, "MESSAGE-INTEGRITY" },
            { 0x0009, "ERROR-CODE" },
            { 0x000A, "UNKNOWN-ATTRIBUTES" },
            { 0x0014, "REALM" },
            { 0x0015, "NONCE" },
            { 0x0020, "XOR-MAPPED-ADDRESS" },
            { 0x0024, "PRIORITY" },  // RFC8445
            { 0x0025, "USE-CANDIDATE" },  // RFC8445
            { 0x8022, "SOFTWARE" },
            { 0x8023, "ALTERNATE-SERVER" },
            { 0x8028, "FINGERPRINT" },
            { 0x8029, "ICE-CONTROLLED" },  // RFC8445
            { 0x802a, "ICE-CONTROLLING" },  // RFC8445
        };

        auto it = kAttrName.find(attrType);
        if (it == kAttrName.end()) {
            if (attrType <= 0x7fff) {
                std::cout
                    << "Unknown mandatory attribute type "
                    << StringPrintf("0x%04x", attrType)
                    << ":"
                    << std::endl;
            } else {
                std::cout
                    << "Unknown optional attribute type "
                    << StringPrintf("0x%04x", attrType)
                    << ":"
                    << std::endl;
            }
        } else {
            std::cout << "attribute '" << it->second << "':" << std::endl;
        }

        hexdump(&data[offset + 4], attrLength);

        if (attrType == 8 /* MESSAGE_INTEGRITY */) {
            if (attrLength != 20) {
                LOG(WARNING)
                    << "Message integrity attribute length mismatch."
                    << " Expected 20, found "
                    << attrLength;
            } else if (password) {
                auto success = verifyMessageIntegrity(offset + 20, *password);

                if (!success) {
                    LOG(WARNING) << "Message integrity check FAILED!";
                }
            }
        } else if (attrType == 0x8028 /* FINGERPRINT */) {
            if (attrLength != 4) {
                LOG(WARNING)
                    << "Fingerprint attribute length mismatch."
                    << " Expected 4, found "
                    << attrLength;
            } else {
                auto success = verifyFingerprint(offset + 20);

                if (!success) {
                    LOG(WARNING) << "Fingerprint check FAILED!";
                }
            }
        }

        offset += 4 + attrLength;
        if (offset & 3) {
            offset += 4 - (offset & 3);
        }
    }
}

bool STUNMessage::verifyMessageIntegrity(
        size_t offset, std::string_view password) const {
    // Password used as "short-term" credentials (RFC 5389).
    // Technically the password would have to be SASLprep'ed...

    std::vector<uint8_t> copy(offset);
    memcpy(copy.data(), mData.data(), offset);

    uint16_t truncatedLength = offset + 4;
    copy[2] = (truncatedLength >> 8);
    copy[3] = (truncatedLength & 0xff);

    uint8_t digest[20];
    unsigned int digestLen = sizeof(digest);

    HMAC(EVP_sha1(),
         password.data(),
         password.size(),
         copy.data(),
         copy.size(),
         digest,
         &digestLen);

    CHECK_EQ(digestLen, 20);

    bool success = !memcmp(
            digest,
            &mData[offset + 4],
            digestLen);

    return success;
}

void STUNMessage::addFingerprint() {
    size_t offset = mData.size();

    // Pretend that we've added the FINGERPRINT attribute already.
    uint16_t truncatedLength = offset + 4 + 4 - 20;
    mData[2] = (truncatedLength >> 8);
    mData[3] = (truncatedLength & 0xff);

    uint32_t crc32 = htonl(computeCrc32(mData.data(), offset) ^ 0x5354554e);

    addAttribute(0x8028 /* FINGERPRINT */, &crc32, sizeof(crc32));
}

bool STUNMessage::verifyFingerprint(size_t offset) const {
    std::vector<uint8_t> copy(offset);
    memcpy(copy.data(), mData.data(), offset);

    copy[2] = ((mData.size() - 20) >> 8) & 0xff;
    copy[3] = (mData.size() - 20) & 0xff;

    uint32_t crc32 = htonl(computeCrc32(copy.data(), offset) ^ 0x5354554e);

    // hexdump(&crc32, 4);

    return !memcmp(&crc32, &mData[offset + 4], 4);
}

bool STUNMessage::findAttribute(
        uint16_t type, const void **attrData, size_t *attrSize) const {
    CHECK(mIsValid);

    const uint8_t *data = mData.data();

    auto messageLength = mData.size() - 20;

    data += 20;
    size_t offset = 0;
    while (offset + 4 <= messageLength) {
        auto attrType = UINT16_AT(&data[offset]);
        auto attrLength = UINT16_AT(&data[offset + 2]);

        if (attrType == type) {
            *attrData = &data[offset + 4];
            *attrSize = attrLength;

            return true;
        }

        offset += 4 + attrLength;

        if (offset & 3) {
            offset += 4 - (offset & 3);
        }
    }

    *attrData = nullptr;
    *attrSize = 0;

    return false;
}

