src/HOL/Auth/TLS.ML
changeset 3519 ab0a9fbed4c0
parent 3515 d8a71f6eaf40
child 3672 56e4365a0c99
equal deleted inserted replaced
3518:6e11c7bfb9c7 3519:ab0a9fbed4c0
    20 open TLS;
    20 open TLS;
    21 
    21 
    22 proof_timing:=true;
    22 proof_timing:=true;
    23 HOL_quantifiers := false;
    23 HOL_quantifiers := false;
    24 
    24 
    25 AddIffs [Spy_in_lost, Server_not_lost];
    25 (** We mostly DO NOT unfold the definition of "certificate".  The attached
    26 Addsimps [certificate_def];
    26     lemmas unfold it lazily, when "certificate B KB" occurs in appropriate
    27 
    27     contexts.
    28 goal thy "!!A. A ~: lost ==> A ~= Spy";
    28 **)
    29 by (Blast_tac 1);
    29 
    30 qed "not_lost_not_eq_Spy";
    30 goalw thy [certificate_def] 
    31 Addsimps [not_lost_not_eq_Spy];
    31     "parts (insert (certificate B KB) H) =  \
       
    32 \    parts (insert (Crypt (priK Server) {|Agent B, Key KB|}) H)";
       
    33 by (rtac refl 1);
       
    34 qed "parts_insert_certificate";
       
    35 
       
    36 goalw thy [certificate_def] 
       
    37     "analz (insert (certificate B KB) H) =  \
       
    38 \    analz (insert (Crypt (priK Server) {|Agent B, Key KB|}) H)";
       
    39 by (rtac refl 1);
       
    40 qed "analz_insert_certificate";
       
    41 Addsimps [parts_insert_certificate, analz_insert_certificate];
       
    42 
       
    43 goalw thy [certificate_def] 
       
    44     "(X = certificate B KB) = (Crypt (priK Server) {|Agent B, Key KB|} = X)";
       
    45 by (Blast_tac 1);
       
    46 qed "eq_certificate_iff";
       
    47 AddIffs [eq_certificate_iff];
       
    48 
    32 
    49 
    33 (*Injectiveness of key-generating functions*)
    50 (*Injectiveness of key-generating functions*)
    34 AddIffs [inj_clientK RS inj_eq, inj_serverK RS inj_eq];
    51 AddIffs [inj_clientK RS inj_eq, inj_serverK RS inj_eq];
    35 
    52 
    36 (* invKey(clientK x) = clientK x  and similarly for serverK*)
    53 (* invKey(clientK x) = clientK x  and similarly for serverK*)
    37 Addsimps [isSym_clientK, rewrite_rule [isSymKey_def] isSym_clientK,
    54 Addsimps [isSym_clientK, rewrite_rule [isSymKey_def] isSym_clientK,
    38 	  isSym_serverK, rewrite_rule [isSymKey_def] isSym_serverK];
    55 	  isSym_serverK, rewrite_rule [isSymKey_def] isSym_serverK];
    39 
       
    40 
       
    41 (*Replacing the variable by a constant improves search speed by 50%!*)
       
    42 val Says_imp_sees_Spy' = 
       
    43     read_instantiate_sg (sign_of thy) [("lost","lost")] Says_imp_sees_Spy;
       
    44 
    56 
    45 
    57 
    46 (*** clientK and serverK make symmetric keys; no clashes with pubK or priK ***)
    58 (*** clientK and serverK make symmetric keys; no clashes with pubK or priK ***)
    47 
    59 
    48 goal thy "pubK A ~= clientK arg";
    60 goal thy "pubK A ~= clientK arg";
   100 by possibility_tac;
   112 by possibility_tac;
   101 result();
   113 result();
   102 
   114 
   103 (*And one for ClientFinished.  Either FINISHED message may come first.*)
   115 (*And one for ClientFinished.  Either FINISHED message may come first.*)
   104 goal thy 
   116 goal thy 
   105  "!!A B. A ~= B ==> EX NA XA NB XB M. EX evs: tls.    \
   117  "!!A B. A ~= B ==> EX NA XA NB XB M. EX evs: tls.              \
   106 \  Says A B (Crypt (clientK(NA,NB,M))                 \
   118 \  Says A B (Crypt (clientK(NA,NB,M))                           \
   107 \            (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|}, \
   119 \            (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|},        \
   108 \                   Nonce NA, Agent XA,               \
   120 \                   Nonce NA, Agent XA, certificate A (pubK A), \
   109 \                   certificate A (pubK A),      \
       
   110 \                   Nonce NB, Agent XB, Agent B|})) : set evs";
   121 \                   Nonce NB, Agent XB, Agent B|})) : set evs";
   111 by (REPEAT (resolve_tac [exI,bexI] 1));
   122 by (REPEAT (resolve_tac [exI,bexI] 1));
   112 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   123 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   113 	  RS tls.ClientFinished) 2);
   124 	  RS tls.ClientFinished) 2);
   114 by possibility_tac;
   125 by possibility_tac;
   115 result();
   126 result();
   116 
   127 
   117 (*Another one, for CertVerify (which is optional)*)
   128 (*Another one, for CertVerify (which is optional)*)
   118 goal thy 
   129 goal thy 
   119  "!!A B. A ~= B ==> EX NB M. EX evs: tls.     \
   130  "!!A B. A ~= B ==> EX NB M. EX evs: tls.   \
   120 \  Says A B (Crypt (priK A)                 \
   131 \  Says A B (Crypt (priK A)                 \
   121 \            (Hash{|Nonce NB, certificate B (pubK B), Nonce M|})) : set evs";
   132 \            (Hash{|Nonce NB, certificate B (pubK B), Nonce M|})) : set evs";
   122 by (REPEAT (resolve_tac [exI,bexI] 1));
   133 by (REPEAT (resolve_tac [exI,bexI] 1));
   123 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   134 by (rtac (tls.Nil RS tls.ClientHello RS tls.ServerHello RS tls.ClientCertKeyEx
   124 	  RS tls.CertVerify) 2);
   135 	  RS tls.CertVerify) 2);
   135 qed_spec_mp "not_Says_to_self";
   146 qed_spec_mp "not_Says_to_self";
   136 Addsimps [not_Says_to_self];
   147 Addsimps [not_Says_to_self];
   137 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
   148 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
   138 
   149 
   139 
   150 
   140 (** Theorems of the form X ~: parts (sees lost Spy evs) imply that NOBODY
   151 (*Induction for regularity theorems.  If induction formula has the form
       
   152    X ~: analz (sees Spy evs) --> ... then it shortens the proof by discarding
       
   153    needless information about analz (insert X (sees Spy evs))  *)
       
   154 fun parts_induct_tac i = 
       
   155     etac tls.induct i
       
   156     THEN 
       
   157     REPEAT (FIRSTGOAL analz_mono_contra_tac)
       
   158     THEN 
       
   159     fast_tac (!claset addss (!simpset)) i THEN
       
   160     ALLGOALS (asm_full_simp_tac (!simpset setloop split_tac [expand_if]));
       
   161 
       
   162 
       
   163 (** Theorems of the form X ~: parts (sees Spy evs) imply that NOBODY
   141     sends messages containing X! **)
   164     sends messages containing X! **)
   142 
   165 
   143 (*Spy never sees another agent's private key! (unless it's lost at start)*)
   166 (*Spy never sees another agent's private key! (unless it's lost at start)*)
   144 goal thy 
   167 goal thy 
   145  "!!evs. evs : tls \
   168  "!!evs. evs : tls ==> (Key (priK A) : parts (sees Spy evs)) = (A : lost)";
   146 \        ==> (Key (priK A) : parts (sees lost Spy evs)) = (A : lost)";
   169 by (parts_induct_tac 1);
   147 by (etac tls.induct 1);
       
   148 by (prove_simple_subgoals_tac 1);
       
   149 by (asm_simp_tac (!simpset setloop split_tac [expand_if]) 2);
       
   150 by (Fake_parts_insert_tac 1);
   170 by (Fake_parts_insert_tac 1);
   151 qed "Spy_see_priK";
   171 qed "Spy_see_priK";
   152 Addsimps [Spy_see_priK];
   172 Addsimps [Spy_see_priK];
   153 
   173 
   154 goal thy 
   174 goal thy 
   155  "!!evs. evs : tls \
   175  "!!evs. evs : tls ==> (Key (priK A) : analz (sees Spy evs)) = (A : lost)";
   156 \        ==> (Key (priK A) : analz (sees lost Spy evs)) = (A : lost)";
       
   157 by (auto_tac(!claset addDs [impOfSubs analz_subset_parts], !simpset));
   176 by (auto_tac(!claset addDs [impOfSubs analz_subset_parts], !simpset));
   158 qed "Spy_analz_priK";
   177 qed "Spy_analz_priK";
   159 Addsimps [Spy_analz_priK];
   178 Addsimps [Spy_analz_priK];
   160 
   179 
   161 goal thy  "!!A. [| Key (priK A) : parts (sees lost Spy evs);       \
   180 goal thy  "!!A. [| Key (priK A) : parts (sees Spy evs);       \
   162 \                  evs : tls |] ==> A:lost";
   181 \                  evs : tls |] ==> A:lost";
   163 by (blast_tac (!claset addDs [Spy_see_priK]) 1);
   182 by (blast_tac (!claset addDs [Spy_see_priK]) 1);
   164 qed "Spy_see_priK_D";
   183 qed "Spy_see_priK_D";
   165 
   184 
   166 bind_thm ("Spy_analz_priK_D", analz_subset_parts RS subsetD RS Spy_see_priK_D);
   185 bind_thm ("Spy_analz_priK_D", analz_subset_parts RS subsetD RS Spy_see_priK_D);
   167 AddSDs [Spy_see_priK_D, Spy_analz_priK_D];
   186 AddSDs [Spy_see_priK_D, Spy_analz_priK_D];
   168 
   187 
   169 
   188 
   170 (*This lemma says that no false certificates exist.  One might extend the
   189 (*This lemma says that no false certificates exist.  One might extend the
   171   model to include bogus certificates for the lost agents, but there seems
   190   model to include bogus certificates for the agents, but there seems
   172   little point in doing so: the loss of their private keys is a worse
   191   little point in doing so: the loss of their private keys is a worse
   173   breach of security.*)
   192   breach of security.*)
   174 goalw thy [certificate_def]
   193 goalw thy [certificate_def]
   175  "!!evs. evs : tls     \
   194  "!!evs. evs : tls     \
   176 \        ==> certificate B KB : parts (sees lost Spy evs) --> KB = pubK B";
   195 \        ==> certificate B KB : parts (sees Spy evs) --> KB = pubK B";
   177 by (etac tls.induct 1);
   196 by (parts_induct_tac 1);
   178 by (ALLGOALS (asm_full_simp_tac (!simpset setloop split_tac [expand_if])));
   197 by (Fake_parts_insert_tac 1);
   179 by (Fake_parts_insert_tac 2);
       
   180 by (Blast_tac 1);
       
   181 bind_thm ("Server_cert_pubB", result() RSN (2, rev_mp));
   198 bind_thm ("Server_cert_pubB", result() RSN (2, rev_mp));
   182 
   199 
   183 
   200 
   184 (*Replace key KB in ClientCertKeyEx by (pubK B) *)
   201 (*Replace key KB in ClientCertKeyEx by (pubK B) *)
   185 val ClientCertKeyEx_tac = 
   202 val ClientCertKeyEx_tac = 
   186     forward_tac [Says_imp_sees_Spy' RS parts.Inj RS 
   203     forward_tac [Says_imp_sees_Spy RS parts.Inj RS 
   187 		 parts.Snd RS parts.Snd RS parts.Snd RS Server_cert_pubB]
   204 		 parts.Snd RS parts.Snd RS parts.Snd RS Server_cert_pubB]
   188     THEN' assume_tac
   205     THEN' assume_tac
   189     THEN' hyp_subst_tac;
   206     THEN' hyp_subst_tac;
   190 
   207 
   191 fun analz_induct_tac i = 
   208 fun analz_induct_tac i = 
   192     etac tls.induct i   THEN
   209     etac tls.induct i   THEN
   193     ClientCertKeyEx_tac  (i+7)  THEN	(*ClientFinished*)
   210     ClientCertKeyEx_tac  (i+7)  THEN	(*ClientFinished*)
   194     ClientCertKeyEx_tac  (i+6)  THEN	(*CertVerify*)
   211     ClientCertKeyEx_tac  (i+6)  THEN	(*CertVerify*)
   195     ClientCertKeyEx_tac  (i+5)  THEN	(*ClientCertKeyEx*)
   212     ClientCertKeyEx_tac  (i+5)  THEN	(*ClientCertKeyEx*)
   196     rewrite_goals_tac  [certificate_def]  THEN
       
   197     ALLGOALS (asm_simp_tac 
   213     ALLGOALS (asm_simp_tac 
   198               (!simpset addsimps [not_parts_not_analz]
   214               (!simpset addsimps [not_parts_not_analz]
   199                         setloop split_tac [expand_if]))  THEN
   215                         setloop split_tac [expand_if]))  THEN
   200     (*Remove instances of pubK B:  the Spy already knows all public keys.
   216     (*Remove instances of pubK B:  the Spy already knows all public keys.
   201       Combining the two simplifier calls makes them run extremely slowly.*)
   217       Combining the two simplifier calls makes them run extremely slowly.*)
   205 
   221 
   206 
   222 
   207 (*** Hashing of nonces ***)
   223 (*** Hashing of nonces ***)
   208 
   224 
   209 (*Every Nonce that's hashed is already in past traffic. *)
   225 (*Every Nonce that's hashed is already in past traffic. *)
   210 goal thy "!!evs. [| Hash {|Nonce N, X|} : parts (sees lost Spy evs);  \
   226 goal thy "!!evs. [| Hash {|Nonce N, X|} : parts (sees Spy evs);  \
   211 \                   evs : tls |]  \
   227 \                   evs : tls |]  \
   212 \                ==> Nonce N : parts (sees lost Spy evs)";
   228 \                ==> Nonce N : parts (sees Spy evs)";
   213 by (etac rev_mp 1);
   229 by (etac rev_mp 1);
   214 by (etac tls.induct 1);
   230 by (parts_induct_tac 1);
   215 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees]
   231 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
   216 			             setloop split_tac [expand_if])));
   232 by (Fake_parts_insert_tac 1);
   217 by (Fake_parts_insert_tac 2);
   233 by (blast_tac (!claset addSDs [Says_imp_sees_Spy RS parts.Inj]
   218 by (REPEAT (blast_tac (!claset addSDs [Says_imp_sees_Spy' RS parts.Inj]
   234 	               addSEs partsEs) 1);
   219 		               addSEs partsEs) 1));
       
   220 qed "Hash_imp_Nonce1";
   235 qed "Hash_imp_Nonce1";
   221 
   236 
   222 (*Lemma needed to prove Hash_Hash_imp_Nonce*)
   237 (*Lemma needed to prove Hash_Hash_imp_Nonce*)
   223 goal thy "!!evs. [| Hash{|Nonce NA, Nonce NB, Nonce M|}  \
   238 goal thy "!!evs. [| Hash{|Nonce NA, Nonce NB, Nonce M|}  \
   224 \                       : parts (sees lost Spy evs);     \
   239 \                       : parts (sees Spy evs);     \
   225 \                   evs : tls |]  \
   240 \                   evs : tls |]  \
   226 \                ==> Nonce M : parts (sees lost Spy evs)";
   241 \                ==> Nonce M : parts (sees Spy evs)";
   227 by (etac rev_mp 1);
   242 by (etac rev_mp 1);
   228 by (etac tls.induct 1);
   243 by (parts_induct_tac 1);
   229 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees]
   244 by (asm_simp_tac (!simpset addsimps [parts_insert_sees]) 1);
   230 			             setloop split_tac [expand_if])));
   245 by (Fake_parts_insert_tac 1);
   231 by (Fake_parts_insert_tac 2);
       
   232 by (blast_tac (!claset addSDs [Says_imp_sees_Spy' RS parts.Inj]
       
   233 		       addSEs partsEs) 1);
       
   234 qed "Hash_imp_Nonce2";
   246 qed "Hash_imp_Nonce2";
   235 AddSDs [Hash_imp_Nonce2];
   247 AddSDs [Hash_imp_Nonce2];
   236 
   248 
   237 
   249 
   238 goal thy "!!evs. [| Notes A {|Agent B, X|} : set evs;  evs : tls |]  \
   250 goal thy "!!evs. [| Notes A {|Agent B, X|} : set evs;  evs : tls |]  \
   239 \                ==> Crypt (pubK B) X : parts (sees lost Spy evs)";
   251 \                ==> Crypt (pubK B) X : parts (sees Spy evs)";
   240 by (etac rev_mp 1);
   252 by (etac rev_mp 1);
   241 by (analz_induct_tac 1);
   253 by (analz_induct_tac 1);
   242 by (blast_tac (!claset addIs [parts_insertI]) 1);
   254 by (blast_tac (!claset addIs [parts_insertI]) 1);
   243 qed "Notes_Crypt_parts_sees";
   255 qed "Notes_Crypt_parts_sees";
   244 
   256 
   245 
   257 
   246 (*NEEDED??*)
   258 (*NEEDED??*)
   247 goal thy "!!evs. [| Hash {| Hash{|Nonce NA, Nonce NB, Nonce M|}, X |}  \
   259 goal thy "!!evs. [| Hash {| Hash{|Nonce NA, Nonce NB, Nonce M|}, X |}  \
   248 \                      : parts (sees lost Spy evs);      \
   260 \                      : parts (sees Spy evs);      \
   249 \                   evs : tls |]                         \
   261 \                   evs : tls |]                         \
   250 \                ==> Nonce M : parts (sees lost Spy evs)";
   262 \                ==> Nonce M : parts (sees Spy evs)";
   251 by (etac rev_mp 1);
   263 by (etac rev_mp 1);
   252 by (etac tls.induct 1);
   264 by (parts_induct_tac 1);
   253 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees]
   265 by (ALLGOALS (asm_simp_tac (!simpset addsimps [parts_insert_sees])));
   254 			             setloop split_tac [expand_if])));
   266 by (Fake_parts_insert_tac 1);
   255 by (Fake_parts_insert_tac 2);
   267 by (REPEAT (blast_tac (!claset addSDs [Notes_Crypt_parts_sees,
   256 by (step_tac (!claset addSDs [Notes_Crypt_parts_sees,
   268 				       Says_imp_sees_Spy RS parts.Inj]
   257 			      Says_imp_sees_Spy' RS parts.Inj]
   269 		               addSEs partsEs) 1));
   258 		      addSEs partsEs) 1);
       
   259 qed "Hash_Hash_imp_Nonce";
   270 qed "Hash_Hash_imp_Nonce";
   260 
   271 
   261 
   272 
   262 (*NEEDED??
   273 (*NEEDED??
   263   Every Nonce that's hashed is already in past traffic. 
   274   Every Nonce that's hashed is already in past traffic. 
   264   This general formulation is tricky to prove and hard to use, since the
   275   This general formulation is tricky to prove and hard to use, since the
   265   2nd premise is typically proved by simplification.*)
   276   2nd premise is typically proved by simplification.*)
   266 goal thy "!!evs. [| Hash X : parts (sees lost Spy evs);  \
   277 goal thy "!!evs. [| Hash X : parts (sees Spy evs);  \
   267 \                   Nonce N : parts {X};  evs : tls |]  \
   278 \                   Nonce N : parts {X};  evs : tls |]  \
   268 \                ==> Nonce N : parts (sees lost Spy evs)";
   279 \                ==> Nonce N : parts (sees Spy evs)";
   269 by (etac rev_mp 1);
   280 by (etac rev_mp 1);
   270 by (etac tls.induct 1);
   281 by (parts_induct_tac 1);
   271 by (ALLGOALS (asm_simp_tac (!simpset setloop split_tac [expand_if])));
       
   272 by (step_tac (!claset addSDs [Notes_Crypt_parts_sees,
   282 by (step_tac (!claset addSDs [Notes_Crypt_parts_sees,
   273 			      Says_imp_sees_Spy' RS parts.Inj]
   283 			      Says_imp_sees_Spy RS parts.Inj]
   274 		      addSEs partsEs) 1);
   284 		      addSEs partsEs) 1);
   275 by (ALLGOALS (asm_full_simp_tac (!simpset addsimps [parts_insert_sees])));
   285 by (ALLGOALS (asm_full_simp_tac (!simpset addsimps [parts_insert_sees])));
   276 by (Fake_parts_insert_tac 1);
   286 by (Fake_parts_insert_tac 1);
   277 (*CertVerify, ClientFinished, ServerFinished (?)*)
   287 (*CertVerify, ClientFinished, ServerFinished (?)*)
   278 by (REPEAT (Blast_tac 1));
   288 by (REPEAT (Blast_tac 1));
   283 
   293 
   284 (*B can check A's signature if he has received A's certificate.
   294 (*B can check A's signature if he has received A's certificate.
   285   Perhaps B~=Spy is unnecessary, but there's no obvious proof if the first
   295   Perhaps B~=Spy is unnecessary, but there's no obvious proof if the first
   286   message is Fake.  We don't need guarantees for the Spy anyway.  We must
   296   message is Fake.  We don't need guarantees for the Spy anyway.  We must
   287   assume A~:lost; otherwise, the Spy can forge A's signature.*)
   297   assume A~:lost; otherwise, the Spy can forge A's signature.*)
   288 goalw thy [certificate_def]
   298 goal thy
   289  "!!evs. [| X = Crypt (priK A)                                        \
   299  "!!evs. [| X = Crypt (priK A)                                        \
   290 \                 (Hash{|Nonce NB, certificate B KB, Nonce M|});      \
   300 \                 (Hash{|Nonce NB, certificate B KB, Nonce M|});      \
   291 \           evs : tls;  A ~: lost;  B ~= Spy |]                       \
   301 \           evs : tls;  A ~: lost;  B ~= Spy |]                       \
   292 \    ==> Says B A {|Nonce NA, Nonce NB, Agent XB, certificate B KB|}  \
   302 \    ==> Says B A {|Nonce NA, Nonce NB, Agent XB, certificate B KB|}  \
   293 \          : set evs --> \
   303 \          : set evs --> \
   294 \        X : parts (sees lost Spy evs) --> Says A B X : set evs";
   304 \        X : parts (sees Spy evs) --> Says A B X : set evs";
   295 by (hyp_subst_tac 1);
   305 by (hyp_subst_tac 1);
   296 by (etac tls.induct 1);
   306 by (parts_induct_tac 1);
   297 by (ALLGOALS (asm_simp_tac (!simpset setloop split_tac [expand_if])));
       
   298 by (Fake_parts_insert_tac 1);
   307 by (Fake_parts_insert_tac 1);
   299 (*ServerHello: nonce NB cannot be in X because it's fresh!*)
   308 (*ServerHello: nonce NB cannot be in X because it's fresh!*)
   300 by (blast_tac (!claset addSDs [Hash_imp_Nonce1]
   309 by (blast_tac (!claset addSDs [Hash_imp_Nonce1]
   301 	               addSEs sees_Spy_partsEs) 1);
   310 	               addSEs sees_Spy_partsEs) 1);
   302 qed_spec_mp "TrustCertVerify";
   311 qed_spec_mp "TrustCertVerify";
   303 
   312 
   304 
   313 
   305 (*If CERTIFICATE VERIFY is present then A has chosen M.*)
   314 (*If CERTIFICATE VERIFY is present then A has chosen M.*)
   306 goal thy
   315 goal thy
   307  "!!evs. [| Crypt (priK A) (Hash{|Nonce NB, certificate B KB, Nonce M|})  \
   316  "!!evs. [| Crypt (priK A) (Hash{|Nonce NB, certificate B KB, Nonce M|})  \
   308 \             : parts (sees lost Spy evs);                                \
   317 \             : parts (sees Spy evs);                                \
   309 \           evs : tls;  A ~: lost |]                                      \
   318 \           evs : tls;  A ~: lost |]                                      \
   310 \        ==> Notes A {|Agent B, Nonce M|} : set evs";
   319 \        ==> Notes A {|Agent B, Nonce M|} : set evs";
   311 be rev_mp 1;
   320 be rev_mp 1;
   312 by (etac tls.induct 1);
   321 by (parts_induct_tac 1);
   313 by (ALLGOALS (asm_full_simp_tac (!simpset setloop split_tac [expand_if])));
   322 by (Fake_parts_insert_tac 1);
   314 by (Fake_parts_insert_tac 2);
       
   315 by (Blast_tac 1);
       
   316 qed "UseCertVerify";
   323 qed "UseCertVerify";
   317 
   324 
   318 
   325 
   319 (*No collection of keys can help the spy get new private keys*)
   326 (*No collection of keys can help the spy get new private keys*)
   320 goal thy  
   327 goal thy  
   321  "!!evs. evs : tls ==>                                    \
   328  "!!evs. evs : tls ==>                                    \
   322 \  ALL KK. (Key(priK B) : analz (Key``KK Un (sees lost Spy evs))) =  \
   329 \  ALL KK. (Key(priK B) : analz (Key``KK Un (sees Spy evs))) =  \
   323 \            (priK B : KK | B : lost)";
   330 \            (priK B : KK | B : lost)";
   324 by (etac tls.induct 1);
   331 by (etac tls.induct 1);
   325 by (ALLGOALS
   332 by (ALLGOALS
   326     (asm_simp_tac (analz_image_keys_ss 
   333     (asm_simp_tac (analz_image_keys_ss
   327 		   addsimps (certificate_def::keys_distinct))));
   334 		   addsimps (certificate_def::keys_distinct))));
   328 (*Fake*) 
   335 (*Fake*) 
   329 by (spy_analz_tac 2);
   336 by (spy_analz_tac 2);
   330 (*Base*)
   337 (*Base*)
   331 by (Blast_tac 1);
   338 by (Blast_tac 1);
   341 
   348 
   342 (*Knowing some clientKs and serverKs is no help in getting new nonces*)
   349 (*Knowing some clientKs and serverKs is no help in getting new nonces*)
   343 goal thy  
   350 goal thy  
   344  "!!evs. evs : tls ==>                                 \
   351  "!!evs. evs : tls ==>                                 \
   345 \    ALL KK. KK <= (range clientK Un range serverK) -->           \
   352 \    ALL KK. KK <= (range clientK Un range serverK) -->           \
   346 \            (Nonce N : analz (Key``KK Un (sees lost Spy evs))) = \
   353 \            (Nonce N : analz (Key``KK Un (sees Spy evs))) = \
   347 \            (Nonce N : analz (sees lost Spy evs))";
   354 \            (Nonce N : analz (sees Spy evs))";
   348 by (etac tls.induct 1);
   355 by (etac tls.induct 1);
   349 by (ClientCertKeyEx_tac 6);
   356 by (ClientCertKeyEx_tac 6);
   350 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   357 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   351 by (REPEAT_FIRST (rtac lemma));
   358 by (REPEAT_FIRST (rtac lemma));
   352 writeln"SLOW simplification: 50 secs!??";
   359 writeln"SLOW simplification: 50 secs!??";
   353 by (ALLGOALS
   360 by (ALLGOALS
   354     (asm_simp_tac (analz_image_keys_ss 
   361     (asm_simp_tac (analz_image_keys_ss 
   355 		   addsimps (analz_image_priK::certificate_def::
   362                    addsimps (analz_image_priK::certificate_def::
   356 			     keys_distinct))));
   363                              keys_distinct))));
   357 by (ALLGOALS (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_priK])));
   364 by (ALLGOALS (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_priK])));
   358 by (ALLGOALS (asm_simp_tac (!simpset addsimps [insert_absorb])));
   365 by (ALLGOALS (asm_simp_tac (!simpset addsimps [insert_absorb])));
   359 (*ClientCertKeyEx: a nonce is sent, but one needs a priK to read it.*)
   366 (*ClientCertKeyEx: a nonce is sent, but one needs a priK to read it.*)
   360 by (Blast_tac 3);
   367 by (Blast_tac 3);
   361 (*Fake*) 
   368 (*Fake*) 
   367 
   374 
   368 (*If A sends ClientCertKeyEx to an uncompromised B, then M will stay secret.*)
   375 (*If A sends ClientCertKeyEx to an uncompromised B, then M will stay secret.*)
   369 goal thy
   376 goal thy
   370  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]           \
   377  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]           \
   371 \        ==> Notes A {|Agent B, Nonce M|} : set evs  -->   \
   378 \        ==> Notes A {|Agent B, Nonce M|} : set evs  -->   \
   372 \            Nonce M ~: analz (sees lost Spy evs)";
   379 \            Nonce M ~: analz (sees Spy evs)";
   373 by (analz_induct_tac 1);
   380 by (analz_induct_tac 1);
   374 (*ClientHello*)
   381 (*ClientHello*)
   375 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   382 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   376                                addSEs sees_Spy_partsEs) 3);
   383                                addSEs sees_Spy_partsEs) 3);
   377 (*SpyKeys*)
   384 (*SpyKeys*)
   380 by (spy_analz_tac 1);
   387 by (spy_analz_tac 1);
   381 (*ServerHello and ClientCertKeyEx: mostly freshness reasoning*)
   388 (*ServerHello and ClientCertKeyEx: mostly freshness reasoning*)
   382 by (REPEAT (blast_tac (!claset addSEs partsEs
   389 by (REPEAT (blast_tac (!claset addSEs partsEs
   383 			       addDs  [Notes_Crypt_parts_sees,
   390 			       addDs  [Notes_Crypt_parts_sees,
   384 				       impOfSubs analz_subset_parts,
   391 				       impOfSubs analz_subset_parts,
   385 				       Says_imp_sees_Spy' RS analz.Inj]) 1));
   392 				       Says_imp_sees_Spy RS analz.Inj]) 1));
   386 bind_thm ("Spy_not_see_premaster_secret", result() RSN (2, rev_mp));
   393 bind_thm ("Spy_not_see_premaster_secret", result() RSN (2, rev_mp));
   387 
   394 
   388 
   395 
   389 (*** Protocol goal: serverK(NA,NB,M) and clientK(NA,NB,M) remain secure ***)
   396 (*** Protocol goal: serverK(NA,NB,M) and clientK(NA,NB,M) remain secure ***)
   390 
   397 
   393 
   400 
   394 (*Lemma: those write keys are never sent if M is secure.  
   401 (*Lemma: those write keys are never sent if M is secure.  
   395   Converse doesn't hold; betraying M doesn't force the keys to be sent!*)
   402   Converse doesn't hold; betraying M doesn't force the keys to be sent!*)
   396 
   403 
   397 goal thy 
   404 goal thy 
   398  "!!evs. [| Nonce M ~: analz (sees lost Spy evs);  evs : tls |]   \
   405  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   399 \        ==> Key (clientK(NA,NB,M)) ~: parts (sees lost Spy evs)";
   406 \        ==> Key (clientK(NA,NB,M)) ~: parts (sees Spy evs)";
   400 by (etac rev_mp 1);
   407 by (etac rev_mp 1);
   401 by (analz_induct_tac 1);
   408 by (analz_induct_tac 1);
   402 (*SpyKeys*)
   409 (*SpyKeys*)
   403 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 3);
   410 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 3);
   404 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS analz.Inj]) 3);
   411 by (blast_tac (!claset addDs [Says_imp_sees_Spy RS analz.Inj]) 3);
   405 (*Fake*) 
   412 (*Fake*) 
   406 by (spy_analz_tac 2);
   413 by (spy_analz_tac 2);
   407 (*Base*)
   414 (*Base*)
   408 by (Blast_tac 1);
   415 by (Blast_tac 1);
   409 qed "clientK_notin_parts";
   416 qed "clientK_notin_parts";
   410 
   417 
   411 Addsimps [clientK_notin_parts];
   418 Addsimps [clientK_notin_parts];
   412 AddSEs [clientK_notin_parts RSN (2, rev_notE)];
   419 AddSEs [clientK_notin_parts RSN (2, rev_notE)];
   413 
   420 
   414 goal thy 
   421 goal thy 
   415  "!!evs. [| Nonce M ~: analz (sees lost Spy evs);  evs : tls |]   \
   422  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   416 \        ==> Key (serverK(NA,NB,M)) ~: parts (sees lost Spy evs)";
   423 \        ==> Key (serverK(NA,NB,M)) ~: parts (sees Spy evs)";
   417 by (etac rev_mp 1);
   424 by (etac rev_mp 1);
   418 by (analz_induct_tac 1);
   425 by (analz_induct_tac 1);
   419 (*SpyKeys*)
   426 (*SpyKeys*)
   420 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 3);
   427 by (asm_simp_tac (analz_image_keys_ss addsimps [analz_image_keys]) 3);
   421 by (blast_tac (!claset addDs [Says_imp_sees_Spy' RS analz.Inj]) 3);
   428 by (blast_tac (!claset addDs [Says_imp_sees_Spy RS analz.Inj]) 3);
   422 (*Fake*) 
   429 (*Fake*) 
   423 by (spy_analz_tac 2);
   430 by (spy_analz_tac 2);
   424 (*Base*)
   431 (*Base*)
   425 by (Blast_tac 1);
   432 by (Blast_tac 1);
   426 qed "serverK_notin_parts";
   433 qed "serverK_notin_parts";
   432   Converse doesn't hold; betraying M doesn't force the keys to be sent!
   439   Converse doesn't hold; betraying M doesn't force the keys to be sent!
   433   NOT suitable as safe elim rules.*)
   440   NOT suitable as safe elim rules.*)
   434 
   441 
   435 goal thy 
   442 goal thy 
   436  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   443  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   437 \        ==> Crypt (clientK(NA,NB,M)) Y ~: parts (sees lost Spy evs)";
   444 \        ==> Crypt (clientK(NA,NB,M)) Y ~: parts (sees Spy evs)";
   438 by (etac rev_mp 1);
   445 by (etac rev_mp 1);
   439 by (analz_induct_tac 1);
   446 by (analz_induct_tac 1);
   440 (*ClientFinished: since M is fresh, a different instance of clientK was used.*)
   447 (*ClientFinished: since M is fresh, a different instance of clientK was used.*)
   441 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   448 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   442                                addSEs sees_Spy_partsEs) 3);
   449                                addSEs sees_Spy_partsEs) 3);
   448 Addsimps [Crypt_clientK_notin_parts];
   455 Addsimps [Crypt_clientK_notin_parts];
   449 AddEs [Crypt_clientK_notin_parts RSN (2, rev_notE)];
   456 AddEs [Crypt_clientK_notin_parts RSN (2, rev_notE)];
   450 
   457 
   451 goal thy 
   458 goal thy 
   452  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   459  "!!evs. [| Nonce M ~: used evs;  evs : tls |]                           \
   453 \        ==> Crypt (serverK(NA,NB,M)) Y ~: parts (sees lost Spy evs)";
   460 \        ==> Crypt (serverK(NA,NB,M)) Y ~: parts (sees Spy evs)";
   454 by (etac rev_mp 1);
   461 by (etac rev_mp 1);
   455 by (analz_induct_tac 1);
   462 by (analz_induct_tac 1);
   456 (*ServerFinished: since M is fresh, a different instance of serverK was used.*)
   463 (*ServerFinished: since M is fresh, a different instance of serverK was used.*)
   457 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   464 by (blast_tac (!claset addSDs [Notes_Crypt_parts_sees]
   458                                addSEs sees_Spy_partsEs) 3);
   465                                addSEs sees_Spy_partsEs) 3);
   463 
   470 
   464 Addsimps [Crypt_serverK_notin_parts];
   471 Addsimps [Crypt_serverK_notin_parts];
   465 AddEs [Crypt_serverK_notin_parts RSN (2, rev_notE)];
   472 AddEs [Crypt_serverK_notin_parts RSN (2, rev_notE)];
   466 
   473 
   467 
   474 
   468 (*Weakening A~:lost to A~=Spy would complicate later uses of the rule*)
   475 (*NEEDED??*)
   469 goal thy
   476 goal thy
   470  "!!evs. [| Says A B {|certA, Crypt KB (Nonce M)|} : set evs;   \
   477  "!!evs. [| Says A B {|certA, Crypt KB (Nonce M)|} : set evs;   \
   471 \           A ~: lost;  evs : tls |] ==> KB = pubK B";
   478 \           A ~= Spy;  evs : tls |] ==> KB = pubK B";
   472 be rev_mp 1;
   479 be rev_mp 1;
   473 by (analz_induct_tac 1);
   480 by (analz_induct_tac 1);
   474 qed "A_Crypt_pubB";
   481 qed "A_Crypt_pubB";
   475 
   482 
   476 
   483 
   477 (*** Unicity results for M, the pre-master-secret ***)
   484 (*** Unicity results for M, the pre-master-secret ***)
   478 
   485 
   479 (*Induction for theorems of the form X ~: analz (sees lost Spy evs) --> ...
       
   480   It simplifies the proof by discarding needless information about
       
   481 	analz (insert X (sees lost Spy evs)) 
       
   482 *)
       
   483 fun analz_mono_parts_induct_tac i = 
       
   484     etac tls.induct i           THEN 
       
   485     ClientCertKeyEx_tac  (i+5)  THEN	(*ClientCertKeyEx*)
       
   486     REPEAT_FIRST analz_mono_contra_tac;
       
   487 
       
   488 
       
   489 (*M determines B.  Proof borrowed from NS_Public/unique_NA and from Yahalom*)
   486 (*M determines B.  Proof borrowed from NS_Public/unique_NA and from Yahalom*)
   490 goal thy 
   487 goal thy 
   491  "!!evs. [| Nonce M ~: analz (sees lost Spy evs);  evs : tls |]   \
   488  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]   \
   492 \        ==> EX B'. ALL B.   \
   489 \        ==> EX B'. ALL B.   \
   493 \              Crypt (pubK B) (Nonce M) : parts (sees lost Spy evs) --> B=B'";
   490 \              Crypt (pubK B) (Nonce M) : parts (sees Spy evs) --> B=B'";
   494 by (etac rev_mp 1);
   491 by (etac rev_mp 1);
   495 by (analz_mono_parts_induct_tac 1);
   492 by (parts_induct_tac 1);
   496 by (prove_simple_subgoals_tac 1);
   493 by (Fake_parts_insert_tac 1);
   497 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]
       
   498                            setloop split_tac [expand_if]) 2);
       
   499 (*ClientCertKeyEx*)
   494 (*ClientCertKeyEx*)
   500 by (expand_case_tac "M = ?y" 2 THEN
   495 by (ClientCertKeyEx_tac 1);
   501     REPEAT (blast_tac (!claset addSEs partsEs) 2));
   496 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   502 by (Fake_parts_insert_tac 1);
   497 by (expand_case_tac "M = ?y" 1 THEN
       
   498     blast_tac (!claset addSEs partsEs) 1);
   503 val lemma = result();
   499 val lemma = result();
   504 
   500 
   505 goal thy 
   501 goal thy 
   506  "!!evs. [| Crypt(pubK B)  (Nonce M) : parts (sees lost Spy evs); \
   502  "!!evs. [| Crypt(pubK B)  (Nonce M) : parts (sees Spy evs); \
   507 \           Crypt(pubK B') (Nonce M) : parts (sees lost Spy evs); \
   503 \           Crypt(pubK B') (Nonce M) : parts (sees Spy evs); \
   508 \           Nonce M ~: analz (sees lost Spy evs);                 \
   504 \           Nonce M ~: analz (sees Spy evs);                 \
   509 \           evs : tls |]                                          \
   505 \           evs : tls |]                                          \
   510 \        ==> B=B'";
   506 \        ==> B=B'";
   511 by (prove_unique_tac lemma 1);
   507 by (prove_unique_tac lemma 1);
   512 qed "unique_M";
   508 qed "unique_M";
   513 
   509 
   514 
   510 
   515 (*In A's note to herself, M determines A and B.*)
   511 (*In A's note to herself, M determines A and B.*)
   516 goal thy 
   512 goal thy 
   517  "!!evs. [| Nonce M ~: analz (sees lost Spy evs);  evs : tls |]            \
   513  "!!evs. [| Nonce M ~: analz (sees Spy evs);  evs : tls |]            \
   518 \ ==> EX A' B'. ALL A B.                                                   \
   514 \ ==> EX A' B'. ALL A B.                                                   \
   519 \        Notes A {|Agent B, Nonce M|} : set evs --> A=A' & B=B'";
   515 \        Notes A {|Agent B, Nonce M|} : set evs --> A=A' & B=B'";
   520 by (etac rev_mp 1);
   516 by (etac rev_mp 1);
   521 by (analz_mono_parts_induct_tac 1);
   517 by (parts_induct_tac 1);
   522 by (prove_simple_subgoals_tac 1);
       
   523 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   518 by (asm_simp_tac (!simpset addsimps [all_conj_distrib]) 1);
   524 (*ClientCertKeyEx: if M is fresh, then it can't appear in Notes A X.*)
   519 (*ClientCertKeyEx: if M is fresh, then it can't appear in Notes A X.*)
   525 by (expand_case_tac "M = ?y" 1 THEN
   520 by (expand_case_tac "M = ?y" 1 THEN
   526     blast_tac (!claset addSDs [Notes_Crypt_parts_sees] addSEs partsEs) 1);
   521     blast_tac (!claset addSDs [Notes_Crypt_parts_sees] addSEs partsEs) 1);
   527 val lemma = result();
   522 val lemma = result();
   528 
   523 
   529 goal thy 
   524 goal thy 
   530  "!!evs. [| Notes A  {|Agent B,  Nonce M|} : set evs;  \
   525  "!!evs. [| Notes A  {|Agent B,  Nonce M|} : set evs;  \
   531 \           Notes A' {|Agent B', Nonce M|} : set evs;  \
   526 \           Notes A' {|Agent B', Nonce M|} : set evs;  \
   532 \           Nonce M ~: analz (sees lost Spy evs);      \
   527 \           Nonce M ~: analz (sees Spy evs);      \
   533 \           evs : tls |]                               \
   528 \           evs : tls |]                               \
   534 \        ==> A=A' & B=B'";
   529 \        ==> A=A' & B=B'";
   535 by (prove_unique_tac lemma 1);
   530 by (prove_unique_tac lemma 1);
   536 qed "Notes_unique_M";
   531 qed "Notes_unique_M";
   537 
   532 
   548 \                 (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|},           \
   543 \                 (Hash{|Hash{|Nonce NA, Nonce NB, Nonce M|},           \
   549 \                        Nonce NA, Agent XA, Agent A,                   \
   544 \                        Nonce NA, Agent XA, Agent A,                   \
   550 \                        Nonce NB, Agent XB, certificate B (pubK B)|}); \
   545 \                        Nonce NB, Agent XB, certificate B (pubK B)|}); \
   551 \           evs : tls;  A ~: lost;  B ~: lost |]                        \
   546 \           evs : tls;  A ~: lost;  B ~: lost |]                        \
   552 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                 \
   547 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                 \
   553 \        X : parts (sees lost Spy evs) --> Says B A X : set evs";
   548 \        X : parts (sees Spy evs) --> Says B A X : set evs";
   554 by (hyp_subst_tac 1);
   549 by (hyp_subst_tac 1);
   555 by (analz_induct_tac 1);
   550 by (analz_induct_tac 1);
   556 by (REPEAT_FIRST (rtac impI));
   551 by (REPEAT_FIRST (rtac impI));
   557 (*Fake: the Spy doesn't have the critical session key!*)
   552 (*Fake: the Spy doesn't have the critical session key!*)
   558 by (REPEAT (rtac impI 1));
   553 by (REPEAT (rtac impI 1));
   559 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees lost Spy evsa)" 1);
   554 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   560 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   555 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   561 				     not_parts_not_analz]) 2);
   556 				     not_parts_not_analz]) 2);
   562 by (Fake_parts_insert_tac 1);
   557 by (Fake_parts_insert_tac 1);
   563 qed_spec_mp "TrustServerFinished";
   558 qed_spec_mp "TrustServerFinished";
   564 
   559 
   565 
   560 
   566 (*This version refers not to SERVER FINISHED but to any message from B.
   561 (*This version refers not to SERVER FINISHED but to any message from B.
   567   We don't assume B has received CERTIFICATE VERIFY, and an intruder could
   562   We don't assume B has received CERTIFICATE VERIFY, and an intruder could
   568   have changed A's identity in all other messages, so we can't be sure
   563   have changed A's identity in all other messages, so we can't be sure
   569   that B sends his message to A.*)
   564   that B sends his message to A.  If CLIENT KEY EXCHANGE were augmented
   570 goal thy
   565   to bind A's identify with M, then we could replace A' by A below.*)
   571  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                         \
   566 goal thy
   572 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                  \
   567  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                     \
   573 \            Crypt (serverK(NA,NB,M)) Y : parts (sees lost Spy evs)  --> \
   568 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->              \
       
   569 \            Crypt (serverK(NA,NB,M)) Y : parts (sees Spy evs)  -->  \
   574 \            (EX A'. Says B A' (Crypt (serverK(NA,NB,M)) Y) : set evs)";
   570 \            (EX A'. Says B A' (Crypt (serverK(NA,NB,M)) Y) : set evs)";
   575 by (analz_induct_tac 1);
   571 by (analz_induct_tac 1);
   576 by (REPEAT_FIRST (rtac impI));
   572 by (REPEAT_FIRST (rtac impI));
   577 (*Fake: the Spy doesn't have the critical session key!*)
   573 (*Fake: the Spy doesn't have the critical session key!*)
   578 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees lost Spy evsa)" 1);
   574 by (subgoal_tac "Key (serverK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   579 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   575 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   580 				     not_parts_not_analz]) 2);
   576 				     not_parts_not_analz]) 2);
   581 by (Fake_parts_insert_tac 1);
   577 by (Fake_parts_insert_tac 1);
   582 (*ServerFinished.  If the message is old then apply induction hypothesis...*)
   578 (*ServerFinished.  If the message is old then apply induction hypothesis...*)
   583 by (rtac conjI 1 THEN Blast_tac 2);
   579 by (rtac conjI 1 THEN Blast_tac 2);
   584 (*...otherwise delete induction hyp and use unicity of M.*)
   580 (*...otherwise delete induction hyp and use unicity of M.*)
   585 by (thin_tac "?PP-->?QQ" 1);
   581 by (thin_tac "?PP-->?QQ" 1);
   586 by (Step_tac 1);
   582 by (Step_tac 1);
   587 by (subgoal_tac "Nonce M ~: analz (sees lost Spy evsa)" 1);
   583 by (subgoal_tac "Nonce M ~: analz (sees Spy evsa)" 1);
   588 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   584 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   589 by (blast_tac (!claset addSEs [MPair_parts]
   585 by (blast_tac (!claset addSEs [MPair_parts]
   590 		       addDs  [Notes_Crypt_parts_sees,
   586 		       addDs  [Notes_Crypt_parts_sees,
   591 			       Says_imp_sees_Spy' RS parts.Inj,
   587 			       Says_imp_sees_Spy RS parts.Inj,
   592 			       unique_M]) 1);
   588 			       unique_M]) 1);
   593 qed_spec_mp "TrustServerMsg";
   589 qed_spec_mp "TrustServerMsg";
   594 
   590 
   595 
   591 
   596 (*** Protocol goal: if B receives any message encrypted with clientK
   592 (*** Protocol goal: if B receives any message encrypted with clientK
   599      CLIENT FINISHED, then B can then check the quoted values XA, XB, etc.
   595      CLIENT FINISHED, then B can then check the quoted values XA, XB, etc.
   600 ***)
   596 ***)
   601 goal thy
   597 goal thy
   602  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                         \
   598  "!!evs. [| evs : tls;  A ~: lost;  B ~: lost |]                         \
   603 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                  \
   599 \        ==> Notes A {|Agent B, Nonce M|} : set evs -->                  \
   604 \            Crypt (clientK(NA,NB,M)) Y : parts (sees lost Spy evs) -->  \
   600 \            Crypt (clientK(NA,NB,M)) Y : parts (sees Spy evs) -->  \
   605 \            Says A B (Crypt (clientK(NA,NB,M)) Y) : set evs";
   601 \            Says A B (Crypt (clientK(NA,NB,M)) Y) : set evs";
   606 by (analz_induct_tac 1);
   602 by (analz_induct_tac 1);
   607 by (REPEAT_FIRST (rtac impI));
   603 by (REPEAT_FIRST (rtac impI));
   608 (*Fake: the Spy doesn't have the critical session key!*)
   604 (*Fake: the Spy doesn't have the critical session key!*)
   609 by (subgoal_tac "Key (clientK(NA,NB,M)) ~: analz (sees lost Spy evsa)" 1);
   605 by (subgoal_tac "Key (clientK(NA,NB,M)) ~: analz (sees Spy evsa)" 1);
   610 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   606 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret, 
   611 				     not_parts_not_analz]) 2);
   607 				     not_parts_not_analz]) 2);
   612 by (Fake_parts_insert_tac 1);
   608 by (Fake_parts_insert_tac 1);
   613 (*ClientFinished.  If the message is old then apply induction hypothesis...*)
   609 (*ClientFinished.  If the message is old then apply induction hypothesis...*)
   614 by (step_tac (!claset delrules [conjI]) 1);
   610 by (step_tac (!claset delrules [conjI]) 1);
   615 by (subgoal_tac "Nonce M ~: analz (sees lost Spy evsa)" 1);
   611 by (subgoal_tac "Nonce M ~: analz (sees Spy evsa)" 1);
   616 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   612 by (asm_simp_tac (!simpset addsimps [Spy_not_see_premaster_secret]) 2);
   617 by (blast_tac (!claset addSEs [MPair_parts]
   613 by (blast_tac (!claset addSEs [MPair_parts]
   618 		       addDs  [Notes_unique_M]) 1);
   614 		       addDs  [Notes_unique_M]) 1);
   619 qed_spec_mp "TrustClientMsg";
   615 qed_spec_mp "TrustClientMsg";
   620 
   616