[PATCH] allow to use engine keyform for server private key

Maxim Dounin mdounin at mdounin.ru
Mon Jul 28 02:43:38 UTC 2014


Hello!

On Wed, Jul 23, 2014 at 06:58:23PM +0400, Dmitrii Pichulin wrote:

> # HG changeset patch
> # User Dmitrii Pichulin
> # Date 1406127158 -14400
> #      Wed Jul 23 18:52:38 2014 +0400
> # Node ID fec1d814c8f363976a1217c81faec3d80e6c718f
> # Parent  9de5820bb3e04d7e21727b472a15831ec0b2be1d
> allow to use engine keyform for server private key
> 
> diff -r 9de5820bb3e0 -r fec1d814c8f3 src/event/ngx_event_openssl.c
> --- a/src/event/ngx_event_openssl.c	Fri Jul 18 20:11:40 2014 +0400
> +++ b/src/event/ngx_event_openssl.c	Wed Jul 23 18:52:38 2014 +0400
> @@ -11,6 +11,7 @@
>  
>  
>  #define NGX_SSL_PASSWORD_BUFFER_SIZE  4096
> +#define NGX_SSL_MAX_ENGINE_NAME_LEN   260
>  
>  
>  typedef struct {
> @@ -270,6 +271,10 @@
>      u_long       n;
>      ngx_str_t   *pwd;
>      ngx_uint_t   tries;
> +    EVP_PKEY    *pkey;
> +    ENGINE      *e;
> +    char        *p, *last;
> +    char         e_name[NGX_SSL_MAX_ENGINE_NAME_LEN + 1];

This doesn't match style used in nginx code.
Both declaration order and variable names should be different.

>  
>      if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
>          return NGX_ERROR;
> @@ -352,6 +357,61 @@
>  
>      BIO_free(bio);
>  
> +    if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) {
> +
> +        p = (char *) key->data + sizeof("engine:") - 1;
> +        last = ngx_strchr(p, ':');
> +
> +        if (last == NULL || ngx_strchr(last + 1, ':') != NULL) {

Why key id shouldn't contain colons?  This restriction on key id 
looks strange.

> +            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid syntax: %V", key);
> +            return NGX_ERROR;
> +        }
> +
> +        if (last - p > NGX_SSL_MAX_ENGINE_NAME_LEN) {
> +            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
> +                          "too long engine name in \"ssl_certificate_key\"");
> +            return NGX_ERROR;
> +        }
> +
> +        ngx_memcpy(e_name, p, last - p);
> +        e_name[last - p] = 0;

It should be fine to assume we can modify the key name passed, and 
just set ':' to '\0' instead of using a fixed-size buffer.

> +
> +        e = ENGINE_by_id((char *) e_name);
> +
> +        if (e == NULL) {
> +            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
> +                          "ENGINE_by_id(\"%s\") failed", e_name);
> +            return NGX_ERROR;
> +        }
> +
> +        pkey = ENGINE_load_private_key(e, (char *) last + 1, 0, 0);

It looks like ENGINE_load_private_key() may need to ask user for a 
password.  The ssl_password_file should be respected here as well.

> +
> +        if (!pkey) {
> +            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
> +                          "ENGINE_load_private_key(\"%s\") failed", last + 1);
> +            ENGINE_free(e);
> +            return NGX_ERROR;
> +        }
> +
> +        if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
> +
> +            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
> +                       "SSL_CTX_use_PrivateKey_file(\"%s\") failed", last + 1);

I believe I've already pointed out in the previous review that 
it's better to split the line instead of shifting it to the left.

> +            EVP_PKEY_free(pkey);
> +            ENGINE_free(e);
> +            return NGX_ERROR;
> +        }
> +
> +        EVP_PKEY_free(pkey);
> +
> +        if (ENGINE_free(e) == 0) {
> +            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "ENGINE_free() failed");
> +            return NGX_ERROR;
> +        }

Checking ENGINE_free(e) errors in one place but not in others is 
really bad idea.

> +
> +        return NGX_OK;
> +    }
> +
>      if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
>          return NGX_ERROR;
>      }
> 
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel

-- 
Maxim Dounin
http://nginx.org/



More information about the nginx-devel mailing list