#!perl
use strict;
use warnings;
use XML::LibXML;
use XML::LibXMLSec::Simple;
use XML::LibXMLSec::Utils;
use Test::More;

sub verify_from_string {
    my ($document_str,$certificate) = @_;
    my $document = XML::LibXML->load_xml(string=>$document_str);
    XML::LibXMLSec::Utils::add_id_attr(
        $document,
        'urn:oasis:names:tc:SAML:2.0:protocol','Response',
        'ID',
    );
    return XML::LibXMLSec::Simple::verify($document,$certificate);
}

my $document_str = <<'XML';
<?xml version="1.0" encoding="UTF-8"?><saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:3000/saml/sso/example-okta-com" ID="id84193712402627052114698066" InResponseTo="f2d11c6d0b90e222f7d016b645fb94c8" IssueInstant="2016-06-09T10:42:48.371Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/exk6gaihj0GexDQ5b0h7</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#id84193712402627052114698066"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>DYw29DDi9UBEpYCZpIo452ypg+vCAgvyEUyKt95xYkU=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>IvGmaLz3+yvXZtVuXI/EsedG9Y/b0ucffSTGxcQreReSYFQQouY17aeEXyVdxheGf52pTBaIAsHpoZaakUWH/0t1VT6JZNFxgGEiX9J1T5bYXxzTyYzAI6U8CXE9T4HIqTMS0QYkg42EVPw/dtqs2atsu1xCnT3RzPnnQWXWmAPvApylrVo+BTi5L7rDBELJWtgswTTlZ82oynFUUI6a6OyZRwN1l/8pkZ01Sv9AGFdV4hdWUb3BNJASU47HHrjwDko9vBJtNc0/VA1+Irn2+I4Ol7Yua3+pF5w5ndYAYAfsB75WmCwHOBte4ibYvA9VrLaX9zC9WzsSEAZFqt8Eqw==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDpDCCAoygAwIBAgIGAVUrJWrGMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi03MzQ2MDkxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTYwNjA3MTM1NDIwWhcNMjYwNjA3MTM1NTIwWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtNzM0NjA5MRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
hsjD1PSQI638lEvKWidE9IeM79WJ9QVI6YzutZxhVMxLl88+qAYmTHYfe3RsRjvPz2Yn4ij+a4Gf
HfL5zxiZsu15gka+iAPDPZF2h++RYjjPDbiYDvoucZ2203I0CzafAJIEnNypM8qvJG/kGhtQZGZj
XDltTGnMLMgYr+8vZXtL1wAMYA5EyU5ZSU+yjEjj9G2T2uKkEg7Q+vEA1r205cscBZxOdW30izMN
vMFDXAXGntQUehH+L5oUlQoprfoi3mYopR8tScYqjHi+276iHqfk+Ecn54A8ctOT8+g15UNK//Uw
qbWX7iN2oi1aeH1VAqGq5V6egQbx6J9gPn+JFwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB8iNrY
nAZkqLikBmETFZ1uIb6QOXzrkeUbtwbFhfJfQuSixosBnIt/bPetcj+UfbxpdwiYO3xUwQ3q/ZNA
WDpkLaeKFd2hsNADHcx3eMaTw9yKijGOUzoicl2SBGYJrXAxknMZrcF2VElUAfh6614YASlWmDkH
1oQoveBEMdKfn45HXEphPjGwtrHz2XfA4hIqlz37IPh7aMFVyle3u/shZzjRbSf+idlb8uSm+/90
fq9VZ8oeHZpAIM7K96SES9VhfKWyxyUUQD90LAAClg9L8eNIFB23FdrjH5DymFFxWdyaG4CEM4km
bU+O5EW7N3ZhUUnAx70FxTNpCihZNwhw</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></saml2p:Status><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id84193712403500102073273027" IssueInstant="2016-06-09T10:42:48.371Z" Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://www.okta.com/exk6gaihj0GexDQ5b0h7</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#id84193712403500102073273027"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>QBPE9QPP8+GF6GpyMJyv4C/0B2DQAYWWwsywST14a9o=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>A5I/ufMSYr2h2O9KwVOYwk5zfs1ZWeytLCKZqar0hX1Lz/Ln5wfsdmhY4TR1cItn/6KxyxxN8tE0abE0YKQRa617v0egksQGWb00Akeh5YOJgxXoedbMwAeOt83lfg5qPaPg1R4UspoapWiFmB0tPCc+yijNprXXWMeJk7puoElfhCNfhK0t01h2D1EKwE9tGp+STVY5waJNDf00jX6ixfxa3JWg0yeX8v3S+S0zJ8Jn6UlJ6zcQ3laGU8imVGExbOt8o6sfRoYFHVQWnR50pIK3JX2qHBHETTL7nO6jkR/42adI+ZSdbgB8NFMIQBTYXFW0m1RsXnfK6Dazqp4xTg==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDpDCCAoygAwIBAgIGAVUrJWrGMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi03MzQ2MDkxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTYwNjA3MTM1NDIwWhcNMjYwNjA3MTM1NTIwWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtNzM0NjA5MRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
hsjD1PSQI638lEvKWidE9IeM79WJ9QVI6YzutZxhVMxLl88+qAYmTHYfe3RsRjvPz2Yn4ij+a4Gf
HfL5zxiZsu15gka+iAPDPZF2h++RYjjPDbiYDvoucZ2203I0CzafAJIEnNypM8qvJG/kGhtQZGZj
XDltTGnMLMgYr+8vZXtL1wAMYA5EyU5ZSU+yjEjj9G2T2uKkEg7Q+vEA1r205cscBZxOdW30izMN
vMFDXAXGntQUehH+L5oUlQoprfoi3mYopR8tScYqjHi+276iHqfk+Ecn54A8ctOT8+g15UNK//Uw
qbWX7iN2oi1aeH1VAqGq5V6egQbx6J9gPn+JFwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB8iNrY
nAZkqLikBmETFZ1uIb6QOXzrkeUbtwbFhfJfQuSixosBnIt/bPetcj+UfbxpdwiYO3xUwQ3q/ZNA
WDpkLaeKFd2hsNADHcx3eMaTw9yKijGOUzoicl2SBGYJrXAxknMZrcF2VElUAfh6614YASlWmDkH
1oQoveBEMdKfn45HXEphPjGwtrHz2XfA4hIqlz37IPh7aMFVyle3u/shZzjRbSf+idlb8uSm+/90
fq9VZ8oeHZpAIM7K96SES9VhfKWyxyUUQD90LAAClg9L8eNIFB23FdrjH5DymFFxWdyaG4CEM4km
bU+O5EW7N3ZhUUnAx70FxTNpCihZNwhw</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2:Subject xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">gianni.ceccarelli@broadbean.com</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml2:SubjectConfirmationData InResponseTo="f2d11c6d0b90e222f7d016b645fb94c8" NotOnOrAfter="2016-06-09T10:47:48.371Z" Recipient="http://localhost:3000/saml/sso/example-okta-com"/></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2016-06-09T10:37:48.371Z" NotOnOrAfter="2016-06-09T10:47:48.371Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:AudienceRestriction><saml2:Audience>http://localhost:3000/saml/sso/example-okta-com</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2016-06-09T10:42:48.371Z" SessionIndex="f2d11c6d0b90e222f7d016b645fb94c8" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><saml2:Attribute Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Gianni</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Ceccarelli</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="Email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"><saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">gianni.ceccarelli@broadbean.com</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion></saml2p:Response>
XML

my $certificate = <<'PEM';
-----BEGIN CERTIFICATE-----
MIIDpDCCAoygAwIBAgIGAVUrJWrGMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJVUzETMBEG
A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU
MBIGA1UECwwLU1NPUHJvdmlkZXIxEzARBgNVBAMMCmRldi03MzQ2MDkxHDAaBgkqhkiG9w0BCQEW
DWluZm9Ab2t0YS5jb20wHhcNMTYwNjA3MTM1NDIwWhcNMjYwNjA3MTM1NTIwWjCBkjELMAkGA1UE
BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNV
BAoMBE9rdGExFDASBgNVBAsMC1NTT1Byb3ZpZGVyMRMwEQYDVQQDDApkZXYtNzM0NjA5MRwwGgYJ
KoZIhvcNAQkBFg1pbmZvQG9rdGEuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
hsjD1PSQI638lEvKWidE9IeM79WJ9QVI6YzutZxhVMxLl88+qAYmTHYfe3RsRjvPz2Yn4ij+a4Gf
HfL5zxiZsu15gka+iAPDPZF2h++RYjjPDbiYDvoucZ2203I0CzafAJIEnNypM8qvJG/kGhtQZGZj
XDltTGnMLMgYr+8vZXtL1wAMYA5EyU5ZSU+yjEjj9G2T2uKkEg7Q+vEA1r205cscBZxOdW30izMN
vMFDXAXGntQUehH+L5oUlQoprfoi3mYopR8tScYqjHi+276iHqfk+Ecn54A8ctOT8+g15UNK//Uw
qbWX7iN2oi1aeH1VAqGq5V6egQbx6J9gPn+JFwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB8iNrY
nAZkqLikBmETFZ1uIb6QOXzrkeUbtwbFhfJfQuSixosBnIt/bPetcj+UfbxpdwiYO3xUwQ3q/ZNA
WDpkLaeKFd2hsNADHcx3eMaTw9yKijGOUzoicl2SBGYJrXAxknMZrcF2VElUAfh6614YASlWmDkH
1oQoveBEMdKfn45HXEphPjGwtrHz2XfA4hIqlz37IPh7aMFVyle3u/shZzjRbSf+idlb8uSm+/90
fq9VZ8oeHZpAIM7K96SES9VhfKWyxyUUQD90LAAClg9L8eNIFB23FdrjH5DymFFxWdyaG4CEM4km
bU+O5EW7N3ZhUUnAx70FxTNpCihZNwhw
-----END CERTIFICATE-----
PEM

subtest 'correct document' => sub {
    my $result = verify_from_string($document_str,$certificate);
    ok($result,'verification should work');
};

subtest 'altered document' => sub {
    my $str2 = $document_str;
    $str2 =~ s{gianni}{gianna};
    my $result = verify_from_string($str2,$certificate);
    ok(!$result,'verification should fail');
};


done_testing();

