-
Notifications
You must be signed in to change notification settings - Fork 0
/
touchdown_client.r
executable file
·232 lines (203 loc) · 4.7 KB
/
touchdown_client.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
REBOL []
;*** TOUCHDOWN CLIENT ***
touchdown-client: make object!
[
key-cache: copy []
deferred-keys: copy []
http-deferred-keys: copy []
decrypt: func
[
{Generic decryption function}
msg [binary!]
k [binary!]
/local res dec-port crypt-str
]
[
crypt-str: 8 * length? k
dec-port: open make port!
[
scheme: 'crypt
algorithm: 'rijndael
direction: 'decrypt
strength: crypt-str
key: k
padding: true
]
insert dec-port msg
update dec-port
res: copy dec-port
close dec-port
return to-string res
]
encrypt: func
[
msg [binary! string!]
k [binary!]
/local res enc-port crypt-str
]
[
crypt-str: 8 * length? k
enc-port: open make port!
[
scheme: 'crypt
algorithm: 'rijndael
direction: 'encrypt
strength: crypt-str
key: k
padding: true
]
insert enc-port msg
update enc-port
res: copy enc-port
close enc-port
return res
]
negotiate: func
[
{Negotiates a session strengh and public rsa keyi with a touchdown
server.}
dest [url!]
/local serv-strength
]
[
if not found? find key-cache mold dest
[
serv-strength: rexec/with [negotiate] dest
if not none? serv-strength
[
append key-cache mold dest
append/only key-cache serv-strength
]
return serv-strength
]
return select key-cache mold dest
]
generate-session-key: func
[
{Idem.}
crypt-str [integer!]
]
[
return copy/part checksum/secure mold now 16
]
secure-result-available?: func
[
{Is a deferred http result available}
index [integer!]
]
[
result-available? index
]
get-secure-result: func
[
{Returns a deferred and secured http request}
index [integer!]
/local s-key res ret
]
[
s-key: select http-deferred-keys index
if none? s-key
[
make error! join {Rugby error: No session key to match}
{ the deferred http request}
]
res: get-http-result index
if object? res [ return remake-error res ]
;Cleanup or key list
remove remove find http-deferred-keys index
set/any 'ret pick get-return-message res s-key 1
either object? get/any 'ret
[
return rugby-client/remake-error ret
]
[
return get/any 'ret
]
]
wait-for-secure-result: func
[
{Waits for a secured result}
index [integer!]
]
[
until [secure-http-result-available? index ]
get-secure-http-result index
]
generate-message: func
[
stm [block!]
s-key [binary!]
r-key [object!]
/local blk-stm p-blk
]
[
blk-stm: copy [ sexec-srv ]
p-blk: copy []
append p-blk rsa-encrypt r-key s-key
append p-blk encrypt mold stm s-key
append/only blk-stm p-blk
return blk-stm
]
get-return-message: func
[
stm
s-key [binary!]
/local ret
]
[
set/any 'ret do decrypt stm s-key
return get/any 'ret
]
sexec: func
[
{A secure exec facility a la rexec for /Pro and /COmmand users}
stm [any-block!]
/with
dest [url!]
/deferred
/local port sst crypt-str s-key ps-key r-key g-stm def-index
]
[
port: either with [ dest] [http://localhost:8002]
sst: negotiate port
if none? sst [print "no sst" return none]
either (crypt-strength? = 'full)
[
either (first sst) = 'full
[
crypt-str: 128
]
[
crypt-str: 56
]
]
[
crypt-str: 56
]
;generate our session-key
s-key: generate-session-key crypt-str
;get and initialize an rsa-key from the server's public key (second sst)
ps-key: second sst
r-key: rsa-make-key
r-key/n: ps-key
r-key/e: 3
;generate our sexec message
g-stm: generate-message stm s-key r-key
either not deferred
[
;A heavy one: get the first element of the decrypted return message
;of you request over http
do get-return-message rexec/with g-stm port s-key
]
[
;What's our http-index
def-index: rexec/with/deferred g-stm port s-key 1
repend http-deferred-keys [def-index s-key]
return def-index
]
];sexec
];touchdown-client
set 'sexec get in touchdown-client 'sexec
set 'secure-result-available? get in touchdown-client 'secure-result-available?
set 'wait-for-secure-result get in touchdown-client 'wait-for-secure-result
set 'get-secure-result get in touchdown-client 'get-secure-result