Commit cd6894f5 authored by Martin van Es's avatar Martin van Es
Browse files

Add PKCS11 (softHSM2) Signer

parent 420ce3ab
......@@ -14,7 +14,7 @@ Alternate MDX research project
## ```mdsigner.py [mdfile] [mdfile] [mdfile] ...```
Reads source metadata file(s) and outputs them signed to filesystem
## ```mdserver.py [mdfile] [mdfile] [mdfile] ...```
## ```mdserver.py```
Starts a metadata signer server.
Reads source metadata files(s) from mdsigner.yaml configuration, see example.
Reloads metadata on inotify CLOSE_WRITE of metadata file.
......@@ -28,3 +28,19 @@ MDQ Queries can then be pointed at
- ```http://mdserver:5001/sign/<entityid>```
- ```http://mdproxy:5002/cache/<entityid>```
## Bootstrap softHSM2
This is a very brief summary of the successive commands to initialize softHSM2 for testing. Tested on Ubuntu 21.10.
```
# softhsm2-util --show-slots
# softhsm2-util --init-token --slot 0 --label "My token 1" --pin "secret" --so-pin "secret"
# softhsm2-util --show-slots
# pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l -k --key-type rsa:1024 --slot-index 0 --id a1b2 --label test --pin secret
# pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l --pin secret -O
# openssl req -new -x509 -subj "/CN=Test Signer" -engine pkcs11 -keyform engine -key label_test -passin 'pass:secret' -out hsm.crt
# openssl x509 -inform PEM -outform DER -in hsm.crt -out hsm.der
# pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l --slot-index 0 --id a1b2 --label test -y cert -w hsm.der --pin secret
```
\ No newline at end of file
#!/usr/bin/env python
from utils import read_config, server, event_notifier
from utils import read_config, Resource, server
from flask import Flask, Response
config = read_config()
......@@ -24,9 +24,10 @@ def serve(domain, entity_id):
for domain, values in config.items():
print(f"domain: {domain}")
conf = (values['metadir'], values['signer'])
server[domain] = conf
location = values['metadir']
signer = values['signer']
server[domain] = Resource(location, signer)
server.add_watch(domain, location)
event_notifier.start()
app.run(host='127.0.0.1', port=5001)
import xmlsec
from signxml import XMLSigner
cert = open("meta.crt").read()
......@@ -17,10 +18,15 @@ def Signers(signer):
print("Foobar signer")
return XMLSigner().sign(xml, key=key, cert=cert)
def _hsm_signer(xml):
print("HSM signer")
return xmlsec.sign(xml, key_spec="pkcs11:///usr/lib/softhsm/libsofthsm2.so/test?pin=secret")
signers = {
'normal_signer': _normal_signer,
'test_signer': _test_signer,
'foobar_signer': _foobar_signer
'foobar_signer': _foobar_signer,
'hsm_signer': _hsm_signer
}
return signers[signer]
......@@ -9,8 +9,8 @@ import yaml
import pyinotify
from signers import Signers
watch_list = {}
watch_manager = pyinotify.WatchManager()
# watch_list = {}
# watch_manager = pyinotify.WatchManager()
def read_config():
......@@ -26,13 +26,6 @@ def hasher(entity_id):
return sha1_digest
class EventProcessor(pyinotify.ProcessEvent):
def process_IN_CLOSE_WRITE(self, event):
domain = watch_list[event.path]
print(f"Notify {domain} {event.path}")
server[domain].walk_location(event.path)
class Entity:
def __init__(self):
self.md = None
......@@ -60,7 +53,6 @@ class Resource:
found = 0
removed = 0
old_idps = self.mdfiles[mdfile].copy()
print(f"old_idps: {old_idps}")
tree = ET.ElementTree(file=mdfile)
root = tree.getroot()
ns = root.nsmap.copy()
......@@ -129,16 +121,35 @@ class Resource:
return data
class EventProcessor(pyinotify.ProcessEvent):
def process_IN_CLOSE_WRITE(self, event):
server.process(event.path)
class Server:
def __setitem__(self, domain, conf):
location, signer = conf
self.__dict__[domain] = Resource(location, signer)
watch_list[location] = domain
watch_manager.add_watch(location, pyinotify.IN_CLOSE_WRITE)
watch_list = {}
def __init__(self):
self.watch_manager = pyinotify.WatchManager()
self.event_notifier = pyinotify.ThreadedNotifier(self.watch_manager, EventProcessor())
self.event_notifier.start()
def add_watch(self, domain, location):
self.watch_list[location] = domain
self.watch_manager.add_watch(location, pyinotify.IN_CLOSE_WRITE)
def process(self, location):
domain = self.watch_list[location]
print(f"Notify {domain} {location}")
self.__dict__[domain].walk_location(location)
def __setitem__(self, domain, resource):
self.__dict__[domain] = resource
# watch_list[location] = domain
# watch_manager.add_watch(location, pyinotify.IN_CLOSE_WRITE)
def __getitem__(self, domain):
return self.__dict__[domain]
server = Server()
event_notifier = pyinotify.ThreadedNotifier(watch_manager, EventProcessor())
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment