New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: add client SSL certificiate support #957
Conversation
|
||
|
||
|
||
=== TEST 33: setsslcert, too many arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These new tests should go to a separate test file. This 129-ssl-socket.t
file is already quite large.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, how about 151-ssl-client-setcert.t?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fine.
local cert = read_file("$TEST_NGINX_HTML_DIR/client.crt") | ||
local key = read_file("$TEST_NGINX_HTML_DIR/client.unsecure.key") | ||
|
||
local ok, err = sock:setsslcert(cert, key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking about a different Lua API than this. Loading the raw certificates upon every SSL cosocket is quite expensive and the client-side certificates tend to be reused over and over again. I think we can introduce an opaque SSL ctx object that loads the certificates only once and for each new SSL cosocket, we just feed the SSL ctx object to it directly. Other custom SSL configurations added in the future can be configured in a similar way. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@agentzh I agree
Loading the raw certificates upon every SSL cosocket is quite expensive and the client-side certificates tend to be reused over and over again.So how about the new directive
lua_ssl_client_keyand
lua_ssl_client_certificate` to feed SSL ctx object to it directly? Also can we provide this Lua API to allow user to set different certificates on the fly?
Just now i misunderstand what you said, now i do understand. I agree to add new Lua API to be easily configure custom SSL configurations, And do you have a good suggestion about the new Lua API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the loading part that @agentzh as actually parsing the certificates (which would be solved by re-using the existing API as I already commented).
However I also think that adding the certificate to the "global" SSL_CTX is wrong, since that would affect any other SSL objects created from it (past and present), so having an API to create a new SSL_CTX and apply configurations to it would be best.
@agentzh so sorry long time to reply. I know you are thinking a different Lua API. Can you explain to me what's the different Lua API so that to change this codebase? Now I have enough time to follow your minds. By the way, happy new year 2017:) |
@detailyang I'm not exactly sure at this point. Maybe something like this? local ssl = require "ngx.ssl"
local ctx = ssl.create_ctx{
client_certificate = "pem-data",
}
-- we can cache the ctx object in a cache like lua-resty-lrucache
local sock = ngx.socket.tcp()
local ok, err = sock:setsslctx(ctx)
sock:sslhandshake(...) @lziest @ghedo @doujiang24 What do you think? |
@agentzh well, it looks like not bad. I will attempt to implement it in localhost |
* Reading the PEM-formatted certificate from memory into an X509 | ||
*/ | ||
|
||
x509 = PEM_read_bio_X509(cbio, NULL, 0, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that we already have PEM (and DER) parsing functions, should users maybe use those and pass the already parsed chain to this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ghedo Yesterday I have try to reuse the already parsed chain. Finally I have found these data is type of Luajit's cdata and we cannot reference these data in Lua CFunction.:(
@agentzh yes, that looks better, since it would avoid setting the certificate for the global SSL_CTX (so other SSLs wouldn't get the same configuration). An alternative API would be having a |
goto done; | ||
} | ||
|
||
pkey = PEM_read_bio_PrivateKey(pbio, NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above. We don't yet support parsing keys with passwords, but that should be added to the existing API instead IMO, so it would be more generally useful. Or better yet, add an additional function (e.g. ngx_http_lua_ffi_parse_pem_priv_key_with_password()
) to do just that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think this should be a separate PR, so this one would get smaller and easier to review.
@ghedo Agreed :) |
@ghedo @agentzh Thanks for yours eager suggestion. I guess I need more time to finish this feature (so sorry for my level). So just want to finish these easy parts pointed by @ghedo (parsing the private key with password), then do other parts. I wil create another PR to add the existing API (ngx_http_lua_ffi_parse_pem_priv_key) or creating additional api (ngx_http_lua_ffi_parse_pem_priv_key_with_password) for parsing the private key with password. What do you thinks of this? |
Hello, guys. I have successfully run a demo for Lua API to feed Recently I I have try to implement two versions Lua API to feed
local ctx = ngx.ssl.create_ctx{
client_certificate = "pem-data",
}
-- we can cache the ctx object in a cache like lua-resty-lrucache
local sock = ngx.socket.tcp()
local ok, err = sock:setsslctx(ctx)
sock:sslhandshake(...) This version
local ctx = ngx.ssl.ctx()
local ok, err = ctx:init({
method = 'xxx', -- the openssl protocol methods
cert = 'xxx', -- cert chains in PEM format
key = 'xxx', -- private keys in PEM format
cacert = 'xxx' -- the trusted CA certificates
})
if not ok then
return error("init ssl ctx error: " .. err)
end
-- we can cache the ctx table in a cache like lua-resty-lrucache
local sock = ngx.socket.tcp()
local ok, err = sock:setsslctx(ctx)
sock:sslhandshake(...) This version local ctx = ngx.ssl.ctx()
local ok, err = ctx:init({
method = 'xxx', -- the openssl protocol methods default SSLv23_method
cert = 'xxx', -- cert chains in PEM format
key = 'xxx', -- private keys in PEM format
cacert = 'xxx' -- the trusted CA certificates in PEM format
})
if not ok then
return error("init ssl ctx error: " .. err)
end
--we can add more api in future as the following
ctx:set_key()
ctx:set_cert()
ctx:add_cacert()
ctx:add_crl()
ctx:set_ciphres()
ctx:set_ecdhcurve()
ctx:set_dhparam()
Also I refer to the Node.js JS API Design and Node.js C++ API Design as a guide to our Lua API. Which one is better? Need yours feedback and let us make a choice :D |
Ping @agentzh @doujiang24 @thibaultcha @lziest @ghedo. Can you have a look at the above, If you are free now. Thanks :D |
@detailyang Sorry for the delay on my side. Been massively distracted. Regarding the API design, I don't quite like the local ssl = require "ngx.ssl"
local ctx = ssl.create_ctx{
client_certificate = "pem-data",
}
-- we can cache the ctx object in a cache like lua-resty-lrucache
local sock = ngx.socket.tcp()
local ok, err = sock:setsslctx(ctx)
sock:sslhandshake(...) But yeah, we'll have to implement the The |
@agentzh Thanks for reply me. |
I hereby granted the copyright of the changes in this pull request
to the authors of this lua-nginx-module project.
@agentzh This feature is talked at openresty/issues/222 and be listed in TODO list
Now I just add the api and tests but lack document. When we think it can be merged to master, i will supplement the api usage later.
Please help me review this PR, many thanks 馃榿