@@ -308,9 +308,11 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
308
308
// data [binary! none!] "Data to work with. Use NONE to release the RSA handle resources!"
309
309
// /encrypt "Use public key to encrypt data"
310
310
// /decrypt "Use private key to decrypt data"
311
- // /sign "Use private key to sign data"
311
+ // /sign "Use private key to sign data. Result is PKCS1 v1.5 binary "
312
312
// /verify "Use public key to verify signed data (returns TRUE or FALSE)"
313
- // signature [binary!] "Result of the sign call"
313
+ // signature [binary!] "Result of the /sign call"
314
+ // /hash "Signature's message digest algorithm"
315
+ // algorithm [word!] "Default value is SHA256"
314
316
// ]
315
317
***********************************************************************/
316
318
{
@@ -324,20 +326,23 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
324
326
REBOOL refSign = D_REF (5 );
325
327
REBOOL refVerify = D_REF (6 );
326
328
REBVAL * val_sign = D_ARG (7 );
329
+ REBOOL refHash = D_REF (8 );
330
+ REBVAL * val_hash = D_ARG (9 );
327
331
328
332
RSA_CTX * rsa ;
329
333
REBSER * data ;
330
334
REBYTE * inBinary ;
331
335
REBYTE * outBinary ;
332
- REBYTE hash [32 ];
336
+ REBYTE hash [64 ];
333
337
REBINT inBytes ;
334
338
REBINT outBytes ;
335
339
REBINT err = 0 ;
340
+ mbedtls_md_type_t md_alg ;
336
341
337
342
// make sure that only one refinement is used!
338
343
if (
339
- (refEncrypt && (refDecrypt || refSign || refVerify )) ||
340
- (refDecrypt && (refEncrypt || refSign || refVerify )) ||
344
+ (refEncrypt && (refDecrypt || refSign || refVerify || refHash )) ||
345
+ (refDecrypt && (refEncrypt || refSign || refVerify || refHash )) ||
341
346
(refSign && (refDecrypt || refEncrypt || refVerify )) ||
342
347
(refVerify && (refDecrypt || refSign || refEncrypt ))
343
348
) {
@@ -365,10 +370,26 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
365
370
inBinary = BIN_DATA (data );
366
371
inBytes = BIN_LEN (data );
367
372
368
- if (refVerify ) {
369
- SHA256 (inBinary , inBytes , hash );
370
- err = mbedtls_rsa_rsassa_pkcs1_v15_verify (rsa , MBEDTLS_MD_SHA256 , 32 , hash , VAL_BIN (val_sign ));
371
- return (err == 0 ) ? R_TRUE : R_FALSE ;
373
+ if (refVerify || refSign ) {
374
+ if (IS_NONE (val_hash )) {
375
+ md_alg = MBEDTLS_MD_NONE ;
376
+ }
377
+ else {
378
+ // count message digest off the input data
379
+ if (Message_Digest (hash , inBinary , inBytes , VAL_WORD_CANON (val_hash ), & inBytes )) {
380
+ // map Rebol word to mbedtls_md_type_t (expets that have same order!)
381
+ // no need to test a range as only known will pass above run
382
+ md_alg = VAL_WORD_CANON (val_hash ) - SYM_MD5 + 1 ;
383
+ inBinary = hash ;
384
+ }
385
+ else {
386
+ return R_NONE ;
387
+ }
388
+ }
389
+ if (refVerify ) {
390
+ err = mbedtls_rsa_rsassa_pkcs1_v15_verify (rsa , md_alg , inBytes , inBinary , VAL_BIN (val_sign ));
391
+ return (err == 0 ) ? R_TRUE : R_FALSE ;
392
+ }
372
393
}
373
394
374
395
//allocate new binary!
@@ -377,8 +398,7 @@ static int myrand(void *rng_state, unsigned char *output, size_t len)
377
398
outBinary = BIN_DATA (data );
378
399
379
400
if (refSign ) {
380
- SHA256 (inBinary , inBytes , hash );
381
- err = mbedtls_rsa_rsassa_pkcs1_v15_sign (rsa , mbedtls_ctr_drbg_random , & ctr_drbg , MBEDTLS_MD_SHA256 , 32 , hash , outBinary );
401
+ err = mbedtls_rsa_rsassa_pkcs1_v15_sign (rsa , mbedtls_ctr_drbg_random , & ctr_drbg , md_alg , inBytes , inBinary , outBinary );
382
402
}
383
403
else if (refEncrypt ) {
384
404
err = mbedtls_rsa_rsaes_pkcs1_v15_encrypt (rsa , mbedtls_ctr_drbg_random , & ctr_drbg , inBytes , inBinary , outBinary );
0 commit comments