src/HOL/Auth/CertifiedEmail.thy
author huffman
Sat Jun 06 09:11:12 2009 -0700 (2009-06-06)
changeset 31488 5691ccb8d6b5
parent 23746 a455e69c31cc
child 32960 69916a850301
permissions -rw-r--r--
generalize tendsto to class topological_space
paulson@13922
     1
(*  Title:      HOL/Auth/CertifiedEmail
paulson@13922
     2
    ID:         $Id$
paulson@13922
     3
    Author:     Giampaolo Bella, Christiano Longo and Lawrence C Paulson
paulson@13956
     4
*)
paulson@13922
     5
paulson@13956
     6
header{*The Certified Electronic Mail Protocol by Abadi et al.*}
paulson@13922
     7
haftmann@16417
     8
theory CertifiedEmail imports Public begin
paulson@13922
     9
wenzelm@20768
    10
abbreviation
wenzelm@21404
    11
  TTP :: agent where
wenzelm@20768
    12
  "TTP == Server"
paulson@13922
    13
wenzelm@21404
    14
abbreviation
wenzelm@21404
    15
  RPwd :: "agent => key" where
wenzelm@20768
    16
  "RPwd == shrK"
paulson@13922
    17
paulson@13922
    18
 
paulson@13922
    19
(*FIXME: the four options should be represented by pairs of 0 or 1.
paulson@13922
    20
  Right now only BothAuth is modelled.*)
paulson@13922
    21
consts
paulson@13922
    22
  NoAuth   :: nat
paulson@13922
    23
  TTPAuth  :: nat
paulson@13922
    24
  SAuth    :: nat
paulson@13922
    25
  BothAuth :: nat
paulson@13922
    26
paulson@13922
    27
text{*We formalize a fixed way of computing responses.  Could be better.*}
paulson@13922
    28
constdefs
paulson@13922
    29
  "response"    :: "agent => agent => nat => msg"
paulson@13922
    30
   "response S R q == Hash {|Agent S, Key (shrK R), Nonce q|}"
paulson@13922
    31
paulson@13922
    32
berghofe@23746
    33
inductive_set certified_mail :: "event list set"
berghofe@23746
    34
  where
paulson@13922
    35
berghofe@23746
    36
  Nil: --{*The empty trace*}
paulson@13922
    37
     "[] \<in> certified_mail"
paulson@13922
    38
berghofe@23746
    39
| Fake: --{*The Spy may say anything he can say.  The sender field is correct,
paulson@13922
    40
          but agents don't use that information.*}
paulson@14145
    41
      "[| evsf \<in> certified_mail; X \<in> synth(analz(spies evsf))|] 
paulson@13956
    42
       ==> Says Spy B X # evsf \<in> certified_mail"
paulson@13922
    43
berghofe@23746
    44
| FakeSSL: --{*The Spy may open SSL sessions with TTP, who is the only agent
paulson@13922
    45
    equipped with the necessary credentials to serve as an SSL server.*}
paulson@14145
    46
	 "[| evsfssl \<in> certified_mail; X \<in> synth(analz(spies evsfssl))|]
paulson@13922
    47
          ==> Notes TTP {|Agent Spy, Agent TTP, X|} # evsfssl \<in> certified_mail"
paulson@13922
    48
berghofe@23746
    49
| CM1: --{*The sender approaches the recipient.  The message is a number.*}
paulson@15068
    50
 "[|evs1 \<in> certified_mail;
paulson@15068
    51
    Key K \<notin> used evs1;
paulson@15068
    52
    K \<in> symKeys;
paulson@15068
    53
    Nonce q \<notin> used evs1;
paulson@15068
    54
    hs = Hash{|Number cleartext, Nonce q, response S R q, Crypt K (Number m)|};
paulson@15068
    55
    S2TTP = Crypt(pubEK TTP) {|Agent S, Number BothAuth, Key K, Agent R, hs|}|]
paulson@15068
    56
  ==> Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number BothAuth, 
paulson@15068
    57
		 Number cleartext, Nonce q, S2TTP|} # evs1 
paulson@15068
    58
	\<in> certified_mail"
paulson@13922
    59
berghofe@23746
    60
| CM2: --{*The recipient records @{term S2TTP} while transmitting it and her
paulson@13922
    61
     password to @{term TTP} over an SSL channel.*}
paulson@15068
    62
 "[|evs2 \<in> certified_mail;
paulson@15068
    63
    Gets R {|Agent S, Agent TTP, em, Number BothAuth, Number cleartext, 
paulson@15068
    64
	     Nonce q, S2TTP|} \<in> set evs2;
paulson@15068
    65
    TTP \<noteq> R;  
paulson@15068
    66
    hr = Hash {|Number cleartext, Nonce q, response S R q, em|} |]
paulson@15068
    67
  ==> 
paulson@15068
    68
   Notes TTP {|Agent R, Agent TTP, S2TTP, Key(RPwd R), hr|} # evs2
paulson@15068
    69
      \<in> certified_mail"
paulson@13922
    70
berghofe@23746
    71
| CM3: --{*@{term TTP} simultaneously reveals the key to the recipient and gives
paulson@13922
    72
         a receipt to the sender.  The SSL channel does not authenticate 
paulson@14735
    73
         the client (@{term R}), but @{term TTP} accepts the message only 
paulson@14735
    74
         if the given password is that of the claimed sender, @{term R}.
paulson@13922
    75
         He replies over the established SSL channel.*}
paulson@13922
    76
 "[|evs3 \<in> certified_mail;
paulson@14735
    77
    Notes TTP {|Agent R, Agent TTP, S2TTP, Key(RPwd R), hr|} \<in> set evs3;
paulson@14735
    78
    S2TTP = Crypt (pubEK TTP) 
paulson@14735
    79
                     {|Agent S, Number BothAuth, Key k, Agent R, hs|};
paulson@14735
    80
    TTP \<noteq> R;  hs = hr;  k \<in> symKeys|]
paulson@15068
    81
  ==> 
paulson@15068
    82
   Notes R {|Agent TTP, Agent R, Key k, hr|} # 
paulson@15068
    83
   Gets S (Crypt (priSK TTP) S2TTP) # 
paulson@15068
    84
   Says TTP S (Crypt (priSK TTP) S2TTP) # evs3 \<in> certified_mail"
paulson@13922
    85
berghofe@23746
    86
| Reception:
paulson@13922
    87
 "[|evsr \<in> certified_mail; Says A B X \<in> set evsr|]
paulson@13922
    88
  ==> Gets B X#evsr \<in> certified_mail"
paulson@13922
    89
paulson@13922
    90
paulson@14145
    91
declare Says_imp_knows_Spy [THEN analz.Inj, dest]
paulson@14145
    92
declare analz_into_parts [dest]
paulson@14145
    93
paulson@13922
    94
(*A "possibility property": there are traces that reach the end*)
paulson@14200
    95
lemma "[| Key K \<notin> used []; K \<in> symKeys |] ==> 
paulson@14200
    96
       \<exists>S2TTP. \<exists>evs \<in> certified_mail.
paulson@13956
    97
           Says TTP S (Crypt (priSK TTP) S2TTP) \<in> set evs"
paulson@13922
    98
apply (intro exI bexI)
paulson@13922
    99
apply (rule_tac [2] certified_mail.Nil
paulson@13922
   100
                    [THEN certified_mail.CM1, THEN certified_mail.Reception,
paulson@13922
   101
                     THEN certified_mail.CM2, 
paulson@14200
   102
                     THEN certified_mail.CM3]) 
paulson@14200
   103
apply (possibility, auto) 
paulson@13922
   104
done
paulson@13922
   105
paulson@13922
   106
paulson@13922
   107
lemma Gets_imp_Says:
paulson@13922
   108
 "[| Gets B X \<in> set evs; evs \<in> certified_mail |] ==> \<exists>A. Says A B X \<in> set evs"
paulson@13922
   109
apply (erule rev_mp)
paulson@13922
   110
apply (erule certified_mail.induct, auto)
paulson@13922
   111
done
paulson@13922
   112
paulson@13922
   113
paulson@13922
   114
lemma Gets_imp_parts_knows_Spy:
paulson@13922
   115
     "[|Gets A X \<in> set evs; evs \<in> certified_mail|] ==> X \<in> parts(spies evs)"
paulson@13922
   116
