src/HOL/Auth/KerberosIV.ML
author wenzelm
Tue May 30 16:08:38 2000 +0200 (2000-05-30)
changeset 9000 c20d58286a51
parent 8954 4fbdda40bb5f
child 10833 c0844a30ea4e
permissions -rw-r--r--
cleaned up;
paulson@6452
     1
(*  Title:      HOL/Auth/KerberosIV
paulson@6452
     2
    ID:         $Id$
paulson@6452
     3
    Author:     Giampaolo Bella, Cambridge University Computer Laboratory
paulson@6452
     4
    Copyright   1998  University of Cambridge
paulson@6452
     5
paulson@6452
     6
The Kerberos protocol, version IV.
paulson@6452
     7
*)
paulson@6452
     8
paulson@6452
     9
Pretty.setdepth 20;
wenzelm@9000
    10
set timing;
paulson@6452
    11
paulson@6452
    12
AddIffs [AuthLife_LB, ServLife_LB, AutcLife_LB, RespLife_LB, Tgs_not_bad];
paulson@6452
    13
paulson@6452
    14
paulson@6452
    15
(** Reversed traces **)
paulson@6452
    16
paulson@6452
    17
Goal "spies (evs @ [Says A B X]) = insert X (spies evs)";
paulson@6452
    18
by (induct_tac "evs" 1);
paulson@6452
    19
by (induct_tac "a" 2);
paulson@6452
    20
by Auto_tac;
paulson@6452
    21
qed "spies_Says_rev";
paulson@6452
    22
paulson@6452
    23
Goal "spies (evs @ [Gets A X]) = spies evs";
paulson@6452
    24
by (induct_tac "evs" 1);
paulson@6452
    25
by (induct_tac "a" 2);
paulson@6452
    26
by Auto_tac;
paulson@6452
    27
qed "spies_Gets_rev";
paulson@6452
    28
paulson@6452
    29
Goal "spies (evs @ [Notes A X]) = \
paulson@6452
    30
\         (if A:bad then insert X (spies evs) else spies evs)";
paulson@6452
    31
by (induct_tac "evs" 1);
paulson@6452
    32
by (induct_tac "a" 2);
paulson@6452
    33
by Auto_tac;
paulson@6452
    34
qed "spies_Notes_rev";
paulson@6452
    35
paulson@6452
    36
Goal "spies evs = spies (rev evs)";
paulson@6452
    37
by (induct_tac "evs" 1);
paulson@6452
    38
by (induct_tac "a" 2);
paulson@6452
    39
by (ALLGOALS 
paulson@6452
    40
    (asm_simp_tac (simpset() addsimps [spies_Says_rev, spies_Gets_rev, 
paulson@6452
    41
				       spies_Notes_rev])));
paulson@6452
    42
qed "spies_evs_rev";
paulson@6452
    43
bind_thm ("parts_spies_evs_revD2", spies_evs_rev RS equalityD2 RS parts_mono);
paulson@6452
    44
paulson@6452
    45
Goal "spies (takeWhile P evs)  <=  spies evs";
paulson@6452
    46
by (induct_tac "evs" 1);
paulson@6452
    47
by (induct_tac "a" 2);
paulson@6452
    48
by Auto_tac;
paulson@6452
    49
(* Resembles "used_subset_append" in Event.ML*)
paulson@6452
    50
qed "spies_takeWhile";
paulson@6452
    51
bind_thm ("parts_spies_takeWhile_mono", spies_takeWhile RS parts_mono);
paulson@6452
    52
paulson@6452
    53
Goal "~P(x) --> takeWhile P (xs @ [x]) = takeWhile P xs";
paulson@6452
    54
by (induct_tac "xs" 1);
paulson@6452
    55
by Auto_tac;
paulson@6452
    56
qed "takeWhile_tail";
paulson@6452
    57
paulson@6452
    58
paulson@6452
    59
(*****************LEMMAS ABOUT AuthKeys****************)
paulson@6452
    60
paulson@6452
    61
Goalw [AuthKeys_def] "AuthKeys [] = {}";
paulson@6452
    62
by (Simp_tac 1);
paulson@6452
    63
qed "AuthKeys_empty";
paulson@6452
    64
paulson@6452
    65
Goalw [AuthKeys_def] 
paulson@6452
    66
 "(ALL A Tk akey Peer.              \
paulson@6452
    67
\  ev ~= Says Kas A (Crypt (shrK A) {|akey, Agent Peer, Tk,      \
paulson@6452
    68
\             (Crypt (shrK Peer) {|Agent A, Agent Peer, akey, Tk|})|}))\ 
paulson@6452
    69
\      ==> AuthKeys (ev # evs) = AuthKeys evs";
paulson@6452
    70
by Auto_tac;
paulson@6452
    71
qed "AuthKeys_not_insert";
paulson@6452
    72
paulson@6452
    73
Goalw [AuthKeys_def] 
paulson@6452
    74
  "AuthKeys \
paulson@6452
    75
\    (Says Kas A (Crypt (shrK A) {|Key K, Agent Peer, Number Tk, \
paulson@6452
    76
\     (Crypt (shrK Peer) {|Agent A, Agent Peer, Key K, Number Tk|})|}) # evs) \
paulson@6452
    77
\      = insert K (AuthKeys evs)";
paulson@6452
    78
by Auto_tac;
paulson@6452
    79
qed "AuthKeys_insert";
paulson@6452
    80
paulson@6452
    81
Goalw [AuthKeys_def] 
paulson@6452
    82
   "K : AuthKeys \
paulson@6452
    83
\   (Says Kas A (Crypt (shrK A) {|Key K', Agent Peer, Number Tk, \
paulson@6452
    84
\    (Crypt (shrK Peer) {|Agent A, Agent Peer, Key K', Number Tk|})|}) # evs) \
paulson@6452
    85
\       ==> K = K' | K : AuthKeys evs";
paulson@6452
    86
by Auto_tac;
paulson@6452
    87
qed "AuthKeys_simp";
paulson@6452
    88
paulson@6452
    89
Goalw [AuthKeys_def]  
paulson@6452
    90
   "Says Kas A (Crypt (shrK A) {|Key K, Agent Tgs, Number Tk, \
paulson@6452
    91
\    (Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key K, Number Tk|})|}) : set evs \
paulson@6452
    92
\       ==> K : AuthKeys evs";
paulson@6452
    93
by Auto_tac;
paulson@6452
    94
qed "AuthKeysI";
paulson@6452
    95
paulson@6452
    96
Goalw [AuthKeys_def] "K : AuthKeys evs ==> Key K : used evs";
paulson@6452
    97
by (Simp_tac 1);
paulson@6452
    98
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
    99
qed "AuthKeys_used";
paulson@6452
   100
paulson@6452
   101
paulson@6452
   102
(**** FORWARDING LEMMAS ****)
paulson@6452
   103
paulson@6452
   104
(*--For reasoning about the encrypted portion of message K3--*)
paulson@6452
   105
Goal "Says Kas' A (Crypt KeyA {|AuthKey, Peer, Tk, AuthTicket|}) \
paulson@6452
   106
\              : set evs ==> AuthTicket : parts (spies evs)";
paulson@6452
   107
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   108
qed "K3_msg_in_parts_spies";
paulson@6452
   109
paulson@6452
   110
Goal "Says Kas A (Crypt KeyA {|AuthKey, Peer, Tk, AuthTicket|}) \
paulson@6452
   111
\              : set evs ==> AuthKey : parts (spies evs)";
paulson@6452
   112
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   113
qed "Oops_parts_spies1";
paulson@6452
   114
                              
paulson@6452
   115
Goal "[| Says Kas A (Crypt KeyA {|Key AuthKey, Peer, Tk, AuthTicket|}) \
paulson@6452
   116
\          : set evs ;\
paulson@6452
   117
\        evs : kerberos |] ==> AuthKey ~: range shrK";
paulson@6452
   118
by (etac rev_mp 1);
paulson@6452
   119
by (etac kerberos.induct 1);
paulson@6452
   120
by Auto_tac;
paulson@6452
   121
qed "Oops_range_spies1";
paulson@6452
   122
paulson@6452
   123
(*--For reasoning about the encrypted portion of message K5--*)
paulson@6452
   124
Goal "Says Tgs' A (Crypt AuthKey {|ServKey, Agent B, Tt, ServTicket|})\
paulson@6452
   125
 \             : set evs ==> ServTicket : parts (spies evs)";
paulson@6452
   126
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   127
qed "K5_msg_in_parts_spies";
paulson@6452
   128
paulson@6452
   129
Goal "Says Tgs A (Crypt AuthKey {|ServKey, Agent B, Tt, ServTicket|})\
paulson@6452
   130
\                  : set evs ==> ServKey : parts (spies evs)";
paulson@6452
   131
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   132
qed "Oops_parts_spies2";
paulson@6452
   133
paulson@6452
   134
Goal "[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|}) \
paulson@6452
   135
\          : set evs ;\
paulson@6452
   136
\        evs : kerberos |] ==> ServKey ~: range shrK";
paulson@6452
   137
by (etac rev_mp 1);
paulson@6452
   138
by (etac kerberos.induct 1);
paulson@6452
   139
by Auto_tac;
paulson@6452
   140
qed "Oops_range_spies2";
paulson@6452
   141
paulson@6452
   142
Goal "Says S A (Crypt K {|SesKey, B, TimeStamp, Ticket|}) : set evs \
paulson@6452
   143
\     ==> Ticket : parts (spies evs)";
paulson@6452
   144
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   145
qed "Says_ticket_in_parts_spies";
paulson@6452
   146
(*Replaces both K3_msg_in_parts_spies and K5_msg_in_parts_spies*)
paulson@6452
   147
paulson@6452
   148
fun parts_induct_tac i = 
paulson@6452
   149
    etac kerberos.induct i  THEN 
paulson@6452
   150
    REPEAT (FIRSTGOAL analz_mono_contra_tac)  THEN
wenzelm@7499
   151
    ftac K3_msg_in_parts_spies (i+4)  THEN
wenzelm@7499
   152
    ftac K5_msg_in_parts_spies (i+6)  THEN
wenzelm@7499
   153
    ftac Oops_parts_spies1 (i+8)  THEN
wenzelm@7499
   154
    ftac Oops_parts_spies2 (i+9) THEN
paulson@6452
   155
    prove_simple_subgoals_tac 1;
paulson@6452
   156
paulson@6452
   157
paulson@6452
   158
(*Spy never sees another agent's shared key! (unless it's lost at start)*)
paulson@6452
   159
Goal "evs : kerberos ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
paulson@6452
   160
by (parts_induct_tac 1);
paulson@6452
   161
by (Fake_parts_insert_tac 1);
paulson@6452
   162
by (ALLGOALS Blast_tac);
paulson@6452
   163
qed "Spy_see_shrK";
paulson@6452
   164
Addsimps [Spy_see_shrK];
paulson@6452
   165
paulson@6452
   166
Goal "evs : kerberos ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
paulson@6452
   167
by (auto_tac (claset() addDs [impOfSubs analz_subset_parts], simpset()));
paulson@6452
   168
qed "Spy_analz_shrK";
paulson@6452
   169
Addsimps [Spy_analz_shrK];
paulson@6452
   170
paulson@6452
   171
Goal "[| Key (shrK A) : parts (spies evs);  evs : kerberos |] ==> A:bad";
paulson@6452
   172
by (blast_tac (claset() addDs [Spy_see_shrK]) 1);
paulson@6452
   173
qed "Spy_see_shrK_D";
paulson@6452
   174
bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
paulson@6452
   175
AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
paulson@6452
   176
paulson@6452
   177
(*Nobody can have used non-existent keys!*)
paulson@6452
   178
Goal "evs : kerberos ==>      \
paulson@6452
   179
\     Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
paulson@6452
   180
by (parts_induct_tac 1);
paulson@6452
   181
(*Fake*)
paulson@6452
   182
by (best_tac
paulson@6452
   183
      (claset() addSDs [impOfSubs (parts_insert_subset_Un RS keysFor_mono)]
paulson@6452
   184
               addIs  [impOfSubs analz_subset_parts]
paulson@6452
   185
               addDs  [impOfSubs (analz_subset_parts RS keysFor_mono)]
paulson@6452
   186
               addss  (simpset())) 1);
paulson@6452
   187
(*Others*)
paulson@6452
   188
by (ALLGOALS (blast_tac (claset() addSEs spies_partsEs)));
paulson@6452
   189
qed_spec_mp "new_keys_not_used";
paulson@6452
   190
paulson@6452
   191
bind_thm ("new_keys_not_analzd",
paulson@6452
   192
          [analz_subset_parts RS keysFor_mono,
paulson@6452
   193
           new_keys_not_used] MRS contra_subsetD);
paulson@6452
   194
paulson@6452
   195
Addsimps [new_keys_not_used, new_keys_not_analzd];
paulson@6452
   196
paulson@6452
   197
paulson@6452
   198
(*********************** REGULARITY LEMMAS ***********************)
paulson@6452
   199
(*       concerning the form of items passed in messages         *)
paulson@6452
   200
(*****************************************************************)
paulson@6452
   201
paulson@6452
   202
(*Describes the form of AuthKey, AuthTicket, and K sent by Kas*)
paulson@6452
   203
Goal "[| Says Kas A (Crypt K {|Key AuthKey, Agent Peer, Tk, AuthTicket|}) \
paulson@6452
   204
\          : set evs;                 \
paulson@6452
   205
\        evs : kerberos |]             \
paulson@6452
   206
