LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_ssl_certby.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 0 535 0.0 %
Date: 2020-03-03 04:25:50 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Yichun Zhang (agentzh)
       4             :  */
       5             : 
       6             : 
       7             : #ifndef DDEBUG
       8             : #define DDEBUG 0
       9             : #endif
      10             : #include "ddebug.h"
      11             : 
      12             : 
      13             : #if (NGX_HTTP_SSL)
      14             : 
      15             : 
      16             : #include "ngx_http_lua_cache.h"
      17             : #include "ngx_http_lua_initworkerby.h"
      18             : #include "ngx_http_lua_util.h"
      19             : #include "ngx_http_ssl_module.h"
      20             : #include "ngx_http_lua_contentby.h"
      21             : #include "ngx_http_lua_ssl_certby.h"
      22             : #include "ngx_http_lua_directive.h"
      23             : #include "ngx_http_lua_ssl.h"
      24             : 
      25             : 
      26             : enum {
      27             :     NGX_HTTP_LUA_ADDR_TYPE_UNIX  = 0,
      28             :     NGX_HTTP_LUA_ADDR_TYPE_INET  = 1,
      29             :     NGX_HTTP_LUA_ADDR_TYPE_INET6 = 2
      30             : };
      31             : 
      32             : 
      33             : static void ngx_http_lua_ssl_cert_done(void *data);
      34             : static void ngx_http_lua_ssl_cert_aborted(void *data);
      35             : static u_char *ngx_http_lua_log_ssl_cert_error(ngx_log_t *log, u_char *buf,
      36             :     size_t len);
      37             : static ngx_int_t ngx_http_lua_ssl_cert_by_chunk(lua_State *L,
      38             :     ngx_http_request_t *r);
      39             : 
      40             : 
      41             : ngx_int_t
      42           0 : ngx_http_lua_ssl_cert_handler_file(ngx_http_request_t *r,
      43             :     ngx_http_lua_srv_conf_t *lscf, lua_State *L)
      44             : {
      45             :     ngx_int_t           rc;
      46             : 
      47           0 :     rc = ngx_http_lua_cache_loadfile(r->connection->log, L,
      48           0 :                                      lscf->srv.ssl_cert_src.data,
      49           0 :                                      lscf->srv.ssl_cert_src_key);
      50           0 :     if (rc != NGX_OK) {
      51           0 :         return rc;
      52             :     }
      53             : 
      54             :     /*  make sure we have a valid code chunk */
      55           0 :     ngx_http_lua_assert(lua_isfunction(L, -1));
      56             : 
      57           0 :     return ngx_http_lua_ssl_cert_by_chunk(L, r);
      58             : }
      59             : 
      60             : 
      61             : ngx_int_t
      62           0 : ngx_http_lua_ssl_cert_handler_inline(ngx_http_request_t *r,
      63             :     ngx_http_lua_srv_conf_t *lscf, lua_State *L)
      64             : {
      65             :     ngx_int_t           rc;
      66             : 
      67           0 :     rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
      68           0 :                                        lscf->srv.ssl_cert_src.data,
      69             :                                        lscf->srv.ssl_cert_src.len,
      70           0 :                                        lscf->srv.ssl_cert_src_key,
      71             :                                        "=ssl_certificate_by_lua");
      72           0 :     if (rc != NGX_OK) {
      73           0 :         return rc;
      74             :     }
      75             : 
      76             :     /*  make sure we have a valid code chunk */
      77           0 :     ngx_http_lua_assert(lua_isfunction(L, -1));
      78             : 
      79           0 :     return ngx_http_lua_ssl_cert_by_chunk(L, r);
      80             : }
      81             : 
      82             : 
      83             : char *
      84           0 : ngx_http_lua_ssl_cert_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
      85             :     void *conf)
      86             : {
      87             :     char        *rv;
      88             :     ngx_conf_t   save;
      89             : 
      90           0 :     save = *cf;
      91           0 :     cf->handler = ngx_http_lua_ssl_cert_by_lua;
      92           0 :     cf->handler_conf = conf;
      93             : 
      94           0 :     rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
      95             : 
      96           0 :     *cf = save;
      97             : 
      98           0 :     return rv;
      99             : }
     100             : 
     101             : 
     102             : char *
     103           0 : ngx_http_lua_ssl_cert_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
     104             :     void *conf)
     105             : {
     106             : #if OPENSSL_VERSION_NUMBER < 0x1000205fL
     107             : 
     108             :     ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
     109             :                   "at least OpenSSL 1.0.2e required but found "
     110             :                   OPENSSL_VERSION_TEXT);
     111             : 
     112             :     return NGX_CONF_ERROR;
     113             : 
     114             : #else
     115             : 
     116             :     u_char                      *p;
     117             :     u_char                      *name;
     118             :     ngx_str_t                   *value;
     119           0 :     ngx_http_lua_srv_conf_t    *lscf = conf;
     120             : 
     121             :     /*  must specify a concrete handler */
     122           0 :     if (cmd->post == NULL) {
     123           0 :         return NGX_CONF_ERROR;
     124             :     }
     125             : 
     126           0 :     if (lscf->srv.ssl_cert_handler) {
     127           0 :         return "is duplicate";
     128             :     }
     129             : 
     130           0 :     if (ngx_http_lua_ssl_init(cf->log) != NGX_OK) {
     131           0 :         return NGX_CONF_ERROR;
     132             :     }
     133             : 
     134           0 :     value = cf->args->elts;
     135             : 
     136           0 :     lscf->srv.ssl_cert_handler = (ngx_http_lua_srv_conf_handler_pt) cmd->post;
     137             : 
     138           0 :     if (cmd->post == ngx_http_lua_ssl_cert_handler_file) {
     139             :         /* Lua code in an external file */
     140             : 
     141           0 :         name = ngx_http_lua_rebase_path(cf->pool, value[1].data,
     142           0 :                                         value[1].len);
     143           0 :         if (name == NULL) {
     144           0 :             return NGX_CONF_ERROR;
     145             :         }
     146             : 
     147           0 :         lscf->srv.ssl_cert_src.data = name;
     148           0 :         lscf->srv.ssl_cert_src.len = ngx_strlen(name);
     149             : 
     150           0 :         p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1);
     151           0 :         if (p == NULL) {
     152           0 :             return NGX_CONF_ERROR;
     153             :         }
     154             : 
     155           0 :         lscf->srv.ssl_cert_src_key = p;
     156             : 
     157           0 :         p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN);
     158           0 :         p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
     159           0 :         *p = '\0';
     160             : 
     161             :     } else {
     162             :         /* inlined Lua code */
     163             : 
     164           0 :         lscf->srv.ssl_cert_src = value[1];
     165             : 
     166           0 :         p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
     167           0 :         if (p == NULL) {
     168           0 :             return NGX_CONF_ERROR;
     169             :         }
     170             : 
     171           0 :         lscf->srv.ssl_cert_src_key = p;
     172             : 
     173           0 :         p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
     174           0 :         p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
     175           0 :         *p = '\0';
     176             :     }
     177             : 
     178           0 :     return NGX_CONF_OK;
     179             : 
     180             : #endif  /* OPENSSL_VERSION_NUMBER < 0x1000205fL */
     181             : }
     182             : 
     183             : 
     184             : int
     185           0 : ngx_http_lua_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data)
     186             : {
     187             :     lua_State                       *L;
     188             :     ngx_int_t                        rc;
     189             :     ngx_connection_t                *c, *fc;
     190           0 :     ngx_http_request_t              *r = NULL;
     191             :     ngx_pool_cleanup_t              *cln;
     192             :     ngx_http_connection_t           *hc;
     193             :     ngx_http_lua_srv_conf_t         *lscf;
     194             :     ngx_http_core_loc_conf_t        *clcf;
     195             :     ngx_http_lua_ssl_ctx_t          *cctx;
     196             :     ngx_http_core_srv_conf_t        *cscf;
     197             : 
     198           0 :     c = ngx_ssl_get_connection(ssl_conn);
     199             : 
     200           0 :     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
     201             :                    "ssl cert: connection reusable: %ud", c->reusable);
     202             : 
     203           0 :     cctx = ngx_http_lua_ssl_get_ctx(c->ssl->connection);
     204             : 
     205             :     dd("ssl cert handler, cert-ctx=%p", cctx);
     206             : 
     207           0 :     if (cctx && cctx->entered_cert_handler) {
     208             :         /* not the first time */
     209             : 
     210           0 :         if (cctx->done) {
     211           0 :             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
     212             :                            "lua_certificate_by_lua: cert cb exit code: %d",
     213             :                            cctx->exit_code);
     214             : 
     215             :             dd("lua ssl cert done, finally");
     216           0 :             return cctx->exit_code;
     217             :         }
     218             : 
     219           0 :         return -1;
     220             :     }
     221             : 
     222             :     dd("first time");
     223             : 
     224           0 :     ngx_reusable_connection(c, 0);
     225             : 
     226           0 :     hc = c->data;
     227             : 
     228           0 :     fc = ngx_http_lua_create_fake_connection(NULL);
     229           0 :     if (fc == NULL) {
     230           0 :         goto failed;
     231             :     }
     232             : 
     233           0 :     fc->log->handler = ngx_http_lua_log_ssl_cert_error;
     234           0 :     fc->log->data = fc;
     235             : 
     236           0 :     fc->addr_text = c->addr_text;
     237           0 :     fc->listening = c->listening;
     238             : 
     239           0 :     r = ngx_http_lua_create_fake_request(fc);
     240           0 :     if (r == NULL) {
     241           0 :         goto failed;
     242             :     }
     243             : 
     244           0 :     r->main_conf = hc->conf_ctx->main_conf;
     245           0 :     r->srv_conf = hc->conf_ctx->srv_conf;
     246           0 :     r->loc_conf = hc->conf_ctx->loc_conf;
     247             : 
     248           0 :     fc->log->file = c->log->file;
     249           0 :     fc->log->log_level = c->log->log_level;
     250           0 :     fc->ssl = c->ssl;
     251             : 
     252           0 :     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
     253             : 
     254             : #if defined(nginx_version) && nginx_version >= 1003014
     255             : 
     256             : #   if nginx_version >= 1009000
     257             : 
     258           0 :     ngx_set_connection_log(fc, clcf->error_log);
     259             : 
     260             : #   else
     261             : 
     262             :     ngx_http_set_connection_log(fc, clcf->error_log);
     263             : 
     264             : #   endif
     265             : 
     266             : #else
     267             : 
     268             :     fc->log->file = clcf->error_log->file;
     269             : 
     270             :     if (!(fc->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
     271             :         fc->log->log_level = clcf->error_log->log_level;
     272             :     }
     273             : 
     274             : #endif
     275             : 
     276           0 :     if (cctx == NULL) {
     277           0 :         cctx = ngx_pcalloc(c->pool, sizeof(ngx_http_lua_ssl_ctx_t));
     278           0 :         if (cctx == NULL) {
     279           0 :             goto failed;  /* error */
     280             :         }
     281             :     }
     282             : 
     283           0 :     cctx->exit_code = 1;  /* successful by default */
     284           0 :     cctx->connection = c;
     285           0 :     cctx->request = r;
     286           0 :     cctx->entered_cert_handler = 1;
     287           0 :     cctx->done = 0;
     288             : 
     289             :     dd("setting cctx");
     290             : 
     291           0 :     if (SSL_set_ex_data(c->ssl->connection, ngx_http_lua_ssl_ctx_index, cctx)
     292             :         == 0)
     293             :     {
     294           0 :         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
     295           0 :         goto failed;
     296             :     }
     297             : 
     298           0 :     lscf = ngx_http_get_module_srv_conf(r, ngx_http_lua_module);
     299             : 
     300             :     /* TODO honor lua_code_cache off */
     301           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     302             : 
     303           0 :     c->log->action = "loading SSL certificate by lua";
     304             : 
     305           0 :     if (lscf->srv.ssl_cert_handler == NULL) {
     306           0 :         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
     307             : 
     308           0 :         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
     309             :                       "no ssl_certificate_by_lua* defined in "
     310             :                       "server %V", &cscf->server_name);
     311             : 
     312           0 :         goto failed;
     313             :     }
     314             : 
     315           0 :     rc = lscf->srv.ssl_cert_handler(r, lscf, L);
     316             : 
     317           0 :     if (rc >= NGX_OK || rc == NGX_ERROR) {
     318           0 :         cctx->done = 1;
     319             : 
     320           0 :         if (cctx->cleanup) {
     321           0 :             *cctx->cleanup = NULL;
     322             :         }
     323             : 
     324           0 :         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
     325             :                        "lua_certificate_by_lua: handler return value: %i, "
     326             :                        "cert cb exit code: %d", rc, cctx->exit_code);
     327             : 
     328           0 :         c->log->action = "SSL handshaking";
     329           0 :         return cctx->exit_code;
     330             :     }
     331             : 
     332             :     /* rc == NGX_DONE */
     333             : 
     334           0 :     cln = ngx_pool_cleanup_add(fc->pool, 0);
     335           0 :     if (cln == NULL) {
     336           0 :         goto failed;
     337             :     }
     338             : 
     339           0 :     cln->handler = ngx_http_lua_ssl_cert_done;
     340           0 :     cln->data = cctx;
     341             : 
     342           0 :     if (cctx->cleanup == NULL) {
     343           0 :         cln = ngx_pool_cleanup_add(c->pool, 0);
     344           0 :         if (cln == NULL) {
     345           0 :             goto failed;
     346             :         }
     347             : 
     348           0 :         cln->data = cctx;
     349           0 :         cctx->cleanup = &cln->handler;
     350             :     }
     351             : 
     352           0 :     *cctx->cleanup = ngx_http_lua_ssl_cert_aborted;
     353             : 
     354           0 :     return -1;
     355             : 
     356             : #if 1
     357           0 : failed:
     358             : 
     359           0 :     if (r && r->pool) {
     360           0 :         ngx_http_lua_free_fake_request(r);
     361             :     }
     362             : 
     363           0 :     if (fc) {
     364           0 :         ngx_http_lua_close_fake_connection(fc);
     365             :     }
     366             : 
     367           0 :     return 0;
     368             : #endif
     369             : }
     370             : 
     371             : 
     372             : static void
     373           0 : ngx_http_lua_ssl_cert_done(void *data)
     374             : {
     375             :     ngx_connection_t                *c;
     376           0 :     ngx_http_lua_ssl_ctx_t          *cctx = data;
     377             : 
     378             :     dd("lua ssl cert done");
     379             : 
     380           0 :     if (cctx->aborted) {
     381           0 :         return;
     382             :     }
     383             : 
     384           0 :     ngx_http_lua_assert(cctx->done == 0);
     385             : 
     386           0 :     cctx->done = 1;
     387             : 
     388           0 :     if (cctx->cleanup) {
     389           0 :         *cctx->cleanup = NULL;
     390             :     }
     391             : 
     392           0 :     c = cctx->connection;
     393             : 
     394           0 :     c->log->action = "SSL handshaking";
     395             : 
     396           0 :     ngx_post_event(c->write, &ngx_posted_events);
     397             : }
     398             : 
     399             : 
     400             : static void
     401           0 : ngx_http_lua_ssl_cert_aborted(void *data)
     402             : {
     403           0 :     ngx_http_lua_ssl_ctx_t      *cctx = data;
     404             : 
     405             :     dd("lua ssl cert done");
     406             : 
     407           0 :     if (cctx->done) {
     408             :         /* completed successfully already */
     409           0 :         return;
     410             :     }
     411             : 
     412           0 :     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cctx->connection->log, 0,
     413             :                    "lua_certificate_by_lua: cert cb aborted");
     414             : 
     415           0 :     cctx->aborted = 1;
     416           0 :     cctx->request->connection->ssl = NULL;
     417             : 
     418           0 :     ngx_http_lua_finalize_fake_request(cctx->request, NGX_ERROR);
     419             : }
     420             : 
     421             : 
     422             : static u_char *
     423           0 : ngx_http_lua_log_ssl_cert_error(ngx_log_t *log, u_char *buf, size_t len)
     424             : {
     425             :     u_char              *p;
     426             :     ngx_connection_t    *c;
     427             : 
     428           0 :     if (log->action) {
     429           0 :         p = ngx_snprintf(buf, len, " while %s", log->action);
     430           0 :         len -= p - buf;
     431           0 :         buf = p;
     432             :     }
     433             : 
     434           0 :     p = ngx_snprintf(buf, len, ", context: ssl_certificate_by_lua*");
     435           0 :     len -= p - buf;
     436           0 :     buf = p;
     437             : 
     438           0 :     c = log->data;
     439             : 
     440           0 :     if (c->addr_text.len) {
     441           0 :         p = ngx_snprintf(buf, len, ", client: %V", &c->addr_text);
     442           0 :         len -= p - buf;
     443           0 :         buf = p;
     444             :     }
     445             : 
     446           0 :     if (c && c->listening && c->listening->addr_text.len) {
     447           0 :         p = ngx_snprintf(buf, len, ", server: %V", &c->listening->addr_text);
     448             :         /* len -= p - buf; */
     449           0 :         buf = p;
     450             :     }
     451             : 
     452           0 :     return buf;
     453             : }
     454             : 
     455             : 
     456             : static ngx_int_t
     457           0 : ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r)
     458             : {
     459             :     int                      co_ref;
     460             :     ngx_int_t                rc;
     461             :     lua_State               *co;
     462             :     ngx_http_lua_ctx_t      *ctx;
     463             :     ngx_http_cleanup_t      *cln;
     464             : 
     465           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     466             : 
     467           0 :     if (ctx == NULL) {
     468           0 :         ctx = ngx_http_lua_create_ctx(r);
     469           0 :         if (ctx == NULL) {
     470           0 :             rc = NGX_ERROR;
     471           0 :             ngx_http_lua_finalize_request(r, rc);
     472           0 :             return rc;
     473             :         }
     474             : 
     475             :     } else {
     476             :         dd("reset ctx");
     477           0 :         ngx_http_lua_reset_ctx(r, L, ctx);
     478             :     }
     479             : 
     480           0 :     ctx->entered_content_phase = 1;
     481             : 
     482             :     /*  {{{ new coroutine to handle request */
     483           0 :     co = ngx_http_lua_new_thread(r, L, &co_ref);
     484             : 
     485           0 :     if (co == NULL) {
     486           0 :         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
     487             :                       "lua: failed to create new coroutine to handle request");
     488             : 
     489           0 :         rc = NGX_ERROR;
     490           0 :         ngx_http_lua_finalize_request(r, rc);
     491           0 :         return rc;
     492             :     }
     493             : 
     494             :     /*  move code closure to new coroutine */
     495           0 :     lua_xmove(L, co, 1);
     496             : 
     497             :     /*  set closure's env table to new coroutine's globals table */
     498           0 :     ngx_http_lua_get_globals_table(co);
     499           0 :     lua_setfenv(co, -2);
     500             : 
     501             :     /* save nginx request in coroutine globals table */
     502           0 :     ngx_http_lua_set_req(co, r);
     503             : 
     504           0 :     ctx->cur_co_ctx = &ctx->entry_co_ctx;
     505           0 :     ctx->cur_co_ctx->co = co;
     506           0 :     ctx->cur_co_ctx->co_ref = co_ref;
     507             : #ifdef NGX_LUA_USE_ASSERT
     508           0 :     ctx->cur_co_ctx->co_top = 1;
     509             : #endif
     510             : 
     511             :     /* register request cleanup hooks */
     512           0 :     if (ctx->cleanup == NULL) {
     513           0 :         cln = ngx_http_cleanup_add(r, 0);
     514           0 :         if (cln == NULL) {
     515           0 :             rc = NGX_ERROR;
     516           0 :             ngx_http_lua_finalize_request(r, rc);
     517           0 :             return rc;
     518             :         }
     519             : 
     520           0 :         cln->handler = ngx_http_lua_request_cleanup_handler;
     521           0 :         cln->data = ctx;
     522           0 :         ctx->cleanup = &cln->handler;
     523             :     }
     524             : 
     525           0 :     ctx->context = NGX_HTTP_LUA_CONTEXT_SSL_CERT;
     526             : 
     527           0 :     rc = ngx_http_lua_run_thread(L, r, ctx, 0);
     528             : 
     529           0 :     if (rc == NGX_ERROR || rc >= NGX_OK) {
     530             :         /* do nothing */
     531             : 
     532           0 :     } else if (rc == NGX_AGAIN) {
     533           0 :         rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0);
     534             : 
     535           0 :     } else if (rc == NGX_DONE) {
     536           0 :         rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 1);
     537             : 
     538             :     } else {
     539           0 :         rc = NGX_OK;
     540             :     }
     541             : 
     542           0 :     ngx_http_lua_finalize_request(r, rc);
     543           0 :     return rc;
     544             : }
     545             : 
     546             : 
     547             : #ifndef NGX_LUA_NO_FFI_API
     548             : 
     549             : int
     550           0 : ngx_http_lua_ffi_ssl_get_tls1_version(ngx_http_request_t *r, char **err)
     551             : {
     552             : #ifndef TLS1_get_version
     553             : 
     554             :     *err = "no TLS1 support";
     555             :     return NGX_ERROR;
     556             : 
     557             : #else
     558             : 
     559             :     ngx_ssl_conn_t    *ssl_conn;
     560             : 
     561           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     562           0 :         *err = "bad request";
     563           0 :         return NGX_ERROR;
     564             :     }
     565             : 
     566           0 :     ssl_conn = r->connection->ssl->connection;
     567           0 :     if (ssl_conn == NULL) {
     568           0 :         *err = "bad ssl conn";
     569           0 :         return NGX_ERROR;
     570             :     }
     571             : 
     572             :     dd("tls1 ver: %d", (int) TLS1_get_version(ssl_conn));
     573             : 
     574           0 :     return (int) TLS1_get_version(ssl_conn);
     575             : 
     576             : #endif
     577             : }
     578             : 
     579             : 
     580             : int
     581           0 : ngx_http_lua_ffi_ssl_clear_certs(ngx_http_request_t *r, char **err)
     582             : {
     583             : #ifdef LIBRESSL_VERSION_NUMBER
     584             : 
     585             :     *err = "LibreSSL not supported";
     586             :     return NGX_ERROR;
     587             : 
     588             : #else
     589             : 
     590             : #   if OPENSSL_VERSION_NUMBER < 0x1000205fL
     591             : 
     592             :     *err = "at least OpenSSL 1.0.2e required but found " OPENSSL_VERSION_TEXT;
     593             :     return NGX_ERROR;
     594             : 
     595             : #   else
     596             : 
     597             :     ngx_ssl_conn_t    *ssl_conn;
     598             : 
     599           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     600           0 :         *err = "bad request";
     601           0 :         return NGX_ERROR;
     602             :     }
     603             : 
     604           0 :     ssl_conn = r->connection->ssl->connection;
     605           0 :     if (ssl_conn == NULL) {
     606           0 :         *err = "bad ssl conn";
     607           0 :         return NGX_ERROR;
     608             :     }
     609             : 
     610           0 :     SSL_certs_clear(ssl_conn);
     611           0 :     return NGX_OK;
     612             : 
     613             : #   endif  /* OPENSSL_VERSION_NUMBER < 0x1000205fL */
     614             : #endif
     615             : }
     616             : 
     617             : 
     618             : int
     619           0 : ngx_http_lua_ffi_ssl_set_der_certificate(ngx_http_request_t *r,
     620             :     const char *data, size_t len, char **err)
     621             : {
     622             : #ifdef LIBRESSL_VERSION_NUMBER
     623             : 
     624             :     *err = "LibreSSL not supported";
     625             :     return NGX_ERROR;
     626             : 
     627             : #else
     628             : 
     629             : #   if OPENSSL_VERSION_NUMBER < 0x1000205fL
     630             : 
     631             :     *err = "at least OpenSSL 1.0.2e required but found " OPENSSL_VERSION_TEXT;
     632             :     return NGX_ERROR;
     633             : 
     634             : #   else
     635             : 
     636           0 :     BIO               *bio = NULL;
     637           0 :     X509              *x509 = NULL;
     638             :     ngx_ssl_conn_t    *ssl_conn;
     639             : 
     640           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     641           0 :         *err = "bad request";
     642           0 :         return NGX_ERROR;
     643             :     }
     644             : 
     645           0 :     ssl_conn = r->connection->ssl->connection;
     646           0 :     if (ssl_conn == NULL) {
     647           0 :         *err = "bad ssl conn";
     648           0 :         return NGX_ERROR;
     649             :     }
     650             : 
     651           0 :     bio = BIO_new_mem_buf((char *) data, len);
     652           0 :     if (bio == NULL) {
     653           0 :         *err = "BIO_new_mem_buf() failed";
     654           0 :         goto failed;
     655             :     }
     656             : 
     657           0 :     x509 = d2i_X509_bio(bio, NULL);
     658           0 :     if (x509 == NULL) {
     659           0 :         *err = "d2i_X509_bio() failed";
     660           0 :         goto failed;
     661             :     }
     662             : 
     663           0 :     if (SSL_use_certificate(ssl_conn, x509) == 0) {
     664           0 :         *err = "SSL_use_certificate() failed";
     665           0 :         goto failed;
     666             :     }
     667             : 
     668             : #if 0
     669             :     if (SSL_set_ex_data(ssl_conn, ngx_ssl_certificate_index, x509) == 0) {
     670             :         *err = "SSL_set_ex_data() failed";
     671             :         goto failed;
     672             :     }
     673             : #endif
     674             : 
     675           0 :     X509_free(x509);
     676           0 :     x509 = NULL;
     677             : 
     678             :     /* read rest of the chain */
     679             : 
     680           0 :     while (!BIO_eof(bio)) {
     681             : 
     682           0 :         x509 = d2i_X509_bio(bio, NULL);
     683           0 :         if (x509 == NULL) {
     684           0 :             *err = "d2i_X509_bio() failed";
     685           0 :             goto failed;
     686             :         }
     687             : 
     688           0 :         if (SSL_add0_chain_cert(ssl_conn, x509) == 0) {
     689           0 :             *err = "SSL_add0_chain_cert() failed";
     690           0 :             goto failed;
     691             :         }
     692             :     }
     693             : 
     694           0 :     BIO_free(bio);
     695             : 
     696           0 :     *err = NULL;
     697           0 :     return NGX_OK;
     698             : 
     699           0 : failed:
     700             : 
     701           0 :     if (bio) {
     702           0 :         BIO_free(bio);
     703             :     }
     704             : 
     705           0 :     if (x509) {
     706           0 :         X509_free(x509);
     707             :     }
     708             : 
     709           0 :     ERR_clear_error();
     710             : 
     711           0 :     return NGX_ERROR;
     712             : 
     713             : #   endif  /* OPENSSL_VERSION_NUMBER < 0x1000205fL */
     714             : #endif
     715             : }
     716             : 
     717             : 
     718             : int
     719           0 : ngx_http_lua_ffi_ssl_set_der_private_key(ngx_http_request_t *r,
     720             :     const char *data, size_t len, char **err)
     721             : {
     722           0 :     BIO               *bio = NULL;
     723           0 :     EVP_PKEY          *pkey = NULL;
     724             :     ngx_ssl_conn_t    *ssl_conn;
     725             : 
     726           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     727           0 :         *err = "bad request";
     728           0 :         return NGX_ERROR;
     729             :     }
     730             : 
     731           0 :     ssl_conn = r->connection->ssl->connection;
     732           0 :     if (ssl_conn == NULL) {
     733           0 :         *err = "bad ssl conn";
     734           0 :         return NGX_ERROR;
     735             :     }
     736             : 
     737           0 :     bio = BIO_new_mem_buf((char *) data, len);
     738           0 :     if (bio == NULL) {
     739           0 :         *err = "BIO_new_mem_buf() failed";
     740           0 :         goto failed;
     741             :     }
     742             : 
     743           0 :     pkey = d2i_PrivateKey_bio(bio, NULL);
     744           0 :     if (pkey == NULL) {
     745           0 :         *err = "d2i_PrivateKey_bio() failed";
     746           0 :         goto failed;
     747             :     }
     748             : 
     749           0 :     if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) {
     750           0 :         *err = "SSL_CTX_use_PrivateKey() failed";
     751           0 :         goto failed;
     752             :     }
     753             : 
     754           0 :     EVP_PKEY_free(pkey);
     755           0 :     BIO_free(bio);
     756             : 
     757           0 :     return NGX_OK;
     758             : 
     759           0 : failed:
     760             : 
     761           0 :     if (pkey) {
     762           0 :         EVP_PKEY_free(pkey);
     763             :     }
     764             : 
     765           0 :     if (bio) {
     766           0 :         BIO_free(bio);
     767             :     }
     768             : 
     769           0 :     ERR_clear_error();
     770             : 
     771           0 :     return NGX_ERROR;
     772             : }
     773             : 
     774             : 
     775             : int
     776           0 : ngx_http_lua_ffi_ssl_raw_server_addr(ngx_http_request_t *r, char **addr,
     777             :     size_t *addrlen, int *addrtype, char **err)
     778             : {
     779             : #if (NGX_HAVE_UNIX_DOMAIN)
     780             :     struct sockaddr_un   *saun;
     781             : #endif
     782             :     ngx_ssl_conn_t       *ssl_conn;
     783             :     ngx_connection_t     *c;
     784             :     struct sockaddr_in   *sin;
     785             : #if (NGX_HAVE_INET6)
     786             :     struct sockaddr_in6  *sin6;
     787             : #endif
     788             : 
     789           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     790           0 :         *err = "bad request";
     791           0 :         return NGX_ERROR;
     792             :     }
     793             : 
     794           0 :     ssl_conn = r->connection->ssl->connection;
     795           0 :     if (ssl_conn == NULL) {
     796           0 :         *err = "bad ssl conn";
     797           0 :         return NGX_ERROR;
     798             :     }
     799             : 
     800           0 :     c = ngx_ssl_get_connection(ssl_conn);
     801             : 
     802           0 :     if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
     803           0 :         return 0;
     804             :     }
     805             : 
     806           0 :     switch (c->local_sockaddr->sa_family) {
     807             : 
     808             : #if (NGX_HAVE_INET6)
     809           0 :     case AF_INET6:
     810           0 :         sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
     811           0 :         *addrlen = 16;
     812           0 :         *addr = (char *) &sin6->sin6_addr.s6_addr;
     813           0 :         *addrtype = NGX_HTTP_LUA_ADDR_TYPE_INET6;
     814             : 
     815           0 :         break;
     816             : #endif
     817             : 
     818             : #if (NGX_HAVE_UNIX_DOMAIN)
     819           0 :     case AF_UNIX:
     820           0 :         saun = (struct sockaddr_un *) c->local_sockaddr;
     821             : 
     822             :         /* on Linux sockaddr might not include sun_path at all */
     823           0 :         if (c->local_socklen <= (socklen_t)
     824             :             offsetof(struct sockaddr_un, sun_path))
     825             :         {
     826           0 :             *addr = "";
     827           0 :             *addrlen = 0;
     828             : 
     829             :         } else {
     830           0 :             *addr = saun->sun_path;
     831           0 :             *addrlen = ngx_strlen(saun->sun_path);
     832             :         }
     833             : 
     834           0 :         *addrtype = NGX_HTTP_LUA_ADDR_TYPE_UNIX;
     835           0 :         break;
     836             : #endif
     837             : 
     838           0 :     default: /* AF_INET */
     839           0 :         sin = (struct sockaddr_in *) c->local_sockaddr;
     840           0 :         *addr = (char *) &sin->sin_addr.s_addr;
     841           0 :         *addrlen = 4;
     842           0 :         *addrtype = NGX_HTTP_LUA_ADDR_TYPE_INET;
     843           0 :         break;
     844             :     }
     845             : 
     846           0 :     return NGX_OK;
     847             : }
     848             : 
     849             : 
     850             : int
     851           0 : ngx_http_lua_ffi_ssl_server_name(ngx_http_request_t *r, char **name,
     852             :     size_t *namelen, char **err)
     853             : {
     854             :     ngx_ssl_conn_t          *ssl_conn;
     855             : 
     856           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
     857           0 :         *err = "bad request";
     858           0 :         return NGX_ERROR;
     859             :     }
     860             : 
     861           0 :     ssl_conn = r->connection->ssl->connection;
     862           0 :     if (ssl_conn == NULL) {
     863           0 :         *err = "bad ssl conn";
     864           0 :         return NGX_ERROR;
     865             :     }
     866             : 
     867             : #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
     868             : 
     869           0 :     *name = (char *) SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
     870             : 
     871           0 :     if (*name) {
     872           0 :         *namelen = ngx_strlen(*name);
     873           0 :         return NGX_OK;
     874             :     }
     875             : 
     876           0 :     return NGX_DECLINED;
     877             : 
     878             : #else
     879             : 
     880             :     *err = "no TLS extension support";
     881             :     return NGX_ERROR;
     882             : 
     883             : #endif
     884             : }
     885             : 
     886             : 
     887             : int
     888           0 : ngx_http_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len, u_char *der,
     889             :     char **err)
     890             : {
     891             :     int       total, len;
     892             :     BIO      *bio;
     893             :     X509     *x509;
     894             :     u_long    n;
     895             : 
     896           0 :     bio = BIO_new_mem_buf((char *) pem, (int) pem_len);
     897           0 :     if (bio == NULL) {
     898           0 :         *err = "BIO_new_mem_buf() failed";
     899           0 :         ERR_clear_error();
     900           0 :         return NGX_ERROR;
     901             :     }
     902             : 
     903           0 :     x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
     904           0 :     if (x509 == NULL) {
     905           0 :         *err = "PEM_read_bio_X509_AUX() failed";
     906           0 :         BIO_free(bio);
     907           0 :         ERR_clear_error();
     908           0 :         return NGX_ERROR;
     909             :     }
     910             : 
     911           0 :     total = i2d_X509(x509, &der);
     912           0 :     if (total < 0) {
     913           0 :         *err = "i2d_X509() failed";
     914           0 :         X509_free(x509);
     915           0 :         BIO_free(bio);
     916           0 :         ERR_clear_error();
     917           0 :         return NGX_ERROR;
     918             :     }
     919             : 
     920           0 :     X509_free(x509);
     921             : 
     922             :     /* read rest of the chain */
     923             : 
     924             :     for ( ;; ) {
     925             : 
     926           0 :         x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
     927           0 :         if (x509 == NULL) {
     928           0 :             n = ERR_peek_last_error();
     929             : 
     930           0 :             if (ERR_GET_LIB(n) == ERR_LIB_PEM
     931           0 :                 && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
     932             :             {
     933             :                 /* end of file */
     934           0 :                 ERR_clear_error();
     935           0 :                 break;
     936             :             }
     937             : 
     938             :             /* some real error */
     939             : 
     940           0 :             *err = "PEM_read_bio_X509() failed";
     941           0 :             BIO_free(bio);
     942           0 :             ERR_clear_error();
     943           0 :             return NGX_ERROR;
     944             :         }
     945             : 
     946           0 :         len = i2d_X509(x509, &der);
     947           0 :         if (len < 0) {
     948           0 :             *err = "i2d_X509() failed";
     949           0 :             X509_free(x509);
     950           0 :             BIO_free(bio);
     951           0 :             ERR_clear_error();
     952           0 :             return NGX_ERROR;
     953             :         }
     954             : 
     955           0 :         total += len;
     956             : 
     957           0 :         X509_free(x509);
     958             :     }
     959             : 
     960           0 :     BIO_free(bio);
     961             : 
     962           0 :     return total;
     963             : }
     964             : 
     965             : 
     966             : int
     967           0 : ngx_http_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len,
     968             :     u_char *der, char **err)
     969             : {
     970             :     int          len;
     971             :     BIO         *in;
     972             :     EVP_PKEY    *pkey;
     973             : 
     974           0 :     in = BIO_new_mem_buf((char *) pem, (int) pem_len);
     975           0 :     if (in == NULL) {
     976           0 :         *err = "BIO_new_mem_buf() failed";
     977           0 :         ERR_clear_error();
     978           0 :         return NGX_ERROR;
     979             :     }
     980             : 
     981           0 :     pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
     982           0 :     if (pkey == NULL) {
     983           0 :         BIO_free(in);
     984           0 :         *err = "PEM_read_bio_PrivateKey() failed";
     985           0 :         ERR_clear_error();
     986           0 :         return NGX_ERROR;
     987             :     }
     988             : 
     989           0 :     BIO_free(in);
     990             : 
     991           0 :     len = i2d_PrivateKey(pkey, &der);
     992           0 :     if (len < 0) {
     993           0 :         EVP_PKEY_free(pkey);
     994           0 :         *err = "i2d_PrivateKey() failed";
     995           0 :         ERR_clear_error();
     996           0 :         return NGX_ERROR;
     997             :     }
     998             : 
     999           0 :     EVP_PKEY_free(pkey);
    1000             : 
    1001           0 :     return len;
    1002             : }
    1003             : 
    1004             : 
    1005             : void *
    1006           0 : ngx_http_lua_ffi_parse_pem_cert(const u_char *pem, size_t pem_len,
    1007             :     char **err)
    1008             : {
    1009             :     BIO             *bio;
    1010             :     X509            *x509;
    1011             :     u_long           n;
    1012             :     STACK_OF(X509)  *chain;
    1013             : 
    1014           0 :     bio = BIO_new_mem_buf((char *) pem, (int) pem_len);
    1015           0 :     if (bio == NULL) {
    1016           0 :         *err = "BIO_new_mem_buf() failed";
    1017           0 :         ERR_clear_error();
    1018           0 :         return NULL;
    1019             :     }
    1020             : 
    1021           0 :     x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
    1022           0 :     if (x509 == NULL) {
    1023           0 :         *err = "PEM_read_bio_X509_AUX() failed";
    1024           0 :         BIO_free(bio);
    1025           0 :         ERR_clear_error();
    1026           0 :         return NULL;
    1027             :     }
    1028             : 
    1029           0 :     chain = sk_X509_new_null();
    1030           0 :     if (chain == NULL) {
    1031           0 :         *err = "sk_X509_new_null() failed";
    1032           0 :         X509_free(x509);
    1033           0 :         BIO_free(bio);
    1034           0 :         ERR_clear_error();
    1035           0 :         return NULL;
    1036             :     }
    1037             : 
    1038           0 :     if (sk_X509_push(chain, x509) == 0) {
    1039           0 :         *err = "sk_X509_push() failed";
    1040           0 :         sk_X509_free(chain);
    1041           0 :         X509_free(x509);
    1042           0 :         BIO_free(bio);
    1043           0 :         ERR_clear_error();
    1044           0 :         return NULL;
    1045             :     }
    1046             : 
    1047             :     /* read rest of the chain */
    1048             : 
    1049             :     for ( ;; ) {
    1050             : 
    1051           0 :         x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
    1052           0 :         if (x509 == NULL) {
    1053           0 :             n = ERR_peek_last_error();
    1054             : 
    1055           0 :             if (ERR_GET_LIB(n) == ERR_LIB_PEM
    1056           0 :                 && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
    1057             :             {
    1058             :                 /* end of file */
    1059           0 :                 ERR_clear_error();
    1060           0 :                 break;
    1061             :             }
    1062             : 
    1063             :             /* some real error */
    1064             : 
    1065           0 :             *err = "PEM_read_bio_X509() failed";
    1066           0 :             sk_X509_pop_free(chain, X509_free);
    1067           0 :             BIO_free(bio);
    1068           0 :             ERR_clear_error();
    1069           0 :             return NULL;
    1070             :         }
    1071             : 
    1072           0 :         if (sk_X509_push(chain, x509) == 0) {
    1073           0 :             *err = "sk_X509_push() failed";
    1074           0 :             sk_X509_pop_free(chain, X509_free);
    1075           0 :             X509_free(x509);
    1076           0 :             BIO_free(bio);
    1077           0 :             ERR_clear_error();
    1078           0 :             return NULL;
    1079             :         }
    1080             :     }
    1081             : 
    1082           0 :     BIO_free(bio);
    1083             : 
    1084           0 :     return chain;
    1085             : }
    1086             : 
    1087             : 
    1088             : void
    1089           0 : ngx_http_lua_ffi_free_cert(void *cdata)
    1090             : {
    1091           0 :     STACK_OF(X509)  *chain = cdata;
    1092             : 
    1093           0 :     sk_X509_pop_free(chain, X509_free);
    1094           0 : }
    1095             : 
    1096             : 
    1097             : void *
    1098           0 : ngx_http_lua_ffi_parse_pem_priv_key(const u_char *pem, size_t pem_len,
    1099             :     char **err)
    1100             : {
    1101             :     BIO         *in;
    1102             :     EVP_PKEY    *pkey;
    1103             : 
    1104           0 :     in = BIO_new_mem_buf((char *) pem, (int) pem_len);
    1105           0 :     if (in == NULL) {
    1106           0 :         *err = "BIO_new_mem_buf() failed";
    1107           0 :         ERR_clear_error();
    1108           0 :         return NULL;
    1109             :     }
    1110             : 
    1111           0 :     pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
    1112           0 :     if (pkey == NULL) {
    1113           0 :         *err = "PEM_read_bio_PrivateKey() failed";
    1114           0 :         BIO_free(in);
    1115           0 :         ERR_clear_error();
    1116           0 :         return NULL;
    1117             :     }
    1118             : 
    1119           0 :     BIO_free(in);
    1120             : 
    1121           0 :     return pkey;
    1122             : }
    1123             : 
    1124             : 
    1125             : void
    1126           0 : ngx_http_lua_ffi_free_priv_key(void *cdata)
    1127             : {
    1128           0 :     EVP_PKEY *pkey = cdata;
    1129             : 
    1130           0 :     EVP_PKEY_free(pkey);
    1131           0 : }
    1132             : 
    1133             : 
    1134             : int
    1135           0 : ngx_http_lua_ffi_set_cert(ngx_http_request_t *r,
    1136             :     void *cdata, char **err)
    1137             : {
    1138             : #ifdef LIBRESSL_VERSION_NUMBER
    1139             : 
    1140             :     *err = "LibreSSL not supported";
    1141             :     return NGX_ERROR;
    1142             : 
    1143             : #else
    1144             : 
    1145             : #   if OPENSSL_VERSION_NUMBER < 0x1000205fL
    1146             : 
    1147             :     *err = "at least OpenSSL 1.0.2e required but found " OPENSSL_VERSION_TEXT;
    1148             :     return NGX_ERROR;
    1149             : 
    1150             : #   else
    1151             : 
    1152             : #ifdef OPENSSL_IS_BORINGSSL
    1153             :     size_t             i;
    1154             : #else
    1155             :     int                i;
    1156             : #endif
    1157           0 :     X509              *x509 = NULL;
    1158             :     ngx_ssl_conn_t    *ssl_conn;
    1159           0 :     STACK_OF(X509)    *chain = cdata;
    1160             : 
    1161           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
    1162           0 :         *err = "bad request";
    1163           0 :         return NGX_ERROR;
    1164             :     }
    1165             : 
    1166           0 :     ssl_conn = r->connection->ssl->connection;
    1167           0 :     if (ssl_conn == NULL) {
    1168           0 :         *err = "bad ssl conn";
    1169           0 :         return NGX_ERROR;
    1170             :     }
    1171             : 
    1172           0 :     if (sk_X509_num(chain) < 1) {
    1173           0 :         *err = "invalid certificate chain";
    1174           0 :         goto failed;
    1175             :     }
    1176             : 
    1177           0 :     x509 = sk_X509_value(chain, 0);
    1178           0 :     if (x509 == NULL) {
    1179           0 :         *err = "sk_X509_value() failed";
    1180           0 :         goto failed;
    1181             :     }
    1182             : 
    1183           0 :     if (SSL_use_certificate(ssl_conn, x509) == 0) {
    1184           0 :         *err = "SSL_use_certificate() failed";
    1185           0 :         goto failed;
    1186             :     }
    1187             : 
    1188           0 :     x509 = NULL;
    1189             : 
    1190             :     /* read rest of the chain */
    1191             : 
    1192           0 :     for (i = 1; i < sk_X509_num(chain); i++) {
    1193             : 
    1194           0 :         x509 = sk_X509_value(chain, i);
    1195           0 :         if (x509 == NULL) {
    1196           0 :             *err = "sk_X509_value() failed";
    1197           0 :             goto failed;
    1198             :         }
    1199             : 
    1200           0 :         if (SSL_add1_chain_cert(ssl_conn, x509) == 0) {
    1201           0 :             *err = "SSL_add1_chain_cert() failed";
    1202           0 :             goto failed;
    1203             :         }
    1204             :     }
    1205             : 
    1206           0 :     *err = NULL;
    1207           0 :     return NGX_OK;
    1208             : 
    1209           0 : failed:
    1210             : 
    1211           0 :     ERR_clear_error();
    1212             : 
    1213           0 :     return NGX_ERROR;
    1214             : 
    1215             : #   endif  /* OPENSSL_VERSION_NUMBER < 0x1000205fL */
    1216             : #endif
    1217             : }
    1218             : 
    1219             : 
    1220             : int
    1221           0 : ngx_http_lua_ffi_set_priv_key(ngx_http_request_t *r,
    1222             :     void *cdata, char **err)
    1223             : {
    1224           0 :     EVP_PKEY          *pkey = NULL;
    1225             :     ngx_ssl_conn_t    *ssl_conn;
    1226             : 
    1227           0 :     if (r->connection == NULL || r->connection->ssl == NULL) {
    1228           0 :         *err = "bad request";
    1229           0 :         return NGX_ERROR;
    1230             :     }
    1231             : 
    1232           0 :     ssl_conn = r->connection->ssl->connection;
    1233           0 :     if (ssl_conn == NULL) {
    1234           0 :         *err = "bad ssl conn";
    1235           0 :         return NGX_ERROR;
    1236             :     }
    1237             : 
    1238           0 :     pkey = cdata;
    1239           0 :     if (pkey == NULL) {
    1240           0 :         *err = "invalid private key failed";
    1241           0 :         goto failed;
    1242             :     }
    1243             : 
    1244           0 :     if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) {
    1245           0 :         *err = "SSL_use_PrivateKey() failed";
    1246           0 :         goto failed;
    1247             :     }
    1248             : 
    1249           0 :     return NGX_OK;
    1250             : 
    1251           0 : failed:
    1252             : 
    1253           0 :     ERR_clear_error();
    1254             : 
    1255           0 :     return NGX_ERROR;
    1256             : }
    1257             : 
    1258             : 
    1259             : #endif  /* NGX_LUA_NO_FFI_API */
    1260             : 
    1261             : 
    1262             : #endif /* NGX_HTTP_SSL */

Generated by: LCOV version 1.13