/*
 *
 *    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 interfaces for generating, verifying, and
 *      working with Weave security signatures.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>

#include <Weave/Support/NLDLLUtil.h>
#include <Weave/Core/WeaveCore.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Support/ASN1.h>
#include <Weave/Support/ASN1Macros.h>
#include <Weave/Support/crypto/HashAlgos.h>
#include <Weave/Support/crypto/EllipticCurve.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include <Weave/Profiles/security/WeaveCert.h>
#include <Weave/Profiles/security/WeaveSig.h>
#include <Weave/Profiles/security/WeavePrivateKey.h>
#include <Weave/Support/CodeUtils.h>

namespace nl {
namespace Weave {
namespace Profiles {
namespace Security {

using namespace nl::Weave::TLV;
using namespace nl::Weave::ASN1;
using namespace nl::Weave::Crypto;
using nl::Weave::Platform::Security::SHA1;
using nl::Weave::Platform::Security::SHA256;

#define kWeaveSigTag ProfileTag(kWeaveProfile_Security, kTag_WeaveSignature)

WEAVE_ERROR WeaveSignatureGeneratorBase::GenerateSignature(const uint8_t * msgHash, uint8_t msgHashLen, TLVWriter & writer)
{
    return GenerateSignature(msgHash, msgHashLen, writer, kWeaveSigTag);
}

WEAVE_ERROR WeaveSignatureGeneratorBase::GenerateSignature(const uint8_t * msgHash, uint8_t msgHashLen,
        uint8_t * sigBuf, uint16_t sigBufSize, uint16_t & sigLen)
{
    WEAVE_ERROR err;
    TLVWriter writer;

    writer.Init(sigBuf, sigBufSize);

    err = GenerateSignature(msgHash, msgHashLen, writer, kWeaveSigTag);
    SuccessOrExit(err);

    err = writer.Finalize();
    SuccessOrExit(err);

    sigLen = writer.GetLengthWritten();

exit:
    return err;
}

WEAVE_ERROR WeaveSignatureGeneratorBase::GenerateSignature(const uint8_t * msgHash, uint8_t msgHashLen, TLVWriter & writer, uint64_t tag)
{
    WEAVE_ERROR err;
    TLVType containerType;

    VerifyOrExit(SigningCert != NULL, err = WEAVE_ERROR_INCORRECT_STATE);

    // Fail with UNSUPPORTED error if caller requested inclusion of certificate DN.
    // This feature is not currently supported.
    VerifyOrExit((Flags & kGenerateWeaveSignatureFlag_IncludeSigningCertSubjectDN) == 0,
                 err = WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE);

    // Start encoding the WeaveSignature structure.
    err = writer.StartContainer(tag, kTLVType_Structure, containerType);
    SuccessOrExit(err);

    // If the signature algorithm is NOT ECDSAWithSHA1, encode the SignatureAlgorithm field.
    if (SigAlgoOID != kOID_SigAlgo_ECDSAWithSHA1)
    {
        err = writer.Put(ContextTag(kTag_WeaveSignature_SignatureAlgorithm), SigAlgoOID);
        SuccessOrExit(err);
    }

    // Call the subclass to compute the actual signature data and encode it into the WeaveSignature structure.
    err = GenerateSignatureData(msgHash, msgHashLen, writer);
    SuccessOrExit(err);

    // If requested to include the signing certificate subject key id...
    if ((Flags & kGenerateWeaveSignatureFlag_IncludeSigningCertKeyId) != 0)
    {
        TLVType containerType2;

        // Verify that the signing certificate data includes a subject key id.
        VerifyOrExit(!SigningCert->SubjectKeyId.IsEmpty(), err = WEAVE_ERROR_INVALID_ARGUMENT);

        // Start the SigningCertificateRef structure.
        err = writer.StartContainer(ContextTag(kTag_WeaveSignature_SigningCertificateRef),
                                    kTLVType_Structure, containerType2);
        SuccessOrExit(err);

        // Write the Public Key Id field containing signing certificate's subject key id.
        err = writer.PutBytes(ContextTag(kTag_WeaveCertificateRef_PublicKeyId),
                              SigningCert->SubjectKeyId.Id, SigningCert->SubjectKeyId.Len);
        SuccessOrExit(err);

        err = writer.EndContainer(containerType2);
        SuccessOrExit(err);
    }

    // If requested to include related certificates...
    if ((Flags & kGenerateWeaveSignatureFlag_IncludeRelatedCertificates) != 0)
    {
        TLVType containerType2;

        // Start the RelatedCertificates array.  This contains the list of certificates the signature verifier
        // will need to verify the signature.
        err = writer.StartContainer(ContextTag(kTag_WeaveSignature_RelatedCertificates), kTLVType_Array, containerType2);
        SuccessOrExit(err);

        // Write all the non-trusted certificates currently in the certificate set, placing the signing certificate
        // first in the list.
        err = CertSet.SaveCerts(writer, SigningCert, false);
        SuccessOrExit(err);

        err = writer.EndContainer(containerType2);
        SuccessOrExit(err);
    }

    err = writer.EndContainer(containerType);
    SuccessOrExit(err);

exit:
    return err;
}

WEAVE_ERROR WeaveSignatureGenerator::GenerateSignature(const uint8_t * msgHash, uint8_t msgHashLen, TLVWriter & writer, uint64_t tag)
{
    WEAVE_ERROR err;

    VerifyOrExit(PrivKey != NULL, err = WEAVE_ERROR_INCORRECT_STATE);

    err = WeaveSignatureGeneratorBase::GenerateSignature(msgHash, msgHashLen, writer, tag);
    SuccessOrExit(err);

exit:
    return err;
}
WEAVE_ERROR WeaveSignatureGenerator::GenerateSignatureData(const uint8_t * msgHash, uint8_t msgHashLen, TLVWriter & writer)
{
    WEAVE_ERROR err;
    EncodedECPrivateKey privKey;
    EncodedECPublicKey pubKeyForPrivKey;
    EncodedECDSASignature ecdsaSig;
    uint32_t privKeyCurveId;
    uint8_t ecdsaRBuf[EncodedECDSASignature::kMaxValueLength];
    uint8_t ecdsaSBuf[EncodedECDSASignature::kMaxValueLength];

    // Verify the specified signature algorithm is supported.
    VerifyOrExit(SigAlgoOID != kOID_SigAlgo_SHA1WithRSAEncryption, err = WEAVE_ERROR_UNSUPPORTED_SIGNATURE_TYPE);
    VerifyOrExit(SigAlgoOID == kOID_SigAlgo_ECDSAWithSHA1 || SigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256, err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Verify the length of the supplied message hash.
    VerifyOrExit((SigAlgoOID == kOID_SigAlgo_ECDSAWithSHA1 && msgHashLen == SHA1::kHashLength) ||
                 (SigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256 && msgHashLen == SHA256::kHashLength), err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Decode the supplied private key.
    err = DecodeWeaveECPrivateKey(PrivKey, PrivKeyLen, privKeyCurveId, pubKeyForPrivKey, privKey);
    SuccessOrExit(err);

    // Verify the signing cert's public key and the supplied private key are from the same curve.
    VerifyOrExit(privKeyCurveId == SigningCert->PubKeyCurveId, err = WEAVE_ERROR_WRONG_KEY_TYPE);

    // If the private key included a copy of the public key, verify it matches the public key of
    // the certificate.
    if (pubKeyForPrivKey.ECPoint != NULL)
        VerifyOrExit(pubKeyForPrivKey.IsEqual(SigningCert->PublicKey.EC), err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Use temporary buffers to hold the generated signature value until we write it.
    ecdsaSig.R = ecdsaRBuf;
    ecdsaSig.RLen = sizeof(ecdsaRBuf);
    ecdsaSig.S = ecdsaSBuf;
    ecdsaSig.SLen = sizeof(ecdsaSBuf);

    // Generate an ECDSA signature for the given message hash.
    err = nl::Weave::Crypto::GenerateECDSASignature(WeaveCurveIdToOID(privKeyCurveId),
                                                    msgHash, msgHashLen,
                                                    privKey,
                                                    ecdsaSig);
    SuccessOrExit(err);

    // Encode the the signature as a Weave ECDSASignature TLV structure, using the
    // appropriate WeaveSignature context tag to identify the type of signature.
    err = EncodeWeaveECDSASignature(writer, ecdsaSig, ContextTag(kTag_WeaveSignature_ECDSASignatureData));
    SuccessOrExit(err);

exit:
    return err;
}

NL_DLL_EXPORT WEAVE_ERROR VerifyWeaveSignature(
    const uint8_t *msgHash, uint8_t msgHashLen,
    const uint8_t *sig, uint16_t sigLen,
    WeaveCertificateSet& certSet,
    ValidationContext& certValidContext)
{
    return VerifyWeaveSignature(msgHash, msgHashLen, sig, sigLen, kOID_SigAlgo_ECDSAWithSHA1, certSet, certValidContext);
}

NL_DLL_EXPORT WEAVE_ERROR VerifyWeaveSignature(
    const uint8_t *msgHash, uint8_t msgHashLen,
    const uint8_t *sig, uint16_t sigLen, OID expectedSigAlgoOID,
    WeaveCertificateSet& certSet,
    ValidationContext& certValidContext)
{
    WEAVE_ERROR err;
    TLVReader reader;
    EncodedECDSASignature ecdsaSig;
    WeaveCertificateData *signingCert = NULL;
    WeaveDN signingCertDN;
    CertificateKeyId signingCertSubjectKeyId;
    OID sigAlgoOID = kOID_SigAlgo_ECDSAWithSHA1; // Default if not specified in signature.

    VerifyOrExit(expectedSigAlgoOID == kOID_SigAlgo_ECDSAWithSHA1 || expectedSigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256,
                 err = WEAVE_ERROR_UNSUPPORTED_SIGNATURE_TYPE);

    signingCertDN.Clear();
    signingCertSubjectKeyId.Clear();

    reader.Init(sig, sigLen);

    // Parse the beginning of the WeaveSignature structure.
    err = reader.Next(kTLVType_Structure, ProfileTag(kWeaveProfile_Security, kTag_WeaveSignature));
    SuccessOrExit(err);

    {
        TLVType containerType;

        err = reader.EnterContainer(containerType);
        SuccessOrExit(err);

        err = reader.Next();

        if (err == WEAVE_NO_ERROR && reader.GetTag() == ContextTag(kTag_WeaveSignature_SignatureAlgorithm))
        {
            err = reader.Get(sigAlgoOID);
            SuccessOrExit(err);

            err = reader.Next();
        }

        VerifyOrExit(sigAlgoOID == expectedSigAlgoOID, err = WEAVE_ERROR_WRONG_WEAVE_SIGNATURE_ALGORITHM);

        if (err == WEAVE_NO_ERROR)
        {
            VerifyOrExit(reader.GetTag() == ContextTag(kTag_WeaveSignature_ECDSASignatureData), err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);
            VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

            // Decode the contained ECDSA signature.
            err = DecodeWeaveECDSASignature(reader, ecdsaSig);
            SuccessOrExit(err);

            err = reader.Next();
        }

        // Look for the SigningCertificateRef structure.  If found...
        if (err == WEAVE_NO_ERROR && reader.GetTag() == ContextTag(kTag_WeaveSignature_SigningCertificateRef))
        {
            TLVType containerType2;

            VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

            // Enter the SigningCertificateRef structure.
            err = reader.EnterContainer(containerType2);
            SuccessOrExit(err);

            // Advance to the first element.
            err = reader.Next();

            // Fail with an UNSUPPORTED error if the SigningCertificateRef contains a Subject path.  This form
            // of certificate reference is not currently supported.
            if (err == WEAVE_NO_ERROR)
            {
                VerifyOrExit(reader.GetTag() != ContextTag(kTag_WeaveCertificateRef_Subject), err = WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE);
            }

            // Look for the PublicKeyId field.  If found...
            if (err == WEAVE_NO_ERROR && reader.GetTag() == ContextTag(kTag_WeaveCertificateRef_PublicKeyId))
            {
                VerifyOrExit(reader.GetType() == kTLVType_ByteString, err = WEAVE_ERROR_WRONG_TLV_TYPE);

                // Extract the subject key id of the signing certificate.
                uint32_t len = reader.GetLength();
                VerifyOrExit(len < UINT8_MAX, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);
                signingCertSubjectKeyId.Len = (uint8_t)len;
                err = reader.GetDataPtr(signingCertSubjectKeyId.Id);
                SuccessOrExit(err);

                err = reader.Next();
            }

            if (err != WEAVE_END_OF_TLV)
                SuccessOrExit(err);

            err = reader.VerifyEndOfContainer();
            SuccessOrExit(err);

            err = reader.ExitContainer(containerType2);
            SuccessOrExit(err);

            err = reader.Next();
        }

        // If the RelatedCertificates array is present, load the specified certificates into the cert set...
        if (err == WEAVE_NO_ERROR && reader.GetTag() == ContextTag(kTag_WeaveSignature_RelatedCertificates))
        {
            uint8_t initialCertCount = certSet.CertCount;

            VerifyOrExit(reader.GetType() == kTLVType_Array, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

            err = certSet.LoadCerts(reader, kDecodeFlag_GenerateTBSHash);
            SuccessOrExit(err);

            // If one or more certificates were loaded...
            if (certSet.CertCount > initialCertCount)
            {
                // Unless otherwise specified, the signing certificate will be the first certificate
                // in the RelatedCertificates array.  So extract its subject key id and DN.
                if (signingCertDN.IsEmpty() && signingCertSubjectKeyId.IsEmpty())
                {
                    signingCertSubjectKeyId = certSet.Certs[initialCertCount].SubjectKeyId;
                    signingCertDN = certSet.Certs[initialCertCount].SubjectDN;
                }
            }

            err = reader.Next();
        }

        if (err != WEAVE_END_OF_TLV)
            SuccessOrExit(err);

        err = reader.VerifyEndOfContainer();
        SuccessOrExit(err);

        err = reader.ExitContainer(containerType);
        SuccessOrExit(err);
    }

    // Verify the length of the supplied message hash.
    VerifyOrExit((sigAlgoOID == kOID_SigAlgo_ECDSAWithSHA1 && msgHashLen == SHA1::kHashLength) ||
                 (sigAlgoOID == kOID_SigAlgo_ECDSAWithSHA256 && msgHashLen == SHA256::kHashLength), err = WEAVE_ERROR_INVALID_ARGUMENT);

    // Search the certificate set for the signing certificate and validate that it is trusted and
    // suitable for signing.
    certValidContext.RequiredKeyUsages |= kKeyUsageFlag_DigitalSignature;
    err = certSet.FindValidCert(signingCertDN, signingCertSubjectKeyId, certValidContext, signingCert);
    SuccessOrExit(err);

    // Verify the signature against the given message hash and the signing cert's public key.
    err = nl::Weave::Crypto::VerifyECDSASignature(WeaveCurveIdToOID(signingCert->PubKeyCurveId),
                                                  msgHash, msgHashLen,
                                                  ecdsaSig,
                                                  signingCert->PublicKey.EC);
    SuccessOrExit(err);

    // Record signing certificate.
    certValidContext.SigningCert = signingCert;

exit:
    return err;
}

WEAVE_ERROR GetWeaveSignatureAlgo(const uint8_t *sig, uint16_t sigLen, OID& sigAlgoOID)
{
    WEAVE_ERROR err;
    TLVReader reader;
    TLVType containerType;

    // Defaults to ECDSA-SHA1 if not specified in signature object.
    sigAlgoOID = kOID_SigAlgo_ECDSAWithSHA1;

    reader.Init(sig, sigLen);

    // Parse the beginning of the WeaveSignature structure.
    err = reader.Next(kTLVType_Structure, ProfileTag(kWeaveProfile_Security, kTag_WeaveSignature));
    SuccessOrExit(err);

    err = reader.EnterContainer(containerType);
    SuccessOrExit(err);

    err = reader.Next();

    if (err == WEAVE_NO_ERROR && reader.GetTag() == ContextTag(kTag_WeaveSignature_SignatureAlgorithm))
    {
        err = reader.Get(sigAlgoOID);
        SuccessOrExit(err);
    }

exit:
    return err;
}

/**
 * Generate and encode a Weave ECDSA signature
 *
 * Computes an ECDSA signature using a given private key and message hash and write the signature
 * as a Weave ECDSASignature structure to the specified TLV writer with the given tag.
 *
 * @param[in] writer            The TLVWriter object to which the encoded signature should
 *                              be written.
 * @param[in] tag               TLV tag to be associated with the encoded signature structure.
 * @param[in] msgHash           A buffer containing the hash of the message to be signed.
 * @param[in] msgHashLen        The length in bytes of the message hash.
 * @param[in] signingKey        A buffer containing the private key to be used to generate
 *                              the signature.  The private key is expected to be encoded as
 *                              a Weave EllipticCurvePrivateKey TLV structure.
 * @param[in] signingKeyLen     The length in bytes of the encoded private key.
 *
 * @retval #WEAVE_NO_ERROR      If the operation succeeded.
 * @retval other                Other Weave error codes related to decoding the private key,
 *                              generating the signature or encoding the signature.
 *
 */
