@@ -366,7 +366,7 @@ const libSaml = () => {
366366 * - The first element is `true` if the signature is valid, `false` otherwise.
367367 * - The second element is the cryptographically authenticated assertion node as a string, or `null` if not found.
368368 */
369- verifySignature ( xml : string , opts : SignatureVerifierOptions ) {
369+ verifySignature ( xml : string , opts : SignatureVerifierOptions ) : [ boolean , string | null ] {
370370 const { dom } = getContext ( ) ;
371371 const doc = dom . parseFromString ( xml ) ;
372372
@@ -395,10 +395,9 @@ const libSaml = () => {
395395
396396 // guarantee to have a signature in saml response
397397 if ( selection . length === 0 ) {
398- throw new Error ( 'ERR_ZERO_SIGNATURE' ) ;
398+ return [ false , null ] ; // we return false now
399399 }
400400
401-
402401 // need to refactor later on
403402 for ( const signatureNode of selection ) {
404403 const sig = new SignedXml ( ) ;
@@ -457,44 +456,50 @@ const libSaml = () => {
457456
458457 sig . loadSignature ( signatureNode ) ;
459458
460- doc . removeChild ( signatureNode ) ;
461-
462459 verified = sig . checkSignature ( doc . toString ( ) ) ;
463460
464461 // immediately throw error when any one of the signature is failed to get verified
465462 if ( ! verified ) {
466- throw new Error ( 'ERR_FAILED_TO_VERIFY_SIGNATURE' ) ;
463+ continue ;
464+ // throw new Error('ERR_FAILED_TO_VERIFY_SIGNATURE');
467465 }
468- // attempt is made to get the signed Reference as a string();
469- // note, we don't have access to the actual signedReferences API unfortunately
470- // mainly a sanity check here for SAML. (Although ours would still be secure, if multiple references are used)
471- if ( ! ( sig . getReferences ( ) . length >= 1 ) ) {
466+ // Require there to be at least one reference that was signed
467+ if ( ! ( sig . getSignedReferences ( ) . length >= 1 ) ) {
472468 throw new Error ( 'NO_SIGNATURE_REFERENCES' )
473469 }
474470 const signedVerifiedXML = sig . getSignedReferences ( ) [ 0 ] ;
475471 const rootNode = docParser . parseFromString ( signedVerifiedXML , 'text/xml' ) . documentElement ;
476472 // process the verified signature:
477473 // case 1, rootSignedDoc is a response:
478474 if ( rootNode . localName === 'Response' ) {
479-
480475 // try getting the Xml from the first assertion
481476 const assertions = select (
482477 "./*[local-name()='Assertion']" ,
483478 rootNode
484479 ) ;
480+
481+ const encryptedAssertions = select (
482+ "./*[local-name()='EncryptedAssertion']" ,
483+ rootNode
484+ ) ;
485485 // now we can process the assertion as an assertion
486486 if ( assertions . length === 1 ) {
487487 return [ true , assertions [ 0 ] . toString ( ) ] ;
488+ } else if ( encryptedAssertions . length >= 1 ) {
489+ return [ true , rootNode . toString ( ) ] ; // we need to return a Response node, which will be decrypted later
490+ } else {
491+ // something has gone seriously wrong here.
492+ // we don't have any assertion to give back
493+ return [ true , null ]
488494 }
489495 } else if ( rootNode . localName === 'Assertion' ) {
490496 return [ true , rootNode . toString ( ) ] ;
491497 } else {
492498 return [ true , null ] ; // signature is valid. But there is no assertion node here. It could be metadata node, hence return null
493499 }
494500 } ;
501+ return [ false , null ] ; // we didn't verify anything, none of the signatures are valid
495502
496- // something has gone seriously wrong if we are still here
497- throw new Error ( 'ERR_ZERO_SIGNATURE' ) ;
498503
499504 /*
500505 // response must be signed, either entire document or assertion
0 commit comments