/* 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.
 */

/*
 * mod_crypto.c --- Encrypt / decrypt data in the input and output filter
 *                  stacks.
 */

#include "mod_crypto.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_crypto.h"
#include "apr_base64.h"
#include "apr_escape.h"
#include "apr_version.h"
#if !APR_VERSION_AT_LEAST(2,0,0)
#include "apu_version.h"
#endif
#include "util_filter.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"
#include "ap_expr.h"

#if APR_VERSION_AT_LEAST(2,0,0) || \
    (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)

APR_HOOK_STRUCT(APR_HOOK_LINK(crypto_key)
                APR_HOOK_LINK(crypto_iv))
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, CRYPTO, apr_status_t, crypto_key,
                                      (request_rec *r,
                                      apr_crypto_block_key_type_t * cipher,
                                      apr_crypto_block_key_mode_t * mode,
                                      int pad,
                                      const apr_crypto_key_rec_t ** rec),
                                      (r, cipher, mode, pad, rec), DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, CRYPTO, apr_status_t, crypto_iv,
                                      (request_rec *r,
                                      apr_crypto_block_key_type_t * cipher,
                                      const unsigned char **iv), (r, cipher,
                                      iv), DECLINED)
module AP_MODULE_DECLARE_DATA crypto_module;

#define DEFAULT_BUFFER_SIZE 128*1024
#define DEFAULT_CIPHER "aes256"
#define DEFAULT_MODE "cbc"
#define CRYPTO_KEY "crypto_context"

typedef struct pass_conf
{
    const char *scheme;
    const ap_expr_info_t *expr;
    unsigned char *raw;
    apr_size_t size;
} pass_conf;

/**
 * Structure to carry the server wide session config.
 */
typedef struct
{
    const char *library;
    const char *params;
    apr_crypto_t **crypto;
    int library_set;
} crypto_conf;

typedef struct crypto_dir_conf
{
    apr_off_t size;        /* size of the buffer */
    int size_set;          /* has the size been set */
    const char *cipher;
    const char *mode;
    int cipher_set;
    pass_conf *key;
    int key_set;
    pass_conf *iv;
    int iv_set;
} crypto_dir_conf;

typedef struct crypto_ctx
{
    apr_bucket_brigade *bb;
    apr_bucket_brigade *tmp;
    crypto_dir_conf *conf;
    unsigned char *out;
    apr_crypto_key_t *key;
    apr_crypto_block_key_type_t *cipher;
    apr_crypto_block_key_mode_t *mode;
    apr_crypto_block_t *block;
    const unsigned char *iv;
    apr_off_t remaining;
    apr_off_t written;
    apr_size_t osize;
    int seen_eos:1;
    int encrypt:1;
    int clength:1;
} crypto_ctx;