WEAVE_ERROR GenerateAndEncodeWeaveECDSASignature(TLVWriter& writer, uint64_t tag,
        const uint8_t * msgHash, uint8_t msgHashLen,
        const uint8_t * signingKey, uint16_t signingKeyLen)
{
    WEAVE_ERROR err;
    uint32_t privKeyCurveId;
    EncodedECPublicKey pubKey;
    EncodedECPrivateKey privKey;
    EncodedECDSASignature ecdsaSig;
    uint8_t ecdsaRBuf[EncodedECDSASignature::kMaxValueLength];
    uint8_t ecdsaSBuf[EncodedECDSASignature::kMaxValueLength];

    // Decode the supplied private key.
    err = DecodeWeaveECPrivateKey(signingKey, signingKeyLen, privKeyCurveId, pubKey, privKey);
    SuccessOrExit(err);

    // Use temporary buffers to hold the generated signature value until we write it.
    ecdsaSig.R = ecdsaRBuf;
    ecdsaSig.RLen = sizeof(ecdsaRBuf);
    ecdsaSig.S = ecdsaSBuf;
    ecdsaSig.SLen = sizeof(ecdsaSBuf);

    // Generate the signature for the message based on its hash.
    err = GenerateECDSASignature(WeaveCurveIdToOID(privKeyCurveId), msgHash, msgHashLen, privKey, ecdsaSig);
    SuccessOrExit(err);

    // Encode an ECDSASignature structure into the supplied writer.
    err = EncodeWeaveECDSASignature(writer, ecdsaSig, tag);
    SuccessOrExit(err);

exit:
    return err;
}

