/*
 *
 *    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
 *      Unit tests for the WeaveCASEEngine class.
 *
 */

#include <stdio.h>
#include <string.h>

#include "ToolCommon.h"
#include <Weave/Support/ErrorStr.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Support/ASN1.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include <Weave/Profiles/security/WeaveCASE.h>
#include <Weave/Profiles/security/WeavePrivateKey.h>
#include <Weave/Profiles/security/WeaveSig.h>
#include <Weave/Support/crypto/EllipticCurve.h>
#include <Weave/Support/NestCerts.h>
#include <Weave/Support/RandUtils.h>

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include "lwip/tcpip.h"
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles::Security;
using namespace nl::Weave::Profiles::Security::CASE;
using namespace nl::Weave::ASN1;

using nl::Weave::Crypto::EncodedECPublicKey;
using nl::Weave::Crypto::EncodedECPrivateKey;

#define TOOL_NAME "TestCASE"

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);

const char *gCurTest = NULL;

#define VerifyOrQuit(TST, MSG) \
do { \
    if (!(TST)) \
    { \
        fprintf(stdout, "%s FAILED: ", (gCurTest != NULL) ? gCurTest : __FUNCTION__); \
        fputs(MSG, stdout); \
        fputs("\n", stdout); \
        exit(-1); \
    } \
} while (0)

#define SuccessOrQuit(ERR, MSG) \
do { \
    if ((ERR) != WEAVE_NO_ERROR) \
    { \
        fprintf(stdout, "%s FAILED: ", (gCurTest != NULL) ? gCurTest : __FUNCTION__); \
        fputs(MSG, stdout); \
        fputs(": ", stdout); \
        fputs(ErrorStr(ERR), stdout); \
        fputs("\n", stdout); \
        exit(-1); \
    } \
} while (0)

extern WEAVE_ERROR MakeCertInfo(uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen,
                                const uint8_t *entityCert, uint16_t entityCertLen,
                                const uint8_t *intermediateCert, uint16_t intermediateCertLen);

class TestAuthDelegate : public WeaveCASEAuthDelegate
{
public:
    bool IsInitiator;

    TestAuthDelegate(bool isInitiator)
    : IsInitiator(isInitiator)
    {
    }

#if !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE

    // ===== Methods that implement the WeaveCASEAuthDelegate interface.

    WEAVE_ERROR EncodeNodeCertInfo(const BeginSessionContext & msgCtx, TLVWriter & writer) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::EncodeNodeCertInfo(): initiator/responder mismatch");

        const uint8_t * nodeCert = (IsInitiator) ? TestDevice1_Cert : TestDevice2_Cert;
        uint16_t nodeCertLen = (IsInitiator) ? TestDevice1_CertLength : TestDevice2_CertLength;

        const uint8_t * intermediateCert = (!IsInitiator) ? nl::NestCerts::Development::DeviceCA::Cert : NULL;
        uint16_t intermediateCertLen = (!IsInitiator) ? nl::NestCerts::Development::DeviceCA::CertLength : 0;

        return EncodeCASECertInfo(writer, nodeCert, nodeCertLen, intermediateCert, intermediateCertLen);
    }

    WEAVE_ERROR GenerateNodeSignature(const BeginSessionContext & msgCtx,
            const uint8_t * msgHash, uint8_t msgHashLen, TLVWriter & writer, uint64_t tag) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::GenerateNodeSignature(): initiator/responder mismatch");

        const uint8_t * privKey = (IsInitiator) ? TestDevice1_PrivateKey : TestDevice2_PrivateKey;
        uint16_t privKeyLen = (IsInitiator) ? TestDevice1_PrivateKeyLength : TestDevice2_PrivateKeyLength;

        return GenerateAndEncodeWeaveECDSASignature(writer, tag, msgHash, msgHashLen, privKey, privKeyLen);
    }

    WEAVE_ERROR EncodeNodePayload(const BeginSessionContext & msgCtx,
            uint8_t * payloadBuf, uint16_t payloadBufSize, uint16_t & payloadLen) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::GetLocalPayload(): initiator/responder mismatch");
        payloadLen = 0;
        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR BeginValidation(const BeginSessionContext & msgCtx, ValidationContext & validCtx,
            WeaveCertificateSet & certSet) __OVERRIDE
    {
        WEAVE_ERROR err;
        ASN1UniversalTime validTime;
        WeaveCertificateData *cert;

        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::BeginValidation(): initiator/responder mismatch");

        certSet.Init(10, 1024);

        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);
        cert->CertFlags |= kCertFlag_IsTrusted;

        if (!IsInitiator)
        {
            err = certSet.LoadCert(nl::NestCerts::Development::DeviceCA::Cert,
                    nl::NestCerts::Development::DeviceCA::CertLength,
                    kDecodeFlag_GenerateTBSHash, cert);
            SuccessOrExit(err);
        }

        memset(&validCtx, 0, sizeof(validCtx));
        validTime.Year = 2013;
        validTime.Month = 11;
        validTime.Day = 20;
        validTime.Hour = validTime.Minute = validTime.Second = 0;
        err = PackCertTime(validTime, validCtx.EffectiveTime);
        SuccessOrExit(err);

        validCtx.RequiredKeyUsages = kKeyUsageFlag_DigitalSignature;
        validCtx.RequiredKeyPurposes = (IsInitiator) ? kKeyPurposeFlag_ServerAuth : kKeyPurposeFlag_ClientAuth;

    exit:
        return err;
    }

    WEAVE_ERROR OnPeerCertsLoaded(const BeginSessionContext & msgCtx,
            WeaveDN & subjectDN, CertificateKeyId & subjectKeyId, ValidationContext & validCtx,
            WeaveCertificateSet & certSet) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::OnPeerCertsLoaded(): initiator/responder mismatch");
        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR HandleValidationResult(const BeginSessionContext & msgCtx, ValidationContext & validCtx,
            WeaveCertificateSet & certSet, WEAVE_ERROR & validRes) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::HandleValidationResult(): initiator/responder mismatch");
        return WEAVE_NO_ERROR;
    }

    void EndValidation(const BeginSessionContext & msgCtx, ValidationContext & validCtx,
            WeaveCertificateSet & certSet) __OVERRIDE
    {
        VerifyOrQuit(msgCtx.IsInitiator() == IsInitiator, "TestAuthDelegate::EndValidation(): initiator/responder mismatch");
    }

