#!/usr/bin/env python3
#
# sim-rest-client.py: client program to test the sim-rest-server.py
#
# this will generate authentication tuples just like a HLR / HSS
# and will then send the related challenge to the REST interface
# of sim-rest-server.py
#
# sim-rest-server.py will then contact the SIM card to perform the
# authentication (just like a 3GPP RAN), and return the results via
# the REST to sim-rest-client.py.
#
# (C) 2021 by 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 typing import Optional, Dict

import sys
import argparse
import secrets
import requests

from CryptoMobile.Milenage import Milenage
from CryptoMobile.utils import xor_buf

def unpack48(x:bytes) -> int:
    """Decode a big-endian 48bit number from binary to integer."""
    return int.from_bytes(x, byteorder='big')

def pack48(x:int) -> bytes:
    """Encode a big-endian 48bit number from integer to binary."""
    return x.to_bytes(48 // 8, byteorder='big')

def milenage_generate(opc:bytes, amf:bytes, k:bytes, sqn:bytes, rand:bytes) -> Dict[str, bytes]:
    """Generate an MILENAGE Authentication Tuple."""
    m = Milenage(None)
    m.set_opc(opc)
    mac_a = m.f1(k, rand, sqn, amf)
    res, ck, ik, ak = m.f2345(k, rand)

    # AUTN = (SQN ^ AK) || AMF || MAC
    sqn_ak = xor_buf(sqn, ak)
    autn = b''.join([sqn_ak, amf, mac_a])

    return {'res': res, 'ck': ck, 'ik': ik, 'autn': autn}

def milenage_auts(opc:bytes, k:bytes, rand:bytes, auts:bytes) -> Optional[bytes]:
    """Validate AUTS. If successful, returns SQN_MS"""
    amf = b'\x00\x00' # TS 33.102 Section 6.3.3
    m = Milenage(None)
    m.set_opc(opc)
    ak = m.f5star(k, rand)

    sqn_ak = auts[:6]
    sqn = xor_buf(sqn_ak, ak[:6])

    mac_s = m.f1star(k, rand, sqn, amf)
    if mac_s == auts[6:14]:
        return sqn
    else:
        return False


def build_url(suffix:str) -> str:
    """Build an URL from global server_host, server_port, BASE_PATH and suffix."""
    BASE_PATH= "/sim-auth-api/v1"
    return "http://%s:%u%s%s" % (server_host, server_port, BASE_PATH, suffix)


def rest_post(suffix:str, js:Optional[dict] = None):
    """Perform a RESTful POST."""
    url = build_url(suffix)
    if verbose:
        print("POST %s (%s)" % (url, str(js)))
    resp = requests.post(url, json=js)
    if verbose:
        print("-> %s" % (resp))
    if not resp.ok:
        print("POST failed")
    return resp



def main(argv):
    global server_port, server_host, verbose

    parser = argparse.ArgumentParser()
    parser.add_argument("-H", "--host", help="Host to connect to", default="localhost")
    parser.add_argument("-p", "--port", help="TCP port to connect to", default=8000)
    parser.add_argument("-v", "--verbose", help="increase output verbosity", action='count', default=0)
    parser.add_argument("-n", "--slot-nr", help="SIM slot number", type=int, default=0)
    parser.add_argument("-c", "--count", help="Auth count", type=int, default=10)

    parser.add_argument("-k", "--key", help="Secret key K (hex)", type=str, required=True)
    parser.add_argument("-o", "--opc", help="Secret OPc (hex)", type=str, required=True)
    parser.add_argument("-a", "--amf", help="AMF Field (hex)", type=str, default="0000")
    parser.add_argument("-s", "--sqn", help="SQN Field (hex)", type=str, default="000000000000")

    args = parser.parse_args()

    server_host = args.host
    server_port = args.port
    verbose = args.verbose

    #opc = bytes.fromhex('767A662ACF4587EB0C450C6A95540A04')
    #k = bytes.fromhex('876B2D8D403EE96755BEF3E0A1857EBE')
    opc = bytes.fromhex(args.opc)
    k = bytes.fromhex(args.key)
    amf = bytes.fromhex(args.amf)
    sqn = bytes.fromhex(args.sqn)

    for i in range(args.count):
        rand = secrets.token_bytes(16)
        t = milenage_generate(opc=opc, amf=amf, k=k, sqn=sqn, rand=rand)

        req_json = {'rand': rand.hex(), 'autn': t['autn'].hex()}
        print("-> %s" % req_json)
        resp = rest_post('/slot/%u' % args.slot_nr, req_json)
        resp_json = resp.json()
        print("<- %s" % resp_json)
        if 'synchronisation_failure' in resp_json:
            auts = bytes.fromhex(resp_json['synchronisation_failure']['auts'])
            sqn_ms = milenage_auts(opc, k, rand, auts)
            if sqn_ms is not False:
                print("SQN_MS = %s" % sqn_ms.hex())
                sqn_ms_int = unpack48(sqn_ms)
                # we assume an IND bit-length of 5 here
                sqn = pack48(sqn_ms_int + (1 << 5))
            else:
                raise RuntimeError("AUTS auth failure during re-sync?!?")
        elif 'successful_3g_authentication' in resp_json:
            auth_res = resp_json['successful_3g_authentication']
            assert bytes.fromhex(auth_res['res']) == t['res']
            assert bytes.fromhex(auth_res['ck']) == t['ck']
            assert bytes.fromhex(auth_res['ik']) == t['ik']
            # we assume an IND bit-length of 5 here
            sqn = pack48(unpack48(sqn) + (1 << 5))
        else:
            raise RuntimeError("Auth failure")


if __name__ == "__main__":
    main(sys.argv)
