src/HOL/Auth/Kerberos_BAN.ML
changeset 5076 fbc9d95b62ba
parent 5064 77bd19f782e6
child 5114 c729d4c299c1
equal deleted inserted replaced
5075:9a3d48fa28ca 5076:fbc9d95b62ba
    31 
    31 
    32 AddIffs [SesKeyLife_LB, AutLife_LB];
    32 AddIffs [SesKeyLife_LB, AutLife_LB];
    33 
    33 
    34 
    34 
    35 (*A "possibility property": there are traces that reach the end.*)
    35 (*A "possibility property": there are traces that reach the end.*)
    36 goal thy 
    36 Goal 
    37  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]       \
    37  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]       \
    38 \        ==> EX Timestamp K. EX evs: kerberos_ban.    \
    38 \        ==> EX Timestamp K. EX evs: kerberos_ban.    \
    39 \               Says B A (Crypt K (Number Timestamp)) \
    39 \               Says B A (Crypt K (Number Timestamp)) \
    40 \                    : set evs";
    40 \                    : set evs";
    41 by (REPEAT (resolve_tac [exI,bexI] 1));
    41 by (REPEAT (resolve_tac [exI,bexI] 1));
    50 
    50 
    51 
    51 
    52 (**** Inductive proofs about kerberos_ban ****)
    52 (**** Inductive proofs about kerberos_ban ****)
    53 
    53 
    54 (*Nobody sends themselves messages*)
    54 (*Nobody sends themselves messages*)
    55 goal thy "!!evs. evs : kerberos_ban ==> ALL A X. Says A A X ~: set evs";
    55 Goal "!!evs. evs : kerberos_ban ==> ALL A X. Says A A X ~: set evs";
    56 by (etac kerberos_ban.induct 1);
    56 by (etac kerberos_ban.induct 1);
    57 by Auto_tac;
    57 by Auto_tac;
    58 qed_spec_mp "not_Says_to_self";
    58 qed_spec_mp "not_Says_to_self";
    59 Addsimps [not_Says_to_self];
    59 Addsimps [not_Says_to_self];
    60 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    60 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    61 
    61 
    62 
    62 
    63 (*Forwarding Lemma for reasoning about the encrypted portion of message Kb3*)
    63 (*Forwarding Lemma for reasoning about the encrypted portion of message Kb3*)
    64 goal thy "!!evs. Says S A (Crypt KA {|Timestamp, B, K, X|}) : set evs \
    64 Goal "!!evs. Says S A (Crypt KA {|Timestamp, B, K, X|}) : set evs \
    65 \                ==> X : parts (spies evs)";
    65 \                ==> X : parts (spies evs)";
    66 by (Blast_tac 1);
    66 by (Blast_tac 1);
    67 qed "Kb3_msg_in_parts_spies";
    67 qed "Kb3_msg_in_parts_spies";
    68                               
    68                               
    69 goal thy
    69 Goal
    70     "!!evs. Says Server A (Crypt (shrK A) {|Timestamp, B, K, X|}) : set evs \
    70     "!!evs. Says Server A (Crypt (shrK A) {|Timestamp, B, K, X|}) : set evs \
    71 \           ==> K : parts (spies evs)";
    71 \           ==> K : parts (spies evs)";
    72 by (Blast_tac 1);
    72 by (Blast_tac 1);
    73 qed "Oops_parts_spies";
    73 qed "Oops_parts_spies";
    74 
    74 
    79     forward_tac [Kb3_msg_in_parts_spies] (i+4)     THEN
    79     forward_tac [Kb3_msg_in_parts_spies] (i+4)     THEN
    80     prove_simple_subgoals_tac i;
    80     prove_simple_subgoals_tac i;
    81 
    81 
    82 
    82 
    83 (*Spy never sees another agent's shared key! (unless it's bad at start)*)
    83 (*Spy never sees another agent's shared key! (unless it's bad at start)*)
    84 goal thy 
    84 Goal 
    85 "!!evs. evs : kerberos_ban ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
    85 "!!evs. evs : kerberos_ban ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
    86 by (parts_induct_tac 1);
    86 by (parts_induct_tac 1);
    87 by (ALLGOALS Blast_tac);
    87 by (ALLGOALS Blast_tac);
    88 qed "Spy_see_shrK";
    88 qed "Spy_see_shrK";
    89 Addsimps [Spy_see_shrK];
    89 Addsimps [Spy_see_shrK];
    90 
    90 
    91 
    91 
    92 goal thy 
    92 Goal 
    93 "!!evs. evs : kerberos_ban ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
    93 "!!evs. evs : kerberos_ban ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
    94 by Auto_tac;
    94 by Auto_tac;
    95 qed "Spy_analz_shrK";
    95 qed "Spy_analz_shrK";
    96 Addsimps [Spy_analz_shrK];
    96 Addsimps [Spy_analz_shrK];
    97 
    97 
    98 goal thy  "!!A. [| Key (shrK A) : parts (spies evs);       \
    98 Goal  "!!A. [| Key (shrK A) : parts (spies evs);       \
    99 \                  evs : kerberos_ban |] ==> A:bad";
    99 \                  evs : kerberos_ban |] ==> A:bad";
   100 by (blast_tac (claset() addDs [Spy_see_shrK]) 1);
   100 by (blast_tac (claset() addDs [Spy_see_shrK]) 1);
   101 qed "Spy_see_shrK_D";
   101 qed "Spy_see_shrK_D";
   102 
   102 
   103 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
   103 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
   104 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
   104 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
   105 
   105 
   106 
   106 
   107 (*Nobody can have used non-existent keys!*)
   107 (*Nobody can have used non-existent keys!*)
   108 goal thy "!!evs. evs : kerberos_ban ==>      \
   108 Goal "!!evs. evs : kerberos_ban ==>      \
   109 \         Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
   109 \         Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
   110 by (parts_induct_tac 1);
   110 by (parts_induct_tac 1);
   111 (*Fake*)
   111 (*Fake*)
   112 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
   112 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
   113 (*Kb2, Kb3, Kb4*)
   113 (*Kb2, Kb3, Kb4*)
   122 
   122 
   123 
   123 
   124 (** Lemmas concerning the form of items passed in messages **)
   124 (** Lemmas concerning the form of items passed in messages **)
   125 
   125 
   126 (*Describes the form of K, X and K' when the Server sends this message.*)
   126 (*Describes the form of K, X and K' when the Server sends this message.*)
   127 goal thy 
   127 Goal 
   128  "!!evs. [| Says Server A (Crypt K' {|Number Ts, Agent B, Key K, X|})  \
   128  "!!evs. [| Says Server A (Crypt K' {|Number Ts, Agent B, Key K, X|})  \
   129 \           : set evs; evs : kerberos_ban |]                           \
   129 \           : set evs; evs : kerberos_ban |]                           \
   130 \        ==> K ~: range shrK &                                         \
   130 \        ==> K ~: range shrK &                                         \
   131 \            X = (Crypt (shrK B) {|Number Ts, Agent A, Key K|}) &      \
   131 \            X = (Crypt (shrK B) {|Number Ts, Agent A, Key K|}) &      \
   132 \            K' = shrK A";
   132 \            K' = shrK A";
   139 (*If the encrypted message appears then it originated with the Server
   139 (*If the encrypted message appears then it originated with the Server
   140   PROVIDED that A is NOT compromised!
   140   PROVIDED that A is NOT compromised!
   141 
   141 
   142   This shows implicitly the FRESHNESS OF THE SESSION KEY to A
   142   This shows implicitly the FRESHNESS OF THE SESSION KEY to A
   143 *)
   143 *)
   144 goal thy
   144 Goal
   145  "!!evs. [| Crypt (shrK A) {|Number Ts, Agent B, Key K, X|} \
   145  "!!evs. [| Crypt (shrK A) {|Number Ts, Agent B, Key K, X|} \
   146 \             : parts (spies evs);                          \
   146 \             : parts (spies evs);                          \
   147 \           A ~: bad;  evs : kerberos_ban |]                \
   147 \           A ~: bad;  evs : kerberos_ban |]                \
   148 \         ==> Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   148 \         ==> Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   149 \               : set evs";
   149 \               : set evs";
   153 qed "A_trusts_K_by_Kb2";
   153 qed "A_trusts_K_by_Kb2";
   154 
   154 
   155 
   155 
   156 (*If the TICKET appears then it originated with the Server*)
   156 (*If the TICKET appears then it originated with the Server*)
   157 (*FRESHNESS OF THE SESSION KEY to B*)
   157 (*FRESHNESS OF THE SESSION KEY to B*)
   158 goal thy
   158 Goal
   159  "!!evs. [| Crypt (shrK B) {|Number Ts, Agent A, Key K|} : parts (spies evs); \
   159  "!!evs. [| Crypt (shrK B) {|Number Ts, Agent A, Key K|} : parts (spies evs); \
   160 \           B ~: bad;  evs : kerberos_ban |]                        \
   160 \           B ~: bad;  evs : kerberos_ban |]                        \
   161 \         ==> Says Server A                                         \
   161 \         ==> Says Server A                                         \
   162 \              (Crypt (shrK A) {|Number Ts, Agent B, Key K,                   \
   162 \              (Crypt (shrK A) {|Number Ts, Agent B, Key K,                   \
   163 \                            Crypt (shrK B) {|Number Ts, Agent A, Key K|}|})  \
   163 \                            Crypt (shrK B) {|Number Ts, Agent A, Key K|}|})  \
   169 
   169 
   170 
   170 
   171 (*EITHER describes the form of X when the following message is sent, 
   171 (*EITHER describes the form of X when the following message is sent, 
   172   OR     reduces it to the Fake case.
   172   OR     reduces it to the Fake case.
   173   Use Says_Server_message_form if applicable.*)
   173   Use Says_Server_message_form if applicable.*)
   174 goal thy 
   174 Goal 
   175  "!!evs. [| Says S A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|})     \
   175  "!!evs. [| Says S A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|})     \
   176 \              : set evs;                                                  \
   176 \              : set evs;                                                  \
   177 \           evs : kerberos_ban |]                                          \
   177 \           evs : kerberos_ban |]                                          \
   178 \   ==> (K ~: range shrK & X = (Crypt (shrK B) {|Number Ts, Agent A, Key K|}))\
   178 \   ==> (K ~: range shrK & X = (Crypt (shrK B) {|Number Ts, Agent A, Key K|}))\
   179 \            | X : analz (spies evs)";
   179 \            | X : analz (spies evs)";
   204 ****)
   204 ****)
   205 
   205 
   206 
   206 
   207 (** Session keys are not used to encrypt other session keys **)
   207 (** Session keys are not used to encrypt other session keys **)
   208 
   208 
   209 goal thy  
   209 Goal  
   210  "!!evs. evs : kerberos_ban ==>                          \
   210  "!!evs. evs : kerberos_ban ==>                          \
   211 \  ALL K KK. KK <= Compl (range shrK) -->                \
   211 \  ALL K KK. KK <= Compl (range shrK) -->                \
   212 \            (Key K : analz (Key``KK Un (spies evs))) =  \
   212 \            (Key K : analz (Key``KK Un (spies evs))) =  \
   213 \            (K : KK | Key K : analz (spies evs))";
   213 \            (K : KK | Key K : analz (spies evs))";
   214 by (etac kerberos_ban.induct 1);
   214 by (etac kerberos_ban.induct 1);
   220 (*Fake*) 
   220 (*Fake*) 
   221 by (spy_analz_tac 1);
   221 by (spy_analz_tac 1);
   222 qed_spec_mp "analz_image_freshK";
   222 qed_spec_mp "analz_image_freshK";
   223 
   223 
   224 
   224 
   225 goal thy
   225 Goal
   226  "!!evs. [| evs : kerberos_ban;  KAB ~: range shrK |] ==>     \
   226  "!!evs. [| evs : kerberos_ban;  KAB ~: range shrK |] ==>     \
   227 \        Key K : analz (insert (Key KAB) (spies evs)) =       \
   227 \        Key K : analz (insert (Key KAB) (spies evs)) =       \
   228 \        (K = KAB | Key K : analz (spies evs))";
   228 \        (K = KAB | Key K : analz (spies evs))";
   229 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   229 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   230 qed "analz_insert_freshK";
   230 qed "analz_insert_freshK";
   231 
   231 
   232 
   232 
   233 (** The session key K uniquely identifies the message **)
   233 (** The session key K uniquely identifies the message **)
   234 
   234 
   235 goal thy 
   235 Goal 
   236  "!!evs. evs : kerberos_ban ==>                                         \
   236  "!!evs. evs : kerberos_ban ==>                                         \
   237 \      EX A' Ts' B' X'. ALL A Ts B X.                                   \
   237 \      EX A' Ts' B' X'. ALL A Ts B X.                                   \
   238 \       Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   238 \       Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   239 \             : set evs \
   239 \             : set evs \
   240 \       -->         A=A' & Ts=Ts' & B=B' & X=X'";
   240 \       -->         A=A' & Ts=Ts' & B=B' & X=X'";
   246 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   246 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   247 by (blast_tac (claset() delrules [conjI]) 1);
   247 by (blast_tac (claset() delrules [conjI]) 1);
   248 val lemma = result();
   248 val lemma = result();
   249 
   249 
   250 (*In messages of this form, the session key uniquely identifies the rest*)
   250 (*In messages of this form, the session key uniquely identifies the rest*)
   251 goal thy 
   251 Goal 
   252  "!!evs. [| Says Server A                                    \
   252  "!!evs. [| Says Server A                                    \
   253 \             (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) : set evs; \ 
   253 \             (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) : set evs; \ 
   254 \           Says Server A'                                   \
   254 \           Says Server A'                                   \
   255 \            (Crypt (shrK A') {|Number Ts', Agent B', Key K, X'|}) : set evs;\
   255 \            (Crypt (shrK A') {|Number Ts', Agent B', Key K, X'|}) : set evs;\
   256 \           evs : kerberos_ban |] ==> A=A' & Ts=Ts' & B=B' & X = X'";
   256 \           evs : kerberos_ban |] ==> A=A' & Ts=Ts' & B=B' & X = X'";
   260 
   260 
   261 (** Lemma: the session key sent in msg Kb2 would be EXPIRED
   261 (** Lemma: the session key sent in msg Kb2 would be EXPIRED
   262     if the spy could see it!
   262     if the spy could see it!
   263 **)
   263 **)
   264 
   264 
   265 goal thy 
   265 Goal 
   266  "!!evs. [| A ~: bad;  B ~: bad;  evs : kerberos_ban |]           \
   266  "!!evs. [| A ~: bad;  B ~: bad;  evs : kerberos_ban |]           \
   267 \    ==> Says Server A                                            \
   267 \    ==> Says Server A                                            \
   268 \            (Crypt (shrK A) {|Number Ts, Agent B, Key K,         \
   268 \            (Crypt (shrK A) {|Number Ts, Agent B, Key K,         \
   269 \                              Crypt (shrK B) {|Number Ts, Agent A, Key K|}|})\
   269 \                              Crypt (shrK B) {|Number Ts, Agent A, Key K|}|})\
   270 \           : set evs -->                                         \
   270 \           : set evs -->                                         \
   292 
   292 
   293 (** CONFIDENTIALITY for the SERVER:
   293 (** CONFIDENTIALITY for the SERVER:
   294                      Spy does not see the keys sent in msg Kb2 
   294                      Spy does not see the keys sent in msg Kb2 
   295                      as long as they have NOT EXPIRED
   295                      as long as they have NOT EXPIRED
   296 **)
   296 **)
   297 goal thy 
   297 Goal 
   298  "!!evs. [| Says Server A                                           \
   298  "!!evs. [| Says Server A                                           \
   299 \            (Crypt K' {|Number T, Agent B, Key K, X|}) : set evs;  \
   299 \            (Crypt K' {|Number T, Agent B, Key K, X|}) : set evs;  \
   300 \           ~ Expired T evs;                                        \
   300 \           ~ Expired T evs;                                        \
   301 \           A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   301 \           A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   302 \        |] ==> Key K ~: analz (spies evs)";
   302 \        |] ==> Key K ~: analz (spies evs)";
   310       WOULD HOLD ONLY IF AN OOPS OCCURRED! ---> Nothing to prove!   ****)
   310       WOULD HOLD ONLY IF AN OOPS OCCURRED! ---> Nothing to prove!   ****)
   311 
   311 
   312 
   312 
   313 (** CONFIDENTIALITY for ALICE: **)
   313 (** CONFIDENTIALITY for ALICE: **)
   314 (** Also A_trusts_K_by_Kb2 RS Confidentiality_S **)
   314 (** Also A_trusts_K_by_Kb2 RS Confidentiality_S **)
   315 goal thy 
   315 Goal 
   316 "!!evs. [| Crypt (shrK A) {|Number T, Agent B, Key K, X|} : parts (spies evs);\
   316 "!!evs. [| Crypt (shrK A) {|Number T, Agent B, Key K, X|} : parts (spies evs);\
   317 \           ~ Expired T evs;          \
   317 \           ~ Expired T evs;          \
   318 \           A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   318 \           A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   319 \        |] ==> Key K ~: analz (spies evs)";
   319 \        |] ==> Key K ~: analz (spies evs)";
   320 by (blast_tac (claset() addSDs [A_trusts_K_by_Kb2, Confidentiality_S]) 1);
   320 by (blast_tac (claset() addSDs [A_trusts_K_by_Kb2, Confidentiality_S]) 1);
   321 qed "Confidentiality_A";
   321 qed "Confidentiality_A";
   322 
   322 
   323 
   323 
   324 (** CONFIDENTIALITY for BOB: **)
   324 (** CONFIDENTIALITY for BOB: **)
   325 (** Also B_trusts_K_by_Kb3 RS Confidentiality_S **)
   325 (** Also B_trusts_K_by_Kb3 RS Confidentiality_S **)
   326 goal thy
   326 Goal
   327 "!!evs. [| Crypt (shrK B) {|Number Tk, Agent A, Key K|} \
   327 "!!evs. [| Crypt (shrK B) {|Number Tk, Agent A, Key K|} \
   328 \            : parts (spies evs);              \
   328 \            : parts (spies evs);              \
   329 \          ~ Expired Tk evs;          \
   329 \          ~ Expired Tk evs;          \
   330 \          A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   330 \          A ~: bad;  B ~: bad;  evs : kerberos_ban                \
   331 \        |] ==> Key K ~: analz (spies evs)";             
   331 \        |] ==> Key K ~: analz (spies evs)";             
   332 by (blast_tac (claset() addSDs [B_trusts_K_by_Kb3, 
   332 by (blast_tac (claset() addSDs [B_trusts_K_by_Kb3, 
   333                                 Confidentiality_S]) 1);
   333                                 Confidentiality_S]) 1);
   334 qed "Confidentiality_B";
   334 qed "Confidentiality_B";
   335 
   335 
   336 
   336 
   337 goal thy
   337 Goal
   338  "!!evs. [| B ~: bad;  evs : kerberos_ban |]                        \
   338  "!!evs. [| B ~: bad;  evs : kerberos_ban |]                        \
   339 \        ==> Key K ~: analz (spies evs) -->                    \
   339 \        ==> Key K ~: analz (spies evs) -->                    \
   340 \            Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   340 \            Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}) \
   341 \            : set evs -->                                             \
   341 \            : set evs -->                                             \
   342 \            Crypt K (Number Ta) : parts (spies evs) -->        \
   342 \            Crypt K (Number Ta) : parts (spies evs) -->        \
   365 			      Crypt_Spy_analz_bad]) 1);
   365 			      Crypt_Spy_analz_bad]) 1);
   366 val lemma_B = result();
   366 val lemma_B = result();
   367 
   367 
   368 
   368 
   369 (*AUTHENTICATION OF B TO A*)
   369 (*AUTHENTICATION OF B TO A*)
   370 goal thy
   370 Goal
   371  "!!evs. [| Crypt K (Number Ta) : parts (spies evs);           \
   371  "!!evs. [| Crypt K (Number Ta) : parts (spies evs);           \
   372 \           Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}    \
   372 \           Crypt (shrK A) {|Number Ts, Agent B, Key K, X|}    \
   373 \           : parts (spies evs);                               \
   373 \           : parts (spies evs);                               \
   374 \           ~ Expired Ts evs;                                  \
   374 \           ~ Expired Ts evs;                                  \
   375 \           A ~: bad;  B ~: bad;  evs : kerberos_ban |]        \
   375 \           A ~: bad;  B ~: bad;  evs : kerberos_ban |]        \
   378                         addSIs [lemma_B RS mp RS mp RS mp]
   378                         addSIs [lemma_B RS mp RS mp RS mp]
   379                         addSEs [Confidentiality_S RSN (2,rev_notE)]) 1);
   379                         addSEs [Confidentiality_S RSN (2,rev_notE)]) 1);
   380 qed "Authentication_B";
   380 qed "Authentication_B";
   381 
   381 
   382 
   382 
   383 goal thy
   383 Goal
   384  "!!evs. [| A ~: bad; B ~: bad; evs : kerberos_ban |]      ==>         \ 
   384  "!!evs. [| A ~: bad; B ~: bad; evs : kerberos_ban |]      ==>         \ 
   385 \           Key K ~: analz (spies evs) -->         \
   385 \           Key K ~: analz (spies evs) -->         \
   386 \           Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|})  \
   386 \           Says Server A (Crypt (shrK A) {|Number Ts, Agent B, Key K, X|})  \
   387 \           : set evs -->  \
   387 \           : set evs -->  \
   388 \            Crypt K {|Agent A, Number Ta|} : parts (spies evs) -->\
   388 \            Crypt K {|Agent A, Number Ta|} : parts (spies evs) -->\
   402 by (blast_tac (claset() addDs [A_trusts_K_by_Kb2, unique_session_keys]) 1);
   402 by (blast_tac (claset() addDs [A_trusts_K_by_Kb2, unique_session_keys]) 1);
   403 val lemma_A = result();
   403 val lemma_A = result();
   404 
   404 
   405 
   405 
   406 (*AUTHENTICATION OF A TO B*)
   406 (*AUTHENTICATION OF A TO B*)
   407 goal thy
   407 Goal
   408  "!!evs. [| Crypt K {|Agent A, Number Ta|} : parts (spies evs);  \
   408  "!!evs. [| Crypt K {|Agent A, Number Ta|} : parts (spies evs);  \
   409 \           Crypt (shrK B) {|Number Ts, Agent A, Key K|}         \
   409 \           Crypt (shrK B) {|Number Ts, Agent A, Key K|}         \
   410 \           : parts (spies evs);                                 \
   410 \           : parts (spies evs);                                 \
   411 \           ~ Expired Ts evs;                                    \
   411 \           ~ Expired Ts evs;                                    \
   412 \           A ~: bad;  B ~: bad;  evs : kerberos_ban |]          \
   412 \           A ~: bad;  B ~: bad;  evs : kerberos_ban |]          \