diff --git a/shared/exig_files/latest_version/xmldsig-core-schema.exig b/shared/exig_files/latest_version/xmldsig-core-schema.exig new file mode 100644 index 0000000..9074362 Binary files /dev/null and b/shared/exig_files/latest_version/xmldsig-core-schema.exig differ diff --git a/shared/global_values.py b/shared/global_values.py index a43b5b8..344106b 100755 --- a/shared/global_values.py +++ b/shared/global_values.py @@ -25,9 +25,11 @@ APP_PROTOCOL_XSD = "../shared/xsd_files/latest_version/V2G_CI_AppProtocol.xsd" COMMON_MESSAGES_XSD = "../shared/xsd_files/latest_version/V2G_CI_CommonMessages.xsd" DC_MESSAGES_XSD = "../shared/xsd_files/latest_version/V2G_CI_DC.xsd" +XMLDSIG_XSD = "../shared/xsd_files/latest_version/xmldsig-core-schema.xsd" APP_PROTOCOL_EXIG = "../shared/exig_files/latest_version/V2G_CI_AppProtocol.exig" COMMON_MESSAGES_EXIG = "../shared/exig_files/latest_version/V2G_CI_CommonMessages.exig" DC_MESSAGES_EXIG = "../shared/exig_files/latest_version/V2G_CI_DC.exig" +XMLDSIG_EXIG = "../shared/exig_files/latest_version/xmldsig-core-schema.exig" # Passphrase used to access private key. This parameter shall be stored in a secured directory. PASSPHRASE = "123456789abcdefgh" diff --git a/shared/message_handling.py b/shared/message_handling.py index 3d80afb..ccd9cbf 100755 --- a/shared/message_handling.py +++ b/shared/message_handling.py @@ -21,7 +21,7 @@ from shared.log import logger import lxml from shared.global_values import SDP_PAYLOAD_TYPES, MAX_PAYLOAD_LENGTH, APP_PROTOCOL_EXIG, COMMON_MESSAGES_EXIG, \ - DC_MESSAGES_EXIG, APP_PROTOCOL_XSD, COMMON_MESSAGES_XSD, DC_MESSAGES_XSD + DC_MESSAGES_EXIG, APP_PROTOCOL_XSD, COMMON_MESSAGES_XSD, DC_MESSAGES_XSD, XMLDSIG_XSD, XMLDSIG_EXIG import jpype import os @@ -107,10 +107,14 @@ class MessageHandler(metaclass=Singleton): dc_schema = open_exi_schema(DC_MESSAGES_EXIG) dc_grammar_cache = GrammarCache(dc_schema, options) + xmldsig_schema = open_exi_schema(XMLDSIG_EXIG) + xmldsig_grammar_cache = GrammarCache(xmldsig_schema, options) + def __init__(self): self.xml_SAP_validator = lxml.etree.XMLSchema(file=APP_PROTOCOL_XSD) self.xml_Common_validator = lxml.etree.XMLSchema(file=COMMON_MESSAGES_XSD) self.xml_DC_validator = lxml.etree.XMLSchema(file=DC_MESSAGES_XSD) + self.xml_xmldsig_validator = lxml.etree.XMLSchema(file=XMLDSIG_XSD) self.parser = XmlParser(context=XmlContext()) self.config = SerializerConfig(pretty_print=True) self.serializer = XmlSerializer(config=self.config) @@ -170,7 +174,7 @@ def is_payload_length_correct(v2gtp_message: V2GTPMessage) -> bool: # return schema @staticmethod - def encode(xml_contents: str, type_msg: str) -> str: + def encode(xml_contents: str, type_msg: str, fragment: bool = False) -> str: """Turns a human-readable string to an EXI-encoded string. Relies on Java classes. :param xml_contents: The XML string to be encoded. @@ -182,18 +186,21 @@ def encode(xml_contents: str, type_msg: str) -> str: output = None try: t = MessageHandler.transmogrifier - input = ByteArrayInputStream(contents.getBytes(Charset.forName("ASCII"))); - output = ByteArrayOutputStream(); + t.setFragment(fragment) + input = ByteArrayInputStream(contents.getBytes(Charset.forName("ASCII"))) + output = ByteArrayOutputStream() if type_msg == "SAP": - t.setGrammarCache(MessageHandler.ap_grammar_cache); + t.setGrammarCache(MessageHandler.ap_grammar_cache) elif type_msg == "Common": - t.setGrammarCache(MessageHandler.common_grammar_cache); + t.setGrammarCache(MessageHandler.common_grammar_cache) elif type_msg == "DC": - t.setGrammarCache(MessageHandler.dc_grammar_cache); + t.setGrammarCache(MessageHandler.dc_grammar_cache) + elif type_msg == "xmldsig": + t.setGrammarCache(MessageHandler.xmldsig_grammar_cache) else: raise Exception("Unknown message type") - t.setOutputStream(output); - t.encode(InputSource(input)); + t.setOutputStream(output) + t.encode(InputSource(input)) result = output.toByteArray() finally: if input: @@ -203,7 +210,7 @@ def encode(xml_contents: str, type_msg: str) -> str: return result @staticmethod - def decode(exi_contents: bytes, type_msg: str) -> str: + def decode(exi_contents: bytes, type_msg: str, fragment: bool = False) -> str: """Turns encoded EXI bytes to human-readable string. Relies on Java classes. :param exi_contents: The EXI encoded contents. @@ -217,13 +224,16 @@ def decode(exi_contents: bytes, type_msg: str) -> str: try: input = ByteArrayInputStream(exi_contents) r = MessageHandler.reader + r.setFragment(fragment) tf_handler = MessageHandler.transformer_handler if type_msg == "SAP": - r.setGrammarCache(MessageHandler.ap_grammar_cache); + r.setGrammarCache(MessageHandler.ap_grammar_cache) elif type_msg == "Common": - r.setGrammarCache(MessageHandler.common_grammar_cache); + r.setGrammarCache(MessageHandler.common_grammar_cache) elif type_msg == "DC": - r.setGrammarCache(MessageHandler.dc_grammar_cache); + r.setGrammarCache(MessageHandler.dc_grammar_cache) + elif type_msg == "xmldsig": + r.setGrammarCache(MessageHandler.xmldsig_grammar_cache) else: raise Exception("Unknown message type") @@ -309,6 +319,8 @@ def is_xml_valid(self, xml, msg_type): validator = self.xml_Common_validator elif msg_type == 'DC': validator = self.xml_DC_validator + elif msg_type == 'xmldsig': + validator = self.xml_xmldsig_validator try: validator.assertValid(xml_file) is_valid = True diff --git a/shared/xml_classes/common_messages/v2_g_ci_common_messages.py b/shared/xml_classes/common_messages/v2_g_ci_common_messages.py index 7a05cc8..eceb50c 100644 --- a/shared/xml_classes/common_messages/v2_g_ci_common_messages.py +++ b/shared/xml_classes/common_messages/v2_g_ci_common_messages.py @@ -948,6 +948,11 @@ class SignedCertificateChainType: } ) +@dataclass +class OEMProvisioningCertificateChain(SignedCertificateChainType): + class Meta: + name = "OEMProvisioningCertificateChain" + namespace = "urn:iso:std:iso:15118:-20:CommonMessages" @dataclass class SignedMeteringDataType: @@ -1463,6 +1468,11 @@ class Meta: } ) +@dataclass +class PnCAreqAuthorizationMode(PnCAreqAuthorizationModeType): + class Meta: + name = "PnC_AReqAuthorizationMode" + namespace = "urn:iso:std:iso:15118:-20:CommonMessages" @dataclass class PowerDeliveryRes(PowerDeliveryResType):