Search in sources :

Example 1 with DataConversionException

use of com.webauthn4j.converter.exception.DataConversionException in project OpenUnison by TremoloSecurity.

the class WebAuthnRegistration method storeCredential.

private void storeCredential(HttpFilterRequest request) throws ParseException, IOException, ClassNotFoundException, ServletException, Exception {
    byte[] requestBytes = (byte[]) request.getAttribute(ProxySys.MSG_BODY);
    String requestString = new String(requestBytes, StandardCharsets.UTF_8);
    JSONObject root = (JSONObject) new JSONParser().parse(requestString);
    if (root.get("label") == null || ((String) root.get("label")).isEmpty()) {
        throw new WebAuthnException("Label required");
    }
    ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getUrlDecoder().decode((String) root.get("serverProperty")));
    ObjectInputStream ois = new ObjectInputStream(bais);
    ServerProperty serverProperty = (ServerProperty) ois.readObject();
    byte[] attestationObject = Base64.getUrlDecoder().decode((String) root.get("attestationObject"));
    byte[] clientDataJSON = Base64.getUrlDecoder().decode((String) root.get("clientDataJSON"));
    String clientExtensionJSON = (String) root.get("clientExtResults");
    Set<String> transports = new HashSet<String>();
    // expectations
    boolean userVerificationRequired = false;
    boolean userPresenceRequired = true;
    RegistrationRequest registrationRequest = new RegistrationRequest(attestationObject, clientDataJSON, clientExtensionJSON, transports);
    RegistrationParameters registrationParameters = new RegistrationParameters(serverProperty, userVerificationRequired, userPresenceRequired);
    RegistrationData registrationData;
    WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
    try {
        registrationData = webAuthnManager.parse(registrationRequest);
    } catch (DataConversionException e) {
        // If you would like to handle WebAuthn data structure parse error, please catch DataConversionException
        throw e;
    }
    try {
        webAuthnManager.validate(registrationData, registrationParameters);
    } catch (ValidationException e) {
        // If you would like to handle WebAuthn data validation error, please catch ValidationException
        throw e;
    }
    OpenUnisonAuthenticator authenticator = new OpenUnisonAuthenticator((String) root.get("label"), registrationData.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(), registrationData.getAttestationObject().getAttestationStatement(), registrationData.getAttestationObject().getAuthenticatorData().getSignCount());
    AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
    WebAuthnUserData webAuthnUserData = WebAuthnUtils.lookupWebAuthnUserData(userData, this.challengeStoreAttribute, this.encryptionKeyName);
    if (webAuthnUserData == null) {
        throw new Exception("No webauthn user data, should not happen");
    }
    for (OpenUnisonAuthenticator auth : webAuthnUserData.getAuthenticators()) {
        if (auth.getLabel().equals(authenticator.getLabel())) {
            throw new WebAuthnException("Label already exists, choose another label");
        }
    }
    webAuthnUserData.getAuthenticators().add(authenticator);
    WebAuthnUtils.storeWebAuthnUserData(webAuthnUserData, encryptionKeyName, userData, workflowName, uidAttributeName, challengeStoreAttribute);
}
Also used : RegistrationData(com.webauthn4j.data.RegistrationData) AuthInfo(com.tremolosecurity.proxy.auth.AuthInfo) ServerProperty(com.webauthn4j.server.ServerProperty) ValidationException(com.webauthn4j.validator.exception.ValidationException) OpenUnisonAuthenticator(com.tremolosecurity.proxy.auth.webauthn.OpenUnisonAuthenticator) WebAuthnUserData(com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData) WebAuthnManager(com.webauthn4j.WebAuthnManager) RegistrationRequest(com.webauthn4j.data.RegistrationRequest) AuthController(com.tremolosecurity.proxy.auth.AuthController) ValidationException(com.webauthn4j.validator.exception.ValidationException) ServletException(javax.servlet.ServletException) WebAuthnException(com.webauthn4j.util.exception.WebAuthnException) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ParseException(org.json.simple.parser.ParseException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) WebAuthnException(com.webauthn4j.util.exception.WebAuthnException) JSONObject(org.json.simple.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONParser(org.json.simple.parser.JSONParser) RegistrationParameters(com.webauthn4j.data.RegistrationParameters) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ObjectInputStream(java.io.ObjectInputStream) HashSet(java.util.HashSet)

Example 2 with DataConversionException

use of com.webauthn4j.converter.exception.DataConversionException in project OpenUnison by TremoloSecurity.

the class WebAuthn method doPost.

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response, AuthStep as) throws IOException, ServletException {
    if (request.getParameter("webauthnResponse") != null) {
        AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        // SharedSession.getSharedSession().getSession(req.getSession().getId());
        HttpSession session = ((HttpServletRequest) request).getSession();
        UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
        RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
        String urlChain = holder.getUrl().getAuthChain();
        AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
        AuthMechType amt = act.getAuthMech().get(as.getId());
        HashMap<String, Attribute> authParams = (HashMap<String, Attribute>) session.getAttribute(ProxyConstants.AUTH_MECH_PARAMS);
        ByteArrayInputStream bais = new ByteArrayInputStream(Base64UrlUtil.decode((String) request.getParameter("serverProperty")));
        ObjectInputStream ois = new ObjectInputStream(bais);
        ServerProperty serverProperty = null;
        try {
            serverProperty = (ServerProperty) ois.readObject();
        } catch (ClassNotFoundException | IOException e) {
            throw new ServletException(e);
        }
        String attributeName = authParams.get("attribute").getValues().get(0);
        String encryptionKeyName = authParams.get("encryptionKeyName").getValues().get(0);
        Authenticator auth = null;
        if (userData.getAttribs().get(attributeName) == null) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' does not have attribute '").append(attributeName).append("'");
            logger.warn(sb.toString());
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        WebAuthnUserData webauthnUser = WebAuthnUtils.lookupWebAuthnUserData(userData, attributeName, encryptionKeyName);
        if (webauthnUser == null) {
            throw new ServletException("No webauthn user data, can not happen");
        }
        JSONObject webauthnResp = null;
        try {
            webauthnResp = (JSONObject) new JSONParser().parse(request.getParameter("webauthnResponse"));
        } catch (ParseException e) {
            throw new ServletException("could not parse webauthn response", e);
        }
        byte[] credentialId = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("credential_id"));
        byte[] userHandle = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("userHandle"));
        ;
        byte[] authenticatorData = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("authenticatorData"));
        byte[] clientDataJSON = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("clientDataJSON"));
        String clientExtensionJSON = (String) webauthnResp.get("clientExtResults");
        byte[] signature = java.util.Base64.getUrlDecoder().decode((String) webauthnResp.get("signature"));
        if (!Arrays.equals(userHandle, webauthnUser.getId())) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' credential not owned by the client");
            logger.warn(sb.toString());
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        auth = null;
        for (Authenticator checkUser : webauthnUser.getAuthenticators()) {
            if (Arrays.equals(checkUser.getAttestedCredentialData().getCredentialId(), credentialId)) {
                auth = checkUser;
            }
        }
        if (auth == null) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' does not have a credential associated with '").append((String) webauthnResp.get("credential_id")).append("'");
            logger.warn(sb.toString());
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        AuthenticationRequest authenticationRequest = new AuthenticationRequest(credentialId, userHandle, authenticatorData, clientDataJSON, clientExtensionJSON, signature);
        AuthenticationParameters authenticationParameters = new AuthenticationParameters(serverProperty, auth, null, false, true);
        WebAuthnManager webAuthnManager = WebAuthnManager.createNonStrictWebAuthnManager();
        AuthenticationData authenticationData;
        try {
            authenticationData = webAuthnManager.parse(authenticationRequest);
        } catch (DataConversionException e) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' could not parse authentication data with credential '").append((String) webauthnResp.get("credential_id")).append("'");
            logger.warn(sb.toString(), e);
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        try {
            webAuthnManager.validate(authenticationData, authenticationParameters);
        } catch (ValidationException e) {
            StringBuilder sb = new StringBuilder();
            sb.append("User '").append(userData.getUserDN()).append("' could not validate authentication data with credential '").append((String) webauthnResp.get("credential_id")).append("'");
            logger.warn(sb.toString(), e);
            as.setExecuted(true);
            as.setSuccess(false);
            holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
            return;
        }
        as.setExecuted(true);
        as.setSuccess(true);
        holder.getConfig().getAuthManager().nextAuth(request, response, session, false);
    } else {
        // redirect the user to the correct URL
        AuthInfo userData = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getAuthInfo();
        // SharedSession.getSharedSession().getSession(req.getSession().getId());
        HttpSession session = ((HttpServletRequest) request).getSession();
        UrlHolder holder = (UrlHolder) request.getAttribute(ProxyConstants.AUTOIDM_CFG);
        RequestHolder reqHolder = ((AuthController) request.getSession().getAttribute(ProxyConstants.AUTH_CTL)).getHolder();
        String urlChain = holder.getUrl().getAuthChain();
        AuthChainType act = holder.getConfig().getAuthChains().get(reqHolder.getAuthChainName());
        AuthMechType amt = act.getAuthMech().get(as.getId());
        response.sendRedirect(holder.getConfig().getAuthMechs().get(amt.getName()).getUri());
        return;
    }
}
Also used : AuthenticationParameters(com.webauthn4j.data.AuthenticationParameters) ValidationException(com.webauthn4j.validator.exception.ValidationException) AuthenticationData(com.webauthn4j.data.AuthenticationData) Attribute(com.tremolosecurity.saml.Attribute) HashMap(java.util.HashMap) HttpServletRequest(javax.servlet.http.HttpServletRequest) UrlHolder(com.tremolosecurity.config.util.UrlHolder) ServletException(javax.servlet.ServletException) AuthenticationRequest(com.webauthn4j.data.AuthenticationRequest) AuthChainType(com.tremolosecurity.config.xml.AuthChainType) Authenticator(com.webauthn4j.authenticator.Authenticator) ServerProperty(com.webauthn4j.server.ServerProperty) HttpSession(javax.servlet.http.HttpSession) WebAuthnUserData(com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData) AuthMechType(com.tremolosecurity.config.xml.AuthMechType) WebAuthnManager(com.webauthn4j.WebAuthnManager) IOException(java.io.IOException) JSONObject(org.json.simple.JSONObject) ByteArrayInputStream(java.io.ByteArrayInputStream) JSONParser(org.json.simple.parser.JSONParser) ParseException(org.json.simple.parser.ParseException) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) ObjectInputStream(java.io.ObjectInputStream)

Example 3 with DataConversionException

use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j-spring-security by webauthn4j.

the class FidoServerAttestationOptionsEndpointFilter method processRequest.

@Override
protected ServerResponse processRequest(HttpServletRequest request) {
    InputStream inputStream;
    try {
        inputStream = request.getInputStream();
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    try {
        ServerPublicKeyCredentialCreationOptionsRequest serverRequest = objectConverter.getJsonConverter().readValue(inputStream, ServerPublicKeyCredentialCreationOptionsRequest.class);
        String username = serverRequest.getUsername();
        String displayName = serverRequest.getDisplayName();
        Challenge challenge = serverEndpointFilterUtil.encodeUsername(new DefaultChallenge(), username);
        challengeRepository.saveChallenge(challenge, request);
        // TODO: UsernamePasswordAuthenticationToken should not be used here in this way
        AttestationOptions attestationOptions = optionsProvider.getAttestationOptions(request, new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()));
        String userHandle;
        if (attestationOptions.getUser() == null) {
            userHandle = Base64UrlUtil.encodeToString(generateUserHandle());
        } else {
            userHandle = Base64UrlUtil.encodeToString(attestationOptions.getUser().getId());
        }
        ServerPublicKeyCredentialUserEntity user = new ServerPublicKeyCredentialUserEntity(userHandle, username, displayName);
        List<ServerPublicKeyCredentialDescriptor> credentials = attestationOptions.getExcludeCredentials().stream().map(credential -> new ServerPublicKeyCredentialDescriptor(credential.getType(), Base64UrlUtil.encodeToString(credential.getId()), credential.getTransports())).collect(Collectors.toList());
        AuthenticationExtensionsClientInputs<RegistrationExtensionClientInput> authenticationExtensionsClientInputs;
        if (serverRequest.getExtensions() != null) {
            authenticationExtensionsClientInputs = serverRequest.getExtensions();
        } else {
            authenticationExtensionsClientInputs = attestationOptions.getExtensions();
        }
        return new ServerPublicKeyCredentialCreationOptionsResponse(attestationOptions.getRp(), user, Base64UrlUtil.encodeToString(attestationOptions.getChallenge().getValue()), attestationOptions.getPubKeyCredParams(), attestationOptions.getTimeout(), credentials, serverRequest.getAuthenticatorSelection(), serverRequest.getAttestation(), authenticationExtensionsClientInputs);
    } catch (DataConversionException e) {
        throw new com.webauthn4j.springframework.security.exception.DataConversionException("Failed to convert data", e);
    }
}
Also used : AttestationOptions(com.webauthn4j.springframework.security.options.AttestationOptions) IOException(java.io.IOException) Challenge(com.webauthn4j.data.client.challenge.Challenge) UUID(java.util.UUID) ChallengeRepository(com.webauthn4j.springframework.security.challenge.ChallengeRepository) Base64UrlUtil(com.webauthn4j.util.Base64UrlUtil) Collectors(java.util.stream.Collectors) ByteBuffer(java.nio.ByteBuffer) AuthenticationExtensionsClientInputs(com.webauthn4j.data.extension.client.AuthenticationExtensionsClientInputs) AttestationOptionsProvider(com.webauthn4j.springframework.security.options.AttestationOptionsProvider) UncheckedIOException(java.io.UncheckedIOException) HttpServletRequest(javax.servlet.http.HttpServletRequest) List(java.util.List) ObjectConverter(com.webauthn4j.converter.util.ObjectConverter) UsernamePasswordAuthenticationToken(org.springframework.security.authentication.UsernamePasswordAuthenticationToken) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) RegistrationExtensionClientInput(com.webauthn4j.data.extension.client.RegistrationExtensionClientInput) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) Collections(java.util.Collections) Assert(org.springframework.util.Assert) InputStream(java.io.InputStream) InputStream(java.io.InputStream) AttestationOptions(com.webauthn4j.springframework.security.options.AttestationOptions) UncheckedIOException(java.io.UncheckedIOException) UsernamePasswordAuthenticationToken(org.springframework.security.authentication.UsernamePasswordAuthenticationToken) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) Challenge(com.webauthn4j.data.client.challenge.Challenge) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) RegistrationExtensionClientInput(com.webauthn4j.data.extension.client.RegistrationExtensionClientInput) DataConversionException(com.webauthn4j.converter.exception.DataConversionException)

Example 4 with DataConversionException

use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j-spring-security by webauthn4j.

the class FidoServerAttestationResultEndpointFilter method processRequest.

@Override
protected ServerResponse processRequest(HttpServletRequest request) {
    InputStream inputStream;
    try {
        inputStream = request.getInputStream();
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    try {
        ServerPublicKeyCredential<ServerAuthenticatorAttestationResponse> credential = this.objectConverter.getJsonConverter().readValue(inputStream, credentialTypeRef);
        serverPublicKeyCredentialValidator.validate(credential);
        ServerAuthenticatorAttestationResponse response = credential.getResponse();
        CollectedClientData collectedClientData = collectedClientDataConverter.convert(response.getClientDataJSON());
        AttestationObject attestationObject = attestationObjectConverter.convert(response.getAttestationObject());
        Set<String> transports = Collections.emptySet();
        webAuthnRegistrationRequestValidator.validate(request, response.getClientDataJSON(), response.getAttestationObject(), transports, credential.getClientExtensionResults());
        String loginUsername = serverEndpointFilterUtil.decodeUsername(collectedClientData.getChallenge());
        try {
            userDetailsService.loadUserByUsername(loginUsername);
        } catch (UsernameNotFoundException e) {
            usernameNotFoundHandler.onUsernameNotFound(loginUsername);
        }
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginUsername);
        WebAuthnAuthenticatorImpl webAuthnAuthenticator = new WebAuthnAuthenticatorImpl("Authenticator", loginUsername, attestationObject.getAuthenticatorData().getAttestedCredentialData(), attestationObject.getAttestationStatement(), attestationObject.getAuthenticatorData().getSignCount());
        webAuthnAuthenticatorManager.createAuthenticator(webAuthnAuthenticator);
        return new AttestationResultSuccessResponse();
    } catch (DataConversionException e) {
        throw new com.webauthn4j.springframework.security.exception.DataConversionException("Failed to convert data", e);
    }
}
Also used : UsernameNotFoundException(org.springframework.security.core.userdetails.UsernameNotFoundException) WebAuthnAuthenticatorImpl(com.webauthn4j.springframework.security.authenticator.WebAuthnAuthenticatorImpl) InputStream(java.io.InputStream) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) CollectedClientData(com.webauthn4j.data.client.CollectedClientData) UserDetails(org.springframework.security.core.userdetails.UserDetails) AttestationObject(com.webauthn4j.data.attestation.AttestationObject) DataConversionException(com.webauthn4j.converter.exception.DataConversionException)

Example 5 with DataConversionException

use of com.webauthn4j.converter.exception.DataConversionException in project webauthn4j by webauthn4j.

the class WebAuthnManagerSample method authenticationValidationSample.

public void authenticationValidationSample() {
    // Client properties
    byte[] credentialId = null;
    byte[] userHandle = null;
    byte[] authenticatorData = null;
    byte[] clientDataJSON = null;
    String clientExtensionJSON = null;
    byte[] signature = null;
    // Server properties
    Origin origin = null;
    String rpId = null;
    Challenge challenge = null;
    byte[] tokenBindingId = null;
    ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, tokenBindingId);
    // expectations
    List<byte[]> allowCredentials = null;
    boolean userVerificationRequired = true;
    boolean userPresenceRequired = true;
    List<String> expectedExtensionIds = Collections.emptyList();
    // please load authenticator object persisted in the registration process in your manner
    Authenticator authenticator = load(credentialId);
    AuthenticationRequest authenticationRequest = new AuthenticationRequest(credentialId, userHandle, authenticatorData, clientDataJSON, clientExtensionJSON, signature);
    AuthenticationParameters authenticationParameters = new AuthenticationParameters(serverProperty, authenticator, allowCredentials, userVerificationRequired, userPresenceRequired);
    AuthenticationData authenticationData;
    try {
        authenticationData = webAuthnManager.parse(authenticationRequest);
    } catch (DataConversionException e) {
        // If you would like to handle WebAuthn data structure parse error, please catch DataConversionException
        throw e;
    }
    try {
        webAuthnManager.validate(authenticationData, authenticationParameters);
    } catch (ValidationException e) {
        // If you would like to handle WebAuthn data validation error, please catch ValidationException
        throw e;
    }
    // please update the counter of the authenticator record
    updateCounter(authenticationData.getCredentialId(), authenticationData.getAuthenticatorData().getSignCount());
}
Also used : Origin(com.webauthn4j.data.client.Origin) ServerProperty(com.webauthn4j.server.ServerProperty) ValidationException(com.webauthn4j.validator.exception.ValidationException) Challenge(com.webauthn4j.data.client.challenge.Challenge) DataConversionException(com.webauthn4j.converter.exception.DataConversionException) Authenticator(com.webauthn4j.authenticator.Authenticator)

Aggregations

DataConversionException (com.webauthn4j.converter.exception.DataConversionException)18 IOException (java.io.IOException)8 ValidationException (com.webauthn4j.validator.exception.ValidationException)6 UncheckedIOException (java.io.UncheckedIOException)6 ServerProperty (com.webauthn4j.server.ServerProperty)5 NonNull (org.checkerframework.checker.nullness.qual.NonNull)5 Challenge (com.webauthn4j.data.client.challenge.Challenge)4 DefaultChallenge (com.webauthn4j.data.client.challenge.DefaultChallenge)4 InputStream (java.io.InputStream)4 Authenticator (com.webauthn4j.authenticator.Authenticator)3 HttpServletRequest (javax.servlet.http.HttpServletRequest)3 Nullable (org.checkerframework.checker.nullness.qual.Nullable)3 WebAuthnUserData (com.tremolosecurity.proxy.auth.webauthn.WebAuthnUserData)2 WebAuthnManager (com.webauthn4j.WebAuthnManager)2 DCAppleDevice (com.webauthn4j.appattest.authenticator.DCAppleDevice)2 DCServerProperty (com.webauthn4j.appattest.server.DCServerProperty)2 ObjectConverter (com.webauthn4j.converter.util.ObjectConverter)2 AttestedCredentialData (com.webauthn4j.data.attestation.authenticator.AttestedCredentialData)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ObjectInputStream (java.io.ObjectInputStream)2