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

Dmitrii Pichulin pdn at cryptopro.ru
Fri Aug 1 05:20:02 UTC 2014


On 31.07.2014 17:49, Maxim Dounin wrote:
 >> + if (engine == NULL) {
 >> + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
 >> + "ENGINE_by_id(\"%s\") failed", p);
 >> + return NGX_ERROR;
 >> + }
 >> +
 >> + p[last - p] = ':';
 >> +
 >> + if (passwords) {
 >> + pwd = passwords->elts;
 >> +
 >> + ngx_cpystrn(pwd_buf, pwd->data, pwd->len + 1);
 >> +
 >> + pwd_data.password = pwd_buf;
 >> + } else {
 >> + pwd_data.password = NULL;
 >> + }
 >> + pwd_data.prompt_info = NULL;
 >> +
 >> + last++;
 >> +
 >> + private_key = ENGINE_load_private_key(engine, last, 0,
 >> + (void *) &pwd_data);
 > I don't see how it's expected to work. You only pass private data
 > for UI callbacks, but not callbacks itself.
 >
 > Anyway, proper implementation of passing key passwords into an engine
 > seems to be rather big, and as per my reading of the code under
 > crypto/engine won't work with most of the engines anyway. It
 > might be better idea to don't try to do this for now.

Maxim, our vision is based on 2 implementations of engines as previously 
noted:
1) gost_capi — doesn't support external passwords
2) opensc — with such code from get_pin function 
(https://github.com/OpenSC/engine_pkcs11/blob/master/src/engine_pkcs11.c):

/* either get the pin code from the supplied callback data, or get the pin
* via asking our self. In both cases keep a copy of the pin code in the
* pin variable (strdup'ed copy). */
static int get_pin(UI_METHOD * ui_method, void *callback_data)
{
UI *ui;
struct {
const void *password;
const char *prompt_info;
} *mycb = callback_data;

/* pin in the call back data, copy and use */
if (mycb != NULL && mycb->password) {
pin = (char *)calloc(MAX_PIN_LENGTH, sizeof(char));
if (!pin)
return 0;
strncpy(pin,mycb->password,MAX_PIN_LENGTH);
pin_length = MAX_PIN_LENGTH;
return 1;
}
...

As you can see, there's no need for ui_method if a password is present.

We suggest to implement something like this:

typedef struct {
const void *password;
const char *prompt_info;
ngx_array_t *passwords;
ngx_uint_t position;
} ngx_openssl_pw_cb_data_ex;

In this case, our ui_read implementation can run through all passwords, 
while supporting the basics.

Or it would be better to pass nothing for now?



More information about the nginx-devel mailing list