From 0eab42611349dace5a596fcbd495bd5e1ddf1d19 Mon Sep 17 00:00:00 2001 From: Doug Hogan Date: Thu, 3 Jan 2019 23:32:07 -0800 Subject: Revamp srp_user_secret_nif() * Add error handling for all OpenSSL calls. * Consolidate freeing resources in both success and failure path. --- lib/crypto/c_src/srp.c | 145 +++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 59 deletions(-) (limited to 'lib/crypto') diff --git a/lib/crypto/c_src/srp.c b/lib/crypto/c_src/srp.c index 18b03206e0..e5ef72af08 100644 --- a/lib/crypto/c_src/srp.c +++ b/lib/crypto/c_src/srp.c @@ -114,80 +114,107 @@ ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar = (B - (k * g^x)) ^ (a + (u * x)) % N */ BIGNUM *bn_exponent = NULL, *bn_a = NULL; - BIGNUM *bn_u = NULL, *bn_multiplier = NULL, *bn_exp2, - *bn_base, *bn_prime = NULL, *bn_generator = NULL, - *bn_B = NULL, *bn_result; - BN_CTX *bn_ctx; - unsigned char* ptr; - unsigned dlen; + BIGNUM *bn_u = NULL, *bn_multiplier = NULL, *bn_exp2 = NULL; + BIGNUM *bn_base = NULL, *bn_prime = NULL, *bn_generator = NULL; + BIGNUM *bn_B = NULL, *bn_result = NULL; + BN_CTX *bn_ctx = NULL; + unsigned char *ptr; + int dlen; ERL_NIF_TERM ret; CHECK_NO_FIPS_MODE(); - if (!get_bn_from_bin(env, argv[0], &bn_a) - || !get_bn_from_bin(env, argv[1], &bn_u) - || !get_bn_from_bin(env, argv[2], &bn_B) - || !get_bn_from_bin(env, argv[3], &bn_multiplier) - || !get_bn_from_bin(env, argv[4], &bn_generator) - || !get_bn_from_bin(env, argv[5], &bn_exponent) - || !get_bn_from_bin(env, argv[6], &bn_prime)) - { - if (bn_exponent) BN_free(bn_exponent); - if (bn_a) BN_free(bn_a); - if (bn_u) BN_free(bn_u); - if (bn_B) BN_free(bn_B); - if (bn_multiplier) BN_free(bn_multiplier); - if (bn_generator) BN_free(bn_generator); - if (bn_prime) BN_free(bn_prime); - return enif_make_badarg(env); - } + if (argc != 7) + goto bad_arg; + if (!get_bn_from_bin(env, argv[0], &bn_a)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[1], &bn_u)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[2], &bn_B)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[3], &bn_multiplier)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[4], &bn_generator)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[5], &bn_exponent)) + goto bad_arg; + if (!get_bn_from_bin(env, argv[6], &bn_prime)) + goto bad_arg; - bn_ctx = BN_CTX_new(); - bn_result = BN_new(); + if ((bn_ctx = BN_CTX_new()) == NULL) + goto err; + if ((bn_result = BN_new()) == NULL) + goto err; /* check that B % N != 0 */ - BN_nnmod(bn_result, bn_B, bn_prime, bn_ctx); - if (BN_is_zero(bn_result)) { - BN_free(bn_exponent); - BN_free(bn_a); - BN_free(bn_generator); - BN_free(bn_prime); - BN_free(bn_u); - BN_free(bn_B); - BN_CTX_free(bn_ctx); - - return atom_error; - } + if (!BN_nnmod(bn_result, bn_B, bn_prime, bn_ctx)) + goto err; + if (BN_is_zero(bn_result)) + goto err; /* (B - (k * g^x)) */ - bn_base = BN_new(); - BN_mod_exp(bn_result, bn_generator, bn_exponent, bn_prime, bn_ctx); - BN_mod_mul(bn_result, bn_multiplier, bn_result, bn_prime, bn_ctx); - BN_mod_sub(bn_base, bn_B, bn_result, bn_prime, bn_ctx); + if ((bn_base = BN_new()) == NULL) + goto err; + if (!BN_mod_exp(bn_result, bn_generator, bn_exponent, bn_prime, bn_ctx)) + goto err; + if (!BN_mod_mul(bn_result, bn_multiplier, bn_result, bn_prime, bn_ctx)) + goto err; + if (!BN_mod_sub(bn_base, bn_B, bn_result, bn_prime, bn_ctx)) + goto err; /* a + (u * x) */ - bn_exp2 = BN_new(); - BN_mul(bn_result, bn_u, bn_exponent, bn_ctx); - BN_add(bn_exp2, bn_a, bn_result); + if ((bn_exp2 = BN_new()) == NULL) + goto err; + if (!BN_mul(bn_result, bn_u, bn_exponent, bn_ctx)) + goto err; + if (!BN_add(bn_exp2, bn_a, bn_result)) + goto err; /* (B - (k * g^x)) ^ (a + (u * x)) % N */ - BN_mod_exp(bn_result, bn_base, bn_exp2, bn_prime, bn_ctx); + if (!BN_mod_exp(bn_result, bn_base, bn_exp2, bn_prime, bn_ctx)) + goto err; - dlen = BN_num_bytes(bn_result); - ptr = enif_make_new_binary(env, dlen, &ret); - BN_bn2bin(bn_result, ptr); - BN_free(bn_result); - BN_CTX_free(bn_ctx); + if ((dlen = BN_num_bytes(bn_result)) < 0) + goto err; + if ((ptr = enif_make_new_binary(env, (size_t)dlen, &ret)) == NULL) + goto err; + + if (BN_bn2bin(bn_result, ptr) < 0) + goto err; + + goto done; + + bad_arg: + ret = enif_make_badarg(env); + goto done; + + err: + ret = atom_error; + + done: + if (bn_a) + BN_free(bn_a); + if (bn_u) + BN_free(bn_u); + if (bn_B) + BN_free(bn_B); + if (bn_multiplier) + BN_free(bn_multiplier); + if (bn_generator) + BN_free(bn_generator); + if (bn_exponent) + BN_free(bn_exponent); + if (bn_prime) + BN_free(bn_prime); + if (bn_ctx) + BN_CTX_free(bn_ctx); + if (bn_result) + BN_free(bn_result); + if (bn_base) + BN_free(bn_base); + if (bn_exp2) + BN_free(bn_exp2); - BN_free(bn_multiplier); - BN_free(bn_exp2); - BN_free(bn_u); - BN_free(bn_exponent); - BN_free(bn_a); - BN_free(bn_B); - BN_free(bn_base); - BN_free(bn_generator); - BN_free(bn_prime); return ret; } -- cgit v1.2.3