/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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.
 */

/**
 *    @file
 *      This file implements an object for reading Abstract Syntax
 *      Notation One (ASN.1) encoded data.
 *
 */

#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <asn1/ASN1.h>

namespace chip {
namespace ASN1 {

void ASN1Reader::Init(const uint8_t * buf, uint32_t len)
{
    ResetElementState();
    mBuf              = buf;
    mBufEnd           = buf + len;
    mElemStart        = buf;
    mContainerEnd     = mBufEnd;
    mNumSavedContexts = 0;
}

ASN1_ERROR ASN1Reader::Next()
{
    if (EndOfContents)
        return ASN1_END;

    if (IndefiniteLen)
    {
        return ASN1_ERROR_UNSUPPORTED_ENCODING;
    }
    else
        mElemStart += (mHeadLen + ValueLen);

    ResetElementState();

    if (mElemStart == mContainerEnd)
        return ASN1_END;

    return DecodeHead();
}

ASN1_ERROR ASN1Reader::EnterConstructedType()
{
    if (!Constructed)
        return ASN1_ERROR_INVALID_STATE;

    return EnterContainer(0);
}

ASN1_ERROR ASN1Reader::ExitConstructedType()
{
    return ExitContainer();
}

ASN1_ERROR ASN1Reader::GetConstructedType(const uint8_t *& val, uint32_t & valLen)
{
    if (!Constructed)
        return ASN1_ERROR_INVALID_STATE;

    val    = mElemStart;
    valLen = mHeadLen + ValueLen;

    return ASN1_NO_ERROR;
}
ASN1_ERROR ASN1Reader::EnterEncapsulatedType()
{
    if (Class != kASN1TagClass_Universal || (Tag != kASN1UniversalTag_OctetString && Tag != kASN1UniversalTag_BitString))
        return ASN1_ERROR_INVALID_STATE;

    if (Constructed)
        return ASN1_ERROR_UNSUPPORTED_ENCODING;

    return EnterContainer((Tag == kASN1UniversalTag_BitString) ? 1 : 0);
}

ASN1_ERROR ASN1Reader::ExitEncapsulatedType()
{
    return ExitContainer();
}

ASN1_ERROR ASN1Reader::EnterContainer(uint32_t offset)
{
    if (mNumSavedContexts == kMaxContextDepth)
        return ASN1_ERROR_MAX_DEPTH_EXCEEDED;

    mSavedContexts[mNumSavedContexts].ElemStart     = mElemStart;
    mSavedContexts[mNumSavedContexts].HeadLen       = mHeadLen;
    mSavedContexts[mNumSavedContexts].ValueLen      = ValueLen;
    mSavedContexts[mNumSavedContexts].IndefiniteLen = IndefiniteLen;
    mSavedContexts[mNumSavedContexts].ContainerEnd  = mContainerEnd;
    mNumSavedContexts++;

    mElemStart = Value + offset;
    if (!IndefiniteLen)
        mContainerEnd = Value + ValueLen;

    ResetElementState();

    return ASN1_NO_ERROR;
}

ASN1_ERROR ASN1Reader::ExitContainer()
{
    if (mNumSavedContexts == 0)
        return ASN1_ERROR_INVALID_STATE;

    ASN1ParseContext & prevContext = mSavedContexts[--mNumSavedContexts];

    if (prevContext.IndefiniteLen)
    {
        return ASN1_ERROR_UNSUPPORTED_ENCODING;
    }
    else
        mElemStart = prevContext.ElemStart + prevContext.HeadLen + prevContext.ValueLen;

    mContainerEnd = prevContext.ContainerEnd;

    ResetElementState();

    return ASN1_NO_ERROR;
}

bool ASN1Reader::IsContained() const
{
    return mNumSavedContexts > 0;
}

ASN1_ERROR ASN1Reader::GetInteger(int64_t & val)
{
    if (Value == nullptr)
        return ASN1_ERROR_INVALID_STATE;
    if (ValueLen < 1)
        return ASN1_ERROR_INVALID_ENCODING;
    if (ValueLen > sizeof(int64_t))
        return ASN1_ERROR_VALUE_OVERFLOW;
    if (mElemStart + mHeadLen + ValueLen > mContainerEnd)
        return ASN1_ERROR_UNDERRUN;
    const uint8_t * p = Value;
    val               = ((*p & 0x80) == 0) ? 0 : -1;
    for (uint32_t i = ValueLen; i > 0; i--, p++)
        val = (val << 8) | *p;
    return ASN1_NO_ERROR;
}

ASN1_ERROR ASN1Reader::GetBoolean(bool & val)
{
    if (Value == nullptr)
        return ASN1_ERROR_INVALID_STATE;
    if (ValueLen != 1)
        return ASN1_ERROR_INVALID_ENCODING;
    if (mElemStart + mHeadLen + ValueLen > mContainerEnd)
        return ASN1_ERROR_UNDERRUN;
    if (*Value == 0)
        val = false;
    else if (*Value == 0xFF)
        val = true;
    else
        return ASN1_ERROR_INVALID_ENCODING;
    return ASN1_NO_ERROR;
}

ASN1_ERROR ASN1Reader::GetUTCTime(ASN1UniversalTime & outTime)
{
    // Supported Encoding: YYMMDDHHMMSSZ

    if (Value == nullptr)
        return ASN1_ERROR_INVALID_STATE;
    if (ValueLen < 1)
        return ASN1_ERROR_INVALID_ENCODING;
    if (mElemStart + mHeadLen + ValueLen > mContainerEnd)
        return ASN1_ERROR_UNDERRUN;

    if (ValueLen != 13 || Value[12] != 'Z')
        return ASN1_ERROR_UNSUPPORTED_ENCODING;

    for (int i = 0; i < 12; i++)
        if (!isdigit(Value[i]))
            return ASN1_ERROR_INVALID_ENCODING;

    outTime.Year   = (Value[0] - '0') * 10 + (Value[1] - '0');
    outTime.Month  = (Value[2] - '0') * 10 + (Value[3] - '0');
    outTime.Day    = (Value[4] - '0') * 10 + (Value[5] - '0');
    outTime.Hour   = (Value[6] - '0') * 10 + (Value[7] - '0');
    outTime.Minute = (Value[8] - '0') * 10 + (Value[9] - '0');
    outTime.Second = (Value[10] - '0') * 10 + (Value[11] - '0');

    if (outTime.Year >= 50)
        outTime.Year += 1900;
    else
        outTime.Year += 2000;

    return ASN1_NO_ERROR;
}

ASN1_ERROR ASN1Reader::GetGeneralizedTime(ASN1UniversalTime & outTime)
{
    // Supported Encoding: YYYYMMDDHHMMSSZ

    if (Value == nullptr)
        return ASN1_ERROR_INVALID_STATE;
    if (ValueLen < 1)
        return ASN1_ERROR_INVALID_ENCODING;
    if (mElemStart + mHeadLen + ValueLen > mContainerEnd)
        return ASN1_ERROR_UNDERRUN;

    if (ValueLen != 15 || Value[14] != 'Z')
        return ASN1_ERROR_UNSUPPORTED_ENCODING;

    for (int i = 0; i < 14; i++)
        if (!isdigit(Value[i]))
            return ASN1_ERROR_INVALID_ENCODING;

    outTime.Year   = (Value[0] - '0') * 1000 + (Value[1] - '0') * 100 + (Value[2] - '0') * 10 + (Value[3] - '0');
    outTime.Month  = (Value[4] - '0') * 10 + (Value[5] - '0');
    outTime.Day    = (Value[6] - '0') * 10 + (Value[7] - '0');
    outTime.Hour   = (Value[8] - '0') * 10 + (Value[9] - '0');
    outTime.Minute = (Value[10] - '0') * 10 + (Value[11] - '0');
    outTime.Second = (Value[12] - '0') * 10 + (Value[13] - '0');

    return ASN1_NO_ERROR;
}

static uint8_t ReverseBits(uint8_t v)
{
    // swap adjacent bits
    v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
    // swap adjacent bit pairs
    v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
    // swap nibbles
    v = (v >> 4) | (v << 4);
    return v;
}

ASN1_ERROR ASN1Reader::GetBitString(uint32_t & outVal)
{
    // NOTE: only supports DER encoding.

    if (Value == nullptr)
        return ASN1_ERROR_INVALID_STATE;
    if (ValueLen < 1)
        return ASN1_ERROR_INVALID_ENCODING;
    if (ValueLen > 5)
        return ASN1_ERROR_UNSUPPORTED_ENCODING;
    if (mElemStart + mHeadLen + ValueLen > mContainerEnd)
        return ASN1_ERROR_UNDERRUN;

    if (ValueLen == 1)
        outVal = 0;
    else
    {
        outVal    = ReverseBits(Value[1]);
        int shift = 8;
        for (uint32_t i = 2; i < ValueLen; i++, shift += 8)
            outVal |= (ReverseBits(Value[i]) << shift);
    }

    return ASN1_NO_ERROR;
}

ASN1_ERROR ASN1Reader::DecodeHead()
{
    const uint8_t * p = mElemStart;

    if (p >= mBufEnd)
        return ASN1_ERROR_UNDERRUN;

    Class       = *p & 0xC0;
    Constructed = (*p & 0x20) != 0;

    Tag = *p & 0x1F;
    p++;
    if (Tag == 0x1F)
    {
        Tag = 0;
        do
        {
            if (p >= mBufEnd)
                return ASN1_ERROR_UNDERRUN;
            if ((Tag & 0xFE000000) != 0)
                return ASN1_ERROR_TAG_OVERFLOW;
            Tag = (Tag << 7) | (*p & 0x7F);
            p++;
        } while ((*p & 0x80) != 0);
    }

    if (p >= mBufEnd)
        return ASN1_ERROR_UNDERRUN;

    if ((*p & 0x80) == 0)
    {
        ValueLen      = *p & 0x7F;
        IndefiniteLen = false;
        p++;
    }
    else if (*p == 0x80)
    {
        ValueLen      = 0;
        IndefiniteLen = true;
        p++;
    }
    else
    {
        ValueLen       = 0;
        uint8_t lenLen = *p & 0x7F;
        p++;
        for (; lenLen > 0; lenLen--, p++)
        {
            if (p >= mBufEnd)
                return ASN1_ERROR_UNDERRUN;
            if ((ValueLen & 0xFF000000) != 0)
                return ASN1_ERROR_LENGTH_OVERFLOW;
            ValueLen = (ValueLen << 8) | *p;
        }
        IndefiniteLen = false;
    }

    mHeadLen = p - mElemStart;

    EndOfContents = (Class == kASN1TagClass_Universal && Tag == 0 && Constructed == false && ValueLen == 0);

    Value = p;

    return ASN1_NO_ERROR;
}

void ASN1Reader::ResetElementState()
{
    Class         = 0;
    Tag           = 0;
    Value         = nullptr;
    ValueLen      = 0;
    Constructed   = false;
    IndefiniteLen = false;
    EndOfContents = false;
    mHeadLen      = 0;
}

ASN1_ERROR DumpASN1(ASN1Reader & asn1Parser, const char * prefix, const char * indent)
{
    ASN1_ERROR err = ASN1_NO_ERROR;

    if (indent == nullptr)
        indent = "  ";

    int nestLevel = 0;
    while (true)
    {
        err = asn1Parser.Next();
        if (err != ASN1_NO_ERROR)
        {
            if (err == ASN1_END)
            {
                if (asn1Parser.IsContained())
                {
                    err = asn1Parser.ExitConstructedType();
                    if (err != ASN1_NO_ERROR)
                    {
                        printf("ASN1Reader::ExitConstructedType() failed: %ld\n", (long) err);
                        return err;
                    }
                    nestLevel--;
                    continue;
                }
                else
                    break;
            }
            printf("ASN1Reader::Next() failed: %ld\n", (long) err);
            return err;
        }
        if (prefix != nullptr)
            printf("%s", prefix);
        for (int i = nestLevel; i; i--)
            printf("%s", indent);
        if (asn1Parser.IsEndOfContents())
            printf("END-OF-CONTENTS ");
        else if (asn1Parser.GetClass() == kASN1TagClass_Universal)
            switch (asn1Parser.GetTag())
            {
            case kASN1UniversalTag_Boolean:
                printf("BOOLEAN ");
                break;
            case kASN1UniversalTag_Integer:
                printf("INTEGER ");
                break;
            case kASN1UniversalTag_BitString:
                printf("BIT STRING ");
                break;
            case kASN1UniversalTag_OctetString:
                printf("OCTET STRING ");
                break;
            case kASN1UniversalTag_Null:
                printf("NULL ");
                break;
            case kASN1UniversalTag_ObjectId:
                printf("OBJECT IDENTIFIER ");
                break;
            case kASN1UniversalTag_ObjectDesc:
                printf("OBJECT DESCRIPTOR ");
                break;
            case kASN1UniversalTag_External:
                printf("EXTERNAL ");
                break;
            case kASN1UniversalTag_Real:
                printf("REAL ");
                break;
            case kASN1UniversalTag_Enumerated:
                printf("ENUMERATED ");
                break;
            case kASN1UniversalTag_Sequence:
                printf("SEQUENCE ");
                break;
            case kASN1UniversalTag_Set:
                printf("SET ");
                break;
            case kASN1UniversalTag_UTF8String:
            case kASN1UniversalTag_NumericString:
            case kASN1UniversalTag_PrintableString:
            case kASN1UniversalTag_T61String:
            case kASN1UniversalTag_VideotexString:
            case kASN1UniversalTag_IA5String:
            case kASN1UniversalTag_GraphicString:
            case kASN1UniversalTag_VisibleString:
            case kASN1UniversalTag_GeneralString:
            case kASN1UniversalTag_UniversalString:
                printf("STRING ");
                break;
            case kASN1UniversalTag_UTCTime:
            case kASN1UniversalTag_GeneralizedTime:
                printf("TIME ");
                break;
            default:
                printf("[UNIVERSAL %lu] ", static_cast<unsigned long>(asn1Parser.GetTag()));
                break;
            }
        else if (asn1Parser.GetClass() == kASN1TagClass_Application)
            printf("[APPLICATION %lu] ", static_cast<unsigned long>(asn1Parser.GetTag()));
        else if (asn1Parser.GetClass() == kASN1TagClass_ContextSpecific)
            printf("[%lu] ", static_cast<unsigned long>(asn1Parser.GetTag()));
        else if (asn1Parser.GetClass() == kASN1TagClass_Private)
            printf("[PRIVATE %lu] ", static_cast<unsigned long>(asn1Parser.GetTag()));

        if (asn1Parser.IsConstructed())
            printf("(constructed) ");

        if (asn1Parser.IsIndefiniteLen())
            printf("Length = indefinite\n");
        else
            printf("Length = %ld\n", static_cast<long>(asn1Parser.GetValueLen()));

        if (asn1Parser.IsConstructed())
        {
            err = asn1Parser.EnterConstructedType();
            if (err != ASN1_NO_ERROR)
            {
                printf("ASN1Reader::EnterConstructedType() failed: %ld\n", (long) err);
                return err;
            }
            nestLevel++;
        }
    }

    return err;
}

} // namespace ASN1
} // namespace chip
