| author | nipkow | 
| Tue, 03 May 2005 10:25:30 +0200 | |
| changeset 15916 | 1314ef1e49dd | 
| parent 15481 | fc075ae929e4 | 
| child 16417 | 9bc16273c2d4 | 
| permissions | -rw-r--r-- | 
| 14199 | 1  | 
(* Title: HOL/Auth/SET/Purchase  | 
2  | 
ID: $Id$  | 
|
3  | 
Authors: Giampaolo Bella, Fabio Massacci, Lawrence C Paulson  | 
|
4  | 
*)  | 
|
5  | 
||
6  | 
header{*Purchase Phase of SET*}
 | 
|
7  | 
||
8  | 
theory Purchase = PublicSET:  | 
|
9  | 
||
10  | 
text{*
 | 
|
11  | 
Note: nonces seem to consist of 20 bytes. That includes both freshness  | 
|
12  | 
challenges (Chall-EE, etc.) and important secrets (CardSecret, PANsecret)  | 
|
13  | 
||
14  | 
This version omits @{text LID_C} but retains @{text LID_M}. At first glance
 | 
|
15  | 
(Programmer's Guide page 267) it seems that both numbers are just introduced  | 
|
16  | 
for the respective convenience of the Cardholder's and Merchant's  | 
|
17  | 
system. However, omitting both of them would create a problem of  | 
|
18  | 
identification: how can the Merchant's system know what transaction is it  | 
|
19  | 
supposed to process?  | 
|
20  | 
||
21  | 
Further reading (Programmer's guide page 309) suggest that there is an outside  | 
|
22  | 
bootstrapping message (SET initiation message) which is used by the Merchant  | 
|
23  | 
and the Cardholder to agree on the actual transaction. This bootstrapping  | 
|
24  | 
message is described in the SET External Interface Guide and ought to generate  | 
|
25  | 
@{text LID_M}. According SET Extern Interface Guide, this number might be a
 | 
|
26  | 
cookie, an invoice number etc. The Programmer's Guide on page 310, states that  | 
|
27  | 
in absence of @{text LID_M} the protocol must somehow ("outside SET") identify
 | 
|
28  | 
the transaction from OrderDesc, which is assumed to be a searchable text only  | 
|
29  | 
field. Thus, it is assumed that the Merchant or the Cardholder somehow agreed  | 
|
30  | 
out-of-bad on the value of @{text LID_M} (for instance a cookie in a web
 | 
|
31  | 
transaction etc.). This out-of-band agreement is expressed with a preliminary  | 
|
32  | 
start action in which the merchant and the Cardholder agree on the appropriate  | 
|
33  | 
values. Agreed values are stored with a suitable notes action.  | 
|
34  | 
||
35  | 
"XID is a transaction ID that is usually generated by the Merchant system,  | 
|
36  | 
unless there is no PInitRes, in which case it is generated by the Cardholder  | 
|
37  | 
system. It is a randomly generated 20 byte variable that is globally unique  | 
|
38  | 
(statistically). Merchant and Cardholder systems shall use appropriate random  | 
|
39  | 
number generators to ensure the global uniqueness of XID."  | 
|
40  | 
--Programmer's Guide, page 267.  | 
|
41  | 
||
42  | 
PI (Payment Instruction) is the most central and sensitive data structure in  | 
|
43  | 
SET. It is used to pass the data required to authorize a payment card payment  | 
|
44  | 
from the Cardholder to the Payment Gateway, which will use the data to  | 
|
45  | 
initiate a payment card transaction through the traditional payment card  | 
|
46  | 
financial network. The data is encrypted by the Cardholder and sent via the  | 
|
47  | 
Merchant, such that the data is hidden from the Merchant unless the Acquirer  | 
|
48  | 
passes the data back to the Merchant.  | 
|
49  | 
--Programmer's Guide, page 271.*}  | 
|
50  | 
||
51  | 
consts  | 
|
52  | 
||
53  | 
CardSecret :: "nat => nat"  | 
|
| 15481 | 54  | 
     --{*Maps Cardholders to CardSecrets.
 | 
55  | 
A CardSecret of 0 means no cerificate, must use unsigned format.*}  | 
|
| 14199 | 56  | 
|
57  | 
PANSecret :: "nat => nat"  | 
|
| 15481 | 58  | 
     --{*Maps Cardholders to PANSecrets.*}
 | 
| 14199 | 59  | 
|
60  | 
set_pur :: "event list set"  | 
|
61  | 
||
62  | 
inductive set_pur  | 
|
63  | 
intros  | 
|
64  | 
||
65  | 
  Nil:   --{*Initial trace is empty*}
 | 
|
66  | 
"[] \<in> set_pur"  | 
|
67  | 
||
68  | 
  Fake:  --{*The spy MAY say anything he CAN say.*}
 | 
|
69  | 
"[| evsf \<in> set_pur; X \<in> synth(analz(knows Spy evsf)) |]  | 
|
70  | 
==> Says Spy B X # evsf \<in> set_pur"  | 
|
71  | 
||
72  | 
||
73  | 
  Reception: --{*If A sends a message X to B, then B might receive it*}
 | 
|
74  | 
"[| evsr \<in> set_pur; Says A B X \<in> set evsr |]  | 
|
75  | 
==> Gets B X # evsr \<in> set_pur"  | 
|
76  | 
||
77  | 
Start:  | 
|
78  | 
      --{*Added start event which is out-of-band for SET: the Cardholder and
 | 
|
79  | 
	  the merchant agree on the amounts and uses @{text LID_M} as an
 | 
|
80  | 
identifier.  | 
|
81  | 
This is suggested by the External Interface Guide. The Programmer's  | 
|
82  | 
	  Guide, in absence of @{text LID_M}, states that the merchant uniquely
 | 
|
83  | 
identifies the order out of some data contained in OrderDesc.*}  | 
|
84  | 
"[|evsStart \<in> set_pur;  | 
|
85  | 
Number LID_M \<notin> used evsStart;  | 
|
86  | 
C = Cardholder k; M = Merchant i; P = PG j;  | 
|
87  | 
      Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
88  | 
LID_M \<notin> range CardSecret;  | 
|
89  | 
LID_M \<notin> range PANSecret |]  | 
|
90  | 
     ==> Notes C {|Number LID_M, Transaction|}
 | 
|
91  | 
       # Notes M {|Number LID_M, Agent P, Transaction|}
 | 
|
92  | 
# evsStart \<in> set_pur"  | 
|
93  | 
||
94  | 
PInitReq:  | 
|
95  | 
     --{*Purchase initialization, page 72 of Formal Protocol Desc.*}
 | 
|
96  | 
"[|evsPIReq \<in> set_pur;  | 
|
97  | 
      Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
98  | 
Nonce Chall_C \<notin> used evsPIReq;  | 
|
99  | 
Chall_C \<notin> range CardSecret; Chall_C \<notin> range PANSecret;  | 
|
100  | 
      Notes C {|Number LID_M, Transaction |} \<in> set evsPIReq |]
 | 
|
101  | 
    ==> Says C M {|Number LID_M, Nonce Chall_C|} # evsPIReq \<in> set_pur"
 | 
|
102  | 
||
103  | 
PInitRes:  | 
|
104  | 
     --{*Merchant replies with his own label XID and the encryption
 | 
|
105  | 
key certificate of his chosen Payment Gateway. Page 74 of Formal  | 
|
106  | 
         Protocol Desc. We use @{text LID_M} to identify Cardholder*}
 | 
|
107  | 
"[|evsPIRes \<in> set_pur;  | 
|
108  | 
      Gets M {|Number LID_M, Nonce Chall_C|} \<in> set evsPIRes;
 | 
|
109  | 
      Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
110  | 
      Notes M {|Number LID_M, Agent P, Transaction|} \<in> set evsPIRes;
 | 
|
111  | 
Nonce Chall_M \<notin> used evsPIRes;  | 
|
112  | 
Chall_M \<notin> range CardSecret; Chall_M \<notin> range PANSecret;  | 
|
113  | 
Number XID \<notin> used evsPIRes;  | 
|
114  | 
XID \<notin> range CardSecret; XID \<notin> range PANSecret|]  | 
|
115  | 
==> Says M C (sign (priSK M)  | 
|
116  | 
		       {|Number LID_M, Number XID,
 | 
|
117  | 
Nonce Chall_C, Nonce Chall_M,  | 
|
118  | 
cert P (pubEK P) onlyEnc (priSK RCA)|})  | 
|
119  | 
# evsPIRes \<in> set_pur"  | 
|
120  | 
||
121  | 
PReqUns:  | 
|
122  | 
      --{*UNSIGNED Purchase request (CardSecret = 0).
 | 
|
123  | 
Page 79 of Formal Protocol Desc.  | 
|
124  | 
Merchant never sees the amount in clear. This holds of the real  | 
|
125  | 
protocol, where XID identifies the transaction. We omit  | 
|
126  | 
	Hash{|Number XID, Nonce (CardSecret k)|} from PIHead because
 | 
|
127  | 
the CardSecret is 0 and because AuthReq treated the unsigned case  | 
|
128  | 
very differently from the signed one anyway.*}  | 
|
129  | 
"[|evsPReqU \<in> set_pur;  | 
|
130  | 
C = Cardholder k; CardSecret k = 0;  | 
|
131  | 
Key KC1 \<notin> used evsPReqU; KC1 \<in> symKeys;  | 
|
132  | 
      Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
133  | 
      HOD = Hash{|Number OrderDesc, Number PurchAmt|};
 | 
|
134  | 
      OIData = {|Number LID_M, Number XID, Nonce Chall_C, HOD,Nonce Chall_M|};
 | 
|
135  | 
      PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M|};
 | 
|
136  | 
Gets C (sign (priSK M)  | 
|
137  | 
		   {|Number LID_M, Number XID,
 | 
|
138  | 
Nonce Chall_C, Nonce Chall_M,  | 
|
139  | 
cert P EKj onlyEnc (priSK RCA)|})  | 
|
140  | 
\<in> set evsPReqU;  | 
|
141  | 
      Says C M {|Number LID_M, Nonce Chall_C|} \<in> set evsPReqU;
 | 
|
142  | 
      Notes C {|Number LID_M, Transaction|} \<in> set evsPReqU |]
 | 