\     ==> AuthKey ~: range shrK & AuthKey : AuthKeys evs & \
paulson@6452
   207
\ AuthTicket = (Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Tk|} ) &\
paulson@6452
   208
\            K = shrK A  & Peer = Tgs";
paulson@6452
   209
by (etac rev_mp 1);
paulson@6452
   210
by (etac kerberos.induct 1);
paulson@6452
   211
by (ALLGOALS (simp_tac (simpset() addsimps [AuthKeys_def, AuthKeys_insert])));
paulson@6452
   212
by (ALLGOALS Blast_tac);
paulson@6452
   213
qed "Says_Kas_message_form";
paulson@6452
   214
paulson@6452
   215
(*This lemma is essential for proving Says_Tgs_message_form: 
paulson@6452
   216
  
paulson@6452
   217
  the session key AuthKey
paulson@6452
   218
  supplied by Kas in the authentication ticket
paulson@6452
   219
  cannot be a long-term key!
paulson@6452
   220
paulson@6452
   221
  Generalised to any session keys (both AuthKey and ServKey).
paulson@6452
   222
*)
paulson@6452
   223
Goal "[| Crypt (shrK Tgs_B) {|Agent A, Agent Tgs_B, Key SesKey, Number T|}\
paulson@6452
   224
\           : parts (spies evs); Tgs_B ~: bad;\
paulson@6452
   225
\        evs : kerberos |]    \
paulson@6452
   226
\     ==> SesKey ~: range shrK";
paulson@6452
   227
by (etac rev_mp 1);
paulson@6452
   228
by (parts_induct_tac 1);
paulson@6452
   229
by (Fake_parts_insert_tac 1);
paulson@6452
   230
qed "SesKey_is_session_key";
paulson@6452
   231
paulson@6452
   232
Goal "[| Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Tk|}  \
paulson@6452
   233
\          : parts (spies evs);                              \
paulson@6452
   234
\        evs : kerberos |]                          \
paulson@6452
   235
\     ==> Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Tk, \
paulson@6452
   236
\                Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Tk|}|})  \
paulson@6452
   237
\           : set evs";
paulson@6452
   238
by (etac rev_mp 1);
paulson@6452
   239
by (parts_induct_tac 1);
paulson@6452
   240
(*Fake*)
paulson@6452
   241
by (Fake_parts_insert_tac 1);
paulson@6452
   242
(*K4*)
paulson@6452
   243
by (Blast_tac 1);
paulson@6452
   244
qed "A_trusts_AuthTicket";
paulson@6452
   245
paulson@6452
   246
Goal "[| Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}\
paulson@6452
   247
\          : parts (spies evs);\
paulson@6452
   248
\        evs : kerberos |]    \
paulson@6452
   249
\     ==> AuthKey : AuthKeys evs";
wenzelm@7499
   250
by (ftac A_trusts_AuthTicket 1);
paulson@6452
   251
by (assume_tac 1);
paulson@6452
   252
by (simp_tac (simpset() addsimps [AuthKeys_def]) 1);
paulson@6452
   253
by (Blast_tac 1);
paulson@6452
   254
qed "AuthTicket_crypt_AuthKey";
paulson@6452
   255
paulson@6452
   256
(*Describes the form of ServKey, ServTicket and AuthKey sent by Tgs*)
paulson@6452
   257
Goal "[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|})\
paulson@6452
   258
\          : set evs; \
paulson@6452
   259
\        evs : kerberos |]    \
paulson@6452
   260
\  ==> B ~= Tgs & ServKey ~: range shrK & ServKey ~: AuthKeys evs &\
paulson@6452
   261
\      ServTicket = (Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|} ) & \
paulson@6452
   262
\      AuthKey ~: range shrK & AuthKey : AuthKeys evs";
paulson@6452
   263
by (etac rev_mp 1);
paulson@6452
   264
by (etac kerberos.induct 1);
paulson@6452
   265
by (ALLGOALS
paulson@6452
   266
    (asm_full_simp_tac
paulson@6452
   267
     (simpset() addsimps [AuthKeys_insert, AuthKeys_not_insert,
paulson@6452
   268
			  AuthKeys_empty, AuthKeys_simp])));
paulson@6452
   269
by (blast_tac (claset() addEs  spies_partsEs) 1);
paulson@6452
   270
by Auto_tac;
paulson@6452
   271
by (blast_tac (claset() addSDs [AuthKeys_used, Says_Kas_message_form]) 1);
paulson@6452
   272
by (blast_tac (claset() addSDs [SesKey_is_session_key]
paulson@6452
   273
                        addEs spies_partsEs) 1);
paulson@6452
   274
by (blast_tac (claset() addDs [AuthTicket_crypt_AuthKey] 
paulson@6452
   275
                        addEs spies_partsEs) 1);
paulson@6452
   276
qed "Says_Tgs_message_form";
paulson@6452
   277
paulson@6452
   278
(*If a certain encrypted message appears then it originated with Kas*)
paulson@6452
   279
Goal "[| Crypt (shrK A) {|Key AuthKey, Peer, Tk, AuthTicket|}  \
paulson@6452
   280
\          : parts (spies evs);                              \
paulson@6452
   281
\        A ~: bad;  evs : kerberos |]                        \
paulson@6452
   282
\     ==> Says Kas A (Crypt (shrK A) {|Key AuthKey, Peer, Tk, AuthTicket|})  \
paulson@6452
   283
\           : set evs";
paulson@6452
   284
by (etac rev_mp 1);
paulson@6452
   285
by (parts_induct_tac 1);
paulson@6452
   286
(*Fake*)
paulson@6452
   287
by (Fake_parts_insert_tac 1);
paulson@6452
   288
(*K4*)
paulson@6452
   289
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj RS parts.Fst,
paulson@6452
   290
			       A_trusts_AuthTicket RS Says_Kas_message_form])
paulson@6452
   291
    1);
paulson@6452
   292
qed "A_trusts_AuthKey";
paulson@6452
   293
paulson@6452
   294
paulson@6452
   295
(*If a certain encrypted message appears then it originated with Tgs*)
paulson@6452
   296
Goal "[| Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|}     \
paulson@6452
   297
\          : parts (spies evs);                                     \
paulson@6452
   298
\        Key AuthKey ~: analz (spies evs);           \
paulson@6452
   299
\        AuthKey ~: range shrK;                      \
paulson@6452
   300
\        evs : kerberos |]         \
paulson@6452
   301
\==> EX A. Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|})\
paulson@6452
   302
\      : set evs";
paulson@6452
   303
by (etac rev_mp 1);
paulson@6452
   304
by (etac rev_mp 1);
paulson@6452
   305
by (parts_induct_tac 1);
paulson@6452
   306
(*Fake*)
paulson@6452
   307
by (Fake_parts_insert_tac 1);
paulson@6452
   308
(*K2*)
paulson@6452
   309
by (Blast_tac 1);
paulson@6452
   310
(*K4*)
paulson@6452
   311
by Auto_tac;
paulson@6452
   312
qed "A_trusts_K4";
paulson@6452
   313
paulson@6452
   314
Goal "[| Crypt (shrK A) {|Key AuthKey, Agent Tgs, Tk, AuthTicket|} \
paulson@6452
   315
\          : parts (spies evs);          \
paulson@6452
   316
\        A ~: bad;                       \
paulson@6452
   317
\        evs : kerberos |]                \
paulson@6452
   318
\   ==> AuthKey ~: range shrK &               \
paulson@6452
   319
\       AuthTicket = Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Tk|}";
paulson@6452
   320
by (etac rev_mp 1);
paulson@6452
   321
by (parts_induct_tac 1);
paulson@6452
   322
by (Fake_parts_insert_tac 1);
paulson@6452
   323
by (Blast_tac 1);
paulson@6452
   324
qed "AuthTicket_form";
paulson@6452
   325
paulson@6452
   326
(* This form holds also over an AuthTicket, but is not needed below.     *)
paulson@6452
   327
Goal "[| Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|} \
paulson@6452
   328
\             : parts (spies evs); \
paulson@6452
   329
\           Key AuthKey ~: analz (spies evs);  \
paulson@6452
   330
\           evs : kerberos |]                                       \
paulson@6452
   331
\        ==> ServKey ~: range shrK &  \
paulson@6452
   332
\   (EX A. ServTicket = Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|})";
paulson@6452
   333
by (etac rev_mp 1);
paulson@6452
   334
by (etac rev_mp 1);
paulson@6452
   335
by (parts_induct_tac 1);
paulson@6452
   336
by (Fake_parts_insert_tac 1);
paulson@6452
   337
qed "ServTicket_form";
paulson@6452
   338
paulson@6452
   339
Goal "[| Says Kas' A (Crypt (shrK A) \
paulson@6452
   340
\             {|Key AuthKey, Agent Tgs, Tk, AuthTicket|} ) : set evs; \
paulson@6452
   341
\        evs : kerberos |]    \
paulson@6452
   342
\     ==> AuthKey ~: range shrK & \
paulson@6452
   343
\         AuthTicket = \
paulson@6452
   344
\                 Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Tk|}\
paulson@6452
   345
\         | AuthTicket : analz (spies evs)";
paulson@6452
   346
by (case_tac "A : bad" 1);
paulson@6452
   347
by (force_tac (claset() addSDs [Says_imp_spies RS analz.Inj], simpset()) 1);
paulson@6452
   348
by (forward_tac [Says_imp_spies RS parts.Inj] 1);
paulson@6452
   349
by (blast_tac (claset() addSDs [AuthTicket_form]) 1);
paulson@6452
   350
qed "Says_kas_message_form";
paulson@6452
   351
(* Essentially the same as AuthTicket_form *)
paulson@6452
   352
paulson@6452
   353
Goal "[| Says Tgs' A (Crypt AuthKey \
paulson@6452
   354
\             {|Key ServKey, Agent B, Tt, ServTicket|} ) : set evs; \
paulson@6452
   355
\        evs : kerberos |]    \
paulson@6452
   356
\     ==> ServKey ~: range shrK & \
paulson@6452
   357
\         (EX A. ServTicket = \
paulson@6452
   358
\                 Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|})  \
paulson@6452
   359
\          | ServTicket : analz (spies evs)";
paulson@6452
   360
by (case_tac "Key AuthKey : analz (spies evs)" 1);
paulson@6452
   361
by (force_tac (claset() addSDs [Says_imp_spies RS analz.Inj], simpset()) 1);
paulson@6452
   362
by (forward_tac [Says_imp_spies RS parts.Inj] 1);
paulson@6452
   363
by (blast_tac (claset() addSDs [ServTicket_form]) 1);
paulson@6452
   364
qed "Says_tgs_message_form";
paulson@6452
   365
(* This form MUST be used in analz_sees_tac below *)
paulson@6452
   366
paulson@6452
   367
paulson@6452
   368
(*****************UNICITY THEOREMS****************)
paulson@6452
   369
paulson@6452
   370
(* The session key, if secure, uniquely identifies the Ticket
paulson@6452
   371
   whether AuthTicket or ServTicket. As a matter of fact, one can read
paulson@6452
   372
   also Tgs in the place of B.                                     *)
paulson@6452
   373
Goal "evs : kerberos ==>                                        \
paulson@6452
   374
\     Key SesKey ~: analz (spies evs) -->   \
paulson@6452
   375
