/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * This module adds support for https://tools.ietf.org/html/rfc7519 JWT tokens
 * as https://tools.ietf.org/html/rfc6750 Bearer tokens, both as a generator
 * of JWT bearer tokens, and as an acceptor of JWT Bearer tokens for authentication.
 */

/* apr_jose support requires >= 1.7 */
#if APU_MAJOR_VERSION > 1 || \
    (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION > 6)
#define HAVE_APU_JOSE 1
#endif

#include "httpd.h"
#include "http_config.h"

#ifdef HAVE_APU_JOSE

#include "apr_strings.h"
#include "apr_hash.h"
#include "apr_crypto.h"
#include "apr_jose.h"
#include "apr_lib.h"            /* for apr_isspace */
#include "apr_base64.h"         /* for apr_base64_decode et al */
#define APR_WANT_STRFUNC        /* for strcasecmp */
#include "apr_want.h"

#include "ap_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_md5.h"
#include "ap_provider.h"
#include "ap_expr.h"

#include "mod_auth.h"

#define CRYPTO_KEY "auth_bearer_context"

module AP_MODULE_DECLARE_DATA autht_jwt_module;

typedef enum jws_alg_type_e {
    /** No specific type. */
    JWS_ALG_TYPE_NONE = 0,
    /** HMAC SHA256 */
    JWS_ALG_TYPE_HS256 = 1,
} jws_alg_type_e;

typedef struct {
    unsigned char *secret;
    apr_size_t secret_len;
    jws_alg_type_e jws_alg;
} auth_bearer_signature_rec;

typedef struct {
    apr_hash_t *claims;
    apr_array_header_t *signs;
    apr_array_header_t *verifies;
    unsigned int signs_set      :1,
                 verifies_set   :1;
} auth_bearer_config_rec;

typedef struct {
    const char *library;
    const char *params;
    apr_crypto_t **crypto;
    unsigned int library_set    :1;
} auth_bearer_conf;

static int auth_bearer_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
        server_rec *s) {
    const apr_crypto_driver_t *driver = NULL;

    /* auth_bearer_init() will be called twice. Don't bother
     * going through all of the initialization on the first call
     * because it will just be thrown away.*/
    if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
        return OK;
    }

    while (s) {

        auth_bearer_conf *conf = ap_get_module_config(s->module_config,
                &autht_jwt_module);

        if (conf->library_set && !*conf->crypto) {

            const apu_err_t *err = NULL;
            apr_status_t rv;

            rv = apr_crypto_init(p);
            if (APR_SUCCESS != rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        APLOGNO(10432) "APR crypto could not be initialised");
                return rv;
            }

            rv = apr_crypto_get_driver(&driver, conf->library, conf->params,
                    &err, p);
            if (APR_EREINIT == rv) {
                ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
                        APLOGNO(10433) "warning: crypto for '%s' was already initialised, " "using existing configuration",
                        conf->library);
                rv = APR_SUCCESS;
            }
            if (APR_SUCCESS != rv && err) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        APLOGNO(10434) "The crypto library '%s' could not be loaded: %s (%s: %d)",
                        conf->library, err->msg, err->reason, err->rc);
                return rv;
            }
            if (APR_ENOTIMPL == rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        APLOGNO(10435) "The crypto library '%s' could not be found",
                        conf->library);
                return rv;
            }
            if (APR_SUCCESS != rv || !driver) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        APLOGNO(10436) "The crypto library '%s' could not be loaded",
                        conf->library);
                return rv;
            }

            rv = apr_crypto_make(conf->crypto, driver, conf->params, p);
            if (APR_SUCCESS != rv) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                        APLOGNO(10437) "The crypto library '%s' could not be initialised",
                        conf->library);
                return rv;
            }

            ap_log_error(APLOG_MARK, APLOG_INFO, rv, s,
                    APLOGNO(10438) "The crypto library '%s' was loaded successfully",
                    conf->library);

        }

        s = s->next;
    }

    return OK;
}

static void *create_auth_bearer_config(apr_pool_t * p, server_rec *s)
{
    auth_bearer_conf *new =
    (auth_bearer_conf *) apr_pcalloc(p, sizeof(auth_bearer_conf));

    /* if no library has been configured, set the recommended library
     * as a sensible default.
     */
#ifdef APU_CRYPTO_RECOMMENDED_DRIVER
    new->library = APU_CRYPTO_RECOMMENDED_DRIVER;
#endif
    new->crypto = apr_pcalloc(p, sizeof(apr_crypto_t *));

    return (void *) new;
}

