Skip to content

Commit 8f30a41

Browse files
committed
CHANGE: making CHECKSUM more compatible with Red language
* removed `/method`; now method is always used as second argument * removed `/tcp`; now accessible as: `checksum data 'tcp` * removed `/secure`; now accessible as: `checksum data 'sha1` (`sha1` is not considered as too secure anyway these days) * removed `/hash`; now accessible as: `checksum/with value 'hash 256` * renamed `/key` to `/with`; given `spec` is used as a key for HMAC and or size of hash table Available checksum methods are now listed in: `system/catalog/checksums` Note: checksum port does not support these methods: adler32, crc24, crc32 and tcp
1 parent 1ab00e6 commit 8f30a41

21 files changed

+181
-175
lines changed

src/boot/natives.reb

+1-14
Original file line numberDiff line numberDiff line change
@@ -385,20 +385,7 @@ collect-words: native [
385385
words [any-object! block! none!] "Words to ignore"
386386
]
387387

388-
checksum: native [
389-
{Computes a checksum, CRC, or hash.}
390-
data [binary! string!] {Bytes to checksum. String value is first converted to UTF-8!}
391-
/part length {Length of data}
392-
/tcp {Returns an Internet TCP 16-bit checksum}
393-
/secure {Returns a cryptographically secure checksum}
394-
/hash {Returns a hash value}
395-
size [integer!] {Size of the hash table}
396-
/method {Method to use}
397-
word [word!] {Methods: SHA1 SHA256 SHA384 SHA512 MD5 CRC32 ADLER32}
398-
/key {Returns keyed HMAC value}
399-
key-value [any-string! binary!] {Key to use}
400-
]
401-
388+
;checksum: native [] ; defined in %n-string.c
402389
;compress: native [] ; defined in %n-string.c
403390
;decompress: native [] ; defined in %n-string.c
404391

src/boot/sysobj.reb

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ catalog: object [
5757
uri: #[bitset! #{000000005BFFFFF5FFFFFFE17FFFFFE2}] ;A-Z a-z 0-9 !#$&'()*+,-./:;=?@_~
5858
uri-component: #[bitset! #{0000000041E6FFC07FFFFFE17FFFFFE2}] ;A-Z a-z 0-9 !'()*-._~
5959
]
60+
checksums: [adler32 crc24 crc32 tcp md4 md5 sha1 sha224 sha256 sha384 sha512 ripemd160]
6061
]
6162

