Skip to content

Commit aea98ad

Browse files
committed
Split get_signature_algorithm into three separate functions.
Signed-off-by: kimbeelen <kbeelen@infiniot.nl>
1 parent 8fbe046 commit aea98ad

1 file changed

Lines changed: 40 additions & 12 deletions

File tree

openleadr/messaging.py

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import os
2626
from signxml.algorithms import SignatureMethod
2727
from cryptography.hazmat.primitives import serialization
28+
from cryptography.hazmat.primitives.asymmetric import rsa, dsa, ec, ed25519, ed448
2829

2930
from openleadr import utils
3031
from .preflight import preflight_message
@@ -64,26 +65,53 @@ def parse_message(data):
6465
return message_type, message_payload
6566

6667

67-
def get_signature_algorithm(key_data, default_algorithm="rsa-sha256"):
68+
def load_private_key(key_data):
6869
"""
69-
Derive the signature algorithm based on the key type. Accepted key types are EC, DSA and RSA keys.
70-
Returns a string that can be used to lookup a signature algorithm by fragment.
71-
If key is not EC or DSA, the lookup will return rsa-sha256, which is the default signature algorithm
72-
for XMLSigner objects.
70+
Load the key based on key data. .pem and .der keys can be loaded.
71+
Returns a private key object.
7372
"""
73+
with open(key_data, "rb") as f:
74+
key_data = f.read()
7475
try:
7576
key = serialization.load_pem_private_key(key_data, password=None)
7677
except ValueError:
7778
try:
7879
key = serialization.load_der_private_key(key_data, password=None)
7980
except ValueError:
80-
logger.warning(f"Could not load key: unknown key type.")
81-
key_type = str(type(key)).lower()
82-
if "ec" in key_type and hasattr(key, "curve"):
83-
return "ecdsa-sha3-256"
84-
elif "dsa" in key_type:
81+
logger.warning(f"Could not load key: unknown key file format.")
82+
return key
83+
84+
def get_private_key_type(key):
85+
"""
86+
Determine the type of the key. ED25519 and ED448 are not supported by SignXML so these are rejected.
87+
"""
88+
if isinstance(key, rsa.RSAPrivateKey):
89+
return "rsa"
90+
elif isinstance(key, dsa.DSAPrivateKey):
91+
return "dsa"
92+
elif isinstance(key, ec.EllipticCurvePrivateKey):
93+
return "ec"
94+
elif isinstance(key, ed25519.Ed25519PrivateKey):
95+
logger.warning("ED25519 keys are not supported")
96+
elif isinstance(key, ed448.Ed448PrivateKey):
97+
logger.warning("ED448 keys are not supported")
98+
logger.warning("Unknown key type.")
99+
100+
101+
def get_signature_algorithm_from_private_key(key_data, default_algorithm="rsa-sha256"):
102+
"""
103+
Derive a signature algorithm based on the private key type. Accepted key types are EC, DSA and RSA keys.
104+
Returns a string that can be used to lookup a signature algorithm by fragment.
105+
By default the lookup will return rsa-sha256, which is the default signature algorithm for XMLSigner objects.
106+
"""
107+
key = load_private_key(key_data)
108+
key_type = get_private_key_type(key)
109+
if key_type == "rsa":
110+
return "rsa-sha256"
111+
elif key_type == "dsa":
85112
return "dsa-sha256"
86-
113+
elif key_type == "ec":
114+
return "ecdsa-sha3-256"
87115
return default_algorithm
88116

89117
def create_message(message_type, cert=None, key=None, passphrase=None, disable_signature=False, **message_payload):
@@ -96,7 +124,7 @@ def create_message(message_type, cert=None, key=None, passphrase=None, disable_s
96124
envelope = TEMPLATES.get_template('oadrPayload.xml')
97125
if cert and key and not disable_signature:
98126
tree = etree.fromstring(signed_object)
99-
SIGNER.sign_alg = SignatureMethod.from_fragment(get_signature_algorithm(key))
127+
SIGNER.sign_alg = SignatureMethod.from_fragment(get_signature_algorithm_from_private_key(key))
100128
signature_tree = SIGNER.sign(tree,
101129
key=key,
102130
cert=cert,

0 commit comments

Comments
 (0)