static void *merge_auth_bearer_config(apr_pool_t * p, void *basev, void *addv)
{
    auth_bearer_conf *new = (auth_bearer_conf *) apr_pcalloc(p, sizeof(auth_bearer_conf));
    auth_bearer_conf *add = (auth_bearer_conf *) addv;
    auth_bearer_conf *base = (auth_bearer_conf *) basev;

    new->library = (add->library_set == 0) ? base->library : add->library;
    new->params = (add->library_set == 0) ? base->params : add->params;
    new->library_set = add->library_set || base->library_set;

    new->crypto = base->crypto;

    return (void *) new;
}

static void *create_auth_bearer_dir_config(apr_pool_t *p, char *d)
{
    auth_bearer_config_rec *conf = apr_pcalloc(p, sizeof(*conf));

    conf->claims = apr_hash_make(p);
    conf->signs = apr_array_make(p, 1, sizeof(auth_bearer_signature_rec));
    conf->verifies = apr_array_make(p, 1, sizeof(auth_bearer_signature_rec));

    return conf;
}

static void *merge_auth_bearer_dir_config(apr_pool_t *p, void *basev, void *overridesv)
{
    auth_bearer_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
    auth_bearer_config_rec *base = basev;
    auth_bearer_config_rec *overrides = overridesv;

    newconf->claims = apr_hash_overlay(p, overrides->claims,
                                          base->claims);

    newconf->signs =
            overrides->signs_set ? overrides->signs : base->signs;
    newconf->signs_set = overrides->signs_set || base->signs_set;

    newconf->verifies =
            overrides->verifies_set ? overrides->verifies : base->verifies;
    newconf->verifies_set = overrides->verifies_set || base->verifies_set;

    return newconf;
}

static const char *set_jwt_claim(cmd_parms *cmd, void *config,
        const char *op, const char *key, const char *expression)
{
    auth_bearer_config_rec *conf = (auth_bearer_config_rec *) config;
    const char *err;

    if (!strcasecmp(op, "set")) {
        ap_expr_info_t *expr;

        expr = ap_expr_parse_cmd(cmd, expression, AP_EXPR_FLAG_STRING_RESULT,
                &err, NULL);
        if (err) {
            return apr_psprintf(cmd->pool,
                    "Could not parse claim '%s' expression '%s': %s", key,
                    expression, err);
        }

        apr_hash_set(conf->claims, key, APR_HASH_KEY_STRING, expr);

    } else if (!strcasecmp(op, "unset")) {

        apr_hash_set(conf->claims, key, APR_HASH_KEY_STRING, NULL);

    } else {

        return apr_psprintf(cmd->pool,
                "Could not parse claim operation '%s', "
                "values should be 'set' or 'unset'", op);

    }

    return NULL;
}

static const char *set_jwt_sign(cmd_parms * cmd, void *config,
        const char *alg, const char *type, const char *sig)
{
    auth_bearer_config_rec *dconf = (auth_bearer_config_rec *) config;

    auth_bearer_signature_rec *srec = apr_array_push(dconf->signs);

    /* handle the algorithm */
    if (!strcasecmp(alg, "none")) {
        srec->jws_alg = JWS_ALG_TYPE_NONE;
        if (type || sig) {
            return "AuthtJwtSign: algorithm 'none' has extra parameters";
        }
    }
    else if (!strcasecmp(alg, "HS256")) {
        srec->jws_alg = JWS_ALG_TYPE_HS256;
    }
    else {
        return apr_psprintf(cmd->pool, "AuthtJwtSign: algorithm not supported: %s", alg);
    }

    /* handle the file */
    if (type) {
        if (!strcasecmp(type, "file")) {
            apr_file_t *file;
            apr_finfo_t finfo;
            apr_status_t status;

            sig = ap_server_root_relative(cmd->temp_pool, sig);

            status = apr_file_open(&file, sig, APR_READ | APR_BUFFERED,
            APR_OS_DEFAULT, cmd->pool);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtSign: file '%s' could not be opened: %s", sig,
                        buf);
            }

            status = apr_file_info_get(&finfo, APR_FINFO_TYPE | APR_FINFO_SIZE,
                    file);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtSign: info could not be obtained for '%s': %s",
                        sig, buf);
            }

            srec->secret = apr_palloc(cmd->pool, finfo.size);
            srec->secret_len = finfo.size;

            status = apr_file_read_full(file, srec->secret,
                    srec->secret_len, NULL);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtSign: file '%s' could not be read: %s", sig,
                        buf);
            }

            apr_file_close(file);

        }
        else {
            return apr_psprintf(cmd->pool,
                    "AuthtJwtSign: parameter '%s' is not 'file'", type);
        }
    }

    dconf->signs_set = 1;

    return NULL;
}

static const char *set_jwt_verify(cmd_parms * cmd, void *config,
        const char *alg, const char *type, const char *sig)
{
    auth_bearer_config_rec *dconf = (auth_bearer_config_rec *) config;

    auth_bearer_signature_rec *srec = apr_array_push(dconf->verifies);

    /* handle the algorithm */
    if (!strcasecmp(alg, "none")) {
        srec->jws_alg = JWS_ALG_TYPE_NONE;
        if (type || sig) {
            return "AuthtJwtVerify: algorithm 'none' has extra parameters";
        }
    }
    else if (!strcasecmp(alg, "HS256")) {
        srec->jws_alg = JWS_ALG_TYPE_HS256;
    }
    else {
        return apr_psprintf(cmd->pool, "AuthtJwtVerify: algorithm not supported: %s", alg);
    }

    /* handle the file */
    if (type) {
        if (!strcasecmp(type, "file")) {
            apr_file_t *file;
            apr_finfo_t finfo;
            apr_status_t status;

            sig = ap_server_root_relative(cmd->temp_pool, sig);

            status = apr_file_open(&file, sig, APR_READ | APR_BUFFERED,
            APR_OS_DEFAULT, cmd->pool);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtVerify: file '%s' could not be opened: %s", sig,
                        buf);
            }

            status = apr_file_info_get(&finfo, APR_FINFO_TYPE | APR_FINFO_SIZE,
                    file);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtVerify: info could not be obtained for '%s': %s",
                        sig, buf);
            }

            srec->secret = apr_palloc(cmd->pool, finfo.size);
            srec->secret_len = finfo.size;

            status = apr_file_read_full(file, srec->secret,
                    srec->secret_len, NULL);
            if (status != APR_SUCCESS) {
                char buf[1024];
                apr_strerror(status, buf, sizeof(buf));
                return apr_psprintf(cmd->pool,
                        "AuthtJwtVerify: file '%s' could not be read: %s", sig,
                        buf);
            }

            apr_file_close(file);

        }
        else {
            return apr_psprintf(cmd->pool,
                    "AuthtJwtVerify: parameter '%s' is not 'file'", type);
        }
    }

    dconf->verifies_set = 1;

    return NULL;
}

static const char *set_jwt_driver(cmd_parms * cmd, void *config, const char *arg)
{
    auth_bearer_conf *conf =
            (auth_bearer_conf *)ap_get_module_config(cmd->server->module_config,
            &autht_jwt_module);

    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    conf->library = ap_getword_conf(cmd->pool, &arg);
    conf->params = arg;
    conf->library_set = 1;

    return NULL;
}

static const command_rec auth_bearer_cmds[] =
{
    AP_INIT_TAKE13("AuthtJwtVerify", set_jwt_verify, NULL, RSRC_CONF|OR_AUTHCFG,
                   "The JWS signing algorithm and passphrase/key to verify an incoming JWT token"),
    AP_INIT_TAKE13("AuthtJwtSign", set_jwt_sign, NULL, RSRC_CONF|OR_AUTHCFG,
            "The JWS signing algorithm and passphrase/key to sign an outgoing JWT token"),

    AP_INIT_TAKE23("AuthtJwtClaim", set_jwt_claim, NULL, OR_AUTHCFG,
            "Set a claim with the given name and expression, or "
            "unset the claim with the given name."),

    AP_INIT_RAW_ARGS("AuthtJwtDriver", set_jwt_driver, NULL, RSRC_CONF,
            "The underlying crypto library driver to use"),

    {NULL}
};

typedef struct claim_iter_t {
    request_rec *r;
    apr_json_value_t *object;
} claim_iter_t;

