Skip to content

Commit 007d6ca

Browse files
feature: ssl/tls supports passphrase protected private key. (#285)
1 parent 738bedc commit 007d6ca

File tree

2 files changed

+134
-8
lines changed

2 files changed

+134
-8
lines changed

src/ngx_stream_lua_ssl_certby.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ ngx_stream_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len, u_char *de
10641064

10651065
int
10661066
ngx_stream_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len,
1067-
u_char *der, char **err)
1067+
const u_char *passphrase, u_char *der, char **err)
10681068
{
10691069
int len;
10701070
BIO *in;
@@ -1077,7 +1077,7 @@ ngx_stream_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len,
10771077
return NGX_ERROR;
10781078
}
10791079

1080-
pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1080+
pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, (void *)passphrase);
10811081
if (pkey == NULL) {
10821082
BIO_free(in);
10831083
*err = "PEM_read_bio_PrivateKey() failed";

t/140-ssl-c-api.t

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ ffi.cdef[[
3434
size_t pem_len, unsigned char *der, char **err);
3535
3636
int ngx_stream_lua_ffi_priv_key_pem_to_der(const unsigned char *pem,
37-
size_t pem_len, unsigned char *der, char **err);
37+
size_t pem_len, const unsigned char *passphrase,
38+
unsigned char *der, char **err);
3839
3940
int ngx_stream_lua_ffi_ssl_set_der_certificate(void *r,
4041
const char *data, size_t len, char **err);
@@ -60,8 +61,6 @@ ffi.cdef[[
6061
6162
void ngx_stream_lua_ffi_free_priv_key(void *cdata);
6263
63-
int ngx_stream_lua_ffi_ssl_clear_certs(void *r, char **err);
64-
6564
int ngx_stream_lua_ffi_ssl_verify_client(void *r, void *cdata, int depth, char **err);
6665
6766
]]
@@ -128,7 +127,7 @@ __DATA__
128127
129128
out = ffi.new("char [?]", #pkey)
130129
131-
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg)
130+
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg)
132131
if rc < 1 then
133132
ngx.log(ngx.ERR, "failed to parse PEM priv key: ",
134133
ffi.string(errmsg[0]))
@@ -255,7 +254,7 @@ lua ssl server name: "test.com"
255254
256255
out = ffi.new("char [?]", #pkey)
257256
258-
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg)
257+
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg)
259258
if rc < 1 then
260259
ngx.log(ngx.ERR, "failed to parse PEM priv key: ",
261260
ffi.string(errmsg[0]))
@@ -366,7 +365,7 @@ lua ssl server name: "test.com"
366365
367366
out = ffi.new("char [?]", #pkey)
368367
369-
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg)
368+
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg)
370369
if rc < 1 then
371370
ngx.log(ngx.ERR, "failed to parse PEM priv key: ",
372371
ffi.string(errmsg[0]))
@@ -864,3 +863,130 @@ client certificate subject: nil
864863
--- no_error_log
865864
[error]
866865
[alert]
866+
867+
868+
869+
=== TEST 9: private key protected by passphrase
870+
--- stream_config
871+
server {
872+
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
873+
874+
ssl_certificate_by_lua_block {
875+
collectgarbage()
876+
877+
require "defines"
878+
local ffi = require "ffi"
879+
880+
local errmsg = ffi.new("char *[1]")
881+
882+
local r = require "resty.core.base" .get_request()
883+
if not r then
884+
ngx.log(ngx.ERR, "no request found")
885+
return
886+
end
887+
888+
ffi.C.ngx_stream_lua_ffi_ssl_clear_certs(r, errmsg)
889+
890+
local f = assert(io.open("t/cert/test.crt", "rb"))
891+
local cert = f:read("*all")
892+
f:close()
893+
894+
local out = ffi.new("char [?]", #cert)
895+
896+
local rc = ffi.C.ngx_stream_lua_ffi_cert_pem_to_der(cert, #cert, out, errmsg)
897+
if rc < 1 then
898+
ngx.log(ngx.ERR, "failed to parse PEM cert: ",
899+
ffi.string(errmsg[0]))
900+
return
901+
end
902+
903+
local cert_der = ffi.string(out, rc)
904+
905+
local rc = ffi.C.ngx_stream_lua_ffi_ssl_set_der_certificate(r, cert_der, #cert_der, errmsg)
906+
if rc ~= 0 then
907+
ngx.log(ngx.ERR, "failed to set DER cert: ",
908+
ffi.string(errmsg[0]))
909+
return
910+
end
911+
912+
f = assert(io.open("t/cert/test.key", "rb"))
913+
local pkey = f:read("*all")
914+
f:close()
915+
916+
out = ffi.new("char [?]", #pkey)
917+
918+
local rc = ffi.C.ngx_stream_lua_ffi_priv_key_pem_to_der(pkey, #pkey, "123456", out, errmsg)
919+
if rc < 1 then
920+
ngx.log(ngx.ERR, "failed to parse PEM priv key: ",
921+
ffi.string(errmsg[0]))
922+
return
923+
end
924+
925+
local pkey_der = ffi.string(out, rc)
926+
927+
local rc = ffi.C.ngx_stream_lua_ffi_ssl_set_der_private_key(r, pkey_der, #pkey_der, errmsg)
928+
if rc ~= 0 then
929+
ngx.log(ngx.ERR, "failed to set DER priv key: ",
930+
ffi.string(errmsg[0]))
931+
return
932+
end
933+
}
934+
935+
ssl_certificate ../../cert/test2.crt;
936+
ssl_certificate_key ../../cert/test2.key;
937+
938+
return 'it works!\n';
939+
}
940+
--- stream_server_config
941+
lua_ssl_trusted_certificate ../../cert/test.crt;
942+
943+
content_by_lua_block {
944+
do
945+
local sock = ngx.socket.tcp()
946+
947+
sock:settimeout(2000)
948+
949+
local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
950+
if not ok then
951+
ngx.say("failed to connect: ", err)
952+
return
953+
end
954+
955+
ngx.say("connected: ", ok)
956+
957+
local sess, err = sock:sslhandshake(nil, "test.com", true)
958+
if not sess then
959+
ngx.say("failed to do SSL handshake: ", err)
960+
return
961+
end
962+
963+
ngx.say("ssl handshake: ", type(sess))
964+
965+
while true do
966+
local line, err = sock:receive()
967+
if not line then
968+
-- ngx.say("failed to receive response status line: ", err)
969+
break
970+
end
971+
972+
ngx.say("received: ", line)
973+
end
974+
975+
local ok, err = sock:close()
976+
ngx.say("close: ", ok, " ", err)
977+
end -- do
978+
-- collectgarbage()
979+
}
980+
981+
--- stream_response
982+
connected: 1
983+
ssl handshake: userdata
984+
received: it works!
985+
close: 1 nil
986+
987+
--- error_log
988+
lua ssl server name: "test.com"
989+
990+
--- no_error_log
991+
[error]
992+
[alert]

0 commit comments

Comments
 (0)