src/HOL/Auth/OtwayRees_AN.ML
changeset 5114 c729d4c299c1
parent 5076 fbc9d95b62ba
child 5223 4cb05273f764
equal deleted inserted replaced
5113:c4da11bb0592 5114:c729d4c299c1
    22 AddDs [impOfSubs Fake_parts_insert];
    22 AddDs [impOfSubs Fake_parts_insert];
    23 
    23 
    24 
    24 
    25 (*A "possibility property": there are traces that reach the end*)
    25 (*A "possibility property": there are traces that reach the end*)
    26 Goal 
    26 Goal 
    27  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]                               \
    27  "[| A ~= B; A ~= Server; B ~= Server |]                               \
    28 \        ==> EX K. EX NA. EX evs: otway.                                      \
    28 \  ==> EX K. EX NA. EX evs: otway.                                      \
    29 \             Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    29 \       Says B A (Crypt (shrK A) {|Nonce NA, Agent A, Agent B, Key K|}) \
    30 \             : set evs";
    30 \       : set evs";
    31 by (REPEAT (resolve_tac [exI,bexI] 1));
    31 by (REPEAT (resolve_tac [exI,bexI] 1));
    32 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2);
    32 by (rtac (otway.Nil RS otway.OR1 RS otway.OR2 RS otway.OR3 RS otway.OR4) 2);
    33 by possibility_tac;
    33 by possibility_tac;
    34 result();
    34 result();
    35 
    35 
    36 
    36 
    37 (**** Inductive proofs about otway ****)
    37 (**** Inductive proofs about otway ****)
    38 
    38 
    39 (*Nobody sends themselves messages*)
    39 (*Nobody sends themselves messages*)
    40 Goal "!!evs. evs : otway ==> ALL A X. Says A A X ~: set evs";
    40 Goal "evs : otway ==> ALL A X. Says A A X ~: set evs";
    41 by (etac otway.induct 1);
    41 by (etac otway.induct 1);
    42 by Auto_tac;
    42 by Auto_tac;
    43 qed_spec_mp "not_Says_to_self";
    43 qed_spec_mp "not_Says_to_self";
    44 Addsimps [not_Says_to_self];
    44 Addsimps [not_Says_to_self];
    45 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    45 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    46 
    46 
    47 
    47 
    48 (** For reasoning about the encrypted portion of messages **)
    48 (** For reasoning about the encrypted portion of messages **)
    49 
    49 
    50 Goal "!!evs. Says S' B {|X, Crypt(shrK B) X'|} : set evs ==> \
    50 Goal "Says S' B {|X, Crypt(shrK B) X'|} : set evs ==> \
    51 \                X : analz (spies evs)";
    51 \          X : analz (spies evs)";
    52 by (dtac (Says_imp_spies RS analz.Inj) 1);
    52 by (dtac (Says_imp_spies RS analz.Inj) 1);
    53 by (Blast_tac 1);
    53 by (Blast_tac 1);
    54 qed "OR4_analz_spies";
    54 qed "OR4_analz_spies";
    55 
    55 
    56 Goal "!!evs. Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} \
    56 Goal "Says Server B {|X, Crypt K' {|NB, a, Agent B, K|}|} \
    57 \                  : set evs ==> K : parts (spies evs)";
    57 \            : set evs ==> K : parts (spies evs)";
    58 by (Blast_tac 1);
    58 by (Blast_tac 1);
    59 qed "Oops_parts_spies";
    59 qed "Oops_parts_spies";
    60 
    60 
    61 bind_thm ("OR4_parts_spies",
    61 bind_thm ("OR4_parts_spies",
    62           OR4_analz_spies RS (impOfSubs analz_subset_parts));
    62           OR4_analz_spies RS (impOfSubs analz_subset_parts));
    71 
    71 
    72 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY
    72 (** Theorems of the form X ~: parts (spies evs) imply that NOBODY
    73     sends messages containing X! **)
    73     sends messages containing X! **)
    74 
    74 
    75 (*Spy never sees a good agent's shared key!*)
    75 (*Spy never sees a good agent's shared key!*)
    76 Goal 
    76 Goal "evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
    77  "!!evs. evs : otway ==> (Key (shrK A) : parts (spies evs)) = (A : bad)";
       
    78 by (parts_induct_tac 1);
    77 by (parts_induct_tac 1);
    79 by (ALLGOALS Blast_tac);
    78 by (ALLGOALS Blast_tac);
    80 qed "Spy_see_shrK";
    79 qed "Spy_see_shrK";
    81 Addsimps [Spy_see_shrK];
    80 Addsimps [Spy_see_shrK];
    82 
    81 
    83 Goal 
    82 Goal "evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
    84  "!!evs. evs : otway ==> (Key (shrK A) : analz (spies evs)) = (A : bad)";
       
    85 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    83 by (auto_tac(claset() addDs [impOfSubs analz_subset_parts], simpset()));
    86 qed "Spy_analz_shrK";
    84 qed "Spy_analz_shrK";
    87 Addsimps [Spy_analz_shrK];
    85 Addsimps [Spy_analz_shrK];
    88 
    86 
    89 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    87 AddSDs [Spy_see_shrK RSN (2, rev_iffD1), 
    90 	Spy_analz_shrK RSN (2, rev_iffD1)];
    88 	Spy_analz_shrK RSN (2, rev_iffD1)];
    91 
    89 
    92 
    90 
    93 (*Nobody can have used non-existent keys!*)
    91 (*Nobody can have used non-existent keys!*)
    94 Goal "!!evs. evs : otway ==>          \
    92 Goal "evs : otway ==> Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
    95 \         Key K ~: used evs --> K ~: keysFor (parts (spies evs))";
       
    96 by (parts_induct_tac 1);
    93 by (parts_induct_tac 1);
    97 (*Fake*)
    94 (*Fake*)
    98 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
    95 by (blast_tac (claset() addSDs [keysFor_parts_insert]) 1);
    99 (*OR3*)
    96 (*OR3*)
   100 by (Blast_tac 1);
    97 by (Blast_tac 1);
   109 
   106 
   110 
   107 
   111 (*** Proofs involving analz ***)
   108 (*** Proofs involving analz ***)
   112 
   109 
   113 (*Describes the form of K and NA when the Server sends this message.*)
   110 (*Describes the form of K and NA when the Server sends this message.*)
   114 Goal 
   111 Goal "[| Says Server B                                           \
   115  "!!evs. [| Says Server B                                           \
   112 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   116 \              {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   113 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   117 \                Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   114 \          : set evs;                                            \
   118 \             : set evs;                                            \
   115 \        evs : otway |]                                          \
   119 \           evs : otway |]                                          \
   116 \     ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
   120 \        ==> K ~: range shrK & (EX i. NA = Nonce i) & (EX j. NB = Nonce j)";
       
   121 by (etac rev_mp 1);
   117 by (etac rev_mp 1);
   122 by (etac otway.induct 1);
   118 by (etac otway.induct 1);
   123 by (ALLGOALS Asm_simp_tac);
   119 by (ALLGOALS Asm_simp_tac);
   124 by (Blast_tac 1);
   120 by (Blast_tac 1);
   125 qed "Says_Server_message_form";
   121 qed "Says_Server_message_form";
   144 
   140 
   145 
   141 
   146 (** Session keys are not used to encrypt other session keys **)
   142 (** Session keys are not used to encrypt other session keys **)
   147 
   143 
   148 (*The equality makes the induction hypothesis easier to apply*)
   144 (*The equality makes the induction hypothesis easier to apply*)
   149 Goal  
   145 Goal "evs : otway ==>                                 \
   150  "!!evs. evs : otway ==>                                 \
       
   151 \  ALL K KK. KK <= Compl (range shrK) -->                \
   146 \  ALL K KK. KK <= Compl (range shrK) -->                \
   152 \            (Key K : analz (Key``KK Un (spies evs))) =  \
   147 \         (Key K : analz (Key``KK Un (spies evs))) =  \
   153 \            (K : KK | Key K : analz (spies evs))";
   148 \         (K : KK | Key K : analz (spies evs))";
   154 by (etac otway.induct 1);
   149 by (etac otway.induct 1);
   155 by analz_spies_tac;
   150 by analz_spies_tac;
   156 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   151 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   157 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   152 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   158 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   153 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   159 (*Fake*) 
   154 (*Fake*) 
   160 by (spy_analz_tac 1);
   155 by (spy_analz_tac 1);
   161 qed_spec_mp "analz_image_freshK";
   156 qed_spec_mp "analz_image_freshK";
   162 
   157 
   163 
   158 
   164 Goal
   159 Goal "[| evs : otway;  KAB ~: range shrK |] ==>       \
   165  "!!evs. [| evs : otway;  KAB ~: range shrK |] ==>       \
   160 \     Key K : analz (insert (Key KAB) (spies evs)) =  \
   166 \        Key K : analz (insert (Key KAB) (spies evs)) =  \
   161 \     (K = KAB | Key K : analz (spies evs))";
   167 \        (K = KAB | Key K : analz (spies evs))";
       
   168 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   162 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   169 qed "analz_insert_freshK";
   163 qed "analz_insert_freshK";
   170 
   164 
   171 
   165 
   172 (*** The Key K uniquely identifies the Server's message. **)
   166 (*** The Key K uniquely identifies the Server's message. **)
   173 
   167 
   174 Goal 
   168 Goal "evs : otway ==>                                            \
   175  "!!evs. evs : otway ==>                                            \
   169 \   EX A' B' NA' NB'. ALL A B NA NB.                             \
   176 \      EX A' B' NA' NB'. ALL A B NA NB.                             \
   170 \    Says Server B                                               \
   177 \       Says Server B                                               \
   171 \      {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},             \
   178 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},             \
   172 \        Crypt (shrK B) {|NB, Agent A, Agent B, K|}|} : set evs  \
   179 \           Crypt (shrK B) {|NB, Agent A, Agent B, K|}|} : set evs  \
   173 \    --> A=A' & B=B' & NA=NA' & NB=NB'";
   180 \       --> A=A' & B=B' & NA=NA' & NB=NB'";
       
   181 by (etac otway.induct 1);
   174 by (etac otway.induct 1);
   182 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
   175 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib])));
   183 by (ALLGOALS Clarify_tac);
   176 by (ALLGOALS Clarify_tac);
   184 (*Remaining cases: OR3 and OR4*)
   177 (*Remaining cases: OR3 and OR4*)
   185 by (ex_strip_tac 2);
   178 by (ex_strip_tac 2);
   189 (*...we assume X is a recent message and handle this case by contradiction*)
   182 (*...we assume X is a recent message and handle this case by contradiction*)
   190 by (blast_tac (claset() addSEs spies_partsEs) 1);
   183 by (blast_tac (claset() addSEs spies_partsEs) 1);
   191 val lemma = result();
   184 val lemma = result();
   192 
   185 
   193 
   186 
   194 Goal 
   187 Goal "[| Says Server B                                           \
   195 "!!evs. [| Says Server B                                           \
   188 \         {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   196 \            {|Crypt (shrK A) {|NA, Agent A, Agent B, K|},         \
   189 \           Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}        \
   197 \              Crypt (shrK B) {|NB, Agent A, Agent B, K|}|}        \
   190 \        : set evs;                                             \
   198 \           : set evs;                                             \
   191 \       Says Server B'                                          \
   199 \          Says Server B'                                          \
   192 \         {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},     \
   200 \            {|Crypt (shrK A') {|NA', Agent A', Agent B', K|},     \
   193 \           Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}    \
   201 \              Crypt (shrK B') {|NB', Agent A', Agent B', K|}|}    \
   194 \        : set evs;                                             \
   202 \           : set evs;                                             \
   195 \       evs : otway |]                                          \
   203 \          evs : otway |]                                          \
   196 \    ==> A=A' & B=B' & NA=NA' & NB=NB'";
   204 \       ==> A=A' & B=B' & NA=NA' & NB=NB'";
       
   205 by (prove_unique_tac lemma 1);
   197 by (prove_unique_tac lemma 1);
   206 qed "unique_session_keys";
   198 qed "unique_session_keys";
   207 
   199 
   208 
   200 
   209 
   201 
   210 (**** Authenticity properties relating to NA ****)
   202 (**** Authenticity properties relating to NA ****)
   211 
   203 
   212 (*If the encrypted message appears then it originated with the Server!*)
   204 (*If the encrypted message appears then it originated with the Server!*)
   213 Goal 
   205 Goal "[| A ~: bad;  evs : otway |]                 \
   214  "!!evs. [| A ~: bad;  evs : otway |]                 \
       
   215 \ ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} : parts (spies evs) \
   206 \ ==> Crypt (shrK A) {|NA, Agent A, Agent B, Key K|} : parts (spies evs) \
   216 \     --> (EX NB. Says Server B                                          \
   207 \  --> (EX NB. Says Server B                                          \
   217 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   208 \               {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   218 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   209 \                 Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   219 \                  : set evs)";
   210 \               : set evs)";
   220 by (parts_induct_tac 1);
   211 by (parts_induct_tac 1);
   221 by (Blast_tac 1);
   212 by (Blast_tac 1);
   222 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   213 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   223 (*OR3*)
   214 (*OR3*)
   224 by (Blast_tac 1);
   215 by (Blast_tac 1);
   225 qed_spec_mp "NA_Crypt_imp_Server_msg";
   216 qed_spec_mp "NA_Crypt_imp_Server_msg";
   226 
   217 
   227 
   218 
   228 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   219 (*Corollary: if A receives B's OR4 message then it originated with the Server.
   229   Freshness may be inferred from nonce NA.*)
   220   Freshness may be inferred from nonce NA.*)
   230 Goal 
   221 Goal "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   231  "!!evs. [| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   222 \         : set evs;                                                 \
   232 \            : set evs;                                                 \
   223 \        A ~: bad;  evs : otway |]                                  \
   233 \           A ~: bad;  evs : otway |]                                  \
   224 \     ==> EX NB. Says Server B                                       \
   234 \        ==> EX NB. Says Server B                                       \
   225 \                 {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   235 \                    {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},  \
   226 \                   Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   236 \                      Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   227 \                : set evs";
   237 \                   : set evs";
       
   238 by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   228 by (blast_tac (claset() addSIs [NA_Crypt_imp_Server_msg]) 1);
   239 qed "A_trusts_OR4";
   229 qed "A_trusts_OR4";
   240 
   230 
   241 
   231 
   242 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   232 (** Crucial secrecy property: Spy does not see the keys sent in msg OR3
   243     Does not in itself guarantee security: an attack could violate 
   233     Does not in itself guarantee security: an attack could violate 
   244     the premises, e.g. by having A=Spy **)
   234     the premises, e.g. by having A=Spy **)
   245 
   235 
   246 Goal 
   236 Goal "[| A ~: bad;  B ~: bad;  evs : otway |]                   \
   247  "!!evs. [| A ~: bad;  B ~: bad;  evs : otway |]                   \
   237 \     ==> Says Server B                                         \
   248 \        ==> Says Server B                                         \
   238 \          {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   249 \             {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   239 \            Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   250 \               Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   240 \         : set evs -->                                         \
   251 \            : set evs -->                                         \
   241 \         Notes Spy {|NA, NB, Key K|} ~: set evs -->            \
   252 \            Notes Spy {|NA, NB, Key K|} ~: set evs -->            \
   242 \         Key K ~: analz (spies evs)";
   253 \            Key K ~: analz (spies evs)";
       
   254 by (etac otway.induct 1);
   243 by (etac otway.induct 1);
   255 by analz_spies_tac;
   244 by analz_spies_tac;
   256 by (ALLGOALS
   245 by (ALLGOALS
   257     (asm_simp_tac (simpset() addcongs [conj_cong, if_weak_cong] 
   246     (asm_simp_tac (simpset() addcongs [conj_cong, if_weak_cong] 
   258                              addsimps [analz_insert_eq, analz_insert_freshK]
   247                              addsimps [analz_insert_eq, analz_insert_freshK]
   265 by (Blast_tac 2);
   254 by (Blast_tac 2);
   266 (*Fake*) 
   255 (*Fake*) 
   267 by (spy_analz_tac 1);
   256 by (spy_analz_tac 1);
   268 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   257 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   269 
   258 
   270 Goal 
   259 Goal "[| Says Server B                                           \
   271  "!!evs. [| Says Server B                                           \
   260 \           {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   272 \              {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},    \
   261 \             Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   273 \                Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}   \
   262 \          : set evs;                                            \
   274 \             : set evs;                                            \
   263 \        Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   275 \           Notes Spy {|NA, NB, Key K|} ~: set evs;                 \
   264 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   276 \           A ~: bad;  B ~: bad;  evs : otway |]                    \
   265 \     ==> Key K ~: analz (spies evs)";
   277 \        ==> Key K ~: analz (spies evs)";
       
   278 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   266 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   279 by (blast_tac (claset() addSEs [lemma]) 1);
   267 by (blast_tac (claset() addSEs [lemma]) 1);
   280 qed "Spy_not_see_encrypted_key";
   268 qed "Spy_not_see_encrypted_key";
   281 
   269 
   282 
   270 
   283 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   271 (*A's guarantee.  The Oops premise quantifies over NB because A cannot know
   284   what it is.*)
   272   what it is.*)
   285 Goal 
   273 Goal "[| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   286  "!!evs. [| Says B' A (Crypt (shrK A) {|NA, Agent A, Agent B, Key K|})  \
   274 \         : set evs;                                                 \
   287 \            : set evs;                                                 \
   275 \        ALL NB. Notes Spy {|NA, NB, Key K|} ~: set evs;         \
   288 \           ALL NB. Notes Spy {|NA, NB, Key K|} ~: set evs;         \
   276 \        A ~: bad;  B ~: bad;  evs : otway |]                    \
   289 \           A ~: bad;  B ~: bad;  evs : otway |]                    \
   277 \     ==> Key K ~: analz (spies evs)";
   290 \        ==> Key K ~: analz (spies evs)";
       
   291 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   278 by (blast_tac (claset() addSDs [A_trusts_OR4, Spy_not_see_encrypted_key]) 1);
   292 qed "A_gets_good_key";
   279 qed "A_gets_good_key";
   293 
   280 
   294 
   281 
   295 (**** Authenticity properties relating to NB ****)
   282 (**** Authenticity properties relating to NB ****)
   296 
   283 
   297 (*If the encrypted message appears then it originated with the Server!*)
   284 (*If the encrypted message appears then it originated with the Server!*)
   298 Goal 
   285 Goal "[| B ~: bad;  evs : otway |]                                 \
   299  "!!evs. [| B ~: bad;  evs : otway |]                                 \
   286 \ ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} : parts (spies evs) \
   300 \    ==> Crypt (shrK B) {|NB, Agent A, Agent B, Key K|} : parts (spies evs) \
   287 \     --> (EX NA. Says Server B                                          \
   301 \        --> (EX NA. Says Server B                                          \
   288 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   302 \                     {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   289 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   303 \                       Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   290 \                  : set evs)";
   304 \                     : set evs)";
       
   305 by (parts_induct_tac 1);
   291 by (parts_induct_tac 1);
   306 by (Blast_tac 1);
   292 by (Blast_tac 1);
   307 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   293 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib])));
   308 (*OR3*)
   294 (*OR3*)
   309 by (Blast_tac 1);
   295 by (Blast_tac 1);
   310 qed_spec_mp "NB_Crypt_imp_Server_msg";
   296 qed_spec_mp "NB_Crypt_imp_Server_msg";
   311 
   297 
   312 
   298 
   313 (*Guarantee for B: if it gets a well-formed certificate then the Server
   299 (*Guarantee for B: if it gets a well-formed certificate then the Server
   314   has sent the correct message in round 3.*)
   300   has sent the correct message in round 3.*)
   315 Goal 
   301 Goal "[| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   316  "!!evs. [| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   302 \          : set evs;                                                    \
   317 \             : set evs;                                                    \
   303 \        B ~: bad;  evs : otway |]                                       \
   318 \           B ~: bad;  evs : otway |]                                       \
   304 \     ==> EX NA. Says Server B                                           \
   319 \        ==> EX NA. Says Server B                                           \
   305 \                  {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   320 \                     {|Crypt (shrK A) {|NA, Agent A, Agent B, Key K|},     \
   306 \                    Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   321 \                       Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|}    \
   307 \                  : set evs";
   322 \                     : set evs";
       
   323 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   308 by (blast_tac (claset() addSIs [NB_Crypt_imp_Server_msg]) 1);
   324 qed "B_trusts_OR3";
   309 qed "B_trusts_OR3";
   325 
   310 
   326 
   311 
   327 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   312 (*The obvious combination of B_trusts_OR3 with Spy_not_see_encrypted_key*)
   328 Goal 
   313 Goal "[| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   329  "!!evs. [| Says S' B {|X, Crypt (shrK B) {|NB, Agent A, Agent B, Key K|}|} \
   314 \         : set evs;                                            \
   330 \            : set evs;                                            \
   315 \        ALL NA. Notes Spy {|NA, NB, Key K|} ~: set evs;                \
   331 \           ALL NA. Notes Spy {|NA, NB, Key K|} ~: set evs;                \
   316 \        A ~: bad;  B ~: bad;  evs : otway |]                   \
   332 \           A ~: bad;  B ~: bad;  evs : otway |]                   \
   317 \     ==> Key K ~: analz (spies evs)";
   333 \        ==> Key K ~: analz (spies evs)";
       
   334 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   318 by (blast_tac (claset() addDs [B_trusts_OR3, Spy_not_see_encrypted_key]) 1);
   335 qed "B_gets_good_key";
   319 qed "B_gets_good_key";