static int claim_iter(void *ctx, const void *key, apr_ssize_t klen,
                     const void *val)
{
    const char *err, *value;
    claim_iter_t *iter = ctx;
    request_rec *r = iter->r;

    value = ap_expr_str_exec(r, val, &err);
    if (err) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10439)
                "AuthtJwtClaim: could not evaluate '%s' expression "
                "'%s' for URI '%s': %s",
                (char * )key, (char * )val, r->uri, err);
        return FALSE;
    }


    apr_json_object_set(iter->object, key, klen,
            apr_json_string_create(r->pool, value, strlen(value)), r->pool);

    return TRUE;
}

static apr_status_t sign_cb(apr_bucket_brigade *bb, apr_jose_t *jose,
        apr_jose_signature_t *signature, void *ctx, apr_pool_t *pool) {
    auth_bearer_signature_rec *srec = NULL;
    request_rec *r = ctx;

    auth_bearer_conf *sconf = ap_get_module_config(r->server->module_config,
            &autht_jwt_module);

    auth_bearer_config_rec *conf = ap_get_module_config(r->per_dir_config,
            &autht_jwt_module);

    if (conf->signs_set) {
        srec = (auth_bearer_signature_rec *) conf->signs->elts;
    }

    if (srec) {
        switch (srec->jws_alg) {
        case JWS_ALG_TYPE_NONE: {

            return APR_SUCCESS;
        }
        case JWS_ALG_TYPE_HS256: {
            apr_bucket *e;
            apr_crypto_key_rec_t *krec;
            apr_crypto_key_t *key = NULL;
            apr_crypto_digest_t *digest = NULL;
            apr_crypto_digest_rec_t *rec;
            char * buf;
            apr_status_t status;

            if (!*sconf->crypto) {
                jose->result.msg = "token could not be signed";
                jose->result.reason = "no crypto driver configured (set AuthtJwtDriver)";
                return APR_EGENERAL;
            }

            krec = apr_crypto_key_rec_make(APR_CRYPTO_KTYPE_HMAC, pool);

            krec->k.hmac.digest = APR_CRYPTO_DIGEST_SHA256;
            krec->k.hmac.secret = srec->secret;
            krec->k.hmac.secretLen = srec->secret_len;

            status = apr_crypto_key(&key, krec, *sconf->crypto, pool);
            if (status != APR_SUCCESS) {
                jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                apr_strerror(status, buf, HUGE_STRING_LEN);
                jose->result.msg = "token could not be signed";
                return status;
            }

            rec = apr_crypto_digest_rec_make(APR_CRYPTO_DTYPE_SIGN, pool);

            status = apr_crypto_digest_init(&digest, key, rec, pool);
            if (status != APR_SUCCESS) {
                jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                apr_strerror(status, buf, HUGE_STRING_LEN);
                jose->result.msg = "token could not be signed";
                return status;
            }

            for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e =
                    APR_BUCKET_NEXT(e)) {
                const char *str;
                apr_size_t len;

                /* If we see an EOS, don't bother doing anything more. */
                if (APR_BUCKET_IS_EOS(e)) {
                    break;
                }

                status = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
                if (status != APR_SUCCESS) {
                    jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                    apr_strerror(status, buf, HUGE_STRING_LEN);
                    jose->result.msg = "token could not be signed";
                    return status;
                }

                status = apr_crypto_digest_update(digest,
                        (const unsigned char *) str, len);
                if (status != APR_SUCCESS) {
                    jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                    apr_strerror(status, buf, HUGE_STRING_LEN);
                    jose->result.msg = "token could not be signed";
                    return status;
                }
            }

            status = apr_crypto_digest_final(digest);
            if (status != APR_SUCCESS) {
                jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                apr_strerror(status, buf, HUGE_STRING_LEN);
                jose->result.msg = "token could not be signed";
                return status;
            }

            signature->sig.data = rec->d.sign.s;
            signature->sig.len = rec->d.sign.slen;

            return APR_SUCCESS;
        }
        }
    }
    else {
        /* algorithm is none */
        return APR_SUCCESS;
    }

    return APR_ENOTIMPL;
}

/* If we have set claims to be made, create a JWT token.
 */
static const char *jwt_get_token(request_rec *r)
{
    claim_iter_t iter = { 0 };
    apr_json_value_t *claims;
    apr_json_value_t *protect;
    apr_jose_t jwt = { 0 };
    apr_jose_t jws = { 0 };
    apr_jose_signature_t signature = { 0 };
    auth_bearer_signature_rec *srec = NULL;
    apr_bucket_brigade *bb;
    char *auth_line;
    apr_size_t len;
    apr_off_t offset;
    apr_status_t status;

    auth_bearer_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &autht_jwt_module);

    apr_jose_cb_t cb = { 0 };

    cb.sign = sign_cb;
    cb.ctx = r;

    if (!conf->claims || !apr_hash_count(conf->claims)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r,
                APLOGNO(10440) "AuthtJwtClaim: could not encode a JWT token for URI '%s': no claims",
                r->uri);
        return "error:no-claims";
    }

    /* sign with the first key, if present */
    if (conf->signs_set) {
        srec = (auth_bearer_signature_rec *)conf->signs->elts;
    }

    /* create a JWT containing the claims */
    claims = apr_json_object_create(r->pool);
    iter.object = claims;
    iter.r = r;

    /* iterate through our claims */
    if (!apr_hash_do(claim_iter, &iter, conf->claims)) {
        return "error:claim-failed";
    }

    apr_jose_jwt_make(&jwt, claims, r->pool);
    protect = apr_json_object_create(r->pool);

    apr_json_object_set(protect, APR_JOSE_JWSE_TYPE,
            APR_JSON_VALUE_STRING,
            apr_json_string_create(r->pool, APR_JOSE_JWSE_TYPE_JWT,
                    APR_JSON_VALUE_STRING), r->pool);

    if (srec) {
        /* which signature type do we have? */
        switch (srec->jws_alg) {
        case JWS_ALG_TYPE_NONE: {
            apr_json_object_set(protect, APR_JOSE_JWKSE_ALGORITHM,
                    APR_JSON_VALUE_STRING,
                    apr_json_string_create(r->pool, APR_JOSE_JWA_NONE,
                            APR_JSON_VALUE_STRING), r->pool);

            break;
        }
        case JWS_ALG_TYPE_HS256: {
            apr_json_object_set(protect, APR_JOSE_JWKSE_ALGORITHM,
                    APR_JSON_VALUE_STRING,
                    apr_json_string_create(r->pool, APR_JOSE_JWA_HS256,
                            APR_JSON_VALUE_STRING), r->pool);

            break;
        }
        }

    }
    else {
        /* no srec defaults to none */
        apr_json_object_set(protect, APR_JOSE_JWKSE_ALGORITHM,
                APR_JSON_VALUE_STRING,
                apr_json_string_create(r->pool, APR_JOSE_JWA_NONE,
                        APR_JSON_VALUE_STRING), r->pool);
    }

    apr_jose_signature_make(&signature, NULL, protect, r->pool);
    apr_jose_jws_make(&jws, &signature, NULL, &jwt, r->pool);

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);

    status = apr_jose_encode(bb, NULL, NULL, &jws, &cb, r->pool);
    if (APR_SUCCESS != status) {
        const apu_err_t *err = apr_jose_error(&jws);
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                APLOGNO(10441) "AuthtJwtClaim: could not encode a JWT token for URI '%s': %s: %s",
                r->uri, err->msg, err->reason);
        return "error:could-not-encode";
    }

    apr_brigade_length(bb, 1, &offset);
    auth_line = apr_pcalloc(r->pool, offset + 1);
    len = offset;
    apr_brigade_flatten(bb, auth_line, &len);
    auth_line[offset] = 0;

    return auth_line;
}

static const char *jwt_expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
{
    char *var = (char *)data;

    if (var && *var && ctx->r && ap_cstr_casecmp(var, "TOKEN") == 0) {
        return jwt_get_token(ctx->r);
    }
    return NULL;
}

static int jwt_expr_lookup(ap_expr_lookup_parms *parms)
{
    switch (parms->type) {
    case AP_EXPR_FUNC_VAR:
        /* for now, we just handle everything that starts with JWT_.
         */
        if (strncasecmp(parms->name, "JWT_", 4) == 0) {
            *parms->func = jwt_expr_var_fn;
            *parms->data = parms->name + 4;
            return OK;
        }
        break;
    }
    return DECLINED;
}

