1010import java .util .Objects ;
1111import javax .xml .parsers .ParserConfigurationException ;
1212import javax .xml .xpath .XPathExpressionException ;
13+
14+ import com .onelogin .saml2 .model .hsm .HSM ;
1315import org .joda .time .DateTime ;
1416import org .joda .time .Instant ;
1517import org .slf4j .Logger ;
@@ -78,7 +80,7 @@ public class SamlResponse {
7880
7981 /**
8082 * After validation, if it fails this property has the cause of the problem
81- */
83+ */
8284 private Exception validationException ;
8385
8486 /**
@@ -156,7 +158,7 @@ public void loadXmlFromBase64(String responseStr) throws ParserConfigurationExce
156158
157159 NodeList encryptedAssertionNodes = samlResponseDocument .getElementsByTagNameNS (Constants .NS_SAML ,"EncryptedAssertion" );
158160
159- if (encryptedAssertionNodes .getLength () != 0 ) {
161+ if (encryptedAssertionNodes .getLength () != 0 ) {
160162 decryptedDocument = Util .copyDocument (samlResponseDocument );
161163 encrypted = true ;
162164 decryptedDocument = this .decryptAssertion (decryptedDocument );
@@ -566,20 +568,20 @@ public String getNameIdSPNameQualifier() throws Exception {
566568 * @throws XPathExpressionException
567569 * @throws ValidationError
568570 *
569- */
571+ */
570572 public HashMap <String , List <String >> getAttributes () throws XPathExpressionException , ValidationError {
571573 HashMap <String , List <String >> attributes = new HashMap <String , List <String >>();
572574
573575 NodeList nodes = this .queryAssertion ("/saml:AttributeStatement/saml:Attribute" );
574-
576+
575577 if (nodes .getLength () != 0 ) {
576578 for (int i = 0 ; i < nodes .getLength (); i ++) {
577579 NamedNodeMap attrName = nodes .item (i ).getAttributes ();
578580 String attName = attrName .getNamedItem ("Name" ).getNodeValue ();
579581 if (attributes .containsKey (attName ) && !settings .isAllowRepeatAttributeName ()) {
580582 throw new ValidationError ("Found an Attribute element with duplicated Name" , ValidationError .DUPLICATED_ATTRIBUTE_NAME_FOUND );
581583 }
582-
584+
583585 NodeList childrens = nodes .item (i ).getChildNodes ();
584586
585587 List <String > attrValues = null ;
@@ -605,7 +607,7 @@ public HashMap<String, List<String>> getAttributes() throws XPathExpressionExcep
605607
606608 /**
607609 * Returns the ResponseStatus object
608- *
610+ *
609611 * @return
610612 */
611613 public SamlResponseStatus getResponseStatus () {
@@ -639,7 +641,7 @@ public void checkStatus() throws ValidationError {
639641 *
640642 * @throws IllegalArgumentException
641643 * if the response not contain status or if Unexpected XPath error
642- * @throws ValidationError
644+ * @throws ValidationError
643645 */
644646 public static SamlResponseStatus getStatus (Document dom ) throws ValidationError {
645647 String statusXpath = "/samlp:Response/samlp:Status" ;
@@ -682,7 +684,7 @@ public Boolean checkOneAuthnStatement() throws XPathExpressionException {
682684 * Gets the audiences.
683685 *
684686 * @return the audiences of the response
685- *
687+ *
686688 * @throws XPathExpressionException
687689 */
688690 public List <String > getAudiences () throws XPathExpressionException {
@@ -706,8 +708,8 @@ public List<String> getAudiences() throws XPathExpressionException {
706708 *
707709 * @return the issuers of the assertion/response
708710 *
709- * @throws XPathExpressionException
710- * @throws ValidationError
711+ * @throws XPathExpressionException
712+ * @throws ValidationError
711713 */
712714 public List <String > getIssuers () throws XPathExpressionException , ValidationError {
713715 List <String > issuers = new ArrayList <String >();
@@ -763,7 +765,7 @@ public DateTime getSessionNotOnOrAfter() throws XPathExpressionException {
763765 *
764766 * @return the SessionIndex value
765767 *
766- * @throws XPathExpressionException
768+ * @throws XPathExpressionException
767769 */
768770 public String getSessionIndex () throws XPathExpressionException {
769771 String sessionIndex = null ;
@@ -852,7 +854,7 @@ public ArrayList<String> processSignedElements() throws XPathExpressionException
852854
853855 String responseTag = "{" + Constants .NS_SAMLP + "}Response" ;
854856 String assertionTag = "{" + Constants .NS_SAML + "}Assertion" ;
855-
857+
856858 if (!signedElement .equals (responseTag ) && !signedElement .equals (assertionTag )) {
857859 throw new ValidationError ("Invalid Signature Element " + signedElement + " SAML Response rejected" , ValidationError .WRONG_SIGNED_ELEMENT );
858860 }
@@ -862,13 +864,13 @@ public ArrayList<String> processSignedElements() throws XPathExpressionException
862864 if (idNode == null || idNode .getNodeValue () == null || idNode .getNodeValue ().isEmpty ()) {
863865 throw new ValidationError ("Signed Element must contain an ID. SAML Response rejected" , ValidationError .ID_NOT_FOUND_IN_SIGNED_ELEMENT );
864866 }
865-
866- String idValue = idNode .getNodeValue ();
867+
868+ String idValue = idNode .getNodeValue ();
867869 if (verifiedIds .contains (idValue )) {
868870 throw new ValidationError ("Duplicated ID. SAML Response rejected" , ValidationError .DUPLICATED_ID_IN_SIGNED_ELEMENTS );
869871 }
870872 verifiedIds .add (idValue );
871-
873+
872874 NodeList refNodes = Util .query (null , "ds:SignedInfo/ds:Reference" , signNode );
873875 if (refNodes .getLength () == 1 ) {
874876 Node refNode = refNodes .item (0 );
@@ -878,7 +880,7 @@ public ArrayList<String> processSignedElements() throws XPathExpressionException
878880 if (!sei .equals (idValue )) {
879881 throw new ValidationError ("Found an invalid Signed Element. SAML Response rejected" , ValidationError .INVALID_SIGNED_ELEMENT );
880882 }
881-
883+
882884 if (verifiedSeis .contains (sei )) {
883885 throw new ValidationError ("Duplicated Reference URI. SAML Response rejected" , ValidationError .DUPLICATED_REFERENCE_IN_SIGNED_ELEMENTS );
884886 }
@@ -958,7 +960,7 @@ public boolean validateSignedElements(ArrayList<String> signedElements) throws X
958960 *
959961 * @return true if still valid
960962 *
961- * @throws ValidationError
963+ * @throws ValidationError
962964 */
963965 public boolean validateTimestamps () throws ValidationError {
964966 NodeList timestampNodes = samlResponseDocument .getElementsByTagNameNS ("*" , "Conditions" );
@@ -1026,7 +1028,7 @@ public Exception getValidationException() {
10261028 * Xpath Expression
10271029 *
10281030 * @return the queried node
1029- * @throws XPathExpressionException
1031+ * @throws XPathExpressionException
10301032 *
10311033 */
10321034 private NodeList queryAssertion (String assertionXpath ) throws XPathExpressionException {
@@ -1075,7 +1077,7 @@ private NodeList queryAssertion(String assertionXpath) throws XPathExpressionExc
10751077 *
10761078 * @param nameQuery
10771079 * Xpath Expression
1078- * @param context
1080+ * @param context
10791081 * The context node
10801082 *
10811083 * @return DOMNodeList The queried nodes
@@ -1094,13 +1096,13 @@ private NodeList query(String nameQuery, Node context) throws XPathExpressionExc
10941096
10951097 /**
10961098 * Decrypt assertion.
1097- *
1099+ *
10981100 * @param dom
10991101 * Encrypted assertion
11001102 *
11011103 * @return Decrypted Assertion.
11021104 *
1103- * @throws XPathExpressionException
1105+ * @throws XPathExpressionException
11041106 * @throws IOException
11051107 * @throws SAXException
11061108 * @throws ParserConfigurationException
@@ -1110,7 +1112,9 @@ private NodeList query(String nameQuery, Node context) throws XPathExpressionExc
11101112 private Document decryptAssertion (Document dom ) throws XPathExpressionException , ParserConfigurationException , SAXException , IOException , SettingsException , ValidationError {
11111113 PrivateKey key = settings .getSPkey ();
11121114
1113- if (key == null ) {
1115+ HSM hsm = this .settings .getHsm ();
1116+
1117+ if (hsm == null && key == null ) {
11141118 throw new SettingsException ("No private key available for decrypt, check settings" , SettingsException .PRIVATE_KEY_NOT_FOUND );
11151119 }
11161120
@@ -1119,7 +1123,13 @@ private Document decryptAssertion(Document dom) throws XPathExpressionException,
11191123 throw new ValidationError ("No /samlp:Response/saml:EncryptedAssertion/xenc:EncryptedData element found" , ValidationError .MISSING_ENCRYPTED_ELEMENT );
11201124 }
11211125 Element encryptedData = (Element ) encryptedDataNodes .item (0 );
1122- Util .decryptElement (encryptedData , key );
1126+
1127+ if (hsm != null ) {
1128+ Util .decryptUsingHsm (encryptedData , hsm );
1129+ } else {
1130+ Util .decryptElement (encryptedData , key );
1131+ }
1132+
11231133
11241134 // We need to Remove the saml:EncryptedAssertion Node
11251135 NodeList AssertionDataNodes = Util .query (dom , "/samlp:Response/saml:EncryptedAssertion/saml:Assertion" );
@@ -1138,7 +1148,7 @@ private Document decryptAssertion(Document dom) throws XPathExpressionException,
11381148 }
11391149
11401150 /**
1141- * @return the SAMLResponse XML, If the Assertion of the SAMLResponse was encrypted,
1151+ * @return the SAMLResponse XML, If the Assertion of the SAMLResponse was encrypted,
11421152 * returns the XML with the assertion decrypted
11431153 */
11441154 public String getSAMLResponseXml () {
@@ -1148,11 +1158,11 @@ public String getSAMLResponseXml() {
11481158 } else {
11491159 xml = samlResponseString ;
11501160 }
1151- return xml ;
1161+ return xml ;
11521162 }
11531163
11541164 /**
1155- * @return the SAMLResponse Document, If the Assertion of the SAMLResponse was encrypted,
1165+ * @return the SAMLResponse Document, If the Assertion of the SAMLResponse was encrypted,
11561166 * returns the Document with the assertion decrypted
11571167 */
11581168 protected Document getSAMLResponseDocument () {
0 commit comments