static const char *parse_pass_conf_binary(cmd_parms *cmd,
                                          pass_conf * pass,
                                          const char *arg)
{
    apr_status_t rv;
    char ps = *arg;

    if ('f' == ps && !strncmp(arg, "file:", 5)) {
        arg += 5;

        if (!*arg) {
            return apr_pstrcat(cmd->pool, "No filename specified", NULL);
        }

        const char *name = ap_server_root_relative(cmd->temp_pool, arg);
        if (name) {
            apr_file_t *file;

            rv = apr_file_open(&file, name, APR_FOPEN_READ,
                               APR_FPROT_OS_DEFAULT, cmd->temp_pool);
            if (APR_SUCCESS == rv) {
                apr_finfo_t finfo;

                rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, file);
                if (rv == APR_SUCCESS) {
                    apr_size_t size;

                    pass->scheme = "file";
                    pass->raw = apr_palloc(cmd->pool, finfo.size);
                    pass->size = finfo.size;
                    apr_crypto_clear(cmd->pool, pass->raw, pass->size);

                    rv = apr_file_read_full(file, pass->raw, pass->size,
                                            &size);
                    if (APR_SUCCESS == rv && size != pass->size) {
                        rv = APR_EGENERAL;
                    }

                }
            }
            if (APR_SUCCESS != rv) {
                char buf[120];
                return apr_pstrcat(cmd->pool, "Unable to load from file '",
                                   arg, "': ", apr_strerror(rv, buf,
                                                            sizeof(buf)),
                                   NULL);
            }
        }
        else {
            return apr_pstrcat(cmd->pool, "Unable to locate file from name ",
                               arg, NULL);
        }
    }

    else if ('h' == ps && (!strncmp(arg, "hex:", 4))) {
        const char *expr_err = NULL;
        arg += 4;

        if (!*arg) {
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression, it is blank", NULL);
        }

        pass->scheme = "hex";
        pass->expr = ap_expr_parse_cmd(cmd, arg, AP_EXPR_FLAG_STRING_RESULT,
                                       &expr_err, NULL);

        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool, "Cannot parse ", pass->scheme,
                               " expression '", arg, "' in: ", expr_err,
                               NULL);
        }

    }

    else if ('b' == ps && !strncmp(arg, "base64:", 7)) {
        const char *expr_err = NULL;
        arg += 7;

        if (!*arg) {
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression, it is blank", NULL);
        }

        pass->scheme = "base64";
        pass->expr = ap_expr_parse_cmd(cmd, arg, AP_EXPR_FLAG_STRING_RESULT,
                                       &expr_err, NULL);

        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool, "Cannot parse ", pass->scheme,
                               " expression '", arg, "' in: ", expr_err,
                               NULL);
        }

    }

    else if ('d' == ps && !strncmp(arg, "decimal:", 8)) {
        const char *expr_err = NULL;
        arg += 8;

        if (!*arg) {
            return apr_pstrcat(cmd->temp_pool,
                               "Cannot parse expression, it is blank", NULL);
        }

        pass->scheme = "decimal";
        pass->expr = ap_expr_parse_cmd(cmd, arg, AP_EXPR_FLAG_STRING_RESULT,
                                       &expr_err, NULL);

        if (expr_err) {
            return apr_pstrcat(cmd->temp_pool, "Cannot parse ", pass->scheme,
                               " expression '", arg, "' in: ", expr_err,
                               NULL);
        }

    }

    else if ('n' == ps && !strcmp(arg, "none")) {
        pass->scheme = arg;
    }

    else {
        return apr_pstrcat(cmd->pool,
                           "Scheme must be 'file:', 'hex:', 'base64:', 'decimal:' or 'none': ",
                           arg, NULL);
    }

    return NULL;
}

static apr_status_t
exec_pass_conf_binary(request_rec *r, pass_conf * pass,
                      const char *description, apr_size_t size,
                      const unsigned char **k)
{

    if (pass) {

        if (pass->raw) {
            *k = pass->raw;

            if (size != pass->size) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r,
                              APLOGNO(03409) "%s has wrong size (was %"
                              APR_SIZE_T_FMT ", must be %" APR_SIZE_T_FMT ")",
                              description, pass->size, size);
                return APR_EGENERAL;
            }

            return APR_SUCCESS;
        }

        else if (pass->expr) {
            char ps = *pass->scheme;
            const char *err = NULL;

            const char *arg = ap_expr_str_exec(r, pass->expr, &err);
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r,
                              APLOGNO(03410) "%s could not be parsed: %s",
                              description, err);
                return APR_EGENERAL;
            }

            /* hex */
            if ('h' == ps) {
                apr_size_t len;
                unsigned char *b;

                apr_unescape_hex(NULL, arg, strlen(arg), 1, &len);
                if (len < size) {
                    b = apr_palloc(r->pool, size);
                    memset(b, 0, size - len);
                    apr_unescape_hex(b + size - len, arg, strlen(arg), 1,
                                     &len);
                }
                else {
                    b = apr_palloc(r->pool, len);
                    apr_unescape_hex(b, arg, strlen(arg), 1, NULL);
                    b += len - size;
                }
                *k = b;

            }

            /* base64 */
            else if ('b' == ps) {
                apr_size_t len;
                unsigned char *b;

                len = apr_base64_decode_len(arg);
                if (len < size) {
                    b = apr_palloc(r->pool, size);
                    memset(b, 0, size - len);
                    apr_base64_decode_binary(b + size - len, arg);
                }
                else {
                    b = apr_palloc(r->pool, len);
                    apr_base64_decode_binary(b, arg);
                    b += len - size;
                }
                *k = b;

            }

            /* decimal */
            else if ('d' == ps) {
                apr_size_t len;
                unsigned char *b;
                char n[8];
                apr_uint64_t t;
                int i;

                t = (apr_uint64_t) apr_atoi64(arg);

                for (i = 7; i >= 0; i--) {
                    n[i] = t & 0xFF;
                    t = t >> 8;
                }

                len = sizeof(n);
                if (len < size) {
                    b = apr_palloc(r->pool, size);
                    memset(b, 0, size - len);
                    memcpy(b + size - len, n, len);
                }
                else {
                    b = apr_palloc(r->pool, len);
                    memcpy(b, n, len);
                    b += len - size;
                }
                *k = b;

            }

        }

    }

    return DECLINED;
}