|
143  | 
==> Says C M  | 
|
144  | 
	     {|EXHcrypt KC1 EKj {|PIHead, Hash OIData|} (Pan (pan C)),
 | 
|
145  | 
	       OIData, Hash{|PIHead, Pan (pan C)|} |}
 | 
|
146  | 
	  # Notes C {|Key KC1, Agent M|}
 | 
|
147  | 
# evsPReqU \<in> set_pur"  | 
|
148  | 
||
149  | 
PReqS:  | 
|
150  | 
      --{*SIGNED Purchase request.  Page 77 of Formal Protocol Desc.
 | 
|
151  | 
We could specify the equation  | 
|
152  | 
	  @{term "PIReqSigned = {| PIDualSigned, OIDualSigned |}"}, since the
 | 
|
153  | 
Formal Desc. gives PIHead the same format in the unsigned case.  | 
|
154  | 
However, there's little point, as P treats the signed and  | 
|
155  | 
unsigned cases differently.*}  | 
|
156  | 
"[|evsPReqS \<in> set_pur;  | 
|
157  | 
C = Cardholder k;  | 
|
158  | 
CardSecret k \<noteq> 0; Key KC2 \<notin> used evsPReqS; KC2 \<in> symKeys;  | 
|
159  | 
      Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
160  | 
      HOD = Hash{|Number OrderDesc, Number PurchAmt|};
 | 
|
161  | 
      OIData = {|Number LID_M, Number XID, Nonce Chall_C, HOD, Nonce Chall_M|};
 | 
|
162  | 
      PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M,
 | 
|
163  | 
		  Hash{|Number XID, Nonce (CardSecret k)|}|};
 | 
|
164  | 
      PANData = {|Pan (pan C), Nonce (PANSecret k)|};
 | 
|
165  | 
      PIData = {|PIHead, PANData|};
 | 
|
166  | 
      PIDualSigned = {|sign (priSK C) {|Hash PIData, Hash OIData|},
 | 
|
167  | 
		       EXcrypt KC2 EKj {|PIHead, Hash OIData|} PANData|};
 | 
|
168  | 
      OIDualSigned = {|OIData, Hash PIData|};
 | 
|
169  | 
Gets C (sign (priSK M)  | 
|
170  | 
		   {|Number LID_M, Number XID,
 | 
|
171  | 
Nonce Chall_C, Nonce Chall_M,  | 
|
172  | 
cert P EKj onlyEnc (priSK RCA)|})  | 
|
173  | 
\<in> set evsPReqS;  | 
|
174  | 
      Says C M {|Number LID_M, Nonce Chall_C|} \<in> set evsPReqS;
 | 
|
175  | 
      Notes C {|Number LID_M, Transaction|} \<in> set evsPReqS |]
 | 
|
176  | 
    ==> Says C M {|PIDualSigned, OIDualSigned|}
 | 
|
177  | 
	  # Notes C {|Key KC2, Agent M|}
 | 
|
178  | 
# evsPReqS \<in> set_pur"  | 
|
179  | 
||
180  | 
  --{*Authorization Request.  Page 92 of Formal Protocol Desc.
 | 
|
181  | 
Sent in response to Purchase Request.*}  | 
|
182  | 
AuthReq:  | 
|
183  | 
"[| evsAReq \<in> set_pur;  | 
|
184  | 
Key KM \<notin> used evsAReq; KM \<in> symKeys;  | 
|
185  | 
       Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
186  | 
       HOD = Hash{|Number OrderDesc, Number PurchAmt|};
 | 
|
187  | 
       OIData = {|Number LID_M, Number XID, Nonce Chall_C, HOD,
 | 
|
188  | 
Nonce Chall_M|};  | 
|
189  | 
CardSecret k \<noteq> 0 -->  | 
|
190  | 
	 P_I = {|sign (priSK C) {|HPIData, Hash OIData|}, encPANData|};
 | 
|
191  | 
       Gets M {|P_I, OIData, HPIData|} \<in> set evsAReq;
 | 
|
192  | 
       Says M C (sign (priSK M) {|Number LID_M, Number XID,
 | 
|
193  | 
Nonce Chall_C, Nonce Chall_M,  | 
|
194  | 
cert P EKj onlyEnc (priSK RCA)|})  | 
|
195  | 
\<in> set evsAReq;  | 
|
196  | 
	Notes M {|Number LID_M, Agent P, Transaction|}
 | 
|
197  | 
\<in> set evsAReq |]  | 
|
198  | 
==> Says M P  | 
|
199  | 
(EncB (priSK M) KM (pubEK P)  | 
|
200  | 
	       {|Number LID_M, Number XID, Hash OIData, HOD|}	P_I)
 | 
|
201  | 
# evsAReq \<in> set_pur"  | 
|
202  | 
||
203  | 
  --{*Authorization Response has two forms: for UNSIGNED and SIGNED PIs.
 | 
|
204  | 
Page 99 of Formal Protocol Desc.  | 
|
205  | 
    PI is a keyword (product!), so we call it @{text P_I}. The hashes HOD and
 | 
|
206  | 
    HOIData occur independently in @{text P_I} and in M's message.
 | 
|
207  | 
The authCode in AuthRes represents the baggage of EncB, which in the  | 
|
208  | 
full protocol is [CapToken], [AcqCardMsg], [AuthToken]:  | 
|
209  | 
optional items for split shipments, recurring payments, etc.*}  | 
|
210  | 
||
211  | 
AuthResUns:  | 
|
212  | 
    --{*Authorization Response, UNSIGNED*}
 | 
|
213  | 
"[| evsAResU \<in> set_pur;  | 
|
214  | 
C = Cardholder k; M = Merchant i;  | 
|
215  | 
Key KP \<notin> used evsAResU; KP \<in> symKeys;  | 
|
216  | 
CardSecret k = 0; KC1 \<in> symKeys; KM \<in> symKeys;  | 
|
217  | 
       PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M|};
 | 
|
218  | 
       P_I = EXHcrypt KC1 EKj {|PIHead, HOIData|} (Pan (pan C));
 | 
|
219  | 
Gets P (EncB (priSK M) KM (pubEK P)  | 
|
220  | 
	       {|Number LID_M, Number XID, HOIData, HOD|} P_I)
 | 
|
221  | 
\<in> set evsAResU |]  | 
|
222  | 
==> Says P M  | 
|
223  | 
(EncB (priSK P) KP (pubEK M)  | 
|
224  | 
	      {|Number LID_M, Number XID, Number PurchAmt|}
 | 
|
225  | 
authCode)  | 
|
226  | 
# evsAResU \<in> set_pur"  | 
|
227  | 
||
228  | 
AuthResS:  | 
|
229  | 
    --{*Authorization Response, SIGNED*}
 | 
|
230  | 
"[| evsAResS \<in> set_pur;  | 
|
231  | 
C = Cardholder k;  | 
|
232  | 
Key KP \<notin> used evsAResS; KP \<in> symKeys;  | 
|
233  | 
CardSecret k \<noteq> 0; KC2 \<in> symKeys; KM \<in> symKeys;  | 
|
234  | 
       P_I = {|sign (priSK C) {|Hash PIData, HOIData|},
 | 
|
235  | 
	       EXcrypt KC2 (pubEK P) {|PIHead, HOIData|} PANData|};
 | 
|
236  | 
       PANData = {|Pan (pan C), Nonce (PANSecret k)|};
 | 
|
237  | 
       PIData = {|PIHead, PANData|};
 | 
|
238  | 
       PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M,
 | 
|
239  | 
		  Hash{|Number XID, Nonce (CardSecret k)|}|};
 | 
|
240  | 
Gets P (EncB (priSK M) KM (pubEK P)  | 
|
241  | 
		{|Number LID_M, Number XID, HOIData, HOD|}
 | 
|
242  | 
P_I)  | 
|
243  | 
\<in> set evsAResS |]  | 
|
244  | 
==> Says P M  | 
|
245  | 
(EncB (priSK P) KP (pubEK M)  | 
|
246  | 
	      {|Number LID_M, Number XID, Number PurchAmt|}
 | 
|
247  | 
authCode)  | 
|
248  | 
# evsAResS \<in> set_pur"  | 
|
249  | 
||
250  | 
PRes:  | 
|
251  | 
    --{*Purchase response.*}
 | 
|
252  | 
"[| evsPRes \<in> set_pur; KP \<in> symKeys; M = Merchant i;  | 
|
253  | 
       Transaction = {|Agent M, Agent C, Number OrderDesc, Number PurchAmt|};
 | 
|
254  | 
Gets M (EncB (priSK P) KP (pubEK M)  | 
|
255  | 
	      {|Number LID_M, Number XID, Number PurchAmt|}
 | 
|
256  | 
authCode)  | 
|
257  | 
\<in> set evsPRes;  | 
|
258  | 
       Gets M {|Number LID_M, Nonce Chall_C|} \<in> set evsPRes;
 | 
|
259  | 
Says M P  | 
|
260  | 
(EncB (priSK M) KM (pubEK P)  | 
|
261  | 
	      {|Number LID_M, Number XID, Hash OIData, HOD|} P_I)
 | 
|
262  | 
\<in> set evsPRes;  | 
|
263  | 
       Notes M {|Number LID_M, Agent P, Transaction|}
 | 
|
264  | 
\<in> set evsPRes  | 
|
265  | 
|]  | 
|
266  | 
==> Says M C  | 
|
267  | 
	 (sign (priSK M) {|Number LID_M, Number XID, Nonce Chall_C,
 | 
|
268  | 
Hash (Number PurchAmt)|})  | 
|
269  | 
# evsPRes \<in> set_pur"  | 
|
270  | 
||
271  | 
||
272  | 
specification (CardSecret PANSecret)  | 
|
273  | 
inj_CardSecret: "inj CardSecret"  | 
|
274  | 
inj_PANSecret: "inj PANSecret"  | 
|
275  | 
CardSecret_neq_PANSecret: "CardSecret k \<noteq> PANSecret k'"  | 
|
276  | 
    --{*No CardSecret equals any PANSecret*}
 | 
