src/HOL/Auth/CertifiedEmail.thy
changeset 14145 2e31b8cc8788
parent 13956 8fe7e12290e1
child 14200 d8598e24f8fa
equal deleted inserted replaced
14144:7195c9b0423f 14145:2e31b8cc8788
    37 Nil: --{*The empty trace*}
    37 Nil: --{*The empty trace*}
    38      "[] \<in> certified_mail"
    38      "[] \<in> certified_mail"
    39 
    39 
    40 Fake: --{*The Spy may say anything he can say.  The sender field is correct,
    40 Fake: --{*The Spy may say anything he can say.  The sender field is correct,
    41           but agents don't use that information.*}
    41           but agents don't use that information.*}
    42       "[| evsf \<in> certified_mail; X \<in> synth(analz(knows Spy evsf))|] 
    42       "[| evsf \<in> certified_mail; X \<in> synth(analz(spies evsf))|] 
    43        ==> Says Spy B X # evsf \<in> certified_mail"
    43        ==> Says Spy B X # evsf \<in> certified_mail"
    44 
    44 
    45 FakeSSL: --{*The Spy may open SSL sessions with TTP, who is the only agent
    45 FakeSSL: --{*The Spy may open SSL sessions with TTP, who is the only agent
    46     equipped with the necessary credentials to serve as an SSL server.*}
    46     equipped with the necessary credentials to serve as an SSL server.*}
    47 	 "[| evsfssl \<in> certified_mail; X \<in> synth(analz(knows Spy evsfssl))|]
    47 	 "[| evsfssl \<in> certified_mail; X \<in> synth(analz(spies evsfssl))|]
    48           ==> Notes TTP {|Agent Spy, Agent TTP, X|} # evsfssl \<in> certified_mail"
    48           ==> Notes TTP {|Agent Spy, Agent TTP, X|} # evsfssl \<in> certified_mail"
    49 
    49 
    50 CM1: --{*The sender approaches the recipient.  The message is a number.*}
    50 CM1: --{*The sender approaches the recipient.  The message is a number.*}
    51 "[|evs1 \<in> certified_mail;
    51 "[|evs1 \<in> certified_mail;
    52    Key K \<notin> used evs1;
    52    Key K \<notin> used evs1;
    87 Reception:
    87 Reception:
    88  "[|evsr \<in> certified_mail; Says A B X \<in> set evsr|]
    88  "[|evsr \<in> certified_mail; Says A B X \<in> set evsr|]
    89   ==> Gets B X#evsr \<in> certified_mail"
    89   ==> Gets B X#evsr \<in> certified_mail"
    90 
    90 
    91 
    91 
       
    92 declare Says_imp_knows_Spy [THEN analz.Inj, dest]
       
    93 declare analz_into_parts [dest]
       
    94 
    92 (*A "possibility property": there are traces that reach the end*)
    95 (*A "possibility property": there are traces that reach the end*)
    93 lemma "\<exists>S2TTP. \<exists>evs \<in> certified_mail.
    96 lemma "\<exists>S2TTP. \<exists>evs \<in> certified_mail.
    94            Says TTP S (Crypt (priSK TTP) S2TTP) \<in> set evs"
    97            Says TTP S (Crypt (priSK TTP) S2TTP) \<in> set evs"
    95 apply (rule bexE [OF Key_supply1]) 
    98 apply (rule bexE [OF Key_supply1]) 
    96 apply (intro exI bexI)
    99 apply (intro exI bexI)
   116 
   119 
   117 lemma CM2_S2TTP_analz_knows_Spy:
   120 lemma CM2_S2TTP_analz_knows_Spy:
   118  "[|Gets R {|Agent A, Agent B, em, Number AO, Number cleartext, 
   121  "[|Gets R {|Agent A, Agent B, em, Number AO, Number cleartext, 
   119               Nonce q, S2TTP|} \<in> set evs;
   122               Nonce q, S2TTP|} \<in> set evs;
   120     evs \<in> certified_mail|] 
   123     evs \<in> certified_mail|] 
   121   ==> S2TTP \<in> analz(knows Spy evs)"
   124   ==> S2TTP \<in> analz(spies evs)"
   122 apply (drule Gets_imp_Says, simp) 
   125 apply (drule Gets_imp_Says, simp) 
   123 apply (blast dest: Says_imp_knows_Spy analz.Inj) 
   126 apply (blast dest: Says_imp_knows_Spy analz.Inj) 
   124 done
   127 done
   125 
   128 
   126 lemmas CM2_S2TTP_parts_knows_Spy = 
   129 lemmas CM2_S2TTP_parts_knows_Spy = 
   127     CM2_S2TTP_analz_knows_Spy [THEN analz_subset_parts [THEN subsetD]]
   130     CM2_S2TTP_analz_knows_Spy [THEN analz_subset_parts [THEN subsetD]]
   128 
   131 
   129 lemma hr_form_lemma [rule_format]:
   132 lemma hr_form_lemma [rule_format]:
   130  "evs \<in> certified_mail
   133  "evs \<in> certified_mail
   131   ==> hr \<notin> synth (analz (knows Spy evs)) --> 
   134   ==> hr \<notin> synth (analz (spies evs)) --> 
   132       (\<forall>S2TTP. Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|}
   135       (\<forall>S2TTP. Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|}
   133           \<in> set evs --> 
   136           \<in> set evs --> 
   134       (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|}))"
   137       (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|}))"
   135 apply (erule certified_mail.induct)
   138 apply (erule certified_mail.induct)
   136 apply (synth_analz_mono_contra, simp_all, blast+)
   139 apply (synth_analz_mono_contra, simp_all, blast+)
   140 the fakessl rule allows Spy to spoof the sender's name.  Maybe can
   143 the fakessl rule allows Spy to spoof the sender's name.  Maybe can
   141 strengthen the second disjunct with @{term "R\<noteq>Spy"}.*}
   144 strengthen the second disjunct with @{term "R\<noteq>Spy"}.*}
   142 lemma hr_form:
   145 lemma hr_form:
   143  "[|Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|} \<in> set evs;
   146  "[|Notes TTP {|Agent R, Agent TTP, S2TTP, pwd, hr|} \<in> set evs;
   144     evs \<in> certified_mail|]
   147     evs \<in> certified_mail|]
   145   ==> hr \<in> synth (analz (knows Spy evs)) | 
   148   ==> hr \<in> synth (analz (spies evs)) | 
   146       (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|})"
   149       (\<exists>clt q S em. hr = Hash {|Number clt, Nonce q, response S R q, em|})"
   147 by (blast intro: hr_form_lemma) 
   150 by (blast intro: hr_form_lemma) 
   148 
   151 
   149 lemma Spy_dont_know_private_keys [rule_format]:
   152 lemma Spy_dont_know_private_keys [dest!]:
   150     "evs \<in> certified_mail
   153     "[|Key (privateKey b A) \<in> parts (spies evs); evs \<in> certified_mail|]
   151      ==> Key (privateKey b A) \<in> parts (spies evs) --> A \<in> bad"
   154      ==> A \<in> bad"
       
   155 apply (erule rev_mp) 
   152 apply (erule certified_mail.induct, simp_all)
   156 apply (erule certified_mail.induct, simp_all)
   153 txt{*Fake*}
   157 txt{*Fake*}
   154 apply (blast dest: Fake_parts_insert[THEN subsetD]
   158 apply (blast dest: Fake_parts_insert_in_Un); 
   155                    analz_subset_parts[THEN subsetD])
       
   156 txt{*Message 1*}
   159 txt{*Message 1*}
   157 apply blast  
   160 apply blast  
   158 txt{*Message 3*}
   161 txt{*Message 3*}
   159 apply (frule_tac hr_form, assumption)
   162 apply (frule_tac hr_form, assumption)
   160 apply (elim disjE exE) 
   163 apply (elim disjE exE) 
   161 apply (simp_all add: parts_insert2) 
   164 apply (simp_all add: parts_insert2) 
   162  apply (force dest!: parts_insert_subset_Un[THEN [2] rev_subsetD] 
   165  apply (force dest!: parts_insert_subset_Un [THEN [2] rev_subsetD] 
   163                      analz_subset_parts[THEN subsetD], blast) 
   166                      analz_subset_parts [THEN subsetD], blast) 
   164 done
   167 done
   165 
   168 
   166 lemma Spy_know_private_keys_iff [simp]:
   169 lemma Spy_know_private_keys_iff [simp]:
   167     "evs \<in> certified_mail
   170     "evs \<in> certified_mail
   168      ==> (Key (privateKey b A) \<in> parts (spies evs)) = (A \<in> bad)"
   171      ==> (Key (privateKey b A) \<in> parts (spies evs)) = (A \<in> bad)"
   169 by (blast intro: Spy_dont_know_private_keys parts.Inj)
   172 by (blast intro: elim:); 
   170 
   173 
   171 lemma Spy_dont_know_TTPKey_parts [simp]:
   174 lemma Spy_dont_know_TTPKey_parts [simp]:
   172      "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> parts(knows Spy evs)" 
   175      "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> parts(spies evs)" 
   173 by simp
   176 by simp
   174 
   177 
   175 lemma Spy_dont_know_TTPKey_analz [simp]:
   178 lemma Spy_dont_know_TTPKey_analz [simp]:
   176      "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> analz(knows Spy evs)" 
   179      "evs \<in> certified_mail ==> Key (privateKey b TTP) \<notin> analz(spies evs)"
   177 by (force dest!: analz_subset_parts[THEN subsetD])
   180 by auto
   178 
   181 
   179 text{*Thus, prove any goal that assumes that @{term Spy} knows a private key
   182 text{*Thus, prove any goal that assumes that @{term Spy} knows a private key
   180 belonging to @{term TTP}*}
   183 belonging to @{term TTP}*}
   181 declare Spy_dont_know_TTPKey_parts [THEN [2] rev_notE, elim!]
   184 declare Spy_dont_know_TTPKey_parts [THEN [2] rev_notE, elim!]
   182 
   185 
   190 apply (rotate_tac 1)
   193 apply (rotate_tac 1)
   191 apply (erule rev_mp)
   194 apply (erule rev_mp)
   192 apply (erule certified_mail.induct, simp_all)
   195 apply (erule certified_mail.induct, simp_all)
   193    apply (blast  intro:parts_insertI)
   196    apply (blast  intro:parts_insertI)
   194 txt{*Fake SSL*}
   197 txt{*Fake SSL*}
   195 apply (blast dest: analz_subset_parts[THEN subsetD] parts.Body) 
   198 apply (blast dest: parts.Body) 
   196 txt{*Message 2*}
   199 txt{*Message 2*}
   197 apply (blast dest!: Says_imp_knows_Spy [THEN parts.Inj] Gets_imp_Says
   200 apply (blast dest!: Gets_imp_Says elim!: knows_Spy_partsEs)
   198              elim!: knows_Spy_partsEs)
       
   199 txt{*Message 3*}
   201 txt{*Message 3*}
   200 apply (frule_tac hr_form, assumption)
   202 apply (frule_tac hr_form, assumption)
   201 apply (elim disjE exE) 
   203 apply (elim disjE exE) 
   202 apply (simp_all add: parts_insert2)
   204 apply (simp_all add: parts_insert2)
   203 apply (blast intro: subsetD [OF parts_mono [OF Set.subset_insertI]])  
   205 apply (blast intro: subsetD [OF parts_mono [OF Set.subset_insertI]])  
   205 
   207 
   206 lemma Spy_dont_know_RPwd [rule_format]:
   208 lemma Spy_dont_know_RPwd [rule_format]:
   207     "evs \<in> certified_mail ==> Key (RPwd A) \<in> parts(spies evs) --> A \<in> bad"
   209     "evs \<in> certified_mail ==> Key (RPwd A) \<in> parts(spies evs) --> A \<in> bad"
   208 apply (erule certified_mail.induct, simp_all) 
   210 apply (erule certified_mail.induct, simp_all) 
   209 txt{*Fake*}
   211 txt{*Fake*}
   210 apply (blast dest: Fake_parts_insert[THEN subsetD]
   212 apply (blast dest: Fake_parts_insert_in_Un); 
   211                    analz_subset_parts[THEN subsetD])
       
   212 txt{*Message 1*}
   213 txt{*Message 1*}
   213 apply blast  
   214 apply blast  
   214 txt{*Message 3*}
   215 txt{*Message 3*}
   215 apply (frule CM3_k_parts_knows_Spy, assumption)
   216 apply (frule CM3_k_parts_knows_Spy, assumption)
   216 apply (frule_tac hr_form, assumption)
   217 apply (frule_tac hr_form, assumption)
   217 apply (elim disjE exE) 
   218 apply (elim disjE exE) 
   218 apply (simp_all add: parts_insert2) 
   219 apply (simp_all add: parts_insert2) 
   219 apply (force dest!: parts_insert_subset_Un[THEN [2] rev_subsetD]
   220 apply (force dest!: parts_insert_subset_Un [THEN [2] rev_subsetD]
   220                     analz_subset_parts[THEN subsetD])
   221                     analz_subset_parts [THEN subsetD])
   221 done
   222 done
   222 
   223 
   223 
   224 
   224 lemma Spy_know_RPwd_iff [simp]:
   225 lemma Spy_know_RPwd_iff [simp]:
   225     "evs \<in> certified_mail ==> (Key (RPwd A) \<in> parts(knows Spy evs)) = (A\<in>bad)"
   226     "evs \<in> certified_mail ==> (Key (RPwd A) \<in> parts(spies evs)) = (A\<in>bad)"
   226 by (auto simp add: Spy_dont_know_RPwd) 
   227 by (auto simp add: Spy_dont_know_RPwd) 
   227 
   228 
   228 lemma Spy_analz_RPwd_iff [simp]:
   229 lemma Spy_analz_RPwd_iff [simp]:
   229     "evs \<in> certified_mail ==> (Key (RPwd A) \<in> analz(knows Spy evs)) = (A\<in>bad)"
   230     "evs \<in> certified_mail ==> (Key (RPwd A) \<in> analz(spies evs)) = (A\<in>bad)"
   230 by (auto simp add: Spy_dont_know_RPwd [OF _ analz_subset_parts[THEN subsetD]]) 
   231 by (auto simp add: Spy_dont_know_RPwd [OF _ analz_subset_parts [THEN subsetD]])
   231 
   232 
   232 
   233 
   233 text{*Unused, but a guarantee of sorts*}
   234 text{*Unused, but a guarantee of sorts*}
   234 theorem CertAutenticity:
   235 theorem CertAutenticity:
   235      "[|Crypt (priSK TTP) X \<in> parts (spies evs); evs \<in> certified_mail|] 
   236      "[|Crypt (priSK TTP) X \<in> parts (spies evs); evs \<in> certified_mail|] 
   236       ==> \<exists>A. Says TTP A (Crypt (priSK TTP) X) \<in> set evs"
   237       ==> \<exists>A. Says TTP A (Crypt (priSK TTP) X) \<in> set evs"
   237 apply (erule rev_mp)
   238 apply (erule rev_mp)
   238 apply (erule certified_mail.induct, simp_all) 
   239 apply (erule certified_mail.induct, simp_all) 
   239 txt{*Fake*}
   240 txt{*Fake*}
   240 apply (blast dest: Spy_dont_know_private_keys Fake_parts_insert[THEN subsetD]
   241 apply (blast dest: Spy_dont_know_private_keys Fake_parts_insert_in_Un)
   241                    analz_subset_parts[THEN subsetD])
       
   242 txt{*Message 1*}
   242 txt{*Message 1*}
   243 apply blast 
   243 apply blast 
   244 txt{*Message 3*}
   244 txt{*Message 3*}
   245 apply (frule_tac hr_form, assumption)
   245 apply (frule_tac hr_form, assumption)
   246 apply (elim disjE exE) 
   246 apply (elim disjE exE) 
   247 apply (simp_all add: parts_insert2) 
   247 apply (simp_all add: parts_insert2 parts_insert_knows_A) 
   248 apply (force dest!: parts_insert_subset_Un[THEN [2] rev_subsetD]
   248  apply (blast dest!: Fake_parts_sing_imp_Un)
   249                     analz_subset_parts[THEN subsetD], blast) 
   249 apply (blast intro: elim:);
   250 done
   250 done
   251 
   251 
   252 
   252 
   253 subsection{*Proving Confidentiality Results*}
   253 subsection{*Proving Confidentiality Results*}
   254 
   254 
   255 lemma analz_image_freshK [rule_format]:
   255 lemma analz_image_freshK [rule_format]:
   256  "evs \<in> certified_mail ==>
   256  "evs \<in> certified_mail ==>
   257    \<forall>K KK. invKey (pubEK TTP) \<notin> KK -->
   257    \<forall>K KK. invKey (pubEK TTP) \<notin> KK -->
   258           (Key K \<in> analz (Key`KK Un (knows Spy evs))) =
   258           (Key K \<in> analz (Key`KK Un (spies evs))) =
   259           (K \<in> KK | Key K \<in> analz (knows Spy evs))"
   259           (K \<in> KK | Key K \<in> analz (spies evs))"
   260 apply (erule certified_mail.induct)
   260 apply (erule certified_mail.induct)
   261 apply (drule_tac [6] A=TTP in symKey_neq_priEK) 
   261 apply (drule_tac [6] A=TTP in symKey_neq_priEK) 
   262 apply (erule_tac [6] disjE [OF hr_form]) 
   262 apply (erule_tac [6] disjE [OF hr_form]) 
   263 apply (drule_tac [5] CM2_S2TTP_analz_knows_Spy) 
   263 apply (drule_tac [5] CM2_S2TTP_analz_knows_Spy) 
   264 prefer 9
   264 prefer 9
   270 done
   270 done
   271 
   271 
   272 
   272 
   273 lemma analz_insert_freshK:
   273 lemma analz_insert_freshK:
   274   "[| evs \<in> certified_mail;  KAB \<noteq> invKey (pubEK TTP) |] ==>
   274   "[| evs \<in> certified_mail;  KAB \<noteq> invKey (pubEK TTP) |] ==>
   275       (Key K \<in> analz (insert (Key KAB) (knows Spy evs))) =
   275       (Key K \<in> analz (insert (Key KAB) (spies evs))) =
   276       (K = KAB | Key K \<in> analz (knows Spy evs))"
   276       (K = KAB | Key K \<in> analz (spies evs))"
   277 by (simp only: analz_image_freshK analz_image_freshK_simps)
   277 by (simp only: analz_image_freshK analz_image_freshK_simps)
   278 
   278 
   279 text{*@{term S2TTP} must have originated from a valid sender
   279 text{*@{term S2TTP} must have originated from a valid sender
   280     provided @{term K} is secure.  Proof is surprisingly hard.*}
   280     provided @{term K} is secure.  Proof is surprisingly hard.*}
   281 
   281 
   282 lemma Notes_SSL_imp_used:
   282 lemma Notes_SSL_imp_used:
   283      "[|Notes B {|Agent A, Agent B, X|} \<in> set evs|] ==> X \<in> used evs"
   283      "[|Notes B {|Agent A, Agent B, X|} \<in> set evs|] ==> X \<in> used evs"
   284 by (blast dest!: Notes_imp_used)
   284 by (blast dest!: Notes_imp_used)
   285 
   285 
   286 
   286 
   287 (*The weaker version, replacing "used evs" by "parts (knows Spy evs)", 
   287 (*The weaker version, replacing "used evs" by "parts (spies evs)", 
   288    isn't inductive: message 3 case can't be proved *)
   288    isn't inductive: message 3 case can't be proved *)
   289 lemma S2TTP_sender_lemma [rule_format]:
   289 lemma S2TTP_sender_lemma [rule_format]:
   290  "evs \<in> certified_mail ==>
   290  "evs \<in> certified_mail ==>
   291     Key K \<notin> analz (knows Spy evs) -->
   291     Key K \<notin> analz (spies evs) -->
   292     (\<forall>AO. Crypt (pubEK TTP)
   292     (\<forall>AO. Crypt (pubEK TTP)
   293 	   {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs -->
   293 	   {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs -->
   294     (\<exists>m ctxt q. 
   294     (\<exists>m ctxt q. 
   295         hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
   295         hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
   296 	Says S R
   296 	Says S R
   300 	      {|Agent S, Number AO, Key K, Agent R, hs |}|} \<in> set evs))" 
   300 	      {|Agent S, Number AO, Key K, Agent R, hs |}|} \<in> set evs))" 
   301 apply (erule certified_mail.induct, analz_mono_contra)
   301 apply (erule certified_mail.induct, analz_mono_contra)
   302 apply (drule_tac [5] CM2_S2TTP_parts_knows_Spy, simp)
   302 apply (drule_tac [5] CM2_S2TTP_parts_knows_Spy, simp)
   303 apply (simp add: used_Nil Crypt_notin_initState, simp_all)
   303 apply (simp add: used_Nil Crypt_notin_initState, simp_all)
   304 txt{*Fake*}
   304 txt{*Fake*}
   305 apply (blast dest: Fake_parts_sing[THEN subsetD]
   305 apply (blast dest: Fake_parts_sing [THEN subsetD]
   306              dest!: analz_subset_parts[THEN subsetD])  
   306              dest!: analz_subset_parts [THEN subsetD])  
   307 txt{*Fake SSL*}
   307 txt{*Fake SSL*}
   308 apply (blast dest: Fake_parts_sing[THEN subsetD]
   308 apply (blast dest: Fake_parts_sing [THEN subsetD]
   309              dest: analz_subset_parts[THEN subsetD])  
   309              dest: analz_subset_parts [THEN subsetD])  
   310 txt{*Message 1*}
   310 txt{*Message 1*}
   311 apply (clarsimp, blast)
   311 apply (clarsimp, blast)
   312 txt{*Message 2*}
   312 txt{*Message 2*}
   313 apply (simp add: parts_insert2, clarify) 
   313 apply (simp add: parts_insert2, clarify) 
   314 apply (drule parts_cut, assumption, simp) 
   314 apply (drule parts_cut, assumption, simp) 
   317 apply (blast dest: Notes_SSL_imp_used used_parts_subset_parts) 
   317 apply (blast dest: Notes_SSL_imp_used used_parts_subset_parts) 
   318 done 
   318 done 
   319 
   319 
   320 lemma S2TTP_sender:
   320 lemma S2TTP_sender:
   321  "[|Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs;
   321  "[|Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|} \<in> used evs;
   322     Key K \<notin> analz (knows Spy evs);
   322     Key K \<notin> analz (spies evs);
   323     evs \<in> certified_mail|]
   323     evs \<in> certified_mail|]
   324   ==> \<exists>m ctxt q. 
   324   ==> \<exists>m ctxt q. 
   325         hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
   325         hs = Hash{|Number ctxt, Nonce q, response S R q, Crypt K (Number m)|} &
   326 	Says S R
   326 	Says S R
   327 	   {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
   327 	   {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
   351 text{*Less easy to prove @{term "m'=m"}.  Maybe needs a separate unicity
   351 text{*Less easy to prove @{term "m'=m"}.  Maybe needs a separate unicity
   352 theorem for ciphertexts of the form @{term "Crypt K (Number m)"}, 
   352 theorem for ciphertexts of the form @{term "Crypt K (Number m)"}, 
   353 where @{term K} is secure.*}
   353 where @{term K} is secure.*}
   354 lemma Key_unique_lemma [rule_format]:
   354 lemma Key_unique_lemma [rule_format]:
   355      "evs \<in> certified_mail ==>
   355      "evs \<in> certified_mail ==>
   356        Key K \<notin> analz (knows Spy evs) -->
   356        Key K \<notin> analz (spies evs) -->
   357        (\<forall>m cleartext q hs.
   357        (\<forall>m cleartext q hs.
   358         Says S R
   358         Says S R
   359            {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
   359            {|Agent S, Agent TTP, Crypt K (Number m), Number AO,
   360              Number cleartext, Nonce q,
   360              Number cleartext, Nonce q,
   361              Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|}|}
   361              Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|}|}
   365            {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
   365            {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
   366              Number cleartext', Nonce q',
   366              Number cleartext', Nonce q',
   367              Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
   367              Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
   368           \<in> set evs --> R' = R & S' = S & AO' = AO & hs' = hs))" 
   368           \<in> set evs --> R' = R & S' = S & AO' = AO & hs' = hs))" 
   369 apply (erule certified_mail.induct, analz_mono_contra, simp_all)
   369 apply (erule certified_mail.induct, analz_mono_contra, simp_all)
   370 txt{*Fake*} 
   370  prefer 2
   371 apply (blast dest!: usedI S2TTP_sender analz_subset_parts[THEN subsetD]) 
   371  txt{*Message 1*}
   372 txt{*Message 1*}
   372  apply (blast dest!: Says_imp_knows_Spy [THEN parts.Inj] new_keys_not_used Crypt_imp_keysFor)
   373 apply (blast dest!: Says_imp_knows_Spy [THEN parts.Inj] new_keys_not_used Crypt_imp_keysFor) 
   373 txt{*Fake*}
       
   374 apply (auto dest!: usedI S2TTP_sender analz_subset_parts [THEN subsetD]) 
   374 done
   375 done
   375 
   376 
   376 text{*The key determines the sender, recipient and protocol options.*}
   377 text{*The key determines the sender, recipient and protocol options.*}
   377 lemma Key_unique:
   378 lemma Key_unique:
   378       "[|Says S R
   379       "[|Says S R
   383          Says S' R'
   384          Says S' R'
   384            {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
   385            {|Agent S', Agent TTP, Crypt K (Number m'), Number AO',
   385              Number cleartext', Nonce q',
   386              Number cleartext', Nonce q',
   386              Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
   387              Crypt (pubEK TTP) {|Agent S', Number AO', Key K, Agent R', hs'|}|}
   387           \<in> set evs;
   388           \<in> set evs;
   388          Key K \<notin> analz (knows Spy evs);
   389          Key K \<notin> analz (spies evs);
   389          evs \<in> certified_mail|]
   390          evs \<in> certified_mail|]
   390        ==> R' = R & S' = S & AO' = AO & hs' = hs"
   391        ==> R' = R & S' = S & AO' = AO & hs' = hs"
   391 by (rule Key_unique_lemma, assumption+)
   392 by (rule Key_unique_lemma, assumption+)
   392 
   393 
   393 
   394 
   398       gets his return receipt (and therefore has no grounds for complaint).*}
   399       gets his return receipt (and therefore has no grounds for complaint).*}
   399 theorem Spy_see_encrypted_key_imp:
   400 theorem Spy_see_encrypted_key_imp:
   400       "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
   401       "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
   401                      Number cleartext, Nonce q, S2TTP|} \<in> set evs;
   402                      Number cleartext, Nonce q, S2TTP|} \<in> set evs;
   402          S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
   403          S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
   403          Key K \<in> analz(knows Spy evs);
   404          Key K \<in> analz(spies evs);
   404 	 evs \<in> certified_mail;
   405 	 evs \<in> certified_mail;
   405          S\<noteq>Spy|]
   406          S\<noteq>Spy|]
   406       ==> R \<in> bad & Gets S (Crypt (priSK TTP) S2TTP) \<in> set evs"
   407       ==> R \<in> bad & Gets S (Crypt (priSK TTP) S2TTP) \<in> set evs"
   407 apply (erule rev_mp)
   408 apply (erule rev_mp)
   408 apply (erule ssubst)
   409 apply (erule ssubst)
   428       "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
   429       "[|Says S R {|Agent S, Agent TTP, Crypt K (Number m), Number AO, 
   429                      Number cleartext, Nonce q, S2TTP|} \<in> set evs;
   430                      Number cleartext, Nonce q, S2TTP|} \<in> set evs;
   430          S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
   431          S2TTP = Crypt (pubEK TTP) {|Agent S, Number AO, Key K, Agent R, hs|};
   431 	 evs \<in> certified_mail;
   432 	 evs \<in> certified_mail;
   432          S\<noteq>Spy; R \<notin> bad|]
   433          S\<noteq>Spy; R \<notin> bad|]
   433       ==> Key K \<notin> analz(knows Spy evs)"
   434       ==> Key K \<notin> analz(spies evs)"
   434 by (blast dest: Spy_see_encrypted_key_imp) 
   435 by (blast dest: Spy_see_encrypted_key_imp) 
   435 
   436 
   436 
   437 
   437 text{*Agent @{term R}, who may be the Spy, doesn't receive the key
   438 text{*Agent @{term R}, who may be the Spy, doesn't receive the key
   438  until @{term S} has access to the return receipt.*} 
   439  until @{term S} has access to the return receipt.*} 
   469 apply (erule rev_mp)
   470 apply (erule rev_mp)
   470 apply (erule ssubst)
   471 apply (erule ssubst)
   471 apply (erule ssubst)
   472 apply (erule ssubst)
   472 apply (erule certified_mail.induct, simp_all)
   473 apply (erule certified_mail.induct, simp_all)
   473 txt{*Fake*} 
   474 txt{*Fake*} 
   474 apply (blast dest: Fake_parts_sing[THEN subsetD]
   475 apply (blast dest: Fake_parts_sing [THEN subsetD]
   475              dest!: analz_subset_parts[THEN subsetD])  
   476              dest!: analz_subset_parts [THEN subsetD])  
   476 txt{*Fake SSL*}
   477 txt{*Fake SSL*}
   477 apply (blast dest: Fake_parts_sing[THEN subsetD]
   478 apply (blast dest: Fake_parts_sing [THEN subsetD]
   478             dest!: analz_subset_parts[THEN subsetD])  
   479             dest!: analz_subset_parts [THEN subsetD])  
   479 txt{*Message 2*}
   480 txt{*Message 2*}
   480 apply (drule CM2_S2TTP_parts_knows_Spy, assumption)
   481 apply (drule CM2_S2TTP_parts_knows_Spy, assumption)
   481 apply (force dest: parts_cut)
   482 apply (force dest: parts_cut)
   482 txt{*Message 3*}
   483 txt{*Message 3*}
   483 apply (frule_tac hr_form, assumption)
   484 apply (frule_tac hr_form, assumption)
   484 apply (elim disjE exE, simp_all) 
   485 apply (elim disjE exE, simp_all) 
   485 apply (blast dest: Fake_parts_sing[THEN subsetD]
   486 apply (blast dest: Fake_parts_sing [THEN subsetD]
   486              dest!: analz_subset_parts[THEN subsetD]) 
   487              dest!: analz_subset_parts [THEN subsetD]) 
   487 done
   488 done
   488 
   489 
   489 end
   490 end