src/HOL/Auth/TLS.ML
changeset 3672 56e4365a0c99
parent 3519 ab0a9fbed4c0
child 3676 cbaec955056b
equal deleted inserted replaced
3671:8326f03d667c 3672:56e4365a0c99
    46 qed "eq_certificate_iff";
    46 qed "eq_certificate_iff";
    47 AddIffs [eq_certificate_iff];
    47 AddIffs [eq_certificate_iff];
    48 
    48 
    49 
    49 
    50 (*Injectiveness of key-generating functions*)
    50 (*Injectiveness of key-generating functions*)
    51 AddIffs [inj_clientK RS inj_eq, inj_serverK RS inj_eq];
    51 AddIffs [inj_PRF RS inj_eq, inj_clientK RS inj_eq, inj_serverK RS inj_eq];
    52 
    52 
    53 (* invKey(clientK x) = clientK x  and similarly for serverK*)
    53 (* invKey(clientK x) = clientK x  and similarly for serverK*)
    54 Addsimps [isSym_clientK, rewrite_rule [isSymKey_def] isSym_clientK,
    54 Addsimps [isSym_clientK, rewrite_rule [isSymKey_def] isSym_clientK,
    55 	  isSym_serverK, rewrite_rule [isSymKey_def] isSym_serverK];
    55 	  isSym_serverK, rewrite_rule [isSymKey_def] isSym_serverK];
    56 
    56 
    95 (**** Protocol Proofs ****)
    95 (**** Protocol Proofs ****)
    96 
    96 
    97 (*A "possibility property": there are traces that reach the end.
    97 (*A "possibility property": there are traces that reach the end.
    98   This protocol has three end points and six messages to consider.*)
    98   This protocol has three end points and six messages to consider.*)
    99 
    99 
       
   100 
       
   101 (** These proofs make the further assumption that the Nonce_supply nonces 
       
   102 	(which have the form  @ N. Nonce N ~: used evs)
       
   103     lie outside the range of PRF.  This assumption seems reasonable, but
       
   104     as it is needed only for the possibility theorems, it is not taken
       
   105     as an axiom.
       
   106 **)
       
   107 
       
   108 
       
   109 
   100 (*Possibility property ending with ServerFinished.*)
   110 (*Possibility property ending with ServerFinished.*)
   101 goal thy 
   111 goal thy 
   102  "!!A B. A ~= B ==> EX NA XA NB XB M. EX evs: tls.    \
   112  "!!A B. [| ALL evs. (@ N. Nonce N ~: used evs) ~: range PRF;  \
   103 \  Says B A (Crypt (serverK(NA,NB,M))                 \
   113 \           A ~= B |] ==> EX NA XA NB XB M. EX evs: tls.    \
   104 \            (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|}, \
   114 \  Says B A (Crypt (serverK(NA,NB,M))                       \
   105 \                   Nonce NA, Agent XA, Agent A,      \
   115 \            (Hash{|Nonce M, Nonce NA, Number XA, Agent A,      \
   106 \                   Nonce NB, Agent XB,               \
   116 \                   Nonce NB, Number XB, Agent B|})) \
   107 \                   certificate B (pubK B)|})) \
       
   108 \    : set evs";
   117 \    : set evs";
   109 by (REPEAT (resolve_tac [exI,bexI] 1));
   118 by (REPEAT (resolve_tac [exI,bexI] 1));
   110 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   119 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   111 	  RS tls.ServerFinished) 2);
   120 	  RS tls.ServerFinished) 2);
   112 by possibility_tac;
   121 by possibility_tac;
       
   122 by (REPEAT (Blast_tac 1));
   113 result();
   123 result();
   114 
   124 
   115 (*And one for ClientFinished.  Either FINISHED message may come first.*)
   125 (*And one for ClientFinished.  Either FINISHED message may come first.*)
   116 goal thy 
   126 goal thy 
   117  "!!A B. A ~= B ==> EX NA XA NB XB M. EX evs: tls.              \
   127  "!!A B. [| ALL evs. (@ N. Nonce N ~: used evs) ~: range PRF;  \
       
   128 \           A ~= B |] ==> EX NA XA NB XB M. EX evs: tls.    \
   118 \  Says A B (Crypt (clientK(NA,NB,M))                           \
   129 \  Says A B (Crypt (clientK(NA,NB,M))                           \
   119 \            (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|},        \
   130 \            (Hash{|Nonce M, Nonce NA, Number XA, Agent A, \
   120 \                   Nonce NA, Agent XA, certificate A (pubK A), \
   131 \                   Nonce NB, Number XB, Agent B|})) : set evs";
   121 \                   Nonce NB, Agent XB, Agent B|})) : set evs";
       
   122 by (REPEAT (resolve_tac [exI,bexI] 1));
   132 by (REPEAT (resolve_tac [exI,bexI] 1));
   123 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   133 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   124 	  RS tls.ClientFinished) 2);
   134 	  RS tls.ClientFinished) 2);
   125 by possibility_tac;
   135 by possibility_tac;
       
   136 by (REPEAT (Blast_tac 1));
   126 result();
   137 result();
   127 
   138 
   128 (*Another one, for CertVerify (which is optional)*)
   139 (*Another one, for CertVerify (which is optional)*)
   129 goal thy 
   140 goal thy 
   130  "!!A B. A ~= B ==> EX NB M. EX evs: tls.   \
   141  "!!A B. [| ALL evs. (@ N. Nonce N ~: used evs) ~: range PRF;  \
       
   142 \           A ~= B |] ==> EX NB PMS. EX evs: tls.   \
   131 \  Says A B (Crypt (priK A)                 \
   143 \  Says A B (Crypt (priK A)                 \
   132 \            (Hash{|Nonce NB, certificate B (pubK B), Nonce M|})) : set evs";
   144 \            (Hash{|Nonce NB, certificate B (pubK B), Nonce PMS|})) : set evs";
   133 by (REPEAT (resolve_tac [exI,bexI] 1));
   145 by (REPEAT (resolve_tac [exI,bexI] 1));
   134 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   146 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   135 	  RS tls.CertVerify) 2);
   147 	  RS tls.CertVerify) 2);
   136 by possibility_tac;
   148 by possibility_tac;
       
   149 by (REPEAT (Blast_tac 1));
   137 result();
   150 result();
   138 
   151 
   139 
   152 
   140 (**** Inductive proofs about tls ****)
   153 (**** Inductive proofs about tls ****)
   141 
   154 
   209     etac tls.induct i   THEN
   222     etac tls.induct i   THEN
   210     ClientCertKeyEx_tac  (i+7)  THEN	(*ClientFinished*)
   223     ClientCertKeyEx_tac  (i+7)  THEN	(*ClientFinished*)
   211     ClientCertKeyEx_tac  (i+6)  THEN	(*CertVerify*)
   224     ClientCertKeyEx_tac  (i+6)  THEN	(*CertVerify*)
   212     ClientCertKeyEx_tac  (i+5)  THEN	(*ClientCertKeyEx*)
   225     ClientCertKeyEx_tac  (i+5)  THEN	(*ClientCertKeyEx*)
   213     ALLGOALS (asm_simp_tac 
   226     ALLGOALS (asm_simp_tac 
   214               (!simpset addsimps [not_parts_not_analz]
   227               (!simpset addcongs [if_weak_cong]
   215                         setloop split_tac [expand_if]))  THEN
   228                         setloop split_tac [expand_if]))  THEN
   216     (*Remove instances of pubK B:  the Spy already knows all public keys.
   229     (*Remove instances of pubK B:  the Spy already knows all public keys.
   217       Combining the two simplifier calls makes them run extremely slowly.*)
   230       Combining the two simplifier calls makes them run extremely slowly.*)
   218     ALLGOALS (asm_simp_tac 
   231     ALLGOALS (asm_simp_tac 
   219               (!simpset addsimps [insert_absorb]
   232               (!simpset addcongs [if_weak_cong]
       
   233 			addsimps [insert_absorb]
   220                         setloop split_tac [expand_if]));
   234                         setloop split_tac [expand_if]));
   221 
   235 
   222 
   236 
   223 (*** Hashing of nonces ***)
   237 (*** Hashing of nonces ***)
   224 
   238 
   225 (*Every Nonce that's hashed is already in past traffic. *)
   239 (*Every Nonce that's hashed is already in past traffic.  
   226 goal thy "!!evs. [| Hash {|Nonce N, X|} : parts (sees Spy evs);  \
   240   This event occurs in CERTIFICATE VERIFY*)
   227 \                   evs : tls |]  \
   241 goal thy "!!evs. [| Hash {|Nonce NB, X|} : parts (sees Spy evs);  \
   228 \                ==> Nonce N : parts (sees Spy evs)";
   242 \                   NB ~: range PRF;  evs : tls |]  \
       
   243 \                ==> Nonce NB : parts (sees Spy evs)";
       
   244 by (etac rev_mp 1);
   229 by (etac rev_mp 1);
   245 by (etac rev_mp 1);
   230 by (parts_induct_tac 1);
   246 by (parts_induct_tac 1);
   231 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
   247 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
   232 by (Fake_parts_insert_tac 1);
   248 by (Fake_parts_insert_tac 1);
   233 by (blast_tac (!claset addSDs [Says_imp_sees_Spy RS parts.Inj]
   249 (*FINISHED messages are trivial because M : range PRF*)
   234 	               addSEs partsEs) 1);
   250 by (REPEAT (Blast_tac 2));
   235 qed "Hash_imp_Nonce1";
   251 (*CERTIFICATE VERIFY is the only interesting case*)
   236 
   252 by (blast_tac (!claset addSEs sees_Spy_partsEs) 1);
   237 (*Lemma needed to prove Hash_Hash_imp_Nonce*)
   253 qed "Hash_Nonce_CV";
   238 goal thy "!!evs. [| Hash{|Nonce NA, Nonce NB, Nonce M|}  \
       
   239 \                       : parts (sees Spy evs);     \
       
   240 \                   evs : tls |]  \
       
   241 \                ==> Nonce M : parts (sees Spy evs)";
       
   242 by (etac rev_mp 1);
       
   243 by (parts_induct_tac 1);
       
   244 by (asm_simp_tac (!simpset addsimps [parts_insert_sees]) 1);
       
   245 by (Fake_parts_insert_tac 1);
       
   246 qed "Hash_imp_Nonce2";
       
   247 AddSDs [Hash_imp_Nonce2];
       
   248 
   254 
   249 
   255 
   250 goal thy "!!evs. [| Notes A {|Agent B, X|} : set evs;  evs : tls |]  \
   256 goal thy "!!evs. [| Notes A {|Agent B, X|} : set evs;  evs : tls |]  \
   251 \                ==> Crypt (pubK B) X : parts (sees Spy evs)";
   257 \                ==> Crypt (pubK B) X : parts (sees Spy evs)";
   252 by (etac rev_mp 1);
   258 by (etac rev_mp 1);
   253 by (analz_induct_tac 1);
   259 by (analz_induct_tac 1);
   254 by (blast_tac (!claset addIs [parts_insertI]) 1);
   260 by (blast_tac (!claset addIs [parts_insertI]) 1);
   255 qed "Notes_Crypt_parts_sees";
   261 qed "Notes_Crypt_parts_sees";
   256 
   262 
   257 
   263 
   258 (*NEEDED??*)
   264 (*****************
   259 goal thy "!!evs. [| Hash {| Hash{|Nonce NA, Nonce NB, Nonce M|}, X |}  \
   265     (*NEEDED?  TRUE???
   260 \                      : parts (sees Spy evs);      \
   266       Every Nonce that's hashed is already in past traffic. 
   261 \                   evs : tls |]                         \
   267       This general formulation is tricky to prove and hard to use, since the
   262 \                ==> Nonce M : parts (sees Spy evs)";
   268       2nd premise is typically proved by simplification.*)
   263 by (etac rev_mp 1);
   269     goal thy "!!evs. [| Hash X : parts (sees Spy evs);  \
   264 by (parts_induct_tac 1);
   270     \                   Nonce N : parts {X};  evs : tls |]  \
   265 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
   271     \                ==> Nonce N : parts (sees Spy evs)";
   266 by (Fake_parts_insert_tac 1);
   272     by (etac rev_mp 1);
   267 by (REPEAT (blast_tac (!claset addSDs [Notes_Crypt_parts_sees,
   273     by (parts_induct_tac 1);
   268 				       Says_imp_sees_Spy RS parts.Inj]
   274     by (step_tac (!claset addSDs [Notes_Crypt_parts_sees,
   269 		               addSEs partsEs) 1));
   275 				  Says_imp_sees_Spy RS parts.Inj]
   270 qed "Hash_Hash_imp_Nonce";
   276 			  addSEs partsEs) 1);
   271 
   277     by (ALLGOALS (asm_full_simp_tac (!simpset addsimps [parts_insert_sees])));
   272 
   278     by (Fake_parts_insert_tac 1);
   273 (*NEEDED??
   279     (*CertVerify, ClientFinished, ServerFinished (?)*)
   274   Every Nonce that's hashed is already in past traffic. 
   280     by (REPEAT (Blast_tac 1));
   275   This general formulation is tricky to prove and hard to use, since the
   281     qed "Hash_imp_Nonce_seen";
   276   2nd premise is typically proved by simplification.*)
   282 ****************************************************************)
   277 goal thy "!!evs. [| Hash X : parts (sees Spy evs);  \
       
   278 \                   Nonce N : parts {X};  evs : tls |]  \
       
   279 \                ==> Nonce N : parts (sees Spy evs)";
       
   280 by (etac rev_mp 1);
       
   281 by (parts_induct_tac 1);
       
   282 by (step_tac (!claset addSDs [Notes_Crypt_parts_sees,
       
   283 			      Says_imp_sees_Spy RS parts.Inj]
       
   284 		      addSEs partsEs) 1);
       
   285 by (ALLGOALS (asm_full_simp_tac (!simpset addsimps [parts_insert_sees])));
       
   286 by (Fake_parts_insert_tac 1);
       
   287 (*CertVerify, ClientFinished, ServerFinished (?)*)
       
   288 by (REPEAT (Blast_tac 1));
       
   289 qed "Hash_imp_Nonce_seen";
       
   290 
   283 
   291 
   284 
   292 (*** Protocol goal: if B receives CERTIFICATE VERIFY, then A sent it ***)
   285 (*** Protocol goal: if B receives CERTIFICATE VERIFY, then A sent it ***)
   293 
   286 
   294 (*B can check A's signature if he has received A's certificate.
   287 (*B can check A's signature if he has received A's certificate.
   295   Perhaps B~=Spy is unnecessary, but there's no obvious proof if the first
   288   Perhaps B~=Spy is unnecessary, but there's no obvious proof if the first
   296   message is Fake.  We don't need guarantees for the Spy anyway.  We must
   289   message is Fake.  We don't need guarantees for the Spy anyway.  We must
   297   assume A~:lost; otherwise, the Spy can forge A's signature.*)
   290   assume A~:lost; otherwise, the Spy can forge A's signature.*)
   298 goal thy
   291 goal thy
   299  "!!evs. [| X = Crypt (priK A)                                        \
   292  "!!evs. [| X = Crypt (priK A)                                        \
   300 \                 (Hash{|Nonce NB, certificate B KB, Nonce M|});      \
   293 \                 (Hash{|Nonce NB, certificate B KB, Nonce PMS|});      \
   301 \           evs : tls;  A ~: lost;  B ~= Spy |]                       \
   294 \           evs : tls;  A ~: lost;  B ~= Spy |]                       \
   302 \    ==> Says B A {|Nonce NA, Nonce NB, Agent XB, certificate B KB|}  \
   295 \    ==> Says B A {|Nonce NA, Nonce NB, Number XB, certificate B KB|}  \
   303 \          : set evs --> \
   296 \          : set evs --> \
   304 \        X : parts (sees Spy evs) --> Says A B X : set evs";
   297 \        X : parts (sees Spy evs) --> Says A B X : set evs";
   305 by (hyp_subst_tac 1);
   298 by (hyp_subst_tac 1);
   306 by (parts_induct_tac 1);
   299 by (parts_induct_tac 1);
   307 by (Fake_parts_insert_tac 1);
   300 by (Fake_parts_insert_tac 1);
   308 (*ServerHello: nonce NB cannot be in X because it's fresh!*)
   301 (*ServerHello: nonce NB cannot be in X because it's fresh!*)
   309 by (blast_tac (!claset addSDs [Hash_imp_Nonce1]
   302 by (blast_tac (!claset addSDs [Hash_Nonce_CV]
   310 	               addSEs sees_Spy_partsEs) 1);
   303 	               addSEs sees_Spy_partsEs) 1);
   311 qed_spec_mp "TrustCertVerify";
   304 qed_spec_mp "TrustCertVerify";
   312 
   305 
   313 
   306 
   314 (*If CERTIFICATE VERIFY is present then A has chosen M.*)
   307 (*If CERTIFICATE VERIFY is present then A has chosen PMS.*)
   315 goal thy
   308 goal thy
   316  "!!evs. [| Crypt (priK A) (Hash{|Nonce NB, certificate B KB, Nonce M|})  \
   309  "!!evs. [| Crypt (priK A) (Hash{|Nonce NB, certificate B KB, Nonce PMS|})  \
   317 \             : parts (sees Spy evs);                                \
   310 \             : parts (sees Spy evs);                                \
   318 \           evs : tls;  A ~: lost |]                                      \
   311 \           evs : tls;  A ~: lost |]                                      \
   319 \        ==> Notes A {|Agent B, Nonce M|} : set evs";
   312 \        ==> Notes A {|Agent B, Nonce PMS|} : set evs";
   320 be rev_mp 1;
   313 be rev_mp 1;
   321 by (parts_induct_tac 1);
   314 by (parts_induct_tac 1);
   322 by (Fake_parts_insert_tac 1);
   315 by (Fake_parts_insert_tac 1);
   323 qed "UseCertVerify";
   316 qed "UseCertVerify";
   324 
   317 
   354 \            (Nonce N : analz (sees Spy evs))";
   347 \            (Nonce N : analz (sees Spy evs))";
   355 by (etac tls.induct 1);
   348 by (etac tls.induct 1);
   356 by (ClientCertKeyEx_tac 6);
   349 by (ClientCertKeyEx_tac 6);
   357 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   350 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   358 by (REPEAT_FIRST (rtac lemma));
   351 by (REPEAT_FIRST (rtac lemma));
   359 writeln"SLOW simplification: 50 secs!??";
   352 writeln"SLOW simplification: 60 secs!??";
   360 by (ALLGOALS
   353 by (ALLGOALS
   361     (asm_simp_tac (analz_image_keys_ss 
   354     (asm_simp_tac (analz_image_keys_ss 
   362                    addsimps (analz_image_priK::certificate_def::
   355 		   addsimps (analz_image_priK::certificate_def::
   363                              keys_distinct))));
   356                              keys_distinct))));
   364 by (ALLGOALS (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_priK])));
       
   365 by (ALLGOALS (asm_simp_tac (!simpset addsimps [insert_absorb])));
   357 by (ALLGOALS (asm_simp_tac (!simpset addsimps [insert_absorb])));
   366 (*ClientCertKeyEx: a nonce is sent, but one needs a priK to read it.*)
   358 (*ClientCertKeyEx: a nonce is sent, but one needs a priK to read it.*)
   367 by (Blast_tac 3);
   359 by (Blast_tac 3);
   368 (*Fake*) 
   360 (*Fake*) 
   369 by (spy_analz_tac 2);
   361 by (spy_analz_tac 2);
   370 (*Base*)
   362 (*Base*)
   371 by (Blast_tac 1);
   363 by (Blast_tac 1);
   372 qed_spec_mp "analz_image_keys";
   364 qed_spec_mp "analz_image_keys";
   373 
   365 
   374 
   366 
   375 (*If A sends ClientCertKeyEx to an uncompromised B, then M will stay secret.*)
   367 goal thy "!!evs. evs : tls ==> Notes A {|Agent B, Nonce (PRF x)|} ~: set evs";
       
   368 by (parts_induct_tac 1);
       
   369 (*ClientCertKeyEx: PMS is assumed to differ from any PRF.*)
       
   370 by (Blast_tac 1);
       
   371 qed "no_Notes_A_PRF";
       
   372 Addsimps [no_Notes_A_PRF];
       
   373 
       
   374 
       
   375 (*If A sends ClientCertKeyEx to an honest B, then the PMS will stay secret.*)
   376 goal thy
   376 goal thy
   377  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]           \
   377  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]           \
   378 \        ==> Notes A {|Agent B, Nonce M|} : set evs  -->   \
   378 \        ==> Notes A {|Agent B, Nonce PMS|} : set evs  -->   \
   379 \            Nonce M ~: analz (sees Spy evs)";
   379 \            Nonce PMS ~: analz (sees Spy evs)";
   380 by (analz_induct_tac 1);
   380 by (analz_induct_tac 1);   (*47 seconds???*)
   381 (*ClientHello*)
   381 (*ClientHello*)
   382 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   382 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   383                                addSEs sees_Spy_partsEs) 3);
   383                                addSEs sees_Spy_partsEs) 3);
   384 (*SpyKeys*)
   384 (*SpyKeys*)
   385 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 2);
   385 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 2);
       
   386 by (fast_tac (!claset addss (!simpset)) 2);
   386 (*Fake*)
   387 (*Fake*)
   387 by (spy_analz_tac 1);
   388 by (spy_analz_tac 1);
   388 (*ServerHello and ClientCertKeyEx: mostly freshness reasoning*)
   389 (*ServerHello and ClientCertKeyEx: mostly freshness reasoning*)
   389 by (REPEAT (blast_tac (!claset addSEs partsEs
   390 by (REPEAT (blast_tac (!claset addSEs partsEs
   390 			       addDs  [Notes_Crypt_parts_sees,
   391 			       addDs  [Notes_Crypt_parts_sees,
   391 				       impOfSubs analz_subset_parts,
   392 				       impOfSubs analz_subset_parts,
   392 				       Says_imp_sees_Spy RS analz.Inj]) 1));
   393 				       Says_imp_sees_Spy RS analz.Inj]) 1));
   393 bind_thm ("Spy_not_see_premaster_secret", result() RSN (2, rev_mp));
   394 bind_thm ("Spy_not_see_PMS", result() RSN (2, rev_mp));
       
   395 
       
   396 
       
   397 
       
   398 goal thy "!!evs. [| Nonce (PRF (PMS,NA,NB)) : parts (sees Spy evs);  \
       
   399 \                   evs : tls |]  \
       
   400 \                ==> Nonce PMS : parts (sees Spy evs)";
       
   401 by (etac rev_mp 1);
       
   402 by (parts_induct_tac 1);
       
   403 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
       
   404 by (Fake_parts_insert_tac 1);
       
   405 (*Client key exchange*)
       
   406 by (Blast_tac 4);
       
   407 (*Server Hello: by freshness*)
       
   408 by (blast_tac (!claset addSEs sees_Spy_partsEs) 3);
       
   409 (*Client Hello: trivial*)
       
   410 by (Blast_tac 2);
       
   411 (*SpyKeys*)
       
   412 by (blast_tac (!claset addSEs sees_Spy_partsEs) 1);
       
   413 qed "MS_imp_PMS";
       
   414 AddSDs [MS_imp_PMS];
       
   415 
       
   416 
       
   417 (*If A sends ClientCertKeyEx to an honest B, then the MASTER SECRET
       
   418   will stay secret.*)
       
   419 goal thy
       
   420  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]           \
       
   421 \        ==> Notes A {|Agent B, Nonce PMS|} : set evs  -->   \
       
   422 \            Nonce (PRF(PMS,NA,NB)) ~: analz (sees Spy evs)";
       
   423 by (analz_induct_tac 1);   (*47 seconds???*)
       
   424 (*ClientHello*)
       
   425 by (Blast_tac 3);
       
   426 (*SpyKeys: by secrecy of the PMS, Spy cannot make the MS*)
       
   427 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 2);
       
   428 by (blast_tac (!claset addSDs [Spy_not_see_PMS, 
       
   429 			       Says_imp_sees_Spy RS analz.Inj]) 2);
       
   430 (*Fake*)
       
   431 by (spy_analz_tac 1);
       
   432 (*ServerHello and ClientCertKeyEx: mostly freshness reasoning*)
       
   433 by (REPEAT (blast_tac (!claset addSEs partsEs
       
   434 			       addDs  [MS_imp_PMS,
       
   435 				       Notes_Crypt_parts_sees,
       
   436 				       impOfSubs analz_subset_parts,
       
   437 				       Says_imp_sees_Spy RS analz.Inj]) 1));
       
   438 bind_thm ("Spy_not_see_MS", result() RSN (2, rev_mp));
       
   439 
   394 
   440 
   395 
   441 
   396 (*** Protocol goal: serverK(NA,NB,M) and clientK(NA,NB,M) remain secure ***)
   442 (*** Protocol goal: serverK(NA,NB,M) and clientK(NA,NB,M) remain secure ***)
   397 
   443 
   398 (** First, some lemmas about those write keys.  The proofs for serverK are 
   444 (** First, some lemmas about those write keys.  The proofs for serverK are 
   399     nearly identical to those for clientK. **)
   445     nearly identical to those for clientK. **)
   400 
   446 
   401 (*Lemma: those write keys are never sent if M is secure.  
   447 (*Lemma: those write keys are never sent if M (MASTER SECRET) is secure.  
   402   Converse doesn't hold; betraying M doesn't force the keys to be sent!*)
   448   Converse doesn't hold; betraying M doesn't force the keys to be sent!*)
   403 
   449 
   404 goal thy 
   450 goal thy 
   405  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   451  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   406 \        ==> Key (clientK(NA,NB,M)) ~: parts (sees Spy evs)";
   452 \        ==> Key (clientK(NA,NB,M)) ~: parts (sees Spy evs)";
   412 (*Fake*) 
   458 (*Fake*) 
   413 by (spy_analz_tac 2);
   459 by (spy_analz_tac 2);
   414 (*Base*)
   460 (*Base*)
   415 by (Blast_tac 1);
   461 by (Blast_tac 1);
   416 qed "clientK_notin_parts";
   462 qed "clientK_notin_parts";
   417 
   463 bind_thm ("clientK_in_partsE", clientK_notin_parts RSN (2, rev_notE));
   418 Addsimps [clientK_notin_parts];
   464 Addsimps [clientK_notin_parts];
   419 AddSEs [clientK_notin_parts RSN (2, rev_notE)];
   465 AddSEs [clientK_in_partsE, 
       
   466 	impOfSubs analz_subset_parts RS clientK_in_partsE];
   420 
   467 
   421 goal thy 
   468 goal thy 
   422  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   469  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   423 \        ==> Key (serverK(NA,NB,M)) ~: parts (sees Spy evs)";
   470 \        ==> Key (serverK(NA,NB,M)) ~: parts (sees Spy evs)";
   424 by (etac rev_mp 1);
   471 by (etac rev_mp 1);
   429 (*Fake*) 
   476 (*Fake*) 
   430 by (spy_analz_tac 2);
   477 by (spy_analz_tac 2);
   431 (*Base*)
   478 (*Base*)
   432 by (Blast_tac 1);
   479 by (Blast_tac 1);
   433 qed "serverK_notin_parts";
   480 qed "serverK_notin_parts";
   434 
   481 bind_thm ("serverK_in_partsE", serverK_notin_parts RSN (2, rev_notE));
   435 Addsimps [serverK_notin_parts];
   482 Addsimps [serverK_notin_parts];
   436 AddSEs [serverK_notin_parts RSN (2, rev_notE)];
   483 AddSEs [serverK_in_partsE, 
   437 
   484 	impOfSubs analz_subset_parts RS serverK_in_partsE];
   438 (*Lemma: those write keys are never used if M is fresh.  
   485 
   439   Converse doesn't hold; betraying M doesn't force the keys to be sent!
   486 
   440   NOT suitable as safe elim rules.*)
   487 (*Lemma: those write keys are never used if PMS is fresh.  
   441 
   488   Nonces don't have to agree, allowing session resumption.
   442 goal thy 
   489   Converse doesn't hold; revealing PMS doesn't force the keys to be sent.
   443  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   490   They are NOT suitable as safe elim rules.*)
   444 \        ==> Crypt (clientK(NA,NB,M)) Y ~: parts (sees Spy evs)";
   491 
       
   492 goal thy 
       
   493  "!!evs. [| Nonce PMS ~: used evs;  evs : tls |]                           \
       
   494 \  ==> Crypt (clientK(Na, Nb, PRF(PMS,NA,NB))) Y ~: parts (sees Spy evs)";
   445 by (etac rev_mp 1);
   495 by (etac rev_mp 1);
   446 by (analz_induct_tac 1);
   496 by (analz_induct_tac 1);
   447 (*ClientFinished: since M is fresh, a different instance of clientK was used.*)
   497 (*ClientFinished: since M is fresh, a different instance of clientK was used.*)
   448 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   498 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   449                                addSEs sees_Spy_partsEs) 3);
   499                        addSEs sees_Spy_partsEs) 3);
   450 by (Fake_parts_insert_tac 2);
   500 by (Fake_parts_insert_tac 2);
   451 (*Base*)
   501 (*Base*)
   452 by (Blast_tac 1);
   502 by (Blast_tac 1);
   453 qed "Crypt_clientK_notin_parts";
   503 qed "Crypt_clientK_notin_parts";
   454 
       
   455 Addsimps [Crypt_clientK_notin_parts];
   504 Addsimps [Crypt_clientK_notin_parts];
   456 AddEs [Crypt_clientK_notin_parts RSN (2, rev_notE)];
   505 AddEs [Crypt_clientK_notin_parts RSN (2, rev_notE)];
   457 
   506 
   458 goal thy 
   507 goal thy 
   459  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   508  "!!evs. [| Nonce PMS ~: used evs;  evs : tls |]                           \
   460 \        ==> Crypt (serverK(NA,NB,M)) Y ~: parts (sees Spy evs)";
   509 \  ==> Crypt (serverK(Na, Nb, PRF(PMS,NA,NB))) Y ~: parts (sees Spy evs)";
   461 by (etac rev_mp 1);
   510 by (etac rev_mp 1);
   462 by (analz_induct_tac 1);
   511 by (analz_induct_tac 1);
   463 (*ServerFinished: since M is fresh, a different instance of serverK was used.*)
   512 (*ServerFinished: since M is fresh, a different instance of serverK was used.*)
   464 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   513 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   465                                addSEs sees_Spy_partsEs) 3);
   514                                addSEs sees_Spy_partsEs) 3);
   479 be rev_mp 1;
   528 be rev_mp 1;
   480 by (analz_induct_tac 1);
   529 by (analz_induct_tac 1);
   481 qed "A_Crypt_pubB";
   530 qed "A_Crypt_pubB";
   482 
   531 
   483 
   532 
   484 (*** Unicity results for M, the pre-master-secret ***)
   533 (*** Unicity results for PMS, the pre-master-secret ***)
   485 
   534 
   486 (*M determines B.  Proof borrowed from NS_Public/unique_NA and from Yahalom*)
   535 (*PMS determines B.  Proof borrowed from NS_Public/unique_NA and from Yahalom*)
   487 goal thy 
   536 goal thy 
   488  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   537  "!!evs. [| Nonce PMS ~: analz (sees Spy evs);  evs : tls |]   \
   489 \        ==> EX B'. ALL B.   \
   538 \        ==> EX B'. ALL B.   \
   490 \              Crypt (pubK B) (Nonce M) : parts (sees Spy evs) --> B=B'";
   539 \              Crypt (pubK B) (Nonce PMS) : parts (sees Spy evs) --> B=B'";
   491 by (etac rev_mp 1);
   540 by (etac rev_mp 1);
   492 by (parts_induct_tac 1);
   541 by (parts_induct_tac 1);
   493 by (Fake_parts_insert_tac 1);
   542 by (Fake_parts_insert_tac 1);
   494 (*ClientCertKeyEx*)
   543 (*ClientCertKeyEx*)
   495 by (ClientCertKeyEx_tac 1);
   544 by (ClientCertKeyEx_tac 1);
   496 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   545 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   497 by (expand_case_tac "M = ?y" 1 THEN
   546 by (expand_case_tac "PMS = ?y" 1 THEN
   498     blast_tac (!claset addSEs partsEs) 1);
   547     blast_tac (!claset addSEs partsEs) 1);
   499 val lemma = result();
   548 val lemma = result();
   500 
   549 
   501 goal thy 
   550 goal thy 
   502  "!!evs. [| Crypt(pubK B)  (Nonce M) : parts (sees Spy evs); \
   551  "!!evs. [| Crypt(pubK B)  (Nonce PMS) : parts (sees Spy evs); \
   503 \           Crypt(pubK B') (Nonce M) : parts (sees Spy evs); \
   552 \           Crypt(pubK B') (Nonce PMS) : parts (sees Spy evs); \
   504 \           Nonce M ~: analz (sees Spy evs);                 \
   553 \           Nonce PMS ~: analz (sees Spy evs);                 \
   505 \           evs : tls |]                                          \
   554 \           evs : tls |]                                          \
   506 \        ==> B=B'";
   555 \        ==> B=B'";
   507 by (prove_unique_tac lemma 1);
   556 by (prove_unique_tac lemma 1);
   508 qed "unique_M";
   557 qed "unique_PMS";
   509 
   558 
   510 
   559 
   511 (*In A's note to herself, M determines A and B.*)
   560 (*In A's note to herself, PMS determines A and B.*)
   512 goal thy 
   561 goal thy 
   513  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]            \
   562  "!!evs. [| Nonce PMS ~: analz (sees Spy evs);  evs : tls |]            \
   514 \ ==> EX A' B'. ALL A B.                                                   \
   563 \ ==> EX A' B'. ALL A B.                                                   \
   515 \        Notes A {|Agent B, Nonce M|} : set evs --> A=A' & B=B'";
   564 \        Notes A {|Agent B, Nonce PMS|} : set evs --> A=A' & B=B'";
   516 by (etac rev_mp 1);
   565 by (etac rev_mp 1);
   517 by (parts_induct_tac 1);
   566 by (parts_induct_tac 1);
   518 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   567 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   519 (*ClientCertKeyEx: if M is fresh, then it can't appear in Notes A X.*)
   568 (*ClientCertKeyEx: if PMS is fresh, then it can't appear in Notes A X.*)
   520 by (expand_case_tac "M = ?y" 1 THEN
   569 by (expand_case_tac "PMS = ?y" 1 THEN
   521     blast_tac (!claset addSDs [Notes_Crypt_parts_sees] addSEs partsEs) 1);
   570     blast_tac (!claset addSDs [Notes_Crypt_parts_sees] addSEs partsEs) 1);
   522 val lemma = result();
   571 val lemma = result();
   523 
   572 
   524 goal thy 
   573 goal thy 
   525  "!!evs. [| Notes A  {|Agent B,  Nonce M|} : set evs;  \
   574  "!!evs. [| Notes A  {|Agent B,  Nonce PMS|} : set evs;  \
   526 \           Notes A' {|Agent B', Nonce M|} : set evs;  \
   575 \           Notes A' {|Agent B', Nonce PMS|} : set evs;  \
   527 \           Nonce M ~: analz (sees Spy evs);      \
   576 \           Nonce PMS ~: analz (sees Spy evs);      \
   528 \           evs : tls |]                               \
   577 \           evs : tls |]                               \
   529 \        ==> A=A' & B=B'";
   578 \        ==> A=A' & B=B'";
   530 by (prove_unique_tac lemma 1);
   579 by (prove_unique_tac lemma 1);
   531 qed "Notes_unique_M";
   580 qed "Notes_unique_PMS";
   532 
   581 
   533 
   582 
   534 
   583 
   535 (*** Protocol goals: if A receives SERVER FINISHED, then B is present 
   584 (*** Protocol goals: if A receives SERVER FINISHED, then B is present 
   536      and has used the quoted values XA, XB, etc.  Note that it is up to A
   585      and has used the quoted values XA, XB, etc.  Note that it is up to A
   537      to compare XA with what she originally sent.
   586      to compare XA with what she originally sent.
   538 ***)
   587 ***)
   539 
   588 
   540 (*The mention of her name (A) in X assumes A that B knows who she is.*)
   589 (*The mention of her name (A) in X assumes A that B knows who she is.*)
   541 goal thy
   590 goal thy
   542  "!!evs. [| X = Crypt (serverK(NA,NB,M))                                \
   591  "!!evs. [| X = Crypt (serverK(Na,Nb,M))                                \
   543 \                 (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|},           \
   592 \                 (Hash{|Nonce M, Nonce NA, Number XA, Agent A,         \
   544 \                        Nonce NA, Agent XA, Agent A,                   \
   593 \                        Nonce NB, Number XB, Agent B|}); \
   545 \                        Nonce NB, Agent XB, certificate B (pubK B)|}); \
   594 \           M = PRF(PMS,NA,NB); \
   546 \           evs : tls;  A ~: lost;  B ~: lost |]                        \
   595 \           evs : tls;  A ~: lost;  B ~: lost |]                        \
   547 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                 \
   596 \        ==> Notes A {|Agent B, Nonce PMS|} : set evs -->                 \
   548 \        X : parts (sees Spy evs) --> Says B A X : set evs";
   597 \        X : parts (sees Spy evs) --> Says B A X : set evs";
   549 by (hyp_subst_tac 1);
   598 by (hyp_subst_tac 1);
   550 by (analz_induct_tac 1);
   599 by (analz_induct_tac 1);
   551 by (REPEAT_FIRST (rtac impI));
       
   552 (*Fake: the Spy doesn't have the critical session key!*)
   600 (*Fake: the Spy doesn't have the critical session key!*)
   553 by (REPEAT (rtac impI 1));
   601 by (REPEAT (rtac impI 1));
   554 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   602 by (subgoal_tac 
   555 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   603     "Key (serverK(Na,Nb,PRF(PMS,NA,NB))) ~: analz (sees Spy evsa)" 1);
       
   604 by (asm_simp_tac (!simpset addsimps [Spy_not_see_MS, 
   556 				     not_parts_not_analz]) 2);
   605 				     not_parts_not_analz]) 2);
   557 by (Fake_parts_insert_tac 1);
   606 by (Fake_parts_insert_tac 1);
   558 qed_spec_mp "TrustServerFinished";
   607 qed_spec_mp "TrustServerFinished";
   559 
   608 
   560 
   609 
   561 (*This version refers not to SERVER FINISHED but to any message from B.
   610 (*This version refers not to SERVER FINISHED but to any message from B.
   562   We don't assume B has received CERTIFICATE VERIFY, and an intruder could
   611   We don't assume B has received CERTIFICATE VERIFY, and an intruder could
   563   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
   564   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
   565   to bind A's identify with M, then we could replace A' by A below.*)
   614   to bind A's identity with M, then we could replace A' by A below.*)
   566 goal thy
   615 goal thy
   567  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                     \
   616  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost;                 \
   568 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->              \
   617 \           M = PRF(PMS,NA,NB) |]            \
   569 \            Crypt (serverK(NA,NB,M)) Y : parts (sees Spy evs)  -->  \
   618 \        ==> Notes A {|Agent B, Nonce PMS|} : set evs -->              \
   570 \            (EX A'. Says B A' (Crypt (serverK(NA,NB,M)) Y) : set evs)";
   619 \            Crypt (serverK(Na,Nb,M)) Y : parts (sees Spy evs)  -->  \
       
   620 \            (EX A'. Says B A' (Crypt (serverK(Na,Nb,M)) Y) : set evs)";
       
   621 by (hyp_subst_tac 1);
   571 by (analz_induct_tac 1);
   622 by (analz_induct_tac 1);
   572 by (REPEAT_FIRST (rtac impI));
   623 by (REPEAT_FIRST (rtac impI));
   573 (*Fake: the Spy doesn't have the critical session key!*)
   624 (*Fake: the Spy doesn't have the critical session key!*)
   574 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   625 by (subgoal_tac 
   575 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   626     "Key (serverK(Na,Nb,PRF(PMS,NA,NB))) ~: analz (sees Spy evsa)" 1);
       
   627 by (asm_simp_tac (!simpset addsimps [Spy_not_see_MS, 
   576 				     not_parts_not_analz]) 2);
   628 				     not_parts_not_analz]) 2);
   577 by (Fake_parts_insert_tac 1);
   629 by (Fake_parts_insert_tac 1);
   578 (*ServerFinished.  If the message is old then apply induction hypothesis...*)
   630 (*ServerFinished.  If the message is old then apply induction hypothesis...*)
   579 by (rtac conjI 1 THEN Blast_tac 2);
   631 by (rtac conjI 1 THEN Blast_tac 2);
   580 (*...otherwise delete induction hyp and use unicity of M.*)
   632 (*...otherwise delete induction hyp and use unicity of PMS.*)
   581 by (thin_tac "?PP-->?QQ" 1);
   633 by (thin_tac "?PP-->?QQ" 1);
   582 by (Step_tac 1);
   634 by (Step_tac 1);
   583 by (subgoal_tac "Nonce M ~: analz (sees Spy evsa)" 1);
   635 by (subgoal_tac "Nonce PMS ~: analz (sees Spy evsSF)" 1);
   584 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   636 by (asm_simp_tac (!simpset addsimps [Spy_not_see_PMS]) 2);
   585 by (blast_tac (!claset addSEs [MPair_parts]
   637 by (blast_tac (!claset addSEs [MPair_parts]
   586 		       addDs  [Notes_Crypt_parts_sees,
   638 		       addDs  [Notes_Crypt_parts_sees,
   587 			       Says_imp_sees_Spy RS parts.Inj,
   639 			       Says_imp_sees_Spy RS parts.Inj,
   588 			       unique_M]) 1);
   640 			       unique_PMS]) 1);
   589 qed_spec_mp "TrustServerMsg";
   641 qed_spec_mp "TrustServerMsg";
   590 
   642 
   591 
   643 
   592 (*** Protocol goal: if B receives any message encrypted with clientK
   644 (*** Protocol goal: if B receives any message encrypted with clientK
   593      then A has sent it, ASSUMING that A chose M.  Authentication is
   645      then A has sent it, ASSUMING that A chose PMS.  Authentication is
   594      assumed here; B cannot verify it.  But if the message is
   646      assumed here; B cannot verify it.  But if the message is
   595      CLIENT FINISHED, then B can then check the quoted values XA, XB, etc.
   647      CLIENT FINISHED, then B can then check the quoted values XA, XB, etc.
   596 ***)
   648 ***)
   597 goal thy
   649 goal thy
   598  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                         \
   650  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                         \
   599 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                  \
   651 \  ==> Notes A {|Agent B, Nonce PMS|} : set evs -->                  \
   600 \            Crypt (clientK(NA,NB,M)) Y : parts (sees Spy evs) -->  \
   652 \      Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y : parts (sees Spy evs) -->  \
   601 \            Says A B (Crypt (clientK(NA,NB,M)) Y) : set evs";
   653 \      Says A B (Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs";
   602 by (analz_induct_tac 1);
   654 by (analz_induct_tac 1);
   603 by (REPEAT_FIRST (rtac impI));
   655 by (REPEAT_FIRST (rtac impI));
   604 (*Fake: the Spy doesn't have the critical session key!*)
   656 (*Fake: the Spy doesn't have the critical session key!*)
   605 by (subgoal_tac "Key (clientK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   657 by (subgoal_tac 
   606 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   658     "Key (clientK(Na,Nb,PRF(PMS,NA,NB))) ~: analz (sees Spy evsa)" 1);
       
   659 by (asm_simp_tac (!simpset addsimps [Spy_not_see_MS, 
   607 				     not_parts_not_analz]) 2);
   660 				     not_parts_not_analz]) 2);
   608 by (Fake_parts_insert_tac 1);
   661 by (Fake_parts_insert_tac 1);
   609 (*ClientFinished.  If the message is old then apply induction hypothesis...*)
   662 (*ClientFinished.  If the message is old then apply induction hypothesis...*)
   610 by (step_tac (!claset delrules [conjI]) 1);
   663 by (step_tac (!claset delrules [conjI]) 1);
   611 by (subgoal_tac "Nonce M ~: analz (sees Spy evsa)" 1);
   664 by (subgoal_tac "Nonce PMS ~: analz (sees Spy evsCF)" 1);
   612 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   665 by (asm_simp_tac (!simpset addsimps [Spy_not_see_PMS]) 2);
   613 by (blast_tac (!claset addSEs [MPair_parts]
   666 by (blast_tac (!claset addSEs [MPair_parts]
   614 		       addDs  [Notes_unique_M]) 1);
   667 		       addDs  [Notes_unique_PMS]) 1);
   615 qed_spec_mp "TrustClientMsg";
   668 qed_spec_mp "TrustClientMsg";
   616 
   669 
   617 
   670 
   618 (*** Protocol goal: if B receives CLIENT FINISHED, and if B is able to
   671 (*** Protocol goal: if B receives CLIENT FINISHED, and if B is able to
   619      check a CERTIFICATE VERIFY from A, then A has used the quoted
   672      check a CERTIFICATE VERIFY from A, then A has used the quoted
   620      values XA, XB, etc.  Even this one requires A to be uncompromised.
   673      values XA, XB, etc.  Even this one requires A to be uncompromised.
   621  ***)
   674  ***)
   622 goal thy
   675 goal thy
   623  "!!evs. [| Says A' B (Crypt (clientK(NA,NB,M)) Y) : set evs;             \
   676  "!!evs. [| Says A' B (Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs; \
   624 \           Says B  A {|Nonce NA, Nonce NB, Agent XB, certificate B KB|}  \
   677 \           Says B  A {|Nonce NA, Nonce NB, Number XB, certificate B KB|}  \
   625 \             : set evs;                                                  \
   678 \             : set evs;                                                  \
   626 \           Says A'' B (Crypt (priK A)                                    \
   679 \           Says A'' B (Crypt (priK A)                                    \
   627 \                       (Hash{|Nonce NB, certificate B KB, Nonce M|}))    \
   680 \                       (Hash{|Nonce NB, certificate B KB, Nonce PMS|}))  \
   628 \             : set evs;                                                  \
   681 \             : set evs;                                                  \
   629 \        evs : tls;  A ~: lost;  B ~: lost |]                             \
   682 \        evs : tls;  A ~: lost;  B ~: lost |]                             \
   630 \     ==> Says A B (Crypt (clientK(NA,NB,M)) Y) : set evs";
   683 \     ==> Says A B (Crypt (clientK(Na,Nb,PRF(PMS,NA,NB))) Y) : set evs";
   631 by (blast_tac (!claset addSIs [TrustClientMsg, UseCertVerify]
   684 by (blast_tac (!claset addSIs [TrustClientMsg, UseCertVerify]
   632                        addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   685                        addDs  [Says_imp_sees_Spy RS parts.Inj]) 1);
   633 qed "AuthClientFinished";
   686 qed "AuthClientFinished";