Skip to content

Commit 070c6b2

Browse files
committed
CHANGE: added new release native as an universal way how to release internal resources available thru handles. Removed all non universal ways of releasing crypt keys!
1 parent 18fdf25 commit 070c6b2

File tree

7 files changed

+66
-55
lines changed

7 files changed

+66
-55
lines changed

src/boot/natives.reb

+5
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ recycle: native [
247247
/torture {Constant recycle (for internal debugging)}
248248
]
249249

250+
release: native [
251+
"Release internal resources of the handle. Returns true on success."
252+
handle [handle!]
253+
]
254+
250255
reduce: native [
251256
{Evaluates expressions and returns multiple results.}
252257
value

src/core/n-crypt.c

+5-23
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
320320
// rsa: native [
321321
// "Encrypt/decrypt/sign/verify data using RSA cryptosystem. Only one refinement must be used!"
322322
// rsa-key [handle!] "RSA context created using `rsa-init` function"
323-
// data [binary! none!] "Data to work with. Use NONE to release the RSA handle resources!"
323+
// data [binary!] "Data to work with."
324324
// /encrypt "Use public key to encrypt data"
325325
// /decrypt "Use private key to decrypt data"
326326
// /sign "Use private key to sign data. Result is PKCS1 v1.5 binary"
@@ -369,12 +369,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
369369

370370
rsa = (RSA_CTX*)VAL_HANDLE_CONTEXT_DATA(key);
371371

372-
if (IS_NONE(val_data)) {
373-
// release RSA key resources
374-
Free_Hob(VAL_HANDLE_CTX(key));
375-
return R_TRUE;
376-
}
377-
378372
if(
379373
(mbedtls_rsa_check_pubkey(rsa) != 0) ||
380374
((refDecrypt || refSign) && (mbedtls_rsa_check_privkey(rsa) != 0))
@@ -510,18 +504,16 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
510504
// dh: native [
511505
// "Diffie-Hellman key exchange"
512506
// dh-key [handle!] "DH key created using `dh-init` function"
513-
// /release "Releases internal DH key resources"
514507
// /public "Returns public key as a binary"
515508
// /secret "Computes secret result using peer's public key"
516509
// public-key [binary!] "Peer's public key"
517510
// ]
518511
***********************************************************************/
519512
{
520513
REBVAL *key = D_ARG(1);
521-
REBOOL refRelease = D_REF(2);
522-
REBOOL refPublic = D_REF(3);
523-
REBOOL refSecret = D_REF(4);
524-
REBVAL *gy = D_ARG(5);
514+
REBOOL refPublic = D_REF(2);
515+
REBOOL refSecret = D_REF(3);
516+
REBVAL *gy = D_ARG(4);
525517

526518
REBSER *out = NULL;
527519
REBINT err;
@@ -556,10 +548,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
556548
if (err) goto error;
557549
BIN_LEN(out) = olen;
558550
}
559-
if (refRelease) {
560-
Free_Hob(VAL_HANDLE_CTX(key));
561-
if (!out) return R_TRUE;
562-
}
563551
SET_BINARY(D_RET, out);
564552
return R_RET;
565553
error:
@@ -582,7 +570,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
582570
// /public "Returns public key as a binary"
583571
// /secret "Computes secret result using peer's public key"
584572
// public-key [binary!] "Peer's public key"
585-
// /release "Releases internal ECDH key resources"
586573
// ]
587574
***********************************************************************/
588575
{
@@ -593,7 +580,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
593580
REBOOL ref_public = D_REF(5);
594581
REBOOL ref_secret = D_REF(6);
595582
REBVAL *val_public = D_ARG(7);
596-
REBOOL ref_release = D_REF(8);
597583

598584

599585
ECDH_CTX *ctx;
@@ -605,7 +591,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
605591

606592
// make sure that only valid combination of refinements is used!
607593
if (
608-
(ref_type && (ref_public || ref_secret || ref_release)) ||
594+
(ref_type && (ref_public || ref_secret )) ||
609595
(ref_public && (ref_type || ref_secret )) ||
610596
(ref_secret && (ref_public || ref_type ))
611597
) {
@@ -677,10 +663,6 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
677663
SET_BINARY(D_RET, bin);
678664
BIN_LEN(bin) = olen;
679665
}
680-
if (ref_release) {
681-
Free_Hob(VAL_HANDLE_CTX(val_handle));
682-
if (bin == NULL) return R_TRUE;
683-
}
684666
return R_RET;
685667

686668
error:

src/core/n-system.c

+14-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@
6868
DEAD_END;
6969
}
7070

71-
7271
/***********************************************************************
7372
**
7473
*/ REBNATIVE(recycle)
@@ -103,6 +102,20 @@
103102
return R_RET;
104103
}
105104

105+
/***********************************************************************
106+
**
107+
*/ REBNATIVE(release)
108+
/*
109+
***********************************************************************/
110+
{
111+
REBVAL *val = D_ARG(1);
112+
113+
if (IS_CONTEXT_HANDLE(val)) {
114+
Free_Hob(VAL_HANDLE_CTX(val));
115+
return R_TRUE;
116+
}
117+
return R_FALSE;
118+
}
106119

107120
/***********************************************************************
108121
**

src/mezz/prot-tls.reb

+10-7
Original file line numberDiff line numberDiff line change
@@ -929,7 +929,7 @@ client-key-exchange: function [
929929
key-data: rsa/encrypt rsa-key pre-secret
930930
key-data-len-bytes: 2
931931
log-more ["W[" seq-write "] key-data:" mold key-data]
932-
rsa rsa-key none ;@@ releases the internal RSA data, should be done by GC one day!
932+
release :rsa-key ; don't wait on GC and release it immediately
933933
]
934934
DHE_DSS
935935
DHE_RSA [
@@ -1747,7 +1747,7 @@ TLS-parse-handshake-message: function [
17471747
;decrypt the `signature` with server's public key
17481748
rsa-key: apply :rsa-init ctx/server-certs/1/public-key/rsaEncryption
17491749
also rsa/verify/hash rsa-key message signature hash-algorithm
1750-
rsa rsa-key none ;@@ releases the internal RSA data, should be done by GC one day!
1750+
release :rsa-key ; release it immediately, don't wait on GC
17511751
]
17521752
rsa_fixed_dh [
17531753
log-more "Checking signature using RSA_fixed_DH"
@@ -1775,18 +1775,21 @@ TLS-parse-handshake-message: function [
17751775
if dh_p [
17761776
dh-key: dh-init dh_g dh_p
17771777
ctx/pre-secret: dh/secret dh-key pub_key
1778-
log-more ["DH common secret:" ctx/pre-secret]
1779-
ctx/key-data: dh/public/release dh-key
1778+
log-more ["DH common secret:" mold ctx/pre-secret]
1779+
ctx/key-data: dh/public :dh-key
1780+
; release immediately, don't wait on GC
1781+
release :dh-key dh-key: none
17801782
]
17811783
if curve [
17821784
;- elyptic curve init
17831785
;curve is defined above (sent from server as well as server's public key)
17841786
dh-key: ecdh/init none curve
17851787
ctx/pre-secret: ecdh/secret dh-key pub_key
1786-
log-more ["ECDH common secret:^[[32m" ctx/pre-secret]
1788+
log-more ["ECDH common secret:^[[32m" mold ctx/pre-secret]
17871789
; resolve the public key to supply it to server
1788-
ctx/key-data: ecdh/public/release dh-key
1789-
dh-key: none
1790+
ctx/key-data: ecdh/public :dh-key
1791+
; release immediately, don't wait on GC
1792+
release :dh-key dh-key: none
17901793
]
17911794
]
17921795
CLIENT_KEY_EXCHANGE [

src/tests/units/crypt-test.r3

+15-9
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ YYFw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ
156156
--assert block? Load-PKIX pkix
157157
--assert binary? Load-PKIX/binary pkix
158158
--assert "#[handle! rsa]" = mold key: decode 'ssh-key pkix
159-
rsa key none ; release key
159+
release key ; don't wait on GC, release it now
160160

161161
--test-- "SSH-public-key-2"
162162
pkix:
@@ -223,28 +223,34 @@ sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV
223223
===start-group=== "SSH-key codec"
224224
--test-- "Init RSA key from file"
225225
--assert handle? try [key: decode 'ssh-key read %units/files/rebol-public.ppk]
226-
rsa key none ; release it, as it is not GCed yet.
226+
release key ; don't wait on GC, release it now
227227

228228
--test-- "Init public DH params from file"
229229
--assert all [
230230
handle? key: load %units/files/dhparam2048.key
231231
'dhm = query/mode key 'type
232-
dh/release key
232+
release key ; release it now (don't wait on GC)
233233
]
234234
===end-group===
235235

236236
===start-group=== "PPK codec"
237237
--test-- "Init RSA key from PPK file"
238-
--assert handle? try [key: load %units/files/rebol-private-no-pass.ppk]
239-
rsa key none ; release it, as it is not GCed yet.
238+
--assert all [
239+
handle? try [key: load %units/files/rebol-private-no-pass.ppk]
240+
release key ; don't wait on GC, release it now
241+
]
240242

241243
--test-- "Init RSA key from encrypted PPK file"
242-
--assert handle? try [key: codecs/ppk/decode/password %units/files/rebol-private.ppk "Rebol"]
243-
rsa key none ; release it, as it is not GCed yet.
244+
--assert all [
245+
handle? try [key: codecs/ppk/decode/password %units/files/rebol-private.ppk "Rebol"]
246+
release key ; don't wait on GC, release it now
247+
]
244248

245249
--test-- "Init public RSA key from SSH2 PPK file"
246-
--assert handle? try [key: load %units/files/rebol-public.ppk]
247-
rsa key none ; release it, as it is not GCed yet.
250+
--assert all [
251+
handle? try [key: load %units/files/rebol-public.ppk]
252+
release key ; don't wait on GC, release it now
253+
]
248254
===end-group===
249255

250256

src/tests/units/dh-test.r3

+9-8
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,12 @@ C79E915C3277361FBFA587C6DC06FEDE0B7E57FEC0B68F96B3AD651D54264357
5757

5858
;- Once done with the exchange, the DH key must be released!
5959

60-
--assert true? dh/release k-Alice
60+
--assert true? release k-Alice
6161
--assert none? dh/public k-Alice
6262

63-
;- the release may be also used while getting the secret
64-
65-
--assert binary? secret-Boban-2: dh/secret/release k-Boban pub-Alice
63+
--assert binary? secret-Boban-2: dh/secret k-Boban pub-Alice
6664
--assert secret-Boban = secret-Boban-2
65+
--assert true? release k-Boban
6766

6867
;- once released, the secret and public will be unavailable
6968

@@ -95,16 +94,18 @@ foreach ecurve system/catalog/elliptic-curves [
9594
;- These keys should be same on both sides
9695
--assert secret-Alice = secret-Boban
9796
;- Once done with the exchange, the ECDH key must be released!
98-
--assert true? ecdh/release k-Alice
97+
--assert true? release k-Alice
9998
--assert none? ecdh/public k-Alice
10099

101100
;- re-initialization...
102101
--assert handle? ecdh/init k-Alice ecurve ;- using existing key for a new init
103102
--assert binary? pub-Alice: ecdh/public k-Alice
104-
;- /release may be used with /secret
105-
--assert binary? secret-Alice: ecdh/secret/release k-Alice pub-Boban
106-
--assert binary? secret-Boban: ecdh/secret/release k-Boban pub-Alice
103+
--assert binary? secret-Alice: ecdh/secret k-Alice pub-Boban
104+
--assert binary? secret-Boban: ecdh/secret k-Boban pub-Alice
107105
--assert secret-Alice = secret-Boban
106+
; It is safe not to release (it would be done on GC), but it's better to do it
107+
--assert true? release k-Alice
108+
--assert true? release k-Boban
108109

109110
if find [curve25519 curve448] ecurve [
110111
; these curves are not for signing

src/tests/units/rsa-test.r3

+8-7
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@ Rebol [
9797
--assert rsa/verify key-pri bin-data sign-hash
9898

9999
--test-- "RSA key release"
100-
;once RSA key is not needed, release the resources using NONE data
101-
--assert rsa key-pub none
102-
--assert rsa key-pri none
100+
;once RSA key is not needed, release its resources
101+
;(it is safe not to manually release it. It would be released by GC, when unused)
102+
--assert release key-pub
103+
--assert release key-pri
103104
; released handle is now unusable:
104105
--assert error? try [rsa/verify/hash key-pub bin-data signature 'SHA512]
105106

@@ -139,18 +140,18 @@ Rebol [
139140
; so she knows, that data were not modified
140141

141142
; used keys should be released by GC, when not referenced, but we can release them immediately:
142-
rsa public-key none
143-
rsa private-key none
143+
release public-key
144+
release private-key
144145
===end-group===
145146

146147
===start-group=== "RSA initialization from file"
147148
--test-- "RSA private key from OpenSSL format (RSA PRIVATE KEY)"
148149
--assert handle? try [private-key: load %units/files/rebol-private-no-pass.key]
149-
rsa private-key none
150+
release private-key
150151
--test-- "RSA private key from OpenSSL x509 format (PRIVATE KEY)"
151152
; openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out MyCertificate.crt -keyout MyKey.key
152153
--assert handle? try [private-key: load %units/files/MyKey.key]
153-
rsa private-key none
154+
release private-key
154155
===end-group===
155156

156157

0 commit comments

Comments
 (0)