\     (EX A B T. ALL A' B' T'.                          \
paulson@6452
   376
\      Crypt (shrK B') {|Agent A', Agent B', Key SesKey, T'|}    \
paulson@6452
   377
\        : parts (spies evs) --> A'=A & B'=B & T'=T)";
paulson@6452
   378
by (parts_induct_tac 1);
paulson@6452
   379
by (REPEAT (etac (exI RSN (2,exE)) 1)   (*stripping EXs makes proof faster*)
paulson@6452
   380
    THEN Fake_parts_insert_tac 1);
paulson@6452
   381
by (asm_simp_tac (simpset() addsimps [all_conj_distrib]) 1); 
paulson@6452
   382
by (expand_case_tac "SesKey = ?y" 1);
paulson@6452
   383
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   384
by (expand_case_tac "SesKey = ?y" 1);
paulson@6452
   385
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   386
val lemma = result();
paulson@6452
   387
paulson@6452
   388
Goal "[| Crypt (shrK B)  {|Agent A,  Agent B,  Key SesKey, T|}        \
paulson@6452
   389
\          : parts (spies evs);            \
paulson@6452
   390
\        Crypt (shrK B') {|Agent A', Agent B', Key SesKey, T'|}     \
paulson@6452
   391
\          : parts (spies evs);            \
paulson@6452
   392
\        evs : kerberos;  Key SesKey ~: analz (spies evs) |]  \
paulson@6452
   393
\     ==> A=A' & B=B' & T=T'";
paulson@6452
   394
by (prove_unique_tac lemma 1);
paulson@6452
   395
qed "unique_CryptKey";
paulson@6452
   396
paulson@6452
   397
Goal "evs : kerberos \
paulson@6452
   398
\     ==> Key SesKey ~: analz (spies evs) -->   \
paulson@6452
   399
\         (EX K' B' T' Ticket'. ALL K B T Ticket.                          \
paulson@6452
   400
\          Crypt K {|Key SesKey, Agent B, T, Ticket|}    \
paulson@6452
   401
\            : parts (spies evs) --> K=K' & B=B' & T=T' & Ticket=Ticket')";
paulson@6452
   402
by (parts_induct_tac 1);
paulson@6452
   403
by (REPEAT (etac (exI RSN (2,exE)) 1) THEN Fake_parts_insert_tac 1);
paulson@6452
   404
by (asm_simp_tac (simpset() addsimps [all_conj_distrib]) 1); 
paulson@6452
   405
by (expand_case_tac "SesKey = ?y" 1);
paulson@6452
   406
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   407
by (expand_case_tac "SesKey = ?y" 1);
paulson@6452
   408
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   409
val lemma = result();
paulson@6452
   410
paulson@6452
   411
(*An AuthKey is encrypted by one and only one Shared key.
paulson@6452
   412
  A ServKey is encrypted by one and only one AuthKey.
paulson@6452
   413
*)
paulson@6452
   414
Goal "[| Crypt K  {|Key SesKey,  Agent B, T, Ticket|}        \
paulson@6452
   415
\          : parts (spies evs);            \
paulson@6452
   416
\        Crypt K' {|Key SesKey,  Agent B', T', Ticket'|}     \
paulson@6452
   417
\          : parts (spies evs);            \
paulson@6452
   418
\        evs : kerberos;  Key SesKey ~: analz (spies evs) |]  \
paulson@6452
   419
\     ==> K=K' & B=B' & T=T' & Ticket=Ticket'";
paulson@6452
   420
by (prove_unique_tac lemma 1);
paulson@6452
   421
qed "Key_unique_SesKey";
paulson@6452
   422
paulson@6452
   423
paulson@6452
   424
(*
paulson@6452
   425
  At reception of any message mentioning A, Kas associates shrK A with
paulson@6452
   426
  a new AuthKey. Realistic, as the user gets a new AuthKey at each login.
paulson@6452
   427
  Similarly, at reception of any message mentioning an AuthKey
paulson@6452
   428
  (a legitimate user could make several requests to Tgs - by K3), Tgs 
paulson@6452
   429
  associates it with a new ServKey.
paulson@6452
   430
paulson@6452
   431
  Therefore, a goal like
paulson@6452
   432
paulson@6452
   433
   "evs : kerberos \
paulson@6452
   434
  \  ==> Key Kc ~: analz (spies evs) -->   \
paulson@6452
   435
  \        (EX K' B' T' Ticket'. ALL K B T Ticket.                          \
paulson@6452
   436
  \         Crypt Kc {|Key K, Agent B, T, Ticket|}    \
paulson@6452
   437
  \          : parts (spies evs) --> K=K' & B=B' & T=T' & Ticket=Ticket')";
paulson@6452
   438
paulson@6452
   439
  would fail on the K2 and K4 cases.
paulson@6452
   440
*)
paulson@6452
   441
paulson@6452
   442
(* AuthKey uniquely identifies the message from Kas *)
paulson@6452
   443
Goal "evs : kerberos ==>                                        \
paulson@6452
   444
\      EX A' Ka' Tk' X'. ALL A Ka Tk X.                          \
paulson@6452
   445
\        Says Kas A (Crypt Ka {|Key AuthKey, Agent Tgs, Tk, X|})  \
paulson@6452
   446
\          : set evs --> A=A' & Ka=Ka' & Tk=Tk' & X=X'";
paulson@6452
   447
by (etac kerberos.induct 1);
paulson@6452
   448
by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
paulson@6452
   449
by (Step_tac 1);
paulson@6452
   450
(*K2: it can't be a new key*)
paulson@6452
   451
by (expand_case_tac "AuthKey = ?y" 1);
paulson@6452
   452
by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
paulson@6452
   453
by (blast_tac (claset() delrules [conjI]   (*prevent split-up into 4 subgoals*)
paulson@6452
   454
                      addSEs spies_partsEs) 1);
paulson@6452
   455
val lemma = result();
paulson@6452
   456
paulson@6452
   457
Goal "[| Says Kas A                                          \
paulson@6452
   458
\             (Crypt Ka {|Key AuthKey, Agent Tgs, Tk, X|}) : set evs;     \ 
paulson@6452
   459
\        Says Kas A'                                         \
paulson@6452
   460
\             (Crypt Ka' {|Key AuthKey, Agent Tgs, Tk', X'|}) : set evs;   \
paulson@6452
   461
\        evs : kerberos |] ==> A=A' & Ka=Ka' & Tk=Tk' & X=X'";
paulson@6452
   462
by (prove_unique_tac lemma 1);
paulson@6452
   463
qed "unique_AuthKeys";
paulson@6452
   464
paulson@6452
   465
(* ServKey uniquely identifies the message from Tgs *)
paulson@6452
   466
Goal "evs : kerberos ==>                                        \
paulson@6452
   467
\      EX A' B' AuthKey' Tk' X'. ALL A B AuthKey Tk X.                     \
paulson@6452
   468
\        Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tk, X|})  \
paulson@6452
   469
\          : set evs --> A=A' & B=B' & AuthKey=AuthKey' & Tk=Tk' & X=X'";
paulson@6452
   470
by (etac kerberos.induct 1);
paulson@6452
   471
by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
paulson@6452
   472
by (Step_tac 1);
paulson@6452
   473
(*K4: it can't be a new key*)
paulson@6452
   474
by (expand_case_tac "ServKey = ?y" 1);
paulson@6452
   475
by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
paulson@6452
   476
by (blast_tac (claset() delrules [conjI]   (*prevent split-up into 4 subgoals*)
paulson@6452
   477
                      addSEs spies_partsEs) 1);
paulson@6452
   478
val lemma = result();
paulson@6452
   479
paulson@6452
   480
Goal "[| Says Tgs A                                             \
paulson@6452
   481
\             (Crypt K {|Key ServKey, Agent B, Tt, X|}) : set evs; \ 
paulson@6452
   482
\        Says Tgs A'                                                 \
paulson@6452
   483
\             (Crypt K' {|Key ServKey, Agent B', Tt', X'|}) : set evs; \
paulson@6452
   484
\        evs : kerberos |] ==> A=A' & B=B' & K=K' & Tt=Tt' & X=X'";
paulson@6452
   485
by (prove_unique_tac lemma 1);
paulson@6452
   486
qed "unique_ServKeys";
paulson@6452
   487
paulson@6452
   488
paulson@6452
   489
(*****************LEMMAS ABOUT the predicate KeyCryptKey****************)
paulson@6452
   490
paulson@6452
   491
Goalw [KeyCryptKey_def] "~ KeyCryptKey AuthKey ServKey []";
paulson@6452
   492
by (Simp_tac 1);
paulson@6452
   493
qed "not_KeyCryptKey_Nil";
paulson@6452
   494
AddIffs [not_KeyCryptKey_Nil];
paulson@6452
   495
paulson@6452
   496
Goalw [KeyCryptKey_def]
paulson@6452
   497
 "[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, tt, X |}) \
paulson@6452
   498
\             : set evs;    \
paulson@6452
   499
\           evs : kerberos |] ==> KeyCryptKey AuthKey ServKey evs";
wenzelm@7499
   500
by (ftac Says_Tgs_message_form 1);
paulson@6452
   501
by (assume_tac 1);
paulson@6452
   502
by (Blast_tac 1);
paulson@6452
   503
qed "KeyCryptKeyI";
paulson@6452
   504
paulson@6452
   505
Goalw [KeyCryptKey_def]
paulson@6452
   506
   "KeyCryptKey AuthKey ServKey (Says S A X # evs) =                       \
paulson@6452
   507
\    (Tgs = S &                                                            \
paulson@6452
   508
\     (EX B tt. X = Crypt AuthKey        \
paulson@6452
   509
\               {|Key ServKey, Agent B, tt,  \
paulson@6452
   510
\                 Crypt (shrK B) {|Agent A, Agent B, Key ServKey, tt|} |}) \
paulson@6452
   511
\    | KeyCryptKey AuthKey ServKey evs)";
paulson@6452
   512
by (Simp_tac 1);
paulson@6452
   513
by (Blast_tac 1);
paulson@6452
   514
qed "KeyCryptKey_Says";
paulson@6452
   515
Addsimps [KeyCryptKey_Says];
paulson@6452
   516
paulson@6452
   517
(*A fresh AuthKey cannot be associated with any other
paulson@6452
   518
  (with respect to a given trace). *)
paulson@6452
   519
Goalw [KeyCryptKey_def]
paulson@6452
   520
 "[| Key AuthKey ~: used evs; evs : kerberos |] \
paulson@6452
   521
\        ==> ~ KeyCryptKey AuthKey ServKey evs";
paulson@6452
   522
by (etac rev_mp 1);
paulson@6452
   523
by (parts_induct_tac 1);
paulson@6452
   524
by (Asm_full_simp_tac 1);
paulson@6452
   525
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   526
qed "Auth_fresh_not_KeyCryptKey";
paulson@6452
   527
paulson@6452
   528
(*A fresh ServKey cannot be associated with any other
paulson@6452
   529
  (with respect to a given trace). *)
paulson@6452
   530
Goalw [KeyCryptKey_def]
paulson@6452
   531
 "Key ServKey ~: used evs ==> ~ KeyCryptKey AuthKey ServKey evs";
paulson@6452
   532
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   533
qed "Serv_fresh_not_KeyCryptKey";
paulson@6452
   534
paulson@6452
   535
Goalw [KeyCryptKey_def]
paulson@6452
   536
 "[| Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, tk|}\
paulson@6452
   537
\             : parts (spies evs);  evs : kerberos |] \
paulson@6452
   538
\        ==> ~ KeyCryptKey K AuthKey evs";
paulson@6452
   539
by (etac rev_mp 1);
paulson@6452
   540
by (parts_induct_tac 1);
paulson@6452
   541
(*K4*)
paulson@6452
   542
by (blast_tac (claset() addEs spies_partsEs) 3);
paulson@6452
   543
(*K2: by freshness*)
paulson@6452
   544
by (blast_tac (claset() addEs spies_partsEs) 2);
paulson@6452
   545
by (Fake_parts_insert_tac 1);
paulson@6452
   546
qed "AuthKey_not_KeyCryptKey";
paulson@6452
   547
paulson@6452
   548
(*A secure serverkey cannot have been used to encrypt others*)
paulson@6452
   549
Goalw [KeyCryptKey_def]
paulson@6452
   550
 "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, tt|} \
paulson@6452
   551
\             : parts (spies evs);                     \
paulson@6452
   552
\           Key ServKey ~: analz (spies evs);             \
paulson@6452
   553
\           B ~= Tgs;  evs : kerberos |] \
paulson@6452
   554
\        ==> ~ KeyCryptKey ServKey K evs";
paulson@6452
   555
by (etac rev_mp 1);
paulson@6452
   556
by (etac rev_mp 1);
paulson@6452
   557
by (parts_induct_tac 1);
paulson@6452
   558
by (Fake_parts_insert_tac 1);
paulson@6452
   559
(*K4 splits into distinct subcases*)
paulson@6452
   560
by (Step_tac 1);
paulson@6452
   561
by (ALLGOALS Asm_full_simp_tac);
paulson@6452
   562
(*ServKey can't have been enclosed in two certificates*)
paulson@6452
   563
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj]
paulson@6452
   564
                       addSEs [MPair_parts]
paulson@6452
   565
                       addDs  [unique_CryptKey]) 4);
paulson@6452
   566
(*ServKey is fresh and so could not have been used, by new_keys_not_used*)
paulson@6452
   567
by (force_tac (claset() addSDs [Says_imp_spies RS parts.Inj,
paulson@6452
   568
				Crypt_imp_invKey_keysFor],
paulson@6452
   569
	       simpset()) 2); 
paulson@6452
   570
(*Others by freshness*)
paulson@6452
   571
by (REPEAT (blast_tac (claset() addSEs spies_partsEs) 1));
paulson@6452
   572
qed "ServKey_not_KeyCryptKey";
paulson@6452
   573
paulson@6452
   574
(*Long term keys are not issued as ServKeys*)
paulson@6452
   575
Goalw [KeyCryptKey_def]
paulson@6452
   576
 "evs : kerberos ==> ~ KeyCryptKey K (shrK A) evs";
paulson@6452
   577
by (parts_induct_tac 1);
paulson@6452
   578
qed "shrK_not_KeyCryptKey";
paulson@6452
   579
paulson@6452
   580
(*The Tgs message associates ServKey with AuthKey and therefore not with any 
paulson@6452
   581
  other key AuthKey.*)
paulson@6452
   582
Goalw [KeyCryptKey_def]
paulson@6452
   583
 "[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, tt, X |}) \
paulson@6452
   584
\      : set evs;                                         \
paulson@6452
   585
\    AuthKey' ~= AuthKey;  evs : kerberos |]                      \
paulson@6452
   586
\ ==> ~ KeyCryptKey AuthKey' ServKey evs";
paulson@6452
   587
by (blast_tac (claset() addDs [unique_ServKeys]) 1);
paulson@6452
   588
qed "Says_Tgs_KeyCryptKey";
paulson@6452
   589
paulson@6452
   590
Goal "[| KeyCryptKey AuthKey ServKey evs;  evs : kerberos |] \
paulson@6452
   591
\     ==> ~ KeyCryptKey ServKey K evs";
paulson@6452
   592
by (etac rev_mp 1);
paulson@6452
   593
by (parts_induct_tac 1);
paulson@6452
   594
by (Step_tac 1);
paulson@6452
   595
by (ALLGOALS Asm_full_simp_tac);
paulson@6452
   596
(*K4 splits into subcases*)
paulson@6452
   597
by (blast_tac (claset() addEs spies_partsEs 
paulson@6452
   598
                       addSDs [AuthKey_not_KeyCryptKey]) 4);
paulson@6452
   599
(*ServKey is fresh and so could not have been used, by new_keys_not_used*)
paulson@6452
   600
by (force_tac (claset() addSDs [Says_imp_spies RS parts.Inj,
paulson@6452
   601
				Crypt_imp_invKey_keysFor],
paulson@6452
   602
                      simpset() addsimps [KeyCryptKey_def]) 2); 
paulson@6452
   603
(*Others by freshness*)
paulson@6452
   604
by (REPEAT (blast_tac (claset() addSEs spies_partsEs) 1));
paulson@6452
   605
qed "KeyCryptKey_not_KeyCryptKey";
paulson@6452
   606
paulson@6452
   607
(*The only session keys that can be found with the help of session keys are
paulson@6452
   608
  those sent by Tgs in step K4.  *)
paulson@6452
   609
paulson@6452
   610
(*We take some pains to express the property
paulson@6452
   611
  as a logical equivalence so that the simplifier can apply it.*)
paulson@6452
   612
Goal "P --> (Key K : analz (Key``KK Un H)) --> (K:KK | Key K : analz H)  \
paulson@6452
   613
\     ==>       \
paulson@6452
   614
\     P --> (Key K : analz (Key``KK Un H)) = (K:KK | Key K : analz H)";
paulson@6452
   615
by (blast_tac (claset() addIs [impOfSubs analz_mono]) 1);
paulson@6452
   616
qed "Key_analz_image_Key_lemma";
paulson@6452
   617
paulson@6452
   618
Goal "[| KeyCryptKey K K' evs; evs : kerberos |] \
paulson@6452
   619
\     ==> Key K' : analz (insert (Key K) (spies evs))";
paulson@6452
   620
by (full_simp_tac (simpset() addsimps [KeyCryptKey_def]) 1);
paulson@6452
   621
by (Clarify_tac 1);
paulson@6452
   622
by (dresolve_tac [Says_imp_spies RS analz.Inj RS analz_insertI] 1);
paulson@6452
   623
by Auto_tac;
paulson@6452
   624
qed "KeyCryptKey_analz_insert";
paulson@6452
   625
paulson@6452
   626
Goal "[| K : AuthKeys evs Un range shrK;  evs : kerberos |]  \
paulson@6452
   627
\     ==> ALL SK. ~ KeyCryptKey SK K evs";
paulson@6452
   628
by (asm_full_simp_tac (simpset() addsimps [KeyCryptKey_def]) 1);
paulson@6452
   629
by (blast_tac (claset() addDs [Says_Tgs_message_form]) 1);
paulson@6452
   630
qed "AuthKeys_are_not_KeyCryptKey";
paulson@6452
   631
paulson@6452
   632
Goal "[| K ~: AuthKeys evs; \
paulson@6452
   633
\        K ~: range shrK; evs : kerberos |]  \
paulson@6452
   634
\     ==> ALL SK. ~ KeyCryptKey K SK evs";
paulson@6452
   635
by (asm_full_simp_tac (simpset() addsimps [KeyCryptKey_def]) 1);
paulson@6452
   636
by (blast_tac (claset() addDs [Says_Tgs_message_form]) 1);
paulson@6452
   637
qed "not_AuthKeys_not_KeyCryptKey";
paulson@6452
   638
paulson@6452
   639
paulson@6452
   640
(*****************SECRECY THEOREMS****************)
paulson@6452
   641
paulson@6452
   642
(*For proofs involving analz.*)
paulson@6452
   643
val analz_sees_tac = 
paulson@6452
   644
  EVERY 
paulson@6452
   645
   [REPEAT (FIRSTGOAL analz_mono_contra_tac),
wenzelm@7499
   646
    ftac Oops_range_spies2 10, 
wenzelm@7499
   647
    ftac Oops_range_spies1 9, 
wenzelm@7499
   648
    ftac Says_tgs_message_form 7,
wenzelm@7499
   649
    ftac Says_kas_message_form 5, 
paulson@6452
   650
    REPEAT_FIRST (eresolve_tac [asm_rl, conjE, disjE, exE]
paulson@6452
   651
		  ORELSE' hyp_subst_tac)];
paulson@6452
   652
paulson@6452
   653
Goal "[| KK <= -(range shrK); Key K : analz (spies evs); evs: kerberos |]   \
paulson@6452
   654
\     ==> Key K : analz (Key `` KK Un spies evs)";
paulson@6452
   655
by (blast_tac (claset() addDs [impOfSubs analz_mono]) 1);
paulson@6452
   656
qed "analz_mono_KK";
paulson@6452
   657
paulson@8954
   658
(*For the Oops2 case of the next theorem*)
paulson@8954
   659
Goal "[| evs : kerberos;  \
paulson@8954
   660
\        Says Tgs A (Crypt AuthKey \
paulson@8954
   661
\                    {|Key ServKey, Agent B, Number Tt, ServTicket|}) \
paulson@8954
   662
\          : set evs |] \
paulson@8954
   663
\     ==> ~ KeyCryptKey ServKey SK evs";
paulson@8954
   664
by (blast_tac (claset() addDs [KeyCryptKeyI, KeyCryptKey_not_KeyCryptKey]) 1);
paulson@8954
   665
qed "Oops2_not_KeyCryptKey";
paulson@8954
   666
paulson@8954
   667
paulson@6452
   668
(* Big simplification law for keys SK that are not crypted by keys in KK   *)
paulson@6452
   669
(* It helps prove three, otherwise hard, facts about keys. These facts are *)
paulson@6452
   670
(* exploited as simplification laws for analz, and also "limit the damage" *)
paulson@6452
   671
(* in case of loss of a key to the spy. See ESORICS98.                     *)
paulson@8954
   672
(* [simplified by LCP]                                                     *)
paulson@6452
   673
Goal "evs : kerberos ==>                                         \
paulson@6452
   674
\     (ALL SK KK. KK <= -(range shrK) -->                   \
paulson@6452
   675
\     (ALL K: KK. ~ KeyCryptKey K SK evs)   -->           \
paulson@6452
   676
\     (Key SK : analz (Key``KK Un (spies evs))) =        \
paulson@6452
   677
\     (SK : KK | Key SK : analz (spies evs)))";
paulson@6452
   678
by (etac kerberos.induct 1);
paulson@6452
   679
by analz_sees_tac;
paulson@6452
   680
by (REPEAT_FIRST (rtac allI));
paulson@6452
   681
by (REPEAT_FIRST (rtac (Key_analz_image_Key_lemma RS impI)));
paulson@8954
   682
(*Case-splits for Oops1 & 5: the negated case simplifies using the ind hyp*)
paulson@8954
   683
by (case_tac "KeyCryptKey AuthKey SK evsO1" 11); 
paulson@8954
   684
by (case_tac "KeyCryptKey ServKey SK evs5" 8);
paulson@6452
   685
by (ALLGOALS  
paulson@6452
   686
    (asm_simp_tac 
paulson@6452
   687
     (analz_image_freshK_ss addsimps
paulson@8954
   688
        [KeyCryptKey_Says, shrK_not_KeyCryptKey, Oops2_not_KeyCryptKey,
paulson@6452
   689
	 Auth_fresh_not_KeyCryptKey, Serv_fresh_not_KeyCryptKey, 
paulson@6452
   690
	 Says_Tgs_KeyCryptKey, Spy_analz_shrK])));
paulson@6452
   691
(*Fake*) 
paulson@6452
   692
by (spy_analz_tac 1);
paulson@6452
   693
(* Base + K2 done by the simplifier! *)
paulson@6452
   694
(*K3*)
paulson@6452
   695
by (Blast_tac 1);
paulson@6452
   696
(*K4*)
paulson@6452
   697
by (blast_tac (claset() addEs spies_partsEs 
paulson@6452
   698
                        addSDs [AuthKey_not_KeyCryptKey]) 1);
paulson@6452
   699
(*K5*)
paulson@6452
   700
by (case_tac "Key ServKey : analz (spies evs5)" 1);
paulson@6452
   701
(*If ServKey is compromised then the result follows directly...*)
paulson@6452
   702
by (asm_simp_tac 
paulson@6452
   703
     (simpset() addsimps [analz_insert_eq, 
paulson@6452
   704
			 impOfSubs (Un_upper2 RS analz_mono)]) 1);
paulson@6452
   705
(*...therefore ServKey is uncompromised.*)
paulson@6452
   706
(*The KeyCryptKey ServKey SK evs5 case leads to a contradiction.*)
paulson@6452
   707
by (blast_tac (claset() addSEs [ServKey_not_KeyCryptKey RSN(2, rev_notE)]
paulson@6452
   708
		        addEs spies_partsEs delrules [allE, ballE]) 1);
paulson@8954
   709
(** Level 13: Oops1 **)
paulson@8954
   710
by (Asm_full_simp_tac 1);
paulson@6452
   711
by (blast_tac (claset() addSDs [KeyCryptKey_analz_insert]) 1);
paulson@6452
   712
qed_spec_mp "Key_analz_image_Key";
paulson@6452
   713
paulson@6452
   714
paulson@6452
   715
(* First simplification law for analz: no session keys encrypt  *)
paulson@6452
   716
(* authentication keys or shared keys.                          *)
paulson@6452
   717
Goal "[| evs : kerberos;  K : (AuthKeys evs) Un range shrK;      \
paulson@6452
   718
\        SesKey ~: range shrK |]                                 \
paulson@6452
   719
\     ==> Key K : analz (insert (Key SesKey) (spies evs)) = \
paulson@6452
   720
\         (K = SesKey | Key K : analz (spies evs))";
wenzelm@7499
   721
