#
# Copyright 2018-2020 NXP
# SPDX-License-Identifier: Apache-2.0
#
#

"""

Provision attached secure element with ECC/RSA keys

Preconditions:
    - Secure element attached
    - Virtual environment should be activated (not for iMX platform.
      Refer ssscli installation steps: Plug & Trust MW, Section 8.3 :ref:`cli-doc-pre-steps`)

Postconditions:
    - Key pair injected on id referred by KEYPAIR_INDEX_CLIENT_PRIVATE variable
    - Ref pem created
    - Client certificate injected on id referred by CERTIFICATE_INDEX variable.

"""

import os
import sys
import logging
import traceback
import argparse
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
log = logging.getLogger(__name__)

# GLOBAL VARIABLES
# ----------------
SE050_PROVISIONING_SCRIPT = "0.9"
EC_KEYPAIR_INDEX_CLIENT_PRIVATE = 0x7DCCBB10
EC_CERTIFICATE_INDEX = 0x7DCCBB11
RSA_KEYPAIR_INDEX_CLIENT_PRIVATE = 0x7DCCBB30
RSA_CERTIFICATE_INDEX = 0x7DCCBB31

example_text = '''
Example invocation::

    python %s --key_type ecc
    python %s --key_type ecc --connection_data 169.254.0.1:8050
    python %s --key_type rsa --connection_data 127.0.0.1:8050 --connection_type jrcpv2
    python %s --key_type rsa --connection_data COM3
    python %s --key_type ecc --subsystem a71ch

''' % (__file__, __file__, __file__, __file__, __file__,)

SUPPORTED_CONNECTION_TYPES = [
    "t1oi2c",
    "sci2c",
    "vcom",
    "jrcpv1",
    "jrcpv2",
    "pcsc"
]


def session_open(subsystem, connection_data, connection_type, auth_type, scpkey):
    ''' Open session based on IOT Secure Element selected. '''
    import sss.const as const
    import sss.connect as connect
    import sss.session as session

    log.info("###############################################################")
    log.info("#")
    log.info("#     SUBSYSTEM            : %s" % subsystem)
    log.info("#     CONNECTION_TYPE      : %s" % connection_type)
    log.info("#     CONNECTION_PARAMETER : %s" % connection_data)
    log.info("#")
    log.info("###############################################################")

    connect.do_open_session(const.SUBSYSTEM_TYPE[subsystem],
                            const.CONNECTION_TYPE[connection_type], connection_data,
                            auth_type=const.AUTH_TYPE_MAP[auth_type][0],
                            scpkey=scpkey)
    session_obj = session.Session()
    try:
        session_obj.session_open()
    except Exception as exc:
        error_log_file = os.path.abspath(os.path.dirname(__file__)) + os.sep + "error_log.txt"
        if not os.path.isfile(error_log_file):
            err_write = open(error_log_file, 'w+')
        else:
            err_write = open(error_log_file, 'a+')
        traceback.print_exc(None, err_write)
        err_write.close()
        return None
    return session_obj


def session_close(session):
    ''' Close opened session. '''
    import sss.connect as connect
    import sss.util as util

    if session:
        session.session_close()

    if os.path.isfile(util.get_session_pkl_path()):
        connect.do_close_session()


def reset(session):
    ''' Reset the Secure Module to the initial state. '''
    from sss.se05x import Se05x
    from sss.a71ch import A71CH
    import sss.sss_api as apis
    if session.subsystem == apis.kType_SSS_SE_SE05x:
        se05x_obj = Se05x(session)
        se05x_obj.debug_reset()
    elif session.subsystem == apis.kType_SSS_SE_A71CH:
        a71ch_obj = A71CH(session)
        a71ch_obj.debug_reset()


def refpem_ecc(session, keyid, file_name):
    ''' Creates reference PEM file for ECC Pair.
        keyid = 32bit Key ID. Should be in hex format. Example: 20E8A001 \n
        filename = File name to store reference key. Can be in PEM or DER or PKCS12 format based on file extension.
        By default filename with extension .pem in PEM format, .pfx or .p12 in PKCS12  format and others in DER format.
    '''
    from sss.refkey import RefPem
    import sss.sss_api as apis
    refpem_obj = RefPem(session)
    status = refpem_obj.do_ecc_refpem_pair(keyid, file_name)
    if status != apis.kStatus_SSS_Success:
        log.error("Refpem creation failed..!")
        session_close(session)
        return status
    log.info("Successfully Created reference key.")
    return status


def refpem_rsa(session, keyid, file_name):
    ''' Creates reference PEM file for RSA Pair.
        keyid = 32bit Key ID. Should be in hex format. Example: 20E8A001 \n
        filename = File name to store reference key. Can be in PEM or DER or PKCS12 format based on file extension.
        By default filename with extension .pem in PEM format, .pfx or .p12 in PKCS12  format and others in DER format.
    '''
    from sss.refkey import RefPem
    import sss.sss_api as apis
    refpem_obj = RefPem(session)
    status = refpem_obj.do_rsa_refpem_pair(keyid, file_name)
    if status != apis.kStatus_SSS_Success:
        log.error("Refpem creation failed..!")
        session_close(session)
        return status
    log.info("Successfully Created reference key.")
    return status


def set_ecc_pair(session, keyid, client_key):
    ''' Set ECC Key pair to the Secure Module \n
        keyid = 32bit Key ID. Should be in hex format. Example: 20E8A001 \n
        key = Can be raw key (DER format) or in file.
        For file, by default filename with extension .pem considered as PEM format and others as DER format.\n
        '''
    import sss.setkey as setkey
    import sss.sss_api as apis
    log.info("client_key file: %s" % (client_key,))
    log.info("Injecting ECC key pair at key ID: 0x%x" % (keyid,))
    set_obj = setkey.Set(session)
    status = set_obj.do_set_ecc_key_pair(keyid, client_key, None)
    if status != apis.kStatus_SSS_Success:
        log.error("Injecting key pair failed..!")
        session_close(session)
        return status
    log.info("Successfully Injected ECC key pair.")
    return status


def set_rsa_pair(session, keyid, client_key):
    ''' Set RSA Key pair to the Secure Module \n
        keyid = 32bit Key ID. Should be in hex format. Example: 20E8A001 \n
        key = Can be raw key (DER format) or in file.
        For file, by default filename with extension .pem considered as PEM format and others as DER format.\n
        '''
    import sss.setkey as setkey
    import sss.sss_api as apis
    log.info("client_key file: %s" % (client_key,))
    log.info("Injecting RSA key pair at key ID: 0x%x" % (keyid,))
    set_obj = setkey.Set(session)
    status = set_obj.do_set_rsa_key_pair(keyid, client_key, None)
    if status != apis.kStatus_SSS_Success:
        log.error("Injecting key pair failed..!")
        session_close(session)
        return status
    log.info("Successfully Injected RSA key pair.")
    return status


def set_cert(session, keyid, cert):
    ''' Inject Certificate to the Secure Module
        keyid = 32bit Key ID. Should be in hex format. Example: 20E8A001 \n
        key = Can be raw certificate (DER format) or in file.
        For file, by default filename with extension .pem and .cer considered as PEM format and others as DER format.\n
    '''
    import sss.setkey as setkey
    import sss.sss_api as apis
    log.info("certificate file: %s" % (cert,))
    log.info("Injecting Certificate at key ID: 0x%x" % (keyid,))
    set_obj = setkey.Set(session)
    status = set_obj.do_set_cert(keyid, cert, None)
    if status != apis.kStatus_SSS_Success:
        log.error("Injecting certificate failed..!")
        session_close(session)
        return status
    log.info("Successfully Injected Certificate.")
    return status


