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, &current_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, &current_length),
                          "secure_comparator_begin_compare: invalid context");
    testsuite_fail_unless(THEMIS_BUFFER_TOO_SMALL
                              == secure_comparator_begin_compare(alice, NULL, &current_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, &current_length),
                          "secure_comparator_begin_compare: get output size (small out buffer)");

    themis_status = secure_comparator_begin_compare(alice, shared_mem, &current_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));
}
Beispiel #8
0
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, &current_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");
}
Beispiel #11
0
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;
}
Beispiel #12
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);
}
Beispiel #13
0
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;
}