Page MenuHomePhabricator

CAS SSO: failed u2f registration
Closed, ResolvedPublic

Description

I tried to register cas on the SSO system and we see the following error message in the logs when he tries to register his u2f device an OnlyKey.

sudo grep -rA100 com.yubico.u2f.exceptions.U2fBadInputException /var/log/cas/cas-2020-01-08.log
com.yubico.u2f.exceptions.U2fBadInputException: Signature is invalid. Public key: EC Public Key [4e:13:6f:63:2a:d1:b8:5e:31:5d:e0:fb:c1:61:da:44:0c:c6:01:54]
            X: 7e40b0a059ec4fa7c589f71fd931ac1e9849f04cb547eacea2d8548cb87a3956
            Y: 9dc96c5ca1d194f4790d5395b94981b8a4f1859fe97b603f9c53ee07218808be
, signed data: ANxoE7aB8Ik69B9SE2zSFS3Cu6fdTbX0WGL3rO31xglCNsEYb-FfOlg4qJgKmB3rIl9fTbRM91YsdTETncsmDiThhPr9MrkOBnhDuQjhMr2rzbz7iJeiCKHWi1gz0YkHzrFzR182_nN1h8qozVNVCP0En9n-h4GU_iMk6gaKM0awr1GBDIvFDiVgNpGs74mK9CRtcWFbrVha-TaRSCZzIhGQ8tugKq1bVdrCSyirXjymkw , signature: MEYCIQDgGDoNXYro-YdhK_5ihJgT5zPHWXpy2TwwzCJHg5llSAIhAIHiqS5GSQiC9aeZVia5bClHX92Bah4QFrSI7zKG8ox6
        at com.yubico.u2f.crypto.BouncyCastleCrypto.checkSignature(BouncyCastleCrypto.java:46) ~[u2flib-server-core-0.19.7.jar!/:?]
        at com.yubico.u2f.crypto.BouncyCastleCrypto.checkSignature(BouncyCastleCrypto.java:35) ~[u2flib-server-core-0.19.7.jar!/:?]
        at com.yubico.u2f.data.messages.key.RawRegisterResponse.checkSignature(RawRegisterResponse.java:100) ~[u2flib-server-core-0.19.7.jar!/:?]
        at com.yubico.u2f.U2fPrimitives.finishRegistration(U2fPrimitives.java:93) ~[u2flib-server-core-0.19.7.jar!/:?]
        at com.yubico.u2f.U2F.finishRegistration(U2F.java:85) ~[u2flib-server-core-0.19.7.jar!/:?]
        at com.yubico.u2f.U2F.finishRegistration(U2F.java:71) ~[u2flib-server-core-0.19.7.jar!/:?]
        at org.apereo.cas.adaptors.u2f.web.flow.U2FAccountSaveRegistrationAction.doExecute(U2FAccountSaveRegistrationAction.java:37) ~[cas-server-support-u2f-6.1.2.jar!/:6.1.2]
        at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.State.enter(State.java:194) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.Transition.execute(Transition.java:228) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.ViewState.handleEvent(ViewState.java:231) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.ViewState.resume(ViewState.java:195) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.Flow.resume(Flow.java:537) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:168) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:279) ~[spring-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:499) ~[spring-cloud-context-2.2.0.RC1.jar!/:2.2.0.RC1]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at com.sun.proxy.$Proxy244.resumeExecution(Unknown Source) ~[?:?]
        at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:254) ~[spring-webflow-2.5.1.RELEASE.jar!/:2.5.1.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:665) ~[javax.servlet-api-4.0.1.jar!/:4.0.1]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[javax.servlet-api-4.0.1.jar!/:4.0.1]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apereo.cas.web.support.AuthenticationCredentialsThreadLocalBinderClearingFilter.doFilter(AuthenticationCredentialsThreadLocalBinderClearingFilter.java:28) ~[cas-server-core-web-api-6.1.2.jar!/:6.1.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apereo.cas.web.support.filters.RequestParameterPolicyEnforcementFilter.doFilter(RequestParameterPolicyEnforcementFilter.java:411) ~[cas-server-core-web-api-6.1.2.jar!/:6.1.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apereo.cas.web.support.filters.ResponseHeadersEnforcementFilter.doFilter(ResponseHeadersEnforcementFilter.java:215) ~[cas-server-core-web-api-6.1.2.jar!/:6.1.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apereo.cas.web.support.filters.AddResponseHeadersFilter.doFilter(AddResponseHeadersFilter.java:67) ~[cas-server-core-web-api-6.1.2.jar!/:6.1.2]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:157) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embd-core-9.0.27.jar!/:9.0.27]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-eb-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-wb-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tocat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embd-core-9.0.27.jar!/:9.0.27]
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricFilter.java:108) ~[spring-boot-actuator-2.2.0.RELEASE.jar!/:2.2.0.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-wb-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tocat-embed-core-9.0.27.jar!/:9.0.27]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embd-core-9.0.27.jar!/:9.0.27]

Cas also reported that he reviced the stack trace to the screen. Cas's key ius working with other u2f services e.g. github, google. Further we have confirmed times are correct on both sides

Event Timeline

jbond triaged this task as Medium priority.Jan 10 2020, 3:32 PM
jbond added a project: User-jbond.

Looking at the code it only accepts SHA256withECDSA which seems to be the only supported type in FIDO. The error message indicates the key being sent is a EC key

Here's a separate avenue that may be related to this. So the traceback from Java shows a bad signature, and I dug into this a bit with u2f testing sites.

https://u2f.bin.coffee/ works entirely with my key, except in U2F register, it fails on the Attestation Certificate signature - apparently the attestation signature is for restricting vendors, and seems like it should be a configuration option in the authenticator side. In any case here is the information I've been able to glean so far.

https://docs.crp.to/features.html#universal-2nd-factor-authentication-u2f

I have tried to do a bit of research on this and from my reading by default attestation signatures are not validated. Further the apereo cas software uses the com.yubico.u2f library however i don't see any mention of com.yubico.u2f.attestation.* or even the word attestation so i'm not sure how or where this validation may be getting switched on

jbond claimed this task.

cas reset his key and registration worked, re-open if a simlar issues is observed