|
277  | 
apply (rule_tac x="curry nat2_to_nat 0" in exI)  | 
|
278  | 
apply (rule_tac x="curry nat2_to_nat 1" in exI)  | 
|
279  | 
apply (simp add: nat2_to_nat_inj [THEN inj_eq] inj_on_def)  | 
|
280  | 
done  | 
|
281  | 
||
282  | 
declare Says_imp_knows_Spy [THEN parts.Inj, dest]  | 
|
283  | 
declare parts.Body [dest]  | 
|
284  | 
declare analz_into_parts [dest]  | 
|
285  | 
declare Fake_parts_insert_in_Un [dest]  | 
|
286  | 
||
287  | 
declare CardSecret_neq_PANSecret [iff]  | 
|
288  | 
CardSecret_neq_PANSecret [THEN not_sym, iff]  | 
|
289  | 
declare inj_CardSecret [THEN inj_eq, iff]  | 
|
290  | 
inj_PANSecret [THEN inj_eq, iff]  | 
|
291  | 
||
292  | 
||
293  | 
subsection{*Possibility Properties*}
 | 
|
294  | 
||
295  | 
lemma Says_to_Gets:  | 
|
296  | 
"Says A B X # evs \<in> set_pur ==> Gets B X # Says A B X # evs \<in> set_pur"  | 
|
297  | 
by (rule set_pur.Reception, auto)  | 
|
298  | 
||
| 
14206
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
299  | 
text{*Possibility for UNSIGNED purchases. Note that we need to ensure
 | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
300  | 
that XID differs from OrderDesc and PurchAmt, since it is supposed to be  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
301  | 
a unique number!*}  | 
| 14199 | 302  | 
lemma possibility_Uns:  | 
| 
14206
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
303  | 
"[| CardSecret k = 0;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
304  | 
C = Cardholder k; M = Merchant i;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
305  | 
Key KC \<notin> used []; Key KM \<notin> used []; Key KP \<notin> used [];  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
306  | 
KC \<in> symKeys; KM \<in> symKeys; KP \<in> symKeys;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
307  | 
KC < KM; KM < KP;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
308  | 
Nonce Chall_C \<notin> used []; Chall_C \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
309  | 
Nonce Chall_M \<notin> used []; Chall_M \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
310  | 
Chall_C < Chall_M;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
311  | 
Number LID_M \<notin> used []; LID_M \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
312  | 
Number XID \<notin> used []; XID \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
313  | 
LID_M < XID; XID < OrderDesc; OrderDesc < PurchAmt |]  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
314  | 
==> \<exists>evs \<in> set_pur.  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
315  | 
Says M C  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
316  | 
(sign (priSK M)  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
317  | 
                    {|Number LID_M, Number XID, Nonce Chall_C, 
 | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
318  | 
Hash (Number PurchAmt)|})  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
319  | 
\<in> set evs"  | 
| 14199 | 320  | 
apply (intro exI bexI)  | 
321  | 
apply (rule_tac [2]  | 
|
| 
14206
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
322  | 
set_pur.Nil  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
323  | 
[THEN set_pur.Start [of _ LID_M C k M i _ _ _ OrderDesc PurchAmt],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
324  | 
THEN set_pur.PInitReq [of concl: C M LID_M Chall_C],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
325  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
326  | 
THEN set_pur.PInitRes [of concl: M C LID_M XID Chall_C Chall_M],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
327  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
328  | 
THEN set_pur.PReqUns [of concl: C M KC],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
329  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
330  | 
THEN set_pur.AuthReq [of concl: M "PG j" KM LID_M XID],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
331  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
332  | 
THEN set_pur.AuthResUns [of concl: "PG j" M KP LID_M XID],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
333  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
334  | 
THEN set_pur.PRes])  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
335  | 
apply (tactic "basic_possibility_tac")  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
336  | 
apply (simp_all add: used_Cons symKeys_neq_imp_neq)  | 
| 14199 | 337  | 
done  | 
338  | 
||
339  | 
lemma possibility_S:  | 
|
| 
14206
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
340  | 
"[| CardSecret k \<noteq> 0;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
341  | 
C = Cardholder k; M = Merchant i;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
342  | 
Key KC \<notin> used []; Key KM \<notin> used []; Key KP \<notin> used [];  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
343  | 
KC \<in> symKeys; KM \<in> symKeys; KP \<in> symKeys;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
344  | 
KC < KM; KM < KP;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
345  | 
Nonce Chall_C \<notin> used []; Chall_C \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
346  | 
Nonce Chall_M \<notin> used []; Chall_M \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
347  | 
Chall_C < Chall_M;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
348  | 
Number LID_M \<notin> used []; LID_M \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
349  | 
Number XID \<notin> used []; XID \<notin> range CardSecret \<union> range PANSecret;  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
350  | 
LID_M < XID; XID < OrderDesc; OrderDesc < PurchAmt |]  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
351  | 
==> \<exists>evs \<in> set_pur.  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
352  | 
Says M C  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
353  | 
                 (sign (priSK M) {|Number LID_M, Number XID, Nonce Chall_C, 
 | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
354  | 
Hash (Number PurchAmt)|})  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
355  | 
\<in> set evs"  | 
| 14199 | 356  | 
apply (intro exI bexI)  | 
357  | 
apply (rule_tac [2]  | 
|
| 
14206
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
358  | 
set_pur.Nil  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
359  | 
[THEN set_pur.Start [of _ LID_M C k M i _ _ _ OrderDesc PurchAmt],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
360  | 
THEN set_pur.PInitReq [of concl: C M LID_M Chall_C],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
361  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
362  | 
THEN set_pur.PInitRes [of concl: M C LID_M XID Chall_C Chall_M],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
363  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
364  | 
THEN set_pur.PReqS [of concl: C M _ _ KC],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
365  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
366  | 
THEN set_pur.AuthReq [of concl: M "PG j" KM LID_M XID],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
367  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
368  | 
THEN set_pur.AuthResS [of concl: "PG j" M KP LID_M XID],  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
369  | 
THEN Says_to_Gets,  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
370  | 
THEN set_pur.PRes])  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
371  | 
apply (tactic "basic_possibility_tac")  | 
| 
 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 
paulson 
parents: 
14199 
diff
changeset
 | 
372  | 
apply (auto simp add: used_Cons symKeys_neq_imp_neq)  | 
| 14199 | 373  | 
done  | 
374  | 
||
| 15481 | 375  | 
text{*General facts about message reception*}
 | 
| 14199 | 376  | 
lemma Gets_imp_Says:  | 
377  | 
"[| Gets B X \<in> set evs; evs \<in> set_pur |]  | 
|
378  | 
==> \<exists>A. Says A B X \<in> set evs"  | 
|
379  | 
apply (erule rev_mp)  | 
|
380  | 
apply (erule set_pur.induct, auto)  | 
|
381  | 
done  | 
|
382  | 
||
383  | 
lemma Gets_imp_knows_Spy:  | 
|
384  | 
"[| Gets B X \<in> set evs; evs \<in> set_pur |] ==> X \<in> knows Spy evs"  | 
|
385  | 
by (blast dest!: Gets_imp_Says Says_imp_knows_Spy)  | 
|
386  | 
||
387  | 
declare Gets_imp_knows_Spy [THEN parts.Inj, dest]  | 
|
388  | 
||
389  | 
text{*Forwarding lemmas, to aid simplification*}
 | 
|
390  | 
||
391  | 
lemma AuthReq_msg_in_parts_spies:  | 
|
392  | 
     "[|Gets M {|P_I, OIData, HPIData|} \<in> set evs;
 | 
|
393  | 
evs \<in> set_pur|] ==> P_I \<in> parts (knows Spy evs)"  | 
|
394  | 
by auto  | 
|
395  | 
||
396  | 
lemma AuthReq_msg_in_analz_spies:  | 
|
397  | 
     "[|Gets M {|P_I, OIData, HPIData|} \<in> set evs;
 | 
|
398  | 
evs \<in> set_pur|] ==> P_I \<in> analz (knows Spy evs)"  | 
|
399  | 
by (blast dest: Gets_imp_knows_Spy [THEN analz.Inj])  | 
|
400  | 
||
401  | 
||
402  | 
subsection{*Proofs on Asymmetric Keys*}
 | 
|
403  | 
||
404  | 
text{*Private Keys are Secret*}
 | 
|
405  | 
||
406  | 
text{*Spy never sees an agent's private keys! (unless it's bad at start)*}
 | 
|
407  | 
lemma Spy_see_private_Key [simp]:  | 
|
408  | 
"evs \<in> set_pur  | 
|
409  | 
==> (Key(invKey (publicKey b A)) \<in> parts(knows Spy evs)) = (A \<in> bad)"  | 
|
410  | 
apply (erule set_pur.induct)  | 
|
411  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
412  | 
apply auto  | 
|
413  | 
done  | 
|
414  | 
declare Spy_see_private_Key [THEN [2] rev_iffD1, dest!]  | 
|
415  | 
||
416  | 
lemma Spy_analz_private_Key [simp]:  | 
|
417  | 
"evs \<in> set_pur ==>  | 
|
418  | 
(Key(invKey (publicKey b A)) \<in> analz(knows Spy evs)) = (A \<in> bad)"  | 
|
419  | 
by auto  | 
|
420  | 
declare Spy_analz_private_Key [THEN [2] rev_iffD1, dest!]  | 
|
421  | 
||
422  | 
text{*rewriting rule for priEK's*}
 | 
|
423  | 
lemma parts_image_priEK:  | 
|
424  | 
"[|Key (priEK C) \<in> parts (Key`KK Un (knows Spy evs));  | 
|
425  | 
evs \<in> set_pur|] ==> priEK C \<in> KK | C \<in> bad"  | 
|
426  | 
by auto  | 
|
427  | 
||
| 15481 | 428  | 
text{*trivial proof because @{term"priEK C"} never appears even in
 | 
429  | 
  @{term "parts evs"}. *}
 | 
|
| 14199 | 430  | 
lemma analz_image_priEK:  | 
431  | 
"evs \<in> set_pur ==>  | 
|
432  | 
(Key (priEK C) \<in> analz (Key`KK Un (knows Spy evs))) =  | 
|
433  | 
(priEK C \<in> KK | C \<in> bad)"  | 
|
434  | 
by (blast dest!: parts_image_priEK intro: analz_mono [THEN [2] rev_subsetD])  | 
|
435  | 
||
| 15481 | 436  | 
|
| 14199 | 437  | 
subsection{*Public Keys in Certificates are Correct*}
 | 
438  | 
||
439  | 
lemma Crypt_valid_pubEK [dest!]:  | 
|
440  | 
     "[| Crypt (priSK RCA) {|Agent C, Key EKi, onlyEnc|}
 | 
|
441  | 
\<in> parts (knows Spy evs);  | 
|
442  | 
evs \<in> set_pur |] ==> EKi = pubEK C"  | 
|
| 15481 | 443  | 
by (erule rev_mp, erule set_pur.induct, auto)  | 
| 14199 | 444  | 
|
445  | 
lemma Crypt_valid_pubSK [dest!]:  | 
|
446  | 
     "[| Crypt (priSK RCA) {|Agent C, Key SKi, onlySig|}
 | 
|
447  | 
\<in> parts (knows Spy evs);  | 
|
448  | 
evs \<in> set_pur |] ==> SKi = pubSK C"  | 
|
| 15481 | 449  | 
by (erule rev_mp, erule set_pur.induct, auto)  | 
| 14199 | 450  | 
|
451  | 
lemma certificate_valid_pubEK:  | 
|
452  | 
"[| cert C EKi onlyEnc (priSK RCA) \<in> parts (knows Spy evs);  | 
|
453  | 
evs \<in> set_pur |]  | 
|
454  | 
==> EKi = pubEK C"  | 
|
455  | 
by (unfold cert_def signCert_def, auto)  | 
|
456  | 
||
457  | 
lemma certificate_valid_pubSK:  | 
|
458  | 
"[| cert C SKi onlySig (priSK RCA) \<in> parts (knows Spy evs);  | 
|
459  | 
evs \<in> set_pur |] ==> SKi = pubSK C"  | 
|
460  | 
by (unfold cert_def signCert_def, auto)  | 
|
461  | 
||
462  | 
lemma Says_certificate_valid [simp]:  | 
|
463  | 
     "[| Says A B (sign SK {|lid, xid, cc, cm,
 | 
|
464  | 
cert C EK onlyEnc (priSK RCA)|}) \<in> set evs;  | 
|
465  | 
evs \<in> set_pur |]  | 
|
466  | 
==> EK = pubEK C"  | 
|
467  | 
by (unfold sign_def, auto)  | 
|
468  | 
||
469  | 
lemma Gets_certificate_valid [simp]:  | 
|
470  | 
     "[| Gets A (sign SK {|lid, xid, cc, cm,
 | 
|
471  | 
cert C EK onlyEnc (priSK RCA)|}) \<in> set evs;  | 
|
472  | 
evs \<in> set_pur |]  | 
|
473  | 
==> EK = pubEK C"  | 
|
474  | 
by (frule Gets_imp_Says, auto)  | 
|
475  | 
||
476  | 
ML  | 
|
477  | 
{*
 | 
|
478  | 
val Gets_certificate_valid = thm "Gets_certificate_valid";  | 
|
479  | 
||
480  | 
fun valid_certificate_tac i =  | 
|
481  | 
EVERY [ftac Gets_certificate_valid i,  | 
|
482  | 
assume_tac i, REPEAT (hyp_subst_tac i)];  | 
|
483  | 
*}  | 
|
484  | 
||
485  | 
||
486  | 
subsection{*Proofs on Symmetric Keys*}
 | 
|
487  | 
||
488  | 
text{*Nobody can have used non-existent keys!*}
 | 
|
489  | 
lemma new_keys_not_used [rule_format,simp]:  | 
|
490  | 
"evs \<in> set_pur  | 
|
491  | 
==> Key K \<notin> used evs --> K \<in> symKeys -->  | 
|
492  | 
K \<notin> keysFor (parts (knows Spy evs))"  | 
|
493  | 
apply (erule set_pur.induct)  | 
|
494  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
495  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
496  | 
apply auto  | 
|
497  | 
apply (force dest!: usedI keysFor_parts_insert) --{*Fake*}
 | 
|
498  | 
done  | 
|
499  | 
||
500  | 
lemma new_keys_not_analzd:  | 
|
501  | 
"[|Key K \<notin> used evs; K \<in> symKeys; evs \<in> set_pur |]  | 
|
502  | 
==> K \<notin> keysFor (analz (knows Spy evs))"  | 
|
503  | 
by (blast intro: keysFor_mono [THEN [2] rev_subsetD] dest: new_keys_not_used)  | 
|
504  | 
||
505  | 
lemma Crypt_parts_imp_used:  | 
|
506  | 
"[|Crypt K X \<in> parts (knows Spy evs);  | 
|
507  | 
K \<in> symKeys; evs \<in> set_pur |] ==> Key K \<in> used evs"  | 
|
508  | 
apply (rule ccontr)  | 
|
509  | 
apply (force dest: new_keys_not_used Crypt_imp_invKey_keysFor)  | 
|
510  | 
done  | 
|
511  | 
||
512  | 
lemma Crypt_analz_imp_used:  | 
|
513  | 
"[|Crypt K X \<in> analz (knows Spy evs);  | 
|
514  | 
K \<in> symKeys; evs \<in> set_pur |] ==> Key K \<in> used evs"  | 
|
515  | 
by (blast intro: Crypt_parts_imp_used)  | 
|
516  | 
||
517  | 
text{*New versions: as above, but generalized to have the KK argument*}
 | 
|
518  | 
||
519  | 
lemma gen_new_keys_not_used:  | 
|
520  | 
"[|Key K \<notin> used evs; K \<in> symKeys; evs \<in> set_pur |]  | 
|
521  | 
==> Key K \<notin> used evs --> K \<in> symKeys -->  | 
|
522  | 
K \<notin> keysFor (parts (Key`KK Un knows Spy evs))"  | 
|
523  | 
by auto  | 
|
524  | 
||
525  | 
lemma gen_new_keys_not_analzd:  | 
|
526  | 
"[|Key K \<notin> used evs; K \<in> symKeys; evs \<in> set_pur |]  | 
|
527  | 
==> K \<notin> keysFor (analz (Key`KK Un knows Spy evs))"  | 
|
528  | 
by (blast intro: keysFor_mono [THEN subsetD] dest: gen_new_keys_not_used)  | 
|
529  | 
||
530  | 
lemma analz_Key_image_insert_eq:  | 
|
531  | 
"[|Key K \<notin> used evs; K \<in> symKeys; evs \<in> set_pur |]  | 
|
532  | 
==> analz (Key ` (insert K KK) \<union> knows Spy evs) =  | 
|
533  | 
insert (Key K) (analz (Key ` KK \<union> knows Spy evs))"  | 
|
534  | 
by (simp add: gen_new_keys_not_analzd)  | 
|
535  | 
||
536  | 
||
537  | 
subsection{*Secrecy of Symmetric Keys*}
 | 
|
538  | 
||
539  | 
lemma Key_analz_image_Key_lemma:  | 
|
540  | 
"P --> (Key K \<in> analz (Key`KK Un H)) --> (K\<in>KK | Key K \<in> analz H)  | 
|
541  | 
==>  | 
|
542  | 
P --> (Key K \<in> analz (Key`KK Un H)) = (K\<in>KK | Key K \<in> analz H)"  | 
|
543  | 
by (blast intro: analz_mono [THEN [2] rev_subsetD])  | 
|
544  | 
||
545  | 
||
546  | 
lemma symKey_compromise:  | 
|
| 15205 | 547  | 
"evs \<in> set_pur \<Longrightarrow>  | 
| 14199 | 548  | 
(\<forall>SK KK. SK \<in> symKeys \<longrightarrow>  | 
| 15205 | 549  | 
(\<forall>K \<in> KK. K \<notin> range(\<lambda>C. priEK C)) \<longrightarrow>  | 
550  | 
(Key SK \<in> analz (Key`KK \<union> (knows Spy evs))) =  | 
|
551  | 
(SK \<in> KK \<or> Key SK \<in> analz (knows Spy evs)))"  | 
|
| 14199 | 552  | 
apply (erule set_pur.induct)  | 
553  | 
apply (rule_tac [!] allI)+  | 
|
554  | 
apply (rule_tac [!] impI [THEN Key_analz_image_Key_lemma, THEN impI])+  | 
|
555  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies) --{*AReq*}
 | 
|
556  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
557  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
558  | 
apply (simp_all  | 
|
559  | 
del: image_insert image_Un imp_disjL  | 
|
560  | 
add: analz_image_keys_simps disj_simps  | 
|
561  | 
analz_Key_image_insert_eq notin_image_iff  | 
|
562  | 
analz_insert_simps analz_image_priEK)  | 
|
563  | 
  --{*35 seconds on a 1.8GHz machine*}
 | 
|
564  | 
apply spy_analz --{*Fake*}
 | 
|
565  | 
apply (blast elim!: ballE)+ --{*PReq: unsigned and signed*}
 | 
|
566  | 
done  | 
|
567  | 
||
568  | 
||
569  | 
||
570  | 
subsection{*Secrecy of Nonces*}
 | 
|
571  | 
||
572  | 
text{*As usual: we express the property as a logical equivalence*}
 | 
|
573  | 
lemma Nonce_analz_image_Key_lemma:  | 
|
574  | 
"P --> (Nonce N \<in> analz (Key`KK Un H)) --> (Nonce N \<in> analz H)  | 
|
575  | 
==> P --> (Nonce N \<in> analz (Key`KK Un H)) = (Nonce N \<in> analz H)"  | 
|
576  | 
by (blast intro: analz_mono [THEN [2] rev_subsetD])  | 
|
577  | 
||
578  | 
text{*The @{text "(no_asm)"} attribute is essential, since it retains
 | 
|
579  | 
the quantifier and allows the simprule's condition to itself be simplified.*}  | 
|
580  | 
lemma Nonce_compromise [rule_format (no_asm)]:  | 
|
581  | 
"evs \<in> set_pur ==>  | 
|
582  | 
(\<forall>N KK. (\<forall>K \<in> KK. K \<notin> range(\<lambda>C. priEK C)) -->  | 
|
| 14256 | 583  | 
(Nonce N \<in> analz (Key`KK \<union> (knows Spy evs))) =  | 
| 14199 | 584  | 
(Nonce N \<in> analz (knows Spy evs)))"  | 
585  | 
apply (erule set_pur.induct)  | 
|
586  | 
apply (rule_tac [!] allI)+  | 
|
587  | 
apply (rule_tac [!] impI [THEN Nonce_analz_image_Key_lemma])+  | 
|
588  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies) --{*AReq*}
 | 