static apr_status_t verify_cb(apr_bucket_brigade *bb,
        apr_jose_t *jose, apr_jose_signature_t *signature, void *ctx,
        int *vflags, apr_pool_t *pool)
{
    request_rec *r = ctx;
    apr_json_kv_t *alg = NULL;

    auth_bearer_conf *sconf = ap_get_module_config(r->server->module_config,
            &autht_jwt_module);

    auth_bearer_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &autht_jwt_module);

    int alg_supported = 0;

    if (signature) {
        apr_json_value_t *ph = signature->protected_header;

        if (ph && ph->type == APR_JSON_OBJECT) {

            alg = apr_json_object_get(ph, APR_JOSE_JWKSE_ALGORITHM,
                    APR_JSON_VALUE_STRING);

        }
    }

    if (!alg) {
        apr_errprintf(&jose->result, r->pool, "", APR_EGENERAL,
                "JWT token protected header has no '"
                APR_JOSE_JWKSE_ALGORITHM
                "' for URI '%s'",
                r->uri);
        return APR_EGENERAL;
    }

    if (alg->v->type != APR_JSON_STRING) {
        apr_errprintf(&jose->result, r->pool, "", APR_EGENERAL,
                "JWT token protected header '"
                APR_JOSE_JWKSE_ALGORITHM
                "' is not a string for URI '%s'",
                r->uri);
        return APR_EGENERAL;
    }

    /* first pass, is our algorithm supported? */
    for (int i = 0; i < conf->verifies->nelts; i++) {
    	auth_bearer_signature_rec *srec = &APR_ARRAY_IDX(conf->verifies,
    			i, auth_bearer_signature_rec);

    	/* which signature type do we have? */
    	switch (srec->jws_alg) {
    	case JWS_ALG_TYPE_NONE: {
        	if (!strncmp(alg->v->value.string.p, "none",
                        alg->v->value.string.len)) {
        		alg_supported = 1;
        	}
        	break;
    	}
    	case JWS_ALG_TYPE_HS256: {
        	if (!strncmp(alg->v->value.string.p, "HS256",
        			alg->v->value.string.len)) {
        		alg_supported = 1;
        	}
    		break;
    	}
    	}

    }

    /* we don't support the algorithm */
    if (!alg_supported) {
    	apr_errprintf(&jose->result, r->pool, "", APR_ENODIGEST,
    			"JWT token protected header '"
    			APR_JOSE_JWKSE_ALGORITHM
				"' %s is not supported for URI '%s'",
				alg->v->value.string.p, r->uri);
    	return APR_ENODIGEST;
    }

    /* second pass, does the signature match? */
    for (int i = 0; i < conf->verifies->nelts; i++) {
    	auth_bearer_signature_rec *srec = &APR_ARRAY_IDX(conf->verifies,
    			i, auth_bearer_signature_rec);

    	/* which signature type do we have? */
    	switch (srec->jws_alg) {
    	case JWS_ALG_TYPE_NONE: {
        	if (!strncmp(alg->v->value.string.p, "none",
                        alg->v->value.string.len)) {
        		return APR_SUCCESS;
        	}
        	break;
    	}
    	case JWS_ALG_TYPE_HS256: {
        	if (!strncmp(alg->v->value.string.p, "HS256",
        			alg->v->value.string.len)) {

                apr_bucket *e;
                apr_crypto_key_rec_t *krec;
                apr_crypto_key_t *key = NULL;
                apr_crypto_digest_t *digest = NULL;
                apr_crypto_digest_rec_t *rec;
                char * buf;
                apr_status_t status;

                if (!*sconf->crypto) {
                    jose->result.msg = "token could not be verified";
                    jose->result.reason = "no crypto driver configured (set AuthtJwtDriver)";
                    return APR_EGENERAL;
                }

                krec = apr_crypto_key_rec_make(APR_CRYPTO_KTYPE_HMAC, pool);

                krec->k.hmac.digest = APR_CRYPTO_DIGEST_SHA256;
                krec->k.hmac.secret = srec->secret;
                krec->k.hmac.secretLen = srec->secret_len;

                status = apr_crypto_key(&key, krec, *sconf->crypto, pool);
                if (status != APR_SUCCESS) {
                    jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                    apr_strerror(status, buf, HUGE_STRING_LEN);
                    jose->result.msg = "token could not be verified";
                    return status;
                }

                rec = apr_crypto_digest_rec_make(APR_CRYPTO_DTYPE_SIGN, pool);

                status = apr_crypto_digest_init(&digest, key, rec, pool);
                if (status != APR_SUCCESS) {
                    jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                    apr_strerror(status, buf, HUGE_STRING_LEN);
                    jose->result.msg = "token could not be verified";
                    return status;
                }

                for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e =
                        APR_BUCKET_NEXT(e)) {
                    const char *str;
                    apr_size_t len;

                    /* If we see an EOS, don't bother doing anything more. */
                    if (APR_BUCKET_IS_EOS(e)) {
                        break;
                    }

                    status = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
                    if (status != APR_SUCCESS) {
                        jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                        apr_strerror(status, buf, HUGE_STRING_LEN);
                        jose->result.msg = "token could not be verified";
                        return status;
                    }

                    status = apr_crypto_digest_update(digest,
                            (const unsigned char *) str, len);
                    if (status != APR_SUCCESS) {
                        jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                        apr_strerror(status, buf, HUGE_STRING_LEN);
                        jose->result.msg = "token could not be verified";
                        return status;
                    }
                }

                status = apr_crypto_digest_final(digest);
                if (status != APR_SUCCESS) {
                    jose->result.reason = buf = apr_pcalloc(pool, HUGE_STRING_LEN);
                    apr_strerror(status, buf, HUGE_STRING_LEN);
                    jose->result.msg = "token could not be verified";
                    return status;
                }

                if (signature->sig.len == rec->d.sign.slen &&
                		!memcmp(signature->sig.data, rec->d.sign.s, rec->d.sign.slen)) {
                    return APR_SUCCESS;
                }

        	}
    		break;
    	}
    	}

    }

    /* no match, oh well */
	apr_errprintf(&jose->result, r->pool, "", APR_ENODIGEST,
			"JWT token protected header '"
			APR_JOSE_JWKSE_ALGORITHM
			"' %s is not supported for URI '%s'",
			alg->v->value.string.p, r->uri);
    return APR_ENOVERIFY;
}

static autht_status check_token(request_rec *r, const char *type,
                                   const char *token)
{
    apr_bucket_brigade *bb;
    apr_jose_t *jose = NULL;
    apr_json_kv_t *kv;
    apr_status_t status;

    apr_jose_cb_t cb;

    apr_table_t *e = r->subprocess_env;

    const char *aud = NULL;
    const char *sub = NULL;

    apr_int64_t exp;
    apr_int64_t nbf;

    int exp_set = 0;
    int nbf_set = 0;

    cb.verify = verify_cb;
    cb.decrypt = NULL;
    cb.ctx = r;

    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);

    if (token) {
        apr_brigade_write(bb, NULL, NULL, token, strlen(token));
    }

    status = apr_jose_decode(&jose, "JWT", bb, &cb, 10, APR_JOSE_FLAG_NONE, r->pool);

    if (APR_SUCCESS != status) {
        const apu_err_t *err = apr_jose_error(jose);
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                APLOGNO(10442) "AuthtJwt: could not decode a JWT token for URI '%s': %s: %s",
                r->uri, err->msg, err->reason);
        return AUTHT_DENIED;
    }

    if (jose->type != APR_JOSE_TYPE_JWT) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                APLOGNO(10443) "AuthtJwt: JOSE token was not a JWT token for URI '%s'",
                r->uri);
        return AUTHT_DENIED;
    }

    /* first pass - identity sub and aud */
    kv = apr_json_object_first(jose->jose.jwt->claims);
    do {

        /* ignore any key that isn't a string */
        if (kv->k->type != APR_JSON_STRING) {
            continue;
        }

        if (!strncmp("aud", kv->k->value.string.p, kv->k->value.string.len)) {
            if (kv->v->type == APR_JSON_STRING) {
                aud = apr_pstrndup(r->pool, kv->v->value.string.p,
                        kv->v->value.string.len);
            }
        }

        if (!strncmp("sub", kv->k->value.string.p, kv->k->value.string.len)) {
            if (kv->v->type == APR_JSON_STRING) {
                sub = apr_pstrndup(r->pool, kv->v->value.string.p,
                        kv->v->value.string.len);
            }
        }

        if (!strncmp("exp", kv->k->value.string.p, kv->k->value.string.len)) {
            if (kv->v->type == APR_JSON_LONG) {
                exp = kv->v->value.lnumber;
                exp_set = 1;
            }
        }

        if (!strncmp("nbf", kv->k->value.string.p, kv->k->value.string.len)) {
            if (kv->v->type == APR_JSON_LONG) {
                nbf = kv->v->value.lnumber;
                nbf_set = 1;
            }
        }


    } while ((kv = apr_json_object_next(jose->jose.jwt->claims, kv)));

    if (!aud) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                APLOGNO(10444) "AuthtJwt: JWT token 'aud' value was missing and did not match AuthName '%s' for URI '%s'",
                ap_auth_name(r), r->uri);
        return AUTHT_MISMATCH;
    }

    if (strcmp(aud, ap_auth_name(r))) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                APLOGNO(10445) "AuthtJwt: JWT token 'aud' value '%s' did not match AuthName '%s' for URI '%s'",
                aud, ap_auth_name(r), r->uri);
        return AUTHT_MISMATCH;
    }

    if (exp_set || nbf_set) {
        apr_time_t now = apr_time_now();

        if (exp_set &&
                exp < apr_time_sec(now)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                    APLOGNO(10446) "AuthtJwt: JWT token is expired (%"
                    APR_INT64_T_FMT " < %" APR_TIME_T_FMT ") for URI '%s'",
                    exp, apr_time_sec(now), r->uri);
            return AUTHT_EXPIRED;
        }

        if (nbf_set &&
                nbf > apr_time_sec(now)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
                    APLOGNO(10447) "AuthtJwt: JWT token is not yet valid (%"
                    APR_INT64_T_FMT " > %" APR_TIME_T_FMT ") for URI '%s'",
                    nbf, apr_time_sec(now), r->uri);
            return AUTHT_INVALID;
        }
    }

    /* we are good at this point - accept the token */

    if (sub) {
        r->user = apr_pstrdup(r->pool, sub);
    }

    /* second pass - add all string claims to the environment, prefixed by TOKEN_ */
    kv = apr_json_object_first(jose->jose.jwt->claims);
    do {
        char *key, *val;
        int j;

        /* ignore anything that isn't a string */
        if (kv->k->type != APR_JSON_STRING || kv->v->type != APR_JSON_STRING) {
            continue;
        }

        key = apr_psprintf(r->pool, AUTHT_PREFIX "%.*s", (int)kv->k->value.string.len, kv->k->value.string.p);
        j = sizeof(AUTHT_PREFIX);
        while (key[j]) {
            if (apr_isalnum(key[j])) {
                key[j] = apr_toupper(key[j]);
            }
            else {
                key[j] = '_';
            }
            j++;
        }

        val = apr_pstrndup(r->pool, kv->v->value.string.p,
                kv->v->value.string.len);

        apr_table_setn(e, key, val);

    } while ((kv = apr_json_object_next(jose->jose.jwt->claims, kv)));

    return AUTHT_GRANTED;
}

static const autht_provider autht_jwt_provider =
{
    &check_token
};

static void register_hooks(apr_pool_t *p)
{
    ap_register_auth_provider(p, AUTHT_PROVIDER_GROUP, "jwt",
                              AUTHT_PROVIDER_VERSION,
                              &autht_jwt_provider, AP_AUTH_INTERNAL_PER_CONF);
    ap_hook_expr_lookup(jwt_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(auth_bearer_init, NULL, NULL, APR_HOOK_LAST);
}

AP_DECLARE_MODULE(autht_jwt) =
{
    STANDARD20_MODULE_STUFF,
    create_auth_bearer_dir_config,  /* dir config creater */
    merge_auth_bearer_dir_config,   /* dir merger --- default is to override */
    create_auth_bearer_config,      /* server config */
    merge_auth_bearer_config,       /* merge server config */
    auth_bearer_cmds,               /* command apr_table_t */
    register_hooks                  /* register hooks */
};

#else

static const command_rec auth_bearer_cmds[] =
{
    {NULL}
};

static void register_hooks(apr_pool_t *p)
{
}

AP_DECLARE_MODULE(autht_jwt) =
{
    STANDARD20_MODULE_STUFF,
    NULL,                           /* dir config creater */
    NULL,                           /* dir merger --- default is to override */
    NULL,                           /* server config */
    NULL,                           /* merge server config */
    auth_bearer_cmds,               /* command apr_table_t */
    register_hooks                  /* register hooks */
};

#endif /* HAVE_APU_JOSE */

