summaryrefslogtreecommitdiff
path: root/src/certstore.cc
blob: 1c384db62704378600274c4e720e50f3b1bbba56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* \brief CertStore Client Module
 *
 * \author Lu Qiuwen<[email protected]>
 * \date 2018-5-10 *
 */

extern "C"
{
#include <event2/util.h>
#include <event2/http.h>
}

#include <thread>
#include <mutex>
#include <vector>
#include <map>
#include <cassert>

#include "certstore.h"
#include "ssl.h"

class CertCache
{
public:
    X509 * x509_cert_query_by_fingerpoint(X509 *crt);
    X509 * x509_cert_query_by_sni(std::string sni);
};

class CertStoreRpc
{
public:
    /* RPC调用异步回调处理函数 */
    using certstore_rpc_done_cb_t = std::function<void(X509 *)>;

    CertStoreRpc(struct event_base * ev_base);
    void backend_server_register(std::string str_backend_addr, uint16_t port);
    void backend_server_unregister(std::string str_backend_addr, uint16_t port);

    X509 * x509_cert_query_by_fingerpoint(X509 *crt, certstore_rpc_done_cb_t cb);
    X509 * x509_cert_query_by_sni(std::string sni, certstore_rpc_done_cb_t cb);

    void x09_cert_sign();

private:
    struct rpc_server_ctx
    {
        std::string str_backend_addr;
        uint16_t backend_port;
        struct evhttp_connection * ev_http_conn;
    };

    struct rpc_request_ctx
    {
        CertStoreRpc * pthis;
        std::string str_query_uri;
        certstore_rpc_done_cb_t user_cb;
    };

    struct evhttp_connection * ev_http_conn_default;
    struct event_base *ev_base;

    /* HTTP Connection管理 */
    std::mutex rpc_server_ctxs_lock;
    using rpc_server_ctx_key_t = std::pair<std::string, uint16_t>;
    std::map<rpc_server_ctx_key_t, rpc_server_ctx *> rpc_server_ctxs;

    /* HTTP应答处理函数 */
    static void rpc_request_done_cb(struct evhttp_request *req, void *ctx);
};

void CertStoreRpc::backend_server_register(std::string str_backend_addr, uint16_t port)
{
    /* 加锁,防止rpc_server_ctxs并发写,离开作用域时自行释放 */
    std::lock_guard<decltype(rpc_server_ctxs_lock)> __lock_guard(rpc_server_ctxs_lock);

    auto *server_ctx = new rpc_server_ctx;
    server_ctx->str_backend_addr = str_backend_addr;
    server_ctx->backend_port = port;
    server_ctx->ev_http_conn = evhttp_connection_base_new(ev_base, nullptr, str_backend_addr.c_str(), port);

    /* evhttp_connection为空 */
    if(server_ctx->ev_http_conn == nullptr)
    {
        throw std::runtime_error("Failed at create evhttp_connection, backend server is " + str_backend_addr);
    }

    rpc_server_ctxs[{str_backend_addr, port}] = server_ctx;
    ev_http_conn_default = server_ctx->ev_http_conn;
}

void CertStoreRpc::backend_server_unregister(std::string str_backend_addr, uint16_t port)
{
    /* 加锁,防止rpc_server_ctxs并发写,离开作用域时自行释放 */
    std::lock_guard<decltype(rpc_server_ctxs_lock)> __lock_guard(rpc_server_ctxs_lock);

    /* 查找,是否存在了目的服务器地址 */
    rpc_server_ctx * server_ctx = rpc_server_ctxs[{str_backend_addr, port}];
    evhttp_connection_free(server_ctx->ev_http_conn);
    delete server_ctx;

    /* 删除map中的ctx */
    rpc_server_ctxs.erase({str_backend_addr, port});
}

X509 * CertStoreRpc::x509_cert_query_by_fingerpoint(X509 *crt, certstore_rpc_done_cb_t cb)
{
    /* 计算x509证书的SHA1指纹 */
    char * x509_sha1 = ssl_x509_fingerprint(crt, 0);
    if(x509_sha1 == nullptr)
    {
        throw std::runtime_error("Failed at calling ssl_x509_fingerprint of crt");
    }

    /* 本请求的上下文,在异步调用的回调函数中销毁 */
    auto * __request_ctx = new rpc_request_ctx;
    __request_ctx->str_query_uri = "/certstore/query?fingerpoint=" + std::string(x509_sha1);
    __request_ctx->user_cb = cb;
    __request_ctx->pthis = this;

    /* 构造HTTP请求,发送的服务器 */
    struct evhttp_request * http_request = evhttp_request_new(rpc_request_done_cb, __request_ctx);
    evhttp_make_request(ev_http_conn_default, http_request, EVHTTP_REQ_GET, __request_ctx->str_query_uri.c_str());

    return nullptr;
}

X509 * CertStoreRpc::x509_cert_query_by_sni(std::string sni, certstore_rpc_done_cb_t cb)
{
    /* 本请求的上下文,在异步调用的回调函数中销毁 */
    auto * __request_ctx = new rpc_request_ctx;
    __request_ctx->str_query_uri = "/certstore/query?sni=" + sni;
    __request_ctx->user_cb = cb;
    __request_ctx->pthis = this;

    /* 构造HTTP请求,发送的服务器 */
    struct evhttp_request * http_request = evhttp_request_new(rpc_request_done_cb, __request_ctx);
    evhttp_make_request(ev_http_conn_default, http_request, EVHTTP_REQ_GET, __request_ctx->str_query_uri.c_str());
}

void CertStoreRpc::rpc_request_done_cb(struct evhttp_request *req, void *ctx)
{
    auto *__request_ctx = (rpc_request_ctx *) ctx;
    assert(__request_ctx != nullptr && __request_ctx->pthis != nullptr);
    return;
}