Uploaded image for project: 'RH-SSO'
  1. RH-SSO
  2. RHSSO-1387

[GSS] (7.2.x) RestartLoginCookie should check for existence of HMAC key

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Minor Minor
    • RH-SSO-7.2.3.CR1
    • RH-SSO-7.2.1.GA
    • None
    • None

      1) Login to admin console and create realm "foo"
      2) In another browser tab, open http://localhost:8080/auth/realms/foo/account . Login page is shown for "foo" realm (and cookie KC_RESTART is created)
      3) Go back to tab1 with admin console and open http://localhost:8080/auth/admin/master/console/#/realms/foo/keys/providers. Then delete HMAC key. Then create new HMAC generated key
      4) Delete cookie AUTH_SESSION_ID for path "/auth/realms/foo"
      5) Go back to tab2 and fill some username/password and click "Login" . Now there is page "We're sorry" and an exception in server log (See below). Expected behaviour: Some more reasonable error page about expired session will be shown and there won't be exception in server log.

      The issue happens because there is an attempt to restart authentication session from KC_RESTART cookie. This should fail because linked HMAC key was changed, so it's expected that cookie restart is failing. However we should add null check for key to RestartLoginCookie class, to avoid the situation when BouncyCastle is called with null key, which fails with the exception below. Typically, the admin should do key rotation more properly in step 3 and let the old key to be alive for some time. However users may have their KC_RESTART cookie to be "alive" for very long time when old key is deleted and better error page should be shown then.

      Exception:

      08:23:25,395 WARN  [org.keycloak.events] (default task-99) type=LOGIN_ERROR, realmId=foo, clientId=account, userId=null, ipAddress=127.0.0.1, error=user_not_found, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8080/auth/realms/foo/account/login-redirect, code_id=dedad2cb-b886-4559-9cb3-248163d9db45, username=admin
      08:24:56,380 ERROR [org.keycloak.services] (default task-117) KC-SERVICES0067: failed to parse RestartLoginCookie: java.lang.RuntimeException: java.lang.RuntimeException: java.security.InvalidKeyException: key is null
      	at org.keycloak.jose.jws.crypto.HMACProvider.verify(HMACProvider.java:87)
      	at org.keycloak.protocol.RestartLoginCookie.restartSession(RestartLoginCookie.java:157)
      	at org.keycloak.services.resources.SessionCodeChecks.restartAuthenticationSessionFromCookie(SessionCodeChecks.java:379)
      	at org.keycloak.services.resources.SessionCodeChecks.initialVerifyAuthSession(SessionCodeChecks.java:200)
      	at org.keycloak.services.resources.SessionCodeChecks.initialVerify(SessionCodeChecks.java:207)
      	at org.keycloak.services.resources.LoginActionsService.checksForCode(LoginActionsService.java:192)
      	at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:249)
      	at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:318)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
      	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
      	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
      	at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:138)
      	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:101)
      	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:406)
      	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:213)
      	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:228)
      	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
      	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
      	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
      	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
      	at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90)
      	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
      	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
      	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
      	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
      	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
      	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
      	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
      	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
      	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
      	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
      	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
      	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
      	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
      	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
      	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
      	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
      	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
      	at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
      	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
      	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
      	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
      	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
      	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
      	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      	at java.lang.Thread.run(Thread.java:748)
      Caused by: java.lang.RuntimeException: java.security.InvalidKeyException: key is null
      	at org.keycloak.jose.jws.crypto.HMACProvider.sign(HMACProvider.java:78)
      	at org.keycloak.jose.jws.crypto.HMACProvider.verify(HMACProvider.java:84)
      	... 65 more
      Caused by: java.security.InvalidKeyException: key is null
      	at org.bouncycastle.jcajce.provider.symmetric.util.BaseMac.engineInit(Unknown Source)
      	at javax.crypto.Mac.chooseProvider(Mac.java:350)
      	at javax.crypto.Mac.init(Mac.java:415)
      	at org.keycloak.jose.jws.crypto.HMACProvider.sign(HMACProvider.java:74)
      	... 66 more
      

            irum@redhat.com Alice Rum (Inactive)
            rhn-support-dehort Derek Horton
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: