@@ -35,7 +35,7 @@ REBOL [
35
35
0.8.0 "Oldes" "Using new `crypt` port introduced in Rebol 3.8.0"
36
36
0.9.0 "Oldes" "Added (limited) support for a `server` role"
37
37
0.9.1 "Oldes" "Improved initialization to be able reuse already opened TCP port"
38
- 0.9.2 "Oldes" "Added support for GCM crypt mode "
38
+ 0.9.2 "Oldes" "Added support for GCM and SHA384 crypt modes "
39
39
]
40
40
todo: {
41
41
* cached sessions
@@ -82,7 +82,9 @@ TLS-context: context [
82
82
tls-port:
83
83
encrypt-port:
84
84
decrypt-port:
85
- sha-port: ;used for progressive checksum computations
85
+ sha256-port: ;used for progressive checksum computations
86
+ sha384-port: ;used for progressive checksum computations with SHA384 cipher modes
87
+ sha-port: ;one of the above
86
88
md5-port: ;used for progressive checksum computations (in TLSv1.0)
87
89
88
90
version: none ; TLS version (currently just TLSv1.2)
@@ -447,14 +449,14 @@ suported-cipher-suites: decode-cipher-suites suported-cipher-suites-binary: rejo
447
449
#{ CCA9 } ;TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
448
450
#{ CCA8 } ;TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
449
451
#{ C02F } ;TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
450
- ; #{C030} ;TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
452
+ #{ C030 } ;TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
451
453
#{ C02B } ;TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
452
- ; #{C02C} ;TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
454
+ #{ C02C } ;TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
453
455
#{ 009C } ;TLS-RSA-WITH-AES-128-GCM-SHA256
454
456
455
457
;- CBC mode is considered to be weak, but still used!
456
- ; #{C028} ;TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ;need test with https://snappygoat.com/b/8d6492a33fee8f8f0ea289203fdf080608d9d61d
457
- ; #{C024} ;TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
458
+ #{ C028 } ;TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
459
+ #{ C024 } ;TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
458
460
#{ C027 } ;TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
459
461
#{ C023 } ;TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
460
462
#{ C014 } ;TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
@@ -554,6 +556,17 @@ TLS-init-cipher-suite: func [
554
556
ctx/crypt-method: to word! cipher
555
557
ctx/is-aead?: to logic! find [AES-128-GCM AES-256-GCM CHACHA20-POLY1305] ctx/crypt-method
556
558
559
+ either ctx/hash-method = 'SHA384 [
560
+ ; upgrade hashing from default sha256 to sha384
561
+ close ctx/sha256-port
562
+ ctx/sha256-port: none
563
+ ctx/sha-port: ctx/sha384-port
564
+ ][
565
+ ; the sha384 hasning is not needed anymore
566
+ close ctx/sha384-port
567
+ ctx/sha384-port: none
568
+ ]
569
+
557
570
log-more [
558
571
"Key:^[ [1m" ctx/key-method
559
572
"^[ [22mcrypt:^[ [1m" ctx/crypt-method
@@ -609,9 +622,12 @@ TLS-update-messages-hash: function [
609
622
] [
610
623
log-more ["Update-messages-hash bytes:" len "hash:" all [ctx/sha-port ctx/sha-port/spec/method ]]
611
624
if none? ctx/sha-port [
612
- ctx/sha-port: open either ctx/mac-size = 48 [checksum:sha384 ][checksum:sha256 ]
625
+ ctx/sha256-port: open checksum:sha256
626
+ ctx/sha384-port: open checksum:sha384
627
+ ctx/sha-port: ctx/sha256-port
613
628
log-more ["Initialized SHA method:" ctx/sha-port/spec/method ]
614
629
]
630
+ unless ctx/hash-method [ write /part ctx/sha384-port msg len ]
615
631
write /part ctx/sha-port msg len
616
632
log-debug ["messages-hash:" read ctx/sha-port ]
617
633
]
@@ -1046,7 +1062,7 @@ finished: function [
1046
1062
unencrypted: rejoin [
1047
1063
#{ 14 } ; protocol message type (20=Finished)
1048
1064
#{ 00000C } ; protocol message length (12 bytes)
1049
- prf either ctx/server? ["server finished" ]["client finished" ] seed ctx/master-secret 12
1065
+ prf : ctx /sha-port/spec/method either ctx/server? ["server finished" ]["client finished" ] seed ctx/master-secret 12
1050
1066
]
1051
1067
1052
1068
TLS-update-messages-hash ctx unencrypted length? unencrypted
@@ -1077,15 +1093,13 @@ encrypt-handshake-msg: function [
1077
1093
decrypt-msg : function [
1078
1094
ctx [object! ]
1079
1095
data [binary! ]
1080
- /type
1081
- msg-type [integer! ] "application data is default"
1096
+ type [integer! ]
1082
1097
] [
1083
1098
;print "CRYPTED message!"
1084
- msg-type: any [msg-type 23 ]
1085
1099
with ctx [
1086
1100
binary/write bin compose [
1087
1101
UI64 :seq-read
1088
- UI8 :msg- type
1102
+ UI8 :type
1089
1103
UI16 :version
1090
1104
]
1091
1105
either is-aead? [
@@ -1095,13 +1109,13 @@ decrypt-msg: function [
1095
1109
;? remote-IV
1096
1110
modify decrypt-port 'iv remote-IV
1097
1111
1098
- log-more ["Remote-IV: ^[ [32m" remote-IV]
1112
+ log-more ["Remote-IV:^[ [32m" remote-IV]
1099
1113
]
1100
1114
1101
1115
binary/write bin reduce ['UI16 (length? data) - 16 ]
1102
1116
write decrypt-port bin/buffer ; AAD chunk
1103
1117
1104
- log-more ["AAD: ^[ [32m" bin/buffer ]
1118
+ log-more ["AAD: ^[ [32m" bin/buffer ]
1105
1119
1106
1120
mac: take/last/part data 16 ; expected mac
1107
1121
data: read write decrypt-port data
@@ -1246,6 +1260,7 @@ encrypt-data: function [
1246
1260
1247
1261
prf : function [
1248
1262
{(P)suedo-(R)andom (F)unction, generates arbitrarily long binaries}
1263
+ hash [word! ]
1249
1264
label [string! binary! ]
1250
1265
seed [binary! ]
1251
1266
secret [binary! ]
@@ -1257,7 +1272,7 @@ prf: function [
1257
1272
; PRF(secret, label, seed) = P_<hash>(secret, label + seed)
1258
1273
;
1259
1274
1260
- log-more ["PRF" mold label "len:" output-length]
1275
+ log-more ["PRF" hash mold label "len:" output-length]
1261
1276
seed: join to binary! label seed
1262
1277
1263
1278
; TLS 1.2 includes the pseudorandom function as part of its cipher
@@ -1269,8 +1284,8 @@ prf: function [
1269
1284
p-sha256: make binary! output-length
1270
1285
a: seed ; A(0)
1271
1286
while [output-length >= length? p-sha256][
1272
- a: checksum /with a 'sha256 secret
1273
- append p-sha256 checksum /with append copy :a :seed 'sha256 secret
1287
+ a: checksum /with a :hash : secret
1288
+ append p-sha256 checksum /with append copy :a :seed :hash : secret
1274
1289
;?? p-sha256
1275
1290
]
1276
1291
;trim the result to required output length
@@ -1281,7 +1296,7 @@ prf: function [
1281
1296
1282
1297
TLS-key-expansion : func [
1283
1298
ctx [object! ]
1284
- /local rnd1 rnd2 key-expansion
1299
+ /local rnd1 rnd2 key-expansion sha
1285
1300
] [
1286
1301
with ctx [
1287
1302
;-- make all secure data
@@ -1292,8 +1307,9 @@ TLS-key-expansion: func[
1292
1307
rnd2: append copy ctx/remote-random ctx/local-random
1293
1308
rnd1: append copy ctx/local-random ctx/remote-random
1294
1309
]
1295
- master-secret: prf "master secret" rnd1 pre-secret 48
1296
- key-expansion: prf "key expansion" rnd2 master-secret (mac-size + crypt-size + iv-size) * 2
1310
+ sha: ctx/sha-port/spec/method
1311
+ master-secret: prf :sha "master secret" rnd1 pre-secret 48
1312
+ key-expansion: prf :sha "key expansion" rnd2 master-secret (mac-size + crypt-size + iv-size) * 2
1297
1313
1298
1314
either server? [
1299
1315
unless is-aead? [
@@ -1373,13 +1389,7 @@ TLS-init-context: func [
1373
1389
TLS-init-connection : function [ ctx [object! ]] [
1374
1390
binary/init ctx/out none ;reset output buffer
1375
1391
client-hello ctx
1376
- ;ctx/out/buffer: head ctx/out/buffer
1377
- ;?? ctx/out/buffer
1378
- log-debug ["Writing bytes:" length? ctx/out/buffer ]
1379
- ctx/out/buffer: head ctx/out/buffer
1380
- write ctx/tcp-port ctx/out/buffer
1381
- binary/init ctx/out none ;reset output buffer
1382
- ctx/reading?: true
1392
+ do-TCP-write ctx
1383
1393
1384
1394
false
1385
1395
]
@@ -1455,7 +1465,7 @@ TLS-read-data: function [
1455
1465
;?? data
1456
1466
;?? ctx/cipher-spec-set
1457
1467
if ctx/cipher-spec-set > 1 [
1458
- if data: decrypt-msg ctx data [
1468
+ if data: decrypt-msg ctx data :type [
1459
1469
append ctx/port-data data
1460
1470
;@@ TODO: the parent scheme (HTTPS) should be notified here,
1461
1471
;@@ that there are already some decrypted data available!
@@ -1469,7 +1479,7 @@ TLS-read-data: function [
1469
1479
;? ctx/cipher-spec-set
1470
1480
either ctx/cipher-spec-set > 1 [
1471
1481
ctx/seq-read: 0
1472
- data: decrypt-msg/type ctx data 22
1482
+ data: decrypt-msg ctx data :type
1473
1483
;ctx/protocol: 'APPLICATION
1474
1484
;change-state ctx 'APPLICATION
1475
1485
ctx/reading?: ctx/server?
@@ -1499,7 +1509,7 @@ TLS-read-data: function [
1499
1509
binary/read inp [data: BYTES :len ]
1500
1510
if ctx/cipher-spec-set > 1 [
1501
1511
log-debug ["Decrypting ALERT message:" mold data]
1502
- data: decrypt-msg ctx data
1512
+ data: decrypt-msg ctx data :type
1503
1513
unless data [
1504
1514
log-error "Failed to decode ALERT message!"
1505
1515
;@@ TODO: inspect how it's possible that decrypt failes
@@ -1885,7 +1895,7 @@ TLS-parse-handshake-message: function [
1885
1895
FINISHED [
1886
1896
binary/read msg [verify-data: BYTES] ;rest of data
1887
1897
seed: read ctx/sha-port
1888
- result: prf either ctx/server? ["client finished" ]["server finished" ] seed ctx/master-secret 12
1898
+ result: prf : ctx /sha-port/spec/method either ctx/server? ["client finished" ]["server finished" ] seed ctx/master-secret 12
1889
1899
;? verify-data ? result
1890
1900
if result <> verify-data [
1891
1901
return *Alert/Handshake_failure
@@ -2080,8 +2090,7 @@ TLS-client-awake: function [event [event!]][
2080
2090
client-key-exchange ctx
2081
2091
change-cipher-spec ctx
2082
2092
finished ctx
2083
- write ctx/tcp-port ctx/out/buffer
2084
- ctx/reading?: true
2093
+ do-TCP-write ctx
2085
2094
return false
2086
2095
]
2087
2096
FINISHED [
@@ -2250,16 +2259,21 @@ do-TLS-write: func[port [port!] value [any-type!] /local ctx][
2250
2259
binary/init ctx/out none ;resets the output buffer
2251
2260
application-data ctx :value
2252
2261
2253
- log-debug ["Writing bytes:" length? ctx/out/buffer ]
2254
- ;ctx/out/buffer: head ctx/out/buffer
2255
- write ctx/tcp-port ctx/out/buffer
2256
-
2257
- ctx/reading?: true
2258
- binary/init ctx/out none ;resets the output buffer
2262
+ do-TCP-write ctx
2259
2263
return port
2260
2264
]
2261
2265
]
2262
2266
2267
+ do-TCP-write : func [ ctx] [
2268
+ log-debug ["Writing bytes:" length? ctx/out/buffer ]
2269
+ ;?? ctx/out/buffer
2270
+ ;ctx/out/buffer: head ctx/out/buffer
2271
+ write ctx/tcp-port ctx/out/buffer
2272
+
2273
+ ctx/reading?: true
2274
+ binary/init ctx/out none ;resets the output buffer
2275
+ ]
2276
+
2263
2277
sys/make-scheme [
2264
2278
name: 'tls
2265
2279
title: "TLS protocol v1.2"
0 commit comments