Skip to content
Snippets Groups Projects
Commit d079c7d0 authored by Charles Wright's avatar Charles Wright
Browse files

Refactored the C API to be more granular. This should help with the Python bindings.

parent 025a2c00
No related branches found
No related tags found
No related merge requests found
......@@ -81,16 +81,20 @@ bsspeke_client_init(bsspeke_client_ctx *ctx,
void
bsspeke_server_init(bsspeke_server_ctx *ctx,
const char* server_id, const size_t server_id_len
const char* server_id, const size_t server_id_len,
const char* client_id, const size_t client_id_len
) {
ctx->server_id = (uint8_t *)server_id;
ctx->server_id_len = server_id_len;
ctx->client_id = (uint8_t *)client_id;
ctx->client_id_len = client_id_len;
}
void
bsspeke_client_generate_message1
bsspeke_client_generate_blind
(
bsspeke_login_msg1_t *msg1,
uint8_t blind[32],
bsspeke_client_ctx *client
) {
debug(DEBUG, "Hashing client's password");
......@@ -135,71 +139,81 @@ bsspeke_client_generate_message1
debug(DEBUG, "Multiplying curve point by r");
// 3. Multiply our curve point by r
crypto_x25519_scalarmult(msg1->blind, client->r, curve_point, 256);
print_point("blind", msg1->blind);
crypto_x25519_scalarmult(blind, client->r, curve_point, 256);
print_point("blind", blind);
debug(DEBUG, "Done");
msg1->client_id = client->client_id;
return;
}
void
bsspeke_client_setup_generate_message1
(
bsspeke_setup_msg1_t *msg1,
bsspeke_client_ctx *client
) {
bsspeke_client_generate_message1(msg1, client);
}
void
bsspeke_server_setup_generate_message2
bsspeke_server_blind_salt
(
bsspeke_setup_msg2_t *msg2,
const bsspeke_setup_msg1_t *msg1,
// uint8_t *salt, const size_t salt_len,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server_ctx
uint8_t blind_salt[32],
const uint8_t blind[32],
const uint8_t *salt, const size_t salt_len
)
{
/*
// FIXME This function no longer generates its own salt!
// We MUST do this before calling the function!!!
// We're setting up a new account
// So we have to create a new random salt for the user
debug(DEBUG, "Generating new salt");
user_info->salt_len = 32;
//arc4random_buf(user_info->salt, user_info->salt_len);
salt_len = 32;
generate_random_bytes(user_info->salt, user_info->salt_len);
print_point("salt", user_info->salt);
*/
print_point("salt", salt);
// Hash the salt
debug(DEBUG, "Hashing the salt");
uint8_t H_salt[32];
crypto_blake2b_general(H_salt, 32,
NULL, 0,
user_info->salt,
user_info->salt_len);
salt,
salt_len);
// Use clamp() to ensure we stay on the curve in the multiply below
crypto_x25519_clamp(H_salt);
print_point("H_salt", H_salt);
// Multiply H(salt) by msg1->blind, save into msg2->blind_salt
// Multiply H(salt) by blind, save into blind_salt
debug(DEBUG, "Multiplying H_salt by the user's blind");
crypto_x25519_scalarmult(msg2->blind_salt, H_salt, msg1->blind, 256);
print_point("blndsalt", msg2->blind_salt);
crypto_x25519_scalarmult(blind_salt, H_salt, blind, 256);
print_point("blndsalt", blind_salt);
}
void
bsspeke_server_generate_B(const uint8_t P[32],
bsspeke_server_ctx *server)
{
// Generate random ephemeral private key b, save it in server->b
debug(DEBUG, "Generating ephemeral private key b");
//arc4random_buf(server->b, 32);
generate_random_bytes(server->b, 32);
crypto_x25519_clamp(server->b);
print_point("b", server->b);
debug(DEBUG, "Using user's base point P");
print_point("P", P);
// Compute public key B = b * P, save it in msg2->B
debug(DEBUG, "Computing ephemeral public key B = b * P");
crypto_x25519_scalarmult(server->B, server->b, P, 256);
print_point("B", server->B);
}
int
bsspeke_client_setup_generate_message3
(
bsspeke_setup_msg3_t *msg3,
const bsspeke_setup_msg2_t *msg2,
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client
)
bsspeke_client_generate_keys_from_password(const uint8_t blind_salt[32],
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client)
{
// Sanity checks first, before we do any work
if( phf_blocks < BSSPEKE_ARGON2_MIN_PHF_BLOCKS ) {
debug(ERROR, "Requested PHF blocks below the minimum");
return -1;
}
if( phf_iterations < BSSPEKE_ARGON2_MIN_PHF_ITERATIONS ) {
debug(ERROR, "Requested PHF iterations below the minimum");
return -1;
}
......@@ -207,12 +221,10 @@ bsspeke_client_setup_generate_message3
// Multiply the blinded salt by 1/r to get the oblivious salt
// Here we rely on Monocypher to do the heavy lifting for us
debug(DEBUG, "Removing the blind from the oblivious salt");
crypto_x25519_inverse(oblivious_salt, client->r, msg2->blind_salt);
crypto_x25519_inverse(oblivious_salt, client->r, blind_salt);
print_point("obv_salt", oblivious_salt);
// Hash the oblivious salt together with the id's to create the salt for the PHF
uint8_t password_hash[64];
debug(DEBUG, "Creating the salt for the PHF");
uint8_t phf_salt[32];
{
......@@ -230,6 +242,7 @@ bsspeke_client_setup_generate_message3
print_point("phf_salt", phf_salt);
debug(DEBUG, "Running the PHF to generate p and v");
uint8_t password_hash[64];
void *work_area;
if ((work_area = malloc(phf_blocks * 1024)) == NULL) {
return -1;
......@@ -241,180 +254,71 @@ bsspeke_client_setup_generate_message3
free(work_area);
// p || v = pwKdf(password, BlindSalt, idC, idS, settings)
uint8_t *p = &(password_hash[0]);
uint8_t *v = &(password_hash[32]);
// FIXME Should we clamp() v before we multiply???
crypto_x25519_clamp(v);
print_point("p", p);
print_point("v", v);
uint8_t *tmp_p = &(password_hash[0]);
uint8_t *tmp_v = &(password_hash[32]);
// clamp() v before we do anything else with it
crypto_x25519_clamp(tmp_v);
// Hash p onto the curve to get this user's base point P
//uint8_t P[32];
debug(DEBUG, "Hashing p onto the curve to get P");
crypto_hidden_to_curve(msg3->P, p);
print_point("P", msg3->P);
memcpy(client->p, tmp_p, 32);
memcpy(client->v, tmp_v, 32);
crypto_wipe(password_hash, 64);
// Generate our long-term public key V = v * P
debug(DEBUG, "V = v * P");
crypto_x25519_scalarmult(msg3->V, v, msg3->P, 256);
print_point("V", msg3->V);
// Send our PHF params so the server can store them for us
msg3->phf_blocks = phf_blocks;
msg3->phf_iterations = phf_iterations;
print_point("p", client->p);
print_point("v", client->v);
return 0;
}
void
bsspeke_server_setup_process_message3
int
bsspeke_client_generate_P_and_V
(
bsspeke_setup_msg3_t *msg3,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server
uint8_t P[32], uint8_t V[32],
const uint8_t blind_salt[32],
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client
)
{
// Setup Message 3 contains stuff that we need to remember.
// The user info struct is where we store stuff that
// needs to persist across sessions.
memcpy(user_info->P, msg3->P, 32);
memcpy(user_info->V, msg3->V, 32);
user_info->phf_blocks = msg3->phf_blocks;
user_info->phf_iterations = msg3->phf_iterations;
}
void
bsspeke_client_login_generate_message1
(
bsspeke_login_msg1_t *msg1,
bsspeke_client_ctx *client
) {
bsspeke_client_generate_message1(msg1, client);
}
void
bsspeke_server_login_generate_message2(bsspeke_login_msg2_t *msg2,
const bsspeke_login_msg1_t *msg1,
// const uint8_t *salt, const size_t salt_len,
// uint8_t P[32], uint8_t V[32],
// uint32_t phf_blocks,
// uint32_t phf_iterations,
const bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server
) {
// Record the client's id
server->client_id_len = strlen(msg1->client_id);
server->client_id = (uint8_t *)malloc(server->client_id_len + 1);
strncpy(server->client_id, msg1->client_id, server->client_id_len);
printf("Server got msg1 from [%s]\n", (char *)(server->client_id));
// Hash the salt
debug(DEBUG, "Hashing the salt");
uint8_t H_salt[32];
crypto_blake2b_general(H_salt, 32,
NULL, 0,
user_info->salt,
user_info->salt_len);
// Use clamp() to ensure we stay on the curve in the multiply below
crypto_x25519_clamp(H_salt);
print_point("H_salt", H_salt);
// Multiply H(salt) by msg1->blind, save into msg2->blind_salt
debug(DEBUG, "Multiplying H_salt by the user's blind");
crypto_x25519_scalarmult(msg2->blind_salt, H_salt, msg1->blind, 256);
print_point("blndsalt", msg2->blind_salt);
// Generate random ephemeral private key b, save it in ctx->b
debug(DEBUG, "Generating ephemeral private key b");
//arc4random_buf(server->b, 32);
generate_random_bytes(server->b, 32);
crypto_x25519_clamp(server->b);
print_point("b", server->b);
debug(DEBUG, "Using user's base point P");
print_point("P", user_info->P);
// Compute public key B = b * P, save it in msg2->B
debug(DEBUG, "Computing ephemeral public key B = b * P");
crypto_x25519_scalarmult(server->B, server->b, user_info->P, 256);
print_point("B", server->B);
int rc = bsspeke_client_generate_keys_from_password(blind_salt,
phf_blocks, phf_iterations,
client);
if( rc != 0 ) {
debug(ERROR, "Password hashing function failed");
return -1;
}
// Copy the public key into the outgoing message as well
memcpy(msg2->B, server->B, 32);
// Hash p onto the curve to get this user's base point P
//uint8_t P[32];
debug(DEBUG, "Hashing p onto the curve to get P");
crypto_hidden_to_curve(P, client->p);
print_point("P", P);
// Copy the PHF params too
msg2->phf_blocks = user_info->phf_blocks;
msg2->phf_iterations = user_info->phf_iterations;
// Generate our long-term public key V = v * P
debug(DEBUG, "V = v * P");
crypto_x25519_scalarmult(V, client->v, P, 256);
print_point("V", V);
return;
return 0;
}
int
bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
const bsspeke_login_msg2_t *msg2,
bsspeke_client_ctx *client
bsspeke_client_generate_A(const uint8_t blind_salt[32],
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client
) {
// Sanity checks first, before we do any work
if( msg2->phf_blocks < BSSPEKE_ARGON2_MIN_PHF_BLOCKS ) {
debug(ERROR, "phf_blocks is too low. Aborting.");
return -1;
}
if( msg2->phf_iterations < BSSPEKE_ARGON2_MIN_PHF_ITERATIONS ) {
debug(ERROR, "phf_iterations is too low. Aborting.");
int rc = bsspeke_client_generate_keys_from_password(blind_salt,
phf_blocks, phf_iterations,
client);
if( rc != 0 ) {
debug(ERROR, "Password hashing failed");
return -1;
}
uint8_t oblivious_salt[32];
// Multiply the blinded salt by 1/r to get the oblivious salt
// Here we rely on Monocypher to do the heavy lifting for us
debug(DEBUG, "Removing the blind from the oblivious salt");
crypto_x25519_inverse(oblivious_salt, client->r, msg2->blind_salt);
print_point("obv_salt", oblivious_salt);
// Hash the oblivious salt together with the id's to create the salt for the PHF
uint8_t password_hash[64];
debug(DEBUG, "Creating the salt for the PHF");
uint8_t phf_salt[32];
{
crypto_blake2b_ctx hash_ctx;
crypto_blake2b_general_init(&hash_ctx, 32, NULL, 0);
crypto_blake2b_update(&hash_ctx, oblivious_salt, 32);
crypto_blake2b_update(&hash_ctx,
client->client_id,
client->client_id_len);
crypto_blake2b_update(&hash_ctx,
client->server_id,
client->server_id_len);
crypto_blake2b_final(&hash_ctx, phf_salt);
}
print_point("phf_salt", phf_salt);
debug(DEBUG, "Running the PHF to generate p and v");
void *work_area;
if ((work_area = malloc(msg2->phf_blocks * 1024)) == NULL) {
debug(ERROR, "Failed to malloc() memory for PHF work area");
return -1;
}
crypto_argon2i(password_hash, 64, work_area,
msg2->phf_blocks, msg2->phf_iterations,
client->password, client->password_len,
phf_salt, 32);
free(work_area);
// p || v = pwKdf(password, BlindSalt, idC, idS, settings)
uint8_t *p = &(password_hash[0]);
uint8_t *v = &(password_hash[32]);
// In the setup protocol, we clamped v before using it
// So we should do the same here
crypto_x25519_clamp(v);
print_point("p", p);
print_point("v", v);
// Hash p onto the curve to get this user's base point P
uint8_t P[32];
debug(DEBUG, "Hashing p onto the curve to get P");
crypto_hidden_to_curve(P, p);
crypto_hidden_to_curve(P, client->p);
print_point("P", P);
// Generate a random ephemeral private key a, store it in ctx->a
......@@ -425,18 +329,25 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
print_point("a", client->a);
// Generate the ephemeral public key A = a * P, store it in msg3->A
debug(DEBUG, "Generating ephemeral public key A = a * P");
crypto_x25519_scalarmult(msg3->A, client->a, P, 256);
print_point("A", msg3->A);
crypto_x25519_scalarmult(client->A, client->a, P, 256);
print_point("A", client->A);
return 0;
}
void
bsspeke_client_derive_shared_key(const uint8_t B[32],
bsspeke_client_ctx *client)
{
// Compute the two Diffie-Hellman shared secrets
debug(DEBUG, "Computing Diffie-Hellman shared secrets");
// DH shared secret from a * B
uint8_t a_B[32];
crypto_x25519(a_B, client->a, msg2->B);
crypto_x25519(a_B, client->a, B);
print_point("a * B", a_B);
// DH shared secret from v * B
uint8_t v_B[32];
crypto_x25519(v_B, v, msg2->B);
crypto_x25519(v_B, client->v, B);
print_point("v * B", v_B);
// Hash everything we know so far to generate our key, save it in ctx->K_c
......@@ -450,14 +361,19 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
crypto_blake2b_update(&hash_ctx,
client->server_id,
client->server_id_len);
crypto_blake2b_update(&hash_ctx, msg3->A, 32);
crypto_blake2b_update(&hash_ctx, msg2->B, 32);
crypto_blake2b_update(&hash_ctx, client->A, 32);
crypto_blake2b_update(&hash_ctx, B, 32);
crypto_blake2b_update(&hash_ctx, a_B, 32);
crypto_blake2b_update(&hash_ctx, v_B, 32);
crypto_blake2b_final(&hash_ctx, client->K_c);
}
print_point("K_c", client->K_c);
}
void
bsspeke_client_generate_verifier(uint8_t client_verifier[32],
bsspeke_client_ctx *client)
{
// Hash k and the client modifier to get our verifier, save it in msg3->client_verifier
debug(DEBUG, "Hashing K_c and modifier to get our verifier");
{
......@@ -467,29 +383,25 @@ bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
crypto_blake2b_update(&hash_ctx,
(uint8_t *)BSSPEKE_VERIFY_CLIENT_MODIFIER,
BSSPEKE_VERIFY_CLIENT_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, msg3->client_verifier);
crypto_blake2b_final(&hash_ctx, client_verifier);
}
print_point("client_v", msg3->client_verifier);
return 0;
print_point("client_v", client_verifier);
}
int
bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
const bsspeke_login_msg3_t *msg3,
const bsspeke_user_info_t *user_info,
void
bsspeke_server_derive_shared_key(const uint8_t A[32],
const uint8_t V[32],
bsspeke_server_ctx *server
) {
// Compute the two Diffie-Hellman shared secrets
debug(DEBUG, "Computing Diffie-Hellman shared secrets");
// DH shared secret from b * A
uint8_t b_A[32];
crypto_x25519(b_A, server->b, msg3->A);
crypto_x25519(b_A, server->b, A);
print_point("b * A", b_A);
// DH shared secret from b * V
//print_point("V", user_info->V);
uint8_t b_V[32];
crypto_x25519(b_V, server->b, user_info->V);
crypto_x25519(b_V, server->b, V);
print_point("b * V", b_V);
// Hash everything we've learned so far to generate k, save it in ctx->k
......@@ -503,13 +415,19 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
crypto_blake2b_update(&hash_ctx,
server->server_id,
server->server_id_len);
crypto_blake2b_update(&hash_ctx, msg3->A, 32);
crypto_blake2b_update(&hash_ctx, A, 32);
crypto_blake2b_update(&hash_ctx, server->B, 32);
crypto_blake2b_update(&hash_ctx, b_A, 32);
crypto_blake2b_update(&hash_ctx, b_V, 32);
crypto_blake2b_final(&hash_ctx, server->K_s);
}
print_point("K_s", server->K_s);
}
int
bsspeke_server_verify_client(uint8_t client_verifier[32],
bsspeke_server_ctx *server
) {
// Check that the client's hash is correct
// Compute H( k || VERIFY_CLIENT_MODIFIER )
......@@ -524,17 +442,24 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
BSSPEKE_VERIFY_CLIENT_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, my_client_verifier);
}
print_point("client's", msg3->client_verifier);
print_point("client's", client_verifier);
print_point("mine", my_client_verifier);
// Compare vs msg3->client_verifier
if( crypto_verify32(msg3->client_verifier, my_client_verifier) != 0 ) {
if( crypto_verify32(client_verifier, my_client_verifier) != 0 ) {
debug(ERROR, "Client's verifier doesn't match!");
return -1;
}
debug(DEBUG, "Client's verifier checks out");
// Compute our own verifier H( k || VERIFY_SERVER_MODIFIER ), save it in msg4->server_verifier
return 0;
}
void
bsspeke_server_generate_verifier(uint8_t server_verifier[32],
bsspeke_server_ctx *server
) {
// Compute our own verifier H( k || VERIFY_SERVER_MODIFIER ), save it in server_verifier
debug(DEBUG, "Computing server verifier hash");
{
crypto_blake2b_ctx hash_ctx;
......@@ -543,17 +468,14 @@ bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
crypto_blake2b_update(&hash_ctx,
(uint8_t *)BSSPEKE_VERIFY_SERVER_MODIFIER,
BSSPEKE_VERIFY_SERVER_MODIFIER_LEN);
crypto_blake2b_final(&hash_ctx, msg4->server_verifier);
crypto_blake2b_final(&hash_ctx, server_verifier);
}
print_point("server_v", msg4->server_verifier);
// If we made it this far, return success
return 0;
print_point("server_v", server_verifier);
}
int
bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client
bsspeke_client_verify_server(const uint8_t server_verifier[32],
const bsspeke_client_ctx *client
) {
// Compute our own version of the server's verifier hash
debug(DEBUG, "Verifying hash from the server");
......@@ -568,10 +490,10 @@ bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4,
crypto_blake2b_final(&hash_ctx, my_server_verifier);
}
print_point("mine", my_server_verifier);
print_point("server's", msg4->server_verifier);
print_point("server's", server_verifier);
// If the hashes don't match, return failure
if( crypto_verify32(msg4->server_verifier, my_server_verifier) != 0 ) {
if( crypto_verify32(server_verifier, my_server_verifier) != 0 ) {
debug(WARN, "Server's hash doesn't match. Aborting.");
return -1;
}
......
......@@ -47,9 +47,12 @@ typedef struct {
uint8_t r[32];
// Server's ephemeral public key
uint8_t B[32];
// Ephemeral keypair
// Ephemeral keys
uint8_t a[32];
//uint8_t A[32];
uint8_t A[32];
// Long term keys
uint8_t v[32];
uint8_t p[32];
// Session key
uint8_t K_c[32];
} bsspeke_client_ctx;
......@@ -88,6 +91,7 @@ typedef struct {
uint8_t blind[32];
} bsspeke_msg1_t;
/*
typedef bsspeke_msg1_t bsspeke_setup_msg1_t;
typedef struct {
......@@ -100,8 +104,9 @@ typedef struct {
uint32_t phf_blocks;
uint32_t phf_iterations;
} bsspeke_setup_msg3_t;
*/
/*
typedef bsspeke_msg1_t bsspeke_login_msg1_t;
typedef struct {
......@@ -119,6 +124,7 @@ typedef struct {
typedef struct {
uint8_t server_verifier[32];
} bsspeke_login_msg4_t;
*/
void
bsspeke_client_init(bsspeke_client_ctx *ctx,
......@@ -128,71 +134,59 @@ bsspeke_client_init(bsspeke_client_ctx *ctx,
void
bsspeke_server_init(bsspeke_server_ctx *ctx,
const char* server_id, const size_t server_id_len);
const char* server_id, const size_t server_id_len,
const char* client_id, const size_t client_id_len);
void
bsspeke_client_setup_generate_message1
(
bsspeke_setup_msg1_t *msg1,
bsspeke_client_ctx *client
);
bsspeke_client_generate_blind(uint8_t blind[32],
bsspeke_client_ctx *client);
void
bsspeke_server_blind_salt(uint8_t blind_salt[32],
const uint8_t blind[32],
const uint8_t *salt, const size_t salt_len);
void
bsspeke_server_setup_generate_message2
(
bsspeke_setup_msg2_t *msg2,
const bsspeke_setup_msg1_t *msg1,
// uint8_t *salt, const size_t salt_len,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server_ctx
);
bsspeke_server_generate_B(const uint8_t P[32],
bsspeke_server_ctx *server);
int
bsspeke_client_setup_generate_message3
(
bsspeke_setup_msg3_t *msg3,
const bsspeke_setup_msg2_t *msg2,
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client
);
bsspeke_client_generate_P_and_V(uint8_t P[32], uint8_t V[32],
const uint8_t blind_salt[32],
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client);
int
bsspeke_client_generate_A(const uint8_t blind_salt[32],
uint32_t phf_blocks, uint32_t phf_iterations,
bsspeke_client_ctx *client);
void
bsspeke_server_setup_process_message3
(
bsspeke_setup_msg3_t *msg3,
bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server
);
bsspeke_client_derive_shared_key(const uint8_t B[32],
bsspeke_client_ctx *client);
void
bsspeke_client_login_generate_message1(bsspeke_login_msg1_t *msg1,
bsspeke_client_generate_verifier(uint8_t client_verifier[32],
bsspeke_client_ctx *client);
void
bsspeke_server_login_generate_message2(bsspeke_login_msg2_t *msg2,
const bsspeke_login_msg1_t *msg1,
// const uint8_t *salt, const size_t salt_len,
// uint8_t P[32], uint8_t V[32],
// uint32_t phf_blocks,
// uint32_t phf_iterations,
const bsspeke_user_info_t *user,
bsspeke_server_derive_shared_key(const uint8_t A[32],
const uint8_t V[32],
bsspeke_server_ctx *server);
int
bsspeke_client_login_generate_message3(bsspeke_login_msg3_t *msg3,
const bsspeke_login_msg2_t *msg2,
bsspeke_client_ctx *client_ctx);
bsspeke_server_verify_client(uint8_t client_verifier[32],
bsspeke_server_ctx *server);
int
bsspeke_server_login_generate_message4(bsspeke_login_msg4_t *msg4,
const bsspeke_login_msg3_t *msg3,
const bsspeke_user_info_t *user_info,
bsspeke_server_ctx *server_ctx);
void
bsspeke_server_generate_verifier(uint8_t server_verifier[32],
bsspeke_server_ctx *server);
int
bsspeke_client_login_verify_message4(const bsspeke_login_msg4_t *msg4,
const bsspeke_client_ctx *client);
bsspeke_client_verify_server(const uint8_t server_verifier[32],
const bsspeke_client_ctx *client);
#ifdef __cplusplus
}
......
......@@ -36,6 +36,17 @@ int demo_setup(bsspeke_user_info_t *user_info)
const char *server_id = "bob.example.com";
const char *password = "P@ssword1";
// Also, because we got rid of all the
// custom message structs, we need to pretend
// to be the network ferrying messages back
// and forth between the client and server.
// More than that, we have to pretend to be the
// network interface code that marshals and
// unmarshals all of these variables out of
// JSON or whatever.
uint8_t blind[32];
uint8_t blind_salt[32];
puts("");
puts("Setup: Initializing client");
bsspeke_client_init(&client,
......@@ -45,31 +56,36 @@ int demo_setup(bsspeke_user_info_t *user_info)
puts("Setup: Initializing server");
bsspeke_server_init(&server,
server_id, strlen(server_id));
bsspeke_setup_msg1_t msg1;
bsspeke_setup_msg2_t msg2;
bsspeke_setup_msg3_t msg3;
server_id, strlen(server_id),
client_id, strlen(client_id));
puts("");
puts("Setup: Client generating message 1");
bsspeke_client_setup_generate_message1(&msg1, &client);
bsspeke_client_generate_blind(blind, &client);
puts("");
puts("Setup: Server generating message 2");
bsspeke_server_setup_generate_message2(&msg2, &msg1,
user_info,
&server);
memset(user_info->salt, '\xff', 32);
user_info->salt_len = 32;
bsspeke_server_blind_salt(blind_salt,
blind,
user_info->salt, user_info->salt_len);
puts("");
puts("Setup: Client generating message 3");
bsspeke_client_setup_generate_message3(&msg3, &msg2,
100000, 3,
&client);
user_info->phf_blocks = 100000;
user_info->phf_iterations = 3;
bsspeke_client_generate_P_and_V(user_info->P,
user_info->V,
blind_salt,
user_info->phf_blocks,
user_info->phf_iterations,
&client);
/*
puts("");
puts("Setup: Server processing message 3");
bsspeke_server_setup_process_message3(&msg3, user_info, &server);
*/
puts("");
puts("Setup: Done");
......@@ -98,37 +114,65 @@ int demo_login(bsspeke_user_info_t *user_info)
puts("Login: Initializing server");
bsspeke_server_init(&server,
server_id, strlen(server_id));
server_id, strlen(server_id),
client_id, strlen(client_id));
bsspeke_login_msg1_t msg1;
bsspeke_login_msg2_t msg2;
bsspeke_login_msg3_t msg3;
bsspeke_login_msg4_t msg4;
// Again we have to pretend to be the network and the
// data marshalling layers
uint8_t blind[32];
uint8_t blind_salt[32];
uint8_t client_verifier[32];
uint8_t server_verifier[32];
puts("");
puts("Login: Client generating message 1");
bsspeke_client_login_generate_message1(&msg1, &client);
bsspeke_client_generate_blind(blind, &client);
puts("");
puts("Login: Server generating message 2");
bsspeke_server_login_generate_message2(&msg2, &msg1,
// salt, 32,
// P, V,
// 100000, 3,
user_info,
&server);
bsspeke_server_blind_salt(blind_salt, blind,
user_info->salt,
user_info->salt_len);
bsspeke_server_generate_B(user_info->P, &server);
puts("");
puts("Login: Client generating message 3");
bsspeke_client_login_generate_message3(&msg3, &msg2, &client);
int rc_A = bsspeke_client_generate_A(blind_salt,
user_info->phf_blocks,
user_info->phf_iterations,
&client);
if( rc_A != 0 ) {
puts("Login failed to hash user's password");
return -1;
}
bsspeke_client_derive_shared_key(server.B, &client);
bsspeke_client_generate_verifier(client_verifier, &client);
puts("");
puts("Login: Server generating message 4");
bsspeke_server_login_generate_message4(&msg4, &msg3, user_info, &server);
bsspeke_server_derive_shared_key(client.A,
user_info->V,
&server);
int rc_s = bsspeke_server_verify_client(client_verifier,
&server);
if( rc_s != 0 ) {
puts("Server failed to verify client.");
puts("LOGIN FAILED");
return -1;
}
bsspeke_server_generate_verifier(server_verifier,
&server);
puts("");
puts("Login: Client verifying message 4");
bsspeke_client_login_verify_message4(&msg4, &client);
int rc_c = bsspeke_client_verify_server(server_verifier,
&client);
if( rc_c != 0 ) {
puts("Client failed to verify server.");
puts("LOGIN FAILED");
return -1;
}
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment