From 8c298b0fdecedb7c2f58fa9a50d5a8207b98d558 Mon Sep 17 00:00:00 2001 From: Martin van Es <martin@mrvanes.com> Date: Thu, 11 Nov 2021 10:30:17 +0100 Subject: [PATCH] First commit --- .gitignore | 7 ++++++ README.md | 11 +++++++++- mdsigner.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100755 mdsigner.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83d0c5f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# created by virtualenv automatically +bin/ +lib/ +pyvenv.cfg +meta.crt +meta.key +*.xml diff --git a/README.md b/README.md index 7b70569..b329800 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # alternate-mdx -Alternate MDX research project \ No newline at end of file +Alternate MDX research project + +## Usage +- Create python virtualenv +- Activate virtualenv (```. bin/activate```) +- ```pip install -r requirements.txt``` +- Create (self-signed) metadata signing cert (```meta.crt/meta.key```) +- Create output directory (```mkdir output```) +- Download metadata file(s) +- Run ```./mdsigner <metadata file(s)>``` \ No newline at end of file diff --git a/mdsigner.py b/mdsigner.py new file mode 100755 index 0000000..3755643 --- /dev/null +++ b/mdsigner.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +import sys +import copy +from concurrent.futures import ThreadPoolExecutor + +from lxml import etree as ET +from signxml import XMLSigner, XMLVerifier +import hashlib +# import traceback + + +# Find all IdP's in edugain metadata +idps = [] +success = 0 +failed = 0 +maxthreads = 8 + +cert = open("meta.crt").read() +key = open("meta.key").read() + + +def sign(xml, name): + global success, failed, cert + # print("Signer") + try: + sha1 = hashlib.sha1() + sha1.update(name.encode('utf-8')) + sha1d = sha1.hexdigest() + signed = XMLSigner().sign(xml, key=key, cert=cert) + out = ET.tostring(signed, pretty_print=True).decode() + # XMLVerifier().verify(out, x509_cert=cert) + with open(f'output/{sha1d}.xml', 'w') as f: + f.write(out) + success += 1 + except Exception as e: + print(name) + print(f" {e}") + # traceback.print_exc() + failed += 1 + + +with ThreadPoolExecutor(max_workers=maxthreads) as executor: + for mdfile in sys.argv[1:]: + tree = ET.ElementTree(file=mdfile) + root = tree.getroot() + ns = copy.deepcopy(root.nsmap) + ns['xml'] = 'http://www.w3.org/XML/1998/namespace' + + for idp in root.findall('md:EntityDescriptor', ns): + entityID = idp.attrib.get('entityID', 'none') + if entityID not in idps: + idps.append(entityID) + executor.submit(sign, idp, entityID) + +print(f"Succeeded: {success}") +print(f"Failed: {failed}") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fa728d5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +lxml +signxml -- GitLab