@@ -77,6 +77,35 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
77
77
void EVP_PKEY_free (EVP_PKEY * key );
78
78
int i2d_RSA (RSA * a , unsigned char ** out );
79
79
80
+ // Additional typedef of ECC operations (DER/RAW sig conversion)
81
+ typedef struct bignum_st BIGNUM;
82
+ BIGNUM *BN_new (void );
83
+ void BN_free (BIGNUM * a );
84
+ int BN_num_bits (const BIGNUM * a );
85
+ int BN_bn2bin (const BIGNUM * a , unsigned char * to );
86
+ BIGNUM *BN_bin2bn (const unsigned char * s , int len , BIGNUM * ret );
87
+ char *BN_bn2hex (const BIGNUM * a );
88
+
89
+
90
+ typedef struct ECDSA_SIG_st {
91
+ BIGNUM * r ;
92
+ BIGNUM * s ;} ECDSA_SIG;
93
+ ECDSA_SIG* ECDSA_SIG_new (void );
94
+ int i2d_ECDSA_SIG (const ECDSA_SIG * sig , unsigned char ** pp );
95
+ ECDSA_SIG* d2i_ECDSA_SIG (ECDSA_SIG ** sig , unsigned char ** pp ,
96
+ long len );
97
+ void ECDSA_SIG_free (ECDSA_SIG * sig );
98
+
99
+ typedef struct ecgroup_st EC_GROUP;
100
+ typedef struct eckey_st EC_KEY;
101
+
102
+ void EC_GROUP_free (EC_GROUP * group );
103
+ EC_GROUP *EC_KEY_get0_group (const EC_KEY * key );
104
+ void EC_KEY_free (EC_KEY * key );
105
+ EC_KEY *EVP_PKEY_get0_EC_KEY (EVP_PKEY * pkey );
106
+ int EC_GROUP_get_order (const EC_GROUP * group , BIGNUM * order , void * ctx );
107
+
108
+
80
109
// PUBKEY
81
110
EVP_PKEY *PEM_read_bio_PUBKEY (BIO * bp , EVP_PKEY ** x ,
82
111
pem_password_cb * cb , void * u );
@@ -365,6 +394,47 @@ function ECSigner.sign(self, message, digest_name)
365
394
return RSASigner .sign (self , message , digest_name )
366
395
end
367
396
397
+ --- Converts a ASN.1 DER signature to RAW r,s
398
+ -- @param signature The ASN.1 DER signature
399
+ -- @returns signature, error_string
400
+ function ECSigner .get_raw_sig (self , signature )
401
+ if not signature then
402
+ return nil , " Must pass a signature to convert"
403
+ end
404
+ local sig_ptr = ffi_new (" unsigned char *[1]" )
405
+ local sig_bin = ffi_new (" unsigned char [?]" , # signature )
406
+ ffi_copy (sig_bin , signature , # signature )
407
+
408
+ sig_ptr [0 ] = sig_bin
409
+ local sig = _C .d2i_ECDSA_SIG (nil , sig_ptr , # signature )
410
+ ffi_gc (sig , _C .ECDSA_SIG_free )
411
+
412
+ local rbytes = math.floor ((_C .BN_num_bits (sig .r )+ 7 )/ 8 )
413
+ local sbytes = math.floor ((_C .BN_num_bits (sig .s )+ 7 )/ 8 )
414
+
415
+ -- Ensure we copy the BN in a padded form
416
+ local ec = _C .EVP_PKEY_get0_EC_KEY (self .evp_pkey )
417
+ local ecgroup = _C .EC_KEY_get0_group (ec )
418
+
419
+ local order = _C .BN_new ()
420
+ ffi_gc (order , _C .BN_free )
421
+
422
+ -- res is an int, if 0, curve not found
423
+ local res = _C .EC_GROUP_get_order (ecgroup , order , nil )
424
+
425
+ -- BN_num_bytes is a #define, so have to use BN_num_bits
426
+ local order_size_bytes = math.floor ((_C .BN_num_bits (order )+ 7 )/ 8 )
427
+ local resbuf_len = order_size_bytes * 2
428
+ local resbuf = ffi_new (" unsigned char[?]" , resbuf_len )
429
+
430
+ -- Let's whilst preserving MSB
431
+ _C .BN_bn2bin (sig .r , resbuf + order_size_bytes - rbytes )
432
+ _C .BN_bn2bin (sig .s , resbuf + (order_size_bytes * 2 ) - sbytes )
433
+
434
+ local raw = ffi_string (resbuf , resbuf_len )
435
+ return raw , nil
436
+ end
437
+
368
438
local RSAVerifier = {}
369
439
_M .RSAVerifier = RSAVerifier
370
440
@@ -418,6 +488,56 @@ function RSAVerifier.verify(self, message, sig, digest_name)
418
488
end
419
489
end
420
490
491
+ --- Converts a RAW r,s signature to ASN.1 DER signature (ECDSA)
492
+ -- @param signature The raw signature
493
+ -- @returns signature, error_string
494
+ function RSAVerifier .get_der_sig (self , signature )
495
+ -- TODO: should be declared in a new class rather than RSAVerifier
496
+ if not signature then
497
+ return nil , " Must pass a signature to convert"
498
+ end
499
+ -- inspired from https://bit.ly/2yZxzxJ
500
+ local ec = _C .EVP_PKEY_get0_EC_KEY (self .evp_pkey )
501
+ local ecgroup = _C .EC_KEY_get0_group (ec )
502
+
503
+ local order = _C .BN_new ()
504
+ ffi_gc (order , _C .BN_free )
505
+
506
+ -- res is an int, if 0, curve not found
507
+ local res = _C .EC_GROUP_get_order (ecgroup , order , nil )
508
+
509
+ -- BN_num_bytes is a #define, so have to use BN_num_bits
510
+ local order_size_bytes = math.floor ((_C .BN_num_bits (order )+ 7 )/ 8 )
511
+
512
+ if # signature ~= 2 * order_size_bytes then
513
+ return nil , " signature length != 2 * order length"
514
+ end
515
+
516
+ local sig_bytes = ffi_new (" unsigned char [?]" , # signature )
517
+ ffi_copy (sig_bytes , signature , # signature )
518
+ local ecdsa = _C .ECDSA_SIG_new ()
519
+ ffi_gc (ecdsa , _C .ECDSA_SIG_free )
520
+
521
+ local r = _C .BN_bin2bn (sig_bytes , order_size_bytes , nil )
522
+ local s = _C .BN_bin2bn (sig_bytes + order_size_bytes , order_size_bytes , nil )
523
+ ffi_gc (r , _C .BN_free )
524
+ ffi_gc (s , _C .BN_free )
525
+
526
+ ecdsa .r = r
527
+ ecdsa .s = s
528
+
529
+ -- Gives us the buffer size to allocate
530
+ local der_len = _C .i2d_ECDSA_SIG (ecdsa , nil )
531
+
532
+ local der_sig_ptr = ffi_new (" unsigned char *[1]" )
533
+ local der_sig_bin = ffi_new (" unsigned char [?]" , der_len )
534
+ der_sig_ptr [0 ] = der_sig_bin
535
+ der_len = _C .i2d_ECDSA_SIG (ecdsa , der_sig_ptr )
536
+
537
+ local der_str = ffi_string (der_sig_bin , der_len )
538
+ return der_str , nil
539
+ end
540
+
421
541
422
542
local Cert = {}
423
543
_M .Cert = Cert
0 commit comments