src/HOL/Auth/OtwayRees.ML
changeset 2064 5a5e508e2a2b
parent 2053 6c0594bfa726
child 2071 0debdc018d26
equal deleted inserted replaced
2063:2395bc55b3e6 2064:5a5e508e2a2b
     9 
     9 
    10 From page 244 of
    10 From page 244 of
    11   Burrows, Abadi and Needham.  A Logic of Authentication.
    11   Burrows, Abadi and Needham.  A Logic of Authentication.
    12   Proc. Royal Soc. 426 (1989)
    12   Proc. Royal Soc. 426 (1989)
    13 *)
    13 *)
    14 
       
    15 
    14 
    16 open OtwayRees;
    15 open OtwayRees;
    17 
    16 
    18 proof_timing:=true;
    17 proof_timing:=true;
    19 HOL_quantifiers := false;
    18 HOL_quantifiers := false;
    87     in  tac OR2_parts_sees_Spy 4 THEN 
    86     in  tac OR2_parts_sees_Spy 4 THEN 
    88         tac OR4_parts_sees_Spy 6 THEN
    87         tac OR4_parts_sees_Spy 6 THEN
    89         tac Reveal_parts_sees_Spy 7
    88         tac Reveal_parts_sees_Spy 7
    90     end;
    89     end;
    91 
    90 
       
    91 (*For proving the easier theorems about X ~: parts (sees lost Spy evs) *)
       
    92 fun parts_induct_tac i = SELECT_GOAL
       
    93     (DETERM (etac otway.induct 1 THEN parts_Fake_tac THEN
       
    94 	     (*Fake message*)
       
    95 	     TRY (best_tac (!claset addDs [impOfSubs analz_subset_parts,
       
    96 					   impOfSubs Fake_parts_insert]
       
    97                                     addss (!simpset)) 2)) THEN
       
    98      (*Base case*)
       
    99      fast_tac (!claset addss (!simpset)) 1 THEN
       
   100      ALLGOALS Asm_simp_tac) i;
    92 
   101 
    93 (** Theorems of the form X ~: parts (sees lost Spy evs) imply that NOBODY
   102 (** Theorems of the form X ~: parts (sees lost Spy evs) imply that NOBODY
    94     sends messages containing X! **)
   103     sends messages containing X! **)
    95 
   104 
    96 (*Spy never sees lost another agent's shared key! (unless it is leaked at start)*)
   105 (*Spy never sees another agent's shared key! (unless it's lost at start)*)
    97 goal thy 
   106 goal thy 
    98  "!!evs. [| evs : otway lost;  A ~: lost |]    \
   107  "!!evs. [| evs : otway lost;  A ~: lost |]    \
    99 \        ==> Key (shrK A) ~: parts (sees lost Spy evs)";
   108 \        ==> Key (shrK A) ~: parts (sees lost Spy evs)";
   100 by (etac otway.induct 1);
   109 by (parts_induct_tac 1);
   101 by parts_Fake_tac;
       
   102 by (Auto_tac());
   110 by (Auto_tac());
   103 (*Deals with Fake message*)
       
   104 by (best_tac (!claset addDs [impOfSubs analz_subset_parts,
       
   105                              impOfSubs Fake_parts_insert]) 1);
       
   106 qed "Spy_not_see_shrK";
   111 qed "Spy_not_see_shrK";
   107 
   112 
   108 bind_thm ("Spy_not_analz_shrK",
   113 bind_thm ("Spy_not_analz_shrK",
   109           [analz_subset_parts, Spy_not_see_shrK] MRS contra_subsetD);
   114           [analz_subset_parts, Spy_not_see_shrK] MRS contra_subsetD);
   110 
   115 
   137   standard Fake rule.  
   142   standard Fake rule.  
   138       The Union over C is essential for the induction! *)
   143       The Union over C is essential for the induction! *)
   139 goal thy "!!evs. evs : otway lost ==> \
   144 goal thy "!!evs. evs : otway lost ==> \
   140 \                length evs <= length evs' --> \
   145 \                length evs <= length evs' --> \
   141 \                          Key (newK evs') ~: (UN C. parts (sees lost C evs))";
   146 \                          Key (newK evs') ~: (UN C. parts (sees lost C evs))";
   142 by (etac otway.induct 1);
   147 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,
   148 by (REPEAT_FIRST (best_tac (!claset addDs [impOfSubs analz_subset_parts,
   147                                            impOfSubs parts_insert_subset_Un,
   149                                            impOfSubs parts_insert_subset_Un,
   148                                            Suc_leD]
   150                                            Suc_leD]
   149                                     addss (!simpset))));
   151                                     addss (!simpset))));
   150 val lemma = result();
   152 val lemma = result();
   212 (*Nobody can have USED keys that will be generated in the future.
   214 (*Nobody can have USED keys that will be generated in the future.
   213   ...very like new_keys_not_seen*)
   215   ...very like new_keys_not_seen*)
   214 goal thy "!!evs. evs : otway lost ==> \
   216 goal thy "!!evs. evs : otway lost ==> \
   215 \                length evs <= length evs' --> \
   217 \                length evs <= length evs' --> \
   216 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   218 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   217 by (etac otway.induct 1);
   219 by (parts_induct_tac 1);
   218 by parts_Fake_tac;
       
   219 by (ALLGOALS Asm_simp_tac);
       
   220 (*OR1 and OR3*)
   220 (*OR1 and OR3*)
   221 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,2]));
   221 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,2]));
   222 (*Fake, OR2, OR4: these messages send unknown (X) components*)
   222 (*Fake, OR2, OR4: these messages send unknown (X) components*)
   223 by (EVERY 
   223 by (EVERY 
   224     (map
   224     (map
   246            new_keys_not_used] MRS contra_subsetD);
   246            new_keys_not_used] MRS contra_subsetD);
   247 
   247 
   248 Addsimps [new_keys_not_used, new_keys_not_analzd];
   248 Addsimps [new_keys_not_used, new_keys_not_analzd];
   249 
   249 
   250 
   250 
   251 (** Lemmas concerning the form of items passed in messages **)
   251 
       
   252 (*** Proofs involving analz ***)
       
   253 
       
   254 (*Describes the form of Key K when the following message is sent.  The use of
       
   255   "parts" strengthens the induction hyp for proving the Fake case.  The
       
   256   assumption A ~: lost prevents its being a Faked message.  (Based
       
   257   on NS_Shared/Says_S_message_form) *)
       
   258 goal thy
       
   259  "!!evs. evs: otway lost ==>                                           \
       
   260 \          Crypt {|N, Key K|} (shrK A) : parts (sees lost Spy evs) &   \
       
   261 \          A ~: lost -->                                               \
       
   262 \        (EX evt: otway lost. K = newK evt)";
       
   263 by (parts_induct_tac 1);
       
   264 by (Auto_tac());
       
   265 qed_spec_mp "Reveal_message_lemma";
       
   266 
       
   267 (*EITHER describes the form of Key K when the following message is sent, 
       
   268   OR     reduces it to the Fake case.*)
       
   269 
       
   270 goal thy 
       
   271  "!!evs. [| Says B' A {|N, Crypt {|N, Key K|} (shrK A)|} : set_of_list evs;  \
       
   272 \           evs : otway lost |]                      \
       
   273 \        ==> (EX evt: otway lost. K = newK evt)          \
       
   274 \          | Key K : analz (sees lost Spy evs)";
       
   275 br (Reveal_message_lemma RS disjCI) 1;
       
   276 ba 1;
       
   277 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
       
   278                       addDs [impOfSubs analz_subset_parts]
       
   279                       addss (!simpset)) 1);
       
   280 qed "Reveal_message_form";
       
   281 
       
   282 
       
   283 (*For proofs involving analz.  We again instantiate the variable to "lost".*)
       
   284 val analz_Fake_tac = 
       
   285     dres_inst_tac [("lost","lost")] OR2_analz_sees_Spy 4 THEN 
       
   286     dres_inst_tac [("lost","lost")] OR4_analz_sees_Spy 6 THEN
       
   287     forw_inst_tac [("lost","lost")] Reveal_message_form 7;
   252 
   288 
   253 
   289 
   254 (****
   290 (****
   255  The following is to prove theorems of the form
   291  The following is to prove theorems of the form
   256 
   292 
   281 result();
   317 result();
   282 
   318 
   283 
   319 
   284 (** Session keys are not used to encrypt other session keys **)
   320 (** Session keys are not used to encrypt other session keys **)
   285 
   321 
   286 (*Describes the form of Key K when the following message is sent.  The use of
       
   287   "parts" strengthens the induction hyp for proving the Fake case.  The
       
   288   assumptions on A are needed to prevent its being a Faked message.  (Based
       
   289   on NS_Shared/Says_S_message_form) *)
       
   290 goal thy
       
   291  "!!evs. evs: otway lost ==>                                           \
       
   292 \          Crypt {|N, Key K|} (shrK A) : parts (sees lost Spy evs) & \
       
   293 \          A ~: lost -->                                           \
       
   294 \        (EX evt: otway lost. K = newK evt)";
       
   295 by (etac otway.induct 1);
       
   296 by parts_Fake_tac;
       
   297 by (ALLGOALS Asm_simp_tac);
       
   298 (*Deals with Fake message*)
       
   299 by (best_tac (!claset addDs [impOfSubs analz_subset_parts,
       
   300                              impOfSubs Fake_parts_insert]) 2);
       
   301 by (Auto_tac());
       
   302 val lemma = result() RS mp;
       
   303 
       
   304 
       
   305 (*EITHER describes the form of Key K when the following message is sent, 
       
   306   OR     reduces it to the Fake case.*)
       
   307 goal thy 
       
   308  "!!evs. [| Says B' A {|N, Crypt {|N, Key K|} (shrK A)|} : set_of_list evs;  \
       
   309 \           evs : otway lost |]                      \
       
   310 \        ==> (EX evt: otway lost. K = newK evt)          \
       
   311 \          | Key K : analz (sees lost Spy evs)";
       
   312 by (excluded_middle_tac "A : lost" 1);
       
   313 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
       
   314                       addss (!simpset)) 2);
       
   315 by (forward_tac [lemma] 1);
       
   316 by (fast_tac (!claset addEs  partsEs
       
   317                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
       
   318 by (Fast_tac 1);
       
   319 qed "Reveal_message_form";
       
   320 
       
   321 
       
   322 (*The equality makes the induction hypothesis easier to apply*)
   322 (*The equality makes the induction hypothesis easier to apply*)
   323 goal thy  
   323 goal thy  
   324  "!!evs. evs : otway lost ==> \
   324  "!!evs. evs : otway lost ==> \
   325 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   325 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   326 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   326 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   327 by (etac otway.induct 1);
   327 by (etac otway.induct 1);
   328 by (dtac OR2_analz_sees_Spy 4);
   328 by analz_Fake_tac;
   329 by (dtac OR4_analz_sees_Spy 6);
       
   330 by (dtac Reveal_message_form 7);
       
   331 by (REPEAT_FIRST (ares_tac [allI, analz_image_newK_lemma]));
   329 by (REPEAT_FIRST (ares_tac [allI, analz_image_newK_lemma]));
   332 by (REPEAT ((eresolve_tac [bexE, disjE] ORELSE' hyp_subst_tac) 7));
   330 by (REPEAT ((eresolve_tac [bexE, disjE] ORELSE' hyp_subst_tac) 7));
   333 by (ALLGOALS (*Takes 28 secs*)
   331 by (ALLGOALS (*Takes 28 secs*)
   334     (asm_simp_tac 
   332     (asm_simp_tac 
   335      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   333      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   337                setloop split_tac [expand_if])));
   335                setloop split_tac [expand_if])));
   338 (** LEVEL 7 **)
   336 (** LEVEL 7 **)
   339 (*Reveal case 2, OR4, OR2, Fake*) 
   337 (*Reveal case 2, OR4, OR2, Fake*) 
   340 by (EVERY (map spy_analz_tac [7,5,3,2]));
   338 by (EVERY (map spy_analz_tac [7,5,3,2]));
   341 (*Reveal case 1, OR3, Base*)
   339 (*Reveal case 1, OR3, Base*)
   342 by (Auto_tac());
   340 by (REPEAT (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1));
   343 qed_spec_mp "analz_image_newK";
   341 qed_spec_mp "analz_image_newK";
   344 
   342 
   345 
   343 
   346 goal thy
   344 goal thy
   347  "!!evs. evs : otway lost ==>                               \
   345  "!!evs. evs : otway lost ==>                               \
   368 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   366 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   369 by (Step_tac 1);
   367 by (Step_tac 1);
   370 (*Remaining cases: OR3 and OR4*)
   368 (*Remaining cases: OR3 and OR4*)
   371 by (ex_strip_tac 2);
   369 by (ex_strip_tac 2);
   372 by (Fast_tac 2);
   370 by (Fast_tac 2);
   373 by (excluded_middle_tac "K = Key(newK evsa)" 1);
   371 by (expand_case_tac "K = ?y" 1);
   374 by (Asm_simp_tac 1);
   372 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   375 by (REPEAT (ares_tac [refl,exI,impI,conjI] 1));
       
   376 (*...we assume X is a very new message, and handle this case by contradiction*)
   373 (*...we assume X is a very new message, and handle this case by contradiction*)
   377 by (fast_tac (!claset addEs [Says_imp_old_keys RS less_irrefl]
   374 by (fast_tac (!claset addEs [Says_imp_old_keys RS less_irrefl]
   378                       delrules [conjI]    (*prevent split-up into 4 subgoals*)
   375                       delrules [conjI]    (*prevent split-up into 4 subgoals*)
   379                       addss (!simpset addsimps [parts_insertI])) 1);
   376                       addss (!simpset addsimps [parts_insertI])) 1);
   380 val lemma = result();
   377 val lemma = result();
   401 
   398 
   402 (**** Authenticity properties relating to NA ****)
   399 (**** Authenticity properties relating to NA ****)
   403 
   400 
   404 (*Only OR1 can have caused such a part of a message to appear.*)
   401 (*Only OR1 can have caused such a part of a message to appear.*)
   405 goal thy 
   402 goal thy 
   406  "!!evs. [| A ~: lost;  evs : otway lost |]               \
   403  "!!evs. [| A ~: lost;  evs : otway lost |]                        \
   407 \        ==> Crypt {|NA, Agent A, Agent B|} (shrK A)        \
   404 \        ==> Crypt {|NA, Agent A, Agent B|} (shrK A)               \
   408 \             : parts (sees lost Spy evs) -->                  \
   405 \             : parts (sees lost Spy evs) -->                      \
   409 \            Says A B {|NA, Agent A, Agent B,               \
   406 \            Says A B {|NA, Agent A, Agent B,                      \
   410 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   407 \                       Crypt {|NA, Agent A, Agent B|} (shrK A)|}  \
   411 \             : set_of_list evs";
   408 \             : set_of_list evs";
   412 by (etac otway.induct 1);
   409 by (parts_induct_tac 1);
   413 by parts_Fake_tac;
       
   414 by (ALLGOALS Asm_simp_tac);
       
   415 (*Fake*)
       
   416 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   417                               impOfSubs Fake_parts_insert]) 2);
       
   418 by (Auto_tac());
       
   419 qed_spec_mp "Crypt_imp_OR1";
   410 qed_spec_mp "Crypt_imp_OR1";
   420 
   411 
   421 
   412 
   422 (** The Nonce NA uniquely identifies A's  message. **)
   413 (** The Nonce NA uniquely identifies A's message. **)
   423 
   414 
   424 goal thy 
   415 goal thy 
   425  "!!evs. [| evs : otway lost; A ~: lost |]               \
   416  "!!evs. [| evs : otway lost; A ~: lost |]               \
   426 \ ==> EX B'. ALL B.    \
   417 \ ==> EX B'. ALL B.    \
   427 \        Crypt {|NA, Agent A, Agent B|} (shrK A) : parts (sees lost Spy evs) \
   418 \        Crypt {|NA, Agent A, Agent B|} (shrK A) : parts (sees lost Spy evs) \
   428 \        --> B = B'";
   419 \        --> B = B'";
   429 by (etac otway.induct 1);
   420 by (parts_induct_tac 1);
   430 by parts_Fake_tac;
   421 by (simp_tac (!simpset addsimps [all_conj_distrib]) 1); 
   431 by (ALLGOALS Asm_simp_tac);
       
   432 (*Fake*)
       
   433 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   434                               impOfSubs Fake_parts_insert]) 2);
       
   435 (*Base case*)
       
   436 by (fast_tac (!claset addss (!simpset)) 1);
       
   437 by (Step_tac 1);
       
   438 (*OR1: creation of new Nonce.  Move assertion into global context*)
   422 (*OR1: creation of new Nonce.  Move assertion into global context*)
   439 by (excluded_middle_tac "NA = Nonce (newN evsa)" 1);
   423 by (expand_case_tac "NA = ?y" 1);
   440 by (Asm_simp_tac 1);
       
   441 by (Fast_tac 1);
       
   442 by (best_tac (!claset addSEs partsEs
   424 by (best_tac (!claset addSEs partsEs
   443                       addEs  [new_nonces_not_seen RSN(2,rev_notE)]) 1);
   425                       addEs  [new_nonces_not_seen RSN(2,rev_notE)]) 1);
   444 val lemma = result();
   426 val lemma = result();
   445 
   427 
   446 goal thy 
   428 goal thy 
   495 \            (EX NB. Says Server B                                     \
   477 \            (EX NB. Says Server B                                     \
   496 \                 {|NA,                                                \
   478 \                 {|NA,                                                \
   497 \                   Crypt {|NA, Key K|} (shrK A),                      \
   479 \                   Crypt {|NA, Key K|} (shrK A),                      \
   498 \                   Crypt {|NB, Key K|} (shrK B)|}                     \
   480 \                   Crypt {|NB, Key K|} (shrK B)|}                     \
   499 \                   : set_of_list evs)";
   481 \                   : set_of_list evs)";
   500 by (etac otway.induct 1);
   482 by (parts_induct_tac 1);
   501 by parts_Fake_tac;
       
   502 by (ALLGOALS Asm_simp_tac);
       
   503 (*Fake*)
       
   504 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   505                               impOfSubs Fake_parts_insert]) 1);
       
   506 (*OR1: it cannot be a new Nonce, contradiction.*)
   483 (*OR1: it cannot be a new Nonce, contradiction.*)
   507 by (fast_tac (!claset addSIs [parts_insertI]
   484 by (fast_tac (!claset addSIs [parts_insertI]
   508                       addSEs partsEs
   485                       addSEs partsEs
   509                       addEs [Says_imp_old_nonces RS less_irrefl]
   486                       addEs [Says_imp_old_nonces RS less_irrefl]
   510                       addss (!simpset)) 1);
   487                       addss (!simpset)) 1);
   511 (*OR3 and OR4*)  (** LEVEL 5 **)
   488 (*OR3 and OR4*) 
   512 (*OR4*)
   489 (*OR4*)
   513 by (REPEAT (Safe_step_tac 2));
   490 by (REPEAT (Safe_step_tac 2));
   514 by (REPEAT (best_tac (!claset addSDs [parts_cut]) 3));
   491 by (REPEAT (best_tac (!claset addSDs [parts_cut]) 3));
   515 by (fast_tac (!claset addSIs [Crypt_imp_OR1]
   492 by (fast_tac (!claset addSIs [Crypt_imp_OR1]
   516                       addEs  partsEs
   493                       addEs  partsEs
   517                       addDs [Says_imp_sees_Spy RS parts.Inj]) 2);
   494                       addDs [Says_imp_sees_Spy RS parts.Inj]) 2);
   518 (*OR3*)  (** LEVEL 8 **)
   495 (*OR3*)  (** LEVEL 5 **)
   519 by (ALLGOALS (asm_simp_tac (!simpset addsimps [ex_disj_distrib])));
   496 by (asm_simp_tac (!simpset addsimps [ex_disj_distrib]) 1);
   520 by (step_tac (!claset delrules [disjCI, impCE]) 1);
   497 by (step_tac (!claset delrules [disjCI, impCE]) 1);
   521 by (fast_tac (!claset addSEs [MPair_parts]
   498 by (fast_tac (!claset addSEs [MPair_parts]
   522                       addSDs [Says_imp_sees_Spy RS parts.Inj]
   499                       addSDs [Says_imp_sees_Spy RS parts.Inj]
   523                       addEs  [no_nonce_OR1_OR2 RSN (2, rev_notE)]
   500                       addEs  [no_nonce_OR1_OR2 RSN (2, rev_notE)]
   524                       delrules [conjI] (*stop split-up into 4 subgoals*)) 2);
   501                       delrules [conjI] (*stop split-up into 4 subgoals*)) 2);
   545 \                       Crypt {|NB, Key K|} (shrK B)|}             \
   522 \                       Crypt {|NB, Key K|} (shrK B)|}             \
   546 \                       : set_of_list evs";
   523 \                       : set_of_list evs";
   547 by (fast_tac (!claset addSIs [NA_Crypt_imp_Server_msg]
   524 by (fast_tac (!claset addSIs [NA_Crypt_imp_Server_msg]
   548                       addEs  partsEs
   525                       addEs  partsEs
   549                       addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   526                       addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   550 qed "A_can_trust";
   527 qed "A_trust_OR4";
   551 
   528 
   552 
   529 
   553 (*Describes the form of K and NA when the Server sends this message.*)
   530 (*Describes the form of K and NA when the Server sends this message.*)
   554 goal thy 
   531 goal thy 
   555  "!!evs. [| Says Server B \
   532  "!!evs. [| Says Server B \
   575 \              {|NA, Crypt {|NA, Key K|} (shrK A),                         \
   552 \              {|NA, Crypt {|NA, Key K|} (shrK A),                         \
   576 \                Crypt {|NB, Key K|} (shrK B)|} : set_of_list evs -->      \
   553 \                Crypt {|NB, Key K|} (shrK B)|} : set_of_list evs -->      \
   577 \            Says A Spy {|NA, Key K|} ~: set_of_list evs -->               \
   554 \            Says A Spy {|NA, Key K|} ~: set_of_list evs -->               \
   578 \            Key K ~: analz (sees lost Spy evs)";
   555 \            Key K ~: analz (sees lost Spy evs)";
   579 by (etac otway.induct 1);
   556 by (etac otway.induct 1);
   580 by (dtac OR2_analz_sees_Spy 4);
   557 by analz_Fake_tac;
   581 by (dtac OR4_analz_sees_Spy 6);
       
   582 by (forward_tac [Reveal_message_form] 7);
       
   583 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, disjE] ORELSE' hyp_subst_tac));
   558 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, disjE] ORELSE' hyp_subst_tac));
   584 by (ALLGOALS
   559 by (ALLGOALS
   585     (asm_full_simp_tac 
   560     (asm_full_simp_tac 
   586      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
   561      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
   587                           analz_insert_Key_newK] @ pushes)
   562                           analz_insert_Key_newK] @ pushes)
   597 by (excluded_middle_tac "Aa : lost" 1);
   572 by (excluded_middle_tac "Aa : lost" 1);
   598 (*But this contradicts Key K ~: analz (sees lost Spy evsa) *)
   573 (*But this contradicts Key K ~: analz (sees lost Spy evsa) *)
   599 by (dtac (Says_imp_sees_Spy RS analz.Inj) 2);
   574 by (dtac (Says_imp_sees_Spy RS analz.Inj) 2);
   600 by (fast_tac (!claset addSDs [analz.Decrypt] addss (!simpset)) 2);
   575 by (fast_tac (!claset addSDs [analz.Decrypt] addss (!simpset)) 2);
   601 (*So now we have  Aa ~: lost *)
   576 (*So now we have  Aa ~: lost *)
   602 by (dtac A_can_trust 1);
   577 by (dtac A_trust_OR4 1);
   603 by (REPEAT (assume_tac 1));
   578 by (REPEAT (assume_tac 1));
   604 by (fast_tac (!claset addDs [unique_session_keys] addss (!simpset)) 1);
   579 by (fast_tac (!claset addDs [unique_session_keys] addss (!simpset)) 1);
   605 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   580 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   606 
   581 
   607 goal thy 
   582 goal thy 
   641 \             : parts (sees lost Spy evs) -->                  \
   616 \             : parts (sees lost Spy evs) -->                  \
   642 \            (EX X'. Says B Server                             \
   617 \            (EX X'. Says B Server                             \
   643 \             {|NA, Agent A, Agent B, X',                      \
   618 \             {|NA, Agent A, Agent B, X',                      \
   644 \               Crypt {|NA, NB, Agent A, Agent B|} (shrK B)|}  \
   619 \               Crypt {|NA, NB, Agent A, Agent B|} (shrK B)|}  \
   645 \             : set_of_list evs)";
   620 \             : set_of_list evs)";
   646 by (etac otway.induct 1);
   621 by (parts_induct_tac 1);
   647 by parts_Fake_tac;
   622 by (auto_tac (!claset, !simpset addcongs [conj_cong]));
   648 by (ALLGOALS Asm_simp_tac);
       
   649 (*Fake*)
       
   650 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   651                               impOfSubs Fake_parts_insert]) 2);
       
   652 by (Auto_tac());
       
   653 qed_spec_mp "Crypt_imp_OR2";
   623 qed_spec_mp "Crypt_imp_OR2";
   654 
   624 
   655 
   625 
   656 (** The Nonce NB uniquely identifies B's  message. **)
   626 (** The Nonce NB uniquely identifies B's  message. **)
   657 
   627 
   658 goal thy 
   628 goal thy 
   659  "!!evs. [| evs : otway lost; B ~: lost |]               \
   629  "!!evs. [| evs : otway lost; B ~: lost |]               \
   660 \ ==> EX NA' A'. ALL NA A.                              \
   630 \ ==> EX NA' A'. ALL NA A.                               \
   661 \      Crypt {|NA, NB, Agent A, Agent B|} (shrK B) : parts(sees lost Spy evs) \
   631 \      Crypt {|NA, NB, Agent A, Agent B|} (shrK B) : parts(sees lost Spy evs) \
   662 \      --> NA = NA' & A = A'";
   632 \      --> NA = NA' & A = A'";
   663 by (etac otway.induct 1);
   633 by (parts_induct_tac 1);
   664 by parts_Fake_tac;
   634 by (simp_tac (!simpset addsimps [all_conj_distrib]) 1); 
   665 by (ALLGOALS Asm_simp_tac);
       
   666 (*Fake*)
       
   667 by (best_tac (!claset delrules [conjI,conjE]
       
   668 		      addSDs [impOfSubs analz_subset_parts,
       
   669                               impOfSubs Fake_parts_insert]) 2);
       
   670 (*Base case*)
       
   671 by (fast_tac (!claset addss (!simpset)) 1);
       
   672 by (Step_tac 1);
       
   673 (*OR2: creation of new Nonce.  Move assertion into global context*)
   635 (*OR2: creation of new Nonce.  Move assertion into global context*)
   674 by (excluded_middle_tac "NB = Nonce (newN evsa)" 1);
   636 by (expand_case_tac "NB = ?y" 1);
   675 by (Asm_simp_tac 1);
       
   676 by (fast_tac (!claset addSIs [exI]) 1);
       
   677 by (fast_tac (!claset addSEs (nonce_not_seen_now::partsEs)) 1);
   637 by (fast_tac (!claset addSEs (nonce_not_seen_now::partsEs)) 1);
   678 val lemma = result();
   638 val lemma = result();
   679 
   639 
   680 goal thy 
   640 goal thy 
   681  "!!evs.[| Crypt {|NA, NB, Agent A, Agent B|} (shrK B) \
   641  "!!evs.[| Crypt {|NA, NB, Agent A, Agent B|} (shrK B) \
   704 \             : set_of_list evs                                          \
   664 \             : set_of_list evs                                          \
   705 \             --> Says Server B                                          \
   665 \             --> Says Server B                                          \
   706 \                  {|NA, Crypt {|NA, Key K|} (shrK A),                   \
   666 \                  {|NA, Crypt {|NA, Key K|} (shrK A),                   \
   707 \                        Crypt {|NB, Key K|} (shrK B)|}                  \
   667 \                        Crypt {|NB, Key K|} (shrK B)|}                  \
   708 \                   : set_of_list evs)";
   668 \                   : set_of_list evs)";
   709 by (etac otway.induct 1);
   669 by (parts_induct_tac 1);
   710 by parts_Fake_tac;
       
   711 by (ALLGOALS (asm_simp_tac (!simpset addcongs [conj_cong])));
       
   712 (*Fake*)
       
   713 by (best_tac (!claset addSDs [impOfSubs analz_subset_parts,
       
   714                               impOfSubs Fake_parts_insert]) 1);
       
   715 (*OR1: it cannot be a new Nonce, contradiction.*)
   670 (*OR1: it cannot be a new Nonce, contradiction.*)
   716 by (fast_tac (!claset addSIs [parts_insertI]
   671 by (fast_tac (!claset addSIs [parts_insertI]
   717                       addSEs partsEs
   672                       addSEs partsEs
   718                       addEs [Says_imp_old_nonces RS less_irrefl]
   673                       addEs [Says_imp_old_nonces RS less_irrefl]
   719                       addss (!simpset)) 1);
   674                       addss (!simpset)) 1);
   751 \                   Crypt {|NB, Key K|} (shrK B)|}                 \
   706 \                   Crypt {|NB, Key K|} (shrK B)|}                 \
   752 \                   : set_of_list evs";
   707 \                   : set_of_list evs";
   753 by (fast_tac (!claset addSIs [NB_Crypt_imp_Server_msg]
   708 by (fast_tac (!claset addSIs [NB_Crypt_imp_Server_msg]
   754                       addEs  partsEs
   709                       addEs  partsEs
   755                       addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   710                       addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   756 qed "B_can_trust";
   711 qed "B_trust_OR3";
   757 
   712 
   758 
   713 
   759 B_can_trust RS Spy_not_see_encrypted_key;
   714 B_trust_OR3 RS Spy_not_see_encrypted_key;
   760 
   715 
   761 
   716 
   762 (** A session key uniquely identifies a pair of senders in the message
   717 (** A session key uniquely identifies a pair of senders in the message
   763     encrypted by a good agent C.  NEEDED?  INTERESTING?**)
   718     encrypted by a good agent C.  NEEDED?  INTERESTING?**)
   764 goal thy 
   719 goal thy 
   767 \         C ~: lost -->                                             \
   722 \         C ~: lost -->                                             \
   768 \         Crypt {|N, Key K|} (shrK C) : parts (sees lost Spy evs) --> \
   723 \         Crypt {|N, Key K|} (shrK C) : parts (sees lost Spy evs) --> \
   769 \         C=A | C=B";
   724 \         C=A | C=B";
   770 by (Simp_tac 1);        (*Miniscoping*)
   725 by (Simp_tac 1);        (*Miniscoping*)
   771 by (etac otway.induct 1);
   726 by (etac otway.induct 1);
   772 by (dres_inst_tac [("lost","lost")] OR2_analz_sees_Spy 4);
   727 by analz_Fake_tac;
   773 by (dres_inst_tac [("lost","lost")] OR4_analz_sees_Spy 6);
       
   774 (*spy_analz_tac just does not work here: it is an entirely different proof!*)
   728 (*spy_analz_tac just does not work here: it is an entirely different proof!*)
   775 by (ALLGOALS 
   729 by (ALLGOALS 
   776     (asm_simp_tac (!simpset addsimps [all_conj_distrib, ex_disj_distrib,
   730     (asm_simp_tac (!simpset addsimps [all_conj_distrib, ex_disj_distrib,
   777                                       imp_conj_distrib, parts_insert_sees,
   731                                       imp_conj_distrib, parts_insert_sees,
   778                                       parts_insert2])));
   732                                       parts_insert2])));
   779 by (REPEAT_FIRST (etac exE));
   733 by (REPEAT_FIRST (etac exE));
   780 (*OR3: extraction of K = newK evsa to global context...*) (** LEVEL 6 **)
   734 (*OR3: extraction of K = newK evsa to global context...*) (** LEVEL 6 **)
   781 by (excluded_middle_tac "K = newK evsa" 4);
   735 by (expand_case_tac "K = ?y" 4);
   782 by (Asm_simp_tac 4);
   736 by (REPEAT (ares_tac [exI] 5));
   783 by (REPEAT (ares_tac [exI] 4));
       
   784 (*...we prove this case by contradiction: the key is too new!*)
   737 (*...we prove this case by contradiction: the key is too new!*)
   785 by (fast_tac (!claset addSEs partsEs
   738 by (fast_tac (!claset addSEs partsEs
   786                       addEs [Says_imp_old_keys RS less_irrefl]
   739                       addEs [Says_imp_old_keys RS less_irrefl]
   787                       addss (!simpset)) 4);
   740                       addss (!simpset)) 4);
   788 (*Base, Fake, OR2, OR4*)
   741 (*Base, Fake, OR2, OR4*)