by (ftac AuthKeys_are_not_KeyCryptKey 1 THEN assume_tac 1);
paulson@6452
   722
by (asm_full_simp_tac (analz_image_freshK_ss addsimps [Key_analz_image_Key]) 1);
paulson@6452
   723
qed "analz_insert_freshK1";
paulson@6452
   724
paulson@6452
   725
paulson@6452
   726
(* Second simplification law for analz: no service keys encrypt *)
paulson@6452
   727
(* any other keys.					        *)
paulson@6452
   728
Goal "[| evs : kerberos;  ServKey ~: (AuthKeys evs); ServKey ~: range shrK|]\
paulson@6452
   729
\     ==> Key K : analz (insert (Key ServKey) (spies evs)) = \
paulson@6452
   730
\         (K = ServKey | Key K : analz (spies evs))";
wenzelm@7499
   731
by (ftac not_AuthKeys_not_KeyCryptKey 1 
paulson@6452
   732
    THEN assume_tac 1
paulson@6452
   733
    THEN assume_tac 1);
paulson@6452
   734
by (asm_full_simp_tac (analz_image_freshK_ss addsimps [Key_analz_image_Key]) 1);
paulson@6452
   735
qed "analz_insert_freshK2";
paulson@6452
   736
paulson@6452
   737
paulson@6452
   738
(* Third simplification law for analz: only one authentication key *)
paulson@6452
   739
(* encrypts a certain service key.                                 *)
paulson@6452
   740
Goal  
paulson@6452
   741
 "[| Says Tgs A    \
paulson@6452
   742
\           (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}) \
paulson@6452
   743
\             : set evs;          \ 
paulson@6452
   744
\           AuthKey ~= AuthKey'; AuthKey' ~: range shrK; evs : kerberos |]    \
paulson@6452
   745
\       ==> Key ServKey : analz (insert (Key AuthKey') (spies evs)) =  \
paulson@6452
   746
\               (ServKey = AuthKey' | Key ServKey : analz (spies evs))";
paulson@6452
   747
by (dres_inst_tac [("AuthKey'","AuthKey'")] Says_Tgs_KeyCryptKey 1);
paulson@6452
   748
by (Blast_tac 1);
paulson@6452
   749
by (assume_tac 1);
paulson@6452
   750
by (asm_full_simp_tac (analz_image_freshK_ss addsimps [Key_analz_image_Key]) 1);
paulson@6452
   751
qed "analz_insert_freshK3";
paulson@6452
   752
paulson@6452
   753
paulson@6452
   754
(*a weakness of the protocol*)
paulson@6452
   755
Goal "[| Says Tgs A    \
paulson@6452
   756
\             (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}) \
paulson@6452
   757
\          : set evs;          \ 
paulson@6452
   758
\        Key AuthKey : analz (spies evs); evs : kerberos |]    \
paulson@6452
   759
\     ==> Key ServKey : analz (spies evs)";
paulson@6452
   760
by (force_tac (claset() addDs [Says_imp_spies RS analz.Inj RS 
paulson@6452
   761
			       analz.Decrypt RS analz.Fst],
paulson@6452
   762
	       simpset()) 1);
paulson@6452
   763
qed "AuthKey_compromises_ServKey";
paulson@6452
   764
paulson@6452
   765
paulson@6452
   766
(********************** Guarantees for Kas *****************************)
paulson@6452
   767
Goal "[| Crypt AuthKey {|Key ServKey, Agent B, Tt, \
paulson@6452
   768
\                     Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|}|}\
paulson@6452
   769
\          : parts (spies evs); \
paulson@6452
   770
\        Key ServKey ~: analz (spies evs);                          \
paulson@6452
   771
\        B ~= Tgs; evs : kerberos |]                            \
paulson@6452
   772
\     ==> ServKey ~: AuthKeys evs";
paulson@6452
   773
by (etac rev_mp 1);
paulson@6452
   774
by (etac rev_mp 1);
paulson@6452
   775
by (asm_full_simp_tac (simpset() addsimps [AuthKeys_def]) 1);
paulson@6452
   776
by (parts_induct_tac 1);
paulson@6452
   777
by (Fake_parts_insert_tac 1);
paulson@6452
   778
by (ALLGOALS (blast_tac (claset() addSEs spies_partsEs)));
paulson@6452
   779
bind_thm ("ServKey_notin_AuthKeys", result() RSN (2, rev_notE));
paulson@6452
   780
bind_thm ("ServKey_notin_AuthKeysD", result());
paulson@6452
   781
paulson@6452
   782
paulson@6452
   783
(** If Spy sees the Authentication Key sent in msg K2, then 
paulson@6452
   784
    the Key has expired  **)
paulson@6452
   785
Goal "[| A ~: bad;  evs : kerberos |]           \
paulson@6452
   786
\     ==> Says Kas A                             \
paulson@6452
   787
\              (Crypt (shrK A)                      \
paulson@6452
   788
\                 {|Key AuthKey, Agent Tgs, Number Tk,     \
paulson@6452
   789
\         Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
   790
\           : set evs -->                 \
paulson@6452
   791
\         Key AuthKey : analz (spies evs) -->                       \
paulson@6452
   792
\         ExpirAuth Tk evs";
paulson@6452
   793
by (etac kerberos.induct 1);
paulson@6452
   794
by analz_sees_tac;
paulson@6452
   795
by (ALLGOALS 
paulson@6452
   796
    (asm_simp_tac 
paulson@8741
   797
     (simpset() addsimps ([Says_Kas_message_form, less_SucI,
paulson@6452
   798
			   analz_insert_eq, not_parts_not_analz, 
paulson@6452
   799
			   analz_insert_freshK1] @ pushes))));
paulson@6452
   800
(*Fake*) 
paulson@6452
   801
by (spy_analz_tac 1);
paulson@6452
   802
(*K2*)
paulson@6452
   803
by (blast_tac (claset() addSEs spies_partsEs
paulson@6452
   804
            addIs [parts_insertI, impOfSubs analz_subset_parts, less_SucI]) 1);
paulson@6452
   805
(*K4*)
paulson@6452
   806
by (blast_tac (claset() addSEs spies_partsEs) 1);
paulson@6452
   807
(*Level 8: K5*)
paulson@6452
   808
by (blast_tac (claset() addEs [ServKey_notin_AuthKeys]
paulson@6452
   809
                        addDs [Says_Kas_message_form, 
paulson@6452
   810
	       		       Says_imp_spies RS parts.Inj]
paulson@6452
   811
                        addIs [less_SucI]) 1);
paulson@6452
   812
(*Oops1*)
paulson@6452
   813
by (blast_tac (claset() addDs [unique_AuthKeys] addIs [less_SucI]) 1);
paulson@6452
   814
(*Oops2*)
paulson@6452
   815
by (blast_tac (claset() addDs [Says_Tgs_message_form,
paulson@6452
   816
                               Says_Kas_message_form]) 1);
paulson@6452
   817
val lemma = result() RS mp RS mp RSN(1,rev_notE);
paulson@6452
   818
paulson@6452
   819
paulson@6452
   820
Goal "[| Says Kas A                                             \
paulson@6452
   821
\             (Crypt Ka {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|})  \
paulson@6452
   822
\          : set evs;                                \
paulson@6452
   823
\        ~ ExpirAuth Tk evs;                         \
paulson@6452
   824
\        A ~: bad;  evs : kerberos |]            \
paulson@6452
   825
\     ==> Key AuthKey ~: analz (spies evs)";
wenzelm@7499
   826
by (ftac Says_Kas_message_form 1 THEN assume_tac 1);
paulson@6452
   827
by (blast_tac (claset() addSDs [lemma]) 1);
paulson@6452
   828
qed "Confidentiality_Kas";
paulson@6452
   829
paulson@6452
   830
paulson@6452
   831
paulson@6452
   832
paulson@6452
   833
paulson@6452
   834
paulson@6452
   835
(********************** Guarantees for Tgs *****************************)
paulson@6452
   836
paulson@6452
   837
(** If Spy sees the Service Key sent in msg K4, then 
paulson@6452
   838
    the Key has expired  **)
paulson@6452
   839
Goal "[| A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]           \
paulson@6452
   840
\  ==> Key AuthKey ~: analz (spies evs) --> \
paulson@6452
   841
\      Says Tgs A            \
paulson@6452
   842
\        (Crypt AuthKey                      \
paulson@6452
   843
\           {|Key ServKey, Agent B, Number Tt,     \
paulson@6452
   844
\             Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}|})\
paulson@6452
   845
\        : set evs -->                 \
paulson@6452
   846
\      Key ServKey : analz (spies evs) -->                       \
paulson@6452
   847
\      ExpirServ Tt evs";
paulson@6452
   848
by (etac kerberos.induct 1);
paulson@6452
   849
(*The Oops1 case is unusual: must simplify Authkey ~: analz (spies (ev#evs))
paulson@6452
   850
  rather than weakening it to Authkey ~: analz (spies evs), for we then
paulson@6452
   851
  conclude AuthKey ~= AuthKeya.*)
paulson@6452
   852
by (Clarify_tac 9);
paulson@6452
   853
by analz_sees_tac;
paulson@6452
   854
by (rotate_tac ~1 11);
paulson@6452
   855
by (ALLGOALS 
paulson@6452
   856
    (asm_full_simp_tac 
paulson@8741
   857
     (simpset() addsimps [less_SucI, 
paulson@8741
   858
			  Says_Kas_message_form, Says_Tgs_message_form,
paulson@8741
   859
			  analz_insert_eq, not_parts_not_analz, 
paulson@8741
   860
			  analz_insert_freshK1, analz_insert_freshK2] 
paulson@8741
   861
			 @ pushes)));
paulson@6452
   862
(*Fake*) 
paulson@6452
   863
by (spy_analz_tac 1);
paulson@6452
   864
(*K2*)
paulson@6452
   865
by (blast_tac (claset() addSEs spies_partsEs
paulson@6452
   866
            addIs [parts_insertI, impOfSubs analz_subset_parts, less_SucI]) 1);
paulson@6452
   867
(*K4*)
paulson@6452
   868
by (case_tac "A ~= Aa" 1);
paulson@6452
   869
by (blast_tac (claset() addSEs spies_partsEs
paulson@6452
   870
                        addIs [less_SucI]) 1);
paulson@6452
   871
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS parts.Fst, 
paulson@6452
   872
                               A_trusts_AuthTicket, 
paulson@6452
   873
                               Confidentiality_Kas,
paulson@6452
   874
                               impOfSubs analz_subset_parts]) 1);
paulson@6452
   875
by (ALLGOALS Clarify_tac);
paulson@6452
   876
(*Oops2*)
paulson@6452
   877
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj, 
paulson@6452
   878
                               Key_unique_SesKey] addIs [less_SucI]) 3);
paulson@6452
   879
(** Level 12 **)
paulson@6452
   880
(*Oops1*)
wenzelm@7499
   881
by (ftac Says_Kas_message_form 2);
paulson@6452
   882
by (assume_tac 2);
paulson@6452
   883
by (blast_tac (claset() addDs [analz_insert_freshK3,
paulson@6452
   884
			       Says_Kas_message_form, Says_Tgs_message_form] 
paulson@6452
   885
                        addIs  [less_SucI]) 2);
paulson@6452
   886
(** Level 16 **)
paulson@6452
   887
by (thin_tac "Says Aa Tgs ?X : set ?evs" 1);
paulson@6452
   888
by (forward_tac [Says_imp_spies RS parts.Inj RS ServKey_notin_AuthKeysD] 1);
paulson@6452
   889
by (assume_tac 1 THEN Blast_tac 1 THEN assume_tac 1);
paulson@6452
   890
by (rotate_tac ~1 1);
paulson@6452
   891
by (asm_full_simp_tac (simpset() addsimps [analz_insert_freshK2]) 1);
paulson@6452
   892
by (etac disjE 1);
paulson@6452
   893
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj, 
paulson@6452
   894
                               Key_unique_SesKey]) 1);
paulson@6452
   895
by (blast_tac (claset() addIs [less_SucI]) 1);
paulson@6452
   896
val lemma = result() RS mp RS mp RS mp RSN(1,rev_notE);
paulson@6452
   897
paulson@6452
   898
paulson@6452
   899
(* In the real world Tgs can't check wheter AuthKey is secure! *)
paulson@6452
   900
Goal 
paulson@6452
   901
 "[| Says Tgs A      \
paulson@6452
   902
\             (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}) \
paulson@6452
   903
\             : set evs;              \
paulson@6452
   904
\           Key AuthKey ~: analz (spies evs);        \
paulson@6452
   905
