/*
 *
 *    Copyright (c) 2016-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 defines a Wrapper for C++ implementation of key export functionality
 *      to support pin encryption.
 *
 */
#import "NLWeaveKeyExportClient.h"
#import "NLWeaveKeyExportSupport.h"
#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveKeyIds.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Profiles/security/WeaveKeyExportClient.h>

using namespace nl::Weave::Profiles::Security::KeyExport;

NSString * const NLWeaveKeyExportClientErrorDomain = @"NLWeaveKeyExportClientErrorDomain";

@interface NLWeaveKeyExportClient () {
    WeaveStandAloneKeyExportClient * _mKeyExportClientCpp;
}
@end

@implementation NLWeaveKeyExportClient

static UInt32 const kMaxPubKeySize = (((WEAVE_CONFIG_MAX_EC_BITS + 7) / 8) + 1) * 2;
static UInt32 const kMaxECDSASigSize = kMaxPubKeySize;

- (nullable NSData *)generateKeyExportRequest:(UInt32)keyId
                              responderNodeId:(UInt64)responderNodeId
                                  accessToken:(NSData *)accessToken
                                        error:(NSError **)errOut
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint16_t exportReqLen = 0;

    if (accessToken == nil) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidArgument
                                      userInfo:nil];
        }
        return nil;
    }

    size_t exportReqBufSize = 7 // Key export request header size
        + kMaxPubKeySize // Ephemeral public key size
        + kMaxECDSASigSize // Size of bare signature field
        + [accessToken length] // Size equal to at least the total size of the client certificates
        + 1024; // Space for additional signature fields plus encoding overhead

    if (exportReqBufSize > UINT16_MAX) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidExportBufferSize
                                      userInfo:nil];
        }
        return nil;
    }

    NSMutableData * exportReqBuf = [[NSMutableData alloc] initWithLength:exportReqBufSize];

    err = _mKeyExportClientCpp->GenerateKeyExportRequest((uint32_t) keyId, (uint64_t) responderNodeId,
        (unsigned char *) [accessToken bytes], [accessToken length], (unsigned char *) [exportReqBuf mutableBytes],
        exportReqBufSize, exportReqLen);

    if (err != WEAVE_NO_ERROR) {
        if (errOut) {
            NSString * failureReason =
                [NSString stringWithFormat:NSLocalizedString(@"GenerateKeyExportRequest error: %d", @""), err];
            NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainKeyExportRequestFailure
                                      userInfo:userInfo];
        }

        return nil;
    }

    [exportReqBuf setLength:exportReqLen];

    return exportReqBuf;
}

- (nullable NSData *)generateKeyExportRequest:(UInt32)keyId
                              responderNodeId:(UInt64)responderNodeId
                                   clientCert:(NSData *)clientCert
                                    clientKey:(NSData *)clientKey
                                        error:(NSError **)errOut
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    uint16_t exportReqLen = 0;

    if (clientKey == nil || clientCert) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidArgument
                                      userInfo:nil];
        }
        return nil;
    }

    size_t exportReqBufSize = 7 // Key export request header size
        + kMaxPubKeySize // Ephemeral public key size
        + kMaxECDSASigSize // Size of bare signature field
        + [clientCert length] // Size equal to at least the total size of the client certificates
        + 1024; // Space for additional signature fields plus encoding overhead

    if (exportReqBufSize > UINT16_MAX) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidExportBufferSize
                                      userInfo:nil];
        }
        return nil;
    }

    NSMutableData * exportReqBuf = [[NSMutableData alloc] initWithLength:exportReqBufSize];

    err = _mKeyExportClientCpp->GenerateKeyExportRequest((uint32_t) keyId, (uint64_t) responderNodeId,
        (unsigned char *) [clientCert bytes], [clientCert length], (unsigned char *) [clientKey bytes], [clientKey length],
        (unsigned char *) [exportReqBuf mutableBytes], exportReqBufSize, exportReqLen);

    if (err != WEAVE_NO_ERROR) {
        if (errOut) {
            NSString * failureReason =
                [NSString stringWithFormat:NSLocalizedString(@"GenerateKeyExportRequest error: %d", @""), err];
            NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainKeyExportRequestFailure
                                      userInfo:userInfo];
        }

        return nil;
    }

    [exportReqBuf setLength:exportReqLen];
    return exportReqBuf;
}

- (nullable NSData *)processKeyExportResponse:(UInt64)responderNodeId exportResp:(NSData *)exportResp error:(NSError **)errOut
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (exportResp == nil) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidArgument
                                      userInfo:nil];
        }
        return nil;
    }

    // Since the exported key is contained within the export response, a buffer of the same size
    // is guaranteed to be sufficient.
    size_t exportedKeyBufLen = [exportResp length];
    NSMutableData * exportedKeyBuf = [[NSMutableData alloc] initWithLength:exportedKeyBufLen];

    uint16_t exportedKeyLen;
    uint32_t exportedKeyId;
    err = _mKeyExportClientCpp->ProcessKeyExportResponse((unsigned char *) [exportResp bytes], [exportResp length],
        (uint64_t) responderNodeId, (unsigned char *) [exportedKeyBuf mutableBytes], exportedKeyBufLen, exportedKeyLen,
        exportedKeyId);

    if (err != WEAVE_NO_ERROR) {
        if (errOut) {
            NSString * failureReason =
                [NSString stringWithFormat:NSLocalizedString(@"ProcessKeyExportResponse error:: %d", @""), err];
            NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainKeyExportResponseFailure
                                      userInfo:userInfo];
        }

        return nil;
    }

    [exportedKeyBuf setLength:exportedKeyLen];
    return exportedKeyBuf;
}

- (void)reset
{
    _mKeyExportClientCpp->Reset();
}

/**
 @note
 This function can only be called by the ARC runtime
 */
- (void)dealloc
{
    _mKeyExportClientCpp->Reset();
    delete _mKeyExportClientCpp;
}

- (BOOL)processKeyExportReconfigure:(NSData *)reconfig error:(NSError **)errOut
{

    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (reconfig == nil) {
        if (errOut) {
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainInvalidArgument
                                      userInfo:nil];
        }
        return false;
    }

    err = _mKeyExportClientCpp->ProcessKeyExportReconfigure((unsigned char *) [reconfig bytes], [reconfig length]);

    if (err != WEAVE_NO_ERROR) {
        if (errOut) {
            NSString * failureReason =
                [NSString stringWithFormat:NSLocalizedString(@"ProcessKeyExportResponse error: %d", @""), err];
            NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : failureReason };
            *errOut = [NSError errorWithDomain:NLWeaveKeyExportClientErrorDomain
                                          code:NLWeaveKeyExportClientErrorDomainProcessReconfiugreFailure
                                      userInfo:userInfo];
        }
        return false;
    }

    return true;
}

- (BOOL)allowNestDevelopmentDevices
{

    return _mKeyExportClientCpp->AllowNestDevelopmentDevices();
}

- (void)setAllowNestDevelopmentDevices:(BOOL)nestDev
{
    _mKeyExportClientCpp->AllowNestDevelopmentDevices(nestDev);
}

- (BOOL)allowSHA1DeviceCertificates
{
    return _mKeyExportClientCpp->AllowSHA1DeviceCerts();
}

- (void)setAllowSHA1DeviceCertificates:(BOOL)nestDev
{
    _mKeyExportClientCpp->AllowSHA1DeviceCerts(nestDev);
}

- (instancetype)init
{
    self = [super init];

    if (self) {
        _mKeyExportClientCpp = new WeaveStandAloneKeyExportClient();
        _mKeyExportClientCpp->Init();
    }
    return self;
}

@end
