diff options
Diffstat (limited to 'lib/crypto/c_src/engine.c')
-rw-r--r-- | lib/crypto/c_src/engine.c | 563 |
1 files changed, 341 insertions, 222 deletions
diff --git a/lib/crypto/c_src/engine.c b/lib/crypto/c_src/engine.c index dc8e1828ce..6692ccd734 100644 --- a/lib/crypto/c_src/engine.c +++ b/lib/crypto/c_src/engine.c @@ -32,6 +32,9 @@ static int get_engine_load_cmd_list(ErlNifEnv* env, const ERL_NIF_TERM term, cha static int zero_terminate(ErlNifBinary bin, char **buf); static void engine_ctx_dtor(ErlNifEnv* env, struct engine_ctx* ctx) { + if (ctx == NULL) + return; + PRINTF_ERR0("engine_ctx_dtor"); if(ctx->id) { PRINTF_ERR1(" non empty ctx->id=%s", ctx->id); @@ -46,37 +49,51 @@ int get_engine_and_key_id(ErlNifEnv *env, ERL_NIF_TERM key, char ** id, ENGINE * struct engine_ctx *ctx; ErlNifBinary key_id_bin; - if (!enif_get_map_value(env, key, atom_engine, &engine_res) || - !enif_get_resource(env, engine_res, engine_ctx_rtype, (void**)&ctx) || - !enif_get_map_value(env, key, atom_key_id, &key_id_term) || - !enif_inspect_binary(env, key_id_term, &key_id_bin)) { - return 0; - } - else { - *e = ctx->engine; - return zero_terminate(key_id_bin, id); - } + if (!enif_get_map_value(env, key, atom_engine, &engine_res)) + goto err; + if (!enif_get_resource(env, engine_res, engine_ctx_rtype, (void**)&ctx)) + goto err; + if (!enif_get_map_value(env, key, atom_key_id, &key_id_term)) + goto err; + if (!enif_inspect_binary(env, key_id_term, &key_id_bin)) + goto err; + + *e = ctx->engine; + return zero_terminate(key_id_bin, id); + + err: + return 0; } char *get_key_password(ErlNifEnv *env, ERL_NIF_TERM key) { ERL_NIF_TERM tmp_term; ErlNifBinary pwd_bin; char *pwd = NULL; - if (enif_get_map_value(env, key, atom_password, &tmp_term) && - enif_inspect_binary(env, tmp_term, &pwd_bin) && - zero_terminate(pwd_bin, &pwd) - ) return pwd; + if (!enif_get_map_value(env, key, atom_password, &tmp_term)) + goto err; + if (!enif_inspect_binary(env, tmp_term, &pwd_bin)) + goto err; + if (!zero_terminate(pwd_bin, &pwd)) + goto err; + + return pwd; + + err: return NULL; } static int zero_terminate(ErlNifBinary bin, char **buf) { - *buf = enif_alloc(bin.size+1); - if (!*buf) - return 0; + if ((*buf = enif_alloc(bin.size + 1)) == NULL) + goto err; + memcpy(*buf, bin.data, bin.size); - *(*buf+bin.size) = 0; + *(*buf + bin.size) = 0; + return 1; + + err: + return 0; } #endif /* HAS_ENGINE_SUPPORT */ @@ -86,49 +103,65 @@ int init_engine_ctx(ErlNifEnv *env) { (ErlNifResourceDtor*) engine_ctx_dtor, ERL_NIF_RT_CREATE|ERL_NIF_RT_TAKEOVER, NULL); - if (engine_ctx_rtype == NULL) { - PRINTF_ERR0("CRYPTO: Could not open resource type 'ENGINE_CTX'"); - return 0; - } + if (engine_ctx_rtype == NULL) + goto err; #endif return 1; + + err: + PRINTF_ERR0("CRYPTO: Could not open resource type 'ENGINE_CTX'"); + return 0; } ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (EngineId) */ #ifdef HAS_ENGINE_SUPPORT - ERL_NIF_TERM ret; + ERL_NIF_TERM ret, result; ErlNifBinary engine_id_bin; - char *engine_id; + char *engine_id = NULL; ENGINE *engine; - struct engine_ctx *ctx; + struct engine_ctx *ctx = NULL; // Get Engine Id - if(!enif_inspect_binary(env, argv[0], &engine_id_bin)) { - PRINTF_ERR0("engine_by_id_nif Leaved: badarg"); - return enif_make_badarg(env); - } else { - engine_id = enif_alloc(engine_id_bin.size+1); - (void) memcpy(engine_id, engine_id_bin.data, engine_id_bin.size); - engine_id[engine_id_bin.size] = '\0'; - } + ASSERT(argc == 1); - engine = ENGINE_by_id(engine_id); - if(!engine) { - enif_free(engine_id); + if (!enif_inspect_binary(env, argv[0], &engine_id_bin)) + goto bad_arg; + + if ((engine_id = enif_alloc(engine_id_bin.size+1)) == NULL) + goto err; + (void) memcpy(engine_id, engine_id_bin.data, engine_id_bin.size); + engine_id[engine_id_bin.size] = '\0'; + + if ((engine = ENGINE_by_id(engine_id)) == NULL) { PRINTF_ERR0("engine_by_id_nif Leaved: {error, bad_engine_id}"); - return enif_make_tuple2(env, atom_error, atom_bad_engine_id); + ret = enif_make_tuple2(env, atom_error, atom_bad_engine_id); + goto done; } - ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx)); + if ((ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx))) == NULL) + goto err; ctx->engine = engine; ctx->id = engine_id; + /* ctx now owns engine_id */ + engine_id = NULL; - ret = enif_make_resource(env, ctx); - enif_release_resource(ctx); + result = enif_make_resource(env, ctx); + ret = enif_make_tuple2(env, atom_ok, result); + goto done; + + bad_arg: + err: + ret = enif_make_badarg(env); + + done: + if (engine_id) + enif_free(engine_id); + if (ctx) + enif_release_resource(ctx); + return ret; - return enif_make_tuple2(env, atom_ok, ret); #else return atom_notsup; #endif @@ -137,21 +170,22 @@ ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ ERL_NIF_TERM engine_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Engine) */ #ifdef HAS_ENGINE_SUPPORT - ERL_NIF_TERM ret = atom_ok; struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_init_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } - if (!ENGINE_init(ctx->engine)) { - //ERR_print_errors_fp(stderr); - PRINTF_ERR0("engine_init_nif Leaved: {error, engine_init_failed}"); + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + + if (!ENGINE_init(ctx->engine)) return enif_make_tuple2(env, atom_error, atom_engine_init_failed); - } - return ret; + return atom_ok; + + bad_arg: + return enif_make_badarg(env); + #else return atom_notsup; #endif @@ -163,13 +197,18 @@ ERL_NIF_TERM engine_free_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_free_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); - ENGINE_free(ctx->engine); + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + + if (!ENGINE_free(ctx->engine)) + goto err; return atom_ok; + + bad_arg: + err: + return enif_make_badarg(env); #else return atom_notsup; #endif @@ -181,13 +220,19 @@ ERL_NIF_TERM engine_finish_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_finish_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; - ENGINE_finish(ctx->engine); + if (!ENGINE_finish(ctx->engine)) + goto err; return atom_ok; + + bad_arg: + err: + return enif_make_badarg(env); + #else return atom_notsup; #endif @@ -196,6 +241,8 @@ ERL_NIF_TERM engine_finish_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv ERL_NIF_TERM engine_load_dynamic_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* () */ #ifdef HAS_ENGINE_SUPPORT + ASSERT(argc == 0); + ENGINE_load_dynamic(); return atom_ok; #else @@ -204,40 +251,40 @@ ERL_NIF_TERM engine_load_dynamic_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER } ERL_NIF_TERM engine_ctrl_cmd_strings_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Engine, Commands) */ +{/* (Engine, Commands, Optional) */ #ifdef HAS_ENGINE_SUPPORT - ERL_NIF_TERM ret = atom_ok; + ERL_NIF_TERM ret; unsigned int cmds_len = 0; char **cmds = NULL; struct engine_ctx *ctx; - int i, optional = 0; + unsigned int i; + int optional = 0; + int cmds_loaded = 0; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_ctrl_cmd_strings_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 3); - PRINTF_ERR1("Engine Id: %s\r\n", ENGINE_get_id(ctx->engine)); + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + PRINTF_ERR1("Engine Id: %s\r\n", ENGINE_get_id(ctx->engine)); // Get Command List - if(!enif_get_list_length(env, argv[1], &cmds_len)) { - PRINTF_ERR0("engine_ctrl_cmd_strings_nif Leaved: Bad Command List"); - return enif_make_badarg(env); - } else { - cmds_len *= 2; // Key-Value list from erlang - cmds = enif_alloc((cmds_len+1)*sizeof(char*)); - if(get_engine_load_cmd_list(env, argv[1], cmds, 0)) { - PRINTF_ERR0("engine_ctrl_cmd_strings_nif Leaved: Couldn't read Command List"); - ret = enif_make_badarg(env); - goto error; - } - } - - if(!enif_get_int(env, argv[2], &optional)) { - PRINTF_ERR0("engine_ctrl_cmd_strings_nif Leaved: Parameter optional not an integer"); - return enif_make_badarg(env); - } + if (!enif_get_list_length(env, argv[1], &cmds_len)) + goto bad_arg; + + if (cmds_len > (UINT_MAX / 2) - 1) + goto err; + cmds_len *= 2; // Key-Value list from erlang + + if ((size_t)cmds_len + 1 > SIZE_MAX / sizeof(char*)) + goto err; + if ((cmds = enif_alloc((cmds_len + 1) * sizeof(char*))) == NULL) + goto err; + if (get_engine_load_cmd_list(env, argv[1], cmds, 0)) + goto err; + cmds_loaded = 1; + if (!enif_get_int(env, argv[2], &optional)) + goto err; for(i = 0; i < cmds_len; i+=2) { PRINTF_ERR2("Cmd: %s:%s\r\n", @@ -247,18 +294,31 @@ ERL_NIF_TERM engine_ctrl_cmd_strings_nif(ErlNifEnv* env, int argc, const ERL_NIF PRINTF_ERR2("Command failed: %s:%s\r\n", cmds[i] ? cmds[i] : "(NULL)", cmds[i+1] ? cmds[i+1] : "(NULL)"); - //ENGINE_free(ctx->engine); - ret = enif_make_tuple2(env, atom_error, atom_ctrl_cmd_failed); - PRINTF_ERR0("engine_ctrl_cmd_strings_nif Leaved: {error, ctrl_cmd_failed}"); - goto error; + goto cmd_failed; } } + ret = atom_ok; + goto done; + + bad_arg: + err: + ret = enif_make_badarg(env); + goto done; + + cmd_failed: + ret = enif_make_tuple2(env, atom_error, atom_ctrl_cmd_failed); + + done: + if (cmds_loaded) { + for (i = 0; cmds != NULL && cmds[i] != NULL; i++) + enif_free(cmds[i]); + } + + if (cmds != NULL) + enif_free(cmds); - error: - for(i = 0; cmds != NULL && cmds[i] != NULL; i++) - enif_free(cmds[i]); - enif_free(cmds); return ret; + #else return atom_notsup; #endif @@ -270,16 +330,22 @@ ERL_NIF_TERM engine_add_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_add_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + + if (!ENGINE_add(ctx->engine)) + goto failed; - if (!ENGINE_add(ctx->engine)) { - PRINTF_ERR0("engine_add_nif Leaved: {error, add_engine_failed}"); - return enif_make_tuple2(env, atom_error, atom_add_engine_failed); - } return atom_ok; + + bad_arg: + return enif_make_badarg(env); + + failed: + return enif_make_tuple2(env, atom_error, atom_add_engine_failed); + #else return atom_notsup; #endif @@ -291,16 +357,21 @@ ERL_NIF_TERM engine_remove_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_remove_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + + if (!ENGINE_remove(ctx->engine)) + goto failed; - if (!ENGINE_remove(ctx->engine)) { - PRINTF_ERR0("engine_remove_nif Leaved: {error, remove_engine_failed}"); - return enif_make_tuple2(env, atom_error, atom_remove_engine_failed); - } return atom_ok; + + bad_arg: + return enif_make_badarg(env); + + failed: + return enif_make_tuple2(env, atom_error, atom_remove_engine_failed); #else return atom_notsup; #endif @@ -313,95 +384,99 @@ ERL_NIF_TERM engine_register_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar unsigned int method; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_register_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } - // Get Method - if (!enif_get_uint(env, argv[1], &method)) { - PRINTF_ERR0("engine_register_nif Leaved: Parameter Method not an uint"); - return enif_make_badarg(env); - } + ASSERT(argc == 2); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + if (!enif_get_uint(env, argv[1], &method)) + goto bad_arg; switch(method) { #ifdef ENGINE_METHOD_RSA case ENGINE_METHOD_RSA: if (!ENGINE_register_RSA(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_DSA case ENGINE_METHOD_DSA: if (!ENGINE_register_DSA(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_DH case ENGINE_METHOD_DH: if (!ENGINE_register_DH(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_RAND case ENGINE_METHOD_RAND: if (!ENGINE_register_RAND(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_ECDH case ENGINE_METHOD_ECDH: if (!ENGINE_register_ECDH(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_ECDSA case ENGINE_METHOD_ECDSA: if (!ENGINE_register_ECDSA(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_STORE case ENGINE_METHOD_STORE: if (!ENGINE_register_STORE(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_CIPHERS case ENGINE_METHOD_CIPHERS: if (!ENGINE_register_ciphers(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_DIGESTS case ENGINE_METHOD_DIGESTS: if (!ENGINE_register_digests(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_PKEY_METHS case ENGINE_METHOD_PKEY_METHS: if (!ENGINE_register_pkey_meths(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_PKEY_ASN1_METHS case ENGINE_METHOD_PKEY_ASN1_METHS: if (!ENGINE_register_pkey_asn1_meths(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif #ifdef ENGINE_METHOD_EC case ENGINE_METHOD_EC: if (!ENGINE_register_EC(ctx->engine)) - return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + goto failed; break; #endif default: - return enif_make_tuple2(env, atom_error, atom_engine_method_not_supported); - break; + return enif_make_tuple2(env, atom_error, atom_engine_method_not_supported); } + return atom_ok; + + bad_arg: + return enif_make_badarg(env); + + failed: + return enif_make_tuple2(env, atom_error, atom_register_engine_failed); + #else return atom_notsup; #endif @@ -414,15 +489,12 @@ ERL_NIF_TERM engine_unregister_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM unsigned int method; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_unregister_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } - // Get Method - if (!enif_get_uint(env, argv[1], &method)) { - PRINTF_ERR0("engine_unregister_nif Leaved: Parameter Method not an uint"); - return enif_make_badarg(env); - } + ASSERT(argc == 2); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + if (!enif_get_uint(env, argv[1], &method)) + goto bad_arg; switch(method) { @@ -489,35 +561,51 @@ ERL_NIF_TERM engine_unregister_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM default: break; } + return atom_ok; + + bad_arg: + return enif_make_badarg(env); + #else return atom_notsup; #endif } ERL_NIF_TERM engine_get_first_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Engine) */ +{/* () */ #ifdef HAS_ENGINE_SUPPORT - ERL_NIF_TERM ret; + ERL_NIF_TERM ret, result; ENGINE *engine; ErlNifBinary engine_bin; - struct engine_ctx *ctx; + struct engine_ctx *ctx = NULL; + + ASSERT(argc == 0); - engine = ENGINE_get_first(); - if(!engine) { - enif_alloc_binary(0, &engine_bin); + if ((engine = ENGINE_get_first()) == NULL) { + if (!enif_alloc_binary(0, &engine_bin)) + goto err; engine_bin.size = 0; return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &engine_bin)); } - ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx)); + if ((ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx))) == NULL) + goto err; ctx->engine = engine; ctx->id = NULL; - ret = enif_make_resource(env, ctx); - enif_release_resource(ctx); + result = enif_make_resource(env, ctx); + ret = enif_make_tuple2(env, atom_ok, result); + goto done; + + err: + ret = enif_make_badarg(env); + + done: + if (ctx) + enif_release_resource(ctx); + return ret; - return enif_make_tuple2(env, atom_ok, ret); #else return atom_notsup; #endif @@ -526,31 +614,42 @@ ERL_NIF_TERM engine_get_first_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a ERL_NIF_TERM engine_get_next_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Engine) */ #ifdef HAS_ENGINE_SUPPORT - ERL_NIF_TERM ret; + ERL_NIF_TERM ret, result; ENGINE *engine; ErlNifBinary engine_bin; - struct engine_ctx *ctx, *next_ctx; + struct engine_ctx *ctx, *next_ctx = NULL; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_get_next_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } - engine = ENGINE_get_next(ctx->engine); - if (!engine) { - enif_alloc_binary(0, &engine_bin); + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; + + if ((engine = ENGINE_get_next(ctx->engine)) == NULL) { + if (!enif_alloc_binary(0, &engine_bin)) + goto err; engine_bin.size = 0; return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &engine_bin)); } - next_ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx)); + if ((next_ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx))) == NULL) + goto err; next_ctx->engine = engine; next_ctx->id = NULL; - ret = enif_make_resource(env, next_ctx); - enif_release_resource(next_ctx); + result = enif_make_resource(env, next_ctx); + ret = enif_make_tuple2(env, atom_ok, result); + goto done; + + bad_arg: + err: + ret = enif_make_badarg(env); + + done: + if (next_ctx) + enif_release_resource(next_ctx); + return ret; - return enif_make_tuple2(env, atom_ok, ret); #else return atom_notsup; #endif @@ -561,28 +660,34 @@ ERL_NIF_TERM engine_get_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv #ifdef HAS_ENGINE_SUPPORT ErlNifBinary engine_id_bin; const char *engine_id; - int size; - struct engine_ctx *ctx; + size_t size; + struct engine_ctx *ctx = NULL; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_get_id_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; - engine_id = ENGINE_get_id(ctx->engine); - if (!engine_id) { - enif_alloc_binary(0, &engine_id_bin); + if ((engine_id = ENGINE_get_id(ctx->engine)) == NULL) { + if (!enif_alloc_binary(0, &engine_id_bin)) + goto err; engine_id_bin.size = 0; return enif_make_binary(env, &engine_id_bin); } size = strlen(engine_id); - enif_alloc_binary(size, &engine_id_bin); + if (!enif_alloc_binary(size, &engine_id_bin)) + goto err; engine_id_bin.size = size; memcpy(engine_id_bin.data, engine_id, size); return enif_make_binary(env, &engine_id_bin); + + bad_arg: + err: + return enif_make_badarg(env); + #else return atom_notsup; #endif @@ -593,28 +698,34 @@ ERL_NIF_TERM engine_get_name_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar #ifdef HAS_ENGINE_SUPPORT ErlNifBinary engine_name_bin; const char *engine_name; - int size; + size_t size; struct engine_ctx *ctx; // Get Engine - if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) { - PRINTF_ERR0("engine_get_id_nif Leaved: Parameter not an engine resource object"); - return enif_make_badarg(env); - } + ASSERT(argc == 1); + + if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) + goto bad_arg; - engine_name = ENGINE_get_name(ctx->engine); - if (!engine_name) { - enif_alloc_binary(0, &engine_name_bin); + if ((engine_name = ENGINE_get_name(ctx->engine)) == NULL) { + if (!enif_alloc_binary(0, &engine_name_bin)) + goto err; engine_name_bin.size = 0; return enif_make_binary(env, &engine_name_bin); } size = strlen(engine_name); - enif_alloc_binary(size, &engine_name_bin); + if (!enif_alloc_binary(size, &engine_name_bin)) + goto err; engine_name_bin.size = size; memcpy(engine_name_bin.data, engine_name, size); return enif_make_binary(env, &engine_name_bin); + + bad_arg: + err: + return enif_make_badarg(env); + #else return atom_notsup; #endif @@ -627,46 +738,52 @@ static int get_engine_load_cmd_list(ErlNifEnv* env, const ERL_NIF_TERM term, cha const ERL_NIF_TERM *tmp_tuple; ErlNifBinary tmpbin; int arity; - char* tmpstr; - - if(!enif_is_empty_list(env, term)) { - if(!enif_get_list_cell(env, term, &head, &tail)) { - cmds[i] = NULL; - return -1; - } else { - if(!enif_get_tuple(env, head, &arity, &tmp_tuple) || arity != 2) { - cmds[i] = NULL; - return -1; - } else { - if(!enif_inspect_binary(env, tmp_tuple[0], &tmpbin)) { - cmds[i] = NULL; - return -1; - } else { - tmpstr = enif_alloc(tmpbin.size+1); - (void) memcpy(tmpstr, tmpbin.data, tmpbin.size); - tmpstr[tmpbin.size] = '\0'; - cmds[i++] = tmpstr; - } - if(!enif_inspect_binary(env, tmp_tuple[1], &tmpbin)) { - cmds[i] = NULL; - return -1; - } else { - if(tmpbin.size == 0) - cmds[i++] = NULL; - else { - tmpstr = enif_alloc(tmpbin.size+1); - (void) memcpy(tmpstr, tmpbin.data, tmpbin.size); - tmpstr[tmpbin.size] = '\0'; - cmds[i++] = tmpstr; - } - } - return get_engine_load_cmd_list(env, tail, cmds, i); - } - } - } else { + char *tuple1 = NULL, *tuple2 = NULL; + + if (enif_is_empty_list(env, term)) { cmds[i] = NULL; return 0; } + + if (!enif_get_list_cell(env, term, &head, &tail)) + goto err; + if (!enif_get_tuple(env, head, &arity, &tmp_tuple)) + goto err; + if (arity != 2) + goto err; + if (!enif_inspect_binary(env, tmp_tuple[0], &tmpbin)) + goto err; + + if ((tuple1 = enif_alloc(tmpbin.size + 1)) == NULL) + goto err; + + (void) memcpy(tuple1, tmpbin.data, tmpbin.size); + tuple1[tmpbin.size] = '\0'; + cmds[i] = tuple1; + i++; + + if (!enif_inspect_binary(env, tmp_tuple[1], &tmpbin)) + goto err; + + if (tmpbin.size == 0) { + cmds[i] = NULL; + } else { + if ((tuple2 = enif_alloc(tmpbin.size + 1)) == NULL) + goto err; + (void) memcpy(tuple2, tmpbin.data, tmpbin.size); + tuple2[tmpbin.size] = '\0'; + cmds[i] = tuple2; + } + i++; + return get_engine_load_cmd_list(env, tail, cmds, i); + + err: + if (tuple1 != NULL) { + i--; + enif_free(tuple1); + } + cmds[i] = NULL; + return -1; } #endif /* HAS_ENGINE_SUPPORT */ @@ -674,7 +791,9 @@ ERL_NIF_TERM engine_get_all_methods_nif(ErlNifEnv* env, int argc, const ERL_NIF_ {/* () */ #ifdef HAS_ENGINE_SUPPORT ERL_NIF_TERM method_array[12]; - int i = 0; + unsigned int i = 0; + + ASSERT(argc == 0); #ifdef ENGINE_METHOD_RSA method_array[i++] = atom_engine_method_rsa; |