src/HOL/Auth/OtwayRees_Bad.ML
changeset 2131 3106a99d30a5
parent 2107 23e8f15ec95f
child 2160 ad4382e546fc
equal deleted inserted replaced
2130:53b6e0bc8ccf 2131:3106a99d30a5
    66 goal thy "!!evs. Says S B {|N, X, X'|} : set_of_list evs ==> \
    66 goal thy "!!evs. Says S B {|N, X, X'|} : set_of_list evs ==> \
    67 \                X : analz (sees lost Spy evs)";
    67 \                X : analz (sees lost Spy evs)";
    68 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]) 1);
    68 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]) 1);
    69 qed "OR4_analz_sees_Spy";
    69 qed "OR4_analz_sees_Spy";
    70 
    70 
    71 goal thy "!!evs. Says B' A {|N, Crypt {|N,K|} K'|} : set_of_list evs ==> \
    71 goal thy "!!evs. Says Server B {|NA, X, Crypt {|NB,K|} K'|} : set_of_list evs \
    72 \                K : parts (sees lost Spy evs)";
    72 \                 ==> K : parts (sees lost Spy evs)";
    73 by (fast_tac (!claset addSEs partsEs
    73 by (fast_tac (!claset addSEs partsEs
    74                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
    74                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
    75 qed "Reveal_parts_sees_Spy";
    75 qed "Oops_parts_sees_Spy";
    76 
    76 
    77 (*OR2_analz... and OR4_analz... let us treat those cases using the same 
    77 (*OR2_analz... and OR4_analz... let us treat those cases using the same 
    78   argument as for the Fake case.  This is possible for most, but not all,
    78   argument as for the Fake case.  This is possible for most, but not all,
    79   proofs: Fake does not invent new nonces (as in OR2), and of course Fake
    79   proofs: Fake does not invent new nonces (as in OR2), and of course Fake
    80   messages originate from the Spy. *)
    80   messages originate from the Spy. *)
    85           OR4_analz_sees_Spy RS (impOfSubs analz_subset_parts));
    85           OR4_analz_sees_Spy RS (impOfSubs analz_subset_parts));
    86 
    86 
    87 val parts_Fake_tac = 
    87 val parts_Fake_tac = 
    88     forward_tac [OR2_parts_sees_Spy] 4 THEN 
    88     forward_tac [OR2_parts_sees_Spy] 4 THEN 
    89     forward_tac [OR4_parts_sees_Spy] 6 THEN
    89     forward_tac [OR4_parts_sees_Spy] 6 THEN
    90     forward_tac [Reveal_parts_sees_Spy] 7;
    90     forward_tac [Oops_parts_sees_Spy] 7;
       
    91 
       
    92 (*For proving the easier theorems about X ~: parts (sees lost Spy evs) *)
       
    93 fun parts_induct_tac i = SELECT_GOAL
       
    94     (DETERM (etac otway.induct 1 THEN parts_Fake_tac THEN
       
    95 	     (*Fake message*)
       
    96 	     TRY (best_tac (!claset addDs [impOfSubs analz_subset_parts,
       
    97 					   impOfSubs Fake_parts_insert]
       
    98                                     addss (!simpset)) 2)) THEN
       
    99      (*Base case*)
       
   100      fast_tac (!claset addss (!simpset)) 1 THEN
       
   101      ALLGOALS Asm_simp_tac) i;
    91 
   102 
    92 
   103 
    93 (** Theorems of the form X ~: parts (sees lost Spy evs) imply that NOBODY
   104 (** Theorems of the form X ~: parts (sees lost Spy evs) imply that NOBODY
    94     sends messages containing X! **)
   105     sends messages containing X! **)
    95 
   106 
    96 (*Spy never sees another agent's shared key! (unless it is leaked at start)*)
   107 (*Spy never sees another agent's shared key! (unless it's lost at start)*)
    97 goal thy 
   108 goal thy 
    98  "!!evs. [| evs : otway;  A ~: lost |]    \
   109  "!!evs. evs : otway \
    99 \        ==> Key (shrK A) ~: parts (sees lost Spy evs)";
   110 \        ==> (Key (shrK A) : parts (sees lost Spy evs)) = (A : lost)";
   100 by (etac otway.induct 1);
   111 by (parts_induct_tac 1);
   101 by parts_Fake_tac;
       
   102 by (Auto_tac());
   112 by (Auto_tac());
   103 (*Deals with Fake message*)
   113 qed "Spy_see_shrK";
   104 by (best_tac (!claset addDs [impOfSubs analz_subset_parts,
   114 Addsimps [Spy_see_shrK];
   105                              impOfSubs Fake_parts_insert]) 1);
   115 
   106 qed "Spy_not_see_shrK";
   116 goal thy 
   107 
   117  "!!evs. evs : otway \
   108 bind_thm ("Spy_not_analz_shrK",
   118 \        ==> (Key (shrK A) : analz (sees lost Spy evs)) = (A : lost)";
   109           [analz_subset_parts, Spy_not_see_shrK] MRS contra_subsetD);
   119 by (auto_tac(!claset addDs [impOfSubs analz_subset_parts], !simpset));
   110 
   120 qed "Spy_analz_shrK";
   111 Addsimps [Spy_not_see_shrK, Spy_not_analz_shrK];
   121 Addsimps [Spy_analz_shrK];
   112 
   122 
   113 (*We go to some trouble to preserve R in the 3rd and 4th subgoals
   123 goal thy  "!!A. [| Key (shrK A) : parts (sees lost Spy evs);       \
   114   As usual fast_tac cannot be used because it uses the equalities too soon*)
   124 \                  evs : otway |] ==> A:lost";
   115 val major::prems = 
   125 by (fast_tac (!claset addDs [Spy_see_shrK]) 1);
   116 goal thy  "[| Key (shrK A) : parts (sees lost Spy evs);       \
   126 qed "Spy_see_shrK_D";
   117 \             evs : otway;                                 \
   127 
   118 \             A:lost ==> R                                  \
   128 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
   119 \           |] ==> R";
   129 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
   120 by (rtac ccontr 1);
       
   121 by (rtac ([major, Spy_not_see_shrK] MRS rev_notE) 1);
       
   122 by (swap_res_tac prems 2);
       
   123 by (ALLGOALS (fast_tac (!claset addIs prems)));
       
   124 qed "Spy_see_shrK_E";
       
   125 
       
   126 bind_thm ("Spy_analz_shrK_E", 
       
   127           analz_subset_parts RS subsetD RS Spy_see_shrK_E);
       
   128 
       
   129 AddSEs [Spy_see_shrK_E, Spy_analz_shrK_E];
       
   130 
   130 
   131 
   131 
   132 (*** Future keys can't be seen or used! ***)
   132 (*** Future keys can't be seen or used! ***)
   133 
   133 
   134 (*Nobody can have SEEN keys that will be generated in the future.
   134 (*Nobody can have SEEN keys that will be generated in the future.
   137   standard Fake rule.  
   137   standard Fake rule.  
   138       The Union over C is essential for the induction! *)
   138       The Union over C is essential for the induction! *)
   139 goal thy "!!evs. evs : otway ==> \
   139 goal thy "!!evs. evs : otway ==> \
   140 \                length evs <= length evs' --> \
   140 \                length evs <= length evs' --> \
   141 \                          Key (newK evs') ~: (UN C. parts (sees lost C evs))";
   141 \                          Key (newK evs') ~: (UN C. parts (sees lost C evs))";
   142 by (etac otway.induct 1);
   142 by (parts_induct_tac 1);
   143 by parts_Fake_tac;
       
   144 (*auto_tac does not work here, as it performs safe_tac first*)
       
   145 by (ALLGOALS Asm_simp_tac);
       
   146 by (REPEAT_FIRST (best_tac (!claset addDs [impOfSubs analz_subset_parts,
   143 by (REPEAT_FIRST (best_tac (!claset addDs [impOfSubs analz_subset_parts,
   147                                        impOfSubs parts_insert_subset_Un,
   144                                        impOfSubs parts_insert_subset_Un,
   148                                        Suc_leD]
   145                                        Suc_leD]
   149                                 addss (!simpset))));
   146                                 addss (!simpset))));
   150 val lemma = result();
   147 val lemma = result();
   212 (*Nobody can have USED keys that will be generated in the future.
   209 (*Nobody can have USED keys that will be generated in the future.
   213   ...very like new_keys_not_seen*)
   210   ...very like new_keys_not_seen*)
   214 goal thy "!!evs. evs : otway ==> \
   211 goal thy "!!evs. evs : otway ==> \
   215 \                length evs <= length evs' --> \
   212 \                length evs <= length evs' --> \
   216 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   213 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   217 by (etac otway.induct 1);
   214 by (parts_induct_tac 1);
   218 by parts_Fake_tac;
       
   219 by (ALLGOALS Asm_simp_tac);
       
   220 (*OR1 and OR3*)
   215 (*OR1 and OR3*)
   221 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,2]));
   216 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,2]));
   222 (*Fake, OR2, OR4: these messages send unknown (X) components*)
   217 (*Fake, OR2, OR4: these messages send unknown (X) components*)
   223 by (REPEAT
   218 by (REPEAT
   224     (best_tac
   219     (best_tac
   240            new_keys_not_used] MRS contra_subsetD);
   235            new_keys_not_used] MRS contra_subsetD);
   241 
   236 
   242 Addsimps [new_keys_not_used, new_keys_not_analzd];
   237 Addsimps [new_keys_not_used, new_keys_not_analzd];
   243 
   238 
   244 
   239 
   245 (** Lemmas concerning the form of items passed in messages **)
   240 
       
   241 (*** Proofs involving analz ***)
       
   242 
       
   243 (*Describes the form of K and NA when the Server sends this message.  Also
       
   244   for Oops case.*)
       
   245 goal thy 
       
   246  "!!evs. [| Says Server B \
       
   247 \            {|NA, X, Crypt {|NB, K|} (shrK B)|} : set_of_list evs;  \
       
   248 \           evs : otway |]                                   \
       
   249 \        ==> (EX evt: otway. K = Key(newK evt)) &            \
       
   250 \            (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
       
   251 by (etac rev_mp 1);
       
   252 by (etac otway.induct 1);
       
   253 by (ALLGOALS (fast_tac (!claset addss (!simpset))));
       
   254 qed "Says_Server_message_form";
       
   255 
       
   256 
       
   257 (*For proofs involving analz.*)
       
   258 val analz_Fake_tac = 
       
   259     dtac OR2_analz_sees_Spy 4 THEN 
       
   260     dtac OR4_analz_sees_Spy 6 THEN
       
   261     forward_tac [Says_Server_message_form] 7 THEN
       
   262     assume_tac 7 THEN Full_simp_tac 7 THEN
       
   263     REPEAT ((eresolve_tac [bexE, exE, conjE] ORELSE' hyp_subst_tac) 7);
   246 
   264 
   247 
   265 
   248 (****
   266 (****
   249  The following is to prove theorems of the form
   267  The following is to prove theorems of the form
   250 
   268 
   255 
   273 
   256 ****)
   274 ****)
   257 
   275 
   258 
   276 
   259 (** Session keys are not used to encrypt other session keys **)
   277 (** Session keys are not used to encrypt other session keys **)
   260 
       
   261 (*Describes the form of Key K when the following message is sent.  The use of
       
   262   "parts" strengthens the induction hyp for proving the Fake case.  The
       
   263   assumptions on A are needed to prevent its being a Faked message.  (Based
       
   264   on NS_Shared/Says_S_message_form) *)
       
   265 goal thy
       
   266  "!!evs. evs: otway ==>  \
       
   267 \          Crypt {|N, Key K|} (shrK A) : parts (sees lost Spy evs) & \
       
   268 \          A ~: lost --> \
       
   269 \        (EX evt:otway. K = newK evt)";
       
   270 by (etac otway.induct 1);
       
   271 by parts_Fake_tac;
       
   272 by (Auto_tac());
       
   273 (*Deals with Fake message*)
       
   274 by (best_tac (!claset addDs [impOfSubs analz_subset_parts,
       
   275                              impOfSubs Fake_parts_insert]) 1);
       
   276 val lemma = result() RS mp;
       
   277 
       
   278 
       
   279 (*EITHER describes the form of Key K when the following message is sent, 
       
   280   OR     reduces it to the Fake case.*)
       
   281 goal thy 
       
   282  "!!evs. [| Says B' A {|N, Crypt {|N, Key K|} (shrK A)|} : set_of_list evs;  \
       
   283 \           evs : otway |]                      \
       
   284 \        ==> (EX evt:otway. K = newK evt) | Key K : analz (sees lost Spy evs)";
       
   285 by (case_tac "A : lost" 1);
       
   286 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
       
   287                       addss (!simpset)) 1);
       
   288 by (forward_tac [lemma] 1);
       
   289 by (fast_tac (!claset addEs  partsEs
       
   290                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
       
   291 by (Fast_tac 1);
       
   292 qed "Reveal_message_form";
       
   293 
       
   294 
   278 
   295 (*Lemma for the trivial direction of the if-and-only-if*)
   279 (*Lemma for the trivial direction of the if-and-only-if*)
   296 goal thy  
   280 goal thy  
   297  "!!evs. (Key K : analz (Key``nE Un sEe)) --> \
   281  "!!evs. (Key K : analz (Key``nE Un sEe)) --> \
   298 \         (K : nE | Key K : analz sEe)  ==>     \
   282 \         (K : nE | Key K : analz sEe)  ==>     \
   305 goal thy  
   289 goal thy  
   306  "!!evs. evs : otway ==> \
   290  "!!evs. evs : otway ==> \
   307 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   291 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   308 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   292 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   309 by (etac otway.induct 1);
   293 by (etac otway.induct 1);
   310 by (dtac OR2_analz_sees_Spy 4);
   294 by analz_Fake_tac;
   311 by (dtac OR4_analz_sees_Spy 6);
       
   312 by (dtac Reveal_message_form 7);
       
   313 by (REPEAT_FIRST (ares_tac [allI, lemma]));
   295 by (REPEAT_FIRST (ares_tac [allI, lemma]));
   314 by (REPEAT ((eresolve_tac [bexE, disjE] ORELSE' hyp_subst_tac) 7));
   296 by (ALLGOALS
   315 by (ALLGOALS (*Takes 28 secs*)
       
   316     (asm_simp_tac 
   297     (asm_simp_tac 
   317      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   298      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   318                          @ pushes)
   299                          @ pushes)
   319                setloop split_tac [expand_if])));
   300                setloop split_tac [expand_if])));
   320 (** LEVEL 7 **)
   301 (** LEVEL 7 **)
   321 (*Reveal case 2, OR4, OR2, Fake*) 
   302 (*OR4, OR2, Fake*) 
   322 by (EVERY (map spy_analz_tac [7,5,3,2]));
   303 by (EVERY (map spy_analz_tac [5,3,2]));
   323 (*Reveal case 1, OR3, Base*)
   304 (*Oops, OR3, Base*)
   324 by (Auto_tac());
   305 by (REPEAT (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1));
   325 qed_spec_mp "analz_image_newK";
   306 qed_spec_mp "analz_image_newK";
   326 
   307 
   327 
   308 
   328 goal thy
   309 goal thy
   329  "!!evs. evs : otway ==>                               \
   310  "!!evs. evs : otway ==>                               \
   333                                    insert_Key_singleton]) 1);
   314                                    insert_Key_singleton]) 1);
   334 by (Fast_tac 1);
   315 by (Fast_tac 1);
   335 qed "analz_insert_Key_newK";
   316 qed "analz_insert_Key_newK";
   336 
   317 
   337 
   318 
   338 (*Describes the form of K and NA when the Server sends this message.*)
   319 (*** The Key K uniquely identifies the Server's  message. **)
   339 goal thy 
   320 
   340  "!!evs. [| Says Server B \
   321 goal thy 
   341 \            {|NA, Crypt {|NA, K|} (shrK A),                      \
   322  "!!evs. evs : otway ==>                                                 \
   342 \                  Crypt {|NB, K|} (shrK B)|} : set_of_list evs;  \
   323 \   EX B' NA' NB' X'. ALL B NA NB X.                                          \
   343 \           evs : otway |]                                        \
   324 \     Says Server B {|NA, X, Crypt {|NB, K|} (shrK B)|} : set_of_list evs --> \
   344 \        ==> (EX evt:otway. K = Key(newK evt)) &            \
   325 \     B=B' & NA=NA' & NB=NB' & X=X'";
   345 \            (EX i. NA = Nonce i) &                  \
       
   346 \            (EX j. NB = Nonce j)";
       
   347 by (etac rev_mp 1);
       
   348 by (etac otway.induct 1);
       
   349 by (ALLGOALS (fast_tac (!claset addIs [less_SucI] addss (!simpset))));
       
   350 qed "Says_Server_message_form";
       
   351 
       
   352 
       
   353 (*Crucial security property, but not itself enough to guarantee correctness!
       
   354   The need for quantification over N, C seems to indicate the problem.
       
   355   Omitting the Reveal message from the description deprives us of even 
       
   356         this clue. *)
       
   357 goal thy 
       
   358  "!!evs. [| A ~: lost;  B ~: lost;  evs : otway;  evt : otway |]        \
       
   359 \    ==> Says Server B \
       
   360 \          {|NA, Crypt {|NA, Key K|} (shrK A), \
       
   361 \            Crypt {|NB, Key K|} (shrK B)|} : set_of_list evs --> \
       
   362 \        (ALL N C. Says C Spy {|N, Key K|} ~: set_of_list evs) --> \
       
   363 \        Key K ~: analz (sees lost Spy evs)";
       
   364 by (etac otway.induct 1);
       
   365 by (dtac OR2_analz_sees_Spy 4);
       
   366 by (dtac OR4_analz_sees_Spy 6);
       
   367 by (dtac Reveal_message_form 7);
       
   368 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, disjE] ORELSE' hyp_subst_tac));
       
   369 by (ALLGOALS
       
   370     (asm_full_simp_tac 
       
   371      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
       
   372                           analz_insert_Key_newK] @ pushes)
       
   373                setloop split_tac [expand_if])));
       
   374 (** LEVEL 6 **)
       
   375 (*Reveal case 1*)
       
   376 by (Fast_tac 5);
       
   377 (*OR3*)
       
   378 by (fast_tac (!claset addSIs [parts_insertI]
       
   379                       addEs [Says_imp_old_keys RS less_irrefl]
       
   380                       addss (!simpset addsimps [parts_insert2])) 3);
       
   381 (*Reveal case 2, OR4, OR2, Fake*) 
       
   382 by (rtac conjI 3);
       
   383 by (REPEAT (spy_analz_tac 1));
       
   384 val lemma = result() RS mp RS mp RSN(2,rev_notE);
       
   385 
       
   386 
       
   387 
       
   388 (*WEAK VERSION: NEED TO ELIMINATE QUANTIFICATION OVER N, C!!*)
       
   389 goal thy 
       
   390  "!!evs. [| Says Server B \
       
   391 \            {|NA, Crypt {|NA, K|} (shrK A),                      \
       
   392 \                  Crypt {|NB, K|} (shrK B)|} : set_of_list evs;  \
       
   393 \           (ALL N C. Says C Spy {|N, K|} ~: set_of_list evs);  \
       
   394 \           A ~: lost;  B ~: lost;  evs : otway |]                  \
       
   395 \        ==> K ~: analz (sees lost Spy evs)";
       
   396 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
       
   397 by (fast_tac (!claset addSEs [lemma]) 1);
       
   398 qed "Spy_not_see_encrypted_key";
       
   399 
       
   400 
       
   401 (*** Attempting to prove stronger properties ***)
       
   402 
       
   403 (** The Key K uniquely identifies the Server's  message. **)
       
   404 
       
   405 fun ex_strip_tac i = REPEAT (ares_tac [exI, conjI] i) THEN assume_tac (i+1);
       
   406 
       
   407 goal thy 
       
   408  "!!evs. evs : otway ==>                      \
       
   409 \      EX A' B' NA' NB'. ALL A B NA NB.                    \
       
   410 \       Says Server B \
       
   411 \            {|NA, Crypt {|NA, K|} (shrK A),                      \
       
   412 \                  Crypt {|NB, K|} (shrK B)|} : set_of_list evs --> \
       
   413 \       A=A' & B=B' & NA=NA' & NB=NB'";
       
   414 by (etac otway.induct 1);
   326 by (etac otway.induct 1);
   415 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   327 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   416 by (Step_tac 1);
   328 by (Step_tac 1);
   417 (*Remaining cases: OR3 and OR4*)
   329 (*Remaining cases: OR3 and OR4*)
   418 by (ex_strip_tac 2);
   330 by (ex_strip_tac 2);
   424                       delrules [conjI]    (*prevent split-up into 4 subgoals*)
   336                       delrules [conjI]    (*prevent split-up into 4 subgoals*)
   425                       addss (!simpset addsimps [parts_insertI])) 1);
   337                       addss (!simpset addsimps [parts_insertI])) 1);
   426 val lemma = result();
   338 val lemma = result();
   427 
   339 
   428 goal thy 
   340 goal thy 
   429  "!!evs. [| Says Server B                                          \
   341  "!!evs. [| Says Server B {|NA, X, Crypt {|NB, K|} (shrK B)|}      \
   430 \              {|NA, Crypt {|NA, K|} (shrK A),                     \
       
   431 \                    Crypt {|NB, K|} (shrK B)|}                    \
       
   432 \            : set_of_list evs;                                    \ 
   342 \            : set_of_list evs;                                    \ 
   433 \           Says Server B'                                         \
   343 \           Says Server B' {|NA',X',Crypt {|NB',K|} (shrK B')|}    \
   434 \              {|NA', Crypt {|NA', K|} (shrK A'),                  \
       
   435 \                     Crypt {|NB', K|} (shrK B')|}                 \
       
   436 \            : set_of_list evs;                                    \
   344 \            : set_of_list evs;                                    \
   437 \           evs : otway |]                                         \
   345 \           evs : otway |] ==> X=X' & B=B' & NA=NA' & NB=NB'";
   438 \        ==> A=A' & B=B' & NA=NA' & NB=NB'";
       
   439 by (dtac lemma 1);
   346 by (dtac lemma 1);
   440 by (REPEAT (etac exE 1));
   347 by (REPEAT (etac exE 1));
   441 (*Duplicate the assumption*)
   348 (*Duplicate the assumption*)
   442 by (forw_inst_tac [("psi", "ALL C.?P(C)")] asm_rl 1);
   349 by (forw_inst_tac [("psi", "ALL C.?P(C)")] asm_rl 1);
   443 by (fast_tac (!claset addSDs [spec]) 1);
   350 by (fast_tac (!claset addSDs [spec]) 1);
   444 qed "unique_session_keys";
   351 qed "unique_session_keys";
   445 
   352 
   446 
   353 
       
   354 (*Crucial security property, but not itself enough to guarantee correctness!*)
       
   355 goal thy 
       
   356  "!!evs. [| A ~: lost;  B ~: lost;  evs : otway;  evt : otway |]        \
       
   357 \    ==> Says Server B \
       
   358 \          {|NA, Crypt {|NA, Key K|} (shrK A), \
       
   359 \            Crypt {|NB, Key K|} (shrK B)|} : set_of_list evs --> \
       
   360 \            Says B Spy {|NA, NB, Key K|} ~: set_of_list evs -->           \
       
   361 \        Key K ~: analz (sees lost Spy evs)";
       
   362 by (etac otway.induct 1);
       
   363 by analz_Fake_tac;
       
   364 by (ALLGOALS
       
   365     (asm_full_simp_tac 
       
   366      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
       
   367                           analz_insert_Key_newK] @ pushes)
       
   368                setloop split_tac [expand_if])));
       
   369 (*OR3*)
       
   370 by (fast_tac (!claset addSIs [parts_insertI]
       
   371                       addEs [Says_imp_old_keys RS less_irrefl]
       
   372                       addss (!simpset addsimps [parts_insert2])) 3);
       
   373 (*OR4, OR2, Fake*) 
       
   374 by (REPEAT_FIRST (resolve_tac [conjI, impI] ORELSE' spy_analz_tac));
       
   375 (*Oops*) (** LEVEL 5 **)
       
   376 by (fast_tac (!claset delrules [disjE]
       
   377 		      addDs [unique_session_keys] addss (!simpset)) 1);
       
   378 val lemma = result() RS mp RS mp RSN(2,rev_notE);
       
   379 
       
   380 
       
   381 goal thy 
       
   382  "!!evs. [| Says Server B                                         \
       
   383 \            {|NA, Crypt {|NA, K|} (shrK A),                      \
       
   384 \                  Crypt {|NB, K|} (shrK B)|} : set_of_list evs;  \
       
   385 \            Says B Spy {|NA, NB, K|} ~: set_of_list evs;         \
       
   386 \           A ~: lost;  B ~: lost;  evs : otway |]                \
       
   387 \        ==> K ~: analz (sees lost Spy evs)";
       
   388 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
       
   389 by (fast_tac (!claset addSEs [lemma]) 1);
       
   390 qed "Spy_not_see_encrypted_key";
       
   391 
       
   392 
       
   393 (*** Attempting to prove stronger properties ***)
       
   394 
   447 (*Only OR1 can have caused such a part of a message to appear.
   395 (*Only OR1 can have caused such a part of a message to appear.
   448   I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it.
   396   I'm not sure why A ~= B premise is needed: OtwayRees.ML doesn't need it.
   449   Perhaps it's because OR2 has two similar-looking encrypted messages in
   397   Perhaps it's because OR2 has two similar-looking encrypted messages in
   450 	this version.*)
   398 	this version.*)
   451 goal thy 
   399 goal thy 
   452  "!!evs. [| A ~: lost;  A ~= B; evs : otway |]               \
   400  "!!evs. [| A ~: lost;  A ~= B; evs : otway |]                 \
   453 \        ==> Crypt {|NA, Agent A, Agent B|} (shrK A)        \
   401 \        ==> Crypt {|NA, Agent A, Agent B|} (shrK A)           \
   454 \             : parts (sees lost Spy evs) -->                  \
   402 \             : parts (sees lost Spy evs) -->                  \
   455 \            Says A B {|NA, Agent A, Agent B,               \
   403 \            Says A B {|NA, Agent A, Agent B,                  \
   456 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   404 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   457 \             : set_of_list evs";
   405 \             : set_of_list evs";
   458 by (etac otway.induct 1);
   406 by (parts_induct_tac 1);
   459 by parts_Fake_tac;
   407 by (Fast_tac 1);
   460 by (ALLGOALS Asm_simp_tac);
       
   461 (*Fake*)
       
   462 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   463                               impOfSubs Fake_parts_insert]) 2);
       
   464 by (Auto_tac());
       
   465 qed_spec_mp "Crypt_imp_OR1";
   408 qed_spec_mp "Crypt_imp_OR1";
   466 
   409 
   467 
   410 
   468 (*This key property is FALSE.  Somebody could make a fake message to Server
   411 (*Crucial property: If the encrypted message appears, and A has used NA
       
   412   to start a run, then it originated with the Server!*)
       
   413 (*Only it is FALSE.  Somebody could make a fake message to Server
   469           substituting some other nonce NA' for NB.*)
   414           substituting some other nonce NA' for NB.*)
   470 goal thy 
   415 goal thy 
   471  "!!evs. [| A ~: lost;  A ~= Spy;  evs : otway |]                        \
   416  "!!evs. [| A ~: lost;  A ~= Spy;  evs : otway |]                        \
   472 \        ==> Crypt {|NA, Key K|} (shrK A) : parts (sees lost Spy evs) --> \
   417 \        ==> Crypt {|NA, Key K|} (shrK A) : parts (sees lost Spy evs) --> \
   473 \            Says A B {|NA, Agent A, Agent B,  \
   418 \            Says A B {|NA, Agent A, Agent B,                  \
   474 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   419 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   475 \             : set_of_list evs --> \
   420 \             : set_of_list evs -->                            \
   476 \            (EX B NB. Says Server B               \
   421 \            (EX B NB. Says Server B                           \
   477 \                 {|NA,               \
   422 \                 {|NA,                                        \
   478 \                   Crypt {|NA, Key K|} (shrK A),              \
   423 \                   Crypt {|NA, Key K|} (shrK A),              \
   479 \                   Crypt {|NB, Key K|} (shrK B)|}             \
   424 \                   Crypt {|NB, Key K|} (shrK B)|}             \
   480 \                   : set_of_list evs)";
   425 \                   : set_of_list evs)";
   481 by (etac otway.induct 1);
   426 by (parts_induct_tac 1);
   482 by parts_Fake_tac;
       
   483 by (ALLGOALS Asm_simp_tac);
       
   484 (*Fake*)
       
   485 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   486                               impOfSubs Fake_parts_insert]) 1);
       
   487 (*OR1: it cannot be a new Nonce, contradiction.*)
   427 (*OR1: it cannot be a new Nonce, contradiction.*)
   488 by (fast_tac (!claset addSIs [parts_insertI]
   428 by (fast_tac (!claset addSIs [parts_insertI]
   489                       addSEs partsEs
   429                       addSEs partsEs
   490                       addEs [Says_imp_old_nonces RS less_irrefl]
   430                       addEs [Says_imp_old_nonces RS less_irrefl]
   491                       addss (!simpset)) 1);
   431                       addss (!simpset)) 1);
   492 (*OR3 and OR4*)  (** LEVEL 5 **)
       
   493 (*OR4*)
   432 (*OR4*)
   494 by (REPEAT (Safe_step_tac 2));
   433 by (REPEAT (Safe_step_tac 2));
   495 by (REPEAT (best_tac (!claset addSDs [parts_cut]) 3));
   434 by (REPEAT (best_tac (!claset addSDs [parts_cut]) 3));
   496 by (fast_tac (!claset addSIs [Crypt_imp_OR1]
   435 by (fast_tac (!claset addSIs [Crypt_imp_OR1]
   497                       addEs  partsEs
   436                       addEs  partsEs
   498                       addDs [Says_imp_sees_Spy RS parts.Inj]) 2);
   437                       addDs [Says_imp_sees_Spy RS parts.Inj]) 2);
   499 (*OR3*)  (** LEVEL 8 **)
   438 (*OR3*)  (** LEVEL 5 **)
   500 by (ALLGOALS (asm_simp_tac (!simpset addsimps [ex_disj_distrib])));
   439 by (ALLGOALS (asm_simp_tac (!simpset addsimps [ex_disj_distrib])));
   501 by (step_tac (!claset delrules [disjCI, impCE]) 1);
   440 by (step_tac (!claset delrules [disjCI, impCE]) 1);
   502 (*The hypotheses at this point suggest an attack in which nonce NA is used
   441 (*The hypotheses at this point suggest an attack in which nonce NA is used
   503   in two different roles:
   442   in two different roles:
   504           Says B' Server
   443           Says B' Server
   509           Says A B
   448           Says A B
   510            {|Nonce NA, Agent A, Agent B,
   449            {|Nonce NA, Agent A, Agent B,
   511              Crypt {|Nonce NA, Agent A, Agent B|} (shrK A)|}
   450              Crypt {|Nonce NA, Agent A, Agent B|} (shrK A)|}
   512           : set_of_list evsa 
   451           : set_of_list evsa 
   513 *)
   452 *)
   514 writeln "GIVE UP!";
   453 writeln "GIVE UP! on NA_Crypt_imp_Server_msg";
   515 
   454 
   516 
   455 
   517 (*Thus the key property A_can_trust probably fails too.*)
   456 (*Thus the key property A_can_trust probably fails too.*)