2323from openleadr import errors
2424from datetime import datetime , timezone , timedelta
2525import os
26+ from signxml .algorithms import SignatureMethod
27+ from cryptography .hazmat .primitives import serialization
2628
2729from openleadr import utils
2830from .preflight import preflight_message
3133logger = logging .getLogger ('openleadr' )
3234
3335SIGNER = 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" )
3737SIGNER .namespaces ['oadr' ] = "http://openadr.org/oadr-2.0b/2012/07"
3838VERIFIER = 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+
6789def 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