# -*- coding: utf-8 -*-

# without this, pylint will fail when inner classes are used
# within the 'nested' kwarg of our TlvMeta metaclass on python 3.7 :(
# pylint: disable=undefined-variable

"""
Support for the Secure Element Access Control, specifically the ARA-M inside an UICC.
"""

#
# Copyright (C) 2021 Harald Welte <laforge@osmocom.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


from construct import *
from construct import Optional as COptional
from pySim.construct import *
from pySim.filesystem import *
from pySim.tlv import *

# various BER-TLV encoded Data Objects (DOs)


class AidRefDO(BER_TLV_IE, tag=0x4f):
    # SEID v1.1 Table 6-3
    _construct = HexAdapter(GreedyBytes)


class AidRefEmptyDO(BER_TLV_IE, tag=0xc0):
    # SEID v1.1 Table 6-3
    pass


class DevAppIdRefDO(BER_TLV_IE, tag=0xc1):
    # SEID v1.1 Table 6-4
    _construct = HexAdapter(GreedyBytes)


class PkgRefDO(BER_TLV_IE, tag=0xca):
    # Android UICC Carrier Privileges specific extension, see https://source.android.com/devices/tech/config/uicc
    _construct = Struct('package_name_string'/GreedyString("ascii"))


class RefDO(BER_TLV_IE, tag=0xe1, nested=[AidRefDO, AidRefEmptyDO, DevAppIdRefDO, PkgRefDO]):
    # SEID v1.1 Table 6-5
    pass


class ApduArDO(BER_TLV_IE, tag=0xd0):
    # SEID v1.1 Table 6-8
    def _from_bytes(self, do: bytes):
        if len(do) == 1:
            if do[0] == 0x00:
                self.decoded = {'generic_access_rule': 'never'}
                return self.decoded
            elif do[0] == 0x01:
                self.decoded = {'generic_access_rule': 'always'}
                return self.decoded
            else:
                return ValueError('Invalid 1-byte generic APDU access rule')
        else:
            if len(do) % 8:
                return ValueError('Invalid non-modulo-8 length of APDU filter: %d' % len(do))
            self.decoded['apdu_filter'] = []
            offset = 0
            while offset < len(do):
                self.decoded['apdu_filter'] += {'header': b2h(do[offset:offset+4]),
                                                'mask': b2h(do[offset+4:offset+8])}
            self.decoded = res
            return res

    def _to_bytes(self):
        if 'generic_access_rule' in self.decoded:
            if self.decoded['generic_access_rule'] == 'never':
                return b'\x00'
            elif self.decoded['generic_access_rule'] == 'always':
                return b'\x01'
            else:
                return ValueError('Invalid 1-byte generic APDU access rule')
        else:
            if not 'apdu_filter' in self.decoded:
                return ValueError('Invalid APDU AR DO')
            filters = self.decoded['apdu_filter']
            res = b''
            for f in filters:
                if not 'header' in f or not 'mask' in f:
                    return ValueError('APDU filter must contain header and mask')
                header_b = h2b(f['header'])
                mask_b = h2b(f['mask'])
                if len(header_b) != 4 or len(mask_b) != 4:
                    return ValueError('APDU filter header and mask must each be 4 bytes')
                res += header_b + mask_b
            return res


class NfcArDO(BER_TLV_IE, tag=0xd1):
    # SEID v1.1 Table 6-9
    _construct = Struct('nfc_event_access_rule' /
                        Enum(Int8ub, never=0, always=1))


class PermArDO(BER_TLV_IE, tag=0xdb):
    # Android UICC Carrier Privileges specific extension, see https://source.android.com/devices/tech/config/uicc
    _construct = Struct('permissions'/HexAdapter(Bytes(8)))


class ArDO(BER_TLV_IE, tag=0xe3, nested=[ApduArDO, NfcArDO, PermArDO]):
    # SEID v1.1 Table 6-7
    pass


class RefArDO(BER_TLV_IE, tag=0xe2, nested=[RefDO, ArDO]):
    # SEID v1.1 Table 6-6
    pass


