Commit 352815f5 authored by Mark Canterbury's avatar Mark Canterbury
Browse files

Adding signing/verification code and removing temp files

parent 02ec4497
Loading
Loading
Loading
Loading
Loading

utils/sign_json.py

0 → 100644
+36 −0
Original line number Diff line number Diff line

import argparse
from jose import jws
from pathlib import Path

import json


def insert_sig_block (j):
    j['signature'] = {
        'protected_header' : '',
        'signature' : ''
    }
    return j

if __name__ == "__main__":
    json_path = Path("103120/examples/json/request1.json")
    json_text = json_path.read_text()
    
    j = json.loads(json_text)
    j = insert_sig_block(j)
    
    presigned_json_text = json.dumps(j)
    Path('presigned.json').write_text(presigned_json_text)
    presigned_json_bytes = presigned_json_text.encode('utf-8')
    
    signed = jws.sign(presigned_json_bytes, 'secret_key', algorithm="HS256")
    components = signed.split('.')

    j['signature']['protected_header'] = components[0]
    j['signature']['signature'] = components[2]

    signed_json_text = json.dumps(j)
    print(signed_json_text)

    

utils/verify_json.py

0 → 100644
+60 −0
Original line number Diff line number Diff line

import argparse
import sys
import logging
import base64
from jose import jws
from pathlib import Path

import json


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-v', '--verbose', action='count', help='Verbose logging (can be specified multiple times)')
    parser.add_argument('-i', '--input', type=argparse.FileType('r'), default=sys.stdin, help="Path to input file (if absent, stdin is used)")
    args = parser.parse_args()

    match args.verbose:
        case v if v and v >= 2:
            logging.basicConfig(level=logging.DEBUG)
        case 1:
            logging.basicConfig(level=logging.INFO)
        case _:
            logging.basicConfig(level=logging.WARNING)

    logging.debug(f"Arguments: {args}")

    signed_json_text = args.input.read()
    args.input.close()
    
    j = json.loads(signed_json_text)
    
    protected_header = j['signature']['protected_header']
    signature = j['signature']['signature']

    # TODO some safety checks needed here

    # Remove the newline that appears from the console
    if signed_json_text.endswith('\n'): signed_json_text = signed_json_text[:-1]
    signed_json_text = signed_json_text.replace(protected_header, "").replace(signature, "")
    
    print ("\n\nPayload for verification ================================")
    print(signed_json_text)

    payload_bytes = signed_json_text.encode('utf-8')
    payload_token = base64.b64encode(payload_bytes).decode('ascii')

    # Un-pad the token, as per RFC7515 annex C
    payload_token = payload_token.split('=')[0]
    payload_token = payload_token.replace('+','-')
    payload_token = payload_token.replace('/','_')

    print ("Payload bytes:", payload_bytes)
    print ("Payload token:", payload_token)

    token = protected_header + "." + payload_token + "." + signature
    result = jws.verify(token, key="secret_key", algorithms=['HS256'])
    
    print("Signature verified")