6263
contexts: construct [

src/boot/words.reb

+10-3
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,18 @@ bessel
181181
sinc
182182

183183
; Checksum
184-
sha1
185-
sha256
184+
hash
185+
adler32
186+
crc24
187+
crc32
186188
md4
187189
md5
188-
crc32
190+
ripemd160
191+
sha1
192+
sha224
193+
sha256
194+
sha384
195+
sha512
189196

190197
; Codec actions
191198
identify

src/core/n-strings.c

+56-52
Original file line numberDiff line numberDiff line change
@@ -116,75 +116,68 @@ static struct digest {
116116
**
117117
*/ REBNATIVE(checksum)
118118
/*
119-
** Computes checksum or hash value.
120-
**
121-
** Note: Currently BINARY only.
122-
**
123-
** Args:
124-
**
125-
** data [any-string!] {Data to checksum}
126-
** /part length
127-
** /tcp {Returns an Internet TCP 16-bit checksum.}
128-
** /secure {Returns a cryptographically secure checksum.}
129-
** /hash {Returns a hash value}
130-
** size [integer!] {Size of the hash table}
131-
** /method {Method to use}
132-
** word [word!] {Method: SHA1 MD5}
133-
** /key {Returns keyed HMAC value}
134-
** key-value [any-string! binary!] {Key to use}
135-
**
119+
// checksum: native [
120+
// {Computes a checksum, CRC, hash, or HMAC.}
121+
// data [binary! string!] {If string, it will be UTF8 encoded}
122+
// method [word!] {One of `system/catalog/checksums` and HASH}
123+
// /with {Extra value for HMAC key or hash table size; not compatible with TCP/CRC24/CRC32/ADLER32 methods.}
124+
// spec [any-string! binary! integer!] {String or binary for MD5/SHA* HMAC key, integer for hash table size.}
125+
// /part {Limits to a given length}
126+
// length
127+
// ]
136128
***********************************************************************/
137129
{
138-
REBVAL *arg = D_ARG(ARG_CHECKSUM_DATA);
130+
REBVAL *arg = D_ARG(ARG_CHECKSUM_DATA);
131+
REBINT sym = VAL_WORD_CANON(D_ARG(ARG_CHECKSUM_METHOD));
132+
REBVAL *spec = D_ARG(ARG_CHECKSUM_SPEC);
139133
REBINT sum;
140134
REBINT i;
141135
REBINT j;
142-
REBSER *digest;
143-
REBINT sym = SYM_SHA1;
144-
REBCNT len;
136+
REBSER *digest, *ser;
137+
REBCNT len, keylen;
145138
REBYTE *data;
139+
REBYTE *keycp;
140+
146141

147142
len = Partial1(arg, D_ARG(ARG_CHECKSUM_LENGTH));
148143

149144
if (IS_STRING(arg)) {
150-
// using `digest` just as a temp variable here!
151-
digest = Encode_UTF8_Value(arg, len, 0);
152-
data = SERIES_DATA(digest);
153-
len = SERIES_LEN(digest) - 1;
145+
ser = Encode_UTF8_Value(arg, len, 0);
146+
data = SERIES_DATA(ser);
147+
len = SERIES_LEN(ser) - 1;
154148
}
155149
else {
156150
data = VAL_BIN_DATA(arg);
157151
}
158152

159-
160-
161-
// Method word:
162-
if (D_REF(ARG_CHECKSUM_METHOD)) sym = VAL_WORD_CANON(D_ARG(ARG_CHECKSUM_WORD));
163-
164-
// If method, secure, or key... find matching digest:
165-
if (D_REF(ARG_CHECKSUM_METHOD) || D_REF(ARG_CHECKSUM_SECURE) || D_REF(ARG_CHECKSUM_KEY)) {
166-
167-
if (sym == SYM_CRC32 || sym == SYM_ADLER32) {
168-
if (D_REF(ARG_CHECKSUM_SECURE) || D_REF(ARG_CHECKSUM_KEY)) Trap0(RE_BAD_REFINES);
169-
i = (sym == SYM_CRC32) ? CRC32(data, len) : z_adler32_z(0x00000001L, data, len);
170-
DS_RET_INT(i);
171-
return R_RET;
172-
}
173-
153+
if (sym > SYM_CRC32 && sym <= SYM_SHA512) {
154+
// O: could be optimized using index computed from `sym`
155+
// find matching digest:
174156
for (i = 0; i < sizeof(digests) / sizeof(digests[0]); i++) {
175157

176158
if (digests[i].index == sym) {
177159

178160
digest = Make_Series(digests[i].len, 1, FALSE);
179161
LABEL_SERIES(digest, "checksum digest");
180162

181-
if (D_REF(ARG_CHECKSUM_KEY)) {
163+
if (D_REF(ARG_CHECKSUM_WITH)) { // HMAC
164+
if (IS_INTEGER(spec))
165+
Trap1(RE_BAD_REFINE, D_ARG(ARG_CHECKSUM_SPEC));
166+
167+
if (IS_BINARY(spec)) {
168+
keycp = VAL_BIN_DATA(spec);
169+
keylen = VAL_LEN(spec);
170+
}
171+
else {
172+
// normalize to UTF8 first
173+
ser = Encode_UTF8_Value(spec, VAL_LEN(spec), 0);
174+
keycp = SERIES_DATA(ser);
175+
keylen = SERIES_LEN(ser) - 1;
176+
}
182177
REBYTE tmpdigest[128]; // Size must be max of all digest[].len;
183178
REBYTE ipad[128],opad[128]; // Size must be max of all digest[].hmacblock;
184179
void *ctx = Make_Mem(digests[i].ctxsize());
185-
REBVAL *key = D_ARG(ARG_CHECKSUM_KEY_VALUE);
186-
REBYTE *keycp = VAL_BIN_DATA(key);
187-
int keylen = VAL_LEN(key);
180+
188181
int blocklen = digests[i].hmacblock;
189182

190183
if (keylen > blocklen) {
@@ -224,23 +217,34 @@ static struct digest {
224217
return 0;
225218
}
226219
}
227-
228-
Trap_Arg(D_ARG(ARG_CHECKSUM_WORD));
220+
// used correct name, but diggest was not found (excluded from build)
221+
Trap0(RE_FEATURE_NA);
229222
}
230-
else if (D_REF(ARG_CHECKSUM_TCP)) { // /tcp
231-
i = Compute_IPC(data, len);
223+
224+
if (D_REF(ARG_CHECKSUM_WITH) && ((sym > SYM_HASH && sym <= SYM_CRC32) || sym == SYM_TCP))
225+
Trap0(RE_BAD_REFINES);
226+
227+
if (sym == SYM_CRC32 || sym == SYM_ADLER32) {
228+
i = (sym == SYM_CRC32) ? CRC32(data, len) : z_adler32_z(0x00000001L, data, len);
232229
}
233-
else if (D_REF(ARG_CHECKSUM_HASH)) { // /hash
234-
sum = VAL_INT32(D_ARG(ARG_CHECKSUM_SIZE)); // /size
230+
else if (sym == SYM_HASH) { // /hash
231+
if(!D_REF(ARG_CHECKSUM_WITH)) Trap0(RE_MISSING_ARG);
232+
if (!IS_INTEGER(spec)) Trap1(RE_BAD_REFINE, D_ARG(ARG_CHECKSUM_SPEC));
233+
sum = VAL_INT32(spec); // size of the hash table
235234
if (sum <= 1) sum = 1;
236235
i = Hash_String(data, len) % sum;
237236
}
238-
else {
237+
else if (sym == SYM_CRC24) {
239238
i = Compute_CRC24(data, len);
240239
}
240+
else if (sym == SYM_TCP) {
241+
i = Compute_IPC(data, len);
242+
}
243+
else {
244+
Trap_Arg(D_ARG(ARG_CHECKSUM_METHOD));
245+
}
241246

242247
DS_RET_INT(i);
243-
244248
return R_RET;
245249
}
246250

src/mezz/codec-gzip.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ register-codec [
5151
]
5252
if 2 = (2 and flg) [ ;FHCRC
5353
;the two least significant bytes of the CRC32 for all bytes of the gzip header up to and not including the CRC16
54-
;checksum/method/part bin/buffer-write 'CRC32 index? bin/buffer
54+
;checksum/part bin/buffer-write 'CRC32 index? bin/buffer
5555
crc16: binary/read bin 'UI16LE
5656
]
5757
if verbose > 0 [

src/mezz/codec-ppk.reb

+5-5
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ register-codec [
6666
pass: either password [copy pass][
6767
ask/hide ajoin ["Key password for " mold comm ": "]
6868
]
69-
key: join checksum/secure join #{00000000} pass
70-
checksum/secure join #{00000001} pass
69+
key: join checksum join #{00000000} pass 'sha1
70+
checksum join #{00000001} pass 'sha1
7171
key: aes/decrypt/key copy/part key 32 none
7272
pri: aes/decrypt/stream key pri
7373
][
@@ -87,11 +87,11 @@ register-codec [
8787
UI32BYTES :pri
8888
] 'buffer
8989
]
90-
mackey: checksum/secure join "putty-private-key-file-mac-key" any [pass ""]
90+
mackey: checksum join "putty-private-key-file-mac-key" any [pass ""] 'sha1
9191
if pass [forall pass [pass/1: random 255]]
9292
if pmac <> form either mac? [
93-
checksum/secure/key macdata mackey
94-
][ checksum/secure macdata ] [
93+
checksum/with macdata 'sha1 mackey
94+
][ checksum macdata 'sha1 ] [
9595
print either key ["Wrong password!"]["MAC failed!"]
9696
return none
9797
]

src/mezz/codec-ssh-key.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ wrap [
6060
]
6161
iv: debase iv 16
6262
unless p [p: ask/hide "Pasword: "]
63-
p: checksum/method
63+
p: checksum
6464
join to binary! p copy/part iv 8
6565
'md5
6666
d: aes/key/decrypt p iv

src/mezz/codec-zip.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ register-codec [
125125
if all [
126126
data
127127
any [validate validate-crc?]
128-
crc <> crc2: checksum/method data 'crc32
128+
crc <> crc2: checksum data 'crc32
129129
][
130130
sys/log/error 'ZIP ["CRC check failed!" crc "<>" crc2]
131131
]

src/mezz/mezz-save.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ save: function [
100100

101101
case/all [
102102
; Checksum uncompressed data, if requested
103-
tmp: find header-data 'checksum [change next tmp checksum/secure data: to-binary data]
103+
tmp: find header-data 'checksum [change next tmp checksum data: to-binary data 'sha1]
104104
; Compress the data if necessary
105105
compress [data: lib/compress data]
106106
; File content is encoded as base-64:

src/mezz/prot-mysql.reb

+3-3
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ mysql-driver: make object! [
525525

526526
;--- New 4.1.0+ authentication scheme ---
527527
crypt-v11: func [data [binary!] seed [binary!] /local key1 key2][
528-
key1: checksum/secure data
529-
key2: checksum/secure key1
530-
key1 xor checksum/secure rejoin [(to-binary seed) key2]
528+
key1: checksum data 'sha1
529+
key2: checksum key1 'sha1
530+
key1 xor checksum rejoin [(to-binary seed) key2] 'sha1
531531
]
532532

533533
scramble: func [data [string! none!] port [port!] /v10 /local seed][

src/mezz/prot-smtp.reb

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ sync-smtp-handler: func [ event
174174
auth-key: skip response 4
175175
auth-key: debase auth-key 64
176176
; compute challenge response
177-
auth-key: checksum/method/key auth-key 'md5 client/spec/pass
177+
auth-key: checksum/with auth-key 'md5 client/spec/pass
178178
write client to-binary net-log/C join
179179
enbase reform [client/spec/user lowercase enbase auth-key 16] 64 CRLF
180180
client/spec/state: 'PASSWORD

src/mezz/prot-tls.reb

+12-12
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ TLS-update-messages-hash: function [
468468
log-more ["Update-messages-hash bytes:" len "hash:" all [ctx/sha-port ctx/sha-port/spec/method]]
469469
if none? ctx/sha-port [
470470
either ctx/legacy? [
471-
ctx/sha-port: open checksum://sha1
472-
ctx/md5-port: open checksum://md5
471+
ctx/sha-port: open checksum:sha1
472+
ctx/md5-port: open checksum:md5
473473
][
474-
ctx/sha-port: open either ctx/mac-size = 48 [checksum://sha384][checksum://sha256]
474+
ctx/sha-port: open either ctx/mac-size = 48 [checksum:sha384][checksum:sha256]
475475
]
476476
log-more ["Initialized SHA method:" ctx/sha-port/spec/method]
477477
]
@@ -846,7 +846,7 @@ decrypt-msg: function [
846846
binary/write bin [
847847
UI16BYTES :data
848848
]
849-
mac-check: checksum/method/key bin/buffer hash-method server-mac-key
849+
mac-check: checksum/with bin/buffer hash-method server-mac-key
850850

851851
;?? mac
852852
;?? mac-check
@@ -925,7 +925,7 @@ encrypt-data: function [
925925

926926
binary/write bin content
927927

928-
MAC: checksum/method/key bin/buffer ctx/hash-method ctx/client-mac-key
928+
MAC: checksum/with bin/buffer ctx/hash-method ctx/client-mac-key
929929

930930
;?? MAC
931931
data: rejoin [content MAC]
@@ -1032,15 +1032,15 @@ prf: function [
10321032
p-md5: copy #{}
10331033
a: seed ; A(0)
10341034
while [output-length > length? p-md5][
1035-
a: checksum/method/key a 'md5 s-1 ; A(n)
1036-
append p-md5 checksum/method/key rejoin [a seed] 'md5 s-1
1035+
a: checksum/with a 'md5 s-1 ; A(n)
1036+
append p-md5 checksum/with rejoin [a seed] 'md5 s-1
10371037
]
10381038

10391039
p-sha1: copy #{}
10401040
a: seed ; A(0)
10411041
while [output-length > length? p-sha1][
1042-
a: checksum/method/key a 'sha1 s-2 ; A(n)
1043-
append p-sha1 checksum/method/key rejoin [a seed] 'sha1 s-2
1042+
a: checksum/with a 'sha1 s-2 ; A(n)
1043+
append p-sha1 checksum/with rejoin [a seed] 'sha1 s-2
10441044
]
10451045
return (
10461046
(copy/part p-md5 output-length)
@@ -1057,8 +1057,8 @@ prf: function [
10571057
p-sha256: make binary! output-length
10581058
a: seed ; A(0)
10591059
while [output-length >= length? p-sha256][
1060-
a: checksum/method/key a 'sha256 secret
1061-
append p-sha256 checksum/method/key rejoin [a seed] 'sha256 secret
1060+
a: checksum/with a 'sha256 secret
1061+
append p-sha256 checksum/with rejoin [a seed] 'sha256 secret
10621062
;?? p-sha256
10631063
]
10641064
;trim the result to required output length
@@ -1579,7 +1579,7 @@ TLS-parse-handshake-message: function [
15791579
log-error "legacy __private_rsa_verify_hash_md5sha1 not implemented yet!"
15801580
return *Alert/Decode_error
15811581
]
1582-
message-hash: checksum/method message hash-algorithm
1582+
message-hash: checksum message hash-algorithm
15831583
;? message-hash
15841584
if any [
15851585
error? valid?: try [

src/mezz/sys-load.reb

+5-5
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ load-header: function/with [
149149
attempt [decompress/part rest end] ; binary compression
150150
attempt [decompress first transcode/next rest] ; script encoded
151151
] [return 'bad-compress]
152-
if all [sum sum != checksum/secure rest] [return 'bad-checksum]
152+
if all [sum sum != checksum rest 'sha1] [return 'bad-checksum]
153153
] ; else assumed not compressed
154-
all [sum sum != checksum/secure/part rest end] [return 'bad-checksum]
154+
all [sum sum != checksum/part rest 'sha1 end] [return 'bad-checksum]
155155
]
156156
]
157157
;assert/type [rest [binary!]] none
@@ -161,9 +161,9 @@ load-header: function/with [
161161
case [
162162
find hdr/options 'compress [ ; script encoded only
163163
unless rest: attempt [decompress first rest] [return 'bad-compress]
164-
if all [sum sum != checksum/secure rest] [return 'bad-checksum]
164+
if all [sum sum != checksum rest 'sha1] [return 'bad-checksum]
165165
]
166-
all [sum sum != checksum/secure/part tmp back end] [return 'bad-checksum]
166+
all [sum sum != checksum/part tmp 'sha1 back end] [return 'bad-checksum]
167167
]
168168
]
169169
;assert/type [rest [block! binary!]] none
@@ -427,7 +427,7 @@ load-module: function [
427427
{Loads a module (from a file, URL, binary, etc.) and inserts it into the system module list.}
428428
source [word! file! url! string! binary! module! block!] {Source or block of sources}
429429
/version ver [tuple!] "Module must be this version or greater"
430-
/check sum [binary!] "Match checksum (must be set in header)"
430+
/check sum [binary!] "Match SHA1 checksum (must be set in header)"
431431
/no-share "Force module to use its own non-shared global namespace"
432432
/no-lib "Don't export to the runtime library (lib)"
433433
/import "Do module import now, overriding /delay and 'delay option"

0 commit comments

Comments
 (0)