@@ -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+
96140sub 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