• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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