/*
 *
 *    Copyright (c) 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 unit tests for the Weave key export protocol.
 *
 */

#include <stdio.h>

#include <nltest.h>

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

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

using namespace nl::Inet;
using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles::Security;
using namespace nl::Weave::Profiles::Security::KeyExport;
using namespace nl::Weave::Profiles::Security::AppKeys;
using namespace nl::Weave::ASN1;

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

#define DEBUG_PRINT_ENABLE 0

static WEAVE_ERROR InitValidationContext(ValidationContext& validContext)
{
    WEAVE_ERROR err;
    ASN1UniversalTime validTime;

    // Arrange to validate the signature for code signing purposes.
    memset(&validContext, 0, sizeof(validContext));
    validContext.RequiredKeyUsages = kKeyUsageFlag_DigitalSignature;

    // Set the effective validation time.
    validTime.Year = 2017;
    validTime.Month = 01;
    validTime.Day = 31;
    validTime.Hour = validTime.Minute = validTime.Second = 0;
    err = PackCertTime(validTime, validContext.EffectiveTime);
    SuccessOrExit(err);

exit:
    return err;
}

class InitiatorKeyExportDelegate : public WeaveKeyExportDelegate
{
private:
    enum
    {
        // Max Device Private Key Size -- Size of the temporary buffer used to hold
        // a device's TLV encoded private key.
        kMaxDevicePrivateKeySize = 300,

        // Max Validation Certs -- This controls the maximum number of certificates
        // that can be involved in the validation of an image signature. It must
        // include room for the signing cert, the trust anchors and any intermediate
        // certs included in the signature object.
        kMaxCerts = 4,

        // Certificate Decode Buffer Size -- Size of the temporary buffer used to decode
        // certs. The buffer must be big enough to hold the ASN1 DER encoding of the
        // TBSCertificate portion of the largest cert involved in signature verification.
        // Note that all certificates included in the signature are decoded using this
        // buffer, even if they are ultimately not involved in verifying the image
        // signature.
        kCertDecodeBufferSize = 644
    };

public:
    // Get the key export certificate set for the local node.
    virtual WEAVE_ERROR GetNodeCertSet(bool isInitiator, WeaveCertificateSet& certSet)
    {
        WEAVE_ERROR err;
        WeaveCertificateData *cert;
        bool certSetInitialized = false;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Initialize certificate set.
        err = certSet.Init(kMaxCerts, kCertDecodeBufferSize, nl::Weave::Platform::Security::MemoryAlloc, nl::Weave::Platform::Security::MemoryFree);
        SuccessOrExit(err);
        certSetInitialized = true;

        // Load Nest development root cert and mark it trusted.
        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);

        cert->CertFlags |= kCertFlag_IsTrusted;

        // Load the intermediate (DeviceCA) cert.
        err = certSet.LoadCert(nl::NestCerts::Development::DeviceCA::Cert, nl::NestCerts::Development::DeviceCA::CertLength, 0, cert);
        SuccessOrExit(err);

        // Load the signing cert.
        err = certSet.LoadCert(TestDevice1_Cert, TestDevice1_CertLength, 0, cert);
        SuccessOrExit(err);

    exit:
        if (err != WEAVE_NO_ERROR && certSetInitialized)
            certSet.Release();