apply (drule Gets_imp_Says, simp)
paulson@13922
   117
apply (blast dest: Says_imp_knows_Spy parts.Inj) 
paulson@13922
   118
done
paulson@13922
   119
paulson@13922
   120
lemma CM2_S2TTP_analz_knows_Spy:
paulson@13922
   121
 "[|Gets R {|Agent A, Agent B, em, Number AO, Number cleartext, 
paulson@13922
   122
              Nonce q, S2TTP|} \<in> set evs;
paulson@13922
   123
    evs \<in> certified_mail|] 
paulson@14145
   124
  ==> S2TTP \<in> analz(spies evs)"
paulson@13922
   125
apply (drule Gets_imp_Says, simp) 
paulson@13922
   126
apply (blast dest: Says_imp_knows_Spy analz.Inj) 
paulson@13922
   127
done
paulson@13922
   128
paulson@13922
   129
lemmas CM2_S2TTP_parts_knows_Spy = 
paulson@13922
   130
    CM2_S2TTP_analz_knows_Spy [THEN analz_subset_parts [THEN subsetD]]
paulson@13922
   131
paulson@13922
   132
lemma hr_form_lemma [rule_format]:
paulson@13922
   133
 "evs \<in> certified_mail
paulson@14145
   134
  ==> hr \<notin> synth (analz (spies evs)) --> 
paulson@13922
   135
      (\<forall>S2TTP. Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|}
paulson@13922
   136
          \<in> set evs --> 
paulson@13922
   137
      (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|}))"
paulson@13922
   138
apply (erule certified_mail.induct)
paulson@13922
   139
apply (synth_analz_mono_contra, simp_all, blast+)
paulson@13922
   140
done 
paulson@13922
   141
paulson@13922
   142
text{*Cannot strengthen the first disjunct to @{term "R\<noteq>Spy"} because
paulson@13922
   143
the fakessl rule allows Spy to spoof the sender's name.  Maybe can
paulson@13922
   144
strengthen the second disjunct with @{term "R\<noteq>Spy"}.*}
paulson@13922
   145
lemma hr_form:
paulson@13922
   146
 "[|Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|} \<in> set evs;
paulson@13922
   147
    evs \<in> certified_mail|]
paulson@14145
   148
  ==> hr \<in> synth (analz (spies evs)) | 
paulson@13922
   149
      (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|})"
paulson@13922
   150
by (blast intro: hr_form_lemma) 
paulson@13922
   151
paulson@14145
   152
lemma Spy_dont_know_private_keys [dest!]:
paulson@14145
   153
    "[|Key (privateKey b A) \<in> parts (spies evs); evs \<in> certified_mail|]
paulson@14145
   154
     ==> A \<in> bad"
paulson@14145
   155
apply (erule rev_mp) 
paulson@13922
   156
apply (erule certified_mail.induct, simp_all)
paulson@13922
   157
txt{*Fake*}
paulson@14207
   158
apply (blast dest: Fake_parts_insert_in_Un) 
paulson@13922
   159
txt{*Message 1*}
paulson@13922
   160
apply blast  
paulson@13922
   161
txt{*Message 3*}
paulson@13922
   162
apply (frule_tac hr_form, assumption)
paulson@13922
   163
apply (elim disjE exE) 
paulson@13922
   164
apply (simp_all add: parts_insert2) 
paulson@14145
   165
 apply (force dest!: parts_insert_subset_Un [THEN [2] rev_subsetD] 
paulson@14145
   166
                     analz_subset_parts [THEN subsetD], blast) 
paulson@13922
   167
done
paulson@13922
   168
paulson@13922
   169
lemma Spy_know_private_keys_iff [simp]:
paulson@13922
   170
    "evs \<in> certified_mail
paulson@13922
   171
     ==> (Key (privateKey b A) \<in> parts (spies evs)) = (A \<in> bad)"
paulson@14207
   172
by blast 
paulson@13922
   173
paulson@13956
   174
lemma Spy_dont_know_TTPKey_parts [simp]:
paulson@14145
   175
     "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> parts(spies evs)" 
paulson@13956
   176
by simp
paulson@13934
   177
paulson@13956
   178
