src/HOL/Auth/OtwayRees_AN.ML
changeset 11185 1b737b4c2108
parent 11150 67387142225e
child 11204 bb01189f0565
equal deleted inserted replaced
11184:10a307328d2c 11185:1b737b4c2108
    15 AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
    15 AddDs  [Says_imp_knows_Spy RS parts.Inj, parts.Body];
    16 AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
    16 AddDs  [impOfSubs analz_subset_parts, impOfSubs Fake_parts_insert];
    17 
    17 
    18 
    18 
    19 (*A "possibility property": there are traces that reach the end*)
    19 (*A "possibility property": there are traces that reach the end*)
    20 Goal "[| B ~= Server |]   \
    20 Goal "B ~= Server   \
    21 \     ==> EX K. EX NA. EX evs: otway.                                      \
    21 \     ==> \\<exists>K. \\<exists>NA. \\<exists>evs \\<in> otway.                                      \
    22 \          Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    22 \          Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    23 \            : set evs";
    23 \            \\<in> set evs";
    24 by (REPEAT (resolve_tac [exI,bexI] 1));
    24 by (REPEAT (resolve_tac [exI,bexI] 1));
    25 by (rtac (otway.Nil RS 
    25 by (rtac (otway.Nil RS 
    26           otway.OR1 RS otway.Reception RS
    26           otway.OR1 RS otway.Reception RS
    27           otway.OR2 RS otway.Reception RS 
    27           otway.OR2 RS otway.Reception RS 
    28           otway.OR3 RS otway.Reception RS otway.OR4) 2);
    28           otway.OR3 RS otway.Reception RS otway.OR4) 2);
    29 by possibility_tac;
    29 by possibility_tac;
    30 result();
    30 result();
    31 
    31 
    32 Goal "[| Gets B X : set evs; evs : otway |] ==> EX A. Says A B X : set evs";
    32 Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |] ==> \\<exists>A. Says A B X \\<in> set evs";
    33 by (etac rev_mp 1);
    33 by (etac rev_mp 1);
    34 by (etac otway.induct 1);
    34 by (etac otway.induct 1);
    35 by Auto_tac;
    35 by Auto_tac;
    36 qed"Gets_imp_Says";
    36 qed"Gets_imp_Says";
    37 
    37 
    38 (*Must be proved separately for each protocol*)
    38 (*Must be proved separately for each protocol*)
    39 Goal "[| Gets B X : set evs; evs : otway |]  ==> X : knows Spy evs";
    39 Goal "[| Gets B X \\<in> set evs; evs \\<in> otway |]  ==> X \\<in> knows Spy evs";
    40 by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
    40 by (blast_tac (claset() addSDs [Gets_imp_Says, Says_imp_knows_Spy]) 1);
    41 qed"Gets_imp_knows_Spy";
    41 qed"Gets_imp_knows_Spy";
    42 AddDs [Gets_imp_knows_Spy RS parts.Inj];
    42 AddDs [Gets_imp_knows_Spy RS parts.Inj];
    43 
    43 
    44 
    44 
    45 (**** Inductive proofs about otway ****)
    45 (**** Inductive proofs about otway ****)
    46 
    46 
    47 (** For reasoning about the encrypted portion of messages **)
    47 (** For reasoning about the encrypted portion of messages **)
    48 
    48 
    49 Goal "[| Gets B {|X, Crypt(shrK B) X'|} : set evs;  evs : otway |] ==> \
    49 Goal "[| Gets B {|X, Crypt(shrK B) X'|} \\<in> set evs;  evs \\<in> otway |]  \
    50 \          X : analz (knows Spy evs)";
    50 \     ==> X \\<in> analz (knows Spy evs)";
    51 by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    51 by (blast_tac (claset() addSDs [Gets_imp_knows_Spy RS analz.Inj]) 1);
    52 qed "OR4_analz_knows_Spy";
    52 qed "OR4_analz_knows_Spy";
    53 
    53 
    54 Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} : set evs \
    54 Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} \\<in> set evs \
    55 \     ==> K : parts (knows Spy evs)";
    55 \     ==> K \\<in> parts (knows Spy evs)";
    56 by (Blast_tac 1);
    56 by (Blast_tac 1);
    57 qed "Oops_parts_knows_Spy";
    57 qed "Oops_parts_knows_Spy";
    58 
    58 
    59 bind_thm ("OR4_parts_knows_Spy",
    59 bind_thm ("OR4_parts_knows_Spy",
    60           OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    60           OR4_analz_knows_Spy RS (impOfSubs analz_subset_parts));
    61 
    61 
    62 (*For proving the easier theorems about X ~: parts (knows Spy evs).*)
    62 (*For proving the easier theorems about X \\<notin> parts (knows Spy evs).*)
    63 fun parts_induct_tac i = 
    63 fun parts_induct_tac i = 
    64     etac otway.induct i			THEN 
    64     etac otway.induct i			THEN 
    65     ftac Oops_parts_knows_Spy (i+7) THEN
    65     ftac Oops_parts_knows_Spy (i+7) THEN
    66     ftac OR4_parts_knows_Spy (i+6) THEN
    66     ftac OR4_parts_knows_Spy (i+6) THEN
    67     prove_simple_subgoals_tac  i;
    67     prove_simple_subgoals_tac  i;
    68 
    68 
    69 
    69 
    70 (** Theorems of the form X ~: parts (knows Spy evs) imply that NOBODY
    70 (** Theorems of the form X \\<notin> parts (knows Spy evs) imply that NOBODY
    71     sends messages containing X! **)
    71     sends messages containing X! **)
    72 
    72 
    73 (*Spy never sees a good agent's shared key!*)
    73 (*Spy never sees a good agent's shared key!*)
    74 Goal "evs : otway ==> (Key (shrK A) : parts (knows Spy evs)) = (A : bad)";
    74 Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> parts (knows Spy evs)) = (A \\<in> bad)";
    75 by (parts_induct_tac 1);
    75 by (parts_induct_tac 1);
    76 by (ALLGOALS Blast_tac);
    76 by (ALLGOALS Blast_tac);
    77 qed "Spy_see_shrK";
    77 qed "Spy_see_shrK";
    78 Addsimps [Spy_see_shrK];
    78 Addsimps [Spy_see_shrK];
    79 
    79 
    80 Goal "evs : otway ==> (Key (shrK A) : analz (knows Spy evs)) = (A : bad)";
    80 Goal "evs \\<in> otway ==> (Key (shrK A) \\<in> analz (knows Spy evs)) = (A \\<in> bad)";
    81 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    81 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    82 qed "Spy_analz_shrK";
    82 qed "Spy_analz_shrK";
    83 Addsimps [Spy_analz_shrK];
    83 Addsimps [Spy_analz_shrK];
    84 
    84 
    85 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    85 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    86 	Spy_analz_shrK RSN (2, rev_iffD1)];
    86 	Spy_analz_shrK RSN (2, rev_iffD1)];
    87 
       
    88 
       
    89 (*Nobody can have used non-existent keys!*)
       
    90 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (knows Spy evs))";
       
    91 by (parts_induct_tac 1);
       
    92 (*Fake*)
       
    93 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
       
    94 (*OR3*)
       
    95 by (Blast_tac 1);
       
    96 qed_spec_mp "new_keys_not_used";
       
    97 
       
    98 bind_thm ("new_keys_not_analzd",
       
    99           [analz_subset_parts RS keysFor_mono,
       
   100            new_keys_not_used] MRS contra_subsetD);
       
   101 
       
   102 Addsimps [new_keys_not_used, new_keys_not_analzd];
       
   103 
       
   104 
    87 
   105 
    88 
   106 (*** Proofs involving analz ***)
    89 (*** Proofs involving analz ***)
   107 
    90 
   108 (*Describes the form of K and NA when the Server sends this message.*)
    91 (*Describes the form of K and NA when the Server sends this message.*)
   109 Goal "[| Says Server B                                           \
    92 Goal "[| Says Server B                                           \
   110 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
    93 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   111 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
    94 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   112 \          : set evs;                                            \
    95 \          \\<in> set evs;                                            \
   113 \        evs : otway |]                                          \
    96 \        evs \\<in> otway |]                                          \
   114 \     ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
    97 \     ==> K \\<notin> range shrK & (\\<exists>i. NA = Nonce i) & (\\<exists>j. NB = Nonce j)";
   115 by (etac rev_mp 1);
    98 by (etac rev_mp 1);
   116 by (etac otway.induct 1);
    99 by (etac otway.induct 1);
   117 by (ALLGOALS Asm_simp_tac);
   100 by (ALLGOALS Asm_simp_tac);
   118 by (Blast_tac 1);
   101 by (Blast_tac 1);
   119 qed "Says_Server_message_form";
   102 qed "Says_Server_message_form";
   137 
   120 
   138 
   121 
   139 (** Session keys are not used to encrypt other session keys **)
   122 (** Session keys are not used to encrypt other session keys **)
   140 
   123 
   141 (*The equality makes the induction hypothesis easier to apply*)
   124 (*The equality makes the induction hypothesis easier to apply*)
   142 Goal "evs : otway ==>                                 \
   125 Goal "evs \\<in> otway ==>                                 \
   143 \  ALL K KK. KK <= -(range shrK) -->                  \
   126 \  ALL K KK. KK <= -(range shrK) -->                  \
   144 \         (Key K : analz (Key`KK Un (knows Spy evs))) =  \
   127 \         (Key K \\<in> analz (Key`KK Un (knows Spy evs))) =  \
   145 \         (K : KK | Key K : analz (knows Spy evs))";
   128 \         (K \\<in> KK | Key K \\<in> analz (knows Spy evs))";
   146 by (etac otway.induct 1);
   129 by (etac otway.induct 1);
   147 by analz_knows_Spy_tac;
   130 by analz_knows_Spy_tac;
   148 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   131 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   149 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   132 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   150 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   133 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   151 (*Fake*) 
   134 (*Fake*) 
   152 by (spy_analz_tac 1);
   135 by (spy_analz_tac 1);
   153 qed_spec_mp "analz_image_freshK";
   136 qed_spec_mp "analz_image_freshK";
   154 
   137 
   155 
   138 
   156 Goal "[| evs : otway;  KAB ~: range shrK |] ==>       \
   139 Goal "[| evs \\<in> otway;  KAB \\<notin> range shrK |] ==>       \
   157 \     Key K : analz (insert (Key KAB) (knows Spy evs)) =  \
   140 \     Key K \\<in> analz (insert (Key KAB) (knows Spy evs)) =  \
   158 \     (K = KAB | Key K : analz (knows Spy evs))";
   141 \     (K = KAB | Key K \\<in> analz (knows Spy evs))";
   159 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   142 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   160 qed "analz_insert_freshK";
   143 qed "analz_insert_freshK";
   161 
   144 
   162 
   145 
   163 (*** The Key K uniquely identifies the Server's message. **)
   146 (*** The Key K uniquely identifies the Server's message. **)
   164 
   147 
   165 Goal "[| Says Server B                                           \
   148 Goal "[| Says Server B                                           \
   166 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   149 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   167 \           Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}        \
   150 \           Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}        \
   168 \        : set evs;                                             \
   151 \        \\<in> set evs;                                             \
   169 \       Says Server B'                                          \
   152 \       Says Server B'                                          \
   170 \         {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},     \
   153 \         {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},     \
   171 \           Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}    \
   154 \           Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}    \
   172 \        : set evs;                                             \
   155 \        \\<in> set evs;                                             \
   173 \       evs : otway |]                                          \
   156 \       evs \\<in> otway |]                                          \
   174 \    ==> A=A' & B=B' & NA=NA' & NB=NB'";
   157 \    ==> A=A' & B=B' & NA=NA' & NB=NB'";
   175 by (etac rev_mp 1);
   158 by (etac rev_mp 1);
   176 by (etac rev_mp 1);
   159 by (etac rev_mp 1);
   177 by (etac otway.induct 1);
   160 by (etac otway.induct 1);
   178 by (ALLGOALS Asm_simp_tac);
   161 by (ALLGOALS Asm_simp_tac);
   183 
   166 
   184 
   167 
   185 (**** Authenticity properties relating to NA ****)
   168 (**** Authenticity properties relating to NA ****)
   186 
   169 
   187 (*If the encrypted message appears then it originated with the Server!*)
   170 (*If the encrypted message appears then it originated with the Server!*)
   188 Goal "[| A ~: bad;  A ~= B;  evs : otway |]                 \
   171 Goal "[| A \\<notin> bad;  A ~= B;  evs \\<in> otway |]                 \
   189 \     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} : parts (knows Spy evs) \
   172 \     ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} \\<in> parts (knows Spy evs) \
   190 \      --> (EX NB. Says Server B                                          \
   173 \      --> (\\<exists>NB. Says Server B                                          \
   191 \                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   174 \                   {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   192 \                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   175 \                     Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   193 \                   : set evs)";
   176 \                   \\<in> set evs)";
   194 by (parts_induct_tac 1);
   177 by (parts_induct_tac 1);
   195 by (Blast_tac 1);
   178 by (Blast_tac 1);
   196 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   179 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   197 (*OR3*)
   180 (*OR3*)
   198 by (Blast_tac 1);
   181 by (Blast_tac 1);
   200 
   183 
   201 
   184 
   202 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   185 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   203   Freshness may be inferred from nonce NA.*)
   186   Freshness may be inferred from nonce NA.*)
   204 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   187 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   205 \         : set evs;                                                 \
   188 \         \\<in> set evs;                                                 \
   206 \        A ~: bad;  A ~= B;  evs : otway |]                          \
   189 \        A \\<notin> bad;  A ~= B;  evs \\<in> otway |]                          \
   207 \     ==> EX NB. Says Server B                                       \
   190 \     ==> \\<exists>NB. Says Server B                                       \
   208 \                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   191 \                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   209 \                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   192 \                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   210 \                : set evs";
   193 \                \\<in> set evs";
   211 by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   194 by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   212 qed "A_trusts_OR4";
   195 qed "A_trusts_OR4";
   213 
   196 
   214 
   197 
   215 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   198 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   216     Does not in itself guarantee security: an attack could violate 
   199     Does not in itself guarantee security: an attack could violate 
   217     the premises, e.g. by having A=Spy **)
   200     the premises, e.g. by having A=Spy **)
   218 
   201 
   219 Goal "[| A ~: bad;  B ~: bad;  evs : otway |]                   \
   202 Goal "[| A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                   \
   220 \     ==> Says Server B                                         \
   203 \     ==> Says Server B                                         \
   221 \          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   204 \          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   222 \            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   205 \            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   223 \         : set evs -->                                         \
   206 \         \\<in> set evs -->                                         \
   224 \         Notes Spy {|NA, NB, Key K|} ~: set evs -->            \
   207 \         Notes Spy {|NA, NB, Key K|} \\<notin> set evs -->            \
   225 \         Key K ~: analz (knows Spy evs)";
   208 \         Key K \\<notin> analz (knows Spy evs)";
   226 by (etac otway.induct 1);
   209 by (etac otway.induct 1);
   227 by analz_knows_Spy_tac;
   210 by analz_knows_Spy_tac;
   228 by (ALLGOALS
   211 by (ALLGOALS
   229     (asm_simp_tac (simpset() addcongs [conj_cong] 
   212     (asm_simp_tac (simpset() addcongs [conj_cong] 
   230                              addsimps [analz_insert_eq, analz_insert_freshK]
   213                              addsimps [analz_insert_eq, analz_insert_freshK]
   240 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   223 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   241 
   224 
   242 Goal "[| Says Server B                                           \
   225 Goal "[| Says Server B                                           \
   243 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   226 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   244 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   227 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   245 \          : set evs;                                            \
   228 \          \\<in> set evs;                                            \
   246 \        Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   229 \        Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   247 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   230 \        A \\<notin> bad;  B \\<notin> bad;  evs \\<in> otway |]                    \
   248 \     ==> Key K ~: analz (knows Spy evs)";
   231 \     ==> Key K \\<notin> analz (knows Spy evs)";
   249 by (ftac Says_Server_message_form 1 THEN assume_tac 1);
   232 by (ftac Says_Server_message_form 1 THEN assume_tac 1);
   250 by (blast_tac (claset() addSEs [lemma]) 1);
   233 by (blast_tac (claset() addSEs [lemma]) 1);
   251 qed "Spy_not_see_encrypted_key";
   234 qed "Spy_not_see_encrypted_key";
   252 
   235 
   253 
   236 
   254 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   237 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   255   what it is.*)
   238   what it is.*)
   256 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   239 Goal "[| Gets A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   257 \         : set evs;                                                 \
   240 \         \\<in> set evs;                                                 \
   258 \        ALL NB. Notes Spy {|NA, NB, Key K|} ~: set evs;             \
   241 \        ALL NB. Notes Spy {|NA, NB, Key K|} \\<notin> set evs;             \
   259 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]               \
   242 \        A \\<notin> bad;  B \\<notin> bad;  A ~= B;  evs \\<in> otway |]               \
   260 \     ==> Key K ~: analz (knows Spy evs)";
   243 \     ==> Key K \\<notin> analz (knows Spy evs)";
   261 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   244 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   262 qed "A_gets_good_key";
   245 qed "A_gets_good_key";
   263 
   246 
   264 
   247 
   265 (**** Authenticity properties relating to NB ****)
   248 (**** Authenticity properties relating to NB ****)
   266 
   249 
   267 (*If the encrypted message appears then it originated with the Server!*)
   250 (*If the encrypted message appears then it originated with the Server!*)
   268 Goal "[| B ~: bad;  A ~= B;  evs : otway |]                              \
   251 Goal "[| B \\<notin> bad;  A ~= B;  evs \\<in> otway |]                              \
   269 \ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} : parts (knows Spy evs) \
   252 \ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} \\<in> parts (knows Spy evs) \
   270 \     --> (EX NA. Says Server B                                          \
   253 \     --> (\\<exists>NA. Says Server B                                          \
   271 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   254 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   272 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   255 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   273 \                  : set evs)";
   256 \                  \\<in> set evs)";
   274 by (parts_induct_tac 1);
   257 by (parts_induct_tac 1);
   275 by (Blast_tac 1);
   258 by (Blast_tac 1);
   276 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   259 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   277 (*OR3*)
   260 (*OR3*)
   278 by (Blast_tac 1);
   261 by (Blast_tac 1);
   280 
   263 
   281 
   264 
   282 (*Guarantee for B: if it gets a well-formed certificate then the Server
   265 (*Guarantee for B: if it gets a well-formed certificate then the Server
   283   has sent the correct message in round 3.*)
   266   has sent the correct message in round 3.*)
   284 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   267 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   285 \          : set evs;                                                    \
   268 \          \\<in> set evs;                                                    \
   286 \        B ~: bad;  A ~= B;  evs : otway |]                              \
   269 \        B \\<notin> bad;  A ~= B;  evs \\<in> otway |]                              \
   287 \     ==> EX NA. Says Server B                                           \
   270 \     ==> \\<exists>NA. Says Server B                                           \
   288 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   271 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   289 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   272 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   290 \                  : set evs";
   273 \                  \\<in> set evs";
   291 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   274 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   292 qed "B_trusts_OR3";
   275 qed "B_trusts_OR3";
   293 
   276 
   294 
   277 
   295 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   278 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   296 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   279 Goal "[| Gets B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   297 \         : set evs;                                                     \
   280 \         \\<in> set evs;                                                     \
   298 \        ALL NA. Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   281 \        ALL NA. Notes Spy {|NA, NB, Key K|} \\<notin> set evs;                 \
   299 \        A ~: bad;  B ~: bad;  A ~= B;  evs : otway |]                   \
   282 \        A \\<notin> bad;  B \\<notin> bad;  A ~= B;  evs \\<in> otway |]                   \
   300 \     ==> Key K ~: analz (knows Spy evs)";
   283 \     ==> Key K \\<notin> analz (knows Spy evs)";
   301 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   284 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   302 qed "B_gets_good_key";
   285 qed "B_gets_good_key";