@@ -38,6 +38,13 @@ class OneLogin_Saml2_Response
3838     */ 
3939    public  $ encryptedfalse ;
4040
41+     /** 
42+      * The response contains an encrypted nameId in the assertion. 
43+      * 
44+      * @var bool 
45+      */ 
46+     public  $ encryptedNameIdfalse ;
47+ 
4148    /** 
4249     * After validation, if it fail this var has the cause of the problem 
4350     * @var string 
@@ -200,14 +207,12 @@ public function isValid($requestId = null)
200207                    );
201208                }
202209
203-                 if  ($ security'wantNameIdEncrypted ' ]) {
204-                     $ encryptedIdNodes$ this _queryAssertion ('/saml:Subject/saml:EncryptedID/xenc:EncryptedData ' );
205-                     if  ($ encryptedIdNodeslength  != 1 ) {
206-                         throw  new  OneLogin_Saml2_ValidationError (
207-                             "The NameID of the Response is not encrypted and the SP requires it " ,
208-                             OneLogin_Saml2_ValidationError::NO_ENCRYPTED_NAMEID 
209-                         );
210-                     }
210+                 $ this encryptedNameId  = $ this encryptedNameId  || $ this _queryAssertion ('/saml:Subject/saml:EncryptedID/xenc:EncryptedData ' )->length  > 0 ;
211+                 if  (!$ this encryptedNameId  && $ security'wantNameIdEncrypted ' ]) {
212+                     throw  new  OneLogin_Saml2_ValidationError (
213+                         "The NameID of the Response is not encrypted and the SP requires it " ,
214+                         OneLogin_Saml2_ValidationError::NO_ENCRYPTED_NAMEID 
215+                     );
211216                }
212217
213218                // Validate Conditions element exists 
@@ -366,17 +371,6 @@ public function isValid($requestId = null)
366371                }
367372            }
368373
369-             // Detect case not supported 
370-             if  ($ this encrypted ) {
371-                 $ encryptedIDNodesquery ($ this decryptedDocument , '/samlp:Response/saml:Assertion/saml:Subject/saml:EncryptedID ' );
372-                 if  ($ encryptedIDNodeslength  > 0 ) {
373-                     throw  new  OneLogin_Saml2_ValidationError (
374-                         'SAML Response that contains a an encrypted Assertion with encrypted nameId is not supported. ' ,
375-                         OneLogin_Saml2_ValidationError::NOT_SUPPORTED 
376-                     );
377-                 }
378-             }
379- 
380374            if  (empty ($ signedElements$ hasSignedResponse$ hasSignedAssertion
381375                throw  new  OneLogin_Saml2_ValidationError (
382376                    'No Signature found. SAML Response rejected ' ,
@@ -585,9 +579,15 @@ public function getNameIdData()
585579        if  ($ encryptedIdDataEntrieslength  == 1 ) {
586580            $ encryptedData$ encryptedIdDataEntriesitem (0 );
587581
588-             $ key$ this _settings ->getSPkey ();
582+             $ pem$ this _settings ->getSPkey ();
583+             if  (empty ($ pem
584+                 throw  new  OneLogin_Saml2_Error (
585+                     "No private key available, check settings " ,
586+                     OneLogin_Saml2_Error::PRIVATE_KEY_NOT_FOUND 
587+                 );
588+             }
589589            $ seckeynew  XMLSecurityKey (XMLSecurityKey::RSA_1_5 , array ('type ' =>'private ' ));
590-             $ seckeyloadKey ($ key 
590+             $ seckeyloadKey ($ pem 
591591
592592            $ nameIddecryptElement ($ encryptedData$ seckey
593593
@@ -1139,6 +1139,17 @@ protected function _decryptAssertion($dom)
11391139        if  ($ checkfalse ) {
11401140            throw  new  Exception ('Error: string from decrypted assertion could not be loaded into a XML document ' );
11411141        }
1142+ 
1143+         // check if the decrypted assertion contains an encryptedID 
1144+         $ encryptedID$ decryptedgetElementsByTagName ('EncryptedID ' )->item (0 );
1145+         if  ($ encryptedID
1146+             // decrypt the encryptedID 
1147+             $ this encryptedNameId  = true ;
1148+             $ encryptedData$ encryptedIDgetElementsByTagName ('EncryptedData ' )->item (0 );
1149+             $ nameId$ this decryptNameId ($ encryptedData$ pem
1150+             OneLogin_Saml2_Utils::treeCopyReplace ($ encryptedID$ nameId
1151+         }
1152+ 
11421153        if  ($ encDataparentNode  instanceof  DOMDocument) {
11431154            return  $ decrypted
11441155        } else  {
@@ -1171,6 +1182,46 @@ protected function _decryptAssertion($dom)
11711182        }
11721183    }
11731184
1185+     /** 
1186+      * Decrypt EncryptedID element 
1187+      * 
1188+      * @param \DOMElement $encryptedData The encrypted data. 
1189+      * @param string     $key            The private key 
1190+      * 
1191+      * @return \DOMElement  The decrypted element. 
1192+      * 
1193+      * @throws OneLogin_Saml2_Error 
1194+      * @throws OneLogin_Saml2_ValidationError 
1195+      */ 
1196+     private  function  decryptNameId (\DOMElement   $ encryptedDatastring  $ pem
1197+     {
1198+         $ objencnew  XMLSecEnc ();
1199+         $ encData$ objenclocateEncryptedData ($ encryptedData
1200+         $ objencsetNode ($ encData
1201+         $ objenctype  = $ encDatagetAttribute ("Type " );
1202+         if  (!$ objKey$ objenclocateKey ()) {
1203+             throw  new  OneLogin_Saml2_ValidationError (
1204+                 "Unknown algorithm " ,
1205+                 ValidationError::KEY_ALGORITHM_ERROR 
1206+             );
1207+         }
1208+         $ keynull ;
1209+         if  ($ objKeyInfo$ objenclocateKeyInfo ($ objKey
1210+             if  ($ objKeyInfoisEncrypted ) {
1211+                 $ objencKey$ objKeyInfoencryptedCtx ;
1212+                 $ objKeyInfoloadKey ($ pemfalse , false );
1213+                 $ key$ objencKeydecryptKey ($ objKeyInfo
1214+             } else  {
1215+                 // symmetric encryption key support 
1216+                 $ objKeyInfoloadKey ($ pemfalse , false );
1217+             }
1218+         }
1219+         if  (empty ($ objKeykey )) {
1220+             $ objKeyloadKey ($ key
1221+         }
1222+         return  OneLogin_Saml2_Utils::decryptElement ($ encryptedData$ objKey
1223+     }
1224+ 
11741225    /** 
11751226     * After execute a validation process, if fails this method returns the cause 
11761227     * 
0 commit comments