Search in sources :

Example 1 with HmacOTP

use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.

the class HmacTest method testHmac.

@Test
public void testHmac() {
    HmacOTP hmacOTP = new HmacOTP(6, HmacOTP.HMAC_SHA1, 10);
    String secret = "JNSVMMTEKZCUGSKJIVGHMNSQOZBDA5JT";
    String decoded = new String(Base32.decode(secret));
    System.out.println(hmacOTP.generateHOTP(decoded, 0));
    System.out.println(hmacOTP.validateHOTP("550233", decoded, 0));
    Assert.assertEquals(1, hmacOTP.validateHOTP("550233", decoded, 0));
}
Also used : HmacOTP(org.keycloak.models.utils.HmacOTP) Test(org.junit.Test)

Example 2 with HmacOTP

use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.

the class RequiredActionsTest method testOtp.

private void testOtp(String type, String algorithm, int digits, Integer period, Integer counter, String secret) {
    switch(algorithm) {
        case "SHA1":
            algorithm = TimeBasedOTP.HMAC_SHA1;
            break;
        case "SHA256":
            algorithm = TimeBasedOTP.HMAC_SHA256;
            break;
        case "SHA512":
            algorithm = TimeBasedOTP.HMAC_SHA512;
            break;
        default:
            throw new AssertionError("Wrong algorithm type");
    }
    HmacOTP otpGenerator;
    String secretDecoded = new String(Base32.decode(secret));
    String code;
    switch(type) {
        case TOTP:
            otpGenerator = new TimeBasedOTP(algorithm, digits, period, 0);
            code = ((TimeBasedOTP) otpGenerator).generateTOTP(secretDecoded);
            break;
        case HOTP:
            otpGenerator = new HmacOTP(digits, algorithm, 0);
            code = otpGenerator.generateHOTP(secretDecoded, counter);
            break;
        default:
            throw new AssertionError("Wrong OTP type");
    }
    // fill in the form
    otpSetupPage.setTotp(code);
    otpSetupPage.submit();
    assertLoginSuccessful();
    // try the code is working
    deleteAllSessionsInTestRealm();
    testRealmAccountPage.navigateTo();
    testRealmLoginPage.form().login(testUser);
    oneTimeCodePage.assertCurrent();
    // assertEquals("One-time code", oneTimeCodePage.getTotpLabel());
    // bad attempt
    oneTimeCodePage.submit();
    assertTrue(oneTimeCodePage.feedbackMessage().isError());
    assertEquals("[TEST LOCALE] vložen chybný kód", oneTimeCodePage.feedbackMessage().getText());
    oneTimeCodePage.sendCode("XXXXXX");
    assertTrue(oneTimeCodePage.feedbackMessage().isError());
    assertEquals("[TEST LOCALE] vložen chybný kód", oneTimeCodePage.feedbackMessage().getText());
    // generate new code
    code = type.equals(TOTP) ? ((TimeBasedOTP) otpGenerator).generateTOTP(secretDecoded) : otpGenerator.generateHOTP(secretDecoded, ++counter);
    oneTimeCodePage.sendCode(code);
    assertLoginSuccessful();
}
Also used : HmacOTP(org.keycloak.models.utils.HmacOTP) TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP)

Example 3 with HmacOTP

use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.

the class LoginHotpTest method before.

@Before
public void before() throws MalformedURLException {
    RealmRepresentation testRealm = testRealm().toRepresentation();
    policy = new OTPPolicy();
    policy.setAlgorithm(testRealm.getOtpPolicyAlgorithm());
    policy.setDigits(testRealm.getOtpPolicyDigits());
    policy.setInitialCounter(testRealm.getOtpPolicyInitialCounter());
    policy.setLookAheadWindow(testRealm.getOtpPolicyLookAheadWindow());
    policy.setPeriod(testRealm.getOtpPolicyLookAheadWindow());
    policy.setType(testRealm.getOtpPolicyType());
    otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
}
Also used : HmacOTP(org.keycloak.models.utils.HmacOTP) RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) OTPPolicy(org.keycloak.models.OTPPolicy) Before(org.junit.Before)

Example 4 with HmacOTP

use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.

the class OTPCredentialProvider method isValid.

@Override
public boolean isValid(RealmModel realm, UserModel user, CredentialInput credentialInput) {
    if (!(credentialInput instanceof UserCredentialModel)) {
        logger.debug("Expected instance of UserCredentialModel for CredentialInput");
        return false;
    }
    String challengeResponse = credentialInput.getChallengeResponse();
    if (challengeResponse == null) {
        return false;
    }
    if (ObjectUtil.isBlank(credentialInput.getCredentialId())) {
        logger.debugf("CredentialId is null when validating credential of user %s", user.getUsername());
        return false;
    }
    CredentialModel credential = getCredentialStore().getStoredCredentialById(realm, user, credentialInput.getCredentialId());
    OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromCredentialModel(credential);
    OTPSecretData secretData = otpCredentialModel.getOTPSecretData();
    OTPCredentialData credentialData = otpCredentialModel.getOTPCredentialData();
    OTPPolicy policy = realm.getOTPPolicy();
    if (OTPCredentialModel.HOTP.equals(credentialData.getSubType())) {
        HmacOTP validator = new HmacOTP(credentialData.getDigits(), credentialData.getAlgorithm(), policy.getLookAheadWindow());
        int counter = validator.validateHOTP(challengeResponse, secretData.getValue(), credentialData.getCounter());
        if (counter < 0) {
            return false;
        }
        otpCredentialModel.updateCounter(counter);
        getCredentialStore().updateCredential(realm, user, otpCredentialModel);
        return true;
    } else if (OTPCredentialModel.TOTP.equals(credentialData.getSubType())) {
        TimeBasedOTP validator = new TimeBasedOTP(credentialData.getAlgorithm(), credentialData.getDigits(), credentialData.getPeriod(), policy.getLookAheadWindow());
        return validator.validateTOTP(challengeResponse, secretData.getValue().getBytes(StandardCharsets.UTF_8));
    }
    return false;
}
Also used : OTPSecretData(org.keycloak.models.credential.dto.OTPSecretData) HmacOTP(org.keycloak.models.utils.HmacOTP) UserCredentialModel(org.keycloak.models.UserCredentialModel) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) OTPCredentialData(org.keycloak.models.credential.dto.OTPCredentialData) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPPolicy(org.keycloak.models.OTPPolicy) UserCredentialModel(org.keycloak.models.UserCredentialModel)

Example 5 with HmacOTP

use of org.keycloak.models.utils.HmacOTP in project keycloak by keycloak.

the class RequiredActionTotpSetupTest method setupOtpPolicyChangedHotp.

@Test
public void setupOtpPolicyChangedHotp() {
    RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
    RealmBuilder.edit(realmRep).otpLookAheadWindow(0).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.HOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
    adminClient.realm("test").update(realmRep);
    loginPage.open();
    loginPage.login("test-user@localhost", "password");
    totpPage.assertCurrent();
    String totpSecret = totpPage.getTotpSecret();
    HmacOTP otpgen = new HmacOTP(6, HmacOTP.HMAC_SHA1, 1);
    totpPage.configure(otpgen.generateHOTP(totpSecret, 0));
    String uri = driver.getCurrentUrl();
    String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).assertEvent().getDetails().get(Details.CODE_ID);
    assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
    EventRepresentation loginEvent = events.expectLogin().session(sessionId).assertEvent();
    oauth.openLogout();
    events.expectLogout(loginEvent.getSessionId()).assertEvent();
    loginPage.open();
    loginPage.login("test-user@localhost", "password");
    loginTotpPage.assertCurrent();
    loginTotpPage.login(otpgen.generateHOTP(totpSecret, 1));
    assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
    events.expectLogin().assertEvent();
    oauth.openLogout();
    events.expectLogout(null).session(AssertEvents.isUUID()).assertEvent();
    // test lookAheadWindow
    realmRep = adminClient.realm("test").toRepresentation();
    RealmBuilder.edit(realmRep).otpLookAheadWindow(5).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.HOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
    adminClient.realm("test").update(realmRep);
    loginPage.open();
    loginPage.login("test-user@localhost", "password");
    loginTotpPage.assertCurrent();
    loginTotpPage.login(otpgen.generateHOTP(totpSecret, 2));
    assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
    events.expectLogin().assertEvent();
    // Revert
    realmRep = adminClient.realm("test").toRepresentation();
    RealmBuilder.edit(realmRep).otpLookAheadWindow(1).otpDigits(6).otpPeriod(30).otpType(OTPCredentialModel.TOTP).otpAlgorithm(HmacOTP.HMAC_SHA1).otpInitialCounter(0);
    adminClient.realm("test").update(realmRep);
}
Also used : HmacOTP(org.keycloak.models.utils.HmacOTP) RealmRepresentation(org.keycloak.representations.idm.RealmRepresentation) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Aggregations

HmacOTP (org.keycloak.models.utils.HmacOTP)6 Test (org.junit.Test)3 RealmRepresentation (org.keycloak.representations.idm.RealmRepresentation)3 OTPPolicy (org.keycloak.models.OTPPolicy)2 TimeBasedOTP (org.keycloak.models.utils.TimeBasedOTP)2 EventRepresentation (org.keycloak.representations.idm.EventRepresentation)2 Before (org.junit.Before)1 UserCredentialModel (org.keycloak.models.UserCredentialModel)1 OTPCredentialModel (org.keycloak.models.credential.OTPCredentialModel)1 OTPCredentialData (org.keycloak.models.credential.dto.OTPCredentialData)1 OTPSecretData (org.keycloak.models.credential.dto.OTPSecretData)1 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)1