lemma Spy_dont_know_TTPKey_analz [simp]:
paulson@14145
   179
     "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> analz(spies evs)"
paulson@14145
   180
by auto
paulson@13934
   181
paulson@13934
   182
text{*Thus, prove any goal that assumes that @{term Spy} knows a private key
paulson@13934
   183
belonging to @{term TTP}*}
paulson@13956
   184
declare Spy_dont_know_TTPKey_parts [THEN [2] rev_notE, elim!]
paulson@13934
   185
paulson@13922
   186
paulson@13922
   187
lemma CM3_k_parts_knows_Spy:
paulson@13922
   188
 "[| evs \<in> certified_mail;
paulson@13922
   189
     Notes TTP {|Agent A, Agent TTP,
paulson@13956
   190
                 Crypt (pubEK TTP) {|Agent S, Number AO, Key K, 
paulson@13922
   191
                 Agent R, hs|}, Key (RPwd R), hs|} \<in> set evs|]
paulson@13922
   192
  ==> Key K \<in> parts(spies evs)"
paulson@13922
   193
apply (rotate_tac 1)
paulson@13922
   194
apply (erule rev_mp)
paulson@13922
   195
apply (erule certified_mail.induct, simp_all)
paulson@13922
   196
   apply (blast  intro:parts_insertI)
paulson@13922
   197
txt{*Fake SSL*}
paulson@14145
   198
apply (blast dest: parts.Body) 
paulson@13922
   199
txt{*Message 2*}
paulson@14145
   200
apply (blast dest!: Gets_imp_Says elim!: knows_Spy_partsEs)
paulson@13922
   201
txt{*Message 3*}
paulson@13922
   202
apply (frule_tac hr_form, assumption)
paulson@13922
   203
apply (elim disjE exE) 
paulson@13922
   204
apply (simp_all add: parts_insert2)
paulson@13922
   205
apply (blast intro: subsetD [OF parts_mono [OF Set.subset_insertI]])  
paulson@13922
   206
done
paulson@13922
   207
paulson@13922
   208
lemma Spy_dont_know_RPwd [rule_format]:
paulson@13922
   209
    "evs \<in> certified_mail ==> Key (RPwd A) \<in> parts(spies evs) --> A \<in> bad"
paulson@13922
   210
apply (erule certified_mail.induct, simp_all) 
paulson@13922
   211
txt{*Fake*}
paulson@14207
   212
apply (blast dest: Fake_parts_insert_in_Un) 
paulson@13922
   213
txt{*Message 1*}
paulson@13922
   214
apply blast  
paulson@13922
   215
txt{*Message 3*}
paulson@13922
   216
apply (frule CM3_k_parts_knows_Spy, assumption)
paulson@13922
   217
apply (frule_tac hr_form, assumption)
paulson@13922
   218
apply (elim disjE exE) 
paulson@13922
   219
apply (simp_all add: parts_insert2) 
paulson@14145
   220
apply (force dest!: parts_insert_subset_Un [THEN [2] rev_subsetD]
paulson@14145
   221
                    analz_subset_parts [THEN subsetD])
paulson@13922
   222
done
paulson@13922
   223
paulson@13922
   224
paulson@13922
   225
lemma Spy_know_RPwd_iff [simp]:
paulson@14145
   226
    "evs \<in> certified_mail ==> (Key (RPwd A) \<in> parts(spies evs)) = (A\<in>bad)"
paulson@13922
   227
by (auto simp add: Spy_dont_know_RPwd) 
paulson@13922
   228
paulson@13922
   229
lemma Spy_analz_RPwd_iff [simp]:
paulson@14145
   230
    "evs \<in> certified_mail ==> (Key (RPwd A) \<in> analz(spies evs)) = (A\<in>bad)"
paulson@14145
   231
by (auto simp add: Spy_dont_know_RPwd [OF _ analz_subset_parts [THEN subsetD]])
paulson@13922
   232
paulson@13922
   233
paulson@13922
   234
text{*Unused, but a guarantee of sorts*}
paulson@13922
   235
theorem CertAutenticity:
paulson@13956
   236
     "[|Crypt (priSK TTP) X \<in> parts (spies evs); evs \<in> certified_mail|] 
