Skip to content

Commit e896156

Browse files
authored
Merge pull request #180 from waterkip/GL-assertion-decrypt_bug_with_upgraded_xmlenc
Fix decrypt for encrypted assertions
2 parents b672a6e + 79f1a38 commit e896156

File tree

4 files changed

+54
-28
lines changed

4 files changed

+54
-28
lines changed

Makefile.PL

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ my %WriteMakefileArgs = (
4949
"URI::Escape" => 0,
5050
"URI::QueryParam" => 0,
5151
"URN::OASIS::SAML2" => "0.003",
52-
"XML::Enc" => "0.12",
52+
"XML::Enc" => "0.13",
5353
"XML::Generator" => "1.13",
5454
"XML::LibXML" => 0,
5555
"XML::LibXML::XPathContext" => 0,
@@ -131,7 +131,7 @@ my %FallbackPrereqs = (
131131
"URI::QueryParam" => 0,
132132
"URI::URL" => 0,
133133
"URN::OASIS::SAML2" => "0.003",
134-
"XML::Enc" => "0.12",
134+
"XML::Enc" => "0.13",
135135
"XML::Generator" => "1.13",
136136
"XML::LibXML" => 0,
137137
"XML::LibXML::XPathContext" => 0,

cpanfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ requires "URI::Encode" => "0";
3333
requires "URI::Escape" => "0";
3434
requires "URI::QueryParam" => "0";
3535
requires "URN::OASIS::SAML2" => "0.003";
36-
requires "XML::Enc" => "0.12";
36+
requires "XML::Enc" => "0.13";
3737
requires "XML::Generator" => "1.13";
3838
requires "XML::LibXML" => "0";
3939
requires "XML::LibXML::XPathContext" => "0";

dist.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ copy = cpanfile, Makefile.PL, README, LICENSE, CONTRIBUTORS
4848
skip = Saml2Test
4949

5050
[Prereqs / RuntimeRequires]
51-
XML::Enc = 0.12
51+
XML::Enc = 0.13
5252
XML::Sig = 0.64
5353
XML::Writer = 0.625
5454
; Here because otherwise only on test you get to pull in this dependency

lib/Net/SAML2/Protocol/Assertion.pm

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,50 @@ EncryptedAssertion is properly validated.
9393
9494
=cut
9595

96+
sub _verify_encrypted_assertion {
97+
my $self = shift;
98+
my $xml = shift;
99+
my $cacert = shift;
100+
my $key_file = shift;
101+
my $key_name = shift;
102+
103+
my $xpath = XML::LibXML::XPathContext->new($xml);
104+
$xpath->registerNs('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
105+
$xpath->registerNs('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
106+
$xpath->registerNs('dsig', 'http://www.w3.org/2000/09/xmldsig#');
107+
$xpath->registerNs('xenc', 'http://www.w3.org/2001/04/xmlenc#');
108+
109+
return $xml unless $xpath->exists('//saml:EncryptedAssertion');
110+
111+
croak "Encrypted Assertions require key_file" if !defined $key_file;
112+
113+
$xml = $self->_decrypt(
114+
$xml,
115+
key_file => $key_file,
116+
key_name => $key_name,
117+
);
118+
$xpath->setContextNode($xml);
119+
120+
my $assert_nodes = $xpath->findnodes('//saml:Assertion');
121+
return $xml unless $assert_nodes->size;
122+
my $assert = $assert_nodes->get_node(1);
123+
124+
return $xml unless $xpath->exists('dsig:Signature', $assert);
125+
my $xml_opts->{ no_xml_declaration } = 1;
126+
my $x = Net::SAML2::XML::Sig->new($xml_opts);
127+
my $ret = $x->verify($assert->toString());
128+
die "Decrypted Assertion signature check failed" unless $ret;
129+
130+
return $xml unless $cacert;
131+
my $cert = $x->signer_cert;
132+
die "Certificate not provided in SAML Response, cannot validate" unless $cert;
133+
134+
my $ca = Crypt::OpenSSL::Verify->new($cacert, { strict_certs => 0 });
135+
die "Unable to verify signer cert with cacert: " . $cert->subject
136+
unless $ca->verify($cert);
137+
return $xml;
138+
}
139+
96140
sub new_from_xml {
97141
my($class, %args) = @_;
98142

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

111-
my $dom = $xml;
112-
113-
if ($xpath->exists('//saml:EncryptedAssertion')) {
114-
115-
croak "Encrypted Assertions require key_file" if !defined $key_file;
116-
117-
my $assert = $xpath->findnodes('//saml:Assertion')->[0];
118-
my @signedinfo = $xpath->findnodes('dsig:Signature', $assert);
119-
120-
if (defined $assert && (scalar @signedinfo ne 0)) {
121-
my $xml_opts->{ no_xml_declaration } = 1;
122-
my $x = Net::SAML2::XML::Sig->new($xml_opts);
123-
my $ret = $x->verify($assert->serialize);
124-
die "Decrypted Assertion signature check failed" unless $ret;
125-
126-
return unless $cacert;
127-
my $cert = $x->signer_cert
128-
or die "Certificate not provided and not in SAML Response, cannot validate";
129-
130-
my $ca = Crypt::OpenSSL::Verify->new($cacert, { strict_certs => 0 });
131-
die "Unable to verify signer cert with cacert: " . $cert->subject
132-
unless $ca->verify($cert);
133-
}
134-
}
155+
$xml = $class->_verify_encrypted_assertion(
156+
$xml,
157+
$cacert,
158+
$key_file,
159+
$args{key_name},
160+
);
135161

136162
my $dec = $class->_decrypt(
137163
$xml,

0 commit comments

Comments
 (0)