#else // !WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE

    WEAVE_ERROR GetNodeCertInfo(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen) __OVERRIDE
    {
        VerifyOrQuit(isInitiator == IsInitiator, "TestAuthDelegate::EncodeNodeCertInfo(): initiator/responder mismatch");

        const uint8_t * nodeCert = (IsInitiator) ? TestDevice1_Cert : TestDevice2_Cert;
        uint16_t nodeCertLen = (IsInitiator) ? TestDevice1_CertLength : TestDevice2_CertLength;

        const uint8_t * intermediateCert = (!IsInitiator) ? nl::NestCerts::Development::DeviceCA::Cert : NULL;
        uint16_t intermediateCertLen = (!IsInitiator) ? nl::NestCerts::Development::DeviceCA::CertLength : 0;

        return EncodeCASECertInfo(buf, bufSize, certInfoLen, nodeCert, nodeCertLen, intermediateCert, intermediateCertLen);
    }

    WEAVE_ERROR GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen) __OVERRIDE
    {
        VerifyOrQuit(isInitiator == IsInitiator, "TestAuthDelegate::GetNodePrivateKey(): initiator/responder mismatch");

        weavePrivKey = (IsInitiator) ? TestDevice1_PrivateKey : TestDevice2_PrivateKey;
        weavePrivKeyLen = (IsInitiator) ? TestDevice1_PrivateKeyLength : TestDevice2_PrivateKeyLength;

        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR ReleaseNodePrivateKey(const uint8_t *weavePrivKey) __OVERRIDE
    {
        // Nothing to do
        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR GetNodePayload(bool isInitiator, uint8_t *buf, uint16_t bufSize, uint16_t& payloadLen) __OVERRIDE
    {
        VerifyOrQuit(isInitiator == IsInitiator, "TestAuthDelegate::GetNodePayload(): initiator/responder mismatch");
        payloadLen = 0;
        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR BeginCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext) __OVERRIDE
    {
        WEAVE_ERROR err;
        ASN1UniversalTime validTime;
        WeaveCertificateData *cert;

        VerifyOrQuit(isInitiator == IsInitiator, "TestAuthDelegate::BeginCertValidation(): initiator/responder mismatch");

        certSet.Init(10, 1024);

        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);
        cert->CertFlags |= kCertFlag_IsTrusted;

        if (!IsInitiator)
        {
            err = certSet.LoadCert(nl::NestCerts::Development::DeviceCA::Cert, nl::NestCerts::Development::DeviceCA::CertLength, kDecodeFlag_GenerateTBSHash, cert);
            SuccessOrExit(err);
        }

        memset(&validContext, 0, sizeof(validContext));
        validTime.Year = 2013;
        validTime.Month = 11;
        validTime.Day = 20;
        validTime.Hour = validTime.Minute = validTime.Second = 0;
        err = PackCertTime(validTime, validContext.EffectiveTime);
        SuccessOrExit(err);

        validContext.RequiredKeyUsages = kKeyUsageFlag_DigitalSignature;
        validContext.RequiredKeyPurposes = (IsInitiator) ? kKeyPurposeFlag_ServerAuth : kKeyPurposeFlag_ClientAuth;

    exit:
        return err;
    }

    WEAVE_ERROR HandleCertValidationResult(bool isInitiator, WEAVE_ERROR& validRes, WeaveCertificateData *peerCert,
            uint64_t peerNodeId, WeaveCertificateSet& certSet, ValidationContext& validContext) __OVERRIDE
    {
        VerifyOrQuit(isInitiator == IsInitiator, "TestAuthDelegate::HandleCertValidationResult(): initiator/responder mismatch");
        return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR EndCertValidation(WeaveCertificateSet& certSet, ValidationContext& validContext) __OVERRIDE
    {
        return WEAVE_NO_ERROR;
    }

#endif // WEAVE_CONFIG_LEGACY_CASE_AUTH_DELEGATE
};

class MessageMutator
{
public:
    virtual ~MessageMutator() { }
    virtual void Reset() = 0;
    virtual void MutateMessage(const char *msgName, PacketBuffer *msgBuf, WeaveCASEEngine& initiatorEng, WeaveCASEEngine& responderEng) = 0;
    virtual bool IsComplete() = 0;
};

class NullMutator : public MessageMutator
{
public:
    virtual void Reset() { }
    virtual void MutateMessage(const char *msgName, PacketBuffer *msgBuf, WeaveCASEEngine& initiatorEng, WeaveCASEEngine& responderEng) { }
    virtual bool IsComplete() { return true; }
};

static NullMutator gNullMutator;

class MessageFuzzer : public MessageMutator
{
public:
    MessageFuzzer(const char *msgType)
    {
        mMsgType = msgType;
        mIndex = 0;
        mSkipStart = 0;
        mSkipLen = 0;
        mComplete = false;
        mTimeLimit = 0;
    }

    virtual void Reset() { mIndex = 0; mComplete = false; }

    virtual void MutateMessage(const char *msgType, PacketBuffer *msgBuf, WeaveCASEEngine& initiatorEng, WeaveCASEEngine& responderEng)
    {
        if (strcmp(msgType, mMsgType) == 0)
        {
            uint8_t *msgStart = msgBuf->Start();
            uint16_t msgLen = msgBuf->DataLength();
            uint8_t fuzzMask;

            VerifyOrQuit(msgLen > 0, "Unexpected packet length");

            if (mIndex == mSkipStart)
                mIndex += mSkipLen;

            if (mIndex >= msgLen)
                mIndex = msgLen - 1;

            do
                fuzzMask = GetRandU8();
            while (fuzzMask == 0);

            printf("MessageFuzzer: %s message mutated (offset %u, fuzz mask 0x%02X, orig value 0x%02X)\n", msgType, mIndex, fuzzMask, msgStart[mIndex]);

            msgStart[mIndex] ^= fuzzMask;

            mIndex++;

            mComplete = (mIndex >= msgLen);
        }
    }

    virtual bool IsComplete()
    {
        if (mComplete)
            return true;

        if (mTimeLimit != 0)
        {
            time_t now;
            time(&now);
            if (now >= mTimeLimit)
                return true;
        }

        return false;
    }

    MessageFuzzer& Skip(uint16_t start, uint16_t len) { mSkipStart = start; mSkipLen = len; return *this; }

    MessageFuzzer& TimeLimit(time_t timeLimit) { mTimeLimit = timeLimit; return *this; }

private:
    const char *mMsgType;
    uint16_t mIndex;
    uint16_t mSkipStart;
    uint16_t mSkipLen;
    bool mComplete;
    time_t mTimeLimit;
};

class CASEEngineTest
{
public:
    CASEEngineTest(const char *testName)
    {
        mTestName = testName;
        mProposedConfig = mExpectedConfig = kCASEConfig_NotSpecified;
        mProposedCurve = mExpectedCurve = kWeaveCurveId_NotSpecified;
        mInitiatorAllowedConfigs = mResponderAllowedConfigs = kCASEAllowedConfig_Config1|kCASEAllowedConfig_Config2;
        mInitiatorAllowedCurves = mResponderAllowedCurves = kWeaveCurveSet_prime192v1|kWeaveCurveSet_secp160r1|kWeaveCurveSet_secp224r1|kWeaveCurveSet_prime256v1;
        mInitiatorRequestKeyConfirm = true;
        mResponderRequiresKeyConfirm = false;
        mExpectReconfig = false;
        mExpectedConfig = kCASEConfig_NotSpecified;
        mExpectedCurve = kWeaveCurveId_NotSpecified;
        mForceRepeatedReconfig = false;
        memset(mExpectedErrors, 0, sizeof(mExpectedErrors));
        mMutator = &gNullMutator;
        mLogMessageData = false;
    }

    const char *TestName() const { return mTestName; }

    uint32_t ProposedConfig() const { return mProposedConfig; }
    CASEEngineTest& ProposedConfig(uint32_t val) { mProposedConfig = val; return *this; }

    uint32_t ProposedCurve() const { return mProposedCurve; }
    CASEEngineTest& ProposedCurve(uint32_t val) { mProposedCurve = val; return *this; }

    uint32_t InitiatorAllowedConfigs() const { return mInitiatorAllowedConfigs; }
    CASEEngineTest& InitiatorAllowedConfigs(uint8_t val) { mInitiatorAllowedConfigs = val; return *this; }

    uint32_t ResponderAllowedConfigs() const { return mResponderAllowedConfigs; }
    CASEEngineTest& ResponderAllowedConfigs(uint8_t val) { mResponderAllowedConfigs = val; return *this; }

    uint8_t InitiatorAllowedCurves() const { return mInitiatorAllowedCurves; }
    CASEEngineTest& InitiatorAllowedCurves(uint8_t val) { mInitiatorAllowedCurves = val; return *this; }

    uint8_t ResponderAllowedCurves() const { return mResponderAllowedCurves; }
    CASEEngineTest& ResponderAllowedCurves(uint8_t val) { mResponderAllowedCurves = val; return *this; }

    bool InitiatorRequestKeyConfirm() const { return mInitiatorRequestKeyConfirm; }
    CASEEngineTest& InitiatorRequestKeyConfirm(bool val) { mInitiatorRequestKeyConfirm = val; return *this; }

    bool ResponderRequiresKeyConfirm() const { return mResponderRequiresKeyConfirm; }
    CASEEngineTest& ResponderRequiresKeyConfirm(bool val) { mResponderRequiresKeyConfirm = val; return *this; }

    uint32_t ExpectReconfig() const { return mExpectReconfig; }
    CASEEngineTest& ExpectReconfig(uint32_t expectedConfig)
    {
        mExpectReconfig = true;
        mExpectedConfig = expectedConfig;
        return *this;
    }
    CASEEngineTest& ExpectReconfigCurve(uint32_t expectedCurve)
    {
        mExpectReconfig = true;
        mExpectedCurve = expectedCurve;
        return *this;
    }
    uint32_t ExpectedConfig() const { return mExpectedConfig != kCASEConfig_NotSpecified ? mExpectedConfig : mProposedConfig; }
    uint32_t ExpectedCurve() const { return mExpectedCurve != kWeaveCurveId_NotSpecified ? mExpectedCurve : mProposedCurve; }

    bool ForceRepeatedReconfig() const { return mForceRepeatedReconfig; }
    CASEEngineTest& ForceRepeatedReconfig(bool val) { mForceRepeatedReconfig = val; return *this; }

    CASEEngineTest& ExpectError(WEAVE_ERROR err)
    {
        return ExpectError(NULL, err);
    }

    CASEEngineTest& ExpectError(const char *opName, WEAVE_ERROR err)
    {
        for (size_t i = 0; i < kMaxExpectedErrors; i++)
        {
            if (mExpectedErrors[i].Error == WEAVE_NO_ERROR)
            {
                mExpectedErrors[i].Error = err;
                mExpectedErrors[i].OpName = opName;
                break;
            }
        }

        return *this;
    }

    bool IsExpectedError(const char *opName, WEAVE_ERROR err) const
    {
        for (size_t i = 0; i < kMaxExpectedErrors && mExpectedErrors[i].Error != WEAVE_NO_ERROR; i++)
        {
            if (mExpectedErrors[i].Error == err &&
                (mExpectedErrors[i].OpName == NULL || strcmp(mExpectedErrors[i].OpName, opName) == 0))
                return true;
        }
        return false;
    }

    bool IsSuccessExpected() const { return mExpectedErrors[0].Error == WEAVE_NO_ERROR; }

    CASEEngineTest& Mutator(MessageMutator *mutator) { mMutator = mutator; return *this; }

    bool LogMessageData() const { return mLogMessageData; }
    CASEEngineTest& LogMessageData(bool val) { mLogMessageData = val; return *this; }

    void Run() const;

private:
    enum
    {
        kMaxExpectedErrors = 32
    };

    struct ExpectedError
    {
        const char *OpName;
        WEAVE_ERROR Error;
    };

    const char *mTestName;
    uint32_t mProposedConfig;
    uint32_t mProposedCurve;
    uint8_t mInitiatorAllowedConfigs;
    uint8_t mInitiatorAllowedCurves;
    uint8_t mResponderAllowedConfigs;
    uint8_t mResponderAllowedCurves;
    bool mInitiatorRequestKeyConfirm;
    bool mResponderRequiresKeyConfirm;
    bool mExpectReconfig;
    uint32_t mExpectedConfig;
    uint32_t mExpectedCurve;
    bool mForceRepeatedReconfig;
    ExpectedError mExpectedErrors[kMaxExpectedErrors];
    MessageMutator *mMutator;
    bool mLogMessageData;
};

void CASEEngineTest::Run() const
{
    WEAVE_ERROR err;
    WeaveCASEEngine initiatorEng;
    WeaveCASEEngine responderEng;
    PacketBuffer *msgBuf = NULL;
    PacketBuffer *msgBuf2 = NULL;
    TestAuthDelegate initiatorDelegate(true);
    TestAuthDelegate responderDelegate(false);
    const WeaveEncryptionKey *initiatorKey;
    const WeaveEncryptionKey *responderKey;

    printf("========== Starting Test: %s\n", TestName());

    gCurTest = TestName();

    mMutator->Reset();

    do
    {
        bool reconfigPerformed = false;
        uint32_t config = ProposedConfig();
        uint32_t curveId = ProposedCurve();

        initiatorEng.Init();
        initiatorEng.AuthDelegate = &initiatorDelegate;
        initiatorEng.SetAllowedConfigs(InitiatorAllowedConfigs());
        initiatorEng.SetAllowedCurves(InitiatorAllowedCurves());

    onReconfig:

        responderEng.Init();
        responderEng.AuthDelegate = &responderDelegate;
        responderEng.SetAllowedConfigs(ResponderAllowedConfigs());
        responderEng.SetAllowedCurves(ResponderAllowedCurves());
        responderEng.SetResponderRequiresKeyConfirm(ResponderRequiresKeyConfirm());

        // ========== Initiator Forms BeginSessionRequest ==========

        {
            BeginSessionRequestContext req;
            req.Reset();
            req.ProtocolConfig = config;
            initiatorEng.SetAlternateConfigs(req);
            req.CurveId = curveId;
            initiatorEng.SetAlternateCurves(req);
            req.SetPerformKeyConfirm(InitiatorRequestKeyConfirm());
            req.SessionKeyId = sTestDefaultSessionKeyId;
            req.EncryptionType = kWeaveEncryptionType_AES128CTRSHA1;

            msgBuf = PacketBuffer::New();
            VerifyOrQuit(msgBuf != NULL, "PacketBuffer::New() failed");

            printf("Initiator: Calling GenerateBeginSessionRequest\n");

            err = initiatorEng.GenerateBeginSessionRequest(req, msgBuf);

            if (IsExpectedError("Initiator:GenerateBeginSessionRequest", err))
                goto onExpectedError;

            SuccessOrQuit(err, "WeaveCASEEngine::GenerateBeginSessionRequest() failed");
        }

        // ========== Initiator Sends BeginSessionRequest to Responder ==========

        mMutator->MutateMessage("BeginSessionRequest", msgBuf, initiatorEng, responderEng);

        printf("Initiator->Responder: BeginSessionRequest Message (%d bytes)\n", msgBuf->DataLength());
        if (LogMessageData())
            DumpMemory(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);

        // ========== Responder Processes BeginSessionRequest ==========

        {
            BeginSessionRequestContext req;
            ReconfigureContext reconf;
            req.Reset();
            reconf.Reset();

            printf("Responder: Calling ProcessBeginSessionRequest\n");

            err = responderEng.ProcessBeginSessionRequest(msgBuf, req, reconf);

            if (IsExpectedError("Responder:ProcessBeginSessionRequest", err))
                goto onExpectedError;

            if (ExpectReconfig() && !reconfigPerformed)
            {
                VerifyOrQuit(err == WEAVE_ERROR_CASE_RECONFIG_REQUIRED, "WEAVE_ERROR_CASE_RECONFIG_REQUIRED error expected");

                VerifyOrQuit(ExpectedConfig() == kCASEConfig_NotSpecified || reconf.ProtocolConfig == ExpectedConfig(), "Unexpected config proposed in ReconfigureContext");
                VerifyOrQuit(ExpectedCurve() == kWeaveCurveId_NotSpecified || reconf.CurveId == ExpectedCurve(), "Unexpected curve proposed in ReconfigureContext");

                PacketBuffer::Free(msgBuf);
                msgBuf = NULL;

                // ========== Responder Forms Reconfigure ==========

                printf("Responder: Generating Reconfigure Message\n");

                msgBuf = PacketBuffer::New();
                VerifyOrQuit(msgBuf != NULL, "PacketBuffer::New() failed");
                err = reconf.Encode(msgBuf);
                SuccessOrQuit(err, "ReconfigureContext::Encode() failed");

                // ========== Responder Sends Reconfigure to Initiator ==========

                mMutator->MutateMessage("Reconfigure", msgBuf, initiatorEng, responderEng);

                printf("Responder->Initiator: Reconfigure Message (%d bytes)\n", msgBuf->DataLength());
                if (LogMessageData())
                    DumpMemory(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);

                // ========== Initiator Processes Reconfigure ==========

                printf("Initiator: Calling ProcessReconfigure\n");

                err = initiatorEng.ProcessReconfigure(msgBuf, reconf);

                if (IsExpectedError("Initiator:ProcessReconfigure", err))
                    goto onExpectedError;

                SuccessOrQuit(err, "WeaveCASEEngine::ProcessReconfigure() failed");

                PacketBuffer::Free(msgBuf);
                msgBuf = NULL;

                if (!ForceRepeatedReconfig())
                {
                    reconfigPerformed = true;

                    config = reconf.ProtocolConfig;
                    curveId = reconf.CurveId;
                }

                responderEng.Shutdown();

                goto onReconfig;
            }

            else
            {
                VerifyOrQuit(err != WEAVE_ERROR_CASE_RECONFIG_REQUIRED, "Unexpected reconfig");
            }

            SuccessOrQuit(err, "WeaveCASEEngine::ProcessBeginSessionRequest() failed");

            // ========== Responder Forms BeginSessionResponse ==========

            BeginSessionResponseContext resp;
            resp.Reset();
            resp.ProtocolConfig = req.ProtocolConfig;
            resp.CurveId = req.CurveId;

            msgBuf2 = PacketBuffer::New();
            VerifyOrQuit(msgBuf2 != NULL, "PacketBuffer::New() failed");

            printf("Responder: Calling GenerateBeginSessionResponse\n");

            err = responderEng.GenerateBeginSessionResponse(resp, msgBuf2, req);

            if (IsExpectedError("Responder:GenerateBeginSessionResponse", err))
                goto onExpectedError;

            SuccessOrQuit(err, "WeaveCASEEngine::GenerateBeginSessionResponse() failed");

            PacketBuffer::Free(msgBuf);
            msgBuf = NULL;
        }

        // ========== Responder Sends BeginSessionResponse to Initiator ==========

        mMutator->MutateMessage("BeginSessionResponse", msgBuf2, initiatorEng, responderEng);

        printf("Responder->Initiator: BeginSessionResponse Message (%d bytes)\n", msgBuf2->DataLength());
        if (LogMessageData())
            DumpMemory(msgBuf2->Start(), msgBuf2->DataLength(), "  ", 16);

        // ========== Initiator Processes BeginSessionResponse ==========

        {
            BeginSessionResponseContext resp;
            resp.Reset();

            printf("Initiator: Calling ProcessBeginSessionResponse\n");

            err = initiatorEng.ProcessBeginSessionResponse(msgBuf2, resp);

            if (IsExpectedError("Initiator:ProcessBeginSessionResponse", err))
                goto onExpectedError;

            SuccessOrQuit(err, "WeaveCASEEngine::ProcessBeginSessionResponse() failed");

            PacketBuffer::Free(msgBuf2);
            msgBuf2 = NULL;
        }

        if (InitiatorRequestKeyConfirm() || ResponderRequiresKeyConfirm())
        {
            VerifyOrQuit(initiatorEng.PerformingKeyConfirm(), "Initiator not performing key confirmation");
            VerifyOrQuit(responderEng.PerformingKeyConfirm(), "Responder not performing key confirmation");

            // ========== Initiator Forms InitiatorKeyConfirm ==========

            msgBuf = PacketBuffer::New();
            VerifyOrQuit(msgBuf != NULL, "PacketBuffer::New() failed");

            printf("Initiator: Calling GenerateInitiatorKeyConfirm\n");

            err = initiatorEng.GenerateInitiatorKeyConfirm(msgBuf);

            if (IsExpectedError("Initiator:GenerateInitiatorKeyConfirm", err))
                goto onExpectedError;

            SuccessOrQuit(err, "WeaveCASEEngine::GenerateInitiatorKeyConfirm() failed");

            // ========== Initiator Sends InitiatorKeyConfirm to Responder ==========

            mMutator->MutateMessage("InitiatorKeyConfirm", msgBuf, initiatorEng, responderEng);

            printf("Initiator->Responder: InitiatorKeyConfirm Message (%d bytes)\n", msgBuf->DataLength());
            if (LogMessageData())
                DumpMemory(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);

            // ========== Responder Processes InitiatorKeyConfirm ==========

            printf("Responder: Calling ProcessInitiatorKeyConfirm\n");

            err = responderEng.ProcessInitiatorKeyConfirm(msgBuf);

            if (IsExpectedError("Responder:ProcessInitiatorKeyConfirm", err))
                goto onExpectedError;

            SuccessOrQuit(err, "WeaveCASEEngine::ProcessInitiatorKeyConfirm() failed");

            PacketBuffer::Free(msgBuf);
            msgBuf = NULL;
        }

        VerifyOrQuit(initiatorEng.State == WeaveCASEEngine::kState_Complete, "Initiator not in Complete state");
        VerifyOrQuit(responderEng.State == WeaveCASEEngine::kState_Complete, "Responder not in Complete state");

        if (ExpectedConfig() != kCASEConfig_NotSpecified)
        {
            VerifyOrQuit(initiatorEng.SelectedConfig() == ExpectedConfig(), "Initiator did not select expected config");
            VerifyOrQuit(responderEng.SelectedConfig() == ExpectedConfig(), "Responder did not select expected config");
        }

        if (ExpectedCurve() != kWeaveCurveId_NotSpecified)
        {
            VerifyOrQuit(initiatorEng.SelectedCurve() == ExpectedCurve(), "Initiator did not select expected curve");
            VerifyOrQuit(responderEng.SelectedCurve() == ExpectedCurve(), "Responder did not select expected curve");
        }

        printf("Initiator: Calling GetSessionKey\n");

        err = initiatorEng.GetSessionKey(initiatorKey);
        SuccessOrQuit(err, "WeaveCASEEngine::GetSessionKey() failed");

        printf("Responder: Calling GetSessionKey\n");

        err = responderEng.GetSessionKey(responderKey);
        SuccessOrQuit(err, "WeaveCASEEngine::GetSessionKey() failed");

        VerifyOrQuit(memcmp(initiatorKey->AES128CTRSHA1.DataKey, responderKey->AES128CTRSHA1.DataKey, WeaveEncryptionKey_AES128CTRSHA1::DataKeySize) == 0,
                     "Data key mismatch");

        VerifyOrQuit(memcmp(initiatorKey->AES128CTRSHA1.IntegrityKey, responderKey->AES128CTRSHA1.IntegrityKey, WeaveEncryptionKey_AES128CTRSHA1::IntegrityKeySize) == 0,
                     "Integrity key mismatch");

        VerifyOrQuit(IsSuccessExpected(), "Test succeeded unexpectedly");

    onExpectedError:

        PacketBuffer::Free(msgBuf);
        msgBuf = NULL;

        PacketBuffer::Free(msgBuf2);
        msgBuf2 = NULL;

        initiatorEng.Shutdown();
        responderEng.Shutdown();

    } while (!mMutator->IsComplete());

    printf("Test Complete: %s\n", TestName());

    gCurTest = NULL;
}

void CASEEngineTests_BasicTests()
{
    // Basic sanity test with standard parameters
    CASEEngineTest("Sanity test")
        .Run();
}

void CASEEngineTests_EllipticCurveTests()
{
    // Test secp160r1 curve
    CASEEngineTest("Test secp160r1")
        .ProposedCurve(kWeaveCurveId_secp160r1)
#if !WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP160R1
        .ExpectError("Initiator:GenerateBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_ELLIPTIC_CURVE)
#endif
        .Run();

    // Test prime192v1 curve
    CASEEngineTest("Test prime192v1")
        .ProposedCurve(kWeaveCurveId_prime192v1)
#if !WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP192R1
        .ExpectError("Initiator:GenerateBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_ELLIPTIC_CURVE)
#endif
        .Run();

    // Test secp224r1 curve
    CASEEngineTest("Test secp224r1")
        .ProposedCurve(kWeaveCurveId_secp224r1)
#if !WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP224R1
        .ExpectError("Initiator:GenerateBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_ELLIPTIC_CURVE)
#endif
        .Run();

    // Test prime256v1 curve
    CASEEngineTest("Test prime256v1")
        .ProposedCurve(kWeaveCurveId_prime256v1)
#if !WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP256R1
        .ExpectError("Initiator:GenerateBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_ELLIPTIC_CURVE)
#endif
        .Run();
}

void CASEEngineTests_ConfigNegotiationTests()
{
#if WEAVE_CONFIG_SUPPORT_CASE_CONFIG1

    // Initiator only supports Config1, responder supports Config1 and Config2, expect use of Config1
    CASEEngineTest("Config1-only Initiator")
        .ProposedConfig(kCASEConfig_Config1)
        .InitiatorAllowedConfigs(kCASEAllowedConfig_Config1)
        .Run();

    // Initiator proposes Config1 but supports Config2, responder only supports Config1, expect use of Config1
    CASEEngineTest("Config1-only Responder")
        .ProposedConfig(kCASEConfig_Config1)
        .ResponderAllowedConfigs(kCASEAllowedConfig_Config1)
        .Run();

    // Initiator only supports Config2, Responder supports Config1 and Config2, expect use of Config2
    CASEEngineTest("Config2-only initiator")
        .ProposedConfig(kCASEConfig_Config2)
        .InitiatorAllowedConfigs(kCASEAllowedConfig_Config2)
        .Run();

    // Initiator proposes Config1 but supports Config2, Responder only supports Config2, expect reconfig to Config2
    CASEEngineTest("Config2-only responder")
        .ProposedConfig(kCASEConfig_Config1)
        .ResponderAllowedConfigs(kCASEAllowedConfig_Config2)
        .ExpectReconfig(kCASEConfig_Config2)
        .Run();

    // Initiator proposes Config1 but supports Config2, Responder supports Config1 and Config2, expect reconfig to Config2
    CASEEngineTest("Reconfig to Config2")
        .ProposedConfig(kCASEConfig_Config1)
        .ExpectReconfig(kCASEConfig_Config2)
        .Run();

    // Initiator proposes Config2 but supports Config1, Responder only supports Config1, expect reconfig to Config1
    CASEEngineTest("Reconfig to Config1")
        .ProposedConfig(kCASEConfig_Config2)
        .ResponderAllowedConfigs(kCASEAllowedConfig_Config1)
        .ExpectReconfig(kCASEConfig_Config1)
        .Run();

    // Initiator only supports Config1, responder only supports Config2, expect error
    CASEEngineTest("No Common Configs 1")
        .ProposedConfig(kCASEConfig_Config1)
        .InitiatorAllowedConfigs(kCASEAllowedConfig_Config1)
        .ResponderAllowedConfigs(kCASEAllowedConfig_Config2)
        .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_CASE_CONFIGURATION)
        .Run();

    // Initiator only supports Config2, responder only supports Config1, expect error
    CASEEngineTest("No Common Configs 2")
        .ProposedConfig(kCASEConfig_Config2)
        .InitiatorAllowedConfigs(kCASEAllowedConfig_Config2)
        .ResponderAllowedConfigs(kCASEAllowedConfig_Config1)
        .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_CASE_CONFIGURATION)
        .Run();

    // Responder repeatedly sends Reconfigure, expect initiator error
    CASEEngineTest("Repeated reconfigs")
        .ProposedConfig(kCASEConfig_Config1)
        .ExpectReconfig(kCASEConfig_Config2)
        .ForceRepeatedReconfig(true)
        .ExpectError("Initiator:ProcessReconfigure", WEAVE_ERROR_TOO_MANY_CASE_RECONFIGURATIONS)
        .Run();

#endif // WEAVE_CONFIG_SUPPORT_CASE_CONFIG1
}

void CASEEngineTests_CurveNegotiationTests()
{
#if WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP192R1 && WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP224R1 && WEAVE_CONFIG_SUPPORT_ELLIPTIC_CURVE_SECP256R1

    // Initiator proposes prime192v1 and supports secp224r1, responder supports secp224r1 and prime256v1, expect reconfig to secp224r1
    CASEEngineTest("Reconfig to common curve")
        .ProposedCurve(kWeaveCurveId_prime192v1)
        .InitiatorAllowedCurves(kWeaveCurveSet_prime192v1|kWeaveCurveSet_secp224r1)
        .ResponderAllowedCurves(kWeaveCurveSet_secp224r1|kWeaveCurveSet_prime256v1)
        .ExpectReconfigCurve(kWeaveCurveId_secp224r1)
        .Run();

    // Initiator only supports secp224r1, responder only supports prime256v1, expect error
    CASEEngineTest("No common curves")
        .ProposedCurve(kWeaveCurveId_secp224r1)
        .InitiatorAllowedCurves(kWeaveCurveSet_secp224r1)
        .ResponderAllowedCurves(kWeaveCurveSet_prime256v1)
        .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_ELLIPTIC_CURVE)
        .Run();

#endif
}

void CASEEngineTests_KeyConfirmationTests()
{
    // Initiator does not request key confirmation.
    CASEEngineTest("No initiator key confirm")
        .InitiatorRequestKeyConfirm(false)
        .Run();

    // Initiator does not request key confirmation, but responder requires it.
    CASEEngineTest("Responder requires key confirm")
        .InitiatorRequestKeyConfirm(false)
        .ResponderRequiresKeyConfirm(true)
        .Run();
}

uint32_t gFuzzTestDurationSecs = 5;

void CASEEngineTests_FuzzTests()
{
    time_t now, endTime;

    time(&now);
    endTime = now + gFuzzTestDurationSecs;

    while (true)
    {
        time(&now);
        if (now >= endTime)
            break;

        // Fuzz contents of BeginSessionRequest message, verify protocol error.
        {
            MessageFuzzer fuzzer = MessageFuzzer("BeginSessionRequest")
                .Skip(8, 8)  // Avoid mutating the proposed protocol config or ECDH curve fields
                             // in the BeginSessionRequest, as doing so will elicit a reconfigure
                             // rather than an error.
                .TimeLimit(endTime);
            CASEEngineTest("Mutate BeginSessionRequest")
                .Mutator(&fuzzer)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_WRONG_TLV_TYPE)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_INVALID_TLV_TAG)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_INVALID_TLV_ELEMENT)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_END_OF_TLV)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_TLV_UNDERRUN)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_INVALID_SIGNATURE)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_INVALID_ARGUMENT)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_MESSAGE_INCOMPLETE)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_CA_CERT_NOT_FOUND)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_UNSUPPORTED_CERT_FORMAT)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_INCORRECT_STATE)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_CERT_NOT_VALID_YET)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_CERT_EXPIRED)
                .ExpectError("Responder:ProcessBeginSessionRequest", WEAVE_ERROR_CERT_USAGE_NOT_ALLOWED)
                .ExpectError("Responder:ProcessBeginSessionRequest", ASN1_ERROR_UNKNOWN_OBJECT_ID)
                .ExpectError("Responder:ProcessBeginSessionRequest", ASN1_ERROR_OVERFLOW)
                .Run();
        }

        // Fuzz contents of BeginSessionResponse message, verify protocol error.
        {
            MessageFuzzer fuzzer = MessageFuzzer("BeginSessionResponse")
                .TimeLimit(endTime);
            CASEEngineTest("Mutate BeginSessionResponse")
                .Mutator(&fuzzer)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_WRONG_TLV_TYPE)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_INVALID_TLV_TAG)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_INVALID_TLV_ELEMENT)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_END_OF_TLV)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_TLV_UNDERRUN)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_INVALID_SIGNATURE)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_INVALID_ARGUMENT)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_MESSAGE_INCOMPLETE)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_CA_CERT_NOT_FOUND)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_UNSUPPORTED_CERT_FORMAT)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_INCORRECT_STATE)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_KEY_CONFIRMATION_FAILED)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_CERT_USAGE_NOT_ALLOWED)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_CERT_NOT_VALID_YET)
                .ExpectError("Initiator:ProcessBeginSessionResponse", WEAVE_ERROR_CERT_EXPIRED)
                .ExpectError("Initiator:ProcessBeginSessionResponse", ASN1_ERROR_UNKNOWN_OBJECT_ID)
                .ExpectError("Initiator:ProcessBeginSessionResponse", ASN1_ERROR_OVERFLOW)
                .Run();
        }

        // Fuzz contents of InitiatorKeyConfirm message, verify protocol error.
        {
            MessageFuzzer fuzzer = MessageFuzzer("InitiatorKeyConfirm")
                .TimeLimit(endTime);
            CASEEngineTest("Mutate InitiatorKeyConfirm")
                .Mutator(&fuzzer)
                .InitiatorRequestKeyConfirm(true)
                .ExpectError("Responder:ProcessInitiatorKeyConfirm", WEAVE_ERROR_KEY_CONFIRMATION_FAILED)
                .Run();
        }
    }

}

