1 #include <openssl/engine.h>
2 #include <openssl/pem.h>
3
4 #include <assert.h>
5 #include <string.h>
6 #include <stdlib.h>
7
8 #include <fstream>
9 #include <iterator>
10 #include <string>
11
12 #ifndef ENGINE_CMD_BASE
13 # error did not get engine.h
14 #endif
15
16 #define TEST_ENGINE_ID "testengine"
17 #define TEST_ENGINE_NAME "dummy test engine"
18
19 #define AGENT_KEY "test/fixtures/keys/agent1-key.pem"
20 #define AGENT_CERT "test/fixtures/keys/agent1-cert.pem"
21
22 #ifdef _WIN32
23 # define DEFAULT_VISIBILITY __declspec(dllexport)
24 #else
25 # define DEFAULT_VISIBILITY __attribute__((visibility("default")))
26 #endif
27
28 namespace {
29
EngineInit(ENGINE * engine)30 int EngineInit(ENGINE* engine) {
31 return 1;
32 }
33
EngineFinish(ENGINE * engine)34 int EngineFinish(ENGINE* engine) {
35 return 1;
36 }
37
EngineDestroy(ENGINE * engine)38 int EngineDestroy(ENGINE* engine) {
39 return 1;
40 }
41
LoadFile(const char * filename)42 std::string LoadFile(const char* filename) {
43 std::ifstream file(filename);
44 return std::string(std::istreambuf_iterator<char>(file),
45 std::istreambuf_iterator<char>());
46 }
47
48
EngineLoadSSLClientCert(ENGINE * engine,SSL * ssl,STACK_OF (X509_NAME)* ca_dn,X509 ** ppcert,EVP_PKEY ** ppkey,STACK_OF (X509)** pother,UI_METHOD * ui_method,void * callback_data)49 int EngineLoadSSLClientCert(ENGINE* engine,
50 SSL* ssl,
51 STACK_OF(X509_NAME)* ca_dn,
52 X509** ppcert,
53 EVP_PKEY** ppkey,
54 STACK_OF(X509)** pother,
55 UI_METHOD* ui_method,
56 void* callback_data) {
57 if (ppcert != nullptr) {
58 std::string cert = LoadFile(AGENT_CERT);
59 if (cert.empty()) {
60 return 0;
61 }
62
63 BIO* bio = BIO_new_mem_buf(cert.data(), cert.size());
64 *ppcert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr);
65 BIO_vfree(bio);
66 if (*ppcert == nullptr) {
67 printf("Could not read certificate\n");
68 return 0;
69 }
70 }
71
72 if (ppkey != nullptr) {
73 std::string key = LoadFile(AGENT_KEY);
74 if (key.empty()) {
75 return 0;
76 }
77
78 BIO* bio = BIO_new_mem_buf(key.data(), key.size());
79 *ppkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
80 BIO_vfree(bio);
81 if (*ppkey == nullptr) {
82 printf("Could not read private key\n");
83 return 0;
84 }
85 }
86
87 return 1;
88 }
89
bind_fn(ENGINE * engine,const char * id)90 int bind_fn(ENGINE* engine, const char* id) {
91 ENGINE_set_id(engine, TEST_ENGINE_ID);
92 ENGINE_set_name(engine, TEST_ENGINE_NAME);
93 ENGINE_set_init_function(engine, EngineInit);
94 ENGINE_set_finish_function(engine, EngineFinish);
95 ENGINE_set_destroy_function(engine, EngineDestroy);
96 ENGINE_set_load_ssl_client_cert_function(engine, EngineLoadSSLClientCert);
97
98 return 1;
99 }
100
101 extern "C" {
102 DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN();
103 DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn);
104 }
105
106 } // anonymous namespace
107