The patch of Nginx SSL: PEM pass phrase problem

James_Lee nginx-forum at nginx.us
Tue Jul 31 14:30:55 UTC 2012


I'am very glad that this patch is useful for you.
The below is the patch or the diff. It's based on the nginx 0.8.54 or
nginx 0.8.55.
Perhaps it also works for other version. Maybe you need to merge it by
hand.


Index: src/http/modules/ngx_http_ssl_module.c
===================================================================
--- src/http/modules/ngx_http_ssl_module.c	(revision 347)
+++ src/http/modules/ngx_http_ssl_module.c	(revision 348)
@@ -14,6 +14,7 @@
 
 
 #define NGX_DEFAULT_CIPHERS  "HIGH:!ADH:!MD5"
+#define PASS_PHRASE_ARG_LEN  255
 
 
 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
@@ -31,6 +32,11 @@
 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t
*cmd,
     void *conf);
 
+static int ngx_enhanced_system(char* cmdstring, char* buf, int len);
+static int ngx_http_ssl_pass_phase_callback(char *buf, int bufsize,
+    int verify, void *srv);
+static char *ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf,
+    ngx_command_t *cmd, void *conf);
 
 static ngx_conf_bitmask_t  ngx_http_ssl_protocols[] = {
     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
@@ -141,6 +147,13 @@
       offsetof(ngx_http_ssl_srv_conf_t, crl),
       NULL },
 
+    { ngx_string("ssl_pass_phrase_dialog"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_pass_phrase_dialog,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, pass_phrase_conf),
+      NULL },
+
       ngx_null_command
 };
 
@@ -213,6 +226,124 @@
 static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
 
 
+static char *
+ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
+{
+    char             *p = conf;
+    ngx_str_t        *field, *value;
+    int               len;
+
+    field = (ngx_str_t *) (p + cmd->offset);
+
+    if (field->data) {
+        return "is duplicate";
+    }
+
+    value = cf->args->elts;
+
+    *field = value[1];
+
+    if (field->len == 0) {
+        return NGX_CONF_OK;
+    } else if (field->len > PASS_PHRASE_ARG_LEN) {
+        len = PASS_PHRASE_ARG_LEN;
+
+        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+            "The length of ssl_pass_phrase_dialog argument is more than
%d", len);
+
+        return NGX_CONF_ERROR;
+    }
+
+    return NGX_CONF_OK;
+}
+
+static int
+ngx_http_ssl_pass_phase_callback(char *buf, int bufsize, int verify,
void *srv)
+{
+    ngx_str_t    pass_phase_file;
+    int          ret;
+    char         cmdline[PASS_PHRASE_ARG_LEN + 1] = {0};
+
+    ngx_http_ssl_srv_conf_t * conf = srv;
+
+    /* get the executable file path */
+    pass_phase_file.data = conf->pass_phrase_conf.data + 5;
+    pass_phase_file.len = conf->pass_phrase_conf.len - 5;
+
+    ngx_memcpy(cmdline, pass_phase_file.data, pass_phase_file.len);
+    cmdline[pass_phase_file.len] = '\0';
+
+    ret = ngx_enhanced_system(cmdline, buf, bufsize);
+    if (ret != 0) {
+        return -1;
+    }
+
+    /* To support echo command in Linux, Unix shell */
+    if (buf[strlen(buf) - 1] == '\n') {
+        buf[strlen(buf) - 1] = '\0';
+    }
+
+    return strlen(buf);
+}
+
+/**
+* ngx_enhanced_system()
+*
+* @param[in] cmdstring : External command(executable or shell)
+* @param[out] buf : The buffer to store the result of the external
command.
+* @param[in] len : The length of the buffer.
+*
+* @return  0: success   -1: fail
+*/
+static int
+ngx_enhanced_system(char* cmdstring, char* buf, int len)
+{
+    int     fd[2];
+    pid_t   pid;
+    int     n, count;
+
+    memset(buf, 0, len);
+
+    if (pipe(fd) < 0) {
+        return -1;
+    }
+
+    if ((pid = fork()) < 0) {
+        return -1;
+    } else if (pid > 0) {    /* parent process */
+        close(fd[1]);        /* close write end */
+        count = 0;
+
+        while ((n = read(fd[0], buf + count, len)) > 0
+        && count > len) {
+            count += n;
+        }
+
+        close(fd[0]);
+
+        if (waitpid(pid, NULL, 0) != pid) {
+            return -1;
+        }
+
+    } else {              /* child process */
+        close(fd[0]);     /* close read end */
+
+        if (fd[1] != STDOUT_FILENO) {
+            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
+                return -1;
+            }
+            close(fd[1]);
+        }
+
+        if (execl("/bin/sh", "sh", "-c", cmdstring, (char*)0) == -1) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
 static ngx_int_t
 ngx_http_ssl_static_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
@@ -316,6 +447,8 @@
      *     sscf->crl = { 0, NULL };
      *     sscf->ciphers = { 0, NULL };
      *     sscf->shm_zone = NULL;
+     *
+     *     sscf->pass_phrase_conf = { 0, NULL };
      */
 
     sscf->enable = NGX_CONF_UNSET;
@@ -362,7 +495,9 @@
 
     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers,
NGX_DEFAULT_CIPHERS);
 
+    ngx_conf_merge_str_value(conf->pass_phrase_conf,
prev->pass_phrase_conf, "builtin");
 
+
     conf->ssl.log = cf->log;
 
     if (conf->enable) {
@@ -401,6 +536,18 @@
         return NGX_CONF_ERROR;
     }
 
+    if (ngx_strncasecmp(conf->pass_phrase_conf.data, (u_char*)"exec:",
5) == 0) {
+
+        SSL_CTX_set_default_passwd_cb(conf->ssl.ctx,
ngx_http_ssl_pass_phase_callback);
+
+        SSL_CTX_set_default_passwd_cb_userdata(conf->ssl.ctx, (void
*)conf);
+
+    } else if (ngx_strncasecmp(conf->pass_phrase_conf.data,
(u_char*)"builtin", 7) != 0) {
+        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+            "The arg of ssl_pass_phrase_dialog directive is incorrect:
builtin | exec:path");
+        return NGX_CONF_ERROR;
+    }
+
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
 
     if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
Index: src/http/modules/ngx_http_ssl_module.h
===================================================================
--- src/http/modules/ngx_http_ssl_module.h	(revision 347)
+++ src/http/modules/ngx_http_ssl_module.h	(revision 348)
@@ -41,6 +41,8 @@
 
     u_char                         *file;
     ngx_uint_t                      line;
+
+    ngx_str_t                       pass_phrase_conf;
 } ngx_http_ssl_srv_conf_t;

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,214641,229145#msg-229145



More information about the nginx mailing list