static OptionDef gToolOptionDefs[] =
{
    { "fuzz-duration", kArgumentRequired, 'f' },
    { }
};

static const char *const gToolOptionHelp =
    "  -f, --fuzz-duration <seconds>\n"
    "       Fuzzing duration in seconds.\n"
    "\n";

static OptionSet gToolOptions =
{
    HandleOption,
    gToolOptionDefs,
    "GENERAL OPTIONS",
    gToolOptionHelp
};

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT,
    "Unit tests for Weave CASE engine.\n"
);

static OptionSet *gToolOptionSets[] =
{
    &gToolOptions,
    &gHelpOptions,
    NULL
};

int main(int argc, char *argv[])
{
    WEAVE_ERROR err;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    tcpip_init(NULL, NULL);
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    err = nl::Weave::Platform::Security::InitSecureRandomDataSource(NULL, 64, NULL, 0);
    FAIL_ERROR(err, "InitSecureRandomDataSource() failed");

    if (!ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets))
    {
        exit(EXIT_FAILURE);
    }

    CASEEngineTests_BasicTests();
    CASEEngineTests_EllipticCurveTests();
    CASEEngineTests_ConfigNegotiationTests();
    CASEEngineTests_CurveNegotiationTests();
    CASEEngineTests_KeyConfirmationTests();
    CASEEngineTests_FuzzTests();

    printf("All tests succeeded\n");

    exit(EXIT_SUCCESS);
}

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'f':
        if (!ParseInt(arg, gFuzzTestDurationSecs))
        {
            PrintArgError("%s: Invalid value specified for fuzz duration: %s\n", progName, arg);
            return false;
        }
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}