paulson@13956
   237
      ==> \<exists>A. Says TTP A (Crypt (priSK TTP) X) \<in> set evs"
paulson@13922
   238
apply (erule rev_mp)
paulson@13922
   239
apply (erule certified_mail.induct, simp_all) 
paulson@13922
   240
txt{*Fake*}
paulson@14145
   241
apply (blast dest: Spy_dont_know_private_keys Fake_parts_insert_in_Un)
paulson@13922
   242
txt{*Message 1*}
paulson@13922
   243
apply blast 
paulson@13922
   244
txt{*Message 3*}
paulson@13922
   245
apply (frule_tac hr_form, assumption)
paulson@13922
   246
apply (elim disjE exE) 
paulson@14145
   247
apply (simp_all add: parts_insert2 parts_insert_knows_A) 
paulson@14207
   248
 apply (blast dest!: Fake_parts_sing_imp_Un, blast)
paulson@13922
   249
done
paulson@13922
   250
paulson@13922
   251
paulson@13922
   252
subsection{*Proving Confidentiality Results*}
paulson@13922
   253
paulson@13922
   254
lemma analz_image_freshK [rule_format]:
paulson@13922
   255
 "evs \<in> certified_mail ==>
paulson@13956
   256
   \<forall>K KK. invKey (pubEK TTP) \<notin> KK -->
paulson@14145
   257
          (Key K \<in> analz (Key`KK Un (spies evs))) =
paulson@14145
   258
          (K \<in> KK | Key K \<in> analz (spies evs))"
paulson@13922
   259
apply (erule certified_mail.induct)
paulson@13922
   260
apply (drule_tac [6] A=TTP in symKey_neq_priEK) 
paulson@13922
   261
apply (erule_tac [6] disjE [OF hr_form]) 
paulson@13922
   262
apply (drule_tac [5] CM2_S2TTP_analz_knows_Spy) 
paulson@13922
   263
prefer 9
paulson@13922
   264
apply (elim exE)
paulson@13922
   265
apply (simp_all add: synth_analz_insert_eq
paulson@13922
   266
                     subset_trans [OF _ subset_insertI]
paulson@13922
   267
                     subset_trans [OF _ Un_upper2] 
paulson@13922
   268
                del: image_insert image_Un add: analz_image_freshK_simps)
paulson@13922
   269
done
paulson@13922
   270
paulson@13922
   271
paulson@13922
   272
lemma analz_insert_freshK:
paulson@13956
   273
  "[| evs \<in> certified_mail;  KAB \<noteq> invKey (pubEK TTP) |] ==>
paulson@14145
   274
      (Key K \<in> analz (insert (Key KAB) (spies evs))) =
paulson@14145
   275
      (K = KAB | Key K \<in> analz (spies evs))"
paulson@13922
   276
by (simp only: analz_image_freshK analz_image_freshK_simps)
paulson@13922
   277
paulson@13922
   278
text{*@{term S2TTP} must have originated from a valid sender
paulson@13922
   279
    provided @{term K} is secure.  Proof is surprisingly hard.*}
paulson@13922
   280
paulson@13922
   281
lemma Notes_SSL_imp_used:
paulson@13922
   282
     "[|Notes B {|Agent A, Agent B, X|} \<in> set evs|] ==> X \<in> used evs"
paulson@13922
   283
by (blast dest!: Notes_imp_used)
paulson@13922
   284
paulson@13922
   285
paulson@14145
   286
(*The weaker version, replacing "used evs" by "parts (spies evs)", 
paulson@13922
   287
   isn't inductive: message 3 case can't be proved *)
paulson@13922
   288
lemma S2TTP_sender_lemma [rule_format]:
paulson@13922
   289
 "evs \<in> certified_mail ==>
paulson@14145
   290
    Key K \<notin> analz (spies evs) -->
paulson@13956
   291
    (\<forall>AO. Crypt (pubEK TTP)
paulson@13922
   292
	   {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs -->
paulson@13922
   293
    (\<exists>m ctxt q. 
paulson@13922
   294
        hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
paulson@13922
   295
	Says S R
paulson@13922
   296
	   {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
paulson@13922
   297
	     Number ctxt, Nonce q,
paulson@13956
   298
	     Crypt (pubEK TTP)
paulson@13922
   299
	      {|Agent S, Number AO, Key K, Agent R, hs |}|} \<in> set evs))" 
paulson@13922
   300
apply (erule certified_mail.induct, analz_mono_contra)
paulson@13922
   301
apply (drule_tac [5] CM2_S2TTP_parts_knows_Spy, simp)
paulson@13922
   302
apply (simp add: used_Nil Crypt_notin_initState, simp_all)
paulson@13922
   303
txt{*Fake*}
paulson@14145
   304
apply (blast dest: Fake_parts_sing [THEN subsetD]
paulson@14145
   305
             dest!: analz_subset_parts [THEN subsetD])  
paulson@13922
   306
txt{*Fake SSL*}
paulson@14145
   307
apply (blast dest: Fake_parts_sing [THEN subsetD]
paulson@14145
   308
             dest: analz_subset_parts [THEN subsetD])  
paulson@13922
   309
txt{*Message 1*}
paulson@13956
   310
apply (clarsimp, blast)
paulson@13922
   311
txt{*Message 2*}
paulson@13922
   312
apply (simp add: parts_insert2, clarify) 
paulson@13922
   313
apply (drule parts_cut, assumption, simp) 
paulson@13934
   314
apply (blast intro: usedI) 
paulson@13922
   315
txt{*Message 3*} 
paulson@13922
   316
apply (blast dest: Notes_SSL_imp_used used_parts_subset_parts) 
paulson@13922
   317
done 
paulson@13922
   318
paulson@13922
   319
lemma S2TTP_sender:
paulson@13956
   320
 "[|Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs;
paulson@14145
   321
    Key K \<notin> analz (spies evs);
paulson@13922
   322
    evs \<in> certified_mail|]
paulson@13922
   323
  ==> \<exists>m ctxt q. 
paulson@13922
   324
        hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
paulson@13922
   325
	Says S R
paulson@13922
   326
	   {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
paulson@13922
   327
	     Number ctxt, Nonce q,
paulson@13956
   328
	     Crypt (pubEK TTP)
paulson@13922
   329
	      {|Agent S, Number AO, Key K, Agent R, hs |}|} \<in> set evs" 
paulson@13922
   330
by (blast intro: S2TTP_sender_lemma) 
paulson@13922
   331
paulson@13922
   332
paulson@13922
   333
text{*Nobody can have used non-existent keys!*}
paulson@14207
   334
lemma new_keys_not_used [simp]:
paulson@13922
   335
    "[|Key K \<notin> used evs; K \<in> symKeys; evs \<in> certified_mail|]
paulson@13922
   336
     ==> K \<notin> keysFor (parts (spies evs))"
paulson@13922
   337
apply (erule rev_mp) 
paulson@13922
   338
apply (erule certified_mail.induct, simp_all) 
paulson@13922
   339
txt{*Fake*}
paulson@13922
   340
apply (force dest!: keysFor_parts_insert) 
paulson@13922
   341
txt{*Message 1*}
paulson@13922
   342
apply blast 
paulson@13922
   343
txt{*Message 3*}
paulson@13922
   344
apply (frule CM3_k_parts_knows_Spy, assumption)
paulson@13922
   345
apply (frule_tac hr_form, assumption) 
paulson@13922
   346
apply (force dest!: keysFor_parts_insert)
paulson@13922
   347
done
paulson@13922
   348
paulson@13922
   349
paulson@13922
   350
text{*Less easy to prove @{term "m'=m"}.  Maybe needs a separate unicity
paulson@13926
   351
theorem for ciphertexts of the form @{term "Crypt K (Number m)"}, 
paulson@13922
   352
where @{term K} is secure.*}
paulson@13922
   353
lemma Key_unique_lemma [rule_format]:
paulson@13922
   354
     "evs \<in> certified_mail ==>
paulson@14145
   355
       Key K \<notin> analz (spies evs) -->
paulson@13922
   356
       (\<forall>m cleartext q hs.
paulson@13922
   357
        Says S R
paulson@13922
   358
           {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
paulson@13922
   359
             Number cleartext, Nonce q,
paulson@13956
   360
             Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|}|}
paulson@13922
   361
          \<in> set evs -->
paulson@13922
   362
       (\<forall>m' cleartext' q' hs'.
paulson@13922
   363
       Says S' R'
paulson@13922
   364
           {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
paulson@13922
   365
             Number cleartext', Nonce q',
paulson@13956
   366
             Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
paulson@13922
   367
          \<in> set evs --> R' = R & S' = S & AO' = AO & hs' = hs))" 
paulson@13922
   368
apply (erule certified_mail.induct, analz_mono_contra, simp_all)
paulson@14145
   369
 prefer 2
paulson@14145
   370
 txt{*Message 1*}
paulson@14145
   371
 apply (blast dest!: Says_imp_knows_Spy [THEN parts.Inj] new_keys_not_used Crypt_imp_keysFor)
paulson@14145
   372
txt{*Fake*}
paulson@14145
   373
apply (auto dest!: usedI S2TTP_sender analz_subset_parts [THEN subsetD]) 
paulson@13922
   374
done
paulson@13922
   375
paulson@13922
   376
text{*The key determines the sender, recipient and protocol options.*}
paulson@13926
   377
lemma Key_unique:
paulson@13922
   378
      "[|Says S R
paulson@13922
   379
           {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
paulson@13922
   380
             Number cleartext, Nonce q,
paulson@13956
   381
             Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|}|}
paulson@13922
   382
          \<in> set evs;
paulson@13922
   383
         Says S' R'
paulson@13922
   384
           {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
paulson@13922
   385
             Number cleartext', Nonce q',
paulson@13956
   386
             Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
paulson@13922
   387
          \<in> set evs;
paulson@14145
   388
         Key K \<notin> analz (spies evs);
paulson@13922
   389
         evs \<in> certified_mail|]
paulson@13922
   390
       ==> R' = R & S' = S & AO' = AO & hs' = hs"
paulson@13922
   391
by (rule Key_unique_lemma, assumption+)
paulson@13922
   392
paulson@13934
   393
paulson@13926
   394
subsection{*The Guarantees for Sender and Recipient*}
paulson@13926
   395
paulson@13934
   396
text{*A Sender's guarantee:
paulson@13934
   397
      If Spy gets the key then @{term R} is bad and @{term S} moreover
paulson@13922
   398
      gets his return receipt (and therefore has no grounds for complaint).*}
paulson@17689
   399
theorem S_fairness_bad_R:
paulson@13922
   400
      "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
paulson@13922
   401
                     Number cleartext, Nonce q, S2TTP|} \<in> set evs;
paulson@13956
   402
         S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
paulson@17689
   403
         Key K \<in> analz (spies evs);
paulson@13922
   404
	 evs \<in> certified_mail;
paulson@13922
   405
         S\<noteq>Spy|]
paulson@13956
   406
      ==> R \<in> bad & Gets S (Crypt (priSK TTP) S2TTP) \<in> set evs"
paulson@13922
   407
apply (erule rev_mp)
paulson@13922
   408
apply (erule ssubst)
paulson@13956
   409
apply (erule rev_mp)
paulson@13922
   410
apply (erule certified_mail.induct, simp_all)
paulson@13922
   411
txt{*Fake*}
paulson@13922
   412
apply spy_analz
paulson@13922
   413
txt{*Fake SSL*}
paulson@13922
   414
apply spy_analz
paulson@13922
   415
txt{*Message 3*}
paulson@13922
   416
apply (frule_tac hr_form, assumption)
paulson@13922
   417
apply (elim disjE exE) 
paulson@13922
   418
apply (simp_all add: synth_analz_insert_eq  
paulson@13922
   419
                     subset_trans [OF _ subset_insertI]
paulson@13922
   420
                     subset_trans [OF _ Un_upper2] 
paulson@13922
   421
                del: image_insert image_Un add: analz_image_freshK_simps) 
paulson@13922
   422
apply (simp_all add: symKey_neq_priEK analz_insert_freshK)
paulson@13922
   423
apply (blast dest: Notes_SSL_imp_used S2TTP_sender Key_unique)+
paulson@13922
   424
done
paulson@13922
   425
paulson@13922
   426
text{*Confidentially for the symmetric key*}
paulson@13922
   427
theorem Spy_not_see_encrypted_key:
paulson@13922
   428
      "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
paulson@13922
   429
                     Number cleartext, Nonce q, S2TTP|} \<in> set evs;
paulson@13956
   430
         S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
paulson@13922
   431
	 evs \<in> certified_mail;
paulson@13922
   432
         S\<noteq>Spy; R \<notin> bad|]
paulson@14145
   433
      ==> Key K \<notin> analz(spies evs)"
paulson@17689
   434
by (blast dest: S_fairness_bad_R) 
paulson@13922
   435
paulson@13922
   436
paulson@13922
   437
text{*Agent @{term R}, who may be the Spy, doesn't receive the key
paulson@13922
   438
 until @{term S} has access to the return receipt.*} 
paulson@13922
   439
theorem S_guarantee:
paulson@17689
   440
     "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
paulson@17689
   441
		    Number cleartext, Nonce q, S2TTP|} \<in> set evs;
paulson@17689
   442
	S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
paulson@17689
   443
	Notes R {|Agent TTP, Agent R, Key K, hs|} \<in> set evs;
paulson@17689
   444
	S\<noteq>Spy;  evs \<in> certified_mail|]
paulson@17689
   445
     ==> Gets S (Crypt (priSK TTP) S2TTP) \<in> set evs"
paulson@13922
   446
apply (erule rev_mp)
paulson@13922
   447
apply (erule ssubst)
paulson@13956
   448
apply (erule rev_mp)
paulson@13922
   449
apply (erule certified_mail.induct, simp_all)
paulson@13922
   450
txt{*Message 1*}
paulson@13922
   451
apply (blast dest: Notes_imp_used) 
paulson@17689
   452
txt{*Message 3*}
paulson@17689
   453
apply (blast dest: Notes_SSL_imp_used S2TTP_sender Key_unique S_fairness_bad_R) 
paulson@13922
   454
done
paulson@13922
   455
paulson@13922
   456
paulson@17689
   457
text{*If @{term R} sends message 2, and a delivery certificate exists, 
paulson@17689
   458
 then @{term R} receives the necessary key.  This result is also important
paulson@17689
   459
 to @{term S}, as it confirms the validity of the return receipt.*}
paulson@17689
   460
theorem RR_validity:
paulson@13956
   461
  "[|Crypt (priSK TTP) S2TTP \<in> used evs;
paulson@13956
   462
     S2TTP = Crypt (pubEK TTP)
paulson@13934
   463
               {|Agent S, Number AO, Key K, Agent R, 
paulson@13934
   464
                 Hash {|Number cleartext, Nonce q, r, em|}|};
paulson@13922
   465
     hr = Hash {|Number cleartext, Nonce q, r, em|};
paulson@13922
   466
     R\<noteq>Spy;  evs \<in> certified_mail|]
paulson@13922
   467
  ==> Notes R {|Agent TTP, Agent R, Key K, hr|} \<in> set evs"
paulson@13922
   468
apply (erule rev_mp)
paulson@13922
   469
apply (erule ssubst)
paulson@13922
   470
apply (erule ssubst)
paulson@13922
   471
apply (erule certified_mail.induct, simp_all)
paulson@13934
   472
txt{*Fake*} 
paulson@14145
   473
apply (blast dest: Fake_parts_sing [THEN subsetD]
paulson@14145
   474
             dest!: analz_subset_parts [THEN subsetD])  
paulson@13934
   475
txt{*Fake SSL*}
paulson@14145
   476
apply (blast dest: Fake_parts_sing [THEN subsetD]
paulson@14145
   477
            dest!: analz_subset_parts [THEN subsetD])  
paulson@13922
   478
txt{*Message 2*}
paulson@13934
   479
apply (drule CM2_S2TTP_parts_knows_Spy, assumption)
paulson@13934
   480
apply (force dest: parts_cut)
paulson@13934
   481
txt{*Message 3*}
paulson@13934
   482
apply (frule_tac hr_form, assumption)
paulson@13934
   483
apply (elim disjE exE, simp_all) 
paulson@14145
   484
apply (blast dest: Fake_parts_sing [THEN subsetD]
paulson@14145
   485
             dest!: analz_subset_parts [THEN subsetD]) 
paulson@13922
   486
done
paulson@13922
   487
paulson@13922
   488
end