diff options
author | Doug Hogan <[email protected]> | 2019-01-03 18:46:08 -0800 |
---|---|---|
committer | Doug Hogan <[email protected]> | 2019-01-08 00:08:22 -0800 |
commit | 7ad28fd1bd0b6504c78c5d76903878cebd5cd631 (patch) | |
tree | f883f98ac4c07dc71a1ff167bcb69ac6f18beeaf | |
parent | 74a4f7b390581859b798079484f4af2644d41ee2 (diff) | |
download | otp-7ad28fd1bd0b6504c78c5d76903878cebd5cd631.tar.gz otp-7ad28fd1bd0b6504c78c5d76903878cebd5cd631.tar.bz2 otp-7ad28fd1bd0b6504c78c5d76903878cebd5cd631.zip |
Revamp get_dss_public_key()
* Simplify logic by having incremental allocation and only free on error on one place.
* Add error checking on all OpenSSL calls.
* Make it explicit when you need to be careful with non-reference counted pointers.
- set0 calls will use the pointer values without ref counting.
- On success, set pointers to NULL to avoid double frees since the struct
is now responsible for freeing the resources.
-rw-r--r-- | lib/crypto/c_src/dss.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/lib/crypto/c_src/dss.c b/lib/crypto/c_src/dss.c index 934b33d87c..9bf8eb3ce0 100644 --- a/lib/crypto/c_src/dss.c +++ b/lib/crypto/c_src/dss.c @@ -94,23 +94,51 @@ int get_dss_public_key(ErlNifEnv* env, ERL_NIF_TERM key, DSA *dsa) ERL_NIF_TERM head, tail; BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_y = NULL; - if (!enif_get_list_cell(env, key, &head, &tail) - || !get_bn_from_bin(env, head, &dsa_p) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_bin(env, head, &dsa_q) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_bin(env, head, &dsa_g) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_bin(env, head, &dsa_y) - || !enif_is_empty_list(env,tail)) { - if (dsa_p) BN_free(dsa_p); - if (dsa_q) BN_free(dsa_q); - if (dsa_g) BN_free(dsa_g); - if (dsa_y) BN_free(dsa_y); - return 0; - } - - DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g); - DSA_set0_key(dsa, dsa_y, NULL); + if (!enif_get_list_cell(env, key, &head, &tail)) + goto err; + if (!get_bn_from_bin(env, head, &dsa_p)) + goto err; + + if (!enif_get_list_cell(env, tail, &head, &tail)) + goto err; + if (!get_bn_from_bin(env, head, &dsa_q)) + goto err; + + if (!enif_get_list_cell(env, tail, &head, &tail)) + goto err; + if (!get_bn_from_bin(env, head, &dsa_g)) + goto err; + + if (!enif_get_list_cell(env, tail, &head, &tail)) + goto err; + if (!get_bn_from_bin(env, head, &dsa_y)) + goto err; + + if (!enif_is_empty_list(env,tail)) + goto err; + + if (!DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g)) + goto err; + /* dsa takes ownership on success */ + dsa_p = NULL; + dsa_q = NULL; + dsa_g = NULL; + + if (!DSA_set0_key(dsa, dsa_y, NULL)) + goto err; + /* dsa takes ownership on success */ + dsa_y = NULL; + return 1; + + err: + if (dsa_p) + BN_free(dsa_p); + if (dsa_q) + BN_free(dsa_q); + if (dsa_g) + BN_free(dsa_g); + if (dsa_y) + BN_free(dsa_y); + return 0; } |