diff options
author | Doug Hogan <[email protected]> | 2019-01-03 22:47:26 -0800 |
---|---|---|
committer | Doug Hogan <[email protected]> | 2019-01-08 01:11:58 -0800 |
commit | a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3 (patch) | |
tree | 87afd1a3616dfe3a707eb7266558766d80a59675 | |
parent | 7ce4de4668b0b472d54da1b99687fd3fcd643402 (diff) | |
download | otp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.tar.gz otp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.tar.bz2 otp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.zip |
Revamp hmac_final_nif()
* Add error handling for all OpenSSL calls.
-rw-r--r-- | lib/crypto/c_src/hmac.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/lib/crypto/c_src/hmac.c b/lib/crypto/c_src/hmac.c index d95ce5cd01..08d9049caa 100644 --- a/lib/crypto/c_src/hmac.c +++ b/lib/crypto/c_src/hmac.c @@ -219,29 +219,49 @@ ERL_NIF_TERM hmac_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) unsigned int req_len = 0; unsigned int mac_len; - if (!enif_get_resource(env,argv[0],hmac_context_rtype, (void**)&obj) - || (argc == 2 && !enif_get_uint(env, argv[1], &req_len))) { - return enif_make_badarg(env); + if (argc != 1 && argc != 2) + goto bad_arg; + if (!enif_get_resource(env, argv[0], hmac_context_rtype, (void**)&obj)) + goto bad_arg; + if (argc == 2) { + if (!enif_get_uint(env, argv[1], &req_len)) + goto bad_arg; } enif_mutex_lock(obj->mtx); - if (!obj->alive) { - enif_mutex_unlock(obj->mtx); - return enif_make_badarg(env); - } + if (!obj->alive) + goto err; +#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,0,0) + if (!HMAC_Final(obj->ctx, mac_buf, &mac_len)) + goto err; +#else + // In ancient versions of OpenSSL, this was a void function. HMAC_Final(obj->ctx, mac_buf, &mac_len); - HMAC_CTX_free(obj->ctx); +#endif + + if (obj->ctx) + HMAC_CTX_free(obj->ctx); obj->alive = 0; - enif_mutex_unlock(obj->mtx); if (argc == 2 && req_len < mac_len) { /* Only truncate to req_len bytes if asked. */ mac_len = req_len; } - mac_bin = enif_make_new_binary(env, mac_len, &ret); + if ((mac_bin = enif_make_new_binary(env, mac_len, &ret)) == NULL) + goto err; + memcpy(mac_bin, mac_buf, mac_len); + goto done; + + bad_arg: + return enif_make_badarg(env); + + err: + ret = enif_make_badarg(env); + done: + enif_mutex_unlock(obj->mtx); return ret; } |