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 created this task.Jan 10 2020, 3:31 PM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJan 10 2020, 3:31 PM
jbond triaged this task as Medium priority.Jan 10 2020, 3:32 PM
jbond added a project: User-jbond.
jbond added a comment.Jan 10 2020, 3:50 PM

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

jbond moved this task from Unsorted 💣 to Active 🚁 on the User-jbond board.Jan 20 2020, 10:45 AM

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

jbond added a comment.Jan 29 2020, 7:48 PM

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 closed this task as Resolved.Feb 14 2020, 2:30 PM
jbond claimed this task.

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