Skip to content
Snippets Groups Projects
Commit cd6894f5 authored by Martin van Es's avatar Martin van Es
Browse files

Add PKCS11 (softHSM2) Signer

parent 420ce3ab
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......@@ -6,3 +6,5 @@ python-dateutil
isoduration
pyyaml
pyinotify
pyXMLSecurity
PyKCS11
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())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment