private String processCertificate(HttpHeaders headers) {

        //
        // NOTE: A result with an associated state is ALWAYS returned by
        // processCertificate(), even if the request does not actually contain
        // a valid certificate. This is by design and ensures that the nature
        // of a certificate (valid vs. invalid) cannot be determined except
        // via Guacamole's authentication endpoint, thus allowing auth failure
        // hooks to consider attempts to use invalid certificates as auth
        // failures.
        //

        try {

            // Verify that SSL termination has already verified the certificate
            String verified = getHeader(headers, confService.getClientVerifiedHeader());
            if (verified != null && verified.startsWith(CLIENT_VERIFIED_HEADER_FAILED_PREFIX)) {
                String message = verified.substring(CLIENT_VERIFIED_HEADER_FAILED_PREFIX.length());
                throw new GuacamoleClientException("Client certificate did "
                        + "not pass validation. SSL termination reports the "
                        + "following failure: \"" + message + "\"");
            }
            else if (CLIENT_VERIFIED_HEADER_NONE_VALUE.equals(verified)) {
                throw new GuacamoleClientException("No client certificate was presented.");
            }
            else if (!CLIENT_VERIFIED_HEADER_SUCCESS_VALUE.equals(verified)) {
                throw new GuacamoleClientException("Client certificate did not pass validation.");
            }

            String certificate = getHeader(headers, confService.getClientCertificateHeader());
            if (certificate == null)
                throw new GuacamoleClientException("Client certificate missing from request.");

            String username = getUsername(decode(certificate));
            long validityDuration = TimeUnit.MINUTES.toMillis(confService.getMaxTokenValidity());
            return sessionManager.defer(new SSLAuthenticationSession(username, validityDuration));

        }
        catch (GuacamoleClientException e) {
            logger.warn("SSL/TLS client authentication attempt rejected: {}", e.getMessage());
            logger.debug("SSL/TLS client authentication failed.", e);
        }
        catch (GuacamoleException e) {
            logger.error("SSL/TLS client authentication attempt could not be processed: {}", e.getMessage());
            logger.debug("SSL/TLS client authentication failed.", e);
        }
        catch (RuntimeException | Error e) {
            logger.error("SSL/TLS client authentication attempt failed internally: {}", e.getMessage());
            logger.debug("Internal failure processing SSL/TLS client authentication attempt.", e);
        }

        return sessionManager.generateInvalid();

    }
Processes the X.509 certificate in the given set of HTTP request
headers, returning an authentication session token representing the
identity in that certificate. If the certificate is invalid or not
present, an invalid session token is returned.

@param headers
    The headers of the HTTP request to process.

@return
    An authentication session token representing the identity in the
    certificate in the given HTTP request, or an invalid session token
    if no valid identity was asserted.
extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java