aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src/hmac.c
diff options
context:
space:
mode:
authorDoug Hogan <[email protected]>2019-01-03 22:47:26 -0800
committerDoug Hogan <[email protected]>2019-01-08 01:11:58 -0800
commita8ff8b19b82876b838f3701fb4adaf3a4a0d55d3 (patch)
tree87afd1a3616dfe3a707eb7266558766d80a59675 /lib/crypto/c_src/hmac.c
parent7ce4de4668b0b472d54da1b99687fd3fcd643402 (diff)
downloadotp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.tar.gz
otp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.tar.bz2
otp-a8ff8b19b82876b838f3701fb4adaf3a4a0d55d3.zip
Revamp hmac_final_nif()
* Add error handling for all OpenSSL calls.
Diffstat (limited to 'lib/crypto/c_src/hmac.c')
-rw-r--r--lib/crypto/c_src/hmac.c40
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;
}