// Encode a Weave ECDSASignature structure.
WEAVE_ERROR EncodeWeaveECDSASignature(TLVWriter& writer, EncodedECDSASignature& sig, uint64_t tag)
{
    WEAVE_ERROR err;
    TLVType containerType;

    // Start the ECDSASignature structure
    err = writer.StartContainer(tag, kTLVType_Structure, containerType);
    SuccessOrExit(err);

    // Write the R value
    err = writer.PutBytes(ContextTag(kTag_ECDSASignature_r), sig.R, sig.RLen);
    SuccessOrExit(err);

    // Write the S value
    err = writer.PutBytes(ContextTag(kTag_ECDSASignature_s), sig.S, sig.SLen);
    SuccessOrExit(err);

    err = writer.EndContainer(containerType);
    SuccessOrExit(err);

exit:
    return err;
}

// Takes an ECDSA signature in DER form and converts it to Weave form.
// ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER }
WEAVE_ERROR ConvertECDSASignature_DERToWeave(const uint8_t * sigBuf, uint8_t sigLen, EncodedECDSASignature& sig)
{
    WEAVE_ERROR err;
    ASN1Reader reader;

    reader.Init(sigBuf, sigLen);

    // ECDSA-Sig-Value ::= SEQUENCE
    ASN1_PARSE_ENTER_SEQUENCE {
        // r INTEGER
        ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Integer);
        sig.R = const_cast<uint8_t *>(reader.Value);
        sig.RLen = reader.ValueLen;
        // s INTEGER
        ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Integer);
        sig.S = const_cast<uint8_t *>(reader.Value);
        sig.SLen = reader.ValueLen;
    } ASN1_EXIT_SEQUENCE;