        return err;
    }

    // Called when the key export engine is done with the certificate set returned by GetNodeCertSet().
    virtual WEAVE_ERROR ReleaseNodeCertSet(bool isInitiator, WeaveCertificateSet& certSet)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        certSet.Release();

    exit:
        return err;
    }

    // Get the local node's private key.
    virtual WEAVE_ERROR GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        weavePrivKey = (uint8_t *)nl::Weave::Platform::Security::MemoryAlloc(kMaxDevicePrivateKeySize);
        VerifyOrExit(weavePrivKey != NULL, err = WEAVE_ERROR_NO_MEMORY);

        memcpy((uint8_t *)weavePrivKey, TestDevice1_PrivateKey, TestDevice1_PrivateKeyLength);
        weavePrivKeyLen = TestDevice1_PrivateKeyLength;

    exit:
        return err;
    }

    // Called when the key export engine is done with the buffer returned by GetNodePrivateKey().
    virtual WEAVE_ERROR ReleaseNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        if (weavePrivKey != NULL)
        {
            nl::Weave::Platform::Security::MemoryFree((void *)weavePrivKey);
            weavePrivKey = NULL;
        }

    exit:
        return err;
    }

    // Prepare the supplied certificate set and validation context for use in validating the certificate of a peer.
    // This method is responsible for loading the trust anchors into the certificate set.
    virtual WEAVE_ERROR BeginCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext)
    {
        WEAVE_ERROR err;
        WeaveCertificateData *cert;
        bool certSetInitialized = false;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Initialize certificate set.
        err = certSet.Init(kMaxCerts, kCertDecodeBufferSize, nl::Weave::Platform::Security::MemoryAlloc, nl::Weave::Platform::Security::MemoryFree);
        SuccessOrExit(err);
        certSetInitialized = true;

        // Load Nest development root cert and mark it trusted.
        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);

        cert->CertFlags |= kCertFlag_IsTrusted;

        // Initialize the validation context.
        InitValidationContext(validContext);

    exit:
        if (err != WEAVE_NO_ERROR && certSetInitialized)
            certSet.Release();

        return err;
    }

    // Called with the results of validating the peer's certificate.
    // Requestor verifies that response came from expected node.
    virtual WEAVE_ERROR HandleCertValidationResult(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext,
                                                   const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t requestedKeyId)
    {
        WEAVE_ERROR err;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Client root key export response message should be signed by the Weave device certificate.
        if (requestedKeyId == WeaveKeyId::kClientRootKey &&
            validContext.SigningCert->SubjectDN.AttrOID == ASN1::kOID_AttributeType_WeaveDeviceId)
            err = WEAVE_NO_ERROR;
        else
            err = WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_RESPONSE;

    exit:
        return err;
    }

    // Called when peer certificate validation is complete.
    virtual WEAVE_ERROR EndCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        certSet.Release();

    exit:
        return err;
    }

    // Called by requestor and responder to verify that received message was appropriately secured when the message isn't signed.
    virtual WEAVE_ERROR ValidateUnsignedKeyExportMessage(bool isInitiator, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t requestedKeyId)
    {
        WEAVE_ERROR err;

        VerifyOrExit(isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // IN THIS TEST ONLY:
        //   - Fabric secret can be exported by any Weave node if the request/response messages are encrypted
        //     with session key, which was created during PASE handshake.
        //   - Intermediate application key can be exported by the service end point.
        // IN THE REAL IMPLEMENTATION:
        //   - Currently there is no use case where fabric secret or any other key can be exported if the
        //     request/response messages are unsigned. This function should always return
        //     WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_RESPONSE error.
        if (requestedKeyId == WeaveKeyId::kFabricSecret &&
            WeaveKeyId::IsSessionKey(msgInfo->KeyId) &&
            msgInfo->PeerAuthMode == kWeaveAuthMode_PASE_PairingCode)
            err = WEAVE_NO_ERROR;
        else if (WeaveKeyId::GetType(requestedKeyId) == WeaveKeyId::kType_AppIntermediateKey &&
                 WeaveKeyId::IsSessionKey(msgInfo->KeyId) &&
                 msgInfo->PeerAuthMode == kWeaveAuthMode_CASE_ServiceEndPoint)
            err = WEAVE_NO_ERROR;
        else
            err = WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_RESPONSE;

    exit:
        return err;
    }
};

class ResponderKeyExportDelegate : public WeaveKeyExportDelegate
{
private:
    enum
    {
        // Max Device Private Key Size -- Size of the temporary buffer used to hold
        // a device's TLV encoded private key.
        kMaxDevicePrivateKeySize = 300,

        // Max Validation Certs -- This controls the maximum number of certificates
        // that can be involved in the validation of an image signature. It must
        // include room for the signing cert, the trust anchors and any intermediate
        // certs included in the signature object.
        kMaxCerts = 4,

