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