exit:
    return err;
}

// Takes an ECDSA signature in DER form and converts it to Weave form.
// ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER }
WEAVE_ERROR ConvertECDSASignature_DERToWeave(const uint8_t * sigBuf, uint8_t sigLen, TLVWriter& writer, uint64_t tag)
{
    WEAVE_ERROR err;
    EncodedECDSASignature sig;

    err = ConvertECDSASignature_DERToWeave(sigBuf, sigLen, sig);
    SuccessOrExit(err);

    err = EncodeWeaveECDSASignature(writer, sig, tag);
    SuccessOrExit(err);

exit:
    return err;
}

// Decode a Weave ECDSASignature structure.
WEAVE_ERROR DecodeWeaveECDSASignature(TLVReader& reader, EncodedECDSASignature& sig)
{
    WEAVE_ERROR err;
    TLVType containerType;

    VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_WRONG_TLV_TYPE);

    err = reader.EnterContainer(containerType);
    SuccessOrExit(err);

    // r INTEGER
    err = reader.Next(kTLVType_ByteString, ContextTag(kTag_ECDSASignature_r));
    SuccessOrExit(err);
    err = reader.GetDataPtr((const uint8_t *&)sig.R);
    SuccessOrExit(err);
    sig.RLen = reader.GetLength();

    // s INTEGER
    err = reader.Next(kTLVType_ByteString, ContextTag(kTag_ECDSASignature_s));
    SuccessOrExit(err);
    err = reader.GetDataPtr((const uint8_t *&)sig.S);
    SuccessOrExit(err);
    sig.SLen = reader.GetLength();

    err = reader.ExitContainer(containerType);
    SuccessOrExit(err);

