Skip to content

Commit 8fbe046

Browse files
committed
Added function to derive signature algorithm based on RSA, DSA and EC keys.
Signed-off-by: kimbeelen <kbeelen@infiniot.nl>
1 parent 076ca34 commit 8fbe046

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

openleadr/messaging.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from openleadr import errors
2424
from datetime import datetime, timezone, timedelta
2525
import os
26+
from signxml.algorithms import SignatureMethod
27+
from cryptography.hazmat.primitives import serialization
2628

2729
from openleadr import utils
2830
from .preflight import preflight_message
@@ -31,9 +33,7 @@
3133
logger = logging.getLogger('openleadr')
3234

3335
SIGNER = XMLSigner(method=methods.detached,
34-
c14n_algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315",
35-
signature_algorithm="ecdsa-sha256")
36-
print("hello from messaging CHANGED MESSAGE")
36+
c14n_algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315")
3737
SIGNER.namespaces['oadr'] = "http://openadr.org/oadr-2.0b/2012/07"
3838
VERIFIER = XMLVerifier()
3939

@@ -64,6 +64,28 @@ def parse_message(data):
6464
return message_type, message_payload
6565

6666

67+
def get_signature_algorithm(key_data, default_algorithm="rsa-sha256"):
68+
"""
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.
73+
"""
74+
try:
75+
key = serialization.load_pem_private_key(key_data, password=None)
76+
except ValueError:
77+
try:
78+
key = serialization.load_der_private_key(key_data, password=None)
79+
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:
85+
return "dsa-sha256"
86+
87+
return default_algorithm
88+
6789
def create_message(message_type, cert=None, key=None, passphrase=None, disable_signature=False, **message_payload):
6890
"""
6991
Create and optionally sign an OpenADR message. Returns an XML string.
@@ -74,6 +96,7 @@ def create_message(message_type, cert=None, key=None, passphrase=None, disable_s
7496
envelope = TEMPLATES.get_template('oadrPayload.xml')
7597
if cert and key and not disable_signature:
7698
tree = etree.fromstring(signed_object)
99+
SIGNER.sign_alg = SignatureMethod.from_fragment(get_signature_algorithm(key))
77100
signature_tree = SIGNER.sign(tree,
78101
key=key,
79102
cert=cert,

0 commit comments

Comments
 (0)