static apr_status_t
init_cipher(request_rec *r,
            apr_crypto_block_key_type_t ** cipher,
            apr_crypto_block_key_mode_t ** mode)
{
    apr_status_t rv;
    apr_hash_t *ciphers;
    apr_hash_t *modes;

    crypto_conf *conf = ap_get_module_config(r->server->module_config,
                                             &crypto_module);
    crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                  &crypto_module);

    if (cipher) {

        rv = apr_crypto_get_block_key_types(&ciphers, *conf->crypto);
        if (APR_SUCCESS != rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03411) "no ciphers returned by APR");
            return rv;
        }

        *cipher = apr_hash_get(ciphers, dconf->cipher, APR_HASH_KEY_STRING);
        if (!*cipher) {
            apr_hash_index_t *hi;
            const void *key;
            apr_ssize_t klen;
            int sum = 0;
            int offset = 0;
            char *options = NULL;

            for (hi = apr_hash_first(r->pool, ciphers); hi;
                 hi = apr_hash_next(hi)) {
                apr_hash_this(hi, NULL, &klen, NULL);
                sum += klen + 2;
            }
            for (hi = apr_hash_first(r->pool, ciphers); hi;
                 hi = apr_hash_next(hi)) {
                apr_hash_this(hi, &key, &klen, NULL);
                if (!options) {
                    options = apr_palloc(r->pool, sum + 1);
                }
                else {
                    options[offset++] = ',';
                    options[offset++] = ' ';
                }
                strncpy(options + offset, key, klen);
                offset += klen;
            }
            options[offset] = 0;

            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03428) "cipher '%s' not recognised by crypto driver. "
                          "Options: %s", dconf->cipher, options);

            return rv;
        }

    }

    if (mode) {

        rv = apr_crypto_get_block_key_modes(&modes, *conf->crypto);
        if (APR_SUCCESS != rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03412) "no cipher modes returned by APR");
            return rv;
        }

        *mode = apr_hash_get(modes, dconf->mode, APR_HASH_KEY_STRING);
        if (!*mode) {
            apr_hash_index_t *hi;
            const void *key;
            apr_ssize_t klen;
            int sum = 0;
            int offset = 0;
            char *options = NULL;

            for (hi = apr_hash_first(r->pool, modes); hi;
                 hi = apr_hash_next(hi)) {
                apr_hash_this(hi, NULL, &klen, NULL);
                sum += klen + 2;
            }
            for (hi = apr_hash_first(r->pool, modes); hi;
                 hi = apr_hash_next(hi)) {
                apr_hash_this(hi, &key, &klen, NULL);
                if (!options) {
                    options = apr_palloc(r->pool, sum + 1);
                }
                else {
                    options[offset++] = ',';
                    options[offset++] = ' ';
                }
                strncpy(options + offset, key, klen);
                offset += klen;
            }
            options[offset] = 0;

            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03429) "cipher mode '%s' not recognised by crypto driver. "
                          "Options: %s", dconf->mode, options);

            return rv;
        }

    }

    return APR_SUCCESS;
}

static apr_status_t init_crypt(ap_filter_t * f)
{
    apr_status_t rv;
    crypto_ctx *ctx = f->ctx;
    const apr_crypto_key_rec_t *rec;

    crypto_conf *conf = ap_get_module_config(f->r->server->module_config,
                                             &crypto_module);
    crypto_dir_conf *dconf =
        ap_get_module_config(f->r->per_dir_config, &crypto_module);

    /* sanity check - has crypto been switched on? */
    if (!conf->crypto || !*conf->crypto) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, f->r,
                      APLOGNO(03430) "crypto driver has not been enabled for this server");
        return APR_EGENERAL;
    }

    /* initial setup of the context */
    ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    ctx->conf = dconf;
    ctx->remaining = ctx->conf->size;
    ctx->written = 0;
    ctx->osize = ctx->conf->size;

    /* fetch the cipher for this location */
    rv = init_cipher(f->r, &ctx->cipher, &ctx->mode);
    if (APR_SUCCESS != rv) {
        return rv;
    }

    /* sanity check - buffer size multiple of block size? */
    if (ctx->conf->size % ctx->cipher->blocksize) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, f->r,
                      APLOGNO(03413) "Buffer size %" APR_OFF_T_FMT
                      " is not a multiple of the block size %d of cipher '%s'",
                      ctx->conf->size, ctx->cipher->blocksize, dconf->cipher);
        return APR_EGENERAL;
    }

    /* fetch the key we'll be using for decryption */
    rv = ap_run_crypto_key(f->r, ctx->cipher, ctx->mode, 1, &rec);
    if (DECLINED == rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
                      APLOGNO(03414) "no key specified for this URL");
        return APR_ENOKEY;
    }
    if (APR_SUCCESS != rv || !rec) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03415) "key could not be retrieved");
        return APR_ENOKEY;
    }
    if (rec->ktype != APR_CRYPTO_KTYPE_SECRET) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03416) "key is not a symmetrical key");
        return APR_ENOKEY;
    }

    /* attempt to import the key */
    rv = apr_crypto_key(&ctx->key, rec, *conf->crypto, f->r->pool);
    if (APR_STATUS_IS_ENOKEY(rv)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03417) "key could not be loaded");
    }
    if (APR_STATUS_IS_EPADDING(rv)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03418) "padding is not supported for cipher");
    }
    if (APR_STATUS_IS_EKEYTYPE(rv)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03419) "the key type is not known");
    }
    if (APR_SUCCESS != rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03420) "encryption could not be configured.");
        return rv;
    }

    /* fetch the optional iv */
    rv = ap_run_crypto_iv(f->r, ctx->cipher, &ctx->iv);
    if (DECLINED != rv && APR_SUCCESS != rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                      APLOGNO(03431) "initialisation vector could not be retrieved");
        return rv;
    }

    return APR_SUCCESS;
}

static int init_encrypt(ap_filter_t * f)
{
    apr_status_t rv;
    crypto_ctx *ctx;

    ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
    ctx->encrypt = 1;

    rv = init_crypt(f);
    if (APR_SUCCESS != rv) {
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    return OK;
}

static int init_decrypt(ap_filter_t * f)
{
    apr_status_t rv;
    crypto_ctx *ctx;

    ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
    ctx->encrypt = 0;

    rv = init_crypt(f);
    if (APR_SUCCESS != rv) {
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    return OK;
}

/**
 * Run the crypto algorithm, write to ctx->out
 */
static apr_status_t
do_crypto(ap_filter_t * f, unsigned char *in, apr_off_t size, int finish)
{
    apr_status_t rv;
    crypto_ctx *ctx = f->ctx;
    apr_off_t extra = 0;
    apr_size_t blockSize = 0;
    int need_iv = (ctx->iv == NULL);
    unsigned char *out;
    apr_size_t written;

    /* encrypt the given buffer */
    if (ctx->encrypt) {

        if (!ctx->block) {
            rv = apr_crypto_block_encrypt_init(&ctx->block, &ctx->iv,
                                               ctx->key, &blockSize,
                                               f->r->pool);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03421) "could not initialise encryption");
                return rv;
            }
        }

        if (!ctx->out) {

            if (need_iv && ctx->iv) {
                ctx->osize += blockSize;
            }

            out = ctx->out = apr_palloc(f->r->pool,
                                        ctx->osize + ctx->cipher->blocksize);
            apr_crypto_clear(f->r->pool, ctx->out,
                             ctx->osize + ctx->cipher->blocksize);

            /* no precomputed iv? write the generated iv as the first block of the stream */
            if (need_iv && ctx->iv) {
                memcpy(out, ctx->iv, blockSize);
                ctx->remaining += blockSize;
                out += blockSize;
                extra = blockSize;
            }

        }
        else {
            out = ctx->out + (ctx->osize - ctx->remaining);
        }

        if (!finish) {
            rv = apr_crypto_block_encrypt(&out, &written, in, size,
                                          ctx->block);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03422) "crypto: attempt to encrypt failed");
                return rv;
            }
        }

        else {
            rv = apr_crypto_block_encrypt_finish(out, &written, ctx->block);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03432) "crypto: attempt to finish encrypt failed");
                return rv;
            }
        }
    }

    /* decrypt the given buffer */
    else {

        if (!ctx->out) {
            out = ctx->out = apr_palloc(f->r->pool,
                                        ctx->osize + ctx->cipher->blocksize);
            apr_crypto_clear(f->r->pool, ctx->out,
                             ctx->osize + ctx->cipher->blocksize);
        }
        else {
            out = ctx->out + (ctx->osize - ctx->remaining);
        }

        /* no precomputed iv? assume the first block in the stream is the iv */
        if (need_iv) {
            apr_off_t isize =
                ctx->cipher->blocksize - (ctx->osize - ctx->remaining);
            if (size < isize) {
                memcpy(out, in, size);
                ctx->remaining -= size;
                return APR_SUCCESS;
            }
            else {
                memcpy(out, in, isize);
                ctx->remaining -= isize;
                out += isize;
                ctx->iv = ctx->out;
            }
        }

        if (!ctx->block) {
            rv = apr_crypto_block_decrypt_init(&ctx->block, &blockSize,
                                               ctx->iv, ctx->key, f->r->pool);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03423) "could not initialise decryption");
                return rv;
            }
        }

        if (!finish) {
            rv = apr_crypto_block_decrypt(&out, &written, in, size,
                                          ctx->block);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03433) "crypto: attempt to decrypt failed (key/iv incorrect?)");
                return rv;
            }
        }
        else {
            rv = apr_crypto_block_decrypt_finish(out, &written, ctx->block);
            if (APR_SUCCESS != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
                              APLOGNO(03434) "crypto: attempt to finish decrypt failed (key/iv incorrect?)");
                return rv;
            }
        }
    }

    ctx->remaining -= written;
    ctx->written += written;
    ctx->written += extra;

    return rv;
}

