diff options
author | Doug Hogan <[email protected]> | 2019-01-03 18:32:08 -0800 |
---|---|---|
committer | Doug Hogan <[email protected]> | 2019-01-08 00:08:22 -0800 |
commit | e8813319d24ed1f8200b09969b015fb2311967f9 (patch) | |
tree | e895b9b294b25059bf102bfa6cc2965f9afa6fef /lib/crypto | |
parent | 10665143d538b0ed344d172655e174713da3a336 (diff) | |
download | otp-e8813319d24ed1f8200b09969b015fb2311967f9.tar.gz otp-e8813319d24ed1f8200b09969b015fb2311967f9.tar.bz2 otp-e8813319d24ed1f8200b09969b015fb2311967f9.zip |
Revamp ecdh_compute_key_nif()
* Bug fix: ECDH_compute_key was not being checked for failures
- That function returns 0 on failure and never returns < 0.
- Using <= 0 check because OpenSSL uses that internally and on their wiki.
* Remove unnecessary variable i
* Make the gotos always flow downward rather than jumping back.
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/c_src/ecdh.c | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/lib/crypto/c_src/ecdh.c b/lib/crypto/c_src/ecdh.c index d458f3c48e..ee4b352730 100644 --- a/lib/crypto/c_src/ecdh.c +++ b/lib/crypto/c_src/ecdh.c @@ -32,48 +32,62 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a ERL_NIF_TERM ret; unsigned char *p; EC_KEY* key = NULL; - int field_size = 0; - int i; - EC_GROUP *group; + int degree; + size_t field_size; + EC_GROUP *group = NULL; const BIGNUM *priv_key; EC_POINT *my_ecpoint = NULL; EC_KEY *other_ecdh = NULL; + if (argc != 3) + goto bad_arg; if (!get_ec_key(env, argv[1], argv[2], atom_undefined, &key)) - return make_badarg_maybe(env); - - group = EC_GROUP_dup(EC_KEY_get0_group(key)); + goto bad_arg; + if ((group = EC_GROUP_dup(EC_KEY_get0_group(key))) == NULL) + goto bad_arg; priv_key = EC_KEY_get0_private_key(key); if (!term2point(env, argv[0], group, &my_ecpoint)) { - goto out_err; + goto err; } - if ((other_ecdh = EC_KEY_new()) == NULL - || !EC_KEY_set_group(other_ecdh, group) - || !EC_KEY_set_private_key(other_ecdh, priv_key)) - goto out_err; + if ((other_ecdh = EC_KEY_new()) == NULL) + goto err; + if (!EC_KEY_set_group(other_ecdh, group)) + goto err; + if (!EC_KEY_set_private_key(other_ecdh, priv_key)) + goto err; - field_size = EC_GROUP_get_degree(group); - if (field_size <= 0) - goto out_err; + if ((degree = EC_GROUP_get_degree(group)) <= 0) + goto err; - p = enif_make_new_binary(env, (field_size+7)/8, &ret); - i = ECDH_compute_key(p, (field_size+7)/8, my_ecpoint, other_ecdh, NULL); + field_size = (size_t)degree; + if ((p = enif_make_new_binary(env, (field_size+7)/8, &ret)) == NULL) + goto err; + if (ECDH_compute_key(p, (field_size+7)/8, my_ecpoint, other_ecdh, NULL) < 1) + goto err; - if (i < 0) - goto out_err; -out: - if (group) EC_GROUP_free(group); - if (my_ecpoint) EC_POINT_free(my_ecpoint); - if (other_ecdh) EC_KEY_free(other_ecdh); - if (key) EC_KEY_free(key); + goto done; - return ret; + bad_arg: + ret = make_badarg_maybe(env); + goto done; -out_err: + err: ret = enif_make_badarg(env); - goto out; + + done: + if (group) + EC_GROUP_free(group); + if (my_ecpoint) + EC_POINT_free(my_ecpoint); + if (other_ecdh) + EC_KEY_free(other_ecdh); + if (key) + EC_KEY_free(key); + + return ret; + #else return atom_notsup; #endif |