#pragma once
#include "common.hpp"
#include "test.hpp"
#include "mkcert.hpp"
#include "hash.hpp"
#include "aio.hpp"
class SslCtx: public ConfigInst<size_t> {
private:
typedef struct {
char host[MAX_SNI_LEN+1];
ssl_ctx_t* ctx;
} node_t;
HashMap<node_t> cache;
public:
SslCtx(size_t);
~SslCtx();
bool is_valid() const { return true; }
ssl_ctx_t* get(const char*, const char*, size_t, const char*, size_t); ///< for given cn, cert, and key, return new ctx and cache it for this CN. Ctx must be freed.
ssl_ctx_t* get(const char*); ///< for given CN return cache-hit, if any. Ctx must be freed.
};
class Wallet: public ConfigInst<char*> { // Goal is not to have to import a CA that can sign everything
private:
typedef struct {
char host[MAX_SNI_LEN+1]; // prevent hash collisions:
AioFileIn::Result* aio_result;
// parsed #aio_result:
const char* cert;
size_t certlen;
const char* key;
size_t keylen;
} data_t;
HashMap<data_t> data;
int dirfd;
void load(const char*); ///< load cert~key file in #dirfd
bool parse(data_t*); ///< parse aio result buf in cert and key
tristate_t get(const char*, const char*&, size_t&, const char*&, size_t&); ///< #data lookup and defered parsing, TRI_TRUE: success, TRI_FALSE: error or no data (yet), TRI_NONE: not responsible for this host
public:
Wallet(const char*); ///< crawls given path and loads pre-defined cert~key files
~Wallet();
bool is_valid() const { return dirfd != -1; }
tristate_t get(const char*, SslCtx*, ssl_ctx_t*&); ///< sets ctx (if cert found) and caches it in given @see SslCtx, TRI_TRUE: success, TRI_FALSE: error or no data (yet), TRI_NONE: not responsible for this host
};