NOEXPORT int load_key_engine(SERVICE_OPTIONS *section) {
    int i;
    EVP_PKEY *pkey;

    s_log(LOG_INFO, "Initializing private key on engine ID: %s", section->key);

    /* do not use caching for engine PINs to prevent device lockout */
    SSL_CTX_set_default_passwd_cb(section->ctx, ui_passwd_cb);

    for(i=0; i<3; i++) {
        pkey=ENGINE_load_private_key(section->engine, section->key,
            UI_stunnel(), NULL);
        if(!pkey) {
            if(i<2 && ui_retry()) { /* wrong PIN */
                sslerror_queue(); /* dump the error queue */
                s_log(LOG_ERR, "Wrong PIN: retrying");
                continue;
            }
            sslerror("ENGINE_load_private_key");
            return 1; /* FAILED */
        }
        if(SSL_CTX_use_PrivateKey(section->ctx, pkey))
            break; /* success */
        sslerror("SSL_CTX_use_PrivateKey");
        return 1; /* FAILED */
    }
    s_log(LOG_INFO, "Private key initialized on engine ID: %s", section->key);
    return 0; /* OK */
}
NOEXPORT int load_key_engine(SERVICE_OPTIONS *section) {
    int i;
    EVP_PKEY *pkey;

    s_log(LOG_INFO, "Initializing private key on engine ID: %s", section->key);

     
    SSL_CTX_set_default_passwd_cb(section->ctx, ui_passwd_cb);

    for(i=0; i<3; i++) {
        pkey=ENGINE_load_private_key(section->engine, section->key,
            UI_stunnel(), NULL);
        if(!pkey) {
            if(i<2 && ui_retry()) {  
                sslerror_queue();  
                s_log(LOG_ERR, "Wrong PIN: retrying");
                continue;
            }
            sslerror("ENGINE_load_private_key");
            return 1;  
        }
        if(SSL_CTX_use_PrivateKey(section->ctx, pkey))
            break;  
        sslerror("SSL_CTX_use_PrivateKey");
        return 1;  
    }
    s_log(LOG_INFO, "Private key initialized on engine ID: %s", section->key);
    return 0;  
}