11package com .onelogin .saml ;
22
3- import java .lang . reflect . Method ;
3+ import java .security . cert . Certificate ;
44import java .security .cert .CertificateException ;
5- import java .security .cert .X509Certificate ;
65import java .util .ArrayList ;
76import java .util .Calendar ;
87import java .util .HashMap ;
9- import java .util .Iterator ;
108import java .util .LinkedHashSet ;
119import java .util .Map ;
1210import java .util .Set ;
1311import java .util .TimeZone ;
1412
1513import javax .xml .crypto .dsig .XMLSignature ;
16- import javax .xml .crypto .dsig .XMLSignatureFactory ;
17- import javax .xml .crypto .dsig .dom .DOMValidateContext ;
18- import javax .xml .namespace .NamespaceContext ;
19- import javax .xml .xpath .XPath ;
2014import javax .xml .xpath .XPathExpressionException ;
21- import javax .xml .xpath .XPathFactory ;
2215
2316import org .apache .commons .codec .binary .Base64 ;
2417import org .slf4j .Logger ;
@@ -40,10 +33,8 @@ public class Response {
4033 */
4134 private Document document ;
4235
43- private NodeList assertions ;
4436 private Element rootElement ;
4537 private final AccountSettings accountSettings ;
46- private final Certificate certificate ;
4738 private String response ;
4839 private String currentUrl ;
4940 private StringBuffer error ;
@@ -55,8 +46,6 @@ public class Response {
5546 public Response (AccountSettings accountSettings ) throws CertificateException {
5647 error = new StringBuffer ();
5748 this .accountSettings = accountSettings ;
58- certificate = new Certificate ();
59- certificate .loadCertificate (this .accountSettings .getCertificate ());
6049 }
6150
6251 public Response (AccountSettings accountSettings , String response ) throws Exception {
@@ -98,10 +87,10 @@ public boolean isValid(String... requestId){
9887 throw new Exception ("SAML Response must contain 1 Assertion." );
9988 }
10089
101- NodeList nodes = document .getElementsByTagName ( "Signature" );
90+ NodeList signNodes = document .getElementsByTagNameNS ( XMLSignature . XMLNS , "Signature" );
10291 ArrayList <String > signedElements = new ArrayList <String >();
103- for (int i = 0 ; i < nodes .getLength (); i ++) {
104- signedElements .add (nodes .item (i ).getParentNode ().getLocalName ());
92+ for (int i = 0 ; i < signNodes .getLength (); i ++) {
93+ signedElements .add (signNodes .item (i ).getParentNode ().getLocalName ());
10594 }
10695 if (!signedElements .isEmpty ()) {
10796 if (!this .validateSignedElements (signedElements )){
@@ -208,24 +197,17 @@ public boolean isValid(String... requestId){
208197 throw new Exception ("A valid SubjectConfirmation was not found on this Response" );
209198 }
210199
211-
212- // ------------ working validations until here!
213- //TODO: more validations
214-
215-
216-
217-
218-
219- // if (setIdAttributeExists()) {
220- // tagIdAttributes(xmlDoc);
221- // }
222-
223- X509Certificate cert = certificate .getX509Cert ();
224- DOMValidateContext ctx = new DOMValidateContext (cert .getPublicKey (), nodes .item (0 ));
225- XMLSignatureFactory sigF = XMLSignatureFactory .getInstance ("DOM" );
226- XMLSignature xmlSignature = sigF .unmarshalXMLSignature (ctx );
200+ if (signedElements .isEmpty ()){
201+ throw new Exception ("No Signature found. SAML Response rejected" );
202+ }else {
203+ Certificate cert = this .accountSettings .getCert ();
227204
228- return xmlSignature .validate (ctx );
205+ // Only validates the first signed element
206+ if (!Utils .validateSign (signNodes .item (0 ), cert )) {
207+ throw new Exception ("Signature validation failed. SAML Response rejected" );
208+ }
209+ }
210+ return true ;
229211 }catch (Error e ) {
230212 error .append (e .getMessage ());
231213 return false ;
@@ -245,15 +227,15 @@ public String getNameId() throws Exception {
245227 }
246228
247229 public String getAttribute (String name ) {
248- HashMap attributes = getAttributes ();
230+ HashMap < String , ArrayList < String >> attributes = getAttributes ();
249231 if (!attributes .isEmpty ()) {
250232 return attributes .get (name ).toString ();
251233 }
252234 return null ;
253235 }
254236
255- public HashMap getAttributes () {
256- HashMap <String , ArrayList > attributes = new HashMap <String , ArrayList >();
237+ public HashMap < String , ArrayList < String >> getAttributes () {
238+ HashMap <String , ArrayList < String >> attributes = new HashMap <String , ArrayList < String > >();
257239 NodeList nodes = document .getElementsByTagNameNS ("urn:oasis:names:tc:SAML:2.0:assertion" , "Attribute" );
258240
259241 if (nodes .getLength () != 0 ) {
@@ -435,21 +417,6 @@ private boolean validateTimestamps()
435417 return true ;
436418 }
437419
438-
439-
440- private boolean setIdAttributeExists () {
441- for (Method method : Element .class .getDeclaredMethods ()) {
442- if (method .getName ().equals ("setIdAttribute" )) {
443- return true ;
444- }
445- }
446- return false ;
447- }
448-
449- private void tagIdAttributes (Document xmlDoc ) {
450- throw new UnsupportedOperationException ("Not supported yet." );
451- }
452-
453420 public void setDestinationUrl (String urld ){
454421 currentUrl = urld ;
455422 }
0 commit comments