春哥:
你好,最近用你的lua-nginx-module-ssl-cert-by-lua分支有一些疑问,想向你请教下:
1. 分支不支持pem格式的证书,我看了下源码主要是lua-nginx-module-ssl-cert-by-lua/src/ngx_http_lua_sslcertby.c中的函数ngx_http_lua_ffi_ssl_set_der_certificate
函数在解析证书文件时,你用的openssl接口是d2i_X509_bio;其实若传进来的数据是文本PEM格式的,可以用PEM_read_bio_X509_AUX接口直接解析返回x509 证书结构。当时你实现的时候没考虑用这个接口是否是因为lua传二进制缓存更加安全?还是其他?
2. der编码的证书有个缺点,就是只能对单个证书,不能是证书链(我目前在网上搜索的资料,存证书链都是用pem格式的,很少用der编码的),而PEM格式的证书 可以是证书链。所以,在你的实现中,虽然有对der编码证书循环读证书链,但是der编码证书文件中只有一个证书,故中间证书缺失,导致ssl握手证书验证不过。
3. 目前https服务证书格式基本上都是pem的,很少有der编码的,故个人觉得将此接口改为pem的较好;
4. 当然,私钥也可改变为pem格式的证书;
这是我的一些疑问和建议,还望回复,谢谢
paulvon
如下是在你原来的接口基础上改的支持pem格式证书的接口(在我这里已测试通过)
int
ngx_http_lua_ffi_ssl_set_der_certificate(ngx_http_request_t *r,
const char *data, size_t len, char **err)
{
BIO *bio = NULL;
X509 *x509 = NULL;
ngx_ssl_conn_t *ssl_conn;
if (r->connection == NULL || r->connection->ssl == NULL) {
*err = "bad request";
return NGX_ERROR;
}
ssl_conn = r->connection->ssl->connection;
if (ssl_conn == NULL) {
*err = "bad ssl conn";
return NGX_ERROR;
}
bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = " BIO_new_mem_buf() failed";
goto failed;
}
//x509 = d2i_X509_bio(bio, NULL);
x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
if (x509 == NULL) {
*err = " PEM_read_bio_X509_AUX() failed";
goto failed;
}
if (SSL_use_certificate(ssl_conn, x509) == 0) {
*err = " SSL_use_certificate() failed";
goto failed;
}
#if 0
if (SSL_set_ex_data(ssl_conn, ngx_ssl_certificate_index, x509) == 0) {
*err = " SSL_set_ex_data() failed";
goto failed;
}
#endif
X509_free(x509);
x509 = NULL;
// read rest of the chain
/*
while (!BIO_eof(bio)) {
x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed";
goto failed;
}
if (SSL_add0_chain_cert(ssl_conn, x509) == 0) {
*err = "SSL_add0_chain_cert() failed";
goto failed;
}
}
*/
while (!BIO_eof(bio)) {
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
if (x509 == NULL) {
*err = "PEM_read_bio_X509() failed";
goto failed;
}
if (SSL_add0_chain_cert(ssl_conn, x509) == 0) {
*err = "SSL_add0_chain_cert() failed";
goto failed;
}
}
BIO_free(bio);
*err = NULL;
return NGX_OK;
failed:
if (bio) {
BIO_free(bio);
}
if (x509) {
X509_free(x509);
}
return NGX_ERROR;
}
int
ngx_http_lua_ffi_ssl_set_der_private_key(ngx_http_request_t *r,
const char *data, size_t len, char **err)
{
BIO *bio = NULL;
EVP_PKEY *pkey = NULL;
ngx_ssl_conn_t *ssl_conn;
if (r->connection == NULL || r->connection->ssl == NULL) {
*err = "bad request";
return NGX_ERROR;
}
ssl_conn = r->connection->ssl->connection;
if (ssl_conn == NULL) {
*err = "bad ssl conn";
return NGX_ERROR;
}
bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = "BIO_new_mem_buf() failed";
goto failed;
}
//pkey = d2i_PrivateKey_bio(bio, NULL);
pkey = PEM_read_bio_PrivateKey(bio, NULL, 0, NULL);
if (pkey == NULL) {
*err = "PEM_read_bio_PrivateKey() failed";
goto failed;
}
if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) {
*err = "SSL_CTX_use_PrivateKey() failed";
goto failed;
}
EVP_PKEY_free(pkey);
BIO_free(bio);
return NGX_OK;
failed:
if (pkey) {
EVP_PKEY_free(pkey);
}
if (bio) {
BIO_free(bio);
}
return NGX_ERROR;
}
On Friday, September 25, 2015 at 7:52:51 PM UTC+8, agentzh wrote:
Hello!
2015-09-25 18:37 GMT+08:00 <paul...@gmail.com>:
> 好吧,我再试试低版本的lua-resy-core库。话说我今天把base.lua里的版本判断降成0.9.16了,并且也能运行了,但是不知道有没有隐患,目前还在测试你写的那些配置以及lua-ssl脚本。
>
有隐患。那个版本的 base.lua 文件里要求 0.9.17 是有原因的,lua-resty-core 的一些部分依赖新版 ngx_lua
的 ABI,当这些部分遇到老版 ngx_lua 的时候,轻则内存出错,重则进程崩溃。
Regards,
-agentzh