class ResponseAllRefArDO(BER_TLV_IE, tag=0xff40, nested=[RefArDO]):
    # SEID v1.1 Table 4-2
    pass


class ResponseArDO(BER_TLV_IE, tag=0xff50, nested=[ArDO]):
    # SEID v1.1 Table 4-3
    pass


class ResponseRefreshTagDO(BER_TLV_IE, tag=0xdf20):
    # SEID v1.1 Table 4-4
    _construct = Struct('refresh_tag'/HexAdapter(Bytes(8)))


class DeviceInterfaceVersionDO(BER_TLV_IE, tag=0xe6):
    # SEID v1.1 Table 6-12
    _construct = Struct('major'/Int8ub, 'minor'/Int8ub, 'patch'/Int8ub)


class DeviceConfigDO(BER_TLV_IE, tag=0xe4, nested=[DeviceInterfaceVersionDO]):
    # SEID v1.1 Table 6-10
    pass


class ResponseDeviceConfigDO(BER_TLV_IE, tag=0xff7f, nested=[DeviceConfigDO]):
    # SEID v1.1 Table 5-14
    pass


class AramConfigDO(BER_TLV_IE, tag=0xe5, nested=[DeviceInterfaceVersionDO]):
    # SEID v1.1 Table 6-11
    pass


class ResponseAramConfigDO(BER_TLV_IE, tag=0xdf21, nested=[AramConfigDO]):
    # SEID v1.1 Table 4-5
    pass


class CommandStoreRefArDO(BER_TLV_IE, tag=0xf0, nested=[RefArDO]):
    # SEID v1.1 Table 5-2
    pass


class CommandDelete(BER_TLV_IE, tag=0xf1, nested=[AidRefDO, AidRefEmptyDO, RefDO, RefArDO]):
    # SEID v1.1 Table 5-4
    pass


class CommandUpdateRefreshTagDO(BER_TLV_IE, tag=0xf2):
    # SEID V1.1 Table 5-6
    pass


class CommandRegisterClientAidsDO(BER_TLV_IE, tag=0xf7, nested=[AidRefDO, AidRefEmptyDO]):
    # SEID v1.1 Table 5-7
    pass


class CommandGet(BER_TLV_IE, tag=0xf3, nested=[AidRefDO, AidRefEmptyDO]):
    # SEID v1.1 Table 5-8
    pass


class CommandGetAll(BER_TLV_IE, tag=0xf4):
    # SEID v1.1 Table 5-9
    pass


class CommandGetClientAidsDO(BER_TLV_IE, tag=0xf6):
    # SEID v1.1 Table 5-10
    pass


class CommandGetNext(BER_TLV_IE, tag=0xf5):
    # SEID v1.1 Table 5-11
    pass


class CommandGetDeviceConfigDO(BER_TLV_IE, tag=0xf8):
    # SEID v1.1 Table 5-12
    pass


class ResponseAracAidDO(BER_TLV_IE, tag=0xff70, nested=[AidRefDO, AidRefEmptyDO]):
    # SEID v1.1 Table 5-13
    pass


class BlockDO(BER_TLV_IE, tag=0xe7):
    # SEID v1.1 Table 6-13
    _construct = Struct('offset'/Int16ub, 'length'/Int8ub)


# SEID v1.1 Table 4-1
class GetCommandDoCollection(TLV_IE_Collection, nested=[RefDO, DeviceConfigDO]):
    pass

# SEID v1.1 Table 4-2


class GetResponseDoCollection(TLV_IE_Collection, nested=[ResponseAllRefArDO, ResponseArDO,
                                                         ResponseRefreshTagDO, ResponseAramConfigDO]):
    pass

# SEID v1.1 Table 5-1


class StoreCommandDoCollection(TLV_IE_Collection,
                               nested=[BlockDO, CommandStoreRefArDO, CommandDelete,
                                       CommandUpdateRefreshTagDO, CommandRegisterClientAidsDO,
                                       CommandGet, CommandGetAll, CommandGetClientAidsDO,
                                       CommandGetNext, CommandGetDeviceConfigDO]):
    pass


