KEYCLOAK-12609 Fix integer overflow for SAML XMLTimeUtil add method parameters

This commit is contained in:
mhajas 2020-01-06 12:32:13 +01:00 committed by Hynek Mlnařík
parent e96725127f
commit 28b01bc34d
2 changed files with 25 additions and 6 deletions

View file

@ -213,13 +213,13 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
//Update Conditions NotOnOrAfter //Update Conditions NotOnOrAfter
if(assertionExpiration > 0) { if(assertionExpiration > 0) {
ConditionsType conditions = assertion.getConditions(); ConditionsType conditions = assertion.getConditions();
conditions.setNotOnOrAfter(XMLTimeUtil.add(conditions.getNotBefore(), assertionExpiration * 1000)); conditions.setNotOnOrAfter(XMLTimeUtil.add(conditions.getNotBefore(), assertionExpiration * 1000L));
} }
//Update SubjectConfirmationData NotOnOrAfter //Update SubjectConfirmationData NotOnOrAfter
if(subjectExpiration > 0) { if(subjectExpiration > 0) {
SubjectConfirmationDataType subjectConfirmationData = assertion.getSubject().getConfirmation().get(0).getSubjectConfirmationData(); SubjectConfirmationDataType subjectConfirmationData = assertion.getSubject().getConfirmation().get(0).getSubjectConfirmationData();
subjectConfirmationData.setNotOnOrAfter(XMLTimeUtil.add(assertion.getConditions().getNotBefore(), subjectExpiration * 1000)); subjectConfirmationData.setNotOnOrAfter(XMLTimeUtil.add(assertion.getConditions().getNotBefore(), subjectExpiration * 1000L));
} }
// Create an AuthnStatementType // Create an AuthnStatementType
@ -232,7 +232,7 @@ public class SAML2LoginResponseBuilder implements SamlProtocolExtensionsAwareBui
authContextRef); authContextRef);
if (sessionExpiration > 0) if (sessionExpiration > 0)
authnStatement.setSessionNotOnOrAfter(XMLTimeUtil.add(authnStatement.getAuthnInstant(), sessionExpiration * 1000)); authnStatement.setSessionNotOnOrAfter(XMLTimeUtil.add(authnStatement.getAuthnInstant(), sessionExpiration * 1000L));
if (sessionIndex != null) authnStatement.setSessionIndex(sessionIndex); if (sessionIndex != null) authnStatement.setSessionIndex(sessionIndex);
else authnStatement.setSessionIndex(assertion.getID()); else authnStatement.setSessionIndex(assertion.getID());

View file

@ -56,14 +56,14 @@ public class SessionNotOnOrAfterTest extends AbstractSamlTest {
assertThat(authType, notNullValue()); assertThat(authType, notNullValue());
assertThat(authType.getSessionNotOnOrAfter(), notNullValue()); assertThat(authType.getSessionNotOnOrAfter(), notNullValue());
assertThat(authType.getSessionNotOnOrAfter(), is(XMLTimeUtil.add(authType.getAuthnInstant(), ssoMaxLifespan * 1000))); assertThat(authType.getSessionNotOnOrAfter(), is(XMLTimeUtil.add(authType.getAuthnInstant(), ssoMaxLifespan * 1000L)));
// Conditions // Conditions
Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getConditions()); Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getConditions());
Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getConditions()); Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getConditions());
ConditionsType condition = resp.getAssertions().get(0).getAssertion().getConditions(); ConditionsType condition = resp.getAssertions().get(0).getAssertion().getConditions();
Assert.assertEquals(XMLTimeUtil.add(condition.getNotBefore(), accessCodeLifespan * 1000), condition.getNotOnOrAfter()); Assert.assertEquals(XMLTimeUtil.add(condition.getNotBefore(), accessCodeLifespan * 1000L), condition.getNotOnOrAfter());
// SubjectConfirmation (confirmationData has no NotBefore, using the previous one because it's the same) // SubjectConfirmation (confirmationData has no NotBefore, using the previous one because it's the same)
Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getSubject()); Assert.assertNotNull(resp.getAssertions().get(0).getAssertion().getSubject());
@ -77,7 +77,7 @@ public class SessionNotOnOrAfterTest extends AbstractSamlTest {
.orElse(null); .orElse(null);
Assert.assertNotNull(confirmationData); Assert.assertNotNull(confirmationData);
Assert.assertEquals(XMLTimeUtil.add(condition.getNotBefore(), accessTokenLifespan * 1000), confirmationData.getNotOnOrAfter()); Assert.assertEquals(XMLTimeUtil.add(condition.getNotBefore(), accessTokenLifespan * 1000L), confirmationData.getNotOnOrAfter());
return null; return null;
} }
@ -101,6 +101,25 @@ public class SessionNotOnOrAfterTest extends AbstractSamlTest {
} }
} }
@Test
public void testMaxValuesForAllTimeouts() throws Exception {
try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME))
.updateWith(r -> {
r.setSsoSessionMaxLifespan(Integer.MAX_VALUE);
r.setAccessCodeLifespan(Integer.MAX_VALUE);
r.setAccessTokenLifespan(Integer.MAX_VALUE);
})
.update()) {
new SamlClientBuilder()
.idpInitiatedLogin(getAuthServerSamlEndpoint(REALM_NAME), "sales-post").build()
.login().user(bburkeUser).build()
.processSamlResponse(SamlClient.Binding.POST)
.transformObject(r -> checkSessionNotOnOrAfter(r, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE))
.build()
.execute();
}
}
@Test @Test
public void testSamlResponseContainsSessionNotOnOrAfterAuthnLogin() throws Exception { public void testSamlResponseContainsSessionNotOnOrAfterAuthnLogin() throws Exception {
try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME)) try(AutoCloseable c = new RealmAttributeUpdater(adminClient.realm(REALM_NAME))