Skip to content

Commit faecd40

Browse files
committed
Fix decrypt for encrypted assertions
Signed-off-by: Wesley Schwengle <waterkip@cpan.org>
1 parent b672a6e commit faecd40

File tree

1 file changed

+50
-24
lines changed

1 file changed

+50
-24
lines changed

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)