static int alice_function(void) { size_t input_length = current_length; themis_status_t themis_status; current_length = sizeof(shared_mem); themis_status = secure_comparator_proceed_compare(alice, shared_mem, input_length, shared_mem, ¤t_length); switch (themis_status) { case THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER: if (0 == current_length) { testsuite_fail_if(true, "secure_comparator_proceed_compare: invalid output length"); return TEST_STOP_ERROR; } return TEST_CONTINUE; case THEMIS_SUCCESS: if (current_length > 0) { testsuite_fail_if(true, "secure_comparator_proceed_compare: invalid output length"); return TEST_STOP_ERROR; } return TEST_STOP_SUCCESS; default: return TEST_STOP_ERROR; } }
static void schedule(void) { int (*peer_run)(void) = bob_function; int res = TEST_CONTINUE; themis_status_t themis_status; /* alice starts */ testsuite_fail_unless(THEMIS_INVALID_PARAMETER == secure_comparator_begin_compare(NULL, shared_mem, ¤t_length), "secure_comparator_begin_compare: invalid context"); testsuite_fail_unless(THEMIS_BUFFER_TOO_SMALL == secure_comparator_begin_compare(alice, NULL, ¤t_length), "secure_comparator_begin_compare: get output size (NULL out buffer)"); current_length--; testsuite_fail_unless(THEMIS_BUFFER_TOO_SMALL == secure_comparator_begin_compare(alice, shared_mem, ¤t_length), "secure_comparator_begin_compare: get output size (small out buffer)"); themis_status = secure_comparator_begin_compare(alice, shared_mem, ¤t_length); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != themis_status) { testsuite_fail_if(true, "secure_comparator_begin_compare: failed"); return; } while (TEST_CONTINUE == res) { res = peer_run(); peer_run = (peer_run == alice_function) ? bob_function : alice_function; } testsuite_fail_if(res, "secure comparator: protocol exchange"); }
static void server_function(void) { uint8_t recv_buf[2048]; ssize_t bytes_received; if (current_length > 0) { bytes_received = secure_session_receive((server.session), recv_buf, sizeof(recv_buf)); } else { /* Nothing to receive. Do nothing */ return; } if (bytes_received < 0) { testsuite_fail_if(bytes_received, "secure_session_receive failed"); return; } size_t remote_id_length = 0; if (THEMIS_BUFFER_TOO_SMALL != secure_session_get_remote_id(server.session, NULL, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed (length_determination)"); return; } uint8_t* remote_id = malloc(remote_id_length); assert(remote_id); if (THEMIS_SUCCESS != secure_session_get_remote_id(server.session, remote_id, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed"); free(remote_id); return; } testsuite_fail_unless(remote_id_length == strlen(client.id) && 0 == memcmp(remote_id, client.id, strlen(client.id)), "secure_session remote id getting"); free(remote_id); if (0 == bytes_received) { /* This was a key agreement packet. Nothing to do */ return; } if (bytes_received > 0) { /* We received some data. Echo it back to the client. */ ssize_t bytes_sent = secure_session_send((server.session), recv_buf, (size_t)bytes_received); if (bytes_sent == bytes_received) { /* Check whether data was indeed encrypted (it should not be the same as in * data_to_send) */ testsuite_fail_if(((size_t)bytes_sent == current_length) || (!memcmp(recv_buf, shared_mem, bytes_sent)), "secure_session server message wrap"); } else { testsuite_fail_if(true, "secure_session_send failed"); } } }
static void test_basic_flow_no_transport(void) { themis_status_t res; memcpy(&(client.transport), &transport, sizeof(secure_session_user_callbacks_t)); client.transport.user_data = &client; memcpy(&(server.transport), &transport, sizeof(secure_session_user_callbacks_t)); server.transport.user_data = &server; client.session = secure_session_create(client.id, strlen(client.id), client.priv, client.priv_length, &(client.transport)); if (client.session == NULL) { testsuite_fail_if(false, "secure_session_init failed"); return; } server.session = secure_session_create(server.id, strlen(server.id), server.priv, server.priv_length, &(server.transport)); if (server.session == NULL) { testsuite_fail_if(false, "secure_session_init failed"); secure_session_destroy((client.session)); return; } schedule_no_transport(); res = secure_session_destroy((server.session)); if (res) { testsuite_fail_if(res, "secure_session_destroy failed"); } res = secure_session_destroy((client.session)); if (res) { testsuite_fail_if(res, "secure_session_destroy failed"); } }
static void schedule_no_transport(void) { int res = client_function_no_transport(); while (TEST_CONTINUE == res) { server_function_no_transport(); res = client_function_no_transport(); } testsuite_fail_if(res, "secure session: basic flow (no transport)"); }
static void schedule(void) { int res = client_function(); while (TEST_CONTINUE == res) { server_function(); res = client_function(); } testsuite_fail_if(res, "secure session: basic flow"); }
static void corrupt_bob_step2(secure_comparator_t *bob, const void *input, size_t input_length, void *output, size_t *output_length) { /* Let's assume bob is malicious and uses zeroes instead of random numbers */ ge_p3 g2a; ge_p3 g3a; ge_p3 g2b; ge_p3 g3b; ge_frombytes_vartime(&g2a, (const unsigned char *)input); ge_frombytes_vartime(&g3a, ((const unsigned char *)input) + (3 * ED25519_GE_LENGTH)); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(bob, input, input_length, output, output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } memset(bob->rand2, 0, sizeof(bob->rand2)); memset(bob->rand3, 0, sizeof(bob->rand3)); ge_scalarmult_base(&g2b, bob->rand2); ge_scalarmult_base(&g3b, bob->rand3); ge_scalarmult_blinded(&(bob->g2), bob->rand2, &g2a); ge_scalarmult_blinded(&(bob->g3), bob->rand3, &g3a); memset(bob->rand, 0, sizeof(bob->rand)); ge_scalarmult_blinded(&(bob->P), bob->rand, &(bob->g3)); ge_double_scalarmult_vartime((ge_p2 *)&(bob->Q), bob->secret, &(bob->g2), bob->rand); ge_p2_to_p3(&(bob->Q), (const ge_p2 *)&(bob->Q)); ge_p3_tobytes((unsigned char *)output, &g2b); ed_sign(3, bob->rand2, ((unsigned char *)output) + ED25519_GE_LENGTH); ge_p3_tobytes(((unsigned char *)output) + (3 * ED25519_GE_LENGTH), &g3b); ed_sign(4, bob->rand3, ((unsigned char *)output) + (4 * ED25519_GE_LENGTH)); ge_p3_tobytes(((unsigned char *)output) + (6 * ED25519_GE_LENGTH), &(bob->P)); ge_p3_tobytes(((unsigned char *)output) + (7 * ED25519_GE_LENGTH), &(bob->Q)); ed_dbl_base_sign(5, bob->rand, bob->secret, &(bob->g2), &(bob->g3), ((unsigned char *)output) + (8 * ED25519_GE_LENGTH)); }
static void test_basic_ka_flow(void) { uint8_t key_buffer[KEY_BUFFER_SIZE]; size_t key_buffer_length = sizeof(key_buffer); uint8_t peer1_shared_secret[SHARED_SECRET_BUFFER_SIZE]; size_t peer1_shared_secret_length = sizeof(peer1_shared_secret); uint8_t peer2_shared_secret[SHARED_SECRET_BUFFER_SIZE]; size_t peer2_shared_secret_length = sizeof(peer2_shared_secret); uint8_t peer2_private[SHARED_SECRET_BUFFER_SIZE]; size_t peer2_private_length = sizeof(peer2_private); soter_status_t res; soter_asym_ka_t *peer1 = soter_asym_ka_create(SOTER_ASYM_KA_EC_P256); soter_asym_ka_t *peer2 = soter_asym_ka_create(SOTER_ASYM_KA_EC_P256); if ((!peer1) || (!peer2)) { goto err; } res = soter_asym_ka_gen_key(peer1); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_gen_key fail"); goto err; } res = soter_asym_ka_gen_key(peer2); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_gen_key fail"); goto err; } res = soter_asym_ka_export_key(peer2, key_buffer, &key_buffer_length, false); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_export_key fail"); goto err; } res = soter_asym_ka_derive(peer1, key_buffer, key_buffer_length, peer1_shared_secret, &peer1_shared_secret_length); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_derive fail"); goto err; } key_buffer_length = sizeof(key_buffer); res = soter_asym_ka_export_key(peer1, key_buffer, &key_buffer_length, false); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_export_key fail"); goto err; } res = soter_asym_ka_derive(peer2, key_buffer, key_buffer_length, peer2_shared_secret, &peer2_shared_secret_length); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_derive fail"); goto err; } testsuite_fail_unless((peer1_shared_secret_length == peer2_shared_secret_length) && !memcmp(peer1_shared_secret, peer2_shared_secret, peer1_shared_secret_length), "Basic ECDH"); res = soter_asym_ka_export_key(peer2, peer2_private, &peer2_private_length, true); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_export_key fail"); goto err; } res = soter_asym_ka_destroy(peer2); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_destroy fail"); goto err; } peer2 = soter_asym_ka_create(SOTER_ASYM_KA_EC_P256); if (!peer2) { testsuite_fail_if(NULL == peer2, "soter_asym_ka_create fail"); goto err; } res = soter_asym_ka_import_key(peer2, peer2_private, peer2_private_length); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_import_key fail"); goto err; } peer2_shared_secret_length = sizeof(peer2_shared_secret); res = soter_asym_ka_derive(peer2, key_buffer, key_buffer_length, peer2_shared_secret, &peer2_shared_secret_length); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_derive fail"); goto err; } testsuite_fail_unless((peer1_shared_secret_length == peer2_shared_secret_length) && !memcmp(peer1_shared_secret, peer2_shared_secret, peer1_shared_secret_length), "Basic ECDH with imported key"); err: if (peer1) { res = soter_asym_ka_destroy(peer1); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_destroy fail"); } } if (peer2) { res = soter_asym_ka_destroy(peer2); if (SOTER_SUCCESS != res) { testsuite_fail_unless(SOTER_SUCCESS == res, "soter_asym_ka_destroy fail"); } } }
static void secure_comparator_api_test(void) { /* setup */ themis_status_t themis_status; secret_length = rand_int(MAX_SECRET_SIZE); if (SOTER_SUCCESS != soter_rand(secret, secret_length)) { testsuite_fail_if(true, "soter_rand failed"); return; } /* match */ alice = secure_comparator_create(); if (!alice) { testsuite_fail_if(true, "secure_comparator_create failed"); return; } bob = secure_comparator_create(); if (!bob) { testsuite_fail_if(true, "secure_comparator_create failed"); secure_comparator_destroy(alice); alice = NULL; return; } testsuite_fail_unless(THEMIS_INVALID_PARAMETER == secure_comparator_append_secret(NULL, secret, secret_length), "secure_comparator_append_secret: invalid context"); testsuite_fail_unless(THEMIS_INVALID_PARAMETER == secure_comparator_append_secret(alice, NULL, secret_length), "secure_comparator_append_secret: invalid input buffer"); testsuite_fail_unless(THEMIS_INVALID_PARAMETER == secure_comparator_append_secret(alice, secret, 0), "secure_comparator_append_secret: invalid input length"); themis_status = secure_comparator_append_secret(alice, secret, secret_length); if (THEMIS_SUCCESS != themis_status) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); secure_comparator_destroy(bob); bob = NULL; secure_comparator_destroy(alice); alice = NULL; return; } themis_status = secure_comparator_append_secret(bob, secret, secret_length); if (THEMIS_SUCCESS != themis_status) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); secure_comparator_destroy(bob); bob = NULL; secure_comparator_destroy(alice); alice = NULL; return; } schedule(); testsuite_fail_unless((THEMIS_SCOMPARE_MATCH == secure_comparator_get_result(alice)) && (THEMIS_SCOMPARE_MATCH == secure_comparator_get_result(bob)), "compare result match"); testsuite_fail_unless(THEMIS_INVALID_PARAMETER == secure_comparator_destroy(NULL), "secure_comparator_destroy: invalid context"); testsuite_fail_unless(THEMIS_SUCCESS == secure_comparator_destroy(bob), "secure_comparator_destroy: destroy bob"); testsuite_fail_unless(THEMIS_SUCCESS == secure_comparator_destroy(alice), "secure_comparator_destroy: destroy alice"); bob = NULL; alice = NULL; alice = secure_comparator_create(); if (!alice) { testsuite_fail_if(true, "secure_comparator_create failed"); return; } bob = secure_comparator_create(); if (!bob) { testsuite_fail_if(true, "secure_comparator_create failed"); secure_comparator_destroy(alice); alice = NULL; return; } themis_status = secure_comparator_append_secret(alice, secret, secret_length); if (THEMIS_SUCCESS != themis_status) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); secure_comparator_destroy(bob); bob = NULL; secure_comparator_destroy(alice); alice = NULL; return; } themis_status = secure_comparator_append_secret(bob, secret, secret_length - 1); if (THEMIS_SUCCESS != themis_status) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); secure_comparator_destroy(bob); bob = NULL; secure_comparator_destroy(alice); alice = NULL; return; } schedule(); testsuite_fail_unless((THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(alice)) && (THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(bob)), "compare result no match"); testsuite_fail_unless(THEMIS_SUCCESS == secure_comparator_destroy(bob), "secure_comparator_destroy: destroy bob"); testsuite_fail_unless(THEMIS_SUCCESS == secure_comparator_destroy(alice), "secure_comparator_destroy: destroy alice"); bob = NULL; alice = NULL; }
void secure_comparator_security_test(void) { const char alice_secret[] = "alice secret"; const char bob_secret[] = "bob secret"; size_t output_length = sizeof(shared_mem); secure_comparator_t alice, bob; if (THEMIS_SUCCESS != secure_comparator_init(&alice)) { testsuite_fail_if(true, "secure_comparator_init failed"); return; } if (THEMIS_SUCCESS != secure_comparator_init(&bob)) { testsuite_fail_if(true, "secure_comparator_init failed"); return; } if (THEMIS_SUCCESS != secure_comparator_append_secret(&alice, alice_secret, sizeof(alice_secret))) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); return; } if (THEMIS_SUCCESS != secure_comparator_append_secret(&bob, bob_secret, sizeof(bob_secret))) { testsuite_fail_if(true, "secure_comparator_append_secret failed"); return; } current_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_begin_compare(&alice, shared_mem, ¤t_length)) { testsuite_fail_if(true, "secure_comparator_begin_compare failed"); return; } corrupt_alice_step1(&alice, shared_mem); corrupt_bob_step2(&bob, shared_mem, current_length, shared_mem, &output_length); current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(&alice, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SCOMPARE_SEND_OUTPUT_TO_PEER != secure_comparator_proceed_compare(&bob, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } current_length = output_length; output_length = sizeof(shared_mem); if (THEMIS_SUCCESS != secure_comparator_proceed_compare(&alice, shared_mem, current_length, shared_mem, &output_length)) { testsuite_fail_if(true, "secure_comparator_proceed_compare failed"); return; } testsuite_fail_unless((THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(&alice)) && (THEMIS_SCOMPARE_NO_MATCH == secure_comparator_get_result(&bob)), "compare result no match"); }
static int sign_test(soter_sign_alg_t alg) { char test_data[]="test message"; size_t test_data_length=strlen(test_data); soter_sign_ctx_t* ctx=NULL; uint8_t* signature=NULL; size_t signature_length=0; ctx=soter_sign_create(alg,NULL,0,NULL,0); if(!ctx){ testsuite_fail_if(!ctx, "soter_sign_ctx_t == NULL"); return -1; } uint8_t private_key[8192]; size_t private_key_length=sizeof(private_key); uint8_t public_key[8192]; size_t public_key_length=sizeof(public_key); soter_status_t res; res=soter_sign_export_key(ctx, private_key, &private_key_length, true); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS,"soter_sign_export_key (private key) fail"); soter_sign_destroy(ctx); return -6; } res=soter_sign_export_key(ctx, public_key, &public_key_length, false); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS,"soter_sign_export_key (public key) fail"); soter_sign_destroy(ctx); return -7; } res=soter_sign_destroy(ctx); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS,"soter_sign_destroy fail"); return -8; } soter_sign_ctx_t* sctx=NULL; sctx=soter_sign_create(alg,private_key,private_key_length,NULL,0); if(!sctx){ testsuite_fail_if(!sctx, "soter_sign_ctx_t == NULL 2"); return -1; } res=soter_sign_update(sctx, test_data, test_data_length); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS, "soter_sign_update fail"); soter_sign_destroy(sctx); return -2; } res=soter_sign_final(sctx, signature, &signature_length); if(res!=SOTER_BUFFER_TOO_SMALL){ testsuite_fail_if(res!=SOTER_BUFFER_TOO_SMALL, "soter_sign_final (signature length determine) fail"); soter_sign_destroy(sctx); return -3; } signature=malloc(signature_length); if(!signature){ testsuite_fail_if(!signature, "out of memory"); soter_sign_destroy(ctx); return -4; } res=soter_sign_final(sctx, signature, &signature_length); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS, "soter_sign_final fail"); soter_sign_destroy(sctx); return -5; } res=soter_sign_destroy(sctx); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS,"soter_sign_destroy fail"); return -8; } soter_verify_ctx_t* vctx=NULL; vctx=soter_verify_create(alg, NULL, 0, public_key, public_key_length); if(!vctx){ testsuite_fail_if(!vctx, "soter_verify_ctx_t == NULL"); return -9; } res=soter_verify_update(vctx, test_data, test_data_length); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS, "soter_verify_update fail"); soter_verify_destroy(vctx); return -10; } res=soter_verify_final(vctx, signature, signature_length); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS, "soter_verify_final fail"); soter_verify_destroy(vctx); return -11; } res=soter_sign_destroy(vctx); if(res!=SOTER_SUCCESS){ testsuite_fail_if(res!=SOTER_SUCCESS,"soter_sign_destroy fail"); return -12; } return 0; }
static void soter_sign_api_test() { uint8_t priv[MAX_TEST_KEY]; size_t priv_length = sizeof(priv); uint8_t pub[MAX_TEST_KEY]; size_t pub_length = sizeof(pub); uint8_t message[MAX_TEST_DATA]; size_t message_length = rand_int(MAX_TEST_DATA); uint8_t signature[MAX_TEST_DATA]; size_t signature_length = sizeof(signature); soter_status_t res; if (soter_rand(message, message_length)) { testsuite_fail_if(true, "soter_rand failed"); return; } soter_sign_ctx_t *sign_ctx = soter_sign_create(SOTER_SIGN_ecdsa_none_pkcs8, NULL, 0, NULL, 0); if (!sign_ctx) { testsuite_fail_if(true, "soter_sign_create failed"); return; } res = soter_sign_export_key(sign_ctx, priv, &priv_length, true); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_sign_export_key failed"); soter_sign_destroy(sign_ctx); return; } res = soter_sign_export_key(sign_ctx, pub, &pub_length, false); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_sign_export_key failed"); soter_sign_destroy(sign_ctx); return; } soter_sign_destroy(sign_ctx); sign_ctx = soter_sign_create((soter_sign_alg_t)-1, priv, priv_length, NULL, 0); testsuite_fail_if(sign_ctx, "soter_sign_create: invalid algorithm"); sign_ctx = soter_sign_create(SOTER_SIGN_ecdsa_none_pkcs8, priv, priv_length - 1, NULL, 0); testsuite_fail_if(sign_ctx, "soter_sign_create: invalid private key length"); sign_ctx = soter_sign_create(SOTER_SIGN_ecdsa_none_pkcs8, priv, priv_length, NULL, 0); if (!sign_ctx) { testsuite_fail_if(true, "soter_sign_create failed"); return; } testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_sign_update(NULL, message, message_length), "soter_sign_update: invalid context"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_sign_update(sign_ctx, NULL, message_length), "soter_sign_update: invalid message"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_sign_update(sign_ctx, message, 0), "soter_sign_update: invalid message length"); res = soter_sign_update(sign_ctx, message, message_length); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_sign_update failed"); soter_sign_destroy(sign_ctx); return; } testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_sign_final(NULL, signature, &signature_length), "soter_sign_final: invalid context"); testsuite_fail_unless(SOTER_BUFFER_TOO_SMALL == soter_sign_final(sign_ctx, NULL, &signature_length), "soter_sign_final: get output size (NULL out buffer)"); signature_length--; testsuite_fail_unless(SOTER_BUFFER_TOO_SMALL == soter_sign_final(sign_ctx, signature, &signature_length), "soter_sign_final: get output size (small out buffer)"); res = soter_sign_final(sign_ctx, signature, &signature_length); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_sign_final failed"); soter_sign_destroy(sign_ctx); return; } testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_sign_destroy(NULL), "soter_sign_destroy: invalid context"); res = soter_sign_destroy(sign_ctx); if (SOTER_SUCCESS != res){ testsuite_fail_if(true, "soter_sign_destroy failed"); return; } sign_ctx = soter_verify_create((soter_sign_alg_t)-1, NULL, 0, pub, pub_length); testsuite_fail_if(sign_ctx, "soter_verify_create: invalid algorithm"); sign_ctx = soter_verify_create(SOTER_SIGN_ecdsa_none_pkcs8, NULL, 0, pub, pub_length - 1); testsuite_fail_if(sign_ctx, "soter_verify_create: invalid public key length"); sign_ctx = soter_verify_create(SOTER_SIGN_ecdsa_none_pkcs8, NULL, 0, pub, pub_length); if (!sign_ctx) { testsuite_fail_if(true, "soter_verify_create failed"); return; } testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_update(NULL, message, message_length), "soter_verify_update: invalid context"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_update(sign_ctx, NULL, message_length), "soter_verify_update: invalid message"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_update(sign_ctx, message, 0), "soter_verify_update: invalid message length"); res = soter_verify_update(sign_ctx, message, message_length); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_verify_update failed"); soter_verify_destroy(sign_ctx); return; } testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_final(NULL, signature, signature_length), "soter_verify_final: invalid context"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_final(sign_ctx, NULL, signature_length), "soter_verify_final: invalid signature buffer"); testsuite_fail_unless(SOTER_INVALID_SIGNATURE == soter_verify_final(sign_ctx, signature, signature_length - 1), "soter_verify_final: invalid signature length"); signature[signature_length / 2]++; testsuite_fail_unless(SOTER_INVALID_SIGNATURE == soter_verify_final(sign_ctx, signature, signature_length), "soter_verify_final: invalid signature value"); signature[signature_length / 2]--; testsuite_fail_unless(SOTER_SUCCESS == soter_verify_final(sign_ctx, signature, signature_length), "soter_verify_final: normal flow"); testsuite_fail_unless(SOTER_INVALID_PARAMETER == soter_verify_destroy(NULL), "soter_verify_destroy: invalid context"); res = soter_verify_destroy(sign_ctx); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_verify_destroy failed"); return; } sign_ctx = soter_verify_create(SOTER_SIGN_ecdsa_none_pkcs8, NULL, 0, pub, pub_length); if (!sign_ctx) { testsuite_fail_if(true, "soter_verify_create failed"); return; } message[message_length / 2]++; res = soter_verify_update(sign_ctx, message, message_length); if (SOTER_SUCCESS != res) { testsuite_fail_if(true, "soter_verify_update failed"); soter_verify_destroy(sign_ctx); return; } message[message_length / 2]--; testsuite_fail_unless(SOTER_INVALID_SIGNATURE == soter_verify_final(sign_ctx, signature, signature_length), "soter_verify_final: wrong signed message"); soter_verify_destroy(sign_ctx); }
static void soter_sign_test() { testsuite_fail_if(sign_test(SOTER_SIGN_rsa_pss_pkcs8),"soter sign SOTER_SIGN_rsa_pss_pkcs8"); testsuite_fail_if(sign_test(SOTER_SIGN_ecdsa_none_pkcs8),"soter sign SOTER_SIGN_ecdsa_none_pkcs8"); }
static void server_function_no_transport(void) { uint8_t recv_buf[2048]; ssize_t bytes_received; uint8_t processing_buf[2048]; ssize_t processing_buf_size = sizeof(processing_buf); themis_status_t res; if (current_length > 0) { bytes_received = on_receive_data(recv_buf, sizeof(recv_buf), NULL); res = secure_session_unwrap((server.session), recv_buf, bytes_received, processing_buf, (size_t*)(&processing_buf_size)); } else { /* Nothing to receive. Do nothing */ return; } size_t remote_id_length = 0; if (THEMIS_BUFFER_TOO_SMALL != secure_session_get_remote_id(server.session, NULL, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed (length_determination)"); return; } uint8_t* remote_id = malloc(remote_id_length); assert(remote_id); if (THEMIS_SUCCESS != secure_session_get_remote_id(server.session, remote_id, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed"); free(remote_id); return; } testsuite_fail_unless(remote_id_length == strlen(client.id) && 0 == memcmp(remote_id, client.id, strlen(client.id)), "secure_session remote id getting"); free(remote_id); if ((THEMIS_SSESSION_SEND_OUTPUT_TO_PEER == res) && (processing_buf_size > 0)) { /* This is key agreement data. Return response to the client. */ on_send_data(processing_buf, processing_buf_size, NULL); return; } if ((THEMIS_SUCCESS == res) && (processing_buf_size > 0)) { ssize_t bytes_sent = 0; /* This is actual data. Echo it to the client. */ if (!secure_session_is_established((server.session))) { /* Should not happen */ testsuite_fail_if(true, "secure_session_unwrap failed"); return; } memcpy(recv_buf, processing_buf, (size_t)processing_buf_size); res = secure_session_wrap((server.session), recv_buf, processing_buf_size, processing_buf, (size_t*)(&bytes_sent)); if (THEMIS_BUFFER_TOO_SMALL != res) { testsuite_fail_if(true, "secure_session_wrap failed"); return; } res = secure_session_wrap((server.session), recv_buf, processing_buf_size, processing_buf, (size_t*)(&bytes_sent)); if (THEMIS_SUCCESS != res) { testsuite_fail_if(true, "secure_session_wrap failed"); return; } testsuite_fail_if(processing_buf_size == bytes_sent, "secure_session server message wrap"); on_send_data(processing_buf, bytes_sent, NULL); return; } testsuite_fail_if(true, "secure_session_unwrap failed"); }
static int client_function_no_transport(void) { static bool connected = false; themis_status_t res; uint8_t recv_buf[2048]; ssize_t bytes_received = 0; uint8_t processing_buf[2048]; size_t processing_buf_size = 0; /* Client is not connected yet. Initiate key agreement */ if (!connected) { res = secure_session_generate_connect_request((client.session), processing_buf, (size_t*)(&processing_buf_size)); if (THEMIS_BUFFER_TOO_SMALL != res) { testsuite_fail_if(res, "secure_session_generate_connect_request failed"); return TEST_STOP_ERROR; } res = secure_session_generate_connect_request((client.session), processing_buf, (size_t*)(&processing_buf_size)); if (THEMIS_SUCCESS == res) { /* This test-send function never fails, so we do not check for error here */ on_send_data(processing_buf, processing_buf_size, NULL); connected = true; return TEST_CONTINUE; } testsuite_fail_if(res, "secure_session_generate_connect_request failed"); return TEST_STOP_ERROR; } if (secure_session_is_established((client.session))) { size_t remote_id_length = 0; if (THEMIS_BUFFER_TOO_SMALL != secure_session_get_remote_id(client.session, NULL, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed (length_determination)"); return TEST_STOP_ERROR; } uint8_t* remote_id = malloc(remote_id_length); assert(remote_id); if (THEMIS_SUCCESS != secure_session_get_remote_id(client.session, remote_id, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed"); free(remote_id); return TEST_STOP_ERROR; } testsuite_fail_unless(remote_id_length == strlen(server.id) && 0 == memcmp(remote_id, server.id, strlen(server.id)), "secure_session remote id getting"); free(remote_id); static int messages_to_send = MESSAGES_TO_SEND; /* Connection is already established. */ static uint8_t data_to_send[MAX_MESSAGE_SIZE]; static size_t length_to_send; processing_buf_size = sizeof(processing_buf); /* If there is anything to receive, receive it */ if (current_length) { bytes_received = on_receive_data(recv_buf, sizeof(recv_buf), NULL); if (bytes_received > 0) { res = secure_session_unwrap((client.session), recv_buf, (size_t)bytes_received, processing_buf, (size_t*)(&processing_buf_size)); if (THEMIS_SUCCESS != res) { testsuite_fail_if(res, "secure_session_unwrap failed"); return TEST_STOP_ERROR; } /* The server should echo our previously sent data */ testsuite_fail_if(current_length == (size_t)processing_buf_size, "secure_session message send/receive"); messages_to_send--; if (!messages_to_send) { return TEST_STOP_SUCCESS; } } else { /* We shoud receive something. */ testsuite_fail_if(bytes_received, "secure_session_receive failed"); return TEST_STOP_ERROR; } } length_to_send = rand_int(MAX_MESSAGE_SIZE - 64); if (THEMIS_SUCCESS != soter_rand(data_to_send, length_to_send)) { testsuite_fail_if(true, "soter_rand failed"); return TEST_STOP_ERROR; } processing_buf_size = sizeof(processing_buf); res = secure_session_wrap((client.session), data_to_send, length_to_send, processing_buf, (size_t*)(&processing_buf_size)); if (THEMIS_SUCCESS != res) { testsuite_fail_if(res, "secure_session_wrap failed"); return TEST_STOP_ERROR; } /* This test-send function never fails, so we do not check for error here */ on_send_data(processing_buf, processing_buf_size, NULL); testsuite_fail_if(length_to_send == current_length, "secure_session client message wrap"); return TEST_CONTINUE; } /* Connection is not established. We should receive some key agreement data. */ bytes_received = on_receive_data(recv_buf, sizeof(recv_buf), NULL); if (bytes_received <= 0) { testsuite_fail_if(bytes_received, "secure_session_receive failed"); return TEST_STOP_ERROR; } res = secure_session_unwrap((client.session), recv_buf, bytes_received, processing_buf, (size_t*)(&processing_buf_size)); if (THEMIS_SUCCESS == res) { if (secure_session_is_established((client.session))) { /* Negotiation completed. Clear the shared memory. */ current_length = 0; return TEST_CONTINUE; } testsuite_fail_if(true, "secure_session_unwrap failed"); return TEST_STOP_ERROR; } if (THEMIS_BUFFER_TOO_SMALL != res) { testsuite_fail_if(true, "secure_session_unwrap failed"); return TEST_STOP_ERROR; } res = secure_session_unwrap((client.session), recv_buf, bytes_received, processing_buf, (size_t*)(&processing_buf_size)); if ((THEMIS_SSESSION_SEND_OUTPUT_TO_PEER == res) && (processing_buf_size > 0)) { /* This test-send function never fails, so we do not check for error here */ on_send_data(processing_buf, processing_buf_size, NULL); return TEST_CONTINUE; } testsuite_fail_if(true, "secure_session_unwrap failed"); return TEST_STOP_ERROR; }
static int client_function(void) { static bool connected = false; themis_status_t res; uint8_t recv_buf[2048]; ssize_t bytes_received; ssize_t bytes_sent; /* Client is not connected yet. Initiate key agreement */ if (!connected) { res = secure_session_connect((client.session)); if (THEMIS_SUCCESS == res) { connected = true; return TEST_CONTINUE; } testsuite_fail_if(res, "secure_session_connect failed"); return TEST_STOP_ERROR; } if (secure_session_is_established(client.session)) { size_t remote_id_length = 0; if (THEMIS_BUFFER_TOO_SMALL != secure_session_get_remote_id(client.session, NULL, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed (length_determination)"); return TEST_STOP_ERROR; } uint8_t* remote_id = malloc(remote_id_length); assert(remote_id); if (THEMIS_SUCCESS != secure_session_get_remote_id(client.session, remote_id, &remote_id_length)) { testsuite_fail_if(true, "remote id getting failed"); free(remote_id); return TEST_STOP_ERROR; } testsuite_fail_unless(remote_id_length == strlen(server.id) && 0 == memcmp(remote_id, server.id, strlen(server.id)), "secure_session remote id getting"); free(remote_id); static int messages_to_send = MESSAGES_TO_SEND; /* Connection is already established. */ static uint8_t data_to_send[MAX_MESSAGE_SIZE]; static size_t length_to_send; /* If there is anything to receive, receive it */ if (current_length) { bytes_received = secure_session_receive(client.session, recv_buf, sizeof(recv_buf)); if (bytes_received > 0) { /* The server should echo our previously sent data */ testsuite_fail_unless((length_to_send == (size_t)bytes_received) && (!memcmp(recv_buf, data_to_send, bytes_received)), "secure_session message send/receive"); messages_to_send--; if (!messages_to_send) { return TEST_STOP_SUCCESS; } } else { /* We shoud receive something. */ testsuite_fail_if(bytes_received, "secure_session_receive failed"); return TEST_STOP_ERROR; } } length_to_send = rand_int(MAX_MESSAGE_SIZE); if (THEMIS_SUCCESS != soter_rand(data_to_send, length_to_send)) { testsuite_fail_if(true, "soter_rand failed"); return TEST_STOP_ERROR; } bytes_sent = secure_session_send((client.session), data_to_send, length_to_send); if (bytes_sent > 0) { /* Check whether data was indeed encrypted (it should not be the same as in * data_to_send) */ testsuite_fail_if((length_to_send == current_length) || (!memcmp(data_to_send, shared_mem, length_to_send)), "secure_session client message wrap"); return TEST_CONTINUE; } testsuite_fail_if(true, "secure_session_send failed"); return TEST_STOP_ERROR; } /* Connection is not established. We should receive some key agreement data. */ bytes_received = secure_session_receive((client.session), recv_buf, sizeof(recv_buf)); /* When key agreement data is received and processed client gets 0 in return value (no data * for client is received) */ if (bytes_received) { testsuite_fail_if(bytes_received, "secure_session_receive failed"); return TEST_STOP_ERROR; } if (secure_session_is_established((client.session))) { /* Negotiation completed. Clear the shared memory. */ current_length = 0; } return TEST_CONTINUE; }