Search in sources :

Example 1 with ValidationException

use of com.webauthn4j.validator.exception.ValidationException 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 ValidationException

use of com.webauthn4j.validator.exception.ValidationException 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 ValidationException

use of com.webauthn4j.validator.exception.ValidationException in project webauthn4j by webauthn4j.

the class ClientPlatform method get.

public PublicKeyCredential<AuthenticatorAssertionResponse, AuthenticationExtensionClientOutput> get(PublicKeyCredentialRequestOptions publicKeyCredentialRequestOptions, CollectedClientData collectedClientData, AuthenticationEmulationOption authenticationEmulationOption) {
    NoAuthenticatorSuccessException noAuthenticatorSuccessException = new NoAuthenticatorSuccessException();
    if (authenticatorAdaptor == null) {
        throw noAuthenticatorSuccessException;
    }
    try {
        CredentialRequestResponse credentialRequestResponse = authenticatorAdaptor.authenticate(publicKeyCredentialRequestOptions, collectedClientData, authenticationEmulationOption);
        byte[] credentialId = credentialRequestResponse.getCredentialId();
        AuthenticationExtensionsClientOutputs<AuthenticationExtensionClientOutput> clientExtensions = processAuthenticationExtensions(publicKeyCredentialRequestOptions.getExtensions());
        return new PublicKeyCredential<>(credentialId, new AuthenticatorAssertionResponse(credentialRequestResponse.getCollectedClientDataBytes(), credentialRequestResponse.getAuthenticatorDataBytes(), credentialRequestResponse.getSignature(), credentialRequestResponse.getUserHandle()), clientExtensions);
    } catch (ValidationException e) {
        noAuthenticatorSuccessException.addSuppressed(e);
    }
    throw noAuthenticatorSuccessException;
}
Also used : ValidationException(com.webauthn4j.validator.exception.ValidationException) CredentialRequestResponse(com.webauthn4j.test.authenticator.CredentialRequestResponse)

Example 4 with ValidationException

use of com.webauthn4j.validator.exception.ValidationException 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)

Example 5 with ValidationException

use of com.webauthn4j.validator.exception.ValidationException in project webauthn4j by webauthn4j.

the class DeviceCheckManagerSample method attestationValidationSample.

public void attestationValidationSample() {
    // Client properties
    byte[] keyId = null;
    /* set keyId */
    byte[] attestationObject = null;
    /* set attestationObject */
    byte[] challenge = null;
    /* set challenge */
    byte[] clientDataHash = MessageDigestUtil.createSHA256().digest(challenge);
    // Server properties
    String teamIdentifier = null;
    String cfBundleIdentifier = null;
    DCServerProperty dcServerProperty = new DCServerProperty(teamIdentifier, cfBundleIdentifier, new DefaultChallenge(challenge));
    DCAttestationRequest dcAttestationRequest = new DCAttestationRequest(keyId, attestationObject, clientDataHash);
    DCAttestationParameters dcAttestationParameters = new DCAttestationParameters(dcServerProperty);
    DCAttestationData dcAttestationData;
    try {
        dcAttestationData = deviceCheckManager.parse(dcAttestationRequest);
    } catch (DataConversionException e) {
        // If you would like to handle Apple App Attest data structure parse error, please catch DataConversionException
        throw e;
    }
    try {
        deviceCheckManager.validate(dcAttestationData, dcAttestationParameters);
    } catch (ValidationException e) {
        // If you would like to handle Apple App Attest data validation error, please catch ValidationException
        throw e;
    }
    // please persist Authenticator object, which will be used in the authentication process.
    DCAppleDevice dcAppleDevice = new // You may create your own Authenticator implementation to save friendly authenticator name
    DCAppleDeviceImpl(dcAttestationData.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(), dcAttestationData.getAttestationObject().getAttestationStatement(), dcAttestationData.getAttestationObject().getAuthenticatorData().getSignCount(), dcAttestationData.getAttestationObject().getAuthenticatorData().getExtensions());
    // please persist authenticator in your manner
    save(dcAppleDevice);
}
Also used : DCServerProperty(com.webauthn4j.appattest.server.DCServerProperty) DefaultChallenge(com.webauthn4j.data.client.challenge.DefaultChallenge) DCAppleDevice(com.webauthn4j.appattest.authenticator.DCAppleDevice) ValidationException(com.webauthn4j.validator.exception.ValidationException) DCAppleDeviceImpl(com.webauthn4j.appattest.authenticator.DCAppleDeviceImpl) DataConversionException(com.webauthn4j.converter.exception.DataConversionException)

Aggregations

ValidationException (com.webauthn4j.validator.exception.ValidationException)7 DataConversionException (com.webauthn4j.converter.exception.DataConversionException)6 ServerProperty (com.webauthn4j.server.ServerProperty)4 Authenticator (com.webauthn4j.authenticator.Authenticator)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 Origin (com.webauthn4j.data.client.Origin)2 Challenge (com.webauthn4j.data.client.challenge.Challenge)2 DefaultChallenge (com.webauthn4j.data.client.challenge.DefaultChallenge)2 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 ObjectInputStream (java.io.ObjectInputStream)2 ServletException (javax.servlet.ServletException)2 JSONObject (org.json.simple.JSONObject)2 JSONParser (org.json.simple.parser.JSONParser)2 ParseException (org.json.simple.parser.ParseException)2 UrlHolder (com.tremolosecurity.config.util.UrlHolder)1 AuthChainType (com.tremolosecurity.config.xml.AuthChainType)1