def validate(self, msg): if isinstance(msg, tuple): msg = msg[0] _msg = cloneDocument(msg) # validate everything dsig = _msg.find(XBE("MessageHeader") + "/" + XBE_SEC("SecurityInformation") + "/" + DSIG("Signature")) if dsig is None: raise SignatureMissing("No signature found") cert_text = dsig.findtext(DSIG("KeyInfo/X509Certificate")) if cert_text: if self.__other_cert: # check if they are the same, else raise an error if self.__other_cert.as_pem() != cert_text: raise SecurityError("the included certificate does not match the saved certificate.") else: valid = False # validate the x509 certificate cert = X509Certificate.load(cert_text) for ca in self.__ca_certs: if ca.validate_certificate(cert): valid = True; break if not valid: raise ValidationError("X.509 certificate could not be validated") self.__other_cert = cert x509 = self.__other_cert if x509 is None: raise CertificateMissing( "cannot verify message, since i do not have the matching certificate") signature_value = dsig.find(DSIG("SignatureValue")) dsig.remove(signature_value) # validate the signature c14n = StringIO() _msg.getroottree().write_c14n(c14n) x509.msg_validate(c14n.getvalue(), signature_value.text) return _msg
def sign(self, msg, include_certificate=False): _msg = cloneDocument(msg) hdr = _msg.find(XBE("MessageHeader")) if hdr is None: raise ValueError("the message requires a header!") nsmap = { "xbe": str(XBE), "xbe-sec": str(XBE_SEC), "dsig": str(DSIG) } # append securityInformation sec_info = etree.SubElement(hdr, XBE_SEC("SecurityInformation"), nsmap=nsmap) dsig_sig = etree.SubElement(sec_info, DSIG("Signature"), nsmap=nsmap) if include_certificate: dsig_key = etree.SubElement(dsig_sig, DSIG("KeyInfo")) etree.SubElement(dsig_key, DSIG("X509Certificate")).text = self.__my_cert.as_der() # sign the whole message as it is right now and put it into the header signature = self.__my_cert.msg_signature(etree.tostring(_msg)) etree.SubElement(dsig_sig, DSIG("SignatureValue")).text = signature return (_msg, signature)