exit:
    return err;
}

WEAVE_ERROR InsertRelatedCertificatesIntoWeaveSignature(
    uint8_t *sigBuf, uint16_t sigLen, uint16_t sigBufLen,
    const uint8_t *relatedCerts, uint16_t relatedCertsLen,
    uint16_t& outSigLen)
{
    WEAVE_ERROR err;
    TLVUpdater sigUpdater;
    TLVReader certsReader;
    TLVType sigContainerType, relatedCertsContainerType;

    // Initialize a TLVUpdater to rewrite the given signature.
    err = sigUpdater.Init(sigBuf, sigLen, sigBufLen);
    SuccessOrExit(err);

    // Parse the beginning of the existing WeaveSignature structure.
    err = sigUpdater.Next();
    SuccessOrExit(err);
    VerifyOrExit(sigUpdater.GetType() == kTLVType_Structure, err = WEAVE_ERROR_WRONG_TLV_TYPE);
    VerifyOrExit(sigUpdater.GetTag() == ProfileTag(kWeaveProfile_Security, kTag_WeaveSignature), err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

    // Enter the WeaveSignature structure.
    err = sigUpdater.EnterContainer(sigContainerType);
    SuccessOrExit(err);

    // Loop through all fields within the current WeaveSignature, moving them to the output signature.
    // HOWEVER, if an existing RelatedCertificates field is encountered, fail with an error.
    while ((err = sigUpdater.Next()) == WEAVE_NO_ERROR)
    {
        VerifyOrExit(sigUpdater.GetTag() != ContextTag(kTag_WeaveSignature_RelatedCertificates), err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);
        err = sigUpdater.Move();
        SuccessOrExit(err);
    }

    // Verify we successfully found the end of the WeaveSignature structure.
    VerifyOrExit(err == WEAVE_END_OF_TLV, /* no-op */);

    // Start writing a RelatedCertificates array.
    err = sigUpdater.StartContainer(ContextTag(kTag_WeaveSignature_RelatedCertificates), kTLVType_Array, relatedCertsContainerType);
    SuccessOrExit(err);

    // Initialize a reader to read the given related certs TLV.
    certsReader.Init(relatedCerts, relatedCertsLen);
    certsReader.ImplicitProfileId = kWeaveProfile_Security;

    // Move to the first element of the related certs TLV.
    err = certsReader.Next();
    SuccessOrExit(err);

    // If the related certs TLV is an array, enter the array and advance to the first element.
    if (certsReader.GetType() == kTLVType_Array)
    {
        TLVType outerContainerType;
        err = certsReader.EnterContainer(outerContainerType);
        SuccessOrExit(err);
        err = certsReader.Next();
    }

    // Loop for each element in the related certs TLV...
    while (err == WEAVE_NO_ERROR)
    {
        // Verify that the current element from the related certs TLV is a structure (presumed to contain a certificate).
        VerifyOrExit(certsReader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

        // Write a copy of the certificate element into the RelatedCertificates array.
        err = sigUpdater.CopyElement(AnonymousTag, certsReader);
        SuccessOrExit(err);

        // Advance to the next element.
        err = certsReader.Next();
    }

    // Verify we successfully processed the entire contents of the related certs TLV.
    VerifyOrExit(err == WEAVE_END_OF_TLV, /* no-op */);

    // Write the end of the RelatedCertificates array.
    err = sigUpdater.EndContainer(relatedCertsContainerType);

    // Move the remainder of the input WeaveSignature structure to the output.
    sigUpdater.MoveUntilEnd();

    // Finalize writing the output signature.
    err = sigUpdater.Finalize();
    SuccessOrExit(err);

    // Return the length of the updated signature to the caller.
    outSigLen = (uint16_t)sigUpdater.GetLengthWritten();

exit:
    return err;
}

} // namespace Security
} // namespace Profiles
} // namespace Weave
} // namespace nl