|
589  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
590  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
591  | 
apply (simp_all  | 
|
592  | 
del: image_insert image_Un imp_disjL  | 
|
593  | 
add: analz_image_keys_simps disj_simps symKey_compromise  | 
|
594  | 
analz_Key_image_insert_eq notin_image_iff  | 
|
595  | 
analz_insert_simps analz_image_priEK)  | 
|
596  | 
  --{*35 seconds on a 1.8GHz machine*}
 | 
|
597  | 
apply spy_analz --{*Fake*}
 | 
|
598  | 
apply (blast elim!: ballE) --{*PReqS*}
 | 
|
599  | 
done  | 
|
600  | 
||
601  | 
lemma PANSecret_notin_spies:  | 
|
| 14256 | 602  | 
"[|Nonce (PANSecret k) \<in> analz (knows Spy evs); evs \<in> set_pur|]  | 
603  | 
==>  | 
|
| 14199 | 604  | 
(\<exists>V W X Y KC2 M. \<exists>P \<in> bad.  | 
605  | 
Says (Cardholder k) M  | 
|
606  | 
               {|{|W, EXcrypt KC2 (pubEK P) X {|Y, Nonce (PANSecret k)|}|},
 | 
|
607  | 
V|} \<in> set evs)"  | 
|
| 14256 | 608  | 
apply (erule rev_mp)  | 
| 14199 | 609  | 
apply (erule set_pur.induct)  | 
610  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies)  | 
|
611  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
612  | 
apply (simp_all  | 
|
613  | 
del: image_insert image_Un imp_disjL  | 
|
614  | 
add: analz_image_keys_simps disj_simps  | 
|
615  | 
symKey_compromise pushes sign_def Nonce_compromise  | 
|
616  | 
analz_Key_image_insert_eq notin_image_iff  | 
|
617  | 
analz_insert_simps analz_image_priEK)  | 
|
618  | 
  --{*13 seconds on a 1.8GHz machine*}
 | 
|
619  | 
apply spy_analz  | 
|
620  | 
apply (blast dest!: Gets_imp_knows_Spy [THEN analz.Inj])  | 
|
621  | 
apply (blast dest: Says_imp_knows_Spy [THEN analz.Inj]  | 
|
622  | 
Gets_imp_knows_Spy [THEN analz.Inj])  | 
|
623  | 
apply (blast dest: Gets_imp_knows_Spy [THEN analz.Inj]) --{*PReqS*}
 | 
|
624  | 
apply (blast dest: Says_imp_knows_Spy [THEN analz.Inj]  | 
|
625  | 
                   Gets_imp_knows_Spy [THEN analz.Inj]) --{*PRes*}
 | 
|
626  | 
done  | 
|
627  | 
||
628  | 
text{*This theorem is a bit silly, in that many CardSecrets are 0!
 | 
|
629  | 
But then we don't care. NOT USED*}  | 
|
630  | 
lemma CardSecret_notin_spies:  | 
|
631  | 
"evs \<in> set_pur ==> Nonce (CardSecret i) \<notin> parts (knows Spy evs)"  | 
|
632  | 
by (erule set_pur.induct, auto)  | 
|
633  | 
||
| 15214 | 634  | 
|
| 14199 | 635  | 
subsection{*Confidentiality of PAN*}
 | 
636  | 
||
637  | 
lemma analz_image_pan_lemma:  | 
|
638  | 
"(Pan P \<in> analz (Key`nE Un H)) --> (Pan P \<in> analz H) ==>  | 
|
639  | 
(Pan P \<in> analz (Key`nE Un H)) = (Pan P \<in> analz H)"  | 
|
640  | 
by (blast intro: analz_mono [THEN [2] rev_subsetD])  | 
|
641  | 
||
642  | 
text{*The @{text "(no_asm)"} attribute is essential, since it retains
 | 
|
643  | 
the quantifier and allows the simprule's condition to itself be simplified.*}  | 
|
644  | 
lemma analz_image_pan [rule_format (no_asm)]:  | 
|
645  | 
"evs \<in> set_pur ==>  | 
|
646  | 
\<forall>KK. (\<forall>K \<in> KK. K \<notin> range(\<lambda>C. priEK C)) -->  | 
|
647  | 
(Pan P \<in> analz (Key`KK Un (knows Spy evs))) =  | 
|
648  | 
(Pan P \<in> analz (knows Spy evs))"  | 
|
649  | 
apply (erule set_pur.induct)  | 
|
650  | 
apply (rule_tac [!] allI impI)+  | 
|
651  | 
apply (rule_tac [!] analz_image_pan_lemma)+  | 
|
652  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies) --{*AReq*}
 | 
|
653  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
654  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
655  | 
apply (simp_all  | 
|
656  | 
del: image_insert image_Un imp_disjL  | 
|
657  | 
add: analz_image_keys_simps  | 
|
658  | 
symKey_compromise pushes sign_def  | 
|
659  | 
analz_Key_image_insert_eq notin_image_iff  | 
|
660  | 
analz_insert_simps analz_image_priEK)  | 
|
661  | 
  --{*32 seconds on a 1.8GHz machine*}
 | 
|
662  | 
apply spy_analz --{*Fake*}
 | 
|
663  | 
apply auto  | 
|
664  | 
done  | 
|
665  | 
||
666  | 
lemma analz_insert_pan:  | 
|
667  | 
"[| evs \<in> set_pur; K \<notin> range(\<lambda>C. priEK C) |] ==>  | 
|
668  | 
(Pan P \<in> analz (insert (Key K) (knows Spy evs))) =  | 
|
669  | 
(Pan P \<in> analz (knows Spy evs))"  | 
|
670  | 
by (simp del: image_insert image_Un  | 
|
671  | 
add: analz_image_keys_simps analz_image_pan)  | 
|
672  | 
||
673  | 
text{*Confidentiality of the PAN, unsigned case.*}
 | 
|
| 15214 | 674  | 
theorem pan_confidentiality_unsigned:  | 
| 14199 | 675  | 
"[| Pan (pan C) \<in> analz(knows Spy evs); C = Cardholder k;  | 
676  | 
CardSecret k = 0; evs \<in> set_pur|]  | 
|
677  | 
==> \<exists>P M KC1 K X Y.  | 
|
678  | 
     Says C M {|EXHcrypt KC1 (pubEK P) X (Pan (pan C)), Y|}
 | 
|
679  | 
\<in> set evs &  | 
|
680  | 
P \<in> bad"  | 
|
681  | 
apply (erule rev_mp)  | 
|
682  | 
apply (erule set_pur.induct)  | 
|
683  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies) --{*AReq*}
 | 
|
684  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
685  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
686  | 
apply (simp_all  | 
|
687  | 
del: image_insert image_Un imp_disjL  | 
|
688  | 
add: analz_image_keys_simps analz_insert_pan analz_image_pan  | 
|
689  | 
notin_image_iff  | 
|
690  | 
analz_insert_simps analz_image_priEK)  | 
|
691  | 
  --{*15 seconds on a 1.8GHz machine*}
 | 
|
692  | 
apply spy_analz --{*Fake*}
 | 
|
693  | 
apply blast --{*PReqUns: unsigned*}
 | 
|
694  | 
apply force --{*PReqS: signed*}
 | 
|
695  | 
done  | 
|
696  | 
||
697  | 
text{*Confidentiality of the PAN, signed case.*}
 | 
|
| 15214 | 698  | 
theorem pan_confidentiality_signed:  | 
699  | 
"[|Pan (pan C) \<in> analz(knows Spy evs); C = Cardholder k;  | 
|
700  | 
CardSecret k \<noteq> 0; evs \<in> set_pur|]  | 
|
701  | 
==> \<exists>P M KC2 PIDualSign_1 PIDualSign_2 other OIDualSign.  | 
|
702  | 
      Says C M {|{|PIDualSign_1, 
 | 
|
703  | 
                   EXcrypt KC2 (pubEK P) PIDualSign_2 {|Pan (pan C), other|}|}, 
 | 
|
704  | 
OIDualSign|} \<in> set evs & P \<in> bad"  | 
|
| 14199 | 705  | 
apply (erule rev_mp)  | 
706  | 
apply (erule set_pur.induct)  | 
|
707  | 
apply (frule_tac [9] AuthReq_msg_in_analz_spies) --{*AReq*}
 | 
|
708  | 
apply (tactic{*valid_certificate_tac 8*}) --{*PReqS*}
 | 
|
709  | 
apply (tactic{*valid_certificate_tac 7*}) --{*PReqUns*}
 | 
|
710  | 
apply (simp_all  | 
|
711  | 
del: image_insert image_Un imp_disjL  | 
|
712  | 
add: analz_image_keys_simps analz_insert_pan analz_image_pan  | 
|
713  | 
notin_image_iff  | 
|
714  | 
analz_insert_simps analz_image_priEK)  | 
|
715  | 
  --{*17 seconds on a 1.8GHz machine*}
 | 
|
716  | 
apply spy_analz --{*Fake*}
 | 
|
717  | 
apply force --{*PReqUns: unsigned*}
 | 
|
718  | 
apply blast --{*PReqS: signed*}
 | 
|
719  | 
done  | 
|
720  | 
||
721  | 
text{*General goal: that C, M and PG agree on those details of the transaction
 | 
|
722  | 
that they are allowed to know about. PG knows about price and account  | 
|
723  | 
details. M knows about the order description and price. C knows both.*}  | 
|
724  | 
||
725  | 
||
726  | 
subsection{*Proofs Common to Signed and Unsigned Versions*}
 | 
|
727  | 
||
728  | 
lemma M_Notes_PG:  | 
|
729  | 
     "[|Notes M {|Number LID_M, Agent P, Agent M, Agent C, etc|} \<in> set evs;
 | 