        // Certificate Decode Buffer Size -- Size of the temporary buffer used to decode
        // certs. The buffer must be big enough to hold the ASN1 DER encoding of the
        // TBSCertificate portion of the largest cert involved in signature verification.
        // Note that all certificates included in the signature are decoded using this
        // buffer, even if they are ultimately not involved in verifying the image
        // signature.
        kCertDecodeBufferSize = 644
    };

public:
    // Get the key export certificate set for the local node.
    virtual WEAVE_ERROR GetNodeCertSet(bool isInitiator, WeaveCertificateSet& certSet)
    {
        WEAVE_ERROR err;
        WeaveCertificateData *cert;
        bool certSetInitialized = false;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Initialize certificate set.
        err = certSet.Init(kMaxCerts, kCertDecodeBufferSize, nl::Weave::Platform::Security::MemoryAlloc, nl::Weave::Platform::Security::MemoryFree);
        SuccessOrExit(err);
        certSetInitialized = true;

        // Load Nest development root cert and mark it trusted.
        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);

        cert->CertFlags |= kCertFlag_IsTrusted;

        // Load the intermediate (DeviceCA) cert.
        err = certSet.LoadCert(nl::NestCerts::Development::DeviceCA::Cert, nl::NestCerts::Development::DeviceCA::CertLength, 0, cert);
        SuccessOrExit(err);

        // Load the signing cert.
        err = certSet.LoadCert(TestDevice2_Cert, TestDevice2_CertLength, 0, cert);
        SuccessOrExit(err);

    exit:
        if (err != WEAVE_NO_ERROR && certSetInitialized)
            certSet.Release();

        return err;
    }

    // Called when the key export engine is done with the certificate set returned by GetNodeCertSet().
    virtual WEAVE_ERROR ReleaseNodeCertSet(bool isInitiator, WeaveCertificateSet& certSet)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        certSet.Release();

    exit:
        return err;
    }

    // Get the local node's private key.
    virtual WEAVE_ERROR GetNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey, uint16_t& weavePrivKeyLen)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        weavePrivKey = (uint8_t *)nl::Weave::Platform::Security::MemoryAlloc(kMaxDevicePrivateKeySize);
        VerifyOrExit(weavePrivKey != NULL, err = WEAVE_ERROR_NO_MEMORY);

        memcpy((uint8_t *)weavePrivKey, TestDevice2_PrivateKey, TestDevice2_PrivateKeyLength);
        weavePrivKeyLen = TestDevice2_PrivateKeyLength;

    exit:
        return err;
    }

    // Called when the key export engine is done with the buffer returned by GetNodePrivateKey().
    virtual WEAVE_ERROR ReleaseNodePrivateKey(bool isInitiator, const uint8_t *& weavePrivKey)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        if (weavePrivKey != NULL)
        {
            nl::Weave::Platform::Security::MemoryFree((void *)weavePrivKey);
            weavePrivKey = NULL;
        }

    exit:
        return err;
    }

    // Prepare the supplied certificate set and validation context for use in validating the certificate of a peer.
    // This method is responsible for loading the trust anchors into the certificate set.
    virtual WEAVE_ERROR BeginCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext)
    {
        WEAVE_ERROR err;
        WeaveCertificateData *cert;
        bool certSetInitialized = false;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Initialize certificate set.
        err = certSet.Init(kMaxCerts, kCertDecodeBufferSize, nl::Weave::Platform::Security::MemoryAlloc, nl::Weave::Platform::Security::MemoryFree);
        SuccessOrExit(err);
        certSetInitialized = true;

        // Load Nest development root cert and mark it trusted.
        err = certSet.LoadCert(nl::NestCerts::Development::Root::Cert, nl::NestCerts::Development::Root::CertLength, 0, cert);
        SuccessOrExit(err);

        cert->CertFlags |= kCertFlag_IsTrusted;

        // Initialize the validation context.
        InitValidationContext(validContext);

    exit:
        if (err != WEAVE_NO_ERROR && certSetInitialized)
            certSet.Release();

        return err;
    }

    // Called with the results of validating the peer's certificate.
    // Responder verifies that requestor is authorized to export the specified key.
    virtual WEAVE_ERROR HandleCertValidationResult(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext,
                                                   const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t requestedKeyId)
    {
        WEAVE_ERROR err;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // IN THIS TEST ONLY:
        //   - Client root key can be exported by any Weave node if the request message was signed
        //     and the trust anchor is Nest root certificate.
        // IN THE REAL IMPLEMENTATION:
        //   - Client root key can be exported only by mobiles, i.e. the trust anchor should be an access
        //     token certificate.
        if (requestedKeyId == WeaveKeyId::kClientRootKey && validContext.TrustAnchor == &certSet.Certs[0])
            err = WEAVE_NO_ERROR;
        else
            err = WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_REQUEST;

    exit:
        return err;
    }

    // Called when peer certificate validation is complete.
    virtual WEAVE_ERROR EndCertValidation(bool isInitiator, WeaveCertificateSet& certSet, ValidationContext& validContext)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        certSet.Release();

    exit:
        return err;
    }

    // Called by requestor and responder to verify that received message was appropriately secured when the message isn't signed.
    virtual WEAVE_ERROR ValidateUnsignedKeyExportMessage(bool isInitiator, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t requestedKeyId)
    {
        WEAVE_ERROR err;

        VerifyOrExit(!isInitiator, err = WEAVE_ERROR_INVALID_ARGUMENT);

        // IN THIS TEST ONLY:
        //   - Fabric secret can be exported by any Weave node if the request/response messages are encrypted
        //     with session key, which was created during PASE handshake.
        //   - Intermediate application key can be exported by the service end point.
        // IN THE REAL IMPLEMENTATION:
        //   - Currently there is no use case where fabric secret or any other key can be exported if the
        //     request/response messages are unsigned. This function should always return
        //     WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_REQUEST error.
        if (requestedKeyId == WeaveKeyId::kFabricSecret &&
            WeaveKeyId::IsSessionKey(msgInfo->KeyId) &&
            msgInfo->PeerAuthMode == kWeaveAuthMode_PASE_PairingCode)
            err = WEAVE_NO_ERROR;
        else if (WeaveKeyId::GetType(requestedKeyId) == WeaveKeyId::kType_AppIntermediateKey &&
                 WeaveKeyId::IsSessionKey(msgInfo->KeyId) &&
                 msgInfo->PeerAuthMode == kWeaveAuthMode_CASE_ServiceEndPoint)
            err = WEAVE_NO_ERROR;
        else
            err = WEAVE_ERROR_UNAUTHORIZED_KEY_EXPORT_REQUEST;

    exit:
        return err;
    }
};


enum
{
    kKeyExportRequestError_None             = 0,
    kKeyExportRequestError_InvalidConfig,
};

enum
{
    kKeyExportResponseError_None             = 0,
    kKeyExportResponseError_Reconfigure,
    kKeyExportResponseError_NoCommonConfig,
};

// Test input vector format.
struct TestContext {
    uint8_t config;
    bool signMessages;
    const uint32_t* requestedKeyId;
    const uint32_t* expectedKeyId;
    const uint8_t* expectedKey;
    const uint8_t* expectedKeyLen;
    const uint16_t* msgKeyId;
    WeaveAuthMode msgKeyAuthMode;
    uint8_t requestErrorType;
    uint8_t responseErrorType;
};

static const uint32_t sFabricSecretId = WeaveKeyId::kFabricSecret;
static const uint32_t sClientRootKeyId = WeaveKeyId::kClientRootKey;
static const uint16_t sNoneKeyId = WeaveKeyId::kNone;

// Test input data.
static struct TestContext sContext[] = {
    // Proposed Config1 tests.
    { kKeyExportConfig_Config1, false, &sFabricSecretId, &sFabricSecretId, sFabricSecret,
      &sFabricSecretLen, &sTestDefaultSessionKeyId, kWeaveAuthMode_PASE_PairingCode,
      kKeyExportRequestError_InvalidConfig, kKeyExportResponseError_None },
    { kKeyExportConfig_Config1, false, &sIntermediateKeyId_FRK_EC, &sIntermediateKeyId_FRK_E2, sIntermediateKey_FRK_E2,
      &sIntermediateKeyLen_FRK_E2, &sTestDefaultSessionKeyId, kWeaveAuthMode_CASE_ServiceEndPoint,
      kKeyExportRequestError_None, kKeyExportResponseError_None },
    { kKeyExportConfig_Config1, true, &sClientRootKeyId, &sClientRootKeyId, sClientRootKey,
      &sClientRootKeyLen, &sNoneKeyId, kWeaveAuthMode_Unauthenticated,
      kKeyExportRequestError_None, kKeyExportResponseError_None },
    // Proposed Config2 tests.
    { kKeyExportConfig_Config2, false, &sFabricSecretId, &sFabricSecretId, sFabricSecret,
      &sFabricSecretLen, &sTestDefaultSessionKeyId, kWeaveAuthMode_PASE_PairingCode,
      kKeyExportRequestError_None, kKeyExportResponseError_None },
    { kKeyExportConfig_Config2, false, &sIntermediateKeyId_FRK_EC, &sIntermediateKeyId_FRK_E2, sIntermediateKey_FRK_E2,
      &sIntermediateKeyLen_FRK_E2, &sTestDefaultSessionKeyId, kWeaveAuthMode_CASE_ServiceEndPoint,
      kKeyExportRequestError_InvalidConfig, kKeyExportResponseError_None },
    { kKeyExportConfig_Config2, true, &sClientRootKeyId, &sClientRootKeyId, sClientRootKey,
      &sClientRootKeyLen, &sNoneKeyId, kWeaveAuthMode_Unauthenticated,
      kKeyExportRequestError_None, kKeyExportResponseError_None },
    // Proposed Config1 reconfigured to Config2 tests.
    { kKeyExportConfig_Config1, false, &sFabricSecretId, &sFabricSecretId, sFabricSecret,
      &sFabricSecretLen, &sTestDefaultSessionKeyId, kWeaveAuthMode_PASE_PairingCode,
      kKeyExportRequestError_None, kKeyExportResponseError_Reconfigure },
    { kKeyExportConfig_Config1, false, &sIntermediateKeyId_FRK_EC, &sIntermediateKeyId_FRK_E2, sIntermediateKey_FRK_E2,
      &sIntermediateKeyLen_FRK_E2, &sTestDefaultSessionKeyId, kWeaveAuthMode_CASE_ServiceEndPoint,
      kKeyExportRequestError_None, kKeyExportResponseError_Reconfigure },
    { kKeyExportConfig_Config1, true, &sClientRootKeyId, &sClientRootKeyId, sClientRootKey,
      &sClientRootKeyLen, &sNoneKeyId, kWeaveAuthMode_Unauthenticated,
      kKeyExportRequestError_InvalidConfig, kKeyExportResponseError_Reconfigure },
    // Proposed Config2 reconfigured to Config1 tests.
    { kKeyExportConfig_Config2, false, &sFabricSecretId, &sFabricSecretId, sFabricSecret,
      &sFabricSecretLen, &sTestDefaultSessionKeyId, kWeaveAuthMode_PASE_PairingCode,
      kKeyExportRequestError_None, kKeyExportResponseError_Reconfigure },
    { kKeyExportConfig_Config2, false, &sIntermediateKeyId_FRK_EC, &sIntermediateKeyId_FRK_E2, sIntermediateKey_FRK_E2,
      &sIntermediateKeyLen_FRK_E2, &sTestDefaultSessionKeyId, kWeaveAuthMode_CASE_ServiceEndPoint,
      kKeyExportRequestError_None, kKeyExportResponseError_Reconfigure },
    { kKeyExportConfig_Config2, true, &sClientRootKeyId, &sClientRootKeyId, sClientRootKey,
      &sClientRootKeyLen, &sNoneKeyId, kWeaveAuthMode_Unauthenticated,
      kKeyExportRequestError_None, kKeyExportResponseError_Reconfigure },
    // No common Configs for requester and responder tests.
    { kKeyExportConfig_Config1, false, &sFabricSecretId, &sFabricSecretId, sFabricSecret,
      &sFabricSecretLen, &sTestDefaultSessionKeyId, kWeaveAuthMode_PASE_PairingCode,
      kKeyExportRequestError_InvalidConfig, kKeyExportResponseError_NoCommonConfig },
    { kKeyExportConfig_Config2, false, &sIntermediateKeyId_FRK_EC, &sIntermediateKeyId_FRK_E2, sIntermediateKey_FRK_E2,
      &sIntermediateKeyLen_FRK_E2, &sTestDefaultSessionKeyId, kWeaveAuthMode_CASE_ServiceEndPoint,
      kKeyExportRequestError_None, kKeyExportResponseError_NoCommonConfig },
};