/**
 * Encrypt/decrypt buckets being written to the output filter stack.
 */
static apr_status_t
crypto_out_filter(ap_filter_t * f, apr_bucket_brigade * bb)
{
    apr_bucket *e, *after;
    crypto_ctx *ctx = f->ctx;
    apr_status_t rv = APR_SUCCESS;

    /* Do nothing if asked to filter nothing. */
    if (APR_BRIGADE_EMPTY(bb)) {
        return ap_pass_brigade(f->next, bb);
    }

    /* clear the content length */
    if (!ctx->clength) {
        ctx->clength = 1;
        apr_table_unset(f->r->headers_out, "Content-Length");
    }

    /* make sure we fit in the buffer snugly */
    if (APR_BRIGADE_EMPTY(ctx->bb)) {
        apr_brigade_partition(bb, ctx->remaining, &after);
    }

    while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(bb)) {
        const char *data;
        apr_size_t size;

        e = APR_BRIGADE_FIRST(bb);

        /* EOS means we are done. */
        if (APR_BUCKET_IS_EOS(e)) {

            /* handle any leftovers */
            do_crypto(f, NULL, 0, 1);
            apr_brigade_write(ctx->bb, NULL, NULL, (const char *) ctx->out,
                              ctx->conf->size - ctx->remaining);
            ctx->remaining = ctx->osize;
            ctx->written = 0;
            apr_brigade_partition(bb, ctx->remaining, &after);

            /* pass the EOS across */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);

            /* pass what we have down the chain */
            rv = ap_pass_brigade(f->next, ctx->bb);

            ap_remove_output_filter(f);
            continue;
        }

        /* handle flush */
        if (APR_BUCKET_IS_FLUSH(e)) {

            /* we cannot change the laws of physics: crypto can only happen
             * on a block boundary. As a result, just pass the flush bucket
             * through as is, we'll send the rest of the block when it
             * arrives in full.
             */

            /* pass the flush bucket across */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);

            /* pass what we have down the chain */
            rv = ap_pass_brigade(f->next, ctx->bb);
            continue;
        }

        /* metadata buckets are preserved as is */
        if (APR_BUCKET_IS_METADATA(e)) {
            /*
             * Remove meta data bucket from old brigade and insert into the
             * new.
             */
            APR_BUCKET_REMOVE(e);
            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
            continue;
        }

        if (APR_SUCCESS
            == (rv = apr_bucket_read(e, &data, &size, APR_BLOCK_READ))) {

            do_crypto(f, (unsigned char *) data, size, 0);
            apr_bucket_delete(e);

            if (!ctx->remaining) {
                apr_brigade_write(ctx->bb, NULL, NULL,
                                  (const char *) ctx->out, ctx->written);
                ctx->remaining = ctx->osize;
                ctx->written = 0;
                apr_brigade_partition(bb, ctx->remaining, &after);
                rv = ap_pass_brigade(f->next, ctx->bb);
            }

        }

    }

    return rv;

}

/**
 * Decrypt/encrypt buckets being read from the input filter stack.
 */