|
730  | 
evs \<in> set_pur|] ==> \<exists>j. P = PG j"  | 
|
| 15481 | 731  | 
by (erule rev_mp, erule set_pur.induct, simp_all)  | 
| 14199 | 732  | 
|
733  | 
text{*If we trust M, then @{term LID_M} determines his choice of P
 | 
|
734  | 
(Payment Gateway)*}  | 
|
735  | 
lemma goodM_gives_correct_PG:  | 
|
736  | 
"[| MsgPInitRes =  | 
|
737  | 
            {|Number LID_M, xid, cc, cm, cert P EKj onlyEnc (priSK RCA)|};
 | 
|
738  | 
Crypt (priSK M) (Hash MsgPInitRes) \<in> parts (knows Spy evs);  | 
|
739  | 
evs \<in> set_pur; M \<notin> bad |]  | 
|
740  | 
==> \<exists>j trans.  | 
|
741  | 
P = PG j &  | 
|
742  | 
            Notes M {|Number LID_M, Agent P, trans|} \<in> set evs"
 | 
|
743  | 
apply clarify  | 
|
744  | 
apply (erule rev_mp)  | 
|
745  | 
apply (erule set_pur.induct)  | 
|
746  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
747  | 
apply simp_all  | 
|
748  | 
apply (blast intro: M_Notes_PG)+  | 
|
749  | 
done  | 
|
750  | 
||
751  | 
lemma C_gets_correct_PG:  | 
|
752  | 
     "[| Gets A (sign (priSK M) {|Number LID_M, xid, cc, cm,
 | 
|
753  | 
cert P EKj onlyEnc (priSK RCA)|}) \<in> set evs;  | 
|
754  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
755  | 
==> \<exists>j trans.  | 
|
756  | 
P = PG j &  | 
|
757  | 
            Notes M {|Number LID_M, Agent P, trans|} \<in> set evs &
 | 
|
758  | 
EKj = pubEK P"  | 
|
759  | 
by (rule refl [THEN goodM_gives_correct_PG, THEN exE], auto)  | 
|
760  | 
||
761  | 
text{*When C receives PInitRes, he learns M's choice of P*}
 | 
|
762  | 
lemma C_verifies_PInitRes:  | 
|
763  | 
 "[| MsgPInitRes = {|Number LID_M, Number XID, Nonce Chall_C, Nonce Chall_M,
 | 
|
764  | 
cert P EKj onlyEnc (priSK RCA)|};  | 
|
765  | 
Crypt (priSK M) (Hash MsgPInitRes) \<in> parts (knows Spy evs);  | 
|
766  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
767  | 
==> \<exists>j trans.  | 
|
768  | 
         Notes M {|Number LID_M, Agent P, trans|} \<in> set evs &
 | 
|
769  | 
P = PG j &  | 
|
770  | 
EKj = pubEK P"  | 
|
771  | 
apply clarify  | 
|
772  | 
apply (erule rev_mp)  | 
|
773  | 
apply (erule set_pur.induct)  | 
|
774  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
775  | 
apply simp_all  | 
|
776  | 
apply (blast intro: M_Notes_PG)+  | 
|
777  | 
done  | 
|
778  | 
||
779  | 
text{*Corollary of previous one*}
 | 
|
780  | 
lemma Says_C_PInitRes:  | 
|
781  | 
"[|Says A C (sign (priSK M)  | 
|
782  | 
                      {|Number LID_M, Number XID,
 | 
|
783  | 
Nonce Chall_C, Nonce Chall_M,  | 
|
784  | 
cert P EKj onlyEnc (priSK RCA)|})  | 
|
785  | 
\<in> set evs; M \<notin> bad; evs \<in> set_pur|]  | 
|
786  | 
==> \<exists>j trans.  | 
|
787  | 
           Notes M {|Number LID_M, Agent P, trans|} \<in> set evs &
 | 
|
788  | 
P = PG j &  | 
|
789  | 
EKj = pubEK (PG j)"  | 
|
790  | 
apply (frule Says_certificate_valid)  | 
|
791  | 
apply (auto simp add: sign_def)  | 
|
792  | 
apply (blast dest: refl [THEN goodM_gives_correct_PG])  | 
|
793  | 
apply (blast dest: refl [THEN C_verifies_PInitRes])  | 
|
794  | 
done  | 
|
795  | 
||
796  | 
text{*When P receives an AuthReq, he knows that the signed part originated 
 | 
|
797  | 
with M. PIRes also has a signed message from M....*}  | 
|
798  | 
lemma P_verifies_AuthReq:  | 
|
799  | 
     "[| AuthReqData = {|Number LID_M, Number XID, HOIData, HOD|};
 | 
|
800  | 
         Crypt (priSK M) (Hash {|AuthReqData, Hash P_I|})
 | 
|
801  | 
\<in> parts (knows Spy evs);  | 
|
802  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
803  | 
==> \<exists>j trans KM OIData HPIData.  | 
|
804  | 
            Notes M {|Number LID_M, Agent (PG j), trans|} \<in> set evs &
 | 
|
805  | 
            Gets M {|P_I, OIData, HPIData|} \<in> set evs &
 | 
|
806  | 
Says M (PG j) (EncB (priSK M) KM (pubEK (PG j)) AuthReqData P_I)  | 
|
807  | 
\<in> set evs"  | 
|
808  | 
apply clarify  | 
|
809  | 
apply (erule rev_mp)  | 
|
810  | 
apply (erule set_pur.induct, simp_all)  | 
|
811  | 
apply (frule_tac [4] M_Notes_PG, auto)  | 
|
812  | 
done  | 
|
813  | 
||
814  | 
text{*When M receives AuthRes, he knows that P signed it, including
 | 
|
| 15481 | 815  | 
the identifying tags and the purchase amount, which he can verify.  | 
| 14199 | 816  | 
(Although the spec has SIGNED and UNSIGNED forms of AuthRes, they  | 
817  | 
send the same message to M.)*}  | 
|
| 15214 | 818  | 
theorem M_verifies_AuthRes:  | 
| 14199 | 819  | 
  "[| MsgAuthRes = {|Number LID_M, Number XID, Number PurchAmt|};
 | 
820  | 
Crypt (priSK (PG j)) (Hash MsgAuthRes) \<in> parts (knows Spy evs);  | 
|
821  | 
evs \<in> set_pur; PG j \<notin> bad|]  | 
|
822  | 
==> \<exists>i KM HOIData HOD P_I.  | 
|
823  | 
Gets (PG j)  | 
|
824  | 
(EncB (priSK (Merchant i)) KM (pubEK (PG j))  | 
|
825  | 
		    {|Number LID_M, Number XID, HOIData, HOD|}
 | 
|
826  | 
P_I) \<in> set evs &  | 
|
827  | 
Says (PG j) (Merchant i)  | 
|
828  | 
(Crypt (pubEK (Merchant i)) (sign (priSK (PG j)) MsgAuthRes))  | 
|
829  | 
\<in> set evs"  | 
|
830  | 
apply clarify  | 
|
831  | 
apply (erule rev_mp)  | 
|
832  | 
apply (erule set_pur.induct)  | 
|
833  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
834  | 
apply simp_all  | 
|
835  | 
apply blast+  | 
|
836  | 
done  | 
|
837  | 
||
838  | 
||
839  | 
subsection{*Proofs for Unsigned Purchases*}
 | 
|
840  | 
||
841  | 
text{*What we can derive from the ASSUMPTION that C issued a purchase request.
 | 
|
842  | 
In the unsigned case, we must trust "C": there's no authentication.*}  | 
|
843  | 
lemma C_determines_EKj:  | 
|
844  | 
     "[| Says C M {|EXHcrypt KC1 EKj {|PIHead, Hash OIData|} (Pan (pan C)),
 | 
|
845  | 
                    OIData, Hash{|PIHead, Pan (pan C)|} |} \<in> set evs;
 | 
|
846  | 
         PIHead = {|Number LID_M, Trans_details|};
 | 
|
847  | 
evs \<in> set_pur; C = Cardholder k; M \<notin> bad|]  | 
|
848  | 
==> \<exists>trans j.  | 
|
849  | 
               Notes M {|Number LID_M, Agent (PG j), trans |} \<in> set evs &
 | 
|
850  | 
EKj = pubEK (PG j)"  | 
|
851  | 
apply clarify  | 
|
852  | 
apply (erule rev_mp)  | 
|
853  | 
apply (erule set_pur.induct, simp_all)  | 
|
854  | 
apply (tactic{*valid_certificate_tac 2*}) --{*PReqUns*}
 | 
|
855  | 
apply auto  | 
|
856  | 
apply (blast dest: Gets_imp_Says Says_C_PInitRes)  | 
|
857  | 
done  | 
|
858  | 
||
859  | 
||
860  | 
text{*Unicity of @{term LID_M} between Merchant and Cardholder notes*}
 | 
|
861  | 
lemma unique_LID_M:  | 
|
862  | 
     "[|Notes (Merchant i) {|Number LID_M, Agent P, Trans|} \<in> set evs;
 | 
|
863  | 
        Notes C {|Number LID_M, Agent M, Agent C, Number OD,
 | 
|
864  | 
Number PA|} \<in> set evs;  | 
|
865  | 
evs \<in> set_pur|]  | 
|
866  | 
      ==> M = Merchant i & Trans = {|Agent M, Agent C, Number OD, Number PA|}"
 | 
|
867  | 
apply (erule rev_mp)  | 
|
868  | 
apply (erule rev_mp)  | 
|
869  | 
apply (erule set_pur.induct, simp_all)  | 
|
870  | 
apply (force dest!: Notes_imp_parts_subset_used)  | 
|
871  | 
done  | 
|
872  | 
||
873  | 
text{*Unicity of @{term LID_M}, for two Merchant Notes events*}
 | 
|
874  | 
lemma unique_LID_M2:  | 
|
875  | 
     "[|Notes M {|Number LID_M, Trans|} \<in> set evs;
 | 
|
876  | 
        Notes M {|Number LID_M, Trans'|} \<in> set evs;
 | 
|
877  | 
evs \<in> set_pur|] ==> Trans' = Trans"  | 
|
878  | 
apply (erule rev_mp)  | 
|
879  | 
apply (erule rev_mp)  | 
|
880  | 
apply (erule set_pur.induct, simp_all)  | 
|
881  | 
apply (force dest!: Notes_imp_parts_subset_used)  | 
|
882  | 
done  | 
|
883  | 
||
884  | 
text{*Lemma needed below: for the case that
 | 
|
885  | 
  if PRes is present, then @{term LID_M} has been used.*}
 | 
|
886  | 
lemma signed_imp_used:  | 
|
887  | 
"[| Crypt (priSK M) (Hash X) \<in> parts (knows Spy evs);  | 
|
888  | 
         M \<notin> bad;  evs \<in> set_pur|] ==> parts {X} \<subseteq> used evs"
 | 
|
889  | 
apply (erule rev_mp)  | 
|
890  | 
apply (erule set_pur.induct)  | 
|
891  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
892  | 
apply simp_all  | 
|
893  | 
apply safe  | 
|
894  | 
apply blast+  | 
|
895  | 
done  | 
|
896  | 
||
897  | 
text{*Similar, with nested Hash*}
 | 
|
898  | 
lemma signed_Hash_imp_used:  | 
|
899  | 
     "[| Crypt (priSK C) (Hash {|H, Hash X|}) \<in> parts (knows Spy evs);
 | 
|
900  | 
         C \<notin> bad;  evs \<in> set_pur|] ==> parts {X} \<subseteq> used evs"
 | 
|
901  | 
apply (erule rev_mp)  | 
|
902  | 
apply (erule set_pur.induct)  | 
|
903  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
904  | 
apply simp_all  | 
|
905  | 
apply safe  | 
|
906  | 
apply blast+  | 
|
907  | 
done  | 
|
908  | 
||
909  | 
text{*Lemma needed below: for the case that
 | 
|
910  | 
  if PRes is present, then @{text LID_M} has been used.*}
 | 
|
911  | 
lemma PRes_imp_LID_used:  | 
|
912  | 
     "[| Crypt (priSK M) (Hash {|N, X|}) \<in> parts (knows Spy evs);
 | 
|
913  | 
M \<notin> bad; evs \<in> set_pur|] ==> N \<in> used evs"  | 
|
914  | 
by (drule signed_imp_used, auto)  | 
|
915  | 
||
916  | 
text{*When C receives PRes, he knows that M and P agreed to the purchase details.
 | 
|
917  | 
He also knows that P is the same PG as before*}  | 
|
918  | 
lemma C_verifies_PRes_lemma:  | 
|
919  | 
"[| Crypt (priSK M) (Hash MsgPRes) \<in> parts (knows Spy evs);  | 
|
920  | 
         Notes C {|Number LID_M, Trans |} \<in> set evs;
 | 
|
921  | 
         Trans = {| Agent M, Agent C, Number OrderDesc, Number PurchAmt |};
 | 
|
922  | 
         MsgPRes = {|Number LID_M, Number XID, Nonce Chall_C,
 | 
|
923  | 
Hash (Number PurchAmt)|};  | 
|
924  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
925  | 
==> \<exists>j KP.  | 
|
926  | 
        Notes M {|Number LID_M, Agent (PG j), Trans |}
 | 
|
927  | 
\<in> set evs &  | 
|
928  | 
Gets M (EncB (priSK (PG j)) KP (pubEK M)  | 
|
929  | 
                {|Number LID_M, Number XID, Number PurchAmt|}
 | 
|
930  | 
authCode)  | 
|
931  | 
\<in> set evs &  | 
|
932  | 
Says M C (sign (priSK M) MsgPRes) \<in> set evs"  | 
|
933  | 
apply clarify  | 
|
934  | 
apply (erule rev_mp)  | 
|
935  | 
apply (erule rev_mp)  | 
|
936  | 
apply (erule set_pur.induct)  | 
|
937  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
938  | 
apply simp_all  | 
|
939  | 
apply blast  | 
|
940  | 
apply blast  | 
|
941  | 
apply (blast dest: PRes_imp_LID_used)  | 
|
942  | 
apply (frule M_Notes_PG, auto)  | 
|
943  | 
apply (blast dest: unique_LID_M)  | 
|
944  | 
done  | 
|
945  | 
||
| 15214 | 946  | 
text{*When the Cardholder receives Purchase Response from an uncompromised
 | 
947  | 
Merchant, he knows that M sent it. He also knows that M received a message signed  | 
|
948  | 
by a Payment Gateway chosen by M to authorize the purchase.*}  | 
|
949  | 
theorem C_verifies_PRes:  | 
|
| 14199 | 950  | 
     "[| MsgPRes = {|Number LID_M, Number XID, Nonce Chall_C,
 | 
951  | 
Hash (Number PurchAmt)|};  | 
|
952  | 
Gets C (sign (priSK M) MsgPRes) \<in> set evs;  | 
|
953  | 
         Notes C {|Number LID_M, Agent M, Agent C, Number OrderDesc,
 | 
|
954  | 
Number PurchAmt|} \<in> set evs;  | 
|
955  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
956  | 
==> \<exists>P KP trans.  | 
|
957  | 
        Notes M {|Number LID_M,Agent P, trans|} \<in> set evs &
 | 
|
958  | 
Gets M (EncB (priSK P) KP (pubEK M)  | 
|
959  | 
                {|Number LID_M, Number XID, Number PurchAmt|}
 | 
|
| 15214 | 960  | 
authCode) \<in> set evs &  | 
| 14199 | 961  | 
Says M C (sign (priSK M) MsgPRes) \<in> set evs"  | 
962  | 
apply (rule C_verifies_PRes_lemma [THEN exE])  | 
|
963  | 
apply (auto simp add: sign_def)  | 
|
964  | 
done  | 
|
965  | 
||
966  | 
subsection{*Proofs for Signed Purchases*}
 | 
|
967  | 
||
968  | 
text{*Some Useful Lemmas: the cardholder knows what he is doing*}
 | 
|
969  | 
||
970  | 
lemma Crypt_imp_Says_Cardholder:  | 
|
971  | 
     "[| Crypt K {|{|{|Number LID_M, others|}, Hash OIData|}, Hash PANData|}
 | 
|
972  | 
\<in> parts (knows Spy evs);  | 
|
973  | 
         PANData = {|Pan (pan (Cardholder k)), Nonce (PANSecret k)|};
 | 
|
974  | 
Key K \<notin> analz (knows Spy evs);  | 
|
975  | 
evs \<in> set_pur|]  | 
|
976  | 
==> \<exists>M shash EK HPIData.  | 
|
977  | 
       Says (Cardholder k) M {|{|shash,
 | 
|
978  | 
Crypt K  | 
|
979  | 
            {|{|{|Number LID_M, others|}, Hash OIData|}, Hash PANData|},
 | 
|
980  | 
           Crypt EK {|Key K, PANData|}|},
 | 
|
981  | 
OIData, HPIData|} \<in> set evs"  | 
|
982  | 
apply (erule rev_mp)  | 
|
983  | 
apply (erule rev_mp)  | 
|
984  | 
apply (erule rev_mp)  | 
|
985  | 
apply (erule set_pur.induct, analz_mono_contra)  | 
|
986  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
987  | 
apply simp_all  | 
|
988  | 
apply auto  | 
|
989  | 
done  | 
|
990  | 
||
991  | 
lemma Says_PReqS_imp_trans_details_C:  | 
|
992  | 
     "[| MsgPReqS = {|{|shash,
 | 
|
993  | 
Crypt K  | 
|
994  | 
                  {|{|{|Number LID_M, PIrest|}, Hash OIData|}, hashpd|},
 | 
|
995  | 
cryptek|}, data|};  | 
|
996  | 
Says (Cardholder k) M MsgPReqS \<in> set evs;  | 
|
997  | 
evs \<in> set_pur |]  | 
|
998  | 
==> \<exists>trans.  | 
|
999  | 
Notes (Cardholder k)  | 
|
1000  | 
                 {|Number LID_M, Agent M, Agent (Cardholder k), trans|}
 | 
|
1001  | 
\<in> set evs"  | 
|
1002  | 
apply (erule rev_mp)  | 
|
1003  | 
apply (erule rev_mp)  | 
|
1004  | 
apply (erule set_pur.induct)  | 
|
1005  | 
apply (simp_all (no_asm_simp))  | 
|
1006  | 
apply auto  | 
|
1007  | 
done  | 
|
1008  | 
||
1009  | 
text{*Can't happen: only Merchants create this type of Note*}
 | 
|
1010  | 
lemma Notes_Cardholder_self_False:  | 
|
1011  | 
"[|Notes (Cardholder k)  | 
|
1012  | 
          {|Number n, Agent P, Agent (Cardholder k), Agent C, etc|} \<in> set evs;
 | 
|
1013  | 
evs \<in> set_pur|] ==> False"  | 
|
| 15481 | 1014  | 
by (erule rev_mp, erule set_pur.induct, auto)  | 
| 14199 | 1015  | 
|
1016  | 
text{*When M sees a dual signature, he knows that it originated with C.
 | 
|
1017  | 
Using XID he knows it was intended for him.  | 
|
1018  | 
This guarantee isn't useful to P, who never gets OIData.*}  | 
|
| 15214 | 1019  | 
theorem M_verifies_Signed_PReq:  | 
1020  | 
 "[| MsgDualSign = {|HPIData, Hash OIData|};
 | 
|
1021  | 
     OIData = {|Number LID_M, etc|};
 | 
|
1022  | 
Crypt (priSK C) (Hash MsgDualSign) \<in> parts (knows Spy evs);  | 
|
1023  | 
     Notes M {|Number LID_M, Agent P, extras|} \<in> set evs;
 | 
|
1024  | 
M = Merchant i; C = Cardholder k; C \<notin> bad; evs \<in> set_pur|]  | 
|
1025  | 
==> \<exists>PIData PICrypt.  | 
|
1026  | 
HPIData = Hash PIData &  | 
|
1027  | 
	Says C M {|{|sign (priSK C) MsgDualSign, PICrypt|}, OIData, Hash PIData|}
 | 
