From 6cea97df2a8e2f8b569db5ba6c65817fb964fd07 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 17 Jan 2017 16:48:23 +0100 Subject: [PATCH 1/3] note that result of C_Initialize should be checked --- src/xmlsec/pk11.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xmlsec/pk11.py b/src/xmlsec/pk11.py index 8f97bf79..56538429 100644 --- a/src/xmlsec/pk11.py +++ b/src/xmlsec/pk11.py @@ -141,6 +141,7 @@ def _session(library, slot, pin=None): lib = PyKCS11.PyKCS11Lib() assert type(library) == str # lib.load does not like unicode lib.load(library) + # XXX should check result of C_Initialize() lib.lib.C_Initialize() _modules[library] = lib else: From c76f9962450966af9cab7942575c481854a12dd8 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 17 Jan 2017 16:49:26 +0100 Subject: [PATCH 2/3] Remove prefix 'xmlsec+' from keyspec. This is a workaround to allow passing "http://" keyspecs from pysaml2. --- src/xmlsec/crypto.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/xmlsec/crypto.py b/src/xmlsec/crypto.py index 065da62a..dbb0f752 100644 --- a/src/xmlsec/crypto.py +++ b/src/xmlsec/crypto.py @@ -27,10 +27,15 @@ def from_keyspec(keyspec, private=False, signature_element=None): set to a function calling the 'sign' function for the key, and the rest based on the (public) key returned by xmlsec.pk11.signer(). + - an http:// URL REST URL used for signing (see pyeleven). - a fingerprint. If signature_element is provided, the key is located using the fingerprint (provided as string). - X.509 string. An X.509 certificate as string. + If the keyspec is prefixed by 'xmlsec+', that prefix will be removed. + This is a workaround for pysaml2 that handles keyspecs starting with + 'http' differently. + Resulting dictionary (used except for 'callable') : {'keyspec': keyspec, @@ -47,6 +52,9 @@ def from_keyspec(keyspec, private=False, signature_element=None): :param signature_element: :returns: dict, see above. """ + if keyspec.startswith('xmlsec+'): + # workaround for pysaml2 which handles http keyspecs differently + keyspec = keyspec[7:] thread_local = threading.local() cache = getattr(thread_local, 'keycache', {}) if keyspec in cache: From d85ad451c00295cb34f1d26e64f7ddcec1a86546 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Tue, 17 Jan 2017 16:52:13 +0100 Subject: [PATCH 3/3] Allow using the '/rawsign' pyeleven endpoint. /rawsign does not put the certificate in every REST response. --- src/xmlsec/crypto.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/xmlsec/crypto.py b/src/xmlsec/crypto.py index dbb0f752..fd4dc5b2 100644 --- a/src/xmlsec/crypto.py +++ b/src/xmlsec/crypto.py @@ -164,14 +164,17 @@ def __init__(self, signature_element, keyspec): class XMLSecCryptoREST(XMlSecCrypto): def __init__(self, keyspec): super(XMLSecCryptoREST, self).__init__(source="rest", do_padding=False, private=True) - self._url = "%s/sign" % keyspec + self._keyspec = keyspec - def sign(self, data): + def sign(self, data, raw_sign=False): try: import requests import json - r = requests.post(self._url, - json=dict(mech='RSAPKCS1', data=data.encode("base64"))) + if raw_sign: + url = '{!s}/rawsign'.format(self._keyspec) + else: + url = '{!s}/sign'.format(self._keyspec) + r = requests.post(url, json=dict(mech='RSAPKCS1', data=data.encode("base64"))) if r.status_code != requests.codes.ok: r.raise_for_status() msg = r.json()