Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ my %WriteMakefileArgs = (
"URI::Escape" => 0,
"URI::QueryParam" => 0,
"URN::OASIS::SAML2" => "0.003",
"XML::Enc" => "0.12",
"XML::Enc" => "0.13",
"XML::Generator" => "1.13",
"XML::LibXML" => 0,
"XML::LibXML::XPathContext" => 0,
Expand Down Expand Up @@ -131,7 +131,7 @@ my %FallbackPrereqs = (
"URI::QueryParam" => 0,
"URI::URL" => 0,
"URN::OASIS::SAML2" => "0.003",
"XML::Enc" => "0.12",
"XML::Enc" => "0.13",
"XML::Generator" => "1.13",
"XML::LibXML" => 0,
"XML::LibXML::XPathContext" => 0,
Expand Down
2 changes: 1 addition & 1 deletion cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ requires "URI::Encode" => "0";
requires "URI::Escape" => "0";
requires "URI::QueryParam" => "0";
requires "URN::OASIS::SAML2" => "0.003";
requires "XML::Enc" => "0.12";
requires "XML::Enc" => "0.13";
requires "XML::Generator" => "1.13";
requires "XML::LibXML" => "0";
requires "XML::LibXML::XPathContext" => "0";
Expand Down
2 changes: 1 addition & 1 deletion dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ copy = cpanfile, Makefile.PL, README, LICENSE, CONTRIBUTORS
skip = Saml2Test

[Prereqs / RuntimeRequires]
XML::Enc = 0.12
XML::Enc = 0.13
XML::Sig = 0.64
XML::Writer = 0.625
; Here because otherwise only on test you get to pull in this dependency
Expand Down
74 changes: 50 additions & 24 deletions lib/Net/SAML2/Protocol/Assertion.pm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,50 @@ EncryptedAssertion is properly validated.

=cut

sub _verify_encrypted_assertion {
my $self = shift;
my $xml = shift;
my $cacert = shift;
my $key_file = shift;
my $key_name = shift;

my $xpath = XML::LibXML::XPathContext->new($xml);
$xpath->registerNs('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$xpath->registerNs('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
$xpath->registerNs('dsig', 'http://www.w3.org/2000/09/xmldsig#');
$xpath->registerNs('xenc', 'http://www.w3.org/2001/04/xmlenc#');

return $xml unless $xpath->exists('//saml:EncryptedAssertion');

croak "Encrypted Assertions require key_file" if !defined $key_file;

$xml = $self->_decrypt(
$xml,
key_file => $key_file,
key_name => $key_name,
);
$xpath->setContextNode($xml);

my $assert_nodes = $xpath->findnodes('//saml:Assertion');
return $xml unless $assert_nodes->size;
my $assert = $assert_nodes->get_node(1);

return $xml unless $xpath->exists('dsig:Signature', $assert);
my $xml_opts->{ no_xml_declaration } = 1;
my $x = Net::SAML2::XML::Sig->new($xml_opts);
my $ret = $x->verify($assert->toString());
die "Decrypted Assertion signature check failed" unless $ret;

return $xml unless $cacert;
my $cert = $x->signer_cert;
die "Certificate not provided in SAML Response, cannot validate" unless $cert;

my $ca = Crypt::OpenSSL::Verify->new($cacert, { strict_certs => 0 });
die "Unable to verify signer cert with cacert: " . $cert->subject
unless $ca->verify($cert);
return $xml;
}

sub new_from_xml {
my($class, %args) = @_;

Expand All @@ -108,30 +152,12 @@ sub new_from_xml {
my $xml = no_comments($args{xml});
$xpath->setContextNode($xml);

my $dom = $xml;

if ($xpath->exists('//saml:EncryptedAssertion')) {

croak "Encrypted Assertions require key_file" if !defined $key_file;

my $assert = $xpath->findnodes('//saml:Assertion')->[0];
my @signedinfo = $xpath->findnodes('dsig:Signature', $assert);

if (defined $assert && (scalar @signedinfo ne 0)) {
my $xml_opts->{ no_xml_declaration } = 1;
my $x = Net::SAML2::XML::Sig->new($xml_opts);
my $ret = $x->verify($assert->serialize);
die "Decrypted Assertion signature check failed" unless $ret;

return unless $cacert;
my $cert = $x->signer_cert
or die "Certificate not provided and not in SAML Response, cannot validate";

my $ca = Crypt::OpenSSL::Verify->new($cacert, { strict_certs => 0 });
die "Unable to verify signer cert with cacert: " . $cert->subject
unless $ca->verify($cert);
}
}
$xml = $class->_verify_encrypted_assertion(
$xml,
$cacert,
$key_file,
$args{key_name},
);

my $dec = $class->_decrypt(
$xml,
Expand Down