diff --git a/lib/saml2.coffee b/lib/saml2.coffee
index defac31..6fd0b12 100644
--- a/lib/saml2.coffee
+++ b/lib/saml2.coffee
@@ -422,11 +422,12 @@ add_namespaces_to_child_assertions = (xml_string) ->
# Takes a DOM of a saml_response, private keys with which to attempt decryption and the
# certificate(s) of the identity provider that issued it and will return a user object containing
# the attributes or an error if keys are incorrect or the response is invalid.
-parse_authn_response = (saml_response, sp_private_keys, idp_certificates, allow_unencrypted, ignore_signature, require_session_index, cb) ->
+parse_authn_response = (saml_response, sp_private_keys, idp_certificates, allow_unencrypted, ignore_signature, require_session_index, ignore_timing, notbefore_skew, sp_audience, cb) ->
user = {}
async.waterfall [
(cb_wf) ->
+ # Decrypt the assertion
decrypt_assertion saml_response, sp_private_keys, (err, result) ->
return cb_wf null, result unless err?
return cb_wf err, result unless allow_unencrypted and err.message == "Expected 1 EncryptedAssertion; found 0."
@@ -435,6 +436,7 @@ parse_authn_response = (saml_response, sp_private_keys, idp_certificates, allow_
return cb_wf new Error("Expected 1 Assertion or 1 EncryptedAssertion; found #{assertion.length}")
cb_wf null, assertion[0].toString()
(result, cb_wf) ->
+ # Validate the signature
debug result
if ignore_signature
return cb_wf null, (new xmldom.DOMParser()).parseFromString(result)
@@ -450,25 +452,54 @@ parse_authn_response = (saml_response, sp_private_keys, idp_certificates, allow_
for sd in signed_data
signed_dom = (new xmldom.DOMParser()).parseFromString(sd)
+
assertion = signed_dom.getElementsByTagNameNS(XMLNS.SAML, 'Assertion')
if assertion.length is 1
return cb_wf null, signed_dom
+
+ encryptedAssertion = signed_dom.getElementsByTagNameNS(XMLNS.SAML, 'EncryptedAssertion')
+ if encryptedAssertion.length is 1
+ return decrypt_assertion saml_response, sp_private_keys, (err, result) ->
+ return cb_wf null, (new xmldom.DOMParser()).parseFromString(result) unless err?
+ return cb_wf err
return cb_wf new Error("Signed data did not contain a SAML Assertion!")
return cb_wf new Error("SAML Assertion signature check failed! (checked #{idp_certificates.length} certificate(s))")
(decrypted_assertion, cb_wf) ->
- try
- session_info = get_session_info decrypted_assertion, require_session_index
- user.name_id = get_name_id decrypted_assertion
- user.session_index = session_info.index
- if session_info.not_on_or_after?
- user.session_not_on_or_after = session_info.not_on_or_after
-
- assertion_attributes = parse_assertion_attributes decrypted_assertion
- user = _.extend user, pretty_assertion_attributes(assertion_attributes)
- user = _.extend user, attributes: assertion_attributes
- cb_wf null, { user }
- catch err
- return cb_wf err
+ # Validate the assertion conditions
+ conditions = decrypted_assertion.getElementsByTagNameNS(XMLNS.SAML, 'Conditions')[0]
+ if conditions?
+ if ignore_timing != true
+ for attribute in conditions.attributes
+ condition = attribute.name.toLowerCase()
+ if condition == 'notbefore' and Date.parse(attribute.value) > Date.now() + (notbefore_skew * 1000)
+ return cb_wf new SAMLError('SAML Response is not yet valid', {NotBefore: attribute.value})
+ if condition == 'notonorafter' and Date.parse(attribute.value) <= Date.now()
+ return cb_wf new SAMLError('SAML Response is no longer valid', {NotOnOrAfter: attribute.value})
+
+ audience_restriction = conditions.getElementsByTagNameNS(XMLNS.SAML, 'AudienceRestriction')[0]
+ audiences = audience_restriction?.getElementsByTagNameNS(XMLNS.SAML, 'Audience')
+ if audiences?.length > 0
+ validAudience = _.find audiences, (audience) ->
+ audienceValue = audience.firstChild?.data?.trim()
+ !_.isEmpty(audienceValue?.trim()) and (
+ (_.isRegExp(sp_audience) and sp_audience.test(audienceValue)) or
+ (_.isString(sp_audience) and sp_audience.toLowerCase() == audienceValue.toLowerCase())
+ )
+ if !validAudience?
+ return cb_wf new SAMLError('SAML Response is not valid for this audience')
+ return cb_wf null, decrypted_assertion
+ (validated_assertion, cb_wf) ->
+ # Populate attributes
+ session_info = get_session_info validated_assertion, require_session_index
+ user.name_id = get_name_id validated_assertion
+ user.session_index = session_info.index
+ if session_info.not_on_or_after?
+ user.session_not_on_or_after = session_info.not_on_or_after
+
+ assertion_attributes = parse_assertion_attributes validated_assertion
+ user = _.extend user, pretty_assertion_attributes(assertion_attributes)
+ user = _.extend user, attributes: assertion_attributes
+ cb_wf null, { user }
], cb
parse_logout_request = (dom) ->
@@ -605,28 +636,6 @@ module.exports.ServiceProvider =
response.type = 'authn_response'
- conditions = saml_response.getElementsByTagNameNS(XMLNS.SAML, 'Conditions')[0]
- if conditions?
- if options.ignore_timing != true
- for attribute in conditions.attributes
- condition = attribute.name.toLowerCase()
- if condition == 'notbefore' and Date.parse(attribute.value) > Date.now() + (options.notbefore_skew * 1000)
- return cb_wf new SAMLError('SAML Response is not yet valid', {NotBefore: attribute.value})
- if condition == 'notonorafter' and Date.parse(attribute.value) <= Date.now()
- return cb_wf new SAMLError('SAML Response is no longer valid', {NotOnOrAfter: attribute.value})
-
- audience_restriction = conditions.getElementsByTagNameNS(XMLNS.SAML, 'AudienceRestriction')[0]
- audiences = audience_restriction?.getElementsByTagNameNS(XMLNS.SAML, 'Audience')
- if audiences?.length > 0
- validAudience = _.find audiences, (audience) ->
- audienceValue = audience.firstChild?.data?.trim()
- !_.isEmpty(audienceValue?.trim()) and (
- (_.isRegExp(options.audience) and options.audience.test(audienceValue)) or
- (_.isString(options.audience) and options.audience.toLowerCase() == audienceValue.toLowerCase())
- )
- if !validAudience?
- return cb_wf new SAMLError('SAML Response is not valid for this audience')
-
parse_authn_response(
saml_response,
[@private_key].concat(@alt_private_keys),
@@ -634,6 +643,9 @@ module.exports.ServiceProvider =
options.allow_unencrypted_assertion,
options.ignore_signature,
options.require_session_index,
+ options.ignore_timing,
+ options.notbefore_skew,
+ options.audience
cb_wf)
when saml_response.getElementsByTagNameNS(XMLNS.SAMLP, 'LogoutResponse').length is 1
diff --git a/test/data/response_notbefore_future_encrypted.xml b/test/data/response_notbefore_future_encrypted.xml
new file mode 100644
index 0000000..a3a8e3e
--- /dev/null
+++ b/test/data/response_notbefore_future_encrypted.xml
@@ -0,0 +1 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIElEPSJfMiIgVmVyc2lvbj0iMi4wIiBJblJlc3BvbnNlVG89Il8xIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9hc3NlcnQiPg0KICAgIDxzYW1scDpTdGF0dXM+DQogICAgICAgIDxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz4NCiAgICA8L3NhbWxwOlN0YXR1cz4NCiAgICANCjxzYW1sOkVuY3J5cHRlZEFzc2VydGlvbj48eGVuYzpFbmNyeXB0ZWREYXRhIHhtbG5zOnhlbmM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jIyIgeG1sbnM6ZHNpZz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyIgVHlwZT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjRWxlbWVudCI+PHhlbmM6RW5jcnlwdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI2FlczEyOC1jYmMiLz48ZHNpZzpLZXlJbmZvIHhtbG5zOmRzaWc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjx4ZW5jOkVuY3J5cHRlZEtleT48eGVuYzpFbmNyeXB0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjcnNhLW9hZXAtbWdmMXAiLz48eGVuYzpDaXBoZXJEYXRhPjx4ZW5jOkNpcGhlclZhbHVlPlduVU5MUnF0SEdrWE9uMXRKc2FWaDNBeXp2TDkrRnJKWWNoeE5BbkZDcGVWbG5nSC9oM3BSOFlLdG5BWEtmZHVSL2tVbXVRNFU4ZW14cDc3OXdjYzNqY2NEajJFcXZTUlhsNDM1MkhrQVV3T2Y2eWc3RURILzFKeFMrbHJRdURCd08yTCtmbVo1ckczdjdLeHlqc29GamMrQzhaNGNKaE5LWDcraFMyUWxBcHRDekNmNUhwaWk4TG9KVTk5bXUrZHJHckZZZ1A5SWV4QzZyWGRKSUNjM2NwWlh2d3ZKNDJYcXh5alNvTzU3OWFZTFdLZFdjdlVRVkhXaExIbTl4TTFkOVRDSGFRK0Q0NHlMM2xLUGViQVNMZGxwVWZ3S2V1UEs2MkZkN052ODVac2lWMm9WeEdzUmVmYk9zRk5hMEduTFNKSEpTYmxGYmZDQnlLaHJIV3BTQT09PC94ZW5jOkNpcGhlclZhbHVlPjwveGVuYzpDaXBoZXJEYXRhPjwveGVuYzpFbmNyeXB0ZWRLZXk+PC9kc2lnOktleUluZm8+DQogICA8eGVuYzpDaXBoZXJEYXRhPg0KICAgICAgPHhlbmM6Q2lwaGVyVmFsdWU+blVBYjk3SW0rbzBPN0pRd3V1R1dNdHpPR0hMZnFxVzVlVGVjejZYd0VldjBtQ3BsbHlRUzhHYnFIWHA1RWpVcXg1czZja3J5UXdKK2svT09uUTBFVnVCMStER1V6TmNjODJGWTF0NE9NRjJiRnVtUVBvK29GbUUyMWpHMnJabzhZSFdyMzNIVDNibzVYZUxPQ1JwTFRGRy9ZZ2lOSDRZN0dZblR4Sy9XZUtlN1JmY092QTZiWXBReWc0Qm1hdTZaeHBZaU42bmdMbFFqMmt4bFJHSG5yMWY0eFVGbjF0RVhvYThGTTNBTndiSlV2K1dyWEt4ZjlnZDNWSG9XL2VvVDVrK3pxLy9VejN4Wi9QTVhDa3loeGp0cmsxYWxkVTB5cEIxblV0UGo0N0lDNEJId2l1dEpneExMaTRrb2tRb0J0dU1PNzFyQ0c3bTFVUFI2Yy9idXlpaGMvZ0RuUTVWditzT3NndFA1NndoeTdoeVl1Y3hQRDUxMElSNlcySW5kMFp5eXNwcDRkM1JtZXBzSUZNRHNmcTE4VzZMWmFUQ1FSd0xyNTZORlJibjBaempEYy9GNEFhU1pleFdCTEg5VG9CcXdDVnpDNmorZjdGMWhEMHFQMU9jZ1dvcERFeHlTVllCNUtKQlIwUDNIRFBWdlg5VmNVN2lLVklQTUlRWEhVRnlMQjlZWjZBTCt4L1AvR2k1UG93MEh6bmU0TTFzQzk3eWc1RHU4WlQvcXM4cTBoVnJneTgweVR0Y3VwK1ZIZU96M3lxVWlWMDZJVlR1eStDRzZWbTR6am13RjB2b3BuanFKcElXRjMvN3ZZc1FmYlNJbld0OUdNdGYvQTgyNW4vRi8vMVpwRjFUL0pxTFRwR3NIczRRYmREdDJoR3pudThyWnpnMjZOT1dLR0wwVnZtdEJncmVWT3VnclYrV3FDNnVsZC9KWWFFZjFTSnNNOTZGcXdyME5tSXdWRFhJM09zZXc3QkRkTDVTRUV0UFRheHFXbVlybGpmRmZ0TXNLbGFBenU3SFpjU1V2Zi8wMTRobUJiaTBaY3N1cmVzQVBYMlFOcUJCaDJRYm95TS90VStxZSt2MXVsMTA3K2RLNFRnZU5oQWtsMHFnU1JsMmVNTkJDWUVPREZ0d0RmSVE3T3lLT1pFMzJsVzhmeGlMV3lleDdxczlDd2pCODRHeCtGMjVlSllPU0xJL0xvMUo4eE9McVN1UnVIYjRNNjR6bUZyalBENHdjcUZ2bTQ4d2UzWlVPVUVIREMyWDY4MjVoOWRvRGsrRDFtZFJoN3B5SEd0QmR6NTR4Tk5lajY5ZG1PNEJBcWRIZXhBNkNPTiszTndNYW02WmJoZm5RNkpscGVIUmtRZzkyeGh1d2NwWmo5bGpkSTl2bFM5T05XS09INGYwY3R1NEc3eFNjcGpDZkpBWlhuM2ZjeEg2U1VXY2g1UG1PYWFVazdCRmRLdTdzYitXcjNFWWsxd2F4aWtuNjNHdXJra1VhL2YrY1dDRWJZVXpZdWlHOUpkUVF1K1BHSmVjaXpKc21hL2lRTjl4NUxGUFNnM040L0RKZnVuRU9zN2tvVzhGR00zVWdnZ3h1N1VxY3lRNVphLzdVVmxoMmhtUFpsc09TNFlSNjh2VHFmaVYwQldsdmNoaE5ORTFxL3RYTWMxeHNhbGJVOS85UVcxcGxYTzMyb0F3ajVnSG0rcERSSUluakRKMDkxTFEzdnNweGVBbWJwOWJBYisyRC9DSXJaU21MWVhZMTY4aGFpVFFPYURHZXdtOElncm15UnhEWHkwWDFOU0FhL1U5Szd4cjZWNVhoaVVBVnVyVGN3Y1pnTVNOS29GMllwMlo5ajE4d0hpU09nd1Rna25UN0Z4K3BPMVdRMVBPVFJkN2JGa3RlMHR2a1BQaCttSk40cmN2N2ZpT3ljaEVnckdYNUo4YVp5ZUk5L2F6Z0RCVzdFdE1IRWNIakkyTFR0bEdXaG8wVjhBbzVFd09zd3lkRU5iTUFFNVBoWFhNc29kUXdadm1LZEt6U1AzWkR1VEhSUWVHcTdwc2NQc20xWERtZWxZOFFEeC84RUFpNzAwNy9leXA0Z1BKZVBTVlF3bHJGamFzS20rS1dQc1NqWG5CTGZ1TzVjOFZ6SDFhMDk5dlBxYTVZQzFQUUdPd3B4ZENxUG5HRmxuK2pTa05oaTNQcTZKNnZiTjVmbXBQS3VuWks3Y2E5b3VXNGlYRTBoUGhPY3l4bWZFeVV4R3NPQWtLSlBlZzdSVjRMUnpDNnB0cElDc0NXNU9PdW5nblhVSElWVnlRN0hXbDhBTStHclI2VjBidjBEcjh3U29IMmpjakRMclYxRHhtZktjd1kxV2JVNHZEWlBKYjFBZy85c2VJNEdwTmIyOFdmY3I5QUNhdlVsKzJEVjR2VXFKckRQRTFwRzFUVm1uUHhzQnNIbURiTThGL0FKUXRjRkNNYjRQcDdXbytrU3VWNVVibDlrR0VDMitGTkVTWlJsdlUxTVNNOFVBeGhkOHp0Tk1xcitVMTFDM2JlcWo2WjFpT1dDN21VU1dJMjByT2crTi9CY0pVUkZ4Mmo5QVpnS2J6dnBHcG4rSURSUXB2Sy9Saz08L3hlbmM6Q2lwaGVyVmFsdWU+DQogICA8L3hlbmM6Q2lwaGVyRGF0YT4NCjwveGVuYzpFbmNyeXB0ZWREYXRhPjwvc2FtbDpFbmNyeXB0ZWRBc3NlcnRpb24+PC9zYW1scDpSZXNwb25zZT4=
\ No newline at end of file
diff --git a/test/data/response_notbefore_future_encrypted_decoded.xml b/test/data/response_notbefore_future_encrypted_decoded.xml
new file mode 100644
index 0000000..a2c2095
--- /dev/null
+++ b/test/data/response_notbefore_future_encrypted_decoded.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+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
+
+
diff --git a/test/data/response_notbefore_future_encrypted_then_signed.xml b/test/data/response_notbefore_future_encrypted_then_signed.xml
new file mode 100644
index 0000000..b5dab92
--- /dev/null
+++ b/test/data/response_notbefore_future_encrypted_then_signed.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ VNpShLvByJ91Q9vRHRCHCpMrj8I=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
+
+
\ No newline at end of file
diff --git a/test/data/response_notbefore_future_encrypted_then_signed_base64.xml b/test/data/response_notbefore_future_encrypted_then_signed_base64.xml
new file mode 100644
index 0000000..b04f802
--- /dev/null
+++ b/test/data/response_notbefore_future_encrypted_then_signed_base64.xml
@@ -0,0 +1,99 @@
+PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c2FtbHA6UmVzcG9uc2UgeG1sbnM6c2FtbHA9InVybjpv
+YXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6c2FtbD0idXJuOm9hc2lzOm5h
+bWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9InBmeDk1ZmI2MjQ1LTI3YWUtNjA5ZC0xYzlk
+LWQxN2NmY2EwNTU2NyIgVmVyc2lvbj0iMi4wIiBJblJlc3BvbnNlVG89Il8xIiBEZXN0aW5hdGlv
+bj0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9hc3NlcnQiPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9
+Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPg0KICA8ZHM6U2lnbmVkSW5mbz48
+ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIw
+MDEvMTAveG1sLWV4Yy1jMTRuIyIvPg0KICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGht
+PSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4NCiAgPGRzOlJl
+ZmVyZW5jZSBVUkk9IiNwZng5NWZiNjI0NS0yN2FlLTYwOWQtMWM5ZC1kMTdjZmNhMDU1NjciPjxk
+czpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8y
+MDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3Jp
+dGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5z
+Zm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAv
+MDkveG1sZHNpZyNzaGExIi8+PGRzOkRpZ2VzdFZhbHVlPlZOcFNoTHZCeUo5MVE5dlJIUkNIQ3BN
+cmo4ST08L2RzOkRpZ2VzdFZhbHVlPjwvZHM6UmVmZXJlbmNlPjwvZHM6U2lnbmVkSW5mbz48ZHM6
+U2lnbmF0dXJlVmFsdWU+dHV3SGg0a2NKSkFaSXpSd1lTOXJ6TmtDSUY0SEdVOVloTEo5TndmdDQ4
+YXhDSnJVajBoa2lJZFpmMyt2aW42WVVGajRKU3RQSzBZQkVJUXNCNXB4cjkxSlpXbllMa290Z0Qv
+VCtyS2hWa3p4T01uM0djSzI0ODU2Y1NGbVFMbUw1M0tScXpZU0pJRFk1eTBjNkUva3hEZTlyK1BN
+RzQvY2g4M21qR09TUGdITUZEWWViSUdFcHcrN1k3OXFjR1RmWVVybng3b0lPT1VzcFpOdWFTdjJ5
+cjNncUFtRzhaTTA2L0Y4Rnp1bmJXMlMwblA4eW12MDl5ZmhvWmY3WHRKQUxEQzZmbXcvTTBjemJX
+V01WdStPQzlwY1JtQ29kNXRvNWt1ZDRCSW9HSUxDcHNMYjlqeTh1S1BQcFB1dUZoMFU4c01pajQ1
+QTNJSEFKd2kyYnRVSjZRPT08L2RzOlNpZ25hdHVyZVZhbHVlPg0KPGRzOktleUluZm8+PGRzOlg1
+MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJREdUQ0NBZ0dnQXdJQkFnSUpBSlFkL1JTSTUx
+dEtNQTBHQ1NxR1NJYjNEUUVCQlFVQU1DTXhJVEFmQmdOVkJBb01HRWx1ZEdWeWJtVjBJRmRwWkdk
+cGRITWdVSFI1SUV4MFpEQWVGdzB4TkRBek1UZ3lNRE14TUROYUZ3MHlOREF6TVRjeU1ETXhNRE5h
+TUNNeElUQWZCZ05WQkFvTUdFbHVkR1Z5Ym1WMElGZHBaR2RwZEhNZ1VIUjVJRXgwWkRDQ0FTSXdE
+UVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTHhlcmtVUk00Njc4bnVmdDdMUUk3
+ZzVqeVNVSHdIUk9DaGVBVnQra2VtVmVnN0pORnpQYUYxQU9tMm40UzR4cTRhSTAzL0hXNzI1c3ha
+VEpJaXQ2VEJTaWJvQzZ5dU4vY00vbXp3amhiVitnQ1FSejJEckk3TWtHR3VqbjViSCt2dTNxenhw
+WFNvU3Fya3VIV3JkZU5HSExCUDBDLzBwSFUyUlpKT0dHMWgrUyt0aVcrRUdLejFQSXRmTDdtZzhW
+MkVoaWVVQllMZ3hHeFZzTll3dEw3ZFdjaWI3WTQ0NzZZeDI1ZDM0azFJZ0Jydmt5bzN5eDFHaXp3
+RzAwKzBGUjMveWtNWU9leHdpWnpDcktiWm96MUJmMGl0dTl2cWpiekR5OWdia0VRQkljWnhwRTVH
+T3dBdHlMTktnQmRTeUZqM3piUlRVSXlPdE5kVHY1Q04zNFdNQ0F3RUFBYU5RTUU0d0hRWURWUjBP
+QkJZRUZGSVE3cjBzb3BuL2g3OXBYMXFpUWFXemNNR29NQjhHQTFVZEl3UVlNQmFBRkZJUTdyMHNv
+cG4vaDc5cFgxcWlRYVd6Y01Hb01Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFRkJR
+QURnZ0VCQUhjTWZFQXN3bVNWUnNSb2ZhaWJMZVA3MkhtOHp1dGIyNW50cG0zZ2NhaytEaWtFNFp3
+SS9IR1l3MllwekdaOXY4eXN4Yy9lZ2M3bExLbit5T2xPYlJkSUZKbVh1NU1TZjBHNkQ1L05SdjhS
+YWdDYTN4NktnamdaT1R4NU1OUjhLWDJ5NzliT3VwTU1qL1BuSTRqQTJqWGJGRlNVd3o2TVFGUC80
+VnlobHBZcWRobjNRcHV1OFlWclc3S0hjWW02UlFIbHJDNzBXQ2NmWkVXTEVIalUvdVJ3RksxK2hN
+c1VMYmJ1M084L3ptSnNVNk80YjJaYmpDb1B2c0FaWVBLMC9PSllieVV4ZnBmSFo4MkttRjI2MUhF
+S0ljaEVXUGtwaVppdnRyUGZJT1pGeTZpVjRidDBQVC9TR29JYktPeGgwTnh4eXQybUhucGQwMzB0
+VVhOWUxUYz08L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48
+L2RzOlNpZ25hdHVyZT4NCiAgICA8c2FtbHA6U3RhdHVzPg0KICAgICAgICA8c2FtbHA6U3RhdHVz
+Q29kZSBWYWx1ZT0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnN0YXR1czpTdWNjZXNzIi8+
+DQogICAgPC9zYW1scDpTdGF0dXM+DQogICAgDQo8c2FtbDpFbmNyeXB0ZWRBc3NlcnRpb24+PHhl
+bmM6RW5jcnlwdGVkRGF0YSB4bWxuczp4ZW5jPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3ht
+bGVuYyMiIHhtbG5zOmRzaWc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiIFR5
+cGU9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI0VsZW1lbnQiPjx4ZW5jOkVuY3J5
+cHRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNh
+ZXMxMjgtY2JjIi8+PGRzaWc6S2V5SW5mbyB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8y
+MDAwLzA5L3htbGRzaWcjIj48eGVuYzpFbmNyeXB0ZWRLZXk+PHhlbmM6RW5jcnlwdGlvbk1ldGhv
+ZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3JzYS1vYWVwLW1n
+ZjFwIi8+PHhlbmM6Q2lwaGVyRGF0YT48eGVuYzpDaXBoZXJWYWx1ZT5XblVOTFJxdEhHa1hPbjF0
+SnNhVmgzQXl6dkw5K0ZySlljaHhOQW5GQ3BlVmxuZ0gvaDNwUjhZS3RuQVhLZmR1Ui9rVW11UTRV
+OGVteHA3Nzl3Y2MzamNjRGoyRXF2U1JYbDQzNTJIa0FVd09mNnlnN0VESC8xSnhTK2xyUXVEQndP
+MkwrZm1aNXJHM3Y3S3h5anNvRmpjK0M4WjRjSmhOS1g3K2hTMlFsQXB0Q3pDZjVIcGlpOExvSlU5
+OW11K2RyR3JGWWdQOUlleEM2clhkSklDYzNjcFpYdnd2SjQyWHF4eWpTb081NzlhWUxXS2RXY3ZV
+UVZIV2hMSG05eE0xZDlUQ0hhUStENDR5TDNsS1BlYkFTTGRscFVmd0tldVBLNjJGZDdOdjg1WnNp
+VjJvVnhHc1JlZmJPc0ZOYTBHbkxTSkhKU2JsRmJmQ0J5S2hySFdwU0E9PTwveGVuYzpDaXBoZXJW
+YWx1ZT48L3hlbmM6Q2lwaGVyRGF0YT48L3hlbmM6RW5jcnlwdGVkS2V5PjwvZHNpZzpLZXlJbmZv
+Pg0KICAgPHhlbmM6Q2lwaGVyRGF0YT4NCiAgICAgIDx4ZW5jOkNpcGhlclZhbHVlPm5VQWI5N0lt
+K28wTzdKUXd1dUdXTXR6T0dITGZxcVc1ZVRlY3o2WHdFZXYwbUNwbGx5UVM4R2JxSFhwNUVqVXF4
+NXM2Y2tyeVF3SitrL09PblEwRVZ1QjErREdVek5jYzgyRlkxdDRPTUYyYkZ1bVFQbytvRm1FMjFq
+RzJyWm84WUhXcjMzSFQzYm81WGVMT0NScExURkcvWWdpTkg0WTdHWW5UeEsvV2VLZTdSZmNPdkE2
+YllwUXlnNEJtYXU2WnhwWWlONm5nTGxRajJreGxSR0hucjFmNHhVRm4xdEVYb2E4Rk0zQU53YkpV
+ditXclhLeGY5Z2QzVkhvVy9lb1Q1ayt6cS8vVXozeFovUE1YQ2t5aHhqdHJrMWFsZFUweXBCMW5V
+dFBqNDdJQzRCSHdpdXRKZ3hMTGk0a29rUW9CdHVNTzcxckNHN20xVVBSNmMvYnV5aWhjL2dEblE1
+VnYrc09zZ3RQNTZ3aHk3aHlZdWN4UEQ1MTBJUjZXMkluZDBaeXlzcHA0ZDNSbWVwc0lGTURzZnEx
+OFc2TFphVENRUndMcjU2TkZSYm4wWnpqRGMvRjRBYVNaZXhXQkxIOVRvQnF3Q1Z6QzZqK2Y3RjFo
+RDBxUDFPY2dXb3BERXh5U1ZZQjVLSkJSMFAzSERQVnZYOVZjVTdpS1ZJUE1JUVhIVUZ5TEI5WVo2
+QUwreC9QL0dpNVBvdzBIem5lNE0xc0M5N3lnNUR1OFpUL3FzOHEwaFZyZ3k4MHlUdGN1cCtWSGVP
+ejN5cVVpVjA2SVZUdXkrQ0c2Vm00emptd0Ywdm9wbmpxSnBJV0YzLzd2WXNRZmJTSW5XdDlHTXRm
+L0E4MjVuL0YvLzFacEYxVC9KcUxUcEdzSHM0UWJkRHQyaEd6bnU4clp6ZzI2Tk9XS0dMMFZ2bXRC
+Z3JlVk91Z3JWK1dxQzZ1bGQvSllhRWYxU0pzTTk2RnF3cjBObUl3VkRYSTNPc2V3N0JEZEw1U0VF
+dFBUYXhxV21ZcmxqZkZmdE1zS2xhQXp1N0haY1NVdmYvMDE0aG1CYmkwWmNzdXJlc0FQWDJRTnFC
+QmgyUWJveU0vdFUrcWUrdjF1bDEwNytkSzRUZ2VOaEFrbDBxZ1NSbDJlTU5CQ1lFT0RGdHdEZklR
+N095S09aRTMybFc4ZnhpTFd5ZXg3cXM5Q3dqQjg0R3grRjI1ZUpZT1NMSS9MbzFKOHhPTHFTdVJ1
+SGI0TTY0em1GcmpQRDR3Y3FGdm00OHdlM1pVT1VFSERDMlg2ODI1aDlkb0RrK0QxbWRSaDdweUhH
+dEJkejU0eE5OZWo2OWRtTzRCQXFkSGV4QTZDT04rM053TWFtNlpiaGZuUTZKbHBlSFJrUWc5Mnho
+dXdjcFpqOWxqZEk5dmxTOU9OV0tPSDRmMGN0dTRHN3hTY3BqQ2ZKQVpYbjNmY3hINlNVV2NoNVBt
+T2FhVWs3QkZkS3U3c2IrV3IzRVlrMXdheGlrbjYzR3Vya2tVYS9mK2NXQ0ViWVV6WXVpRzlKZFFR
+dStQR0plY2l6SnNtYS9pUU45eDVMRlBTZzNONC9ESmZ1bkVPczdrb1c4RkdNM1VnZ2d4dTdVcWN5
+UTVaYS83VVZsaDJobVBabHNPUzRZUjY4dlRxZmlWMEJXbHZjaGhOTkUxcS90WE1jMXhzYWxiVTkv
+OVFXMXBsWE8zMm9Bd2o1Z0htK3BEUklJbmpESjA5MUxRM3ZzcHhlQW1icDliQWIrMkQvQ0lyWlNt
+TFlYWTE2OGhhaVRRT2FER2V3bThJZ3JteVJ4RFh5MFgxTlNBYS9VOUs3eHI2VjVYaGlVQVZ1clRj
+d2NaZ01TTktvRjJZcDJaOWoxOHdIaVNPZ3dUZ2tuVDdGeCtwTzFXUTFQT1RSZDdiRmt0ZTB0dmtQ
+UGgrbUpONHJjdjdmaU95Y2hFZ3JHWDVKOGFaeWVJOS9hemdEQlc3RXRNSEVjSGpJMkxUdGxHV2hv
+MFY4QW81RXdPc3d5ZEVOYk1BRTVQaFhYTXNvZFF3WnZtS2RLelNQM1pEdVRIUlFlR3E3cHNjUHNt
+MVhEbWVsWThRRHgvOEVBaTcwMDcvZXlwNGdQSmVQU1ZRd2xyRmphc0ttK0tXUHNTalhuQkxmdU81
+YzhWekgxYTA5OXZQcWE1WUMxUFFHT3dweGRDcVBuR0ZsbitqU2tOaGkzUHE2SjZ2Yk41Zm1wUEt1
+blpLN2NhOW91VzRpWEUwaFBoT2N5eG1mRXlVeEdzT0FrS0pQZWc3UlY0TFJ6QzZwdHBJQ3NDVzVP
+T3VuZ25YVUhJVlZ5UTdIV2w4QU0rR3JSNlYwYnYwRHI4d1NvSDJqY2pETHJWMUR4bWZLY3dZMVdi
+VTR2RFpQSmIxQWcvOXNlSTRHcE5iMjhXZmNyOUFDYXZVbCsyRFY0dlVxSnJEUEUxcEcxVFZtblB4
+c0JzSG1EYk04Ri9BSlF0Y0ZDTWI0UHA3V28ra1N1VjVVYmw5a0dFQzIrRk5FU1pSbHZVMU1TTThV
+QXhoZDh6dE5NcXIrVTExQzNiZXFqNloxaU9XQzdtVVNXSTIwck9nK04vQmNKVVJGeDJqOUFaZ0ti
+enZwR3BuK0lEUlFwdksvUms9PC94ZW5jOkNpcGhlclZhbHVlPg0KICAgPC94ZW5jOkNpcGhlckRh
+dGE+DQo8L3hlbmM6RW5jcnlwdGVkRGF0YT48L3NhbWw6RW5jcnlwdGVkQXNzZXJ0aW9uPjwvc2Ft
+bHA6UmVzcG9uc2U+
diff --git a/test/data/response_notbefore_future_signed.xml b/test/data/response_notbefore_future_signed.xml
new file mode 100644
index 0000000..7814e25
--- /dev/null
+++ b/test/data/response_notbefore_future_signed.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+ This data has no meaning.
+ http://idp.example.com/metadata.xml
+
+
+ I7HHjuQfXmELXf7TyRClXhzshwQ=K5JAWPa2KVtx2r4s5FN0XagYCUaxlN2OQbbzvqxZRbsnqFhluYaBR0Hlv/aygvGkv7OFBfpvojKsshHxPOArNT7CM1YNhV2RQ9v5IL7A396XvNpWdcMgGRL4FcAEzOcgAwmRYjYUfqChbY7cFKyMvyVVowdE4wGKyYAZiRwC8npbjZNuqTekofheF0fxnYm3CRzT5akztMugY0HHmy9WsochrDtoglwkjrZTSBlgYLGD3Yk7mCZos6IGo9zK6eF/ycPxGqR597WQOtLr9dnmhs0IE3iKQaS2hY2WwoPqJZgDPOoHtFBaDrkVY/JG0ucrg0eVkKtNHRKTYSgzv+JK/w==
+MIIDGTCCAgGgAwIBAgIJAO8HJfrb3JZeMA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xNDAzMTgwMTE3MTdaFw0yNDAzMTcwMTE3MTdaMCMxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFf1kCef6FTPMxQSoThAZGFNmixh8fRDLsUo58pEFwztBRUPWS6s6Ql8mA75aAEdo4+JVyE8QPi5F+fWbnToWkIw7E7YGl6s+EScSMQYHKCLq4mPHPMHtZspFowNp+Vax88SSUo1TKlpVNVIGim8JQ5SRi3p0aD6UAiu9WxQ5s+xHnDwgvQiu3Sa4COl5NQjkC1r2LrhJnJQQiw0hsn1nGgg15jEaDCZa8uPw1EtHv8smoZpjTbwRBVjXtzLskYIRyYLQjvqR+/QAd0XZcav0LdTwQR6obg/CwSgv7qG/WN6t25VIIGQDIUkVMBhLDmCh8QRpTvx1YWumSWW4D2k2kCAwEAAaNQME4wHQYDVR0OBBYEFLpo8Vz1m19xvPmzx+2wf2PaSTIpMB8GA1UdIwQYMBaAFLpo8Vz1m19xvPmzx+2wf2PaSTIpMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALhwpLS6C+97nWrEICI5yetQjexCJGltMESg1llNYjsbIuJ/S4XbrVzhN4nfNGMSbj8rb/9FT6TSru5QLjJQQmj38pqsWtEhR2vBLclqGqEcJfvPMdn1qAJhJfhrs0KUpsX6xFTnSkNoyGxCP8Wh2C1L0NL5r+x58lkma5vL6ncwWYY+0C3bt1XbBRdeOZHUwuYTIcD+BCNixQiNor7KjO1TzpOb6V3m1SKHu8idDM5fUcKooGbV3WuE7AJrAG5fvt59V9MtMPc2FklVFminfTeYKboEaxZJxuPDbQs2IyJ/0lI8P0Mv4LIKj4+OipQ/fGbZuE7cOioPKKl02dE7eCA=
+
+ tstudent
+
+
+
+
+
+
+ https://sp.example.com/metadata.xml
+
+
+
+
+ Test
+
+
+
+
+ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
+
+
+
+
\ No newline at end of file
diff --git a/test/data/response_notbefore_future_signed_then_encrypted.xml b/test/data/response_notbefore_future_signed_then_encrypted.xml
new file mode 100644
index 0000000..962aa50
--- /dev/null
+++ b/test/data/response_notbefore_future_signed_then_encrypted.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+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
+
+
\ No newline at end of file
diff --git a/test/data/response_notbefore_future_signed_then_encrypted_base64.xml b/test/data/response_notbefore_future_signed_then_encrypted_base64.xml
new file mode 100644
index 0000000..ff8f76b
--- /dev/null
+++ b/test/data/response_notbefore_future_signed_then_encrypted_base64.xml
@@ -0,0 +1,111 @@
+PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6
+cHJvdG9jb2wiIElEPSJfMiIgVmVyc2lvbj0iMi4wIiBJblJlc3BvbnNlVG89Il8xIiBEZXN0aW5h
+dGlvbj0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9hc3NlcnQiPg0KICAgIDxzYW1scDpTdGF0dXM+
+DQogICAgICAgIDxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FN
+TDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz4NCiAgICA8L3NhbWxwOlN0YXR1cz4NCiAgICANCjxFbmNy
+eXB0ZWRBc3NlcnRpb24geG1sbnM9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRp
+b24iPjx4ZW5jOkVuY3J5cHRlZERhdGEgeG1sbnM6eGVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAw
+MS8wNC94bWxlbmMjIiB4bWxuczpkc2lnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRz
+aWcjIiBUeXBlPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNFbGVtZW50Ij48eGVu
+YzpFbmNyeXB0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94
+bWxlbmMjYWVzMTI4LWNiYyIvPjxkc2lnOktleUluZm8geG1sbnM6ZHNpZz0iaHR0cDovL3d3dy53
+My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PHhlbmM6RW5jcnlwdGVkS2V5Pjx4ZW5jOkVuY3J5cHRp
+b25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNyc2Et
+b2FlcC1tZ2YxcCIvPjx4ZW5jOkNpcGhlckRhdGE+PHhlbmM6Q2lwaGVyVmFsdWU+TUgvSElYMmw5
+QVA0c1dJRmhCeTlKYm9ZWHd1eXlaRU9HSEtveW1helovdHZMRE5JZGxsbGs0TjZrbjU0cEdkdkNw
+cTJ2Z0EyamRCdkcydVJ6eVZrQU5aZGI2RWFMQ3RWaE5wRUl5cnkrbklhVzJ4d2hwL0lHU0FmbU9H
+eTh3MGc5Tjhqc1lxZ3VlK0wzQ3VjbUIzUkh2eUF4ODV5N09DV3Raa1Jkd3JMbi9YL1lBOGYxZGNa
+ajd3MkRPN21WWVhybkl4OEJVTDNDc3JQNU0vSUpWdjZ3UldPRTBzRG9iSDVFS1FBSmtUQWlhTDMw
+dHdHOVA3WTJiYjdtekQzN1F4cVJUY29tMjh0Ry9DQXAydlBxaitCdWdYeDd6Uk1RanhkZk5Cc1RV
+L2FvYnp5WDFEZWJIazJzb0ovK2tFTTF3UnBRNnpXeUFONVpRNHlta2wwcjdVS053PT08L3hlbmM6
+Q2lwaGVyVmFsdWU+PC94ZW5jOkNpcGhlckRhdGE+PC94ZW5jOkVuY3J5cHRlZEtleT48L2RzaWc6
+S2V5SW5mbz4NCiAgIDx4ZW5jOkNpcGhlckRhdGE+DQogICAgICA8eGVuYzpDaXBoZXJWYWx1ZT5n
+c3hwZUNPM0JpelpqMVpxZ25HR2lMVWN6cFR3SUM0bjlMQ09VMEFXdUxSdndRUmJmRHQyOVdJNnJE
+RGpHWVBXUU03SFRTWC9WTVVoRzQ4YnYrWjdEem9qbmpWOExZaXF0WVF3ci92ZWhpODg1ZnlvNlJZ
+cVhpb1cxbERDMHQ4YnNRaXpscEpmSzB0SkFEaUxiQnNubWRZbU9PeURSVHp2Wm9teEZFN3ZKYmFC
+NmdJVXhOa2I5MzdnUVo2VnBtVHhpSnJwRHQvZFJ0VmFLRmlBNWlWYmZyTDBnME1BeEZyYUVnalhr
+MFd1akdHc2t6bUNjcGM5bUtmS3VMS1h2bXR5M1pRTXU5Zk9zUUJEQW9odjBrQjVKOFpESVcyNTQ3
+akNDZVRqT256VE82RVJFNnlFcHhpV2V4Sy90VUFFT2NYY3U1aTV4cWM4ai9MclZxTUhxcVNuTlVW
+R2JZUFNvUGlhbXhhbjQzTzM2bkdmU3doRWd6ODBzdXNGRFFSOGV5Z0k1WkQ4VDZOQWM4LzZyd1pK
+eW9uMmFBczgydk5iemo2Ymo3ZVJ3K3hGS2dCNDFMRUxna0UvUFg5VDkxdDV1a1RzbVJyNXNnam13
+TWEzT0E1WVVYYy8rd0YyZVMrTlJiOU0yNmtYcU95aVpaQWhraXJudVhLQ0kvMTZ2aE9CbUJPRzRR
+ZVpaSC9OM2VIUmpMS1l5ZVRRclBSY2Q0SHplY2NjMGs4alRUQkZjMFJ6YTBTaERqYVZjQXE5WlIv
+Vmd6NExSc2FKMi9Gc0tuLzBFRCtrd3BRVmgzT0h5Zk5HMGpPUHNEUE8xeXFuenNBeStPZHFudWgv
+TzVBUXhZWHlGZGw1YXlyd2ZzTzNTY3BGWEhWWkRPMEZYSnpZOXQ3TndFNlRtdzRVVG1QbHIzNGE4
+T1ZOYU5NdGxXSHJFb2xOZG9YdStiNGZvQXljV1pxSGlnVXFJSDJpU1lRcW5nNHlqOVIvaHBEY01y
+STYyakZLWjk4c2pGaW8yVXNwVURXc1hXdkdSL0M1OW5qRy9EcU9wcUpKRHR6Q29ycXFtQktIOTRP
+WGxQUkJCK1FlUGlMaFNyU3M2UXhVNnA0cWIzTDkwRktsUjdhOG8waU1IbHBDYm5zZDZPekhoWGht
+UjhTZU1ET3BEWWhucStsUTJmcE5KVFFyOEtoUGgzYnBwekxIZTh5aWZQSDM0RTlVN1dvMFFTK0tk
+MWJaSzRPWUE5cWE0b0RhcVJYaXdGZnczWmRQS0RzbzZnTHQ1bkczVm1yS3dxUWxHNzZhc1dNbHhs
+QzFMbEc5QkFlWGM1ZnhmazU2OEl0VGJkSmp6ZmUyczZpY3NYaTkrcjA0OTlpMEt0L3ErTTFEMUZt
+dUtkRGl1cUNvSXQ2dDZLbEVldDNZT1Z0MW1lZUxuQnlHTmpVanFRQzVnQmRSM3pTU2ZYcmJoOFFx
+RitQQU4vUUp6OHlNSDF1UUlCUndZTnR6bTRXcjhISWN5d20rZm9aa1BoeGh6R0JaeG80cHp2K28w
+anZOeWZXbmltT01jYTM1OERtZmZPa0hvY0lKMWs5QlV2aUpIMmwvZEdwbFRzcVhTT1I3NW5nUUFa
+R1hFMVArNW9QVTRtR1cxbjBpK3RqNkc5S2ZqRm9Lei94cmpaa1BXM2NVVFFhU2g0Q05vR3YwK2p2
+WG54QmZzdmFzNTVzUWNFWEtqUDNGck9selV5UkR6SUVjNGRjbHZSOVZwRzVLKzNqZHRWU3lIcTJW
+eWcvMFRuZS9ydzhqUEhEdS85WTFVVzRYWFVSWjdQd0dTKzBlSmhoVzlpMXVZcFJrb0FWc1IwOFdB
+bXg4WFVQL1NGTWZqQVhuVWY0Uy9OSGJqcUVBQXNwblZPUHJ1ZUhtWnlVRTJRQTlEUGtCcEdJOHRr
+SlB1QWY1eTFUQ1dSMDF0U0E5Zzg1d3EzNTBRSWlMNzgvT1pOdjZkTVQvMDhQZ2x4ZjJFdEpUQUZT
+dEsrQVRuU0w1Y1p0MDRCSFpIMWpEWDJHZTBwaEhBUTEwTVZEYTNTU2o0QjR2TFdLSDR2Vm9QRTZX
+VHVpZVdGMmhaeEE2RGRMNTlrWFRMV0pYSHNBOUNTaUZ3dTNsRDZaK05IVVgxR0J3Z3lJL3ZNNUhz
+cVg4Mk1Xd2E3SW55WnZpS1llTk5rdXBZWkUrN2Vaa08waUQxeWFFQVlVeUtnN0NsVlpnWmo5b2Jv
+cWFVbDZBUnJmV1M0eXJraG5IUmdBazFSZ0tLODlPWW1YVUhBNmFQemJTaDVuOHZZUzYwaXdnTkN6
+bUlha3lUc2VnVzFZbVN4Rk53SzRlZG5XTVc2TlFkanZhRWRnYVZFUlZDRXg1bmxrbEVvaDJwTFFa
+T0hSYVVDblhrRzN5VWJ0R2QyM0F4WndIY1JnOFpxYVEvOVpLL0tpSTd1eWFoWHIrU0xiQ2E5SU92
+VEVucnN3SjFBSm9zTGRCbjIySktVME1hU0JyQThBL0RWd3lWa0JEOGNNWHlkcTNMblVib3NBODBH
+QkFGUGcycS9sVHNZWElCWUZKZktrYnlEb0I2clZ3Y3lSL05jL3dTbUpRUkZud3lCZEE3RFRhQVhN
+aGNXUzdwLzNZdVk1RmVZVjhEVTd4bWtlRmE4d3J3NXQ0OFFLbGxGQitsbTdSak15TmNYQXE0Ylgx
+bEcyUEo2Um04RzhrNmozTWNsV1FYcGVRSThuKzJ0d0dzV1FhcWNOUGJ0SXpWVGE4M2J3TmF3emVv
+ejFlL0txcXZGU2xackxMYXR6N2xYcUp0VFZqU1BuMXpZYis1ZVhyRmU4MFNlTzE4c3hGWHN4bmw4
+VS9PVlRvRDV1eHREOFJzSGpqRjVjTVYydkY0ckdGTkJjbno2Ukg2QTNkd0hCdlo2NFE1NFUwb2N6
+ZzZvSUdCbnMweE5NOUhVREE0SVFBYUdrU29HWTdzVEp5djB5Tjk3ZFMvSWVIZVV2ZXh2ODZlSFVl
+b2t3QXl1Yks4Z1JCQTl0a3F5Mi8veStCM1VlaXArZm9UWGlLaWt1dTFkN2p1bWpxYmE5MDBpRFUw
+MTRkVkphVU9LYkY0TE5XZG9PNkh4NTBoOEpoNjlVSS9LTnQ0TU9VWVFPNVZJaGM3OEJpUFRScjhE
+dXdNd1FTQ090RlYrcSt0VUxnK1UxRVpaVjdqU1F5NWJGN2lJbzJlN3BBMGRSaGM3aXVmV21NN3B2
+bzNIRU5ZNGFhZDVLdXM5VXNYWG80K2V2aVdiOXU5L2FtWFZwbWJyNTdmUmRmZGZXUHd4cmlFTGNX
+RVRiUWxUdTY5c3lPeTc0TTdmckt0TDg1bUJWRFRJenlna3lzWVIrWlNXMEVvTU1PUUVrOStkSkhX
+Vk1rRjhlVjNCSDBYbFkwczNFNFpCdlQySWdFWUNvd2YzS0FqUGJKcDE4N0JvWDN3Z2E4c2hpWnR4
+K0gvNkRZekxxeHV5c0JPVnl3eHVnOEx2Zk9wWEJiR0NoMWpOUWQvMnU5VVBxNjJVbnNJR2pqVndZ
+bVpSOW5IZHVWTTEvd3JUTkJOODVKems5ZzczdE1vK3RFRFNpUlhWZEdVR3crcVJmdjJHM3hQUFJJ
+NVRhb1BkRHlWWGFOSGwydWJlV2lGcDE3TDR2S3lOemp5VEowbDZ2dng5WE5MRy9oM1NUOHN2bGVx
+cXpvTzRwM0ZseUt4VGNQWkxINXc5cW5nbTlSdktsc1hjcU84ZVBxMWZobkxPNlVYNDBxcURKWThY
+NXNTVHNyK055QzdNQkF5K3lvWmlnQURrcDZ0RE5VTVJMMmp5UHI2aWpFRjcxUkVzald6V3N1Ylps
+Qkp1SGdaclR2dGZRT3dnUFNrYWlCQzdjaUdTUUlSeDhUaFpiNzRMOTVMbkFNakpMRkxqdVRxZnFs
+N2JSNGRTMyszWDI1WVRGb2E3Tk44T1FyUEJkUGNkemozNUpIR3Y4eGRZcXg3L1BCdTZ5aGhiaXdm
+Y1lpMFlqMm5sR3laUjFBenJTWVhDN1c0S1NlVTZjaDZXRmNzY280em1KL1A2TlMzQjBtRHJTNks2
+YzgrRTNuVU85VTZkSkJDZWdSb1VlclZCLzFXNFRIMjJMcWRycm1CUWoyaDRFb25CS0E0TFJjTXdo
+VEJMS0srM2lOdEJaQUR6K0dTYlVJOE9NRCtMV1dhU3p2RlU2Q0lPNUNZcVM4aDFzb2puM1lmQXYv
+YUR2RUZjRm1SQmpva1A4bXJzT0V4NGwrUTBrOURUTzRjdkMxQ3hHRlUxekZZUWNZMHZ6TkZKZTE1
+bjQ3RmZwbUFKNG5xRWpkK0xhOVBOM1c1UElOazlaL09reHJYeWZLTkZ5TUlEa2lWMkp5Qm85NU9S
+UGVYSEhFWEtkQWdsRGxscEllMmtpdTk5RnlSSlV6NmZNc2pEL3NYOVBxVGd1TDZ6L0dzN0taMDFz
+Q2ZudGtPZ2pQam9kb3YzWHFGTWZKRFFkVmYvVjQ2KzE5elhmdGlOUWcrNnU5WXF6MzN5c2QwSGVk
+UWpTekdBM1JWQi9EblRaenJjaEkzbStVQnZvTmNCR1ZtNFhlKzQvSkMzWWx1NDZOdHUzME1JT2kw
+cHZab0hoN2pwZzZMaENEbDBYdGd4Mi9PWXVVd0NzU3dtUk1QTEQxZHRRd1hNYy9FVVNJZjVBY1h2
+anI3TDgrN284eWs4RWpaRkRnTWw5eVVneEM4ZENzN2p4VjRFRWRKK2hkU3FMZERBZTZSTnpyQUEw
+cUVVZFhIOGpRWEd3NFJxOFNvRnFkakZVMndjR0E0VFpVelFuck15S2dOdVhPU2hGMmFtbEJocmlP
+T2hTT3puSnFxVkU0NTVyTXdHRE84NXFxUWp0S0RzdzlKcnY4NjRVTUJpbmhmOFpqaW54Y1orZFFU
+cjhNL2djMERjSWhaTlBZdGZQOElBMlZJRm1TR3llcm9tTlNML0krejk3N0h5blhTZ05ZY0lmcU9E
+WklnaTRCUmpaek94enFCQmJWOGVHeDhYU21SdWVjNnFkMmI1aThyR0lCWHZwZ1pGN0ZUTEFEVFRj
+ZU9xUy9xendsQm9mVFRZN2tPTFFYTFlMamFJcG1yZGVXNS9TWWZCOFE1dyt3RDlxcWNMczFPYXRI
+R21KTnRhZDFsUWUwNFpmUVlRVEtnVjU2MmV1cUxNZWpUbkV6dTFEcVk2czlqNW00eHdVL2QyN2xT
+Q0dCdHZBbXlwQTdqbnE5WURXa0tZQlVRWmVKNjdTWXlLN0VHUUVlcDYweUM2eDNtNWt3U1VHYTMr
+amJLYzVINU4xajJ1akhNbEhDTGlFWWM5K2NFYjBvQmhHajZ4bEpSbHhTcitpalQ0NlBrQ0ZlYTh2
+L1FHTENlblFBelFqTUVvSDM0b2xTQnRSZ0lXRHFpOEVCZjM2TTgraDQzTHc2Y21JRkdyYllFUUN6
+Z09kN1VzMzlkYVc2R2gra3VvVTJvdFNnVGw0NTh4ekhNdCs4N2hwbm5aaTdXTmdNUGhFRFVXKzdD
+YllYZzlWWCt6TFVrTFhnQlRrNkpCL1RnRXUzc1J1aVBJOWQ4S2lRcUNzVUVVK2dCYWhSeGdDRzZw
+N2ZJd1huR1Y2OXZVa1ZvVFd3eWxSWHdUcnJBOUdXQ0crM29pNkFxT2JoajRCTW5WUW5GalByT1RK
+WG1iajRUdFZKUUNKYkpTdjF4TGtyMVRxak12MFV4Y0N3N0EwY0pMbVB6RlZ0aWFVa2k3aXowZ29v
+SW1SYzVzdVVsMkxRZlZUYjNyVWZna3A0RXl5ZVo4a1lMNE81eDNYVkEzalgyU1dnbWp6ZGVYTFpk
+RGpLWlVxclNONFBydmlJTVN5TVUyTnEzdnNra3N6VTFoYU1jbEZPd1BqMU94eSt5bUYvL2NpcUtz
+OUdWVXpDRkl2Nno0N1QvZjVVamYxVGFZM1NybjdwSk5QMUVIZzZHeVVONWJEaS9HQlZNdU5qTTAz
+OUN0a2VGZnprbGNrK0dyeXJhYUh1bThRSklZeFJ3UmNVQnlqa1VDUmdVUUtVb1FXVTQvNWZEcG1M
+b04xQVFmZS8xaW15bVlOUkt4Tnd2S3ErVlhuWTc0OXZWdStrZThCM25IU1BicWtxMGh3WFFFV0hO
+d3c2UlZFYU5vV0JTZ0pEci9PSzAxdlFrWGxjMWNLanJ0TkJxWjFQTGVpVE9Rby9rVVMreHZTSnV1
+S0pDNm8vY2VERWpCekdmajV3eTN1VkNVRGRXTyt2QXpSVnErcWIrYzk1dUFVUXMrejRyVXBobzZh
+a0hlayszQXVKbFZoY09BRGJyMEIzZ25mQlVTbTJrSkVlNjNRcDl3M3BjVkJVdk8wMlFMM291Q1hE
+RmNJa3lFbDFLYUo0YXRReks0SnplOTd3NVVXWENPaks0L00wZU9zMkhJMU84aFZyb1NaZnBhN05N
+anhBMG9kOUNKR3NEZGdBVWQ3eHRnUnZQT2l0THlKNVphOWJmU0tJTld1eUMwYnN4d0tVZnhJcHli
+eE15cGJESmlrSFhTRkRBNEZJaGxTQml5VzNXRm5rWU90OGVTeU1zbVY0UzhhMDczejBHSVk3ZGxu
+djR5TVdBSEVzNG1KZVprVmptWCszZ3doSjwveGVuYzpDaXBoZXJWYWx1ZT4NCiAgIDwveGVuYzpD
+aXBoZXJEYXRhPg0KPC94ZW5jOkVuY3J5cHRlZERhdGE+PC9FbmNyeXB0ZWRBc3NlcnRpb24+PC9z
+YW1scDpSZXNwb25zZT4=
diff --git a/test/saml2.coffee b/test/saml2.coffee
index 99ac4ee..1c3d174 100644
--- a/test/saml2.coffee
+++ b/test/saml2.coffee
@@ -371,6 +371,7 @@ describe 'saml2', ->
sso_logout_url: 'https://idp.example.com/logout'
certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
request_options =
+ ignore_timing: true
request_body:
SAMLResponse: get_test_file("post_response.xml")
@@ -619,6 +620,83 @@ describe 'saml2', ->
assert (/SAML Response is not yet valid/.test(err.message)), "Unexpected error message:" + err.message
done()
+ it 'rejects an encrypted assertion with an NotBefore condition in the future', (done) ->
+ sp_options =
+ entity_id: 'https://sp.example.com/metadata.xml'
+ private_key: get_test_file('test2.pem')
+ alt_private_keys: get_test_file('test.pem')
+ certificate: get_test_file('test2.crt')
+ alt_certs: get_test_file('test.crt')
+ assert_endpoint: 'https://sp.example.com/assert'
+ idp_options =
+ sso_login_url: 'https://idp.example.com/login'
+ sso_logout_url: 'https://idp.example.com/logout'
+ certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
+ request_options =
+ require_session_index: false
+ ignore_signature: true
+ allow_unencrypted_assertion: true
+ request_body:
+ SAMLResponse: get_test_file("response_notbefore_future_encrypted.xml")
+
+ sp = new saml2.ServiceProvider sp_options
+ idp = new saml2.IdentityProvider idp_options
+
+ sp.post_assert idp, request_options, (err, response) ->
+ assert (err instanceof Error), "Did not get expected error."
+ assert (/SAML Response is not yet valid/.test(err.message)), "Unexpected error message:" + err.message
+ done()
+
+ it 'rejects a signed-then-encrypted assertion with a NotBefore condition in the future', (done) ->
+ sp_options =
+ entity_id: 'https://sp.example.com/metadata.xml'
+ private_key: get_test_file('test2.pem')
+ alt_private_keys: get_test_file('test.pem')
+ certificate: get_test_file('test2.crt')
+ alt_certs: get_test_file('test.crt')
+ assert_endpoint: 'https://sp.example.com/assert'
+ idp_options =
+ sso_login_url: 'https://idp.example.com/login'
+ sso_logout_url: 'https://idp.example.com/logout'
+ certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
+ request_options =
+ require_session_index: false
+ request_body:
+ SAMLResponse: get_test_file("response_notbefore_future_signed_then_encrypted_base64.xml")
+
+ sp = new saml2.ServiceProvider sp_options
+ idp = new saml2.IdentityProvider idp_options
+
+ sp.post_assert idp, request_options, (err, response) ->
+ assert (err instanceof Error), "Did not get expected error."
+ assert (/SAML Response is not yet valid/.test(err.message)), "Unexpected error message:" + err.message
+ done()
+
+ it 'rejects an encrypted-then-signed assertion with a NotBefore condition in the future', (done) ->
+ sp_options =
+ entity_id: 'https://sp.example.com/metadata.xml'
+ private_key: get_test_file('test2.pem')
+ alt_private_keys: get_test_file('test.pem')
+ certificate: get_test_file('test2.crt')
+ alt_certs: get_test_file('test.crt')
+ assert_endpoint: 'https://sp.example.com/assert'
+ idp_options =
+ sso_login_url: 'https://idp.example.com/login'
+ sso_logout_url: 'https://idp.example.com/logout'
+ certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
+ request_options =
+ require_session_index: false
+ request_body:
+ SAMLResponse: get_test_file("response_notbefore_future_encrypted_then_signed_base64.xml")
+
+ sp = new saml2.ServiceProvider sp_options
+ idp = new saml2.IdentityProvider idp_options
+
+ sp.post_assert idp, request_options, (err, response) ->
+ assert (err instanceof Error), "Did not get expected error."
+ assert (/SAML Response is not yet valid/.test(err.message)), "Unexpected error message:" + err.message
+ done()
+
it 'throws if options.notbefore_skew is not a number', (done) ->
sp_options = { notbefore_skew: 'carrot_cake' }
request_options = { request_body: { SAMLResponse: '…' } }
@@ -692,6 +770,33 @@ describe 'saml2', ->
assert (/SAML Response is no longer valid/.test(err.message)), "Unexpected error message:" + err.message
done()
+ it 'rejects an encrypted assertion with an NotOnOrAfter condition in the past', (done) ->
+ sp_options =
+ entity_id: 'https://sp.example.com/metadata.xml'
+ private_key: get_test_file('test2.pem')
+ alt_private_keys: get_test_file('test.pem')
+ certificate: get_test_file('test2.crt')
+ alt_certs: get_test_file('test.crt')
+ assert_endpoint: 'https://sp.example.com/assert'
+ idp_options =
+ sso_login_url: 'https://idp.example.com/login'
+ sso_logout_url: 'https://idp.example.com/logout'
+ certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
+ request_options =
+ require_session_index: false
+ ignore_signature: true
+ allow_unencrypted_assertion: true
+ request_body:
+ SAMLResponse: get_test_file("post_response.xml")
+
+ sp = new saml2.ServiceProvider sp_options
+ idp = new saml2.IdentityProvider idp_options
+
+ sp.post_assert idp, request_options, (err, response) ->
+ assert (err instanceof Error), "Did not get expected error."
+ assert (/SAML Response is no longer valid/.test(err.message)), "Unexpected error message:" + err.message
+ done()
+
context 'when response contains AudienceRestriction', ->
sp_options = (properties = {}) ->
_.extend
@@ -715,7 +820,7 @@ describe 'saml2', ->
SAMLResponse: get_test_file("response_audience_no_timing.xml")
, properties
- it 'rejects an empty audience', ->
+ it 'rejects an empty audience', (done) ->
sp = new saml2.ServiceProvider sp_options
audience: 'https://another-sp.example.com/metadata.xml'
idp = new saml2.IdentityProvider idp_options()
@@ -827,6 +932,7 @@ describe 'saml2', ->
sso_logout_url: 'https://idp.example.com/logout'
certificates: [ get_test_file('test.crt'), get_test_file('test2.crt') ]
request_options =
+ ignore_timing: true
request_body:
SAMLResponse: get_test_file("redirect_response.xml")