|
1028  | 
\<in> set evs"  | 
|
| 14199 | 1029  | 
apply clarify  | 
1030  | 
apply (erule rev_mp)  | 
|
1031  | 
apply (erule rev_mp)  | 
|
1032  | 
apply (erule set_pur.induct)  | 
|
1033  | 
apply (frule_tac [9] AuthReq_msg_in_parts_spies) --{*AuthReq*}
 | 
|
1034  | 
apply simp_all  | 
|
1035  | 
apply blast  | 
|
1036  | 
apply (force dest!: signed_Hash_imp_used)  | 
|
1037  | 
apply (clarify) --{*speeds next step*}
 | 
|
1038  | 
apply (blast dest: unique_LID_M)  | 
|
1039  | 
apply (blast dest!: Notes_Cardholder_self_False)  | 
|
1040  | 
done  | 
|
1041  | 
||
1042  | 
text{*When P sees a dual signature, he knows that it originated with C.
 | 
|
1043  | 
and was intended for M. This guarantee isn't useful to M, who never gets  | 
|
1044  | 
  PIData. I don't see how to link @{term "PG j"} and @{text LID_M} without
 | 
|
1045  | 
  assuming @{term "M \<notin> bad"}.*}
 | 
|
| 15214 | 1046  | 
theorem P_verifies_Signed_PReq:  | 
| 14199 | 1047  | 
     "[| MsgDualSign = {|Hash PIData, HOIData|};
 | 
1048  | 
         PIData = {|PIHead, PANData|};
 | 
|
1049  | 
         PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M,
 | 
|
1050  | 
TransStain|};  | 
|
1051  | 
Crypt (priSK C) (Hash MsgDualSign) \<in> parts (knows Spy evs);  | 
|
1052  | 
evs \<in> set_pur; C \<notin> bad; M \<notin> bad|]  | 
|
1053  | 
==> \<exists>OIData OrderDesc K j trans.  | 
|
1054  | 
          HOD = Hash{|Number OrderDesc, Number PurchAmt|} &
 | 
|
1055  | 
HOIData = Hash OIData &  | 
|
1056  | 
          Notes M {|Number LID_M, Agent (PG j), trans|} \<in> set evs &
 | 
|
1057  | 
          Says C M {|{|sign (priSK C) MsgDualSign,
 | 
|
1058  | 
EXcrypt K (pubEK (PG j))  | 
|
1059  | 
                                {|PIHead, Hash OIData|} PANData|},
 | 
|
1060  | 
OIData, Hash PIData|}  | 
|
1061  | 
\<in> set evs"  | 
|
1062  | 
apply clarify  | 
|
1063  | 
apply (erule rev_mp)  | 
|
1064  | 
apply (erule set_pur.induct, simp_all)  | 
|
1065  | 
apply (auto dest!: C_gets_correct_PG)  | 
|
1066  | 
done  | 
|
1067  | 
||
1068  | 
lemma C_determines_EKj_signed:  | 
|
1069  | 
     "[| Says C M {|{|sign (priSK C) text,
 | 
|
1070  | 
                      EXcrypt K EKj {|PIHead, X|} Y|}, Z|} \<in> set evs;
 | 
|
1071  | 
         PIHead = {|Number LID_M, Number XID, W|};
 | 
|
1072  | 
C = Cardholder k; evs \<in> set_pur; M \<notin> bad|]  | 
|
1073  | 
==> \<exists> trans j.  | 
|
1074  | 
         Notes M {|Number LID_M, Agent (PG j), trans|} \<in> set evs &
 | 
|
1075  | 
EKj = pubEK (PG j)"  | 
|
1076  | 
apply clarify  | 
|
1077  | 
apply (erule rev_mp)  | 
|
1078  | 
apply (erule set_pur.induct, simp_all, auto)  | 
|
1079  | 
apply (blast dest: C_gets_correct_PG)  | 
|
1080  | 
done  | 
|
1081  | 
||
1082  | 
lemma M_Says_AuthReq:  | 
|
1083  | 
     "[| AuthReqData = {|Number LID_M, Number XID, HOIData, HOD|};
 | 
|
1084  | 
         sign (priSK M) {|AuthReqData, Hash P_I|} \<in> parts (knows Spy evs);
 | 
|
1085  | 
evs \<in> set_pur; M \<notin> bad|]  | 
|
1086  | 
==> \<exists>j trans KM.  | 
|
1087  | 
           Notes M {|Number LID_M, Agent (PG j), trans |} \<in> set evs &
 | 
|
1088  | 
Says M (PG j)  | 
|
1089  | 
(EncB (priSK M) KM (pubEK (PG j)) AuthReqData P_I)  | 
|
1090  | 
\<in> set evs"  | 
|
1091  | 
apply (rule refl [THEN P_verifies_AuthReq, THEN exE])  | 
|
1092  | 
apply (auto simp add: sign_def)  | 
|
1093  | 
done  | 
|
1094  | 
||
1095  | 
text{*A variant of @{text M_verifies_Signed_PReq} with explicit PI information.
 | 
|
1096  | 
Even here we cannot be certain about what C sent to M, since a bad  | 
|
1097  | 
PG could have replaced the two key fields. (NOT USED)*}  | 
|
1098  | 
lemma Signed_PReq_imp_Says_Cardholder:  | 
|
1099  | 
     "[| MsgDualSign = {|Hash PIData, Hash OIData|};
 | 
|
1100  | 
         OIData = {|Number LID_M, Number XID, Nonce Chall_C, HOD, etc|};
 | 
|
1101  | 
         PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M,
 | 
|
1102  | 
TransStain|};  | 
|
1103  | 
         PIData = {|PIHead, PANData|};
 | 
|
1104  | 
Crypt (priSK C) (Hash MsgDualSign) \<in> parts (knows Spy evs);  | 
|
1105  | 
M = Merchant i; C = Cardholder k; C \<notin> bad; evs \<in> set_pur|]  | 
|
1106  | 
==> \<exists>KC EKj.  | 
|
1107  | 
            Says C M {|{|sign (priSK C) MsgDualSign,
 | 
|
1108  | 
                       EXcrypt KC EKj {|PIHead, Hash OIData|} PANData|},
 | 
|
1109  | 
OIData, Hash PIData|}  | 
|
1110  | 
\<in> set evs"  | 
|
1111  | 
apply clarify  | 
|
1112  | 
apply (erule rev_mp)  | 
|
1113  | 
apply (erule rev_mp)  | 
|
1114  | 
apply (erule set_pur.induct, simp_all, auto)  | 
|
1115  | 
done  | 
|
1116  | 
||
1117  | 
text{*When P receives an AuthReq and a dual signature, he knows that C and M
 | 
|
1118  | 
agree on the essential details. PurchAmt however is never sent by M to  | 
|
1119  | 
P; instead C and M both send  | 
|
1120  | 
     @{term "HOD = Hash{|Number OrderDesc, Number PurchAmt|}"}
 | 
|
1121  | 
and P compares the two copies of HOD.  | 
|
1122  | 
||
1123  | 
Agreement can't be proved for some things, including the symmetric keys  | 
|
1124  | 
used in the digital envelopes. On the other hand, M knows the true identity  | 
|
1125  | 
of PG (namely j'), and sends AReq there; he can't, however, check that  | 
|
1126  | 
the EXcrypt involves the correct PG's key.  | 
|
1127  | 
*}  | 
|
| 15214 | 1128  | 
theorem P_sees_CM_agreement:  | 
| 14199 | 1129  | 
     "[| AuthReqData = {|Number LID_M, Number XID, HOIData, HOD|};
 | 
1130  | 
KC \<in> symKeys;  | 
|
1131  | 
Gets (PG j) (EncB (priSK M) KM (pubEK (PG j)) AuthReqData P_I)  | 
|
1132  | 
\<in> set evs;  | 
|
1133  | 
C = Cardholder k;  | 
|
1134  | 
         PI_sign = sign (priSK C) {|Hash PIData, HOIData|};
 | 
|
1135  | 
         P_I = {|PI_sign,
 | 
|
1136  | 
                 EXcrypt KC (pubEK (PG j)) {|PIHead, HOIData|} PANData|};
 | 
|
1137  | 
         PANData = {|Pan (pan C), Nonce (PANSecret k)|};
 | 
|
1138  | 
         PIData = {|PIHead, PANData|};
 | 
|
1139  | 
         PIHead = {|Number LID_M, Number XID, HOD, Number PurchAmt, Agent M,
 | 
|
1140  | 
TransStain|};  | 
|
1141  | 
evs \<in> set_pur; C \<notin> bad; M \<notin> bad|]  | 
|
1142  | 
==> \<exists>OIData OrderDesc KM' trans j' KC' KC'' P_I' P_I''.  | 
|
1143  | 
           HOD = Hash{|Number OrderDesc, Number PurchAmt|} &
 | 
|
1144  | 
HOIData = Hash OIData &  | 
|
1145  | 
           Notes M {|Number LID_M, Agent (PG j'), trans|} \<in> set evs &
 | 
|
1146  | 
           Says C M {|P_I', OIData, Hash PIData|} \<in> set evs &
 | 
|
1147  | 
Says M (PG j') (EncB (priSK M) KM' (pubEK (PG j'))  | 
|
1148  | 
AuthReqData P_I'') \<in> set evs &  | 
|
1149  | 
           P_I' = {|PI_sign,
 | 
|
1150  | 
             EXcrypt KC' (pubEK (PG j')) {|PIHead, Hash OIData|} PANData|} &
 | 
|
1151  | 
           P_I'' = {|PI_sign,
 | 
|
1152  | 
             EXcrypt KC'' (pubEK (PG j)) {|PIHead, Hash OIData|} PANData|}"
 | 
|
1153  | 
apply clarify  | 
|
1154  | 
apply (rule exE)  | 
|
1155  | 
apply (rule P_verifies_Signed_PReq [OF refl refl refl])  | 
|
1156  | 
apply (simp (no_asm_use) add: sign_def EncB_def, blast)  | 
|
1157  | 
apply (assumption+, clarify, simp)  | 
|
1158  | 
apply (drule Gets_imp_knows_Spy [THEN parts.Inj], assumption)  | 
|
1159  | 
apply (blast elim: EncB_partsE dest: refl [THEN M_Says_AuthReq] unique_LID_M2)  | 
|
1160  | 
done  | 
|
1161  | 
||
1162  | 
end  |