Skip to content

Commit

Permalink
Add ngx_http_lua_ffi_parse_der_cert and ngx_http_lua_ffi_parse_der_ke…
Browse files Browse the repository at this point in the history
…y functions
  • Loading branch information
devicenull committed Jan 17, 2024
1 parent 0e769b7 commit ab7603a
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -7916,11 +7916,11 @@ Set client certificate chain and corresponding private key to the TCP socket obj
The certificate chain and private key provided will be used later by the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.

* `cert` specify a client certificate chain cdata object that will be used while handshaking with
remote server. These objects can be created using [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert)
remote server. These objects can be created using [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert) or [ngx.ssl.parse\_der\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_der_cert)
function provided by lua-resty-core. Note that specifying the `cert` option requires
corresponding `pkey` be provided too. See below.
* `pkey` specify a private key corresponds to the `cert` option above.
These objects can be created using [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key)
These objects can be created using [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key) or [ngx.ssl.parse\_der\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_der_priv_key)
function provided by lua-resty-core.

If both of `cert` and `pkey` are `nil`, this method will clear any existing client certificate and private key
Expand Down
221 changes: 221 additions & 0 deletions src/ngx_http_lua_ssl_certby.c
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,144 @@ ngx_http_lua_ffi_parse_pem_cert(const u_char *pem, size_t pem_len,
return chain;
}

void *
ngx_http_lua_ffi_parse_der_cert(const char *data, size_t len,
char **err)
{
BIO *bio;
X509 *x509;
u_long n;
STACK_OF(X509) *chain;

bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = "BIO_new_mem_buf() failed";
ERR_clear_error();
return NULL;
}

x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

chain = sk_X509_new_null();
if (chain == NULL) {
*err = "sk_X509_new_null() failed";
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

if (sk_X509_push(chain, x509) == 0) {
*err = "sk_X509_push() failed";
sk_X509_free(chain);
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

/* read rest of the chain */

while (!BIO_eof(bio)) {
x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed in rest of chain";
sk_X509_pop_free(chain, X509_free);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

if (sk_X509_push(chain, x509) == 0) {
*err = "sk_X509_push() failed in rest of chain";
sk_X509_pop_free(chain, X509_free);
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}
}

BIO_free(bio);

return chain;
}

void *
ngx_http_lua_ffi_parse_der_cert(const char *data, size_t len,
char **err)
{
BIO *bio;
X509 *x509;
u_long n;
STACK_OF(X509) *chain;

bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = "BIO_new_mem_buf() failed";
ERR_clear_error();
return NULL;
}

x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

chain = sk_X509_new_null();
if (chain == NULL) {
*err = "sk_X509_new_null() failed";
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

if (sk_X509_push(chain, x509) == 0) {
*err = "sk_X509_push() failed";
sk_X509_free(chain);
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

/* read rest of the chain */

while (!BIO_eof(bio)) {
x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed in rest of chain";
sk_X509_pop_free(chain, X509_free);
BIO_free(bio);
ERR_clear_error();
return NULL;
}

if (sk_X509_push(chain, x509) == 0) {
*err = "sk_X509_push() failed in rest of chain";
sk_X509_pop_free(chain, X509_free);
X509_free(x509);
BIO_free(bio);
ERR_clear_error();
return NULL;
}
}

BIO_free(bio);

return chain;
}


void
ngx_http_lua_ffi_free_cert(void *cdata)
Expand Down Expand Up @@ -1208,6 +1346,62 @@ ngx_http_lua_ffi_parse_pem_priv_key(const u_char *pem, size_t pem_len,
return pkey;
}

void *
ngx_http_lua_ffi_parse_der_priv_key(const char *data, size_t len,
char **err)
{
BIO *bio = NULL;
EVP_PKEY *pkey = NULL;

bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = "BIO_new_mem_buf() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

pkey = d2i_PrivateKey_bio(bio, NULL);
if (pkey == NULL) {
*err = "d2i_PrivateKey_bio() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

BIO_free(bio);

return pkey;
}

void *
ngx_http_lua_ffi_parse_der_priv_key(const char *data, size_t len,
char **err)
{
BIO *bio = NULL;
EVP_PKEY *pkey = NULL;

bio = BIO_new_mem_buf((char *) data, len);
if (bio == NULL) {
*err = "BIO_new_mem_buf() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

pkey = d2i_PrivateKey_bio(bio, NULL);
if (pkey == NULL) {
*err = "d2i_PrivateKey_bio() failed";
BIO_free(bio);
ERR_clear_error();
return NULL;
}

BIO_free(bio);

return pkey;
}


void
ngx_http_lua_ffi_free_priv_key(void *cdata)
Expand All @@ -1217,6 +1411,33 @@ ngx_http_lua_ffi_free_priv_key(void *cdata)
EVP_PKEY_free(pkey);
}

int
ngx_http_lua_ffi_ssl_set_ciphers(ngx_http_request_t *r, const char *ciphers,
char **err)
{
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;
}

if (!SSL_set_cipher_list(ssl_conn, ciphers)) {
*err = "SSL_set_cipher_list() failed";
ERR_clear_error();
return NGX_ERROR;
}

return NGX_OK;
}



int
ngx_http_lua_ffi_set_cert(ngx_http_request_t *r,
Expand Down

0 comments on commit ab7603a

Please sign in to comment.