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;
}
Ejemplo n.º 2
0
void send_asymmetric_decrypted(struct network_status *net_stat, struct keypair *keypair)
  /*@ requires [?f0]world(?pub, ?key_clsfy) &*&
               keypair(keypair, ?attacker_id, ?id, ?info, pub) &*&
               proof_obligations(pub) &*&
               network_status(net_stat) &*&
               principal(attacker_id, ?count1) &*&
               true == bad(attacker_id); @*/
  /*@ ensures  [f0]world(pub, key_clsfy) &*&
               keypair(keypair, attacker_id, id, info, pub) &*&
               proof_obligations(pub) &*&
               network_status(net_stat) &*&
               principal(attacker_id, ?count2); @*/
{
  struct item *key = network_receive(net_stat);
  //@ assert item(key, ?k, pub);
  if (is_private_key(key))
  {
    //@ assert k == private_key_item(?principal2, ?count2);
    struct item *enc = network_receive(net_stat);
    //@ assert item(enc, ?e, pub);
    if (is_asymmetric_encrypted(enc))
    {
      //@ assert e == asymmetric_encrypted_item(?principal3, ?count3, ?pay, ?ent);
      char tag;
      //@ close chars(&tag, 1, _);
      random_buffer_(&tag, 1);
      //@ open chars(&tag, 1, _);
      if (tag == TAG_DATA || tag == TAG_PAIR ||           
          tag == TAG_NONCE || tag == TAG_HASH ||          
          tag == TAG_SYMMETRIC_KEY || tag == TAG_PUBLIC_KEY ||   
          tag == TAG_PRIVATE_KEY || tag == TAG_HMAC ||    
          tag == TAG_SYMMETRIC_ENC || tag == TAG_ASYMMETRIC_ENC ||  
          tag == TAG_ASYMMETRIC_SIG)
      {
        struct item *dec = asymmetric_decryption(key, enc, tag);
        //@ assert item(dec, ?d, pub);
        //@ open proof_obligations(pub);
        /*@ if (col)
            {
              assert [_]pub(d);
            }
            else if (principal2 == principal3 && count2 == count3)
            {
              assert pay == some(d);
              assert is_public_asymmetric_decrypted(?proof, pub);
              proof(e);
            }
            else
            {
              assert [_]pub(d);
            }
        @*/
        network_send(net_stat, dec);
        //@ close proof_obligations(pub);
        item_free(dec);
      }
    }
    item_free(enc);
  }
  item_free(key);
}