Better return value and error checking

This commit is contained in:
est31 2015-09-30 08:43:03 +02:00
parent 29ae96092e
commit d97da9e7c7
3 changed files with 82 additions and 36 deletions

82
srp.c
View File

@ -516,7 +516,7 @@ static void srp_pcgrandom_seed(srp_pcgrandom *r, unsigned long long int state,
}
static int fill_buff()
static SRP_Result fill_buff()
{
g_rand_idx = 0;
@ -532,7 +532,7 @@ static int fill_buff()
CryptGenRandom(wctx, sizeof(g_rand_buff), (BYTE*) g_rand_buff);
CryptReleaseContext(wctx, 0);
return 1;
return SRP_OK;
#else
fp = fopen("/dev/urandom", "r");
@ -542,6 +542,8 @@ static int fill_buff()
fclose(fp);
} else {
srp_pcgrandom *r = (srp_pcgrandom *) srp_alloc(sizeof(srp_pcgrandom));
if (!r)
return SRP_ERR;
srp_pcgrandom_seed(r, time(NULL) ^ clock(), 0xda3e39cb94b95bdbULL);
size_t i = 0;
for (i = 0; i < RAND_BUFF_MAX; i++) {
@ -550,23 +552,27 @@ static int fill_buff()
srp_free(r);
}
#endif
return 1;
return SRP_OK;
}
static void mpz_fill_random(mpz_t num)
static SRP_Result mpz_fill_random(mpz_t num)
{
// was call: BN_rand(num, 256, -1, 0);
if (RAND_BUFF_MAX - g_rand_idx < 32)
fill_buff();
if (fill_buff() != SRP_OK)
return SRP_ERR;
mpz_from_bin((const unsigned char *) (&g_rand_buff[g_rand_idx]), 32, num);
g_rand_idx += 32;
return SRP_OK;
}
static void init_random()
static SRP_Result init_random()
{
if (g_initialized)
return;
g_initialized = fill_buff();
return SRP_OK;
SRP_Result ret = fill_buff();
g_initialized = (ret == SRP_OK);
return ret;
}
#define srp_dbg_num(num, text) ;
@ -586,29 +592,33 @@ static void init_random()
*
***********************************************************************************************************/
void srp_create_salted_verification_key( SRP_HashAlgorithm alg,
SRP_Result srp_create_salted_verification_key( SRP_HashAlgorithm alg,
SRP_NGType ng_type, const char *username_for_verifier,
const unsigned char *password, size_t len_password,
unsigned char **bytes_s, size_t *len_s,
unsigned char **bytes_v, size_t *len_v,
const char *n_hex, const char *g_hex )
{
SRP_Result ret = SRP_OK;
mpz_t v; mpz_init(v);
mpz_t x; mpz_init(x);
NGConstant *ng = new_ng(ng_type, n_hex, g_hex);
if(!ng)
goto cleanup_and_exit;
if (!ng)
goto error_and_exit;
init_random(); /* Only happens once */
if (init_random() != SRP_OK) /* Only happens once */
goto error_and_exit;
if (*bytes_s == NULL) {
*len_s = 16;
if (RAND_BUFF_MAX - g_rand_idx < 16)
fill_buff();
if (fill_buff() != SRP_OK)
goto error_and_exit;
*bytes_s = (unsigned char*)srp_alloc(sizeof(char) * 16);
if (!*bytes_s)
goto cleanup_and_exit;
goto error_and_exit;
memcpy(*bytes_s, &g_rand_buff + g_rand_idx, sizeof(char) * 16);
g_rand_idx += 16;
}
@ -616,7 +626,7 @@ void srp_create_salted_verification_key( SRP_HashAlgorithm alg,
if (!calculate_x(x, alg, *bytes_s, *len_s, username_for_verifier,
password, len_password))
goto cleanup_and_exit;
goto error_and_exit;
srp_dbg_num(x, "Server calculated x: ");
@ -627,7 +637,7 @@ void srp_create_salted_verification_key( SRP_HashAlgorithm alg,
*bytes_v = (unsigned char*)srp_alloc(*len_v);
if (!bytes_v)
goto cleanup_and_exit;
goto error_and_exit;
mpz_to_bin(v, *bytes_v);
@ -635,6 +645,10 @@ cleanup_and_exit:
delete_ng( ng );
mpz_clear(v);
mpz_clear(x);
return ret;
error_and_exit:
ret = SRP_ERR;
goto cleanup_and_exit;
}
@ -677,7 +691,11 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
if (!ver)
goto cleanup_and_exit;
init_random(); /* Only happens once */
if (init_random() != SRP_OK) { /* Only happens once */
srp_free(ver);
ver = 0;
goto cleanup_and_exit;
}
ver->username = (char *) srp_alloc(ulen);
ver->hash_alg = alg;
@ -699,7 +717,11 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
if (bytes_b) {
mpz_from_bin(bytes_b, len_b, b);
} else {
mpz_fill_random(b);
if (mpz_fill_random(b) != SRP_OK) {
srp_free(ver);
ver = 0;
goto cleanup_and_exit;
}
}
if (!H_nn(k, alg, ng->N, ng->N, ng->g)) {
@ -830,7 +852,8 @@ struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
if (!usr)
goto err_exit;
init_random(); /* Only happens once */
if (init_random() != SRP_OK) /* Only happens once */
goto err_exit;
usr->hash_alg = alg;
usr->ng = new_ng(ng_type, n_hex, g_hex);
@ -933,14 +956,15 @@ size_t srp_user_get_session_key_length(struct SRPUser *usr)
/* Output: username, bytes_A, len_A */
void srp_user_start_authentication(struct SRPUser *usr, char **username,
SRP_Result srp_user_start_authentication(struct SRPUser *usr, char **username,
const unsigned char *bytes_a, size_t len_a,
unsigned char **bytes_A, size_t *len_A)
{
if (bytes_a) {
mpz_from_bin(bytes_a, len_a, usr->a);
} else {
mpz_fill_random(usr->a);
if (mpz_fill_random(usr->a) != SRP_OK)
goto error_and_exit;
}
mpz_powm(usr->A, usr->ng->g, usr->a, usr->ng->N);
@ -948,18 +972,22 @@ void srp_user_start_authentication(struct SRPUser *usr, char **username,
*len_A = mpz_num_bytes(usr->A);
*bytes_A = (unsigned char*)srp_alloc(*len_A);
if (!*bytes_A) {
*len_A = 0;
*bytes_A = 0;
*username = 0;
return;
}
if (!*bytes_A)
goto error_and_exit;
mpz_to_bin(usr->A, *bytes_A);
usr->bytes_A = *bytes_A;
if (username)
*username = usr->username;
return SRP_OK;
error_and_exit:
*len_A = 0;
*bytes_A = 0;
*username = 0;
return SRP_ERR;
}

21
srp.h
View File

@ -78,6 +78,12 @@ typedef enum
SRP_SHA512*/
} SRP_HashAlgorithm;
typedef enum
{
SRP_OK,
SRP_ERR,
} SRP_Result;
/* Sets the memory functions used by srp.
* Note: this doesn't set the memory functions used by gmp,
* but it is supported to have different functions for srp and gmp.
@ -96,8 +102,11 @@ void srp_set_memory_functions(
* If provided, they must contain ASCII text of the hexidecimal notation.
*
* If bytes_s == NULL, it is filled with random data. The caller is responsible for freeing.
*
* Returns SRP_OK on success, and SRP_ERR on error.
* bytes_s might be in this case invalid, don't free it.
*/
void srp_create_salted_verification_key( SRP_HashAlgorithm alg,
SRP_Result srp_create_salted_verification_key( SRP_HashAlgorithm alg,
SRP_NGType ng_type, const char *username_for_verifier,
const unsigned char *password, size_t len_password,
unsigned char **bytes_s, size_t *len_s,
@ -111,6 +120,8 @@ void srp_create_salted_verification_key( SRP_HashAlgorithm alg,
* The n_hex and g_hex parameters should be 0 unless SRP_NG_CUSTOM is used for ng_type
*
* If bytes_b == NULL, random data is used for b.
*
* Returns pointer to SRPVerifier on success, and NULL on error.
*/
struct SRPVerifier* srp_verifier_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
const char *username,
@ -124,7 +135,7 @@ struct SRPVerifier* srp_verifier_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
void srp_verifier_delete( struct SRPVerifier* ver );
// srp_verifier_verify_session must have been called before
int srp_verifier_is_authenticated( struct SRPVerifier* ver );
@ -138,7 +149,9 @@ const unsigned char* srp_verifier_get_session_key( struct SRPVerifier* ver,
size_t srp_verifier_get_session_key_length(struct SRPVerifier* ver);
/* user_M must be exactly srp_verifier_get_session_key_length() bytes in size */
/* Verifies session, on success, it writes bytes_HAMK.
* user_M must be exactly srp_verifier_get_session_key_length() bytes in size
*/
void srp_verifier_verify_session( struct SRPVerifier* ver,
const unsigned char* user_M, unsigned char** bytes_HAMK );
@ -164,7 +177,7 @@ size_t srp_user_get_session_key_length(struct SRPUser* usr);
/* Output: username, bytes_A, len_A. If you don't want it get written, set username to NULL.
* If bytes_a == NULL, random data is used for a. */
void srp_user_start_authentication(struct SRPUser* usr, char** username,
SRP_Result srp_user_start_authentication(struct SRPUser* usr, char** username,
const unsigned char* bytes_a, size_t len_a,
unsigned char** bytes_A, size_t* len_A);

View File

@ -268,9 +268,10 @@ int main(int argc, char * argv[])
g_hex = test_g_hex;
}
srp_create_salted_verification_key(alg, ng_type, ver_unam,
(const unsigned char *)password, strlen(password),
&bytes_s, &len_s, &bytes_v, &len_v, n_hex, g_hex);
if (srp_create_salted_verification_key(alg, ng_type, ver_unam,
(const unsigned char *)password, strlen(password),
&bytes_s, &len_s, &bytes_v, &len_v, n_hex, g_hex) != RES_OK)
return 1;
start = get_usec();
@ -279,7 +280,11 @@ int main(int argc, char * argv[])
(const unsigned char *)password,
strlen(password), n_hex, g_hex);
srp_user_start_authentication(usr, NULL, NULL, 0, &bytes_A, &len_A);
if (srp_user_start_authentication(usr, NULL, NULL, 0, &bytes_A, &len_A) != SRP_OK) {
printf("Error while starting SRP-6a authentication!\n");
goto cleanup;
}
/* User -> Host: (username, bytes_A) */
ver = srp_verifier_new(alg, ng_type, username, bytes_s, len_s, bytes_v, len_v,
@ -320,7 +325,7 @@ cleanup:
duration = get_usec() - start;
printf("Usec per login sequence (server + user): %d\n", (int)(duration / NITER));
printf("Usec per login sequence: %d\n", (int)(duration / NITER));
free((char *)bytes_s);