# SEID v1.1 Section 5.1.2
class StoreResponseDoCollection(TLV_IE_Collection,
                                nested=[ResponseAllRefArDO, ResponseAracAidDO, ResponseDeviceConfigDO]):
    pass


class ADF_ARAM(CardADF):
    def __init__(self, aid='a00000015141434c00', name='ADF.ARA-M', fid=None, sfid=None,
                 desc='ARA-M Application'):
        super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc)
        self.shell_commands += [self.AddlShellCommands()]
        files = []
        self.add_files(files)

    @staticmethod
    def xceive_apdu_tlv(tp, hdr: Hexstr, cmd_do, resp_cls, exp_sw='9000'):
        """Transceive an APDU with the card, transparently encoding the command data from TLV
        and decoding the response data tlv."""
        if cmd_do:
            cmd_do_enc = cmd_do.to_ie()
            cmd_do_len = len(cmd_do_enc)
            if cmd_do_len > 255:
                return ValueError('DO > 255 bytes not supported yet')
        else:
            cmd_do_enc = b''
            cmd_do_len = 0
        c_apdu = hdr + ('%02x' % cmd_do_len) + b2h(cmd_do_enc)
        (data, sw) = tp.send_apdu_checksw(c_apdu, exp_sw)
        if data:
            if resp_cls:
                resp_do = resp_cls()
                resp_do.from_tlv(h2b(data))
                return resp_do
            else:
                return data
        else:
            return None

    @staticmethod
    def store_data(tp, do) -> bytes:
        """Build the Command APDU for STORE DATA."""
        return ADF_ARAM.xceive_apdu_tlv(tp, '80e29000', do, StoreResponseDoCollection)

    @staticmethod
    def get_all(tp):
        return ADF_ARAM.xceive_apdu_tlv(tp, '80caff40', None, GetResponseDoCollection)

    @staticmethod
    def get_config(tp, v_major=0, v_minor=0, v_patch=1):
        cmd_do = DeviceConfigDO()
        cmd_do.from_dict([{'DeviceInterfaceVersionDO': {
                         'major': v_major, 'minor': v_minor, 'patch': v_patch}}])
        return ADF_ARAM.xceive_apdu_tlv(tp, '80cadf21', cmd_do, ResponseAramConfigDO)

    @with_default_category('Application-Specific Commands')
    class AddlShellCommands(CommandSet):
        def __init(self):
            super().__init__()

        def do_aram_get_all(self, opts):
            """GET DATA [All] on the ARA-M Applet"""
            res_do = ADF_ARAM.get_all(self._cmd.lchan.scc._tp)
            if res_do:
                self._cmd.poutput_json(res_do.to_dict())

        def do_aram_get_config(self, opts):
            """Perform GET DATA [Config] on the ARA-M Applet: Tell it our version and retrieve its version."""
            res_do = ADF_ARAM.get_config(self._cmd.lchan.scc._tp)
            if res_do:
                self._cmd.poutput_json(res_do.to_dict())

        store_ref_ar_do_parse = argparse.ArgumentParser()
        # REF-DO
        store_ref_ar_do_parse.add_argument(
            '--device-app-id', required=True, help='Identifies the specific device application that the rule appplies to. Hash of Certificate of Application Provider, or UUID. (20/32 hex bytes)')
        aid_grp = store_ref_ar_do_parse.add_mutually_exclusive_group()
        aid_grp.add_argument(
            '--aid', help='Identifies the specific SE application for which rules are to be stored. Can be a partial AID, containing for example only the RID.  (5-16 hex bytes)')
        aid_grp.add_argument('--aid-empty', action='store_true',
                             help='No specific SE application, applies to all applications')
        store_ref_ar_do_parse.add_argument(
            '--pkg-ref', help='Full Android Java package name (up to 127 chars ASCII)')
        # AR-DO
        apdu_grp = store_ref_ar_do_parse.add_mutually_exclusive_group()
        apdu_grp.add_argument(
            '--apdu-never', action='store_true', help='APDU access is not allowed')
        apdu_grp.add_argument(
            '--apdu-always', action='store_true', help='APDU access is allowed')
        apdu_grp.add_argument(
            '--apdu-filter', help='APDU filter: 4 byte CLA/INS/P1/P2 followed by 4 byte mask (8 hex bytes)')
        nfc_grp = store_ref_ar_do_parse.add_mutually_exclusive_group()
        nfc_grp.add_argument('--nfc-always', action='store_true',
                             help='NFC event access is allowed')
        nfc_grp.add_argument('--nfc-never', action='store_true',
                             help='NFC event access is not allowed')
        store_ref_ar_do_parse.add_argument(
            '--android-permissions', help='Android UICC Carrier Privilege Permissions (8 hex bytes)')

        @cmd2.with_argparser(store_ref_ar_do_parse)
        def do_aram_store_ref_ar_do(self, opts):
            """Perform STORE DATA [Command-Store-REF-AR-DO] to store a (new) access rule."""
            # REF
            ref_do_content = []
            if opts.aid:
                ref_do_content += [{'aid_ref_do': opts.aid}]
            elif opts.aid_empty:
                ref_do_content += [{'aid_ref_empty_do': None}]
            ref_do_content += [{'dev_app_id_ref_do': opts.device_app_id}]
            if opts.pkg_ref:
                ref_do_content += [{'pkg_ref_do': {'package_name_string': opts.pkg_ref}}]
            # AR
            ar_do_content = []
            if opts.apdu_never:
                ar_do_content += [{'apdu_ar_od': {'generic_access_rule': 'never'}}]
            elif opts.apdu_always:
                ar_do_content += [{'apdu_ar_do': {'generic_access_rule': 'always'}}]
            elif opts.apdu_filter:
                # TODO: multiple filters
                ar_do_content += [{'apdu_ar_do': {'apdu_filter': [opts.apdu_filter]}}]
            if opts.nfc_always:
                ar_do_content += [{'nfc_ar_do': {'nfc_event_access_rule': 'always'}}]
            elif opts.nfc_never:
                ar_do_content += [{'nfc_ar_do': {'nfc_event_access_rule': 'never'}}]
            if opts.android_permissions:
                ar_do_content += [{'perm_ar_do': {'permissions': opts.android_permissions}}]
            d = [{'ref_ar_do': [{'ref_do': ref_do_content}, {'ar_do': ar_do_content}]}]
            csrado = CommandStoreRefArDO()
            csrado.from_dict(d)
            res_do = ADF_ARAM.store_data(self._cmd.lchan.scc._tp, csrado)
            if res_do:
                self._cmd.poutput_json(res_do.to_dict())

        def do_aram_delete_all(self, opts):
            """Perform STORE DATA [Command-Delete[all]] to delete all access rules."""
            deldo = CommandDelete()
            res_do = ADF_ARAM.store_data(self._cmd.lchan.scc._tp, deldo)
            if res_do:
                self._cmd.poutput_json(res_do.to_dict())


# SEAC v1.1 Section 4.1.2.2 + 5.1.2.2
sw_aram = {
    'ARA-M': {
        '6381': 'Rule successfully stored but an access rule already exists',
        '6382': 'Rule successfully stored bu contained at least one unknown (discarded) BER-TLV',
        '6581': 'Memory Problem',
        '6700': 'Wrong Length in Lc',
        '6981': 'DO is not supported by the ARA-M/ARA-C',
        '6982': 'Security status not satisfied',
        '6984': 'Rules have been updated and must be read again / logical channels in use',
        '6985': 'Conditions not satisfied',
        '6a80': 'Incorrect values in the command data',
        '6a84': 'Rules have been updated and must be read again',
        '6a86': 'Incorrect P1 P2',
        '6a88': 'Referenced data not found',
        '6a89': 'Conflicting access rule already exists in the Secure Element',
        '6d00': 'Invalid instruction',
        '6e00': 'Invalid class',
    }
}


class CardApplicationARAM(CardApplication):
    def __init__(self):
        super().__init__('ARA-M', adf=ADF_ARAM(), sw=sw_aram)