\           ~ ExpirServ Tt evs;                         \
paulson@6452
   906
\           A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
   907
\        ==> Key ServKey ~: analz (spies evs)";
wenzelm@7499
   908
by (ftac Says_Tgs_message_form 1 THEN assume_tac 1);
paulson@6452
   909
by (blast_tac (claset() addDs [lemma]) 1);
paulson@6452
   910
qed "Confidentiality_Tgs1";
paulson@6452
   911
paulson@6452
   912
(* In the real world Tgs CAN check what Kas sends! *)
paulson@6452
   913
Goal 
paulson@6452
   914
 "[| Says Kas A                                             \
paulson@6452
   915
\              (Crypt Ka {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|})  \
paulson@6452
   916
\             : set evs;                                \
paulson@6452
   917
\           Says Tgs A      \
paulson@6452
   918
\             (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}) \
paulson@6452
   919
\             : set evs;              \
paulson@6452
   920
\           ~ ExpirAuth Tk evs; ~ ExpirServ Tt evs;                         \
paulson@6452
   921
\           A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
   922
\        ==> Key ServKey ~: analz (spies evs)";
paulson@6452
   923
by (blast_tac (claset() addSDs [Confidentiality_Kas,
paulson@6452
   924
                                Confidentiality_Tgs1]) 1);
paulson@6452
   925
qed "Confidentiality_Tgs2";
paulson@6452
   926
paulson@6452
   927
(*Most general form*)
paulson@6452
   928
val Confidentiality_Tgs3 = A_trusts_AuthTicket RS Confidentiality_Tgs2;
paulson@6452
   929
paulson@6452
   930
paulson@6452
   931
(********************** Guarantees for Alice *****************************)
paulson@6452
   932
paulson@6452
   933
val Confidentiality_Auth_A = A_trusts_AuthKey RS Confidentiality_Kas;
paulson@6452
   934
paulson@6452
   935
Goal
paulson@6452
   936
 "[| Says Kas A \
paulson@6452
   937
\      (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Tk, AuthTicket|}) : set evs;\
paulson@6452
   938
\    Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|}     \
paulson@6452
   939
\      : parts (spies evs);                                       \
paulson@6452
   940
\    Key AuthKey ~: analz (spies evs);            \
paulson@6452
   941
\    evs : kerberos |]         \
paulson@6452
   942
\==> Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tt, ServTicket|})\
paulson@6452
   943
\      : set evs";
wenzelm@7499
   944
by (ftac Says_Kas_message_form 1 THEN assume_tac 1);
paulson@6452
   945
by (etac rev_mp 1);
paulson@6452
   946
by (etac rev_mp 1);
paulson@6452
   947
by (etac rev_mp 1);
paulson@6452
   948
by (parts_induct_tac 1);
paulson@6452
   949
by (Fake_parts_insert_tac 1);
paulson@6452
   950
(*K2 and K4 remain*)
paulson@6452
   951
by (blast_tac (claset() addEs spies_partsEs addSEs [MPair_parts] 
paulson@6452
   952
                        addSDs [unique_CryptKey]) 2);
paulson@6452
   953
by (blast_tac (claset() addSDs [A_trusts_K4, Says_Tgs_message_form, 
paulson@6452
   954
				AuthKeys_used]) 1);
paulson@6452
   955
qed "A_trusts_K4_bis";
paulson@6452
   956
paulson@6452
   957
paulson@6452
   958
Goal "[| Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}  \
paulson@6452
   959
\          : parts (spies evs);                              \
paulson@6452
   960
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}     \
paulson@6452
   961
\          : parts (spies evs);                                       \
paulson@6452
   962
\        ~ ExpirAuth Tk evs; ~ ExpirServ Tt evs;                         \
paulson@6452
   963
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
   964
\     ==> Key ServKey ~: analz (spies evs)";
paulson@6452
   965
by (dtac A_trusts_AuthKey 1);
paulson@6452
   966
by (assume_tac 1);
paulson@6452
   967
by (assume_tac 1);
paulson@6452
   968
by (blast_tac (claset() addDs [Confidentiality_Kas, 
paulson@6452
   969
                               Says_Kas_message_form,
paulson@6452
   970
                               A_trusts_K4_bis, Confidentiality_Tgs2]) 1);
paulson@6452
   971
qed "Confidentiality_Serv_A";
paulson@6452
   972
paulson@6452
   973
paulson@6452
   974
(********************** Guarantees for Bob *****************************)
paulson@6452
   975
(* Theorems for the refined model have suffix "refined"                *)
paulson@6452
   976
paulson@6452
   977
Goal
paulson@6452
   978
"[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|})\
paulson@6452
   979
\            : set evs; evs : kerberos|]  \
paulson@6452
   980
\  ==> EX Tk. Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk,\
paulson@6452
   981
\          Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
   982
\            : set evs";
paulson@6452
   983
by (etac rev_mp 1);
paulson@6452
   984
by (parts_induct_tac 1);
paulson@6452
   985
by Auto_tac;
paulson@6452
   986
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj RS parts.Fst RS
paulson@6452
   987
                               A_trusts_AuthTicket]) 1);
paulson@6452
   988
qed "K4_imp_K2";
paulson@6452
   989
paulson@6452
   990
Goal
paulson@6452
   991
"[| Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|})\
paulson@6452
   992
\     : set evs; evs : kerberos|]  \
paulson@6452
   993
\  ==> EX Tk. (Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk,\
paulson@6452
   994
\          Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
   995
\            : set evs   \
paulson@6452
   996
\         & ServLife + Tt <= AuthLife + Tk)";
paulson@6452
   997
by (etac rev_mp 1);
paulson@6452
   998
by (parts_induct_tac 1);
paulson@6452
   999
by Auto_tac;
paulson@6452
  1000
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj RS parts.Fst RS
paulson@6452
  1001
                               A_trusts_AuthTicket]) 1);
paulson@6452
  1002
qed "K4_imp_K2_refined";
paulson@6452
  1003
paulson@6452
  1004
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|}  \
paulson@6452
  1005
\          : parts (spies evs);  B ~= Tgs;  B ~: bad;       \
paulson@6452
  1006
\        evs : kerberos |]                        \
paulson@6452
  1007
\==> EX AuthKey. \
paulson@6452
  1008
\      Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Tt,  \
paulson@6452
  1009
\                  Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Tt|}|}) \
paulson@6452
  1010
\      : set evs";
paulson@6452
  1011
by (etac rev_mp 1);
paulson@6452
  1012
by (parts_induct_tac 1);
paulson@6452
  1013
by (Fake_parts_insert_tac 1);
paulson@6452
  1014
by (Blast_tac 1);
paulson@6452
  1015
qed "B_trusts_ServKey";
paulson@6452
  1016
paulson@6452
  1017
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}  \
paulson@6452
  1018
\          : parts (spies evs);  B ~= Tgs;  B ~: bad;       \
paulson@6452
  1019
\        evs : kerberos |]                        \
paulson@6452
  1020
\  ==> EX AuthKey Tk. Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk,\
paulson@6452
  1021
\          Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
  1022
\            : set evs";
paulson@6452
  1023
by (blast_tac (claset() addSDs [B_trusts_ServKey, K4_imp_K2]) 1);
paulson@6452
  1024
qed "B_trusts_ServTicket_Kas";
paulson@6452
  1025
paulson@6452
  1026
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}  \
paulson@6452
  1027
\          : parts (spies evs); B ~= Tgs; B ~: bad;       \
paulson@6452
  1028
\        evs : kerberos |]                        \
paulson@6452
  1029
\  ==> EX AuthKey Tk. (Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk,\
paulson@6452
  1030
\          Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
  1031
\            : set evs            \
paulson@6452
  1032
\          & ServLife + Tt <= AuthLife + Tk)";
paulson@6452
  1033
by (blast_tac (claset() addSDs [B_trusts_ServKey,K4_imp_K2_refined]) 1);
paulson@6452
  1034
qed "B_trusts_ServTicket_Kas_refined";
paulson@6452
  1035
paulson@6452
  1036
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}  \
paulson@6452
  1037
\          : parts (spies evs); B ~= Tgs; B ~: bad;        \
paulson@6452
  1038
\        evs : kerberos |]                        \
paulson@6452
  1039
\==> EX Tk AuthKey.        \
paulson@6452
  1040
\    Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, \
paulson@6452
  1041
\                  Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
  1042
\      : set evs         \ 
paulson@6452
  1043
\    & Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt,  \
paulson@6452
  1044
\                  Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}|}) \
paulson@6452
  1045
\      : set evs";
wenzelm@7499
  1046
by (ftac B_trusts_ServKey 1);
paulson@6452
  1047
by (etac exE 4);
wenzelm@7499
  1048
by (ftac K4_imp_K2 4);
paulson@6452
  1049
by (Blast_tac 5);
paulson@6452
  1050
by (ALLGOALS assume_tac);
paulson@6452
  1051
qed "B_trusts_ServTicket";
paulson@6452
  1052
paulson@6452
  1053
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}  \
paulson@6452
  1054
\          : parts (spies evs); B ~= Tgs; B ~: bad;        \
paulson@6452
  1055
\        evs : kerberos |]                        \
paulson@6452
  1056
\==> EX Tk AuthKey.        \
paulson@6452
  1057
\    (Says Kas A (Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, \
paulson@6452
  1058
\                  Crypt (shrK Tgs) {|Agent A, Agent Tgs, Key AuthKey, Number Tk|}|})\
paulson@6452
  1059
\      : set evs         \ 
paulson@6452
  1060
\    & Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt,  \
paulson@6452
  1061
\                  Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}|}) \
paulson@6452
  1062
\      : set evs         \
paulson@6452
  1063
\    & ServLife + Tt <= AuthLife + Tk)";
wenzelm@7499
  1064
by (ftac B_trusts_ServKey 1);
paulson@6452
  1065
by (etac exE 4);
wenzelm@7499
  1066
by (ftac K4_imp_K2_refined 4);
paulson@6452
  1067
by (Blast_tac 5);
paulson@6452
  1068
by (ALLGOALS assume_tac);
paulson@6452
  1069
qed "B_trusts_ServTicket_refined";
paulson@6452
  1070
paulson@6452
  1071
paulson@6452
  1072
Goal "[| ~ ExpirServ Tt evs; ServLife + Tt <= AuthLife + Tk |]        \
paulson@6452
  1073
\  ==> ~ ExpirAuth Tk evs";
paulson@6452
  1074
by (blast_tac (claset() addDs [leI,le_trans] addEs [leE]) 1);
paulson@6452
  1075
qed "NotExpirServ_NotExpirAuth_refined";
paulson@6452
  1076
paulson@6452
  1077
paulson@6452
  1078
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|} \
paulson@6452
  1079
\          : parts (spies evs);                                        \
paulson@6452
  1080
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|} \
paulson@6452
  1081
\          : parts (spies evs);                                         \
paulson@6452
  1082
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}\
paulson@6452
  1083
\          : parts (spies evs);                     \
paulson@6452
  1084
\        ~ ExpirServ Tt evs; ~ ExpirAuth Tk evs;     \
paulson@6452
  1085
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1086
\     ==> Key ServKey ~: analz (spies evs)";
wenzelm@7499
  1087
by (ftac A_trusts_AuthKey 1);
wenzelm@7499
  1088
by (ftac Confidentiality_Kas 3);
wenzelm@7499
  1089
by (ftac B_trusts_ServTicket 6);
paulson@6452
  1090
by (etac exE 9);
paulson@6452
  1091
by (etac exE 9);
wenzelm@7499
  1092
by (ftac Says_Kas_message_form 9);
paulson@6452
  1093
by (blast_tac (claset() addDs [A_trusts_K4, 
paulson@6452
  1094
                               unique_ServKeys, unique_AuthKeys,
paulson@6452
  1095
                               Confidentiality_Tgs2]) 10);
paulson@6452
  1096
by (ALLGOALS assume_tac);
paulson@6452
  1097
(*
paulson@6452
  1098
The proof above executes in 8 secs. It can be done in one command in 50 secs:
paulson@6452
  1099
by (blast_tac (claset() addDs [A_trusts_AuthKey, A_trusts_K4,
paulson@6452
  1100
                               Says_Kas_message_form, B_trusts_ServTicket,
paulson@6452
  1101
                               unique_ServKeys, unique_AuthKeys,
paulson@6452
  1102
                               Confidentiality_Kas, 
paulson@6452
  1103
                               Confidentiality_Tgs2]) 1);
paulson@6452
  1104
*)
paulson@6452
  1105
