SimpleXml (simple_xml v1.2.2)

This is a thin wrapper around the saxy library. It leverages the DOM generated by saxy's SimpleForm parser and defines some basic operations on the DOM via the XmlNode module.

The main benefit of using saxy's SimpleForm parsing is that it gives us a string presentation of the XML DOM, without exposing the users of this library with the atom exhaustion vulernability of the xmerl library and any parsers based on it.

Summary

Functions

Parses an XML string to return a tuple representing the XML node.

Verifies the signature contained within the XML document represented by the given node. For the sake of simplicity of implementation, this function expects the following to be true for the given XML document

Types

Link to this type

public_key()

@type public_key() :: {atom(), any()}
Link to this type

xml_attribute()

@type xml_attribute() :: {String.t(), String.t()}
@type xml_node() :: {String.t(), [xml_attribute()], [tuple()]}

Functions

@spec parse(String.t()) :: {:ok, xml_node()} | {:error, Saxy.ParseError.t()}

Parses an XML string to return a tuple representing the XML node.

Examples

Well-formed XMLs are successfully parsed

iex> SimpleXml.parse(~S{<foo attr1="value1" attr2="value2">body</foo>})
{:ok, {"foo", [{"attr1", "value1"}, {"attr2", "value2"}], ["body"]}}

Malformed XMLs result in an error

iex> SimpleXml.parse("<foo")
{:error, %Saxy.ParseError{reason: {:token, :name_start_char}, binary: "<foo", position: 4}}
Link to this function

verify(node, public_key)

@spec verify(xml_node(), public_key()) :: :ok | {:error, any()}

Verifies the signature contained within the XML document represented by the given node. For the sake of simplicity of implementation, this function expects the following to be true for the given XML document:

Arguments:

  • node: The xml_node corresponding to the document or portion of the document to be verified
  • public_key: The key to use for verifying the signature. Value matches the key argument given to :pubic_key.verify/4. Please see document here for further details.

Examples

Verifies a valid signature via the given public key

iex> cert_der = ~S(MIIDqDCCApCgAwIBAgIGAYj8lAYkMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA2MjcxMTE3NTlaFw0zMzA2MjcxMTE4NTlaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTE7IRG+oQZBASQ7DY3yeTrwABdI2BgG2FXKSkTPk9enMwtyUyDXCOteOg18+//MA2UTvgSI+n0fiAh7Bi7cxpimnOaj/kcgvpdn+5wpEfSIDKAeEg9VIQf0fz/ks4XkrNxRh8ba6Z/ypOVR2TLozu8v6sjGCiqHSoiPl78KINHx9jMB3QGdTHRxsTzwFPGcUEvO7XvjxxMN9FLZdHkwtA6cZXDbHlAv+o4EbLIRqXFc3vF5rs3Fz+cgqZ3HVGm90TFFcbPbx/eKcvzyHdYt8P5pi364mijt9NKtNV9F9VdPz+Gp/rxlw0i/IWxV0/vBrW10HPd42krsOgHibxBYg8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEArpYzZEoYcRo3YF7Ny4gdc8ODSlPPKIdLvwhUTGbPdzJU2ifxzE/KeTHGmFpjpakjDmmWsr2j9FGU/9U0SjqPmJHP5gYbjmz+tD3jeaEkIBDZpcYc+MveQaA7uDMILA2OUhHuFu0UJVjGxl2EIpxivC+IJ0RpBS5AERT6V91Fqv2Ylwb5sklhoXGDx9s+l+Ud1MLaewIvnUHdIRtC02bvlhjwt0pnICDtHMikvOiTXjTBJgl7X9Q51Gm636q9pJVjS1T0gR3cNt9JJE/foDdOK8JozRFtF4j14xegXLt7BVBIXuSOK6P1c09mCPQ1VJbcj01S1zfrvZ+RZvrxr/0aXQ==)
iex> {:ok, cert} = cert_der |> Base.decode64!() |> X509.Certificate.from_der()
iex> public_key = X509.Certificate.public_key(cert)
iex> saml_response = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsLm1ieC5jb206NDAwMS9hdXRoL2FoZWFkL3NzbyIgSUQ9ImlkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGthNWhhNmJrblk2T2tkODVkNzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT5tc1hWN3BvS2dWSjE1SmFzeU5NVndFRUNqMHJOOGVjeUdUb291WFd6L0drPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5nM1dIaXZCR2hQc01hMDMwaDlCVUlBV2FFckFXZDI4dURqQlVIUk9RK2VoS3dqcXhrQ1BsYzRaVXdyRitnbkZtdzJsdDgxbnBwbzVVMEVTbW4vQUdKNjBKMjBaeFZSZ2pzWnhLMUFoVnFyNDB1MHdBNmY2akNKaUpXbmJxSUdXWERYeWlrV08wLzRycU9kRDl3UDhEdzJQbWlvMit2TXNOSWxwTnl1MnlvQXoydXNsbi92RmVTWXRZNW1LMDk1eDd3VWNIYVcwb2NacE9VTEREalNiMHFHTjhWN1dnSnZGaEhQcURiTnBHMTFSQmNac0VxRnVsYUd6djJQdXU5aER5dStaMEhOcVQwKzNGMEkxVGluTUpHMzNQcXMyUnNva0NaTHh6MkdCNHdqZHBOVFJOTTdKN2loN0x5N2Y5a2RPTWFMbSs2YzkxN3puM2JKUDdWOUdiOWc9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRHFEQ0NBcENnQXdJQkFnSUdBWWo4bEFZa01BMEdDU3FHU0liM0RRRUJDd1VBTUlHVU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFRwpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVCk1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFY01Cb0dDU3FHU0liM0RRRUoKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVEFlRncweU16QTJNamN4TVRFM05UbGFGdzB6TXpBMk1qY3hNVEU0TlRsYU1JR1VNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCd3dOVTJGdUlFWnlZVzVqYVhOamJ6RU5NQXNHCkExVUVDZ3dFVDJ0MFlURVVNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RlRBVEJnTlZCQU1NREdSbGRpMDBOVE0wT1Rrd05qRWMKTUJvR0NTcUdTSWIzRFFFSkFSWU5hVzVtYjBCdmEzUmhMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUxURTdJUkcrb1FaQkFTUTdEWTN5ZVRyd0FCZEkyQmdHMkZYS1NrVFBrOWVuTXd0eVV5RFhDT3RlT2cxOCsvL01BMlVUdmdTCkkrbjBmaUFoN0JpN2N4cGltbk9hai9rY2d2cGRuKzV3cEVmU0lES0FlRWc5VklRZjBmei9rczRYa3JOeFJoOGJhNloveXBPVlIyVEwKb3p1OHY2c2pHQ2lxSFNvaVBsNzhLSU5IeDlqTUIzUUdkVEhSeHNUendGUEdjVUV2TzdYdmp4eE1OOUZMWmRIa3d0QTZjWlhEYkhsQQp2K280RWJMSVJxWEZjM3ZGNXJzM0Z6K2NncVozSFZHbTkwVEZGY2JQYngvZUtjdnp5SGRZdDhQNXBpMzY0bWlqdDlOS3ROVjlGOVZkClB6K0dwL3J4bHcwaS9JV3hWMC92QnJXMTBIUGQ0Mmtyc09nSGlieEJZZzhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKcnBZelpFb1ljUm8zWUY3Tnk0Z2RjOE9EU2xQUEtJZEx2d2hVVEdiUGR6SlUyaWZ4ekUvS2VUSEdtRnBqcGFrakRtbVdzcjJqOUZHVQovOVUwU2pxUG1KSFA1Z1liam16K3REM2plYUVrSUJEWnBjWWMrTXZlUWFBN3VETUlMQTJPVWhIdUZ1MFVKVmpHeGwyRUlweGl2QytJCkowUnBCUzVBRVJUNlY5MUZxdjJZbHdiNXNrbGhvWEdEeDlzK2wrVWQxTUxhZXdJdm5VSGRJUnRDMDJidmxoand0MHBuSUNEdEhNaWsKdk9pVFhqVEJKZ2w3WDlRNTFHbTYzNnE5cEpWalMxVDBnUjNjTnQ5SkpFL2ZvRGRPSzhKb3pSRnRGNGoxNHhlZ1hMdDdCVkJJWHVTTwpLNlAxYzA5bUNQUTFWSmJjajAxUzF6ZnJ2WitSWnZyeHIvMGFYUT09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWwycDpTdGF0dXMgeG1sbnM6c2FtbDJwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPjxzYW1sMnA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1sMnA6U3RhdHVzPjxzYW1sMjpBc3NlcnRpb24gSUQ9ImlkMjc3ODQwNDc4ODc3ODQ3MjgyMTE5MzE4OTUiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGthNWhhNmJrblk2T2tkODVkNzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMjc3ODQwNDc4ODc3ODQ3MjgyMTE5MzE4OTUiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT42b3Ztd3BWNk00bHdBQ3BGZ0tqVm0rNlZ5U0t0dE9iVTF2Y2tvZlVWa2ZBPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5QdGhLcG1TY2k3OTdERExvTXR1TUJHNjgvbzZlcDFSSWxZR0RhRVR6Q1E1a0ZUdmQ3MWJ3RWpjOWl2UVdlU3VHM1U4aUM2THQvN0hmWEpUVDBLeWkvU2laa3pIZkl1bElKbTVQTm9memV1dXVFQVlyMFBoeUpidkJHUk44RWF0UEwwVjNsdlhPMU9YaHcxU2ltYlMwZEdoQkdCM1ovNEptajNBMGdGbmx5TkpOLzc4eFgrYlB1eEJLeFFYcFY5TTEwTnJLRUYrbzc1TVA3bm4xOW5KM002bG93SEFHZ3RhRFg5dTNGYTJ3Lzh4QXFGTnQ2NHdaMERQYWltQWl0RFBKdnRIL3VVN3k0cm1lUit0cXpqdnNHR3BtODNjNVNzd1dEZ1p4alBDSVdHRVRaVVdHQ0Rwb25WVzdUR0JuNDR4b1ZZUEhERStJcWJyWDdUVXIySFFoUGc9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRHFEQ0NBcENnQXdJQkFnSUdBWWo4bEFZa01BMEdDU3FHU0liM0RRRUJDd1VBTUlHVU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFRwpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVCk1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFY01Cb0dDU3FHU0liM0RRRUoKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVEFlRncweU16QTJNamN4TVRFM05UbGFGdzB6TXpBMk1qY3hNVEU0TlRsYU1JR1VNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCd3dOVTJGdUlFWnlZVzVqYVhOamJ6RU5NQXNHCkExVUVDZ3dFVDJ0MFlURVVNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RlRBVEJnTlZCQU1NREdSbGRpMDBOVE0wT1Rrd05qRWMKTUJvR0NTcUdTSWIzRFFFSkFSWU5hVzVtYjBCdmEzUmhMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUxURTdJUkcrb1FaQkFTUTdEWTN5ZVRyd0FCZEkyQmdHMkZYS1NrVFBrOWVuTXd0eVV5RFhDT3RlT2cxOCsvL01BMlVUdmdTCkkrbjBmaUFoN0JpN2N4cGltbk9hai9rY2d2cGRuKzV3cEVmU0lES0FlRWc5VklRZjBmei9rczRYa3JOeFJoOGJhNloveXBPVlIyVEwKb3p1OHY2c2pHQ2lxSFNvaVBsNzhLSU5IeDlqTUIzUUdkVEhSeHNUendGUEdjVUV2TzdYdmp4eE1OOUZMWmRIa3d0QTZjWlhEYkhsQQp2K280RWJMSVJxWEZjM3ZGNXJzM0Z6K2NncVozSFZHbTkwVEZGY2JQYngvZUtjdnp5SGRZdDhQNXBpMzY0bWlqdDlOS3ROVjlGOVZkClB6K0dwL3J4bHcwaS9JV3hWMC92QnJXMTBIUGQ0Mmtyc09nSGlieEJZZzhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKcnBZelpFb1ljUm8zWUY3Tnk0Z2RjOE9EU2xQUEtJZEx2d2hVVEdiUGR6SlUyaWZ4ekUvS2VUSEdtRnBqcGFrakRtbVdzcjJqOUZHVQovOVUwU2pxUG1KSFA1Z1liam16K3REM2plYUVrSUJEWnBjWWMrTXZlUWFBN3VETUlMQTJPVWhIdUZ1MFVKVmpHeGwyRUlweGl2QytJCkowUnBCUzVBRVJUNlY5MUZxdjJZbHdiNXNrbGhvWEdEeDlzK2wrVWQxTUxhZXdJdm5VSGRJUnRDMDJidmxoand0MHBuSUNEdEhNaWsKdk9pVFhqVEJKZ2w3WDlRNTFHbTYzNnE5cEpWalMxVDBnUjNjTnQ5SkpFL2ZvRGRPSzhKb3pSRnRGNGoxNHhlZ1hMdDdCVkJJWHVTTwpLNlAxYzA5bUNQUTFWSmJjajAxUzF6ZnJ2WitSWnZyeHIvMGFYUT09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWwyOlN1YmplY3QgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPjxzYW1sMjpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+ZGouamFpbjwvc2FtbDI6TmFtZUlEPjxzYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+PHNhbWwyOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAyMy0wNy0xMFQxMzo0NToyOS42NTlaIiBSZWNpcGllbnQ9Imh0dHBzOi8vbG9jYWwubWJ4LmNvbTo0MDAxL2F1dGgvYWhlYWQvc3NvIi8+PC9zYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDI6U3ViamVjdD48c2FtbDI6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjMtMDctMTBUMTM6MzU6MjkuNjU5WiIgTm90T25PckFmdGVyPSIyMDIzLTA3LTEwVDEzOjQ1OjI5LjY1OVoiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDI6QXVkaWVuY2VSZXN0cmljdGlvbj48c2FtbDI6QXVkaWVuY2U+eHFPNTJDTkVMZDBoVkI5dmFYMWRfZGN3dVlBeEdVU3I8L3NhbWwyOkF1ZGllbmNlPjwvc2FtbDI6QXVkaWVuY2VSZXN0cmljdGlvbj48L3NhbWwyOkNvbmRpdGlvbnM+PHNhbWwyOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBTZXNzaW9uSW5kZXg9ImlkMTY4ODk5NjQyOTY1Ny4xMTQ1MDMyMDEyIiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+PHNhbWwyOkF1dGhuQ29udGV4dD48c2FtbDI6QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmRQcm90ZWN0ZWRUcmFuc3BvcnQ8L3NhbWwyOkF1dGhuQ29udGV4dENsYXNzUmVmPjwvc2FtbDI6QXV0aG5Db250ZXh0Pjwvc2FtbDI6QXV0aG5TdGF0ZW1lbnQ+PC9zYW1sMjpBc3NlcnRpb24+PC9zYW1sMnA6UmVzcG9uc2U+"
iex> {:ok, saml_body} = saml_response |> Base.decode64()
iex> {:ok, root} = SimpleXml.parse(saml_body)
iex> SimpleXml.verify(root, public_key)
:ok

Verifies a valid signature that relies on InclusiveNamespaces

iex> cert_der = ~S(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)
iex> {:ok, cert} = cert_der |> Base.decode64!() |> X509.Certificate.from_der()
iex> public_key = X509.Certificate.public_key(cert)
iex> saml_response = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9sb2NhbC5tYnguY29tOjQwMDEvYXV0aC9zYW1sL3NzbyIgSUQ9Il81MWM2NWM4ZTNlZGNjNDE3Zjc2NDBiZDkwNWI0M2UyMDE3Mjg5MzMxNDE2NjkiIElzc3VlSW5zdGFudD0iMjAyNC0xMC0xNFQxOToxMjoyMS42NjlaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwczovL2FoZWFkLm15LnNhbGVzZm9yY2UuY29tPC9zYW1sMjpJc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxkczpSZWZlcmVuY2UgVVJJPSIjXzUxYzY1YzhlM2VkY2M0MTdmNzY0MGJkOTA1YjQzZTIwMTcyODkzMzE0MTY2OSI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyI+PGVjOkluY2x1c2l2ZU5hbWVzcGFjZXMgeG1sbnM6ZWM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIgUHJlZml4TGlzdD0ieHNkIi8+PC9kczpUcmFuc2Zvcm0+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNzaGEyNTYiLz48ZHM6RGlnZXN0VmFsdWU+TWEvVkNmcUpKK0hOeDk0SWsyQ0JpSU9aVmpVVDlaT05NaTlTUkZ6WHhpWT08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6U2lnbmF0dXJlVmFsdWU+WTVMcFlTSjhsUWtKbjIrZFZOTTEvSk5DcStScm9qYlJldTFiUlhPR1hHeWhnU241UnVnNlVqeDIzaCtRSTlDckJwcGRtVFNJZW5jd2dhWjJkcDJJa1FJejZmdFJjUXhZL3FNRGgxOEIzd0hhbzVnWDRQVytVSFlrZ3NZS1drZUg5ZDRCclRCeW0zVjZPZ2tSMitCbDRNM0todlVMRGd6MGNlWGdYMmNqUVJ6KzBZQnVOV1YrNE5QM3ZqKzVKUktlK1R6SjMycnQ5UktxTnNBay9FQjJCa2JzN0ZZMHNnbGJCZmFidCtNVG5qQnN1ZzJEdWI1V3dXVkEybVRra2VLZGhWcmFNVDlRT3p1UmFuekY0SjZqQyt4QStFM3U0WjFuVVdXZWZxRzc4enBCUEN3MlY1dzV1ZXd3a0lQMjZ0SWRSZm1TV29sOXhTZnpkY1pPU2taVFJyd083VFF4THB1c0pydHh3TGZXZWd0SUJvYXFVS1Y4LzRLaERzdHZQS2hkL0tVb3hnOUZ0VzRiUjZMSWNGWG9QbGJUQ1JZbEdDYlI0S1Zka0xlNUErd0hIRmdtMktFdldZeTBDZElpbWsvckY4RzRuUjRaM1pSWWh3V3V6QzlDcEI5WGVjbzVSV2xZN0huaHlHWkZlWktPYnlZQURDUWYxY0NxK3Z4SFlnc0xTeEFiWUdad2ZEWlVieURvQ2pRb2piZVBjNGl2WXBOR3JhMWpoZHl4THFzcVlhS1kra0VMTEJCUnR2Vmcvdy8vSTFNKzV2SGM2VUZxWkhBZFBUWTRBZ0g2RUNjUFA0dThWN09nbW5DK1BUazBxdkY1NHZnVUlFZllRUFQ4T2ZnMWs3a3k2d2ZEaENHNWNMaDhrTU1Fb1BnMUtBTnF4ZUpKN0pja3B5M2lzR289PC9kczpTaWduYXR1cmVWYWx1ZT48ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlHaWpDQ0JIS2dBd0lCQWdJT0FZL2xwd0h1QUFBQUFFRHhqRmd3RFFZSktvWklodmNOQVFFTEJRQXdnWVV4SFRBYkJnTlZCQU1NCkZGQm9iMlZ1YVhoZlUyVnNabE5wWjI1RFpYSjBNUmd3RmdZRFZRUUxEQTh3TUVSaGJUQXdNREF3U1hsd2FtWXhGekFWQmdOVkJBb00KRGxOaGJHVnpabTl5WTJVdVkyOXRNUll3RkFZRFZRUUhEQTFUWVc0Z1JuSmhibU5wYzJOdk1Rc3dDUVlEVlFRSURBSkRRVEVNTUFvRwpBMVVFQmhNRFZWTkJNQjRYRFRJME1EWXdOREl6TkRjMU9Gb1hEVEkyTURZd05ERXlNREF3TUZvd2dZVXhIVEFiQmdOVkJBTU1GRkJvCmIyVnVhWGhmVTJWc1psTnBaMjVEWlhKME1SZ3dGZ1lEVlFRTERBOHdNRVJoYlRBd01EQXdTWGx3YW1ZeEZ6QVZCZ05WQkFvTURsTmgKYkdWelptOXlZMlV1WTI5dE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVFzd0NRWURWUVFJREFKRFFURU1NQW9HQTFVRQpCaE1EVlZOQk1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBbG51dXFOOHRnY3NSR0k2bjRBMDhGK29uCjcyOWU0ZE9lZXZJb1BkbTFHc29GTFh3VUwrRUI2UHpiaHBmR0N6RFZ2YlZvUUxlZ01lUko4UFIwZzAxUjZSS0RubDl2VnlCc0xpQ2EKbHdaZnQ4TUdWamVOMktRWWRscEhHeDNlZXJwNTl3cEkySHk2aStnc2V0OHRURGtmaHFQQm5hSVRLTG1uYW5ZMDhRUUhxTlhDdEY5MQp1M3lyZ0ZBU1lmQlpLekE2ekZqNHJCNzdTS2VKUkt0UXlnYUxaUXdyRW9XakJqNkMyQWRzbWZKNFJkVFVJQXpndHA2am11Qi9jN0Z0CmVXbmhVODVEb1BTZlFXeUtxZDdLRlN4ZndjMnUvU2kvajZONHZoZ1phSEdsZVdZNk4ybWhQZW05Mk05dDBmL3A3dnBMN3h0NHh4TlAKTnF6QmRnOHJuaUlLazFLZmFCMERqbFZ4dXVranRRVCsvdm5sdkJnMW5nOFUrSFk0YVcxekRmaEt3THJxYjFaK25lcWN2V2dWaDU1SQpzdVRaZXdGSDl2ZDY5S1RjOWNDN05yMWJ5ZzhxWTF2TEc2eVdSVks3V1RTWnZ6dGtrRTQxMEdHaDZqZjduZ2VvaldkK09iMlN3T1NnClRDNnlKWEN0dFVNczgrR0tVeDYrYURXYkZQanl5b2lIcktxQXFuSFVMdlJZcVdLblFLa0dabWVhWWFKbE1IdlI4T1d6emx6TnNLdmwKWXZ1cG9KdXFOTTJTcElDMEpxMjdraUtXYS93NEZNbEJKcVIrMUQ3dG9hOGV0eXZpZ1VDTFNzNDhORjZieWkwVmo3TENMSXN0cnpCbgo2eTBwNDl0RHpLWWU2TEVZd0U1dnlBdTM3QlAxTVNtV2RCSnZ6M3BRaVFmNU1pRzRDNzhDQXdFQUFhT0I5VENCOGpBZEJnTlZIUTRFCkZnUVVzc2hLZFRvc3FNeWFqY3EvWUo1ZnEvZWwxOW93RHdZRFZSMFRBUUgvQkFVd0F3RUIvekNCdndZRFZSMGpCSUczTUlHMGdCU3kKeUVwMU9peW96SnFOeXI5Z25sK3I5NlhYMnFHQmk2U0JpRENCaFRFZE1Cc0dBMVVFQXd3VVVHaHZaVzVwZUY5VFpXeG1VMmxuYmtObApjblF4R0RBV0JnTlZCQXNNRHpBd1JHRnRNREF3TURCSmVYQnFaakVYTUJVR0ExVUVDZ3dPVTJGc1pYTm1iM0pqWlM1amIyMHhGakFVCkJnTlZCQWNNRFZOaGJpQkdjbUZ1WTJselkyOHhDekFKQmdOVkJBZ01Ba05CTVF3d0NnWURWUVFHRXdOVlUwR0NEZ0dQNWFjQjdnQUEKQUFCQThZeFlNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUNBUUFQSC9Gc2RPVDNjMFdRSXFSalZMNkczdEVoV1R0L2JXK3RnOG4rajhJagpycG1QaElSOFNJbEN3cVNrTzhoMFJrSTRmWXBGbG50UEJLREVWekF4M3p5NVdMK1RKbEkzRTJ0Y1FCUUQxRVpmY1crbE8rZndrSDRWCklXSHYxbzJ6aGVKbkJFQVBLclhqTDY3a3M3TnFGYkM1a1oxS1QzOUFkOGVJV0gyT1o5N3dZTldtV3RLYXFWNjlZanVxWEFjeVd1N00KeVovakxMSTJoWkZEand4UW9wRnVlRTAzMmpQVkZGM0txYjk5RGxCRE5rSVpSVXdBeEZPWmJZZUljcncrWkl6MG4rVWg1OXdrSEE0aQpicFpRanhpN0JscEtuMmVUTEdUTjlHNHYxRE5SbDJjcWxMcm5jUDduMWlOaG1YZW9nd0p3K3VKRUFWWk5mb01OM2lIRnRLSHVVMnpYCkpaOHd6ZmF1ZHgxUW8vUEF2djFTREM1b2tIZllwL2dOZWtxOGpHY1FLRVAwUTU3SmVWRFlTRWR3R1plYUg3N25xWlBvM0NXNk1CQXcKdkV6dThlbmNBTEQvRlpTNlFCeG1YRW1QM3o2VlgrOVI1V1owQzFFbVdwUy85L29hVkV2RitVUHJRajhXcTJGYk94bXVCWVE4cGFPawpGamU0VUcxK3Jyd3FmQU13cHlOL0UvVXZERlM0QmtqRGUvR0JRZVBHMjBlaVd0S1U2Q2t0TDNacm00bEpVYlROdDcvM3llb1M1V3c0CllNM3Y3bnYzUFRTQ1o2TEc2M3Bvb2RoZ3ZnTXYwQzdvRVhJSG84K2xZemlHS1Z4d1dCaFp2SFZrYzc4OXdCRzQwT2tuLytETXUyVWYKR2Y2NDFZNXhDOW1NVklFVXh2MUI0eEx4aWJ2dTdQa3pFUT09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWwycDpTdGF0dXM+PHNhbWwycDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWwycDpTdGF0dXM+PHNhbWwyOkFzc2VydGlvbiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Il9jOTg5NGZhNzAxZjUxM2M2ZmE1MzU4MWQ3MTkwMDExMzE3Mjg5MzMxNDE2NjkiIElzc3VlSW5zdGFudD0iMjAyNC0xMC0xNFQxOToxMjoyMS42NjlaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxzYW1sMjpJc3N1ZXIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkiPmh0dHBzOi8vYWhlYWQubXkuc2FsZXNmb3JjZS5jb208L3NhbWwyOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2Ii8+PGRzOlJlZmVyZW5jZSBVUkk9IiNfYzk4OTRmYTcwMWY1MTNjNmZhNTM1ODFkNzE5MDAxMTMxNzI4OTMzMTQxNjY5Ij48ZHM6VHJhbnNmb3Jtcz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnI2VudmVsb3BlZC1zaWduYXR1cmUiLz48ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIj48ZWM6SW5jbHVzaXZlTmFtZXNwYWNlcyB4bWxuczplYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIiBQcmVmaXhMaXN0PSJ4c2QiLz48L2RzOlRyYW5zZm9ybT48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT5idmk5V2ZMRzdMS254ZTNydjdIMFNZZ25wMGpEUW9aTXlmZW1KcTJNU084PTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5BdWRVQlByYU1aaUxkVEJjTlh4NXlYaDBVMHZwaERSeDVLaVpMTlN1U2JxMXo5ODBwNUtBdUJzc1dxRVhZUVhSeDM3U1NVZGxGMEFjZ1NabzNUektUREt1eWoyOHJUckxzdTZWY01XcFZJRGpHQm9DaVNVRTZFZ0FLYUlWTDlNRUR1cklzLzVIZG1uVjJUa2haUUMxTmFJcGt0YWR4TW9MKzI5bkllbHhsREVWenVmYjB3ZFJXSE14TjJ0dDNTamQvRVpBdmZhd0Z3cVU4WVE2ckhEWnEvemZ5MDV4S3BxM3FuNGxDcjkycU84L0dnWVVLMVNBbjNPaWVBK0FWdnZhUExaVEwwSnI3RlN3WDlxaXgwNkEwOER3UmpITk10alk3bVFaWmo4SFVaa2oyRmxQWFl5cXA4OEFNMzE3N0RGWWtvMnloejN2cUhJUUFqWWZOckl5ZXNXb0pMUng0QmRkR2ZWSFBwNnFya0RTVVg1cXIreWFRKzRTd0pTQ0Nua3FGMmk2aWFpTWJvbStBZ2xmNkRERTJPZEtMbU9IOFI4V0ZYak41SHdhandxd2xBTUV5eEpyL0tVRzZVOVFOdlFVRzBjZ2x1dHk1NlA2dXd0anZ6RU1keW5UR2JuTGczczdGbFJxUkhRWDBjNnVBM3E0L1F1cFBiV3NZd0xZUmtQOHUzajNtYzJBZkNveVNaYWgwcXl0UmdQR3kvQmRZNHJzZkJlMDdtdkdHcmdJbHQyQU5hRDJ1SDl2QkhqZW9vT2JWVFUwSHJocmtXbEZkWTh3UkFWT2JQZ3gxb1c2eXpBeVdvTllnbFpISUcrNDB0T2d6L3Jzc3hpaEF5a0hVc1BENlludDJvM3F5NGpVS3ZibEI0dmpmWXV0a240RitnNm1HT0d1cTRvc0Erdz08L2RzOlNpZ25hdHVyZVZhbHVlPjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUdpakNDQkhLZ0F3SUJBZ0lPQVkvbHB3SHVBQUFBQUVEeGpGZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dZVXhIVEFiQmdOVkJBTU0KRkZCb2IyVnVhWGhmVTJWc1psTnBaMjVEWlhKME1SZ3dGZ1lEVlFRTERBOHdNRVJoYlRBd01EQXdTWGx3YW1ZeEZ6QVZCZ05WQkFvTQpEbE5oYkdWelptOXlZMlV1WTI5dE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVFzd0NRWURWUVFJREFKRFFURU1NQW9HCkExVUVCaE1EVlZOQk1CNFhEVEkwTURZd05ESXpORGMxT0ZvWERUSTJNRFl3TkRFeU1EQXdNRm93Z1lVeEhUQWJCZ05WQkFNTUZGQm8KYjJWdWFYaGZVMlZzWmxOcFoyNURaWEowTVJnd0ZnWURWUVFMREE4d01FUmhiVEF3TURBd1NYbHdhbVl4RnpBVkJnTlZCQW9NRGxOaApiR1Z6Wm05eVkyVXVZMjl0TVJZd0ZBWURWUVFIREExVFlXNGdSbkpoYm1OcGMyTnZNUXN3Q1FZRFZRUUlEQUpEUVRFTU1Bb0dBMVVFCkJoTURWVk5CTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFsbnV1cU44dGdjc1JHSTZuNEEwOEYrb24KNzI5ZTRkT2VldklvUGRtMUdzb0ZMWHdVTCtFQjZQemJocGZHQ3pEVnZiVm9RTGVnTWVSSjhQUjBnMDFSNlJLRG5sOXZWeUJzTGlDYQpsd1pmdDhNR1ZqZU4yS1FZZGxwSEd4M2VlcnA1OXdwSTJIeTZpK2dzZXQ4dFREa2ZocVBCbmFJVEtMbW5hblkwOFFRSHFOWEN0RjkxCnUzeXJnRkFTWWZCWkt6QTZ6Rmo0ckI3N1NLZUpSS3RReWdhTFpRd3JFb1dqQmo2QzJBZHNtZko0UmRUVUlBemd0cDZqbXVCL2M3RnQKZVduaFU4NURvUFNmUVd5S3FkN0tGU3hmd2MydS9TaS9qNk40dmhnWmFIR2xlV1k2TjJtaFBlbTkyTTl0MGYvcDd2cEw3eHQ0eHhOUApOcXpCZGc4cm5pSUtrMUtmYUIwRGpsVnh1dWtqdFFUKy92bmx2Qmcxbmc4VStIWTRhVzF6RGZoS3dMcnFiMVorbmVxY3ZXZ1ZoNTVJCnN1VFpld0ZIOXZkNjlLVGM5Y0M3TnIxYnlnOHFZMXZMRzZ5V1JWSzdXVFNadnp0a2tFNDEwR0doNmpmN25nZW9qV2QrT2IyU3dPU2cKVEM2eUpYQ3R0VU1zOCtHS1V4NithRFdiRlBqeXlvaUhyS3FBcW5IVUx2UllxV0tuUUtrR1ptZWFZYUpsTUh2UjhPV3p6bHpOc0t2bApZdnVwb0p1cU5NMlNwSUMwSnEyN2tpS1dhL3c0Rk1sQkpxUisxRDd0b2E4ZXR5dmlnVUNMU3M0OE5GNmJ5aTBWajdMQ0xJc3RyekJuCjZ5MHA0OXREektZZTZMRVl3RTV2eUF1MzdCUDFNU21XZEJKdnozcFFpUWY1TWlHNEM3OENBd0VBQWFPQjlUQ0I4akFkQmdOVkhRNEUKRmdRVXNzaEtkVG9zcU15YWpjcS9ZSjVmcS9lbDE5b3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96Q0J2d1lEVlIwakJJRzNNSUcwZ0JTeQp5RXAxT2l5b3pKcU55cjlnbmwrcjk2WFgycUdCaTZTQmlEQ0JoVEVkTUJzR0ExVUVBd3dVVUdodlpXNXBlRjlUWld4bVUybG5ia05sCmNuUXhHREFXQmdOVkJBc01EekF3UkdGdE1EQXdNREJKZVhCcVpqRVhNQlVHQTFVRUNnd09VMkZzWlhObWIzSmpaUzVqYjIweEZqQVUKQmdOVkJBY01EVk5oYmlCR2NtRnVZMmx6WTI4eEN6QUpCZ05WQkFnTUFrTkJNUXd3Q2dZRFZRUUdFd05WVTBHQ0RnR1A1YWNCN2dBQQpBQUJBOFl4WU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQVBIL0ZzZE9UM2MwV1FJcVJqVkw2RzN0RWhXVHQvYlcrdGc4bitqOElqCnJwbVBoSVI4U0lsQ3dxU2tPOGgwUmtJNGZZcEZsbnRQQktERVZ6QXgzenk1V0wrVEpsSTNFMnRjUUJRRDFFWmZjVytsTytmd2tINFYKSVdIdjFvMnpoZUpuQkVBUEtyWGpMNjdrczdOcUZiQzVrWjFLVDM5QWQ4ZUlXSDJPWjk3d1lOV21XdEthcVY2OVlqdXFYQWN5V3U3TQp5Wi9qTExJMmhaRkRqd3hRb3BGdWVFMDMyalBWRkYzS3FiOTlEbEJETmtJWlJVd0F4Rk9aYlllSWNydytaSXowbitVaDU5d2tIQTRpCmJwWlFqeGk3QmxwS24yZVRMR1ROOUc0djFETlJsMmNxbExybmNQN24xaU5obVhlb2d3SncrdUpFQVZaTmZvTU4zaUhGdEtIdVUyelgKSlo4d3pmYXVkeDFRby9QQXZ2MVNEQzVva0hmWXAvZ05la3E4akdjUUtFUDBRNTdKZVZEWVNFZHdHWmVhSDc3bnFaUG8zQ1c2TUJBdwp2RXp1OGVuY0FMRC9GWlM2UUJ4bVhFbVAzejZWWCs5UjVXWjBDMUVtV3BTLzkvb2FWRXZGK1VQclFqOFdxMkZiT3htdUJZUThwYU9rCkZqZTRVRzErcnJ3cWZBTXdweU4vRS9VdkRGUzRCa2pEZS9HQlFlUEcyMGVpV3RLVTZDa3RMM1pybTRsSlViVE50Ny8zeWVvUzVXdzQKWU0zdjdudjNQVFNDWjZMRzYzcG9vZGhndmdNdjBDN29FWElIbzgrbFl6aUdLVnh3V0JoWnZIVmtjNzg5d0JHNDBPa24vK0RNdTJVZgpHZjY0MVk1eEM5bU1WSUVVeHYxQjR4THhpYnZ1N1BrekVRPT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbDI6U3ViamVjdD48c2FtbDI6TmFtZUlEIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6ZW1haWxBZGRyZXNzIj5kai5qYWluLmFkbWluQGFoZWFkLmNvbS5yc2llcDwvc2FtbDI6TmFtZUlEPjxzYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+PHNhbWwyOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAyNC0xMC0xNFQxOToxNzoyMS42NjlaIiBSZWNpcGllbnQ9Imh0dHBzOi8vbG9jYWwubWJ4LmNvbTo0MDAxL2F1dGgvc2FtbC9zc28iLz48L3NhbWwyOlN1YmplY3RDb25maXJtYXRpb24+PC9zYW1sMjpTdWJqZWN0PjxzYW1sMjpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyNC0xMC0xNFQxOToxMTo1MS42NjlaIiBOb3RPbk9yQWZ0ZXI9IjIwMjQtMTAtMTRUMTk6MTc6MjEuNjY5WiI+PHNhbWwyOkF1ZGllbmNlUmVzdHJpY3Rpb24+PHNhbWwyOkF1ZGllbmNlPmh0dHBzOi8vbG9jYWwubWJ4LmNvbTozMDAxL21Nem0yWkRBVExFTVBXYWVxUGRmSGZpdFpSWTwvc2FtbDI6QXVkaWVuY2U+PC9zYW1sMjpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDI6Q29uZGl0aW9ucz48c2FtbDI6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDI0LTEwLTE0VDE5OjEyOjIxLjY2OVoiPjxzYW1sMjpBdXRobkNvbnRleHQ+PHNhbWwyOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOnVuc3BlY2lmaWVkPC9zYW1sMjpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWwyOkF1dGhuQ29udGV4dD48L3NhbWwyOkF1dGhuU3RhdGVtZW50PjxzYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJ1c2VySWQiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dW5zcGVjaWZpZWQiPjxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHNkOmFueVR5cGUiPjAwNVdyMDAwMDA1ME14ajwvc2FtbDI6QXR0cmlidXRlVmFsdWU+PC9zYW1sMjpBdHRyaWJ1dGU+PHNhbWwyOkF0dHJpYnV0ZSBOYW1lPSJ1c2VybmFtZSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1bnNwZWNpZmllZCI+PHNhbWwyOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4c2Q6YW55VHlwZSI+ZGouamFpbi5hZG1pbkBhaGVhZC5jb20ucnNpZXA8L3NhbWwyOkF0dHJpYnV0ZVZhbHVlPjwvc2FtbDI6QXR0cmlidXRlPjxzYW1sMjpBdHRyaWJ1dGUgTmFtZT0iZW1haWwiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dW5zcGVjaWZpZWQiPjxzYW1sMjpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6dHlwZT0ieHNkOmFueVR5cGUiPmRqLmphaW5AYWhlYWQuY29tPC9zYW1sMjpBdHRyaWJ1dGVWYWx1ZT48L3NhbWwyOkF0dHJpYnV0ZT48c2FtbDI6QXR0cmlidXRlIE5hbWU9ImlzX3BvcnRhbF91c2VyIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVuc3BlY2lmaWVkIj48c2FtbDI6QXR0cmlidXRlVmFsdWUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnR5cGU9InhzZDphbnlUeXBlIj5mYWxzZTwvc2FtbDI6QXR0cmlidXRlVmFsdWU+PC9zYW1sMjpBdHRyaWJ1dGU+PC9zYW1sMjpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PC9zYW1sMjpBc3NlcnRpb24+PC9zYW1sMnA6UmVzcG9uc2U+"
iex> {:ok, saml_body} = saml_response |> Base.decode64()
iex> {:ok, root} = SimpleXml.parse(saml_body)
iex> SimpleXml.verify(root, public_key)
:ok

Verification fails if the digest doesn't match the expected value

iex> cert_der = ~S(MIIDqDCCApCgAwIBAgIGAYj8lAYkMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA2MjcxMTE3NTlaFw0zMzA2MjcxMTE4NTlaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTE7IRG+oQZBASQ7DY3yeTrwABdI2BgG2FXKSkTPk9enMwtyUyDXCOteOg18+//MA2UTvgSI+n0fiAh7Bi7cxpimnOaj/kcgvpdn+5wpEfSIDKAeEg9VIQf0fz/ks4XkrNxRh8ba6Z/ypOVR2TLozu8v6sjGCiqHSoiPl78KINHx9jMB3QGdTHRxsTzwFPGcUEvO7XvjxxMN9FLZdHkwtA6cZXDbHlAv+o4EbLIRqXFc3vF5rs3Fz+cgqZ3HVGm90TFFcbPbx/eKcvzyHdYt8P5pi364mijt9NKtNV9F9VdPz+Gp/rxlw0i/IWxV0/vBrW10HPd42krsOgHibxBYg8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEArpYzZEoYcRo3YF7Ny4gdc8ODSlPPKIdLvwhUTGbPdzJU2ifxzE/KeTHGmFpjpakjDmmWsr2j9FGU/9U0SjqPmJHP5gYbjmz+tD3jeaEkIBDZpcYc+MveQaA7uDMILA2OUhHuFu0UJVjGxl2EIpxivC+IJ0RpBS5AERT6V91Fqv2Ylwb5sklhoXGDx9s+l+Ud1MLaewIvnUHdIRtC02bvlhjwt0pnICDtHMikvOiTXjTBJgl7X9Q51Gm636q9pJVjS1T0gR3cNt9JJE/foDdOK8JozRFtF4j14xegXLt7BVBIXuSOK6P1c09mCPQ1VJbcj01S1zfrvZ+RZvrxr/0aXQ==)
iex> {:ok, cert} = cert_der |> Base.decode64!() |> X509.Certificate.from_der()
iex> public_key = X509.Certificate.public_key(cert)
iex> saml_response = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsLm1ieC5jb206NDAwMS9hdXRoL2FoZWFkL3NzbyIgSUQ9ImlkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGthNWhhNmJrblk2T2tkODVkNzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT5CQURfRElHRVNUPC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPmczV0hpdkJHaFBzTWEwMzBoOUJVSUFXYUVyQVdkMjh1RGpCVUhST1ErZWhLd2pxeGtDUGxjNFpVd3JGK2duRm13Mmx0ODFucHBvNVUwRVNtbi9BR0o2MEoyMFp4VlJnanNaeEsxQWhWcXI0MHUwd0E2ZjZqQ0ppSlduYnFJR1dYRFh5aWtXTzAvNHJxT2REOXdQOER3MlBtaW8yK3ZNc05JbHBOeXUyeW9BejJ1c2xuL3ZGZVNZdFk1bUswOTV4N3dVY0hhVzBvY1pwT1VMRERqU2IwcUdOOFY3V2dKdkZoSFBxRGJOcEcxMVJCY1pzRXFGdWxhR3p2MlB1dTloRHl1K1owSE5xVDArM0YwSTFUaW5NSkczM1BxczJSc29rQ1pMeHoyR0I0d2pkcE5UUk5NN0o3aWg3THk3ZjlrZE9NYUxtKzZjOTE3em4zYkpQN1Y5R2I5Zz09PC9kczpTaWduYXR1cmVWYWx1ZT48ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEcURDQ0FwQ2dBd0lCQWdJR0FZajhsQVlrTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdVTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHCkExVUVDQXdLUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnd3TlUyRnVJRVp5WVc1amFYTmpiekVOTUFzR0ExVUVDZ3dFVDJ0MFlURVUKTUJJR0ExVUVDd3dMVTFOUFVISnZkbWxrWlhJeEZUQVRCZ05WQkFNTURHUmxkaTAwTlRNME9Ua3dOakVjTUJvR0NTcUdTSWIzRFFFSgpBUllOYVc1bWIwQnZhM1JoTG1OdmJUQWVGdzB5TXpBMk1qY3hNVEUzTlRsYUZ3MHpNekEyTWpjeE1URTROVGxhTUlHVU1Rc3dDUVlEClZRUUdFd0pWVXpFVE1CRUdBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0cKQTFVRUNnd0VUMnQwWVRFVU1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFYwpNQm9HQ1NxR1NJYjNEUUVKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DCmdnRUJBTFRFN0lSRytvUVpCQVNRN0RZM3llVHJ3QUJkSTJCZ0cyRlhLU2tUUGs5ZW5Nd3R5VXlEWENPdGVPZzE4Ky8vTUEyVVR2Z1MKSStuMGZpQWg3Qmk3Y3hwaW1uT2FqL2tjZ3ZwZG4rNXdwRWZTSURLQWVFZzlWSVFmMGZ6L2tzNFhrck54Umg4YmE2Wi95cE9WUjJUTApvenU4djZzakdDaXFIU29pUGw3OEtJTkh4OWpNQjNRR2RUSFJ4c1R6d0ZQR2NVRXZPN1h2anh4TU45RkxaZEhrd3RBNmNaWERiSGxBCnYrbzRFYkxJUnFYRmMzdkY1cnMzRnorY2dxWjNIVkdtOTBURkZjYlBieC9lS2N2enlIZFl0OFA1cGkzNjRtaWp0OU5LdE5WOUY5VmQKUHorR3AvcnhsdzBpL0lXeFYwL3ZCclcxMEhQZDQya3JzT2dIaWJ4QllnOENBd0VBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQQpycFl6WkVvWWNSbzNZRjdOeTRnZGM4T0RTbFBQS0lkTHZ3aFVUR2JQZHpKVTJpZnh6RS9LZVRIR21GcGpwYWtqRG1tV3NyMmo5RkdVCi85VTBTanFQbUpIUDVnWWJqbXordEQzamVhRWtJQkRacGNZYytNdmVRYUE3dURNSUxBMk9VaEh1RnUwVUpWakd4bDJFSXB4aXZDK0kKSjBScEJTNUFFUlQ2VjkxRnF2Mllsd2I1c2tsaG9YR0R4OXMrbCtVZDFNTGFld0l2blVIZElSdEMwMmJ2bGhqd3QwcG5JQ0R0SE1pawp2T2lUWGpUQkpnbDdYOVE1MUdtNjM2cTlwSlZqUzFUMGdSM2NOdDlKSkUvZm9EZE9LOEpvelJGdEY0ajE0eGVnWEx0N0JWQklYdVNPCks2UDFjMDltQ1BRMVZKYmNqMDFTMXpmcnZaK1JadnJ4ci8wYVhRPT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbDJwOlN0YXR1cyB4bWxuczpzYW1sMnA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCI+PHNhbWwycDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWwycDpTdGF0dXM+PHNhbWwyOkFzc2VydGlvbiBJRD0iaWQyNzc4NDA0Nzg4Nzc4NDcyODIxMTkzMTg5NSIgSXNzdWVJbnN0YW50PSIyMDIzLTA3LTEwVDEzOjQwOjI5LjY1OFoiIFZlcnNpb249IjIuMCIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPjxzYW1sMjpJc3N1ZXIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj5odHRwOi8vd3d3Lm9rdGEuY29tL2V4a2E1aGE2YmtuWTZPa2Q4NWQ3PC9zYW1sMjpJc3N1ZXI+PGRzOlNpZ25hdHVyZSB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PGRzOlNpZ25lZEluZm8+PGRzOkNhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxkczpSZWZlcmVuY2UgVVJJPSIjaWQyNzc4NDA0Nzg4Nzc4NDcyODIxMTkzMTg5NSI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8+PGRzOkRpZ2VzdFZhbHVlPjZvdm13cFY2TTRsd0FDcEZnS2pWbSs2VnlTS3R0T2JVMXZja29mVVZrZkE9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPlB0aEtwbVNjaTc5N0RETG9NdHVNQkc2OC9vNmVwMVJJbFlHRGFFVHpDUTVrRlR2ZDcxYndFamM5aXZRV2VTdUczVThpQzZMdC83SGZYSlRUMEt5aS9TaVprekhmSXVsSUptNVBOb2Z6ZXV1dUVBWXIwUGh5SmJ2QkdSTjhFYXRQTDBWM2x2WE8xT1hodzFTaW1iUzBkR2hCR0IzWi80Sm1qM0EwZ0ZubHlOSk4vNzh4WCtiUHV4Qkt4UVhwVjlNMTBOcktFRitvNzVNUDdubjE5bkozTTZsb3dIQUdndGFEWDl1M0ZhMncvOHhBcUZOdDY0d1owRFBhaW1BaXREUEp2dEgvdVU3eTRybWVSK3Rxemp2c0dHcG04M2M1U3N3V0RnWnhqUENJV0dFVFpVV0dDRHBvblZXN1RHQm40NHhvVllQSERFK0lxYnJYN1RVcjJIUWhQZz09PC9kczpTaWduYXR1cmVWYWx1ZT48ZHM6S2V5SW5mbz48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEcURDQ0FwQ2dBd0lCQWdJR0FZajhsQVlrTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdVTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHCkExVUVDQXdLUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnd3TlUyRnVJRVp5WVc1amFYTmpiekVOTUFzR0ExVUVDZ3dFVDJ0MFlURVUKTUJJR0ExVUVDd3dMVTFOUFVISnZkbWxrWlhJeEZUQVRCZ05WQkFNTURHUmxkaTAwTlRNME9Ua3dOakVjTUJvR0NTcUdTSWIzRFFFSgpBUllOYVc1bWIwQnZhM1JoTG1OdmJUQWVGdzB5TXpBMk1qY3hNVEUzTlRsYUZ3MHpNekEyTWpjeE1URTROVGxhTUlHVU1Rc3dDUVlEClZRUUdFd0pWVXpFVE1CRUdBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0cKQTFVRUNnd0VUMnQwWVRFVU1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFYwpNQm9HQ1NxR1NJYjNEUUVKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DCmdnRUJBTFRFN0lSRytvUVpCQVNRN0RZM3llVHJ3QUJkSTJCZ0cyRlhLU2tUUGs5ZW5Nd3R5VXlEWENPdGVPZzE4Ky8vTUEyVVR2Z1MKSStuMGZpQWg3Qmk3Y3hwaW1uT2FqL2tjZ3ZwZG4rNXdwRWZTSURLQWVFZzlWSVFmMGZ6L2tzNFhrck54Umg4YmE2Wi95cE9WUjJUTApvenU4djZzakdDaXFIU29pUGw3OEtJTkh4OWpNQjNRR2RUSFJ4c1R6d0ZQR2NVRXZPN1h2anh4TU45RkxaZEhrd3RBNmNaWERiSGxBCnYrbzRFYkxJUnFYRmMzdkY1cnMzRnorY2dxWjNIVkdtOTBURkZjYlBieC9lS2N2enlIZFl0OFA1cGkzNjRtaWp0OU5LdE5WOUY5VmQKUHorR3AvcnhsdzBpL0lXeFYwL3ZCclcxMEhQZDQya3JzT2dIaWJ4QllnOENBd0VBQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQQpycFl6WkVvWWNSbzNZRjdOeTRnZGM4T0RTbFBQS0lkTHZ3aFVUR2JQZHpKVTJpZnh6RS9LZVRIR21GcGpwYWtqRG1tV3NyMmo5RkdVCi85VTBTanFQbUpIUDVnWWJqbXordEQzamVhRWtJQkRacGNZYytNdmVRYUE3dURNSUxBMk9VaEh1RnUwVUpWakd4bDJFSXB4aXZDK0kKSjBScEJTNUFFUlQ2VjkxRnF2Mllsd2I1c2tsaG9YR0R4OXMrbCtVZDFNTGFld0l2blVIZElSdEMwMmJ2bGhqd3QwcG5JQ0R0SE1pawp2T2lUWGpUQkpnbDdYOVE1MUdtNjM2cTlwSlZqUzFUMGdSM2NOdDlKSkUvZm9EZE9LOEpvelJGdEY0ajE0eGVnWEx0N0JWQklYdVNPCks2UDFjMDltQ1BRMVZKYmNqMDFTMXpmcnZaK1JadnJ4ci8wYVhRPT08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbDI6U3ViamVjdCB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+PHNhbWwyOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj5kai5qYWluPC9zYW1sMjpOYW1lSUQ+PHNhbWwyOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6Y206YmVhcmVyIj48c2FtbDI6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDIzLTA3LTEwVDEzOjQ1OjI5LjY1OVoiIFJlY2lwaWVudD0iaHR0cHM6Ly9sb2NhbC5tYnguY29tOjQwMDEvYXV0aC9haGVhZC9zc28iLz48L3NhbWwyOlN1YmplY3RDb25maXJtYXRpb24+PC9zYW1sMjpTdWJqZWN0PjxzYW1sMjpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMy0wNy0xMFQxMzozNToyOS42NTlaIiBOb3RPbk9yQWZ0ZXI9IjIwMjMtMDctMTBUMTM6NDU6MjkuNjU5WiIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPjxzYW1sMjpBdWRpZW5jZVJlc3RyaWN0aW9uPjxzYW1sMjpBdWRpZW5jZT54cU81MkNORUxkMGhWQjl2YVgxZF9kY3d1WUF4R1VTcjwvc2FtbDI6QXVkaWVuY2U+PC9zYW1sMjpBdWRpZW5jZVJlc3RyaWN0aW9uPjwvc2FtbDI6Q29uZGl0aW9ucz48c2FtbDI6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIzLTA3LTEwVDEzOjQwOjI5LjY1OFoiIFNlc3Npb25JbmRleD0iaWQxNjg4OTk2NDI5NjU3LjExNDUwMzIwMTIiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDI6QXV0aG5Db250ZXh0PjxzYW1sMjpBdXRobkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZFByb3RlY3RlZFRyYW5zcG9ydDwvc2FtbDI6QXV0aG5Db250ZXh0Q2xhc3NSZWY+PC9zYW1sMjpBdXRobkNvbnRleHQ+PC9zYW1sMjpBdXRoblN0YXRlbWVudD48L3NhbWwyOkFzc2VydGlvbj48L3NhbWwycDpSZXNwb25zZT4="
iex> {:ok, saml_body} = saml_response |> Base.decode64()
iex> {:ok, root} = SimpleXml.parse(saml_body)
iex> SimpleXml.verify(root, public_key)
{:error, :digest_verification_failed}

Verification fails if the signature doesn't match the expected value

iex> cert_der = ~S(MIIDqDCCApCgAwIBAgIGAYj8lAYkMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTAeFw0yMzA2MjcxMTE3NTlaFw0zMzA2MjcxMTE4NTlaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi00NTM0OTkwNjEcMBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTE7IRG+oQZBASQ7DY3yeTrwABdI2BgG2FXKSkTPk9enMwtyUyDXCOteOg18+//MA2UTvgSI+n0fiAh7Bi7cxpimnOaj/kcgvpdn+5wpEfSIDKAeEg9VIQf0fz/ks4XkrNxRh8ba6Z/ypOVR2TLozu8v6sjGCiqHSoiPl78KINHx9jMB3QGdTHRxsTzwFPGcUEvO7XvjxxMN9FLZdHkwtA6cZXDbHlAv+o4EbLIRqXFc3vF5rs3Fz+cgqZ3HVGm90TFFcbPbx/eKcvzyHdYt8P5pi364mijt9NKtNV9F9VdPz+Gp/rxlw0i/IWxV0/vBrW10HPd42krsOgHibxBYg8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEArpYzZEoYcRo3YF7Ny4gdc8ODSlPPKIdLvwhUTGbPdzJU2ifxzE/KeTHGmFpjpakjDmmWsr2j9FGU/9U0SjqPmJHP5gYbjmz+tD3jeaEkIBDZpcYc+MveQaA7uDMILA2OUhHuFu0UJVjGxl2EIpxivC+IJ0RpBS5AERT6V91Fqv2Ylwb5sklhoXGDx9s+l+Ud1MLaewIvnUHdIRtC02bvlhjwt0pnICDtHMikvOiTXjTBJgl7X9Q51Gm636q9pJVjS1T0gR3cNt9JJE/foDdOK8JozRFtF4j14xegXLt7BVBIXuSOK6P1c09mCPQ1VJbcj01S1zfrvZ+RZvrxr/0aXQ==)
iex> {:ok, cert} = cert_der |> Base.decode64!() |> X509.Certificate.from_der()
iex> public_key = X509.Certificate.public_key(cert)
iex> saml_response = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOlJlc3BvbnNlIERlc3RpbmF0aW9uPSJodHRwczovL2xvY2FsLm1ieC5jb206NDAwMS9hdXRoL2FoZWFkL3NzbyIgSUQ9ImlkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnNhbWwycD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGthNWhhNmJrblk2T2tkODVkNzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMjc3ODQwNDc4ODc1OTE3NzI4MTU4NDY3MDMiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT5tc1hWN3BvS2dWSjE1SmFzeU5NVndFRUNqMHJOOGVjeUdUb291WFd6L0drPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5Ra0ZFWDFOSlIwNUJWRlZTUlE9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRHFEQ0NBcENnQXdJQkFnSUdBWWo4bEFZa01BMEdDU3FHU0liM0RRRUJDd1VBTUlHVU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFRwpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVCk1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFY01Cb0dDU3FHU0liM0RRRUoKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVEFlRncweU16QTJNamN4TVRFM05UbGFGdzB6TXpBMk1qY3hNVEU0TlRsYU1JR1VNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCd3dOVTJGdUlFWnlZVzVqYVhOamJ6RU5NQXNHCkExVUVDZ3dFVDJ0MFlURVVNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RlRBVEJnTlZCQU1NREdSbGRpMDBOVE0wT1Rrd05qRWMKTUJvR0NTcUdTSWIzRFFFSkFSWU5hVzVtYjBCdmEzUmhMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUxURTdJUkcrb1FaQkFTUTdEWTN5ZVRyd0FCZEkyQmdHMkZYS1NrVFBrOWVuTXd0eVV5RFhDT3RlT2cxOCsvL01BMlVUdmdTCkkrbjBmaUFoN0JpN2N4cGltbk9hai9rY2d2cGRuKzV3cEVmU0lES0FlRWc5VklRZjBmei9rczRYa3JOeFJoOGJhNloveXBPVlIyVEwKb3p1OHY2c2pHQ2lxSFNvaVBsNzhLSU5IeDlqTUIzUUdkVEhSeHNUendGUEdjVUV2TzdYdmp4eE1OOUZMWmRIa3d0QTZjWlhEYkhsQQp2K280RWJMSVJxWEZjM3ZGNXJzM0Z6K2NncVozSFZHbTkwVEZGY2JQYngvZUtjdnp5SGRZdDhQNXBpMzY0bWlqdDlOS3ROVjlGOVZkClB6K0dwL3J4bHcwaS9JV3hWMC92QnJXMTBIUGQ0Mmtyc09nSGlieEJZZzhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKcnBZelpFb1ljUm8zWUY3Tnk0Z2RjOE9EU2xQUEtJZEx2d2hVVEdiUGR6SlUyaWZ4ekUvS2VUSEdtRnBqcGFrakRtbVdzcjJqOUZHVQovOVUwU2pxUG1KSFA1Z1liam16K3REM2plYUVrSUJEWnBjWWMrTXZlUWFBN3VETUlMQTJPVWhIdUZ1MFVKVmpHeGwyRUlweGl2QytJCkowUnBCUzVBRVJUNlY5MUZxdjJZbHdiNXNrbGhvWEdEeDlzK2wrVWQxTUxhZXdJdm5VSGRJUnRDMDJidmxoand0MHBuSUNEdEhNaWsKdk9pVFhqVEJKZ2w3WDlRNTFHbTYzNnE5cEpWalMxVDBnUjNjTnQ5SkpFL2ZvRGRPSzhKb3pSRnRGNGoxNHhlZ1hMdDdCVkJJWHVTTwpLNlAxYzA5bUNQUTFWSmJjajAxUzF6ZnJ2WitSWnZyeHIvMGFYUT09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWwycDpTdGF0dXMgeG1sbnM6c2FtbDJwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiPjxzYW1sMnA6U3RhdHVzQ29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+PC9zYW1sMnA6U3RhdHVzPjxzYW1sMjpBc3NlcnRpb24gSUQ9ImlkMjc3ODQwNDc4ODc3ODQ3MjgyMTE5MzE4OTUiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBWZXJzaW9uPSIyLjAiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDI6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5IiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+aHR0cDovL3d3dy5va3RhLmNvbS9leGthNWhhNmJrblk2T2tkODVkNzwvc2FtbDI6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+PGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz48ZHM6UmVmZXJlbmNlIFVSST0iI2lkMjc3ODQwNDc4ODc3ODQ3MjgyMTE5MzE4OTUiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT42b3Ztd3BWNk00bHdBQ3BGZ0tqVm0rNlZ5U0t0dE9iVTF2Y2tvZlVWa2ZBPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5QdGhLcG1TY2k3OTdERExvTXR1TUJHNjgvbzZlcDFSSWxZR0RhRVR6Q1E1a0ZUdmQ3MWJ3RWpjOWl2UVdlU3VHM1U4aUM2THQvN0hmWEpUVDBLeWkvU2laa3pIZkl1bElKbTVQTm9memV1dXVFQVlyMFBoeUpidkJHUk44RWF0UEwwVjNsdlhPMU9YaHcxU2ltYlMwZEdoQkdCM1ovNEptajNBMGdGbmx5TkpOLzc4eFgrYlB1eEJLeFFYcFY5TTEwTnJLRUYrbzc1TVA3bm4xOW5KM002bG93SEFHZ3RhRFg5dTNGYTJ3Lzh4QXFGTnQ2NHdaMERQYWltQWl0RFBKdnRIL3VVN3k0cm1lUit0cXpqdnNHR3BtODNjNVNzd1dEZ1p4alBDSVdHRVRaVVdHQ0Rwb25WVzdUR0JuNDR4b1ZZUEhERStJcWJyWDdUVXIySFFoUGc9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRHFEQ0NBcENnQXdJQkFnSUdBWWo4bEFZa01BMEdDU3FHU0liM0RRRUJDd1VBTUlHVU1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFRwpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVCk1CSUdBMVVFQ3d3TFUxTlBVSEp2ZG1sa1pYSXhGVEFUQmdOVkJBTU1ER1JsZGkwME5UTTBPVGt3TmpFY01Cb0dDU3FHU0liM0RRRUoKQVJZTmFXNW1iMEJ2YTNSaExtTnZiVEFlRncweU16QTJNamN4TVRFM05UbGFGdzB6TXpBMk1qY3hNVEU0TlRsYU1JR1VNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCd3dOVTJGdUlFWnlZVzVqYVhOamJ6RU5NQXNHCkExVUVDZ3dFVDJ0MFlURVVNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RlRBVEJnTlZCQU1NREdSbGRpMDBOVE0wT1Rrd05qRWMKTUJvR0NTcUdTSWIzRFFFSkFSWU5hVzVtYjBCdmEzUmhMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQUxURTdJUkcrb1FaQkFTUTdEWTN5ZVRyd0FCZEkyQmdHMkZYS1NrVFBrOWVuTXd0eVV5RFhDT3RlT2cxOCsvL01BMlVUdmdTCkkrbjBmaUFoN0JpN2N4cGltbk9hai9rY2d2cGRuKzV3cEVmU0lES0FlRWc5VklRZjBmei9rczRYa3JOeFJoOGJhNloveXBPVlIyVEwKb3p1OHY2c2pHQ2lxSFNvaVBsNzhLSU5IeDlqTUIzUUdkVEhSeHNUendGUEdjVUV2TzdYdmp4eE1OOUZMWmRIa3d0QTZjWlhEYkhsQQp2K280RWJMSVJxWEZjM3ZGNXJzM0Z6K2NncVozSFZHbTkwVEZGY2JQYngvZUtjdnp5SGRZdDhQNXBpMzY0bWlqdDlOS3ROVjlGOVZkClB6K0dwL3J4bHcwaS9JV3hWMC92QnJXMTBIUGQ0Mmtyc09nSGlieEJZZzhDQXdFQUFUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUEKcnBZelpFb1ljUm8zWUY3Tnk0Z2RjOE9EU2xQUEtJZEx2d2hVVEdiUGR6SlUyaWZ4ekUvS2VUSEdtRnBqcGFrakRtbVdzcjJqOUZHVQovOVUwU2pxUG1KSFA1Z1liam16K3REM2plYUVrSUJEWnBjWWMrTXZlUWFBN3VETUlMQTJPVWhIdUZ1MFVKVmpHeGwyRUlweGl2QytJCkowUnBCUzVBRVJUNlY5MUZxdjJZbHdiNXNrbGhvWEdEeDlzK2wrVWQxTUxhZXdJdm5VSGRJUnRDMDJidmxoand0MHBuSUNEdEhNaWsKdk9pVFhqVEJKZ2w3WDlRNTFHbTYzNnE5cEpWalMxVDBnUjNjTnQ5SkpFL2ZvRGRPSzhKb3pSRnRGNGoxNHhlZ1hMdDdCVkJJWHVTTwpLNlAxYzA5bUNQUTFWSmJjajAxUzF6ZnJ2WitSWnZyeHIvMGFYUT09PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9kczpTaWduYXR1cmU+PHNhbWwyOlN1YmplY3QgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPjxzYW1sMjpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+ZGouamFpbjwvc2FtbDI6TmFtZUlEPjxzYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+PHNhbWwyOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAyMy0wNy0xMFQxMzo0NToyOS42NTlaIiBSZWNpcGllbnQ9Imh0dHBzOi8vbG9jYWwubWJ4LmNvbTo0MDAxL2F1dGgvYWhlYWQvc3NvIi8+PC9zYW1sMjpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDI6U3ViamVjdD48c2FtbDI6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMjMtMDctMTBUMTM6MzU6MjkuNjU5WiIgTm90T25PckFmdGVyPSIyMDIzLTA3LTEwVDEzOjQ1OjI5LjY1OVoiIHhtbG5zOnNhbWwyPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIj48c2FtbDI6QXVkaWVuY2VSZXN0cmljdGlvbj48c2FtbDI6QXVkaWVuY2U+eHFPNTJDTkVMZDBoVkI5dmFYMWRfZGN3dVlBeEdVU3I8L3NhbWwyOkF1ZGllbmNlPjwvc2FtbDI6QXVkaWVuY2VSZXN0cmljdGlvbj48L3NhbWwyOkNvbmRpdGlvbnM+PHNhbWwyOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAyMy0wNy0xMFQxMzo0MDoyOS42NThaIiBTZXNzaW9uSW5kZXg9ImlkMTY4ODk5NjQyOTY1Ny4xMTQ1MDMyMDEyIiB4bWxuczpzYW1sMj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiI+PHNhbWwyOkF1dGhuQ29udGV4dD48c2FtbDI6QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmRQcm90ZWN0ZWRUcmFuc3BvcnQ8L3NhbWwyOkF1dGhuQ29udGV4dENsYXNzUmVmPjwvc2FtbDI6QXV0aG5Db250ZXh0Pjwvc2FtbDI6QXV0aG5TdGF0ZW1lbnQ+PC9zYW1sMjpBc3NlcnRpb24+PC9zYW1sMnA6UmVzcG9uc2U+"
iex> {:ok, saml_body} = saml_response |> Base.decode64()
iex> {:ok, root} = SimpleXml.parse(saml_body)
iex> SimpleXml.verify(root, public_key)
{:error, :signature_verification_failed}