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); |
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"; |