qed "Confidentiality_B";
paulson@6452
  1106
paulson@6452
  1107
paulson@6452
  1108
(*Most general form -- only for refined model! *)
paulson@6452
  1109
Goal "[| Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}  \
paulson@6452
  1110
\          : parts (spies evs);                      \
paulson@6452
  1111
\        ~ ExpirServ Tt evs;                         \
paulson@6452
  1112
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1113
\     ==> Key ServKey ~: analz (spies evs)";
paulson@6452
  1114
by (blast_tac (claset() addDs [B_trusts_ServTicket_refined,
paulson@6452
  1115
			       NotExpirServ_NotExpirAuth_refined, 
paulson@6452
  1116
                               Confidentiality_Tgs2]) 1);
paulson@6452
  1117
qed "Confidentiality_B_refined";
paulson@6452
  1118
paulson@6452
  1119
paulson@6452
  1120
(********************** Authenticity theorems *****************************)
paulson@6452
  1121
paulson@6452
  1122
(***1. Session Keys authenticity: they originated with servers.***)
paulson@6452
  1123
paulson@6452
  1124
(*Authenticity of AuthKey for A: "A_trusts_AuthKey"*)
paulson@6452
  1125
paulson@6452
  1126
(*Authenticity of ServKey for A: "A_trusts_ServKey"*)
paulson@6452
  1127
Goal "[| Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|} \
paulson@6452
  1128
\          : parts (spies evs);                                     \
paulson@6452
  1129
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}   \
paulson@6452
  1130
\          : parts (spies evs);                                        \
paulson@6452
  1131
\        ~ ExpirAuth Tk evs; A ~: bad; evs : kerberos |]         \
paulson@6452
  1132
\==>Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|})\
paulson@6452
  1133
\      : set evs";
wenzelm@7499
  1134
by (ftac A_trusts_AuthKey 1 THEN assume_tac 1 THEN assume_tac 1);
paulson@6452
  1135
by (blast_tac (claset() addDs [Confidentiality_Auth_A, A_trusts_K4_bis]) 1);
paulson@6452
  1136
qed "A_trusts_ServKey"; 
paulson@6452
  1137
(*Note: requires a temporal check*)
paulson@6452
  1138
paulson@6452
  1139
paulson@6452
  1140
(*Authenticity of ServKey for B: "B_trusts_ServKey"*)
paulson@6452
  1141
paulson@6452
  1142
(***2. Parties authenticity: each party verifies "the identity of
paulson@6452
  1143
       another party who generated some data" (quoted from Neuman & Ts'o).***)
paulson@6452
  1144
       
paulson@6452
  1145
       (*These guarantees don't assess whether two parties agree on 
paulson@6452
  1146
         the same session key: sending a message containing a key
paulson@6452
  1147
         doesn't a priori state knowledge of the key.***)
paulson@6452
  1148
paulson@6452
  1149
(*B checks authenticity of A: theorems "A_Authenticity", 
paulson@6452
  1150
                                       "A_authenticity_refined" *)
paulson@6452
  1151
Goal "[| Crypt ServKey {|Agent A, Number Ta|} : parts (spies evs);  \
paulson@6452
  1152
\        Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, \
paulson@6452
  1153
\                                    ServTicket|}) : set evs;       \
paulson@6452
  1154
\        Key ServKey ~: analz (spies evs);                \
paulson@6452
  1155
\        A ~: bad; B ~: bad; evs : kerberos |]   \
paulson@6452
  1156
\==> Says A B {|ServTicket, Crypt ServKey {|Agent A, Number Ta|}|} : set evs";
paulson@6452
  1157
by (etac rev_mp 1);
paulson@6452
  1158
by (etac rev_mp 1);
paulson@6452
  1159
by (etac rev_mp 1);
paulson@6452
  1160
by (etac kerberos.induct 1);
wenzelm@7499
  1161
by (ftac Says_ticket_in_parts_spies 5);
wenzelm@7499
  1162
by (ftac Says_ticket_in_parts_spies 7);
paulson@6452
  1163
by (REPEAT (FIRSTGOAL analz_mono_contra_tac));
paulson@6452
  1164
by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
paulson@6452
  1165
by (Fake_parts_insert_tac 1);
paulson@6452
  1166
(*K3*)
paulson@6452
  1167
by (blast_tac (claset() addEs spies_partsEs
paulson@6452
  1168
                        addDs [A_trusts_AuthKey,
paulson@6452
  1169
                               Says_Kas_message_form, 
paulson@6452
  1170
                               Says_Tgs_message_form]) 1);
paulson@6452
  1171
(*K4*)
paulson@6452
  1172
by (force_tac (claset() addSDs [Crypt_imp_keysFor], simpset()) 1); 
paulson@6452
  1173
(*K5*)
paulson@6452
  1174
by (blast_tac (claset() addDs [Key_unique_SesKey] addEs spies_partsEs) 1);
paulson@6452
  1175
qed "Says_Auth";
paulson@6452
  1176
paulson@6452
  1177
(*The second assumption tells B what kind of key ServKey is.*)
paulson@6452
  1178
Goal "[| Crypt ServKey {|Agent A, Number Ta|} : parts (spies evs);     \
paulson@6452
  1179
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}       \
paulson@6452
  1180
\          : parts (spies evs);                                         \
paulson@6452
  1181
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}  \ 
paulson@6452
  1182
\          : parts (spies evs);                                          \
paulson@6452
  1183
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}  \
paulson@6452
  1184
\          : parts (spies evs);                                            \
paulson@6452
  1185
\        ~ ExpirServ Tt evs; ~ ExpirAuth Tk evs;  \
paulson@6452
  1186
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1187
\  ==> Says A B {|Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|},\
paulson@6452
  1188
\                 Crypt ServKey {|Agent A, Number Ta|} |} : set evs";
wenzelm@7499
  1189
by (ftac Confidentiality_B 1);
wenzelm@7499
  1190
by (ftac B_trusts_ServKey 9);
paulson@6452
  1191
by (etac exE 12);
paulson@6452
  1192
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj, Key_unique_SesKey]
paulson@6452
  1193
                        addSIs [Says_Auth]) 12);
paulson@6452
  1194
by (ALLGOALS assume_tac);
paulson@6452
  1195
qed "A_Authenticity";
paulson@6452
  1196
paulson@6452
  1197
(*Stronger form in the refined model*)
paulson@6452
  1198
Goal "[| Crypt ServKey {|Agent A, Number Ta2|} : parts (spies evs);     \
paulson@6452
  1199
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}       \
paulson@6452
  1200
\          : parts (spies evs);                                         \
paulson@6452
  1201
\        ~ ExpirServ Tt evs;                                        \
paulson@6452
  1202
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1203
\  ==> Says A B {|Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|},\
paulson@6452
  1204
\                 Crypt ServKey {|Agent A, Number Ta2|} |} : set evs";
wenzelm@7499
  1205
by (ftac Confidentiality_B_refined 1);
wenzelm@7499
  1206
by (ftac B_trusts_ServKey 6);
paulson@6452
  1207
by (etac exE 9);
paulson@6452
  1208
by (blast_tac (claset() addSDs [Says_imp_spies RS parts.Inj, Key_unique_SesKey]
paulson@6452
  1209
                        addSIs [Says_Auth]) 9);
paulson@6452
  1210
by (ALLGOALS assume_tac);
paulson@6452
  1211
qed "A_Authenticity_refined";
paulson@6452
  1212
paulson@6452
  1213
paulson@6452
  1214
(*A checks authenticity of B: theorem "B_authenticity"*)
paulson@6452
  1215
paulson@6452
  1216
Goal "[| Crypt ServKey (Number Ta) : parts (spies evs);  \
paulson@6452
  1217
\        Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, Number Tt, \
paulson@6452
  1218
\                                    ServTicket|}) : set evs;       \
paulson@6452
  1219
\        Key ServKey ~: analz (spies evs);                \
paulson@6452
  1220
\        A ~: bad; B ~: bad; evs : kerberos |]   \
paulson@6452
  1221
\     ==> Says B A (Crypt ServKey (Number Ta)) : set evs";
paulson@6452
  1222
by (etac rev_mp 1);
paulson@6452
  1223
by (etac rev_mp 1);
paulson@6452
  1224
by (etac rev_mp 1);
paulson@6452
  1225
by (etac kerberos.induct 1);
wenzelm@7499
  1226
by (ftac Says_ticket_in_parts_spies 5);
wenzelm@7499
  1227
by (ftac Says_ticket_in_parts_spies 7);
paulson@6452
  1228
by (REPEAT (FIRSTGOAL analz_mono_contra_tac));
paulson@6452
  1229
by (ALLGOALS Asm_simp_tac);
paulson@6452
  1230
by (Fake_parts_insert_tac 1);
paulson@6452
  1231
by (force_tac (claset() addSDs [Crypt_imp_keysFor], simpset()) 1); 
paulson@6452
  1232
by (Clarify_tac 1);
wenzelm@7499
  1233
by (ftac Says_Tgs_message_form 1 THEN assume_tac 1);
paulson@6452
  1234
by (Clarify_tac 1);  (*PROOF FAILED if omitted*)
paulson@6452
  1235
by (blast_tac (claset() addDs [unique_CryptKey] addEs spies_partsEs) 1);
paulson@6452
  1236
qed "Says_K6";
paulson@6452
  1237
paulson@6452
  1238
Goal "[| Crypt AuthKey {|Key ServKey, Agent B, T, ServTicket|}   \
paulson@6452
  1239
\          : parts (spies evs);    \
paulson@6452
  1240
\        Key AuthKey ~: analz (spies evs); AuthKey ~: range shrK;  \
paulson@6452
  1241
\        evs : kerberos |]              \
paulson@6452
  1242
\ ==> EX A. Says Tgs A (Crypt AuthKey {|Key ServKey, Agent B, T, ServTicket|})\
paulson@6452
  1243
\             : set evs";
paulson@6452
  1244
by (etac rev_mp 1);
paulson@6452
  1245
by (etac rev_mp 1);
paulson@6452
  1246
by (parts_induct_tac 1);
paulson@6452
  1247
by (Fake_parts_insert_tac 1);
paulson@6452
  1248
by (Blast_tac 1);
paulson@6452
  1249
by (Blast_tac 1);
paulson@6452
  1250
qed "K4_trustworthy";
paulson@6452
  1251
paulson@6452
  1252
Goal "[| Crypt ServKey (Number Ta) : parts (spies evs);           \
paulson@6452
  1253
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|} \
paulson@6452
  1254
\          : parts (spies evs);                                        \ 
paulson@6452
  1255
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}\
paulson@6452
  1256
\          : parts (spies evs);                                          \
paulson@6452
  1257
\        ~ ExpirAuth Tk evs; ~ ExpirServ Tt evs;                         \
paulson@6452
  1258
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1259
\     ==> Says B A (Crypt ServKey (Number Ta)) : set evs";
wenzelm@7499
  1260
by (ftac A_trusts_AuthKey 1);
wenzelm@7499
  1261
by (ftac Says_Kas_message_form 3);
wenzelm@7499
  1262
by (ftac Confidentiality_Kas 4);
wenzelm@7499
  1263
by (ftac K4_trustworthy 7);
paulson@6452
  1264
by (Blast_tac 8);
paulson@6452
  1265
by (etac exE 9);
wenzelm@7499
  1266
by (ftac K4_imp_K2 9);
paulson@6452
  1267
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj, Key_unique_SesKey]
paulson@6452
  1268
                        addSIs [Says_K6]
paulson@6452
  1269
                        addSEs [Confidentiality_Tgs1 RSN (2,rev_notE)]) 10);
paulson@6452
  1270
by (ALLGOALS assume_tac);
paulson@6452
  1271
qed "B_Authenticity";
paulson@6452
  1272
paulson@6452
  1273
paulson@6452
  1274
(***3. Parties' knowledge of session keys. A knows a session key if she
paulson@6452
  1275
       used it to build a cipher.***)
paulson@6452
  1276
paulson@6452
  1277
Goal "[| Says B A (Crypt ServKey (Number Ta)) : set evs;           \
paulson@6452
  1278
\        Key ServKey ~: analz (spies evs);                          \
paulson@6452
  1279
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1280
\     ==> B Issues A with (Crypt ServKey (Number Ta)) on evs";
paulson@6452
  1281
by (simp_tac (simpset() addsimps [Issues_def]) 1);
paulson@6452
  1282
by (rtac exI 1);
paulson@6452
  1283
by (rtac conjI 1);
paulson@6452
  1284
by (assume_tac 1);
paulson@6452
  1285