// Number of test context examples.
static const size_t kTestElements = sizeof(sContext) / sizeof(struct TestContext);

static void KeyExportProtocol_Test(nlTestSuite *inSuite, void *inContext)
{
    WEAVE_ERROR err;
    WeaveKeyExport initiatorEng;
    WeaveKeyExport responderEng;
    InetBuffer *msgBuf = NULL;
    InitiatorKeyExportDelegate initiatorDelegate;
    ResponderKeyExportDelegate responderDelegate;
    TestGroupKeyStore keyStore;
    uint32_t exportedKeyId;
    uint16_t exportedKeyLen;
    uint8_t exportedKey[AppKeys::kWeaveFabricSecretSize];
    uint16_t dataLen;
    IPPacketInfo pktInfo;
    WeaveMessageInfo msgInfo;

    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++, theContext++)
    {
        uint8_t proposedConfig = theContext->config;
        bool signMessages = theContext->signMessages;
        uint32_t keyId = *theContext->requestedKeyId;
        uint32_t expectedKeyId = *theContext->expectedKeyId;
        const uint8_t* expectedKey = theContext->expectedKey;
        uint8_t expectedKeyLen = *theContext->expectedKeyLen;

        msgInfo.Clear();
        msgInfo.KeyId = *theContext->msgKeyId;
        msgInfo.PeerAuthMode = theContext->msgKeyAuthMode;

        sCurrentUTCTime = sEpochKey2_StartTime + 1;

        if (theContext->responseErrorType == kKeyExportResponseError_Reconfigure)
            printf("Running Key Export Protocol Test with proposed Config%d (Reconfigured to Config%d) with %s messages to export KeyId = %08X.\n",
                   proposedConfig, (KeyExport::kKeyExportSupportedConfig_All & ~proposedConfig), (signMessages ? "Signed" : "Unsigned"), keyId);
        else if (theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
            printf("Running Key Export Protocol Test with proposed Config%d while responder only supports Config%d, which results in NoCommonConfig error.\n",
                   proposedConfig, (KeyExport::kKeyExportSupportedConfig_All & ~proposedConfig));
        else
            printf("Running Key Export Protocol Test with proposed Config%d with %s messages to export KeyId = %08X.\n",
                   proposedConfig, (signMessages ? "Signed" : "Unsigned"), keyId);

        {
            initiatorEng.Reset();
            initiatorEng.Init(&initiatorDelegate);

            if (theContext->requestErrorType == kKeyExportRequestError_InvalidConfig)
                initiatorEng.SetAllowedConfigs(0);
            else if (theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
                initiatorEng.SetAllowedConfigs(proposedConfig);
            else
                initiatorEng.SetAllowedConfigs(KeyExport::kKeyExportSupportedConfig_All);

            msgBuf = InetBuffer::New();
            NL_TEST_ASSERT(inSuite, msgBuf != NULL);

            err = initiatorEng.GenerateKeyExportRequest(msgBuf->Start(), msgBuf->AvailableDataLength(), dataLen, proposedConfig, keyId, signMessages);

            if (theContext->requestErrorType == kKeyExportRequestError_InvalidConfig)
            {
                NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_INVALID_KEY_EXPORT_CONFIGURATION);

                initiatorEng.Reset();
                initiatorEng.Init(&initiatorDelegate);

                if (theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
                    initiatorEng.SetAllowedConfigs(proposedConfig);
                else
                    initiatorEng.SetAllowedConfigs(KeyExport::kKeyExportSupportedConfig_All);

                InetBuffer::Free(msgBuf);
                msgBuf = InetBuffer::New();
                NL_TEST_ASSERT(inSuite, msgBuf != NULL);

                err = initiatorEng.GenerateKeyExportRequest(msgBuf->Start(), msgBuf->AvailableDataLength(), dataLen, proposedConfig, keyId, signMessages);
            }

            NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

            msgBuf->SetDataLength(dataLen);
        }

#if DEBUG_PRINT_ENABLE
        printf("KeyExportRequest Message (%d bytes):\n", msgBuf->DataLength());
        DumpMemoryCStyle(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);
#endif

        {
            responderEng.Reset();
            responderEng.Init(&responderDelegate, &keyStore);

            if (theContext->responseErrorType == kKeyExportResponseError_Reconfigure ||
                theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
                responderEng.SetAllowedConfigs(KeyExport::kKeyExportSupportedConfig_All & ~proposedConfig);
            else
                responderEng.SetAllowedConfigs(KeyExport::kKeyExportSupportedConfig_All);

            err = responderEng.ProcessKeyExportRequest(msgBuf->Start(), msgBuf->DataLength(), &pktInfo, &msgInfo);
            if (theContext->responseErrorType == kKeyExportResponseError_Reconfigure)
                NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_KEY_EXPORT_RECONFIGURE_REQUIRED);
            else if (theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
                NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_NO_COMMON_KEY_EXPORT_CONFIGURATIONS);
            else
                NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

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

            if (theContext->responseErrorType == kKeyExportResponseError_Reconfigure)
            {
                msgBuf = InetBuffer::New();
                NL_TEST_ASSERT(inSuite, msgBuf != NULL);

                err = responderEng.GenerateKeyExportReconfigure(msgBuf->Start(), msgBuf->AvailableDataLength(), dataLen);
                NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

                msgBuf->SetDataLength(dataLen);

#if DEBUG_PRINT_ENABLE
                printf("KeyExportReconfigure Message (%d bytes):\n", msgBuf->DataLength());
                DumpMemoryCStyle(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);
#endif

                uint8_t newConfig;

                err = initiatorEng.ProcessKeyExportReconfigure(msgBuf->Start(), msgBuf->DataLength(), newConfig);
                NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

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

                msgBuf = InetBuffer::New();
                NL_TEST_ASSERT(inSuite, msgBuf != NULL);

                err = initiatorEng.GenerateKeyExportRequest(msgBuf->Start(), msgBuf->AvailableDataLength(), dataLen, newConfig, keyId, signMessages);
                NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

                msgBuf->SetDataLength(dataLen);

#if DEBUG_PRINT_ENABLE
                printf("Reconfigured KeyExportRequest Message (%d bytes):\n", msgBuf->DataLength());
                DumpMemoryCStyle(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);
#endif

                // For responder this request is unrelated to the previous key export request.
                responderEng.Reset();
                responderEng.Init(&responderDelegate, &keyStore);

                responderEng.SetAllowedConfigs(KeyExport::kKeyExportSupportedConfig_All & ~proposedConfig);

                err = responderEng.ProcessKeyExportRequest(msgBuf->Start(), msgBuf->DataLength(), &pktInfo, &msgInfo);
                NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

                InetBuffer::Free(msgBuf);
                msgBuf = NULL;
            }
            else if (theContext->responseErrorType == kKeyExportResponseError_NoCommonConfig)
            {
                continue;
            }

            msgBuf = InetBuffer::New();
            NL_TEST_ASSERT(inSuite, msgBuf != NULL);

            err = responderEng.GenerateKeyExportResponse(msgBuf->Start(), msgBuf->AvailableDataLength(), dataLen);
            NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

            msgBuf->SetDataLength(dataLen);
        }

#if DEBUG_PRINT_ENABLE
        printf("KeyExportResponse Message (%d bytes):\n", msgBuf->DataLength());
        DumpMemoryCStyle(msgBuf->Start(), msgBuf->DataLength(), "  ", 16);
#endif

        {
            err = initiatorEng.ProcessKeyExportResponse(msgBuf->Start(), msgBuf->DataLength(), &pktInfo, &msgInfo,
                                                        exportedKey, sizeof(exportedKey), exportedKeyLen, exportedKeyId);
            NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

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

#if DEBUG_PRINT_ENABLE
        printf("Exported Client Root Key:\n");
        DumpMemoryCStyle(exportedKey, exportedKeyLen, "  ", 16);
#endif

        // Compare the exported key.
        NL_TEST_ASSERT(inSuite, exportedKeyId == expectedKeyId);
        NL_TEST_ASSERT(inSuite, exportedKeyLen == expectedKeyLen);
        NL_TEST_ASSERT(inSuite, memcmp(exportedKey, expectedKey, exportedKeyLen) == 0);
    }
}


/**
 *   Test Suite. It lists all the test functions.
 */
static const nlTest sTests[] = {
    NL_TEST_DEF("KeyExportProtocol",                KeyExportProtocol_Test),
    NL_TEST_SENTINEL()
};

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

    nlTestSuite testSuite = {
        "weave-key-export-protocol",
        &sTests[0]
    };

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

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

    nl_test_set_output_style(OUTPUT_CSV);

    nlTestRunner(&testSuite, &sContext);

    return nlTestRunnerStats(&testSuite);
}
