Skip to content

Commit 3dae10a

Browse files
committed
tls: test for 'privateKeyEngine' and 'privateKeyIdentifier'
Signed-off-by: Anton Gerasimov <[email protected]>
1 parent 970c366 commit 3dae10a

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'testkeyengine',
5+
'type': 'none',
6+
'includes': ['../common.gypi'],
7+
'conditions': [
8+
['OS=="mac" and '
9+
'node_use_openssl=="true" and '
10+
'node_shared=="false" and '
11+
'node_shared_openssl=="false"', {
12+
'type': 'shared_library',
13+
'sources': [ 'testkeyengine.cc' ],
14+
'product_extension': 'engine',
15+
'include_dirs': ['../../../deps/openssl/openssl/include'],
16+
'link_settings': {
17+
'libraries': [
18+
'../../../../out/<(PRODUCT_DIR)/<(openssl_product)'
19+
]
20+
},
21+
}],
22+
]
23+
}
24+
]
25+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
const common = require('../../common');
3+
const fixture = require('../../common/fixtures');
4+
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const fs = require('fs');
9+
const path = require('path');
10+
11+
const engine = path.join(__dirname,
12+
`/build/${common.buildType}/testkeyengine.engine`);
13+
14+
if (!fs.existsSync(engine))
15+
common.skip('no client cert engine');
16+
17+
const assert = require('assert');
18+
const https = require('https');
19+
20+
const agentKey = fs.readFileSync(fixture.path('/keys/agent1-key.pem'));
21+
const agentCert = fs.readFileSync(fixture.path('/keys/agent1-cert.pem'));
22+
const agentCa = fs.readFileSync(fixture.path('/keys/ca1-cert.pem'));
23+
24+
const serverOptions = {
25+
key: agentKey,
26+
cert: agentCert,
27+
ca: agentCa,
28+
requestCert: true,
29+
rejectUnauthorized: true
30+
};
31+
32+
const server = https.createServer(serverOptions, common.mustCall((req, res) => {
33+
res.writeHead(200);
34+
res.end('hello world');
35+
})).listen(0, common.localhostIPv4, common.mustCall(() => {
36+
const clientOptions = {
37+
method: 'GET',
38+
host: common.localhostIPv4,
39+
port: server.address().port,
40+
path: '/test',
41+
privateKeyEngine: engine,
42+
privateKeyIdentifier: 'dummykey',
43+
cert: agentCert,
44+
rejectUnauthorized: false, // Prevent failing on self-signed certificates
45+
headers: {}
46+
};
47+
48+
const req = https.request(clientOptions, common.mustCall(function(response) {
49+
let body = '';
50+
response.setEncoding('utf8');
51+
response.on('data', function(chunk) {
52+
body += chunk;
53+
});
54+
55+
response.on('end', common.mustCall(function() {
56+
assert.strictEqual(body, 'hello world');
57+
server.close();
58+
}));
59+
}));
60+
61+
req.end();
62+
}));
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <assert.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
5+
#include <openssl/engine.h>
6+
#include <openssl/pem.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 "testkeyengine"
17+
#define TEST_ENGINE_NAME "dummy test key engine"
18+
19+
#define PRIVATE_KEY "test/fixtures/keys/agent1-key.pem"
20+
21+
namespace {
22+
23+
int EngineInit(ENGINE* engine) {
24+
return 1;
25+
}
26+
27+
int EngineFinish(ENGINE* engine) {
28+
return 1;
29+
}
30+
31+
int EngineDestroy(ENGINE* engine) {
32+
return 1;
33+
}
34+
35+
std::string LoadFile(const char* filename) {
36+
std::ifstream file(filename);
37+
return std::string(std::istreambuf_iterator<char>(file),
38+
std::istreambuf_iterator<char>());
39+
}
40+
41+
static EVP_PKEY* EngineLoadPrivkey(ENGINE* engine, const char* name,
42+
UI_METHOD* ui_method, void* callback_data) {
43+
if (strcmp(name, "dummykey") == 0) {
44+
std::string key = LoadFile(PRIVATE_KEY);
45+
BIO* bio = BIO_new_mem_buf(key.data(), key.size());
46+
EVP_PKEY* ret = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
47+
48+
BIO_vfree(bio);
49+
if (ret != nullptr) {
50+
return ret;
51+
}
52+
}
53+
54+
return nullptr;
55+
}
56+
57+
int bind_fn(ENGINE* engine, const char* id) {
58+
ENGINE_set_id(engine, TEST_ENGINE_ID);
59+
ENGINE_set_name(engine, TEST_ENGINE_NAME);
60+
ENGINE_set_init_function(engine, EngineInit);
61+
ENGINE_set_finish_function(engine, EngineFinish);
62+
ENGINE_set_destroy_function(engine, EngineDestroy);
63+
ENGINE_set_load_privkey_function(engine, EngineLoadPrivkey);
64+
65+
return 1;
66+
}
67+
68+
extern "C" {
69+
IMPLEMENT_DYNAMIC_CHECK_FN();
70+
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn);
71+
}
72+
73+
} // anonymous namespace

0 commit comments

Comments
 (0)