by (Simp_tac 1);
paulson@6452
  1286
by (etac rev_mp 1);
paulson@6452
  1287
by (etac rev_mp 1);
paulson@6452
  1288
by (etac kerberos.induct 1);
wenzelm@7499
  1289
by (ftac Says_ticket_in_parts_spies 5);
wenzelm@7499
  1290
by (ftac Says_ticket_in_parts_spies 7);
paulson@6452
  1291
by (REPEAT (FIRSTGOAL analz_mono_contra_tac));
paulson@6452
  1292
by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
paulson@6452
  1293
by (Fake_parts_insert_tac 1);
paulson@6452
  1294
(*K6 requires numerous lemmas*)
paulson@6452
  1295
by (asm_full_simp_tac (simpset() addsimps [takeWhile_tail]) 1);
paulson@6452
  1296
by (blast_tac (claset() addDs [B_trusts_ServTicket,
paulson@6452
  1297
                               impOfSubs parts_spies_takeWhile_mono,
paulson@6452
  1298
                               impOfSubs parts_spies_evs_revD2]
paulson@6452
  1299
                        addIs [Says_K6]
paulson@6452
  1300
                        addEs spies_partsEs) 1);
paulson@6452
  1301
qed "B_Knows_B_Knows_ServKey_lemma";
paulson@6452
  1302
(*Key ServKey ~: analz (spies evs) could be relaxed by Confidentiality_B
paulson@6452
  1303
  but this is irrelevant because B knows what he knows!                  *)
paulson@6452
  1304
paulson@6452
  1305
Goal "[| Says B A (Crypt ServKey (Number Ta)) : set evs;           \
paulson@6452
  1306
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}\
paulson@6452
  1307
\           : parts (spies evs);\
paulson@6452
  1308
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}\
paulson@6452
  1309
\           : parts (spies evs);\
paulson@6452
  1310
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}\
paulson@6452
  1311
\          : parts (spies evs);     \
paulson@6452
  1312
\        ~ ExpirServ Tt evs; ~ ExpirAuth Tk evs;              \
paulson@6452
  1313
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1314
\     ==> B Issues A with (Crypt ServKey (Number Ta)) on evs";
paulson@6452
  1315
by (blast_tac (claset() addSDs [Confidentiality_B,
paulson@6452
  1316
	                       B_Knows_B_Knows_ServKey_lemma]) 1);
paulson@6452
  1317
qed "B_Knows_B_Knows_ServKey";
paulson@6452
  1318
paulson@6452
  1319
Goal "[| Says B A (Crypt ServKey (Number Ta)) : set evs;           \
paulson@6452
  1320
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}\
paulson@6452
  1321
\           : parts (spies evs);\
paulson@6452
  1322
\        ~ ExpirServ Tt evs;            \
paulson@6452
  1323
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1324
\     ==> B Issues A with (Crypt ServKey (Number Ta)) on evs";
paulson@6452
  1325
by (blast_tac (claset() addSDs [Confidentiality_B_refined,
paulson@6452
  1326
	                       B_Knows_B_Knows_ServKey_lemma]) 1);
paulson@6452
  1327
qed "B_Knows_B_Knows_ServKey_refined";
paulson@6452
  1328
paulson@6452
  1329
paulson@6452
  1330
Goal "[| Crypt ServKey (Number Ta) : parts (spies evs);           \
paulson@6452
  1331
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|} \
paulson@6452
  1332
\          : parts (spies evs);                                        \ 
paulson@6452
  1333
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}\
paulson@6452
  1334
\          : parts (spies evs);                                          \
paulson@6452
  1335
\        ~ ExpirAuth Tk evs; ~ ExpirServ Tt evs;                         \
paulson@6452
  1336
\        A ~: bad;  B ~: bad; B ~= Tgs; evs : kerberos |]            \
paulson@6452
  1337
\     ==> B Issues A with (Crypt ServKey (Number Ta)) on evs";
paulson@6452
  1338
by (blast_tac (claset() addSDs [B_Authenticity, Confidentiality_Serv_A,
paulson@6452
  1339
                                B_Knows_B_Knows_ServKey_lemma]) 1);
paulson@6452
  1340
qed "A_Knows_B_Knows_ServKey";
paulson@6452
  1341
paulson@6452
  1342
Goal "[| Says A Tgs     \
paulson@6452
  1343
\            {|AuthTicket, Crypt AuthKey {|Agent A, Number Ta|}, Agent B|}\
paulson@6452
  1344
\          : set evs;      \
paulson@6452
  1345
\        A ~: bad;  evs : kerberos |]         \
paulson@6452
  1346
\     ==> EX Tk. Says Kas A (Crypt (shrK A) \
paulson@6452
  1347
\                     {|Key AuthKey, Agent Tgs, Tk, AuthTicket|}) \
paulson@6452
  1348
\                  : set evs";
paulson@6452
  1349
by (etac rev_mp 1);
paulson@6452
  1350
by (parts_induct_tac 1);
paulson@6452
  1351
by (Fake_parts_insert_tac 1);
paulson@6452
  1352
by (Blast_tac 1);
paulson@6452
  1353
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS 
paulson@6452
  1354
			       A_trusts_AuthKey]) 1);
paulson@6452
  1355
qed "K3_imp_K2";
paulson@6452
  1356
paulson@6452
  1357
Goal "[| Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}   \
paulson@6452
  1358
\          : parts (spies evs);                    \
paulson@6452
  1359
\        Says Kas A (Crypt (shrK A) \
paulson@6452
  1360
\                    {|Key AuthKey, Agent Tgs, Tk, AuthTicket|}) \
paulson@6452
  1361
\        : set evs;    \
paulson@6452
  1362
\        Key AuthKey ~: analz (spies evs);       \
paulson@6452
  1363
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1364
\  ==> Says Tgs A (Crypt AuthKey        \ 
paulson@6452
  1365
\                    {|Key ServKey, Agent B, Number Tt, ServTicket|})  \
paulson@6452
  1366
\        : set evs";      
paulson@6452
  1367
by (etac rev_mp 1);
paulson@6452
  1368
by (etac rev_mp 1);
paulson@6452
  1369
by (etac rev_mp 1);
paulson@6452
  1370
by (parts_induct_tac 1);
paulson@6452
  1371
by (Fake_parts_insert_tac 1);
paulson@6452
  1372
by (force_tac (claset() addSDs [Crypt_imp_keysFor], simpset()) 1); 
paulson@6452
  1373
by (blast_tac (claset() addDs [Says_imp_spies RS parts.Inj RS parts.Fst RS
paulson@6452
  1374
                               A_trusts_AuthTicket, unique_AuthKeys]) 1);
paulson@6452
  1375
qed "K4_trustworthy'";
paulson@6452
  1376
paulson@6452
  1377
Goal "[| Says A B {|ServTicket, Crypt ServKey {|Agent A, Number Ta|}|} \
paulson@6452
  1378
\          : set evs;       \
paulson@6452
  1379
\        Key ServKey ~: analz (spies evs);       \
paulson@6452
  1380
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1381
\  ==> A Issues B with (Crypt ServKey {|Agent A, Number Ta|}) on evs";
paulson@6452
  1382
by (simp_tac (simpset() addsimps [Issues_def]) 1);
paulson@6452
  1383
by (rtac exI 1);
paulson@6452
  1384
by (rtac conjI 1);
paulson@6452
  1385
by (assume_tac 1);
paulson@6452
  1386
by (Simp_tac 1);
paulson@6452
  1387
by (etac rev_mp 1);
paulson@6452
  1388
by (etac rev_mp 1);
paulson@6452
  1389
by (etac kerberos.induct 1);
wenzelm@7499
  1390
by (ftac Says_ticket_in_parts_spies 5);
wenzelm@7499
  1391
by (ftac Says_ticket_in_parts_spies 7);
paulson@6452
  1392
by (REPEAT (FIRSTGOAL analz_mono_contra_tac));
paulson@6452
  1393
by (ALLGOALS Asm_simp_tac);
paulson@6452
  1394
by (Clarify_tac 1);
paulson@6452
  1395
(*K6*)
paulson@6452
  1396
by Auto_tac;
paulson@6452
  1397
by (asm_full_simp_tac (simpset() addsimps [takeWhile_tail]) 1);
paulson@6452
  1398
(*Level 15: case study necessary because the assumption doesn't state
paulson@6452
  1399
  the form of ServTicket. The guarantee becomes stronger.*)
paulson@6452
  1400
by (case_tac "Key AuthKey : analz (spies evs5)" 1);
paulson@6452
  1401
by (force_tac (claset() addDs [Says_imp_spies RS analz.Inj RS 
paulson@6452
  1402
			       analz.Decrypt RS analz.Fst],
paulson@6452
  1403
	       simpset()) 1);
paulson@6452
  1404
by (blast_tac (claset() addDs [K3_imp_K2, K4_trustworthy',
paulson@6452
  1405
                               impOfSubs parts_spies_takeWhile_mono,
paulson@6452
  1406
                               impOfSubs parts_spies_evs_revD2]
paulson@6452
  1407
                        addIs [Says_Auth] 
paulson@6452
  1408
                        addEs spies_partsEs) 1);
paulson@6452
  1409
by (asm_full_simp_tac (simpset() addsimps [takeWhile_tail]) 1);
paulson@6452
  1410
qed "A_Knows_A_Knows_ServKey_lemma";
paulson@6452
  1411
paulson@6452
  1412
Goal "[| Says A B {|ServTicket, Crypt ServKey {|Agent A, Number Ta|}|} \
paulson@6452
  1413
\          : set evs;       \
paulson@6452
  1414
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}\
paulson@6452
  1415
\          : parts (spies evs);\
paulson@6452
  1416
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}\
paulson@6452
  1417
\          : parts (spies evs);                                        \
paulson@6452
  1418
\        ~ ExpirAuth Tk evs; ~ ExpirServ Tt evs;\
paulson@6452
  1419
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1420
\  ==> A Issues B with (Crypt ServKey {|Agent A, Number Ta|}) on evs";
paulson@6452
  1421
by (blast_tac (claset() addSDs [Confidentiality_Serv_A,
paulson@6452
  1422
	                       A_Knows_A_Knows_ServKey_lemma]) 1);
paulson@6452
  1423
qed "A_Knows_A_Knows_ServKey";
paulson@6452
  1424
paulson@6452
  1425
Goal "[| Crypt ServKey {|Agent A, Number Ta|} : parts (spies evs);     \
paulson@6452
  1426
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}       \
paulson@6452
  1427
\          : parts (spies evs);                                         \
paulson@6452
  1428
\        Crypt AuthKey {|Key ServKey, Agent B, Number Tt, ServTicket|}  \ 
paulson@6452
  1429
\          : parts (spies evs);                                          \
paulson@6452
  1430
\        Crypt (shrK A) {|Key AuthKey, Agent Tgs, Number Tk, AuthTicket|}  \
paulson@6452
  1431
\          : parts (spies evs);                                            \
paulson@6452
  1432
\        ~ ExpirServ Tt evs; ~ ExpirAuth Tk evs;  \
paulson@6452
  1433
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1434
\  ==> A Issues B with (Crypt ServKey {|Agent A, Number Ta|}) on evs";
paulson@6452
  1435
by (blast_tac (claset() addDs [A_Authenticity, Confidentiality_B,
paulson@6452
  1436
	                       A_Knows_A_Knows_ServKey_lemma]) 1);
paulson@6452
  1437
qed "B_Knows_A_Knows_ServKey";
paulson@6452
  1438
paulson@6452
  1439
paulson@6452
  1440
Goal "[| Crypt ServKey {|Agent A, Number Ta|} : parts (spies evs);     \
paulson@6452
  1441
\        Crypt (shrK B) {|Agent A, Agent B, Key ServKey, Number Tt|}       \
paulson@6452
  1442
\          : parts (spies evs);                                         \
paulson@6452
  1443
\        ~ ExpirServ Tt evs;                                        \
paulson@6452
  1444
\        B ~= Tgs; A ~: bad;  B ~: bad;  evs : kerberos |]         \
paulson@6452
  1445
\  ==> A Issues B with (Crypt ServKey {|Agent A, Number Ta|}) on evs";
paulson@6452
  1446
by (blast_tac (claset() addDs [A_Authenticity_refined, 
paulson@6452
  1447
                               Confidentiality_B_refined,
paulson@6452
  1448
	                       A_Knows_A_Knows_ServKey_lemma]) 1);
paulson@6452
  1449
qed "B_Knows_A_Knows_ServKey_refined";