99 (*Another one, for session resumption (both ServerResume and ClientResume) *) |
103 (*Another one, for session resumption (both ServerResume and ClientResume) *) |
100 Goal "[| evs0 : tls; \ |
104 Goal "[| evs0 : tls; \ |
101 \ Notes A {|Number SID, Agent A, Agent B, Nonce M|} : set evs0; \ |
105 \ Notes A {|Number SID, Agent A, Agent B, Nonce M|} : set evs0; \ |
102 \ Notes B {|Number SID, Agent A, Agent B, Nonce M|} : set evs0; \ |
106 \ Notes B {|Number SID, Agent A, Agent B, Nonce M|} : set evs0; \ |
103 \ ALL evs. (@ N. Nonce N ~: used evs) ~: range PRF; \ |
107 \ ALL evs. (@ N. Nonce N ~: used evs) ~: range PRF; \ |
104 \ A ~= B |] ==> EX NA PA NB PB X. EX evs: tls. \ |
108 \ A ~= B |] \ |
105 \ X = Hash{|Number SID, Nonce M, \ |
109 \ ==> EX NA PA NB PB X. EX evs: tls. \ |
106 \ Nonce NA, Number PA, Agent A, \ |
110 \ X = Hash{|Number SID, Nonce M, \ |
107 \ Nonce NB, Number PB, Agent B|} & \ |
111 \ Nonce NA, Number PA, Agent A, \ |
108 \ Says A B (Crypt (clientK(NA,NB,M)) X) : set evs & \ |
112 \ Nonce NB, Number PB, Agent B|} & \ |
109 \ Says B A (Crypt (serverK(NA,NB,M)) X) : set evs"; |
113 \ Says A B (Crypt (clientK(NA,NB,M)) X) : set evs & \ |
|
114 \ Says B A (Crypt (serverK(NA,NB,M)) X) : set evs"; |
110 by (REPEAT (resolve_tac [exI,bexI] 1)); |
115 by (REPEAT (resolve_tac [exI,bexI] 1)); |
111 by (etac (tls.ClientHello RS tls.ServerHello RS tls.ServerResume RS |
116 by (etac (tls.ClientHello RS tls.ServerHello RS tls.ServerResume RS |
112 tls.ClientResume) 2); |
117 tls.ClientResume) 2); |
113 by possibility_tac; |
118 by possibility_tac; |
114 by (REPEAT (Blast_tac 1)); |
119 by (REPEAT (Blast_tac 1)); |
115 result(); |
120 result(); |
116 |
121 |
117 |
122 |
118 |
123 |
119 (**** Inductive proofs about tls ****) |
124 (**** Inductive proofs about tls ****) |
120 |
|
121 (*Nobody sends themselves messages*) |
|
122 Goal "evs : tls ==> ALL X. Says A A X ~: set evs"; |
|
123 by (etac tls.induct 1); |
|
124 by Auto_tac; |
|
125 qed_spec_mp "not_Says_to_self"; |
|
126 Addsimps [not_Says_to_self]; |
|
127 AddSEs [not_Says_to_self RSN (2, rev_notE)]; |
|
128 |
125 |
129 |
126 |
130 (*Induction for regularity theorems. If induction formula has the form |
127 (*Induction for regularity theorems. If induction formula has the form |
131 X ~: analz (spies evs) --> ... then it shortens the proof by discarding |
128 X ~: analz (spies evs) --> ... then it shortens the proof by discarding |
132 needless information about analz (insert X (spies evs)) *) |
129 needless information about analz (insert X (spies evs)) *) |
439 \ : parts (spies evs); evs : tls |] \ |
430 \ : parts (spies evs); evs : tls |] \ |
440 \ ==> Nonce PMS : parts (spies evs)"; |
431 \ ==> Nonce PMS : parts (spies evs)"; |
441 by (blast_tac (claset() addDs [lemma]) 1); |
432 by (blast_tac (claset() addDs [lemma]) 1); |
442 qed "PMS_Crypt_sessionK_not_spied"; |
433 qed "PMS_Crypt_sessionK_not_spied"; |
443 |
434 |
444 (*Lemma: write keys are never sent if M (MASTER SECRET) is secure. |
435 (*Write keys are never sent if M (MASTER SECRET) is secure. |
445 Converse doesn't hold; betraying M doesn't force the keys to be sent! |
436 Converse fails; betraying M doesn't force the keys to be sent! |
446 The strong Oops condition can be weakened later by unicity reasoning, |
437 The strong Oops condition can be weakened later by unicity reasoning, |
447 with some effort.*) |
438 with some effort. |
|
439 NO LONGER USED: see clientK_not_spied and serverK_not_spied*) |
448 Goal "[| ALL A. Says A Spy (Key (sessionK((NA,NB,M),b))) ~: set evs; \ |
440 Goal "[| ALL A. Says A Spy (Key (sessionK((NA,NB,M),b))) ~: set evs; \ |
449 \ Nonce M ~: analz (spies evs); evs : tls |] \ |
441 \ Nonce M ~: analz (spies evs); evs : tls |] \ |
450 \ ==> Key (sessionK((NA,NB,M),b)) ~: parts (spies evs)"; |
442 \ ==> Key (sessionK((NA,NB,M),b)) ~: parts (spies evs)"; |
451 by (etac rev_mp 1); |
443 by (etac rev_mp 1); |
452 by (etac rev_mp 1); |
444 by (etac rev_mp 1); |
453 by (analz_induct_tac 1); (*17 seconds*) |
445 by (analz_induct_tac 1); (*7 seconds*) |
454 (*SpyKeys*) |
446 (*SpyKeys*) |
455 by (blast_tac (claset() addDs [Says_imp_spies RS analz.Inj]) 3); |
447 by (blast_tac (claset() addDs [Says_imp_spies RS analz.Inj]) 3); |
456 (*Fake*) |
448 (*Fake*) |
457 by (spy_analz_tac 2); |
449 by (spy_analz_tac 2); |
458 (*Base*) |
450 (*Base*) |
459 by (Blast_tac 1); |
451 by (Blast_tac 1); |
460 qed "sessionK_not_spied"; |
452 qed "sessionK_not_spied"; |
461 Addsimps [sessionK_not_spied]; |
|
462 |
453 |
463 |
454 |
464 (*If A sends ClientKeyExch to an honest B, then the PMS will stay secret.*) |
455 (*If A sends ClientKeyExch to an honest B, then the PMS will stay secret.*) |
465 Goal "[| evs : tls; A ~: bad; B ~: bad |] \ |
456 Goal "[| evs : tls; A ~: bad; B ~: bad |] \ |
466 \ ==> Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
457 \ ==> Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
499 (*Fake*) |
489 (*Fake*) |
500 by (spy_analz_tac 1); |
490 by (spy_analz_tac 1); |
501 (*ServerHello and ClientKeyExch: mostly freshness reasoning*) |
491 (*ServerHello and ClientKeyExch: mostly freshness reasoning*) |
502 by (REPEAT (blast_tac (claset() addSEs partsEs |
492 by (REPEAT (blast_tac (claset() addSEs partsEs |
503 addDs [Notes_Crypt_parts_spies, |
493 addDs [Notes_Crypt_parts_spies, |
504 impOfSubs analz_subset_parts, |
|
505 Says_imp_spies RS analz.Inj]) 1)); |
494 Says_imp_spies RS analz.Inj]) 1)); |
506 bind_thm ("Spy_not_see_MS", result() RSN (2, rev_mp)); |
495 bind_thm ("Spy_not_see_MS", result() RSN (2, rev_mp)); |
507 |
496 |
508 |
497 |
509 (*** Weakening the Oops conditions for leakage of clientK ***) |
498 (*** Weakening the Oops conditions for leakage of clientK ***) |
510 |
499 |
511 (*If A created PMS then nobody other than the Spy would send a message |
500 (*If A created PMS then nobody else (except the Spy in replays) |
512 using a clientK generated from that PMS.*) |
501 would send a message using a clientK generated from that PMS.*) |
513 Goal "[| evs : tls; A' ~= Spy |] \ |
502 Goal "[| Says A' B' (Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs; \ |
514 \ ==> Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
503 \ Notes A {|Agent B, Nonce PMS|} : set evs; \ |
515 \ Says A' B' (Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs --> \ |
504 \ evs : tls; A' ~= Spy |] \ |
516 \ A = A'"; |
505 \ ==> A = A'"; |
|
506 by (etac rev_mp 1); |
|
507 by (etac rev_mp 1); |
517 by (analz_induct_tac 1); (*8 seconds*) |
508 by (analz_induct_tac 1); (*8 seconds*) |
518 by (ALLGOALS Clarify_tac); |
509 by (ALLGOALS Clarify_tac); |
519 (*ClientFinished, ClientResume: by unicity of PMS*) |
510 (*ClientFinished, ClientResume: by unicity of PMS*) |
520 by (REPEAT |
511 by (REPEAT |
521 (blast_tac (claset() addSDs [Notes_master_imp_Notes_PMS] |
512 (blast_tac (claset() addSDs [Notes_master_imp_Notes_PMS] |
522 addIs [Notes_unique_PMS RS conjunct1]) 2)); |
513 addIs [Notes_unique_PMS RS conjunct1]) 2)); |
523 (*ClientKeyExch*) |
514 (*ClientKeyExch*) |
524 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied, |
515 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied, |
525 Says_imp_spies RS parts.Inj]) 1); |
516 Says_imp_spies RS parts.Inj]) 1); |
526 bind_thm ("Says_clientK_unique", |
517 qed "Says_clientK_unique"; |
527 result() RSN(2,rev_mp) RSN(2,rev_mp)); |
|
528 |
518 |
529 |
519 |
530 (*If A created PMS and has not leaked her clientK to the Spy, |
520 (*If A created PMS and has not leaked her clientK to the Spy, |
531 then nobody has.*) |
521 then it is completely secure: not even in parts!*) |
532 Goal "evs : tls \ |
522 Goal "[| Notes A {|Agent B, Nonce PMS|} : set evs; \ |
533 \ ==> Says A Spy (Key(clientK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs --> \ |
523 \ Says A Spy (Key (clientK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs; \ |
534 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
524 \ A ~: bad; B ~: bad; \ |
535 \ (ALL A. Says A Spy (Key(clientK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs)"; |
525 \ evs : tls |] \ |
536 by (etac tls.induct 1); |
526 \ ==> Key (clientK(Na,Nb,PRF(PMS,NA,NB))) ~: parts (spies evs)"; |
537 (*This roundabout proof sequence avoids looping in simplification*) |
527 by (etac rev_mp 1); |
538 by (ALLGOALS Simp_tac); |
528 by (etac rev_mp 1); |
539 by (ALLGOALS Clarify_tac); |
529 by (analz_induct_tac 1); (*17 seconds*) |
540 by (Fake_parts_insert_tac 1); |
|
541 by (ALLGOALS Asm_simp_tac); |
|
542 (*Oops*) |
530 (*Oops*) |
543 by (blast_tac (claset() addIs [Says_clientK_unique]) 2); |
531 by (blast_tac (claset() addIs [Says_clientK_unique]) 4); |
544 (*ClientKeyExch*) |
532 (*ClientKeyExch*) |
545 by (blast_tac (claset() addSDs [PMS_sessionK_not_spied] |
533 by (blast_tac (claset() addSDs [PMS_sessionK_not_spied]) 3); |
546 addSEs spies_partsEs) 1); |
534 (*SpyKeys*) |
547 qed_spec_mp "clientK_Oops_ALL"; |
535 by (blast_tac (claset() addSEs [Spy_not_see_MS RSN (2,rev_notE)]) 2); |
548 |
536 (*Fake*) |
|
537 by (spy_analz_tac 1); |
|
538 qed "clientK_not_spied"; |
549 |
539 |
550 |
540 |
551 (*** Weakening the Oops conditions for leakage of serverK ***) |
541 (*** Weakening the Oops conditions for leakage of serverK ***) |
552 |
542 |
553 (*If A created PMS for B, then nobody other than B or the Spy would |
543 (*If A created PMS for B, then nobody other than B or the Spy would |
554 send a message using a serverK generated from that PMS.*) |
544 send a message using a serverK generated from that PMS.*) |
555 Goal "[| evs : tls; A ~: bad; B ~: bad; B' ~= Spy |] \ |
545 Goal "[| Says B' A' (Crypt (serverK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs; \ |
556 \ ==> Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
546 \ Notes A {|Agent B, Nonce PMS|} : set evs; \ |
557 \ Says B' A' (Crypt (serverK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs --> \ |
547 \ evs : tls; A ~: bad; B ~: bad; B' ~= Spy |] \ |
558 \ B = B'"; |
548 \ ==> B = B'"; |
|
549 by (etac rev_mp 1); |
|
550 by (etac rev_mp 1); |
559 by (analz_induct_tac 1); (*9 seconds*) |
551 by (analz_induct_tac 1); (*9 seconds*) |
560 by (ALLGOALS Clarify_tac); |
552 by (ALLGOALS Clarify_tac); |
561 (*ServerResume, ServerFinished: by unicity of PMS*) |
553 (*ServerResume, ServerFinished: by unicity of PMS*) |
562 by (REPEAT |
554 by (REPEAT |
563 (blast_tac (claset() addSEs [MPair_parts] |
555 (blast_tac (claset() addSDs [Notes_master_imp_Crypt_PMS] |
564 addSDs [Notes_master_imp_Crypt_PMS, |
|
565 Says_imp_spies RS parts.Inj] |
|
566 addDs [Spy_not_see_PMS, |
556 addDs [Spy_not_see_PMS, |
567 Notes_Crypt_parts_spies, |
557 Notes_Crypt_parts_spies, |
568 Crypt_unique_PMS]) 2)); |
558 Crypt_unique_PMS]) 2)); |
569 (*ClientKeyExch*) |
559 (*ClientKeyExch*) |
570 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied, |
560 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied, |
571 Says_imp_spies RS parts.Inj]) 1); |
561 Says_imp_spies RS parts.Inj]) 1); |
572 bind_thm ("Says_serverK_unique", |
562 qed "Says_serverK_unique"; |
573 result() RSN(2,rev_mp) RSN(2,rev_mp)); |
|
574 |
563 |
575 (*If A created PMS for B, and B has not leaked his serverK to the Spy, |
564 (*If A created PMS for B, and B has not leaked his serverK to the Spy, |
576 then nobody has.*) |
565 then it is completely secure: not even in parts!*) |
577 Goal "[| evs : tls; A ~: bad; B ~: bad |] \ |
566 Goal "[| Notes A {|Agent B, Nonce PMS|} : set evs; \ |
578 \ ==> Says B Spy (Key(serverK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs --> \ |
567 \ Says B Spy (Key(serverK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs; \ |
579 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
568 \ evs : tls; A ~: bad; B ~: bad |] \ |
580 \ (ALL A. Says A Spy (Key(serverK(Na,Nb,PRF(PMS,NA,NB)))) ~: set evs) "; |
569 \ ==> Key (serverK(Na,Nb,PRF(PMS,NA,NB))) ~: parts (spies evs)"; |
581 by (etac tls.induct 1); |
570 by (etac rev_mp 1); |
582 (*This roundabout proof sequence avoids looping in simplification*) |
571 by (etac rev_mp 1); |
583 by (ALLGOALS Simp_tac); |
572 by (analz_induct_tac 1); (*6 seconds*) |
584 by (ALLGOALS Clarify_tac); |
|
585 by (Fake_parts_insert_tac 1); |
|
586 by (ALLGOALS Asm_simp_tac); |
|
587 (*Oops*) |
573 (*Oops*) |
588 by (blast_tac (claset() addIs [Says_serverK_unique]) 2); |
574 by (blast_tac (claset() addIs [Says_serverK_unique]) 4); |
589 (*ClientKeyExch*) |
575 (*ClientKeyExch*) |
590 by (blast_tac (claset() addSDs [PMS_sessionK_not_spied] |
576 by (blast_tac (claset() addSDs [PMS_sessionK_not_spied]) 3); |
591 addSEs spies_partsEs) 1); |
577 (*SpyKeys*) |
592 qed_spec_mp "serverK_Oops_ALL"; |
578 by (blast_tac (claset() addSEs [Spy_not_see_MS RSN (2,rev_notE)]) 2); |
593 |
579 (*Fake*) |
|
580 by (spy_analz_tac 1); |
|
581 qed "serverK_not_spied"; |
594 |
582 |
595 |
583 |
596 (*** Protocol goals: if A receives ServerFinished, then B is present |
584 (*** Protocol goals: if A receives ServerFinished, then B is present |
597 and has used the quoted values PA, PB, etc. Note that it is up to A |
585 and has used the quoted values PA, PB, etc. Note that it is up to A |
598 to compare PA with what she originally sent. |
586 to compare PA with what she originally sent. |
603 \ (Hash{|Number SID, Nonce M, \ |
591 \ (Hash{|Number SID, Nonce M, \ |
604 \ Nonce Na, Number PA, Agent A, \ |
592 \ Nonce Na, Number PA, Agent A, \ |
605 \ Nonce Nb, Number PB, Agent B|}); \ |
593 \ Nonce Nb, Number PB, Agent B|}); \ |
606 \ M = PRF(PMS,NA,NB); \ |
594 \ M = PRF(PMS,NA,NB); \ |
607 \ evs : tls; A ~: bad; B ~: bad |] \ |
595 \ evs : tls; A ~: bad; B ~: bad |] \ |
608 \ ==> (ALL A. Says A Spy (Key(serverK(Na,Nb,M))) ~: set evs) --> \ |
596 \ ==> Says B Spy (Key(serverK(Na,Nb,M))) ~: set evs --> \ |
609 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
597 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
610 \ X : parts (spies evs) --> Says B A X : set evs"; |
598 \ X : parts (spies evs) --> Says B A X : set evs"; |
611 by (hyp_subst_tac 1); |
599 by (hyp_subst_tac 1); |
612 by (analz_induct_tac 1); (*10 seconds*) |
600 by (analz_induct_tac 1); (*10 seconds*) |
613 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib]))); |
601 by (ALLGOALS (asm_simp_tac (simpset() addsimps [all_conj_distrib]))); |
614 by (ALLGOALS Clarify_tac); |
602 by (ALLGOALS Clarify_tac); |
615 (*ClientKeyExch*) |
603 (*ClientKeyExch*) |
616 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
604 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
617 (*Fake: the Spy doesn't have the critical session key!*) |
605 (*Fake: the Spy doesn't have the critical session key!*) |
618 by (subgoal_tac "Key (serverK(Na,Nb,PRF(PMS,NA,NB))) ~: analz(spies evs)" 1); |
606 by (blast_tac (claset() addEs [serverK_not_spied RSN (2,rev_notE)]) 1); |
619 by (asm_simp_tac (simpset() addsimps [Spy_not_see_MS, |
|
620 not_parts_not_analz]) 2); |
|
621 by (Fake_parts_insert_tac 1); |
|
622 val lemma = normalize_thm [RSmp] (result()); |
|
623 |
|
624 (*Final version*) |
|
625 Goal "[| X = Crypt (serverK(Na,Nb,M)) \ |
|
626 \ (Hash{|Number SID, Nonce M, \ |
|
627 \ Nonce Na, Number PA, Agent A, \ |
|
628 \ Nonce Nb, Number PB, Agent B|}); \ |
|
629 \ M = PRF(PMS,NA,NB); \ |
|
630 \ X : parts (spies evs); \ |
|
631 \ Notes A {|Agent B, Nonce PMS|} : set evs; \ |
|
632 \ Says B Spy (Key (serverK(Na,Nb,M))) ~: set evs; \ |
|
633 \ evs : tls; A ~: bad; B ~: bad |] \ |
|
634 \ ==> Says B A X : set evs"; |
|
635 by (blast_tac (claset() addIs [lemma] |
|
636 addEs [serverK_Oops_ALL RSN(2, rev_notE)]) 1); |
|
637 qed_spec_mp "TrustServerFinished"; |
607 qed_spec_mp "TrustServerFinished"; |
638 |
|
639 |
608 |
640 |
609 |
641 (*This version refers not to ServerFinished but to any message from B. |
610 (*This version refers not to ServerFinished but to any message from B. |
642 We don't assume B has received CertVerify, and an intruder could |
611 We don't assume B has received CertVerify, and an intruder could |
643 have changed A's identity in all other messages, so we can't be sure |
612 have changed A's identity in all other messages, so we can't be sure |
644 that B sends his message to A. If CLIENT KEY EXCHANGE were augmented |
613 that B sends his message to A. If CLIENT KEY EXCHANGE were augmented |
645 to bind A's identity with PMS, then we could replace A' by A below.*) |
614 to bind A's identity with PMS, then we could replace A' by A below.*) |
646 Goal "[| M = PRF(PMS,NA,NB); evs : tls; A ~: bad; B ~: bad |] \ |
615 Goal "[| M = PRF(PMS,NA,NB); evs : tls; A ~: bad; B ~: bad |] \ |
647 \ ==> (ALL A. Says A Spy (Key(serverK(Na,Nb,M))) ~: set evs) --> \ |
616 \ ==> Says B Spy (Key(serverK(Na,Nb,M))) ~: set evs --> \ |
648 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
617 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
649 \ Crypt (serverK(Na,Nb,M)) Y : parts (spies evs) --> \ |
618 \ Crypt (serverK(Na,Nb,M)) Y : parts (spies evs) --> \ |
650 \ (EX A'. Says B A' (Crypt (serverK(Na,Nb,M)) Y) : set evs)"; |
619 \ (EX A'. Says B A' (Crypt (serverK(Na,Nb,M)) Y) : set evs)"; |
651 by (hyp_subst_tac 1); |
620 by (hyp_subst_tac 1); |
652 by (analz_induct_tac 1); (*20 seconds*) |
621 by (analz_induct_tac 1); (*20 seconds*) |
653 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib]))); |
622 by (ALLGOALS (asm_simp_tac (simpset() addsimps [ex_disj_distrib]))); |
654 by (ALLGOALS Clarify_tac); |
623 by (ALLGOALS Clarify_tac); |
655 (*ServerResume, ServerFinished: by unicity of PMS*) |
624 (*ServerResume, ServerFinished: by unicity of PMS*) |
656 by (REPEAT |
625 by (REPEAT |
657 (blast_tac (claset() addSEs [MPair_parts] |
626 (blast_tac (claset() addSDs [Notes_master_imp_Crypt_PMS] |
658 addSDs [Notes_master_imp_Crypt_PMS, |
|
659 Says_imp_spies RS parts.Inj] |
|
660 addDs [Spy_not_see_PMS, |
627 addDs [Spy_not_see_PMS, |
661 Notes_Crypt_parts_spies, |
628 Notes_Crypt_parts_spies, |
662 Crypt_unique_PMS]) 3)); |
629 Crypt_unique_PMS]) 3)); |
663 (*ClientKeyExch*) |
630 (*ClientKeyExch*) |
664 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
631 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
665 (*Fake: the Spy doesn't have the critical session key!*) |
632 (*Fake: the Spy doesn't have the critical session key!*) |
666 by (subgoal_tac "Key (serverK(Na,Nb,PRF(PMS,NA,NB))) ~: analz(spies evs)" 1); |
633 by (blast_tac (claset() addEs [serverK_not_spied RSN (2,rev_notE)]) 1); |
667 by (asm_simp_tac (simpset() addsimps [Spy_not_see_MS, |
|
668 not_parts_not_analz]) 2); |
|
669 by (Fake_parts_insert_tac 1); |
|
670 val lemma = normalize_thm [RSmp] (result()); |
|
671 |
|
672 (*Final version*) |
|
673 Goal "[| M = PRF(PMS,NA,NB); \ |
|
674 \ Crypt (serverK(Na,Nb,M)) Y : parts (spies evs); \ |
|
675 \ Notes A {|Agent B, Nonce PMS|} : set evs; \ |
|
676 \ Says B Spy (Key (serverK(Na,Nb,M))) ~: set evs; \ |
|
677 \ evs : tls; A ~: bad; B ~: bad |] \ |
|
678 \ ==> EX A'. Says B A' (Crypt (serverK(Na,Nb,M)) Y) : set evs"; |
|
679 by (blast_tac (claset() addIs [lemma] |
|
680 addEs [serverK_Oops_ALL RSN(2, rev_notE)]) 1); |
|
681 qed_spec_mp "TrustServerMsg"; |
634 qed_spec_mp "TrustServerMsg"; |
682 |
|
683 |
635 |
684 |
636 |
685 (*** Protocol goal: if B receives any message encrypted with clientK |
637 (*** Protocol goal: if B receives any message encrypted with clientK |
686 then A has sent it, ASSUMING that A chose PMS. Authentication is |
638 then A has sent it, ASSUMING that A chose PMS. Authentication is |
687 assumed here; B cannot verify it. But if the message is |
639 assumed here; B cannot verify it. But if the message is |
688 ClientFinished, then B can then check the quoted values PA, PB, etc. |
640 ClientFinished, then B can then check the quoted values PA, PB, etc. |
689 ***) |
641 ***) |
690 |
642 |
691 Goal "[| M = PRF(PMS,NA,NB); evs : tls; A ~: bad; B ~: bad |] \ |
643 Goal "[| M = PRF(PMS,NA,NB); evs : tls; A ~: bad; B ~: bad |] \ |
692 \ ==> (ALL A. Says A Spy (Key(clientK(Na,Nb,M))) ~: set evs) --> \ |
644 \ ==> Says A Spy (Key(clientK(Na,Nb,M))) ~: set evs --> \ |
693 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
645 \ Notes A {|Agent B, Nonce PMS|} : set evs --> \ |
694 \ Crypt (clientK(Na,Nb,M)) Y : parts (spies evs) --> \ |
646 \ Crypt (clientK(Na,Nb,M)) Y : parts (spies evs) --> \ |
695 \ Says A B (Crypt (clientK(Na,Nb,M)) Y) : set evs"; |
647 \ Says A B (Crypt (clientK(Na,Nb,M)) Y) : set evs"; |
696 by (hyp_subst_tac 1); |
648 by (hyp_subst_tac 1); |
697 by (analz_induct_tac 1); (*15 seconds*) |
649 by (analz_induct_tac 1); (*15 seconds*) |
701 addSDs [Notes_master_imp_Notes_PMS] |
653 addSDs [Notes_master_imp_Notes_PMS] |
702 addDs [Notes_unique_PMS]) 3)); |
654 addDs [Notes_unique_PMS]) 3)); |
703 (*ClientKeyExch*) |
655 (*ClientKeyExch*) |
704 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
656 by (blast_tac (claset() addSDs [PMS_Crypt_sessionK_not_spied]) 2); |
705 (*Fake: the Spy doesn't have the critical session key!*) |
657 (*Fake: the Spy doesn't have the critical session key!*) |
706 by (subgoal_tac "Key (clientK(Na,Nb,PRF(PMS,NA,NB))) ~: analz(spies evs)" 1); |
658 by (blast_tac (claset() addEs [clientK_not_spied RSN (2,rev_notE)]) 1); |
707 by (asm_simp_tac (simpset() addsimps [Spy_not_see_MS, |
659 qed_spec_mp "TrustClientMsg"; |
708 not_parts_not_analz]) 2); |
|
709 by (Fake_parts_insert_tac 1); |
|
710 val lemma = normalize_thm [RSmp] (result()); |
|
711 |
|
712 (*Final version*) |
|
713 Goal "[| M = PRF(PMS,NA,NB); \ |
|
714 \ Crypt (clientK(Na,Nb,M)) Y : parts (spies evs); \ |
|
715 \ Notes A {|Agent B, Nonce PMS|} : set evs; \ |
|
716 \ Says A Spy (Key(clientK(Na,Nb,M))) ~: set evs; \ |
|
717 \ evs : tls; A ~: bad; B ~: bad |] \ |
|
718 \ ==> Says A B (Crypt (clientK(Na,Nb,M)) Y) : set evs"; |
|
719 by (blast_tac (claset() addIs [lemma] |
|
720 addEs [clientK_Oops_ALL RSN(2, rev_notE)]) 1); |
|
721 qed "TrustClientMsg"; |
|
722 |
660 |
723 |
661 |
724 |
662 |
725 (*** Protocol goal: if B receives ClientFinished, and if B is able to |
663 (*** Protocol goal: if B receives ClientFinished, and if B is able to |
726 check a CertVerify from A, then A has used the quoted |
664 check a CertVerify from A, then A has used the quoted |