def parse_in_args():

    parser = argparse.ArgumentParser(description=__doc__,
                                     epilog=example_text,
                                     formatter_class=argparse.RawTextHelpFormatter)
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--key_type', default="",
                          help='Supported key types => ``ecc``, ``rsa``',
                          required=True)
    optional.add_argument('--connection_data', default="none",
                          help='Parameter to connect to SE => eg. ``COM3``, ``127.0.0.1:8050``, ``none``. '
                               'Default: ``none``')
    optional.add_argument('--connection_type', default="t1oi2c",
                          help='Supported connection types => ``%s``. Default: ``t1oi2c``' %
                               ("``, ``".join(SUPPORTED_CONNECTION_TYPES)))
    optional.add_argument('--subsystem', default="se05x",
                          help='Supported subsystem => ``se05x``, ``a71ch``. Default: ``se05x``')
    optional.add_argument('--auth_type', default="None",
                          help='Supported subsystem => ``None``, ``PlatformSCP``, ``UserID``, ``ECKey``, ``AESKey``. Default: ``None``')
    optional.add_argument('--scpkey', default="None",
                          help='')
    optional.add_argument('--no_reset', action="store_true", help="do not reset contents of attached secure element")

    if len(sys.argv) == 1:
        parser.print_help(sys.stderr)
        return None

    args = parser.parse_args()

    if args.key_type not in ["ecc", "rsa", ]:
        parser.print_help(sys.stderr)
        return None

    if args.subsystem not in ["se05x", "a71ch", ]:
        parser.print_help(sys.stderr)
        return None

    if args.connection_data.find(':') >= 0:
        port_data = args.connection_data.split(':')
        jrcp_host_name = port_data[0]
        jrcp_port = port_data[1]
        os.environ['JRCP_HOSTNAME'] = jrcp_host_name
        os.environ['JRCP_PORT'] = jrcp_port
        log.info("JRCP_HOSTNAME: %s" % jrcp_host_name)
        log.info("JRCP_PORT: %s" % jrcp_port)
        if args.connection_type == "t1oi2c":
            args.connection_type = "jrcpv1"
    elif args.connection_data.find('COM') >= 0:
        if args.connection_type == "t1oi2c":
            args.connection_type = "vcom"
    elif args.connection_data.find('none') >= 0:
        if args.subsystem == "a71ch":
            args.connection_type = "sci2c"
    else:
        parser.print_help(sys.stderr)
        return None

    if args.connection_type not in SUPPORTED_CONNECTION_TYPES:
        parser.print_help(sys.stderr)
        return None

    return args


def main():
    cur_dir = os.path.abspath(os.path.dirname(__file__))
    py_sss_dir = os.path.join(cur_dir, '..', '..', '..', '..', 'pycli', 'src')
    sys.path.append(py_sss_dir)
    import sss.sss_api as apis

    # check for input arguments
    args = parse_in_args()
    if args is None:
        return

    # --------------------------------------------------------------
    # Start of program - Ensure an SE is connected to your system.
    # --------------------------------------------------------------
    log.info("SE050 Key provisioning script (Rev.%s)." % SE050_PROVISIONING_SCRIPT)
    log.info("Executing this script will insert keys in the attached SE050 secure element.")

    if args.key_type == "ecc":
        key_type = "prime256v1"
    else:
        key_type = "RSA"
    keys_dir = os.path.join(cur_dir, '..', 'credentials', key_type) + os.sep

    # ECC keys to be stored in SE
    # ------------------------------
    client_key = keys_dir + "tls_client_key.pem"
    client_key_ref = keys_dir + "tls_client_key_ref.pem"
    client_key_pub = keys_dir + "tls_client_key_pub.pem"  # Contains public key only

    # Client certificate
    client_cer = keys_dir + "tls_client.cer"

    # close old session
    session_close(None)

    # Open a new session
    session = session_open(args.subsystem, args.connection_data, args.connection_type, args.auth_type, args.scpkey)
    if session is None:
        return

    # NOTE: In case of A71CH always issue reset
    # When SE050 is lacking storage / has conflicting storage issue a reset of the Secure Element
    if not args.no_reset:
        reset(session)

    if key_type == "prime256v1":
        # Inject ecc pair key to the Secure Element
        status = set_ecc_pair(session, EC_KEYPAIR_INDEX_CLIENT_PRIVATE, client_key)
        if status != apis.kStatus_SSS_Success:
            return

        # Generate Reference key from the key injected. Store it in file referred by "client_key_ref" variable.
        status = refpem_ecc(session, EC_KEYPAIR_INDEX_CLIENT_PRIVATE, client_key_ref)
        if status != apis.kStatus_SSS_Success:
            return

        key_id_cert = EC_CERTIFICATE_INDEX

    else:
        # Inject rsa key pair into the Secure Element
        status = set_rsa_pair(session, RSA_KEYPAIR_INDEX_CLIENT_PRIVATE, client_key)
        if status != apis.kStatus_SSS_Success:
            return

        # Generate Reference key from the key injected. Store it in file referred by "client_key_ref" variable.
        status = refpem_rsa(session, RSA_KEYPAIR_INDEX_CLIENT_PRIVATE, client_key_ref)
        if status != apis.kStatus_SSS_Success:
            return

        key_id_cert = RSA_CERTIFICATE_INDEX

    # Inject certificate to the Secure Element
    status = set_cert(session, key_id_cert, client_cer)
    if status != apis.kStatus_SSS_Success:
        return

    session_close(session)
    log.info("##############################################################")
    log.info("#                                                            #")
    log.info("#     Program Completed Successfully                         #")
    log.info("#                                                            #")
    log.info("##############################################################")


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    main()


