/**
 * \file asn1ec.c
 * \brief Parser of EC key ASN.1 representation.
 * \author Dmytro Podgornyi (d.podgornyi@samsung.com)
 * \version 0.1
 * \date Created May 28, 2013
 * \par In Samsung Ukraine R&D Center (SURC) under a contract between
 * \par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
 * \par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
 * \par Copyright: (c) Samsung Electronics Co, Ltd 2012. All rights reserved.
 **/

#include <stdint.h>
#include <string.h>

#include "CommLayerData.h"
#include "asn1ec.h"
#include "cryptoEngine.h"
#include "log.h"

int32_t ec_public_key_parse(const uint8_t *buf, size_t len, 
                                   uint8_t **pubkeyX, uint32_t *pubkeyXlen, 
                                   uint8_t **pubkeyY, uint32_t *pubkeyYlen)
{
    if (len < 1 || buf[0] != EC_POINT_CONVERSION_UNCOMPRESSED) {
        LOGE("ec_public_key_parse: it is not an uncompressed point");
        return WRONG_DATA;
    }

    --len;
    ++buf;
    if (len == 0 || len % 2 != 0) {
        LOGE("ec_public_key_parse: bad size of key: %d is not even", len);
        return WRONG_DATA;
    }

    len /= 2;

    if (!pubkeyX || !pubkeyY || !pubkeyXlen || !pubkeyYlen)
    {
        LOGD("ec_public_key_parse: null arguments");
        return WRONG_DATA;
    }
    *pubkeyX = (uint8_t*)buf;
    *pubkeyY = (uint8_t*)buf + len;
    *pubkeyXlen = *pubkeyYlen = len;
    return NOT_ERROR;
}

int32_t ec_keypair_parse(const uint8_t *buf, size_t len, 
                                uint8_t **prikey, uint32_t *prikeylen,
                                uint8_t **pubkeyX, uint32_t *pubkeyXlen, 
                                uint8_t **pubkeyY, uint32_t *pubkeyYlen)
{
    struct asn1_hdr hdr = {0};
    const uint8_t *buf_end = NULL;
    // TODO: implement later
    UNUSED(pubkeyX);
    UNUSED(pubkeyXlen);
    UNUSED(pubkeyY);
    UNUSED(pubkeyYlen);

    buf_end = buf + len;

    if (asn1_get_next(buf, buf_end - buf, &hdr) ||
        hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SEQUENCE) {
        return WRONG_DATA;
    }

    buf = hdr.payload;
    if (asn1_get_next(buf, buf_end - buf, &hdr) ||
        hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
        return WRONG_DATA;
    }

    buf = hdr.payload + hdr.length;
    if (asn1_get_next(buf, buf_end - buf, &hdr) ||
        hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_OCTETSTRING) {
        return WRONG_DATA;
    }
    if (!prikey || !prikeylen)
    {
        LOGD("ec_keypair_parse: null arguments");
        return WRONG_DATA;
    }
    *prikey = (uint8_t*)hdr.payload;
    *prikeylen = hdr.length;
    return NOT_ERROR;
}
