void send_pair_decomposed(struct network_status *net_stat) /*@ requires [?f0]world(?pub, ?key_clsfy) &*& proof_obligations(pub) &*& network_status(net_stat) &*& principal(?principal, ?count1) &*& true == bad(principal); @*/ /*@ ensures [f0]world(pub, key_clsfy) &*& proof_obligations(pub) &*& network_status(net_stat) &*& principal(principal, ?count2); @*/ { struct item *pair = network_receive(net_stat); //@ assert item(pair, ?p, pub); if (is_pair(pair)) { struct item *first = pair_get_first(pair); struct item *second = pair_get_second(pair); //@ open proof_obligations(pub); //@ assert is_public_pair_decompose(?proof1, pub); //@ assert is_public_collision(?proof2, pub); //@ proof1(p); //@ assert item(first, ?f, pub); //@ if (col) proof2(f); //@ assert item(second, ?s, pub); //@ if (col) proof2(s); //@ close proof_obligations(pub); network_send(net_stat, first); network_send(net_stat, second); item_free(first); item_free(second); } item_free(pair); }
struct item *app_receive(struct item *key) /*@ requires [?f0]world(ss_pub) &*& item(key, symmetric_key_item(?creator, ?id), ss_pub); @*/ /*@ ensures [f0]world(ss_pub) &*& item(key, symmetric_key_item(creator, id), ss_pub) &*& item(result, ?msg, ss_pub) &*& ( bad(creator) || collision_in_run() || app_send_event(creator, msg) ); @*/ { struct network_status *net_stat = network_bind_and_accept(APP_RECEIVE_PORT); struct item *m = network_receive(net_stat); struct item *hash = pair_get_first(m); struct item *message = pair_get_second(m); //@ assert item(m, pair_item(?hmac_i, ?message_i), ss_pub); //@ open [_]ss_pub(pair_item(hmac_i, message_i)); //@ if (!collision_in_run()) open [_]ss_pub(hmac_i); //@ if (!collision_in_run()) open [_]ss_pub(message_i); item_free(m); hmac_verify(hash, key, message); item_free(hash); network_disconnect(net_stat); return message; }
struct item *asymmetric_authenticated_decryption(char recipient, struct item *public_key, struct item *private_key, struct item *message) /*@ requires [?f]world(?pub) &*& generated_values(?principal1, ?count1) &*& item(public_key, ?pub_k, pub) &*& pub_k == public_key_item(?principal2, ?count2) &*& item(private_key, ?priv_k, pub) &*& priv_k == private_key_item(?principal3, ?count3) &*& item(message, ?msg, pub); @*/ /*@ ensures [f]world(pub) &*& generated_values(principal1, count1 + 1) &*& item(public_key, pub_k, pub) &*& item(private_key, priv_k, pub) &*& item(message, msg, pub) &*& item(result, ?decrypted, pub) &*& collision_in_run() ? true : msg == pair_item(?enc, ?sig) &*& enc == asymmetric_encrypted_item(?principal4, ?count4, ?pay, _) &*& sig == asymmetric_signature_item(principal2, count2, some(?msg_id), _) &*& msg_id == pair_item(data_item(cons(recipient, nil)), hash_item(some(enc))) &*& principal4 == principal3 && count4 == count3 ? pay == some(decrypted) : [_]pub(decrypted) ; @*/ { check_is_pair(message); struct item* encrypted = pair_get_first(message); check_is_asymmetric_encrypted(encrypted); struct item* signature = pair_get_second(message); struct item* rcp = create_data_item_from_char(recipient); struct item* hash = create_hash(encrypted); struct item* pair = create_pair(rcp, hash); asymmetric_signature_verify(public_key, pair, signature); struct item *result = asymmetric_decryption(private_key, encrypted); item_free(encrypted); item_free(rcp); item_free(pair); item_free(hash); item_free(signature); return result; }
struct item *client(char server, struct item *key, struct item *request) /*@ requires [?f0]world(rpc_pub, rpc_key_clsfy) &*& principal(?client, ?count) &*& item(key, symmetric_key_item(?creator, ?id), rpc_pub) &*& item(request, ?req, rpc_pub) &*& [_]rpc_pub(req) &*& true == request(creator, server, req) &*& shared_with(creator, id) == server; @*/ /*@ ensures [f0]world(rpc_pub, rpc_key_clsfy) &*& principal(client, count) &*& item(key, symmetric_key_item(creator, id), rpc_pub) &*& item(request, req, rpc_pub) &*& item(result, ?resp, rpc_pub) &*& ( col || bad(creator) || bad(server) || response(creator, server, req, resp) ); @*/ { struct network_status *net_stat = network_connect("localhost", SERVER_PORT); { struct item *tag = create_data_item_from_int(0); //@ item d = data_item(chars_of_int(0)); //@ assert item(tag, d, rpc_pub); //@ close rpc_pub(d); //@ leak rpc_pub(d); struct item *payload = create_pair(tag, request); //@ item p = pair_item(d, req); //@ assert item(payload, p, rpc_pub); //@ close rpc_pub(p); //@ leak rpc_pub(p); item_free(tag); struct item *hash = create_hmac(key, payload); //@ item h = hmac_item(creator, id, some(p)); //@ if (!col) assert item(hash, h, rpc_pub); //@ close rpc_pub(h); //@ leak rpc_pub(h); struct item *m = create_pair(hash, payload); //@ assert item(m, ?msg, rpc_pub); //@ item msg0 = pair_item(h, p); //@ if (!col) msg == msg0; //@ close rpc_pub(msg); //@ leak rpc_pub(msg); item_free(hash); item_free(payload); network_send(net_stat, m); item_free(m); } struct item *response; { struct item *r = network_receive(net_stat); check_is_pair(r); //@ assert item(r, pair_item(?h0, ?p0), rpc_pub); struct item *hmac1 = pair_get_first(r); //@ assert item(hmac1, ?h, rpc_pub); struct item *payload = pair_get_second(r); //@ assert item(payload, ?p, rpc_pub); /*@ if (!col) { assert h0 == h; assert p0 == p; open [_]rpc_pub(pair_item(h, p)); open [_]rpc_pub(h); open [_]rpc_pub(p); } @*/ struct item *hmac2 = create_hmac(key, payload); item_check_equal(hmac1, hmac2); item_free(hmac1); item_free(hmac2); item_free(r); //@ assert col || h == hmac_item(creator, id, some(p)); struct item *tag = pair_get_first(payload); check_is_data(tag); int tagValue = item_get_data_as_int(tag); if (tagValue != 1) abort(); //@ item d = data_item(chars_of_int(1)); //@ assert item(tag, ?d0, rpc_pub); //@ assert col || d == d0; item_free(tag); struct item *reqresp = pair_get_second(payload); struct item *request1 = pair_get_first(reqresp); response = pair_get_second(reqresp); //@ assert item(request1, ?req1, rpc_pub); //@ assert item(response, ?resp, rpc_pub); //@ if (!col) assert p == pair_item(d, pair_item(req1, resp)); item_free(payload); item_free(reqresp); item_check_equal(request, request1); //@ assert col || req1 == req; item_free(request1); } network_disconnect(net_stat); return response; }
void server(char server, struct item *key) /*@ requires [?f0]world(rpc_pub, rpc_key_clsfy) &*& principal(server, ?count) &*& item(key, symmetric_key_item(?creator, ?id), rpc_pub) &*& shared_with(creator, id) == server; @*/ /*@ ensures [f0]world(rpc_pub, rpc_key_clsfy) &*& principal(server, count + 1) &*& item(key, symmetric_key_item(creator, id), rpc_pub); @*/ { struct network_status *net_stat = network_bind_and_accept(SERVER_PORT); struct item *request = 0; { struct item *r = network_receive(net_stat); check_is_pair(r); //@ assert item(r, pair_item(?h0, ?p0), rpc_pub); struct item *hmac1 = pair_get_first(r); //@ assert item(hmac1, ?h, rpc_pub); struct item *payload = pair_get_second(r); //@ assert item(payload, ?p, rpc_pub); /*@ if (!col) { assert h0 == h; assert p0 == p; open [_]rpc_pub(pair_item(h, p)); open [_]rpc_pub(h); open [_]rpc_pub(p); } @*/ struct item *hmac2 = create_hmac(key, payload); item_check_equal(hmac1, hmac2); item_free(hmac1); item_free(hmac2); item_free(r); //@ assert col || h == hmac_item(creator, id, some(p)); struct item *tag = pair_get_first(payload); check_is_data(tag); int tagValue = item_get_data_as_int(tag); if (tagValue != 0) abort(); //@ item d = data_item(chars_of_int(0)); request = pair_get_second(payload); /*@ if (!col) { assert item(tag, d, rpc_pub); assert item(request, ?req, rpc_pub); assert p == pair_item(d, req); } @*/ item_free(tag); item_free(payload); } //@ assert item(request, ?req, rpc_pub); struct item *response = compute_response(server, request); //@ assert item(response, ?resp, rpc_pub); { struct item *reqresp = create_pair(request, response); //@ item p = pair_item(req, resp); //@ assert item(reqresp, p, rpc_pub); //@ close rpc_pub(p); //@ leak rpc_pub(p); item_free(response); item_free(request); struct item *tag = create_data_item_from_int(1); struct item *payload = create_pair(tag, reqresp); //@ item d = data_item(chars_of_int(1)); //@ close rpc_pub(d); //@ leak rpc_pub(d); //@ assert item(payload, pair_item(d, p), rpc_pub); //@ close rpc_pub(pair_item(d, p)); //@ leak rpc_pub(pair_item(d, p)); item_free(tag); item_free(reqresp); struct item *hash = create_hmac(key, payload); //@ item h = hmac_item(creator, id, some(pair_item(d, p))); //@ if (!col) assert item(hash, h, rpc_pub); //@ close rpc_pub(h); //@ leak rpc_pub(h); struct item *m = create_pair(hash, payload); //@ assert item(m, ?msg, rpc_pub); //@ if (!col) msg == pair_item(h, pair_item(d, p)); //@ if (!col) assert item(m, msg, rpc_pub); //@ close rpc_pub(msg); //@ leak rpc_pub(msg); item_free(hash); item_free(payload); network_send(net_stat, m); item_free(m); } network_disconnect(net_stat); }