static apr_status_t
crypto_in_filter(ap_filter_t * f, apr_bucket_brigade * bb,
                 ap_input_mode_t mode, apr_read_type_e block,
                 apr_off_t readbytes)
{
    apr_bucket *e, *after;
    apr_status_t rv = APR_SUCCESS;
    crypto_ctx *ctx = f->ctx;

    if (!ctx->tmp) {
        ctx->tmp = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
    }

    /* just get out of the way of things we don't want. */
    if (mode != AP_MODE_READBYTES) {
        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    }

    /* if our buffer is empty, read off the network until the buffer is full */
    if (APR_BRIGADE_EMPTY(ctx->bb)) {
        ctx->remaining = ctx->osize;
        ctx->written = 0;

        while (!ctx->seen_eos && ctx->remaining > 0) {
            const char *data;
            apr_size_t size = 0;

            if (APR_BRIGADE_EMPTY(ctx->tmp)) {
                rv = ap_get_brigade(f->next, ctx->tmp, mode, block,
                                    ctx->remaining);
            }

            /* if an error was received, bail out now. If the error is
             * EAGAIN and we have not yet seen an EOS, we will definitely
             * be called again, at which point we will send our buffered
             * data. Instead of sending EAGAIN, some filters return an
             * empty brigade instead when data is not yet available. In
             * this case, we drop through and pass buffered data, if any.
             */
            if (APR_STATUS_IS_EAGAIN(rv)
                || (rv == APR_SUCCESS
                    && block == APR_NONBLOCK_READ
                    && APR_BRIGADE_EMPTY(ctx->tmp))) {
                if (APR_BRIGADE_EMPTY(ctx->bb)) {
                    return rv;
                }
                break;
            }
            if (APR_SUCCESS != rv) {
                return rv;
            }

            while (!APR_BRIGADE_EMPTY(ctx->tmp)) {
                e = APR_BRIGADE_FIRST(ctx->tmp);

                /* if we see an EOS, we are done */
                if (APR_BUCKET_IS_EOS(e)) {

                    /* handle any leftovers */
                    do_crypto(f, NULL, 0, 1);
                    apr_brigade_write(ctx->bb, NULL, NULL,
                                      (const char *) ctx->out, ctx->written);

                    APR_BUCKET_REMOVE(e);
                    APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                    ctx->seen_eos = 1;
                    break;
                }

                /* flush buckets clear the buffer */
                if (APR_BUCKET_IS_FLUSH(e)) {
                    APR_BUCKET_REMOVE(e);
                    APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                    break;
                }

                /* pass metadata buckets through */
                if (APR_BUCKET_IS_METADATA(e)) {
                    APR_BUCKET_REMOVE(e);
                    APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
                    continue;
                }

                /* read the bucket in, pack it into the buffer */
                rv = apr_bucket_read(e, &data, &size, block);
                if (APR_STATUS_IS_EAGAIN(rv)) {
                    if (APR_BRIGADE_EMPTY(ctx->bb)) {
                        return rv;
                    }
                    break;
                }
                if (APR_SUCCESS != rv) {
                    return rv;
                }

                do_crypto(f, (unsigned char *) data, size, 0);
                if (!ctx->remaining || APR_STATUS_IS_EAGAIN(rv)) {
                    apr_brigade_write(ctx->bb, NULL, NULL,
                                      (const char *) ctx->out, ctx->written);
                }

                apr_bucket_delete(e);

            }
        }
    }

    /* give the caller the data they asked for from the buffer */
    apr_brigade_partition(ctx->bb, readbytes, &after);
    e = APR_BRIGADE_FIRST(ctx->bb);
    while (e != after) {
        if (APR_BUCKET_IS_EOS(e)) {
            /* last bucket read, step out of the way */
            ap_remove_input_filter(f);
        }
        APR_BUCKET_REMOVE(e);
        APR_BRIGADE_INSERT_TAIL(bb, e);
        e = APR_BRIGADE_FIRST(ctx->bb);
    }

    /* clear the content length */
    if (!ctx->clength) {
        ctx->clength = 1;
        apr_table_unset(f->r->headers_in, "Content-Length");
    }

    return APR_SUCCESS;
}

static int crypto_handler(request_rec *r)
{
    crypto_conf *conf;
    crypto_dir_conf *dconf;
    apr_status_t rv;

    if (*r->handler != 'c' || strcmp(r->handler, "crypto-key")) {
        return DECLINED;
    }

    conf = ap_get_module_config(r->server->module_config, &crypto_module);
    dconf = ap_get_module_config(r->per_dir_config, &crypto_module);

    /* sanity check - has crypto been switched on? */
    if (!conf->crypto || !*conf->crypto) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r,
                      APLOGNO(03435) "crypto driver has not been enabled for this server");
        return APR_EGENERAL;
    }

    if (dconf->key_set) {
        const apr_crypto_key_rec_t *rec;
        apr_crypto_block_key_type_t *cipher;
        apr_crypto_block_key_mode_t *mode;

        /* fetch the cipher for this location */
        rv = init_cipher(r, &cipher, &mode);
        if (APR_SUCCESS != rv) {
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        /* fetch the key we'll be using for encryption / decryption */
        rv = ap_run_crypto_key(r, cipher, mode, 1, &rec);
        if (DECLINED == rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          APLOGNO(03424) "no key specified for this URL");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (APR_SUCCESS != rv || !rec) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03425) "key could not be retrieved");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        if (rec->ktype != APR_CRYPTO_KTYPE_SECRET) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          APLOGNO(03426) "key is not a symmetrical key");
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        ap_set_content_type(r, "application/octet-stream");
        ap_set_content_length(r, rec->k.secret.secretLen);
        ap_rwrite(rec->k.secret.secret, rec->k.secret.secretLen, r);

        return OK;

    }
    else {

        return HTTP_NOT_FOUND;

    }

}

static void *create_crypto_config(apr_pool_t * p, server_rec *s)
{
    crypto_conf *new = (crypto_conf *) apr_pcalloc(p, sizeof(crypto_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_crypto_config(apr_pool_t * p, void *basev, void *addv)
{
    crypto_conf *new = (crypto_conf *) apr_pcalloc(p, sizeof(crypto_conf));
    crypto_conf *add = (crypto_conf *) addv;
    crypto_conf *base = (crypto_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_crypto_dir_config(apr_pool_t * p, char *dummy)
{
    crypto_dir_conf *new =
        (crypto_dir_conf *) apr_pcalloc(p, sizeof(crypto_dir_conf));

    new->size = DEFAULT_BUFFER_SIZE;    /* default size */
    new->cipher = DEFAULT_CIPHER;
    new->mode = DEFAULT_MODE;

    return (void *) new;
}

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

    new->size = (add->size_set == 0) ? base->size : add->size;
    new->size_set = add->size_set || base->size_set;

    new->cipher = (add->cipher_set == 0) ? base->cipher : add->cipher;
    new->mode = (add->cipher_set == 0) ? base->mode : add->mode;
    new->cipher_set = add->cipher_set || base->cipher_set;

    new->key = (add->key_set == 0) ? base->key : add->key;
    new->key_set = add->key_set || base->key_set;

    new->iv = (add->iv_set == 0) ? base->iv : add->iv;
    new->iv_set = add->iv_set || base->iv_set;

    return new;
}

static const char *set_crypto_size(cmd_parms *cmd, void *dconf,
                                   const char *arg)
{
    crypto_dir_conf *conf = dconf;

    if (APR_SUCCESS != apr_strtoff(&(conf->size), arg, NULL, 10)
        || conf->size <= 0) {
        return "CryptoSize must be a size in bytes, and greater than zero";
    }
    conf->size_set = 1;

    return NULL;
}

static const char *set_crypto_driver(cmd_parms *cmd, void *config,
                                     const char *arg)
{
    crypto_conf *conf =
        (crypto_conf *) ap_get_module_config(cmd->server->module_config,
                                             &crypto_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->crypto = apr_pcalloc(cmd->pool, sizeof(apr_crypto_t *));
    conf->library_set = 1;

    return NULL;
}

static const char *set_crypto_cipher(cmd_parms *cmd, void *config,
                                     const char *cipher, const char *mode)
{
    crypto_dir_conf *dconf = (crypto_dir_conf *) config;

    dconf->cipher = cipher;
    dconf->mode = mode ? mode : DEFAULT_MODE;
    dconf->cipher_set = 1;

    return NULL;
}

static const char *set_crypto_key(cmd_parms *cmd, void *config,
                                  const char *arg)
{
    crypto_dir_conf *dconf = (crypto_dir_conf *) config;

    pass_conf *key = dconf->key = apr_pcalloc(cmd->pool, sizeof(pass_conf));
    dconf->key_set = 1;

    return parse_pass_conf_binary(cmd, key, arg);
}

static const char *set_crypto_iv(cmd_parms *cmd, void *config,
                                 const char *arg)
{
    crypto_dir_conf *dconf = (crypto_dir_conf *) config;

    pass_conf *iv = dconf->iv = apr_pcalloc(cmd->pool, sizeof(pass_conf));
    dconf->iv_set = 1;

    return parse_pass_conf_binary(cmd, iv, arg);
}

static const command_rec crypto_cmds[] = {
    AP_INIT_TAKE1("CryptoSize", set_crypto_size, NULL, ACCESS_CONF,
                  "Maximum size of the buffer used by the crypto filters"),
    AP_INIT_RAW_ARGS("CryptoDriver", set_crypto_driver, NULL, RSRC_CONF,
                     "The underlying crypto library driver to use"),
    AP_INIT_TAKE12("CryptoCipher", set_crypto_cipher, NULL,
                   RSRC_CONF | OR_AUTHCFG,
                   "The underlying crypto cipher and mode to use. If unspecified, the mode defaults to 'cbc'"),
    AP_INIT_TAKE1("CryptoKey", set_crypto_key, NULL, RSRC_CONF | OR_AUTHCFG,
                  "The crypto key scheme and value to use. Scheme is one of 'none', 'file:', 'hex:', 'base64:' or 'decimal:'"),
    AP_INIT_TAKE1("CryptoIV", set_crypto_iv, NULL, RSRC_CONF | OR_AUTHCFG,
                  "The crypto IV scheme and value to use. Scheme is one of 'none', 'file:', 'hex:', 'base64:' or 'decimal:'"),
    {NULL}
};

/**
 * Initialise the SSL in the post_config hook.
 */
static int
crypto_init(apr_pool_t * p, apr_pool_t * plog,
            apr_pool_t * ptemp, server_rec *s)
{
    const apr_crypto_driver_t *driver = NULL;

    while (s) {

        crypto_conf *conf = ap_get_module_config(s->module_config,
                                                 &crypto_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(03427) "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(03436) "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(03437) "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(03438) "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(03439) "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(03440) "The crypto library '%s' could not be initialised",
                             conf->library);
                return rv;
            }

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

        }
        s = s->next;
    }

    return OK;
}

static apr_status_t
crypto_key(request_rec *r,
           apr_crypto_block_key_type_t * cipher,
           apr_crypto_block_key_mode_t * mode, int pad,
           const apr_crypto_key_rec_t ** recptr)
{
    apr_crypto_key_rec_t *rec;

    crypto_dir_conf *conf =
        ap_get_module_config(r->per_dir_config, &crypto_module);

    pass_conf *key = conf->key;

    *recptr = rec = apr_palloc(r->pool, sizeof(apr_crypto_key_rec_t));
    rec->ktype = APR_CRYPTO_KTYPE_SECRET;
    rec->type = cipher->type;
    rec->mode = mode->mode;
    rec->pad = pad;
    rec->k.secret.secretLen = cipher->keysize;

    return exec_pass_conf_binary(r, key, "key", cipher->keysize,
                                 &(rec->k.secret.secret));
}

static apr_status_t
crypto_iv(request_rec *r,
          apr_crypto_block_key_type_t * cipher, const unsigned char **v)
{
    crypto_dir_conf *conf =
        ap_get_module_config(r->per_dir_config, &crypto_module);

    pass_conf *iv = conf->iv;

    return exec_pass_conf_binary(r, iv, "iv", cipher->ivsize, v);
}

static void register_hooks(apr_pool_t * p)
{
    ap_hook_crypto_key(crypto_key, NULL, NULL, APR_HOOK_REALLY_LAST);
    ap_hook_crypto_iv(crypto_iv, NULL, NULL, APR_HOOK_REALLY_LAST);
    ap_hook_post_config(crypto_init, NULL, NULL, APR_HOOK_LAST);
    ap_hook_handler(crypto_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_register_output_filter("ENCRYPT", crypto_out_filter, init_encrypt,
                              AP_FTYPE_RESOURCE);
    ap_register_input_filter("ENCRYPT", crypto_in_filter, init_encrypt,
                             AP_FTYPE_RESOURCE);
    ap_register_output_filter("DECRYPT", crypto_out_filter, init_decrypt,
                              AP_FTYPE_RESOURCE);
    ap_register_input_filter("DECRYPT", crypto_in_filter, init_decrypt,
                             AP_FTYPE_RESOURCE);
}

AP_DECLARE_MODULE(crypto) = {
    STANDARD20_MODULE_STUFF,
    create_crypto_dir_config, /* create per-directory config structure */
    merge_crypto_dir_config,  /* merge per-directory config structures */
    create_crypto_config,     /* create per-server config structure */
    merge_crypto_config,      /* merge per-server config structures */
    crypto_cmds,              /* command apr_table_t */
    register_hooks            /* register hooks */
};

#else
#error This module requires at least v1.6.0 of apr-util.
#endif
