Skip to content

Commit ddedadf

Browse files
committed
crypto.ecdsa: the last bits of migration steps
1 parent 4236baf commit ddedadf

File tree

3 files changed

+27
-44
lines changed

3 files changed

+27
-44
lines changed

vlib/crypto/ecdsa/ecdsa.c.v

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ fn C.EVP_PKEY_bits(pkey &C.EVP_PKEY) int
4444
fn C.EVP_PKEY_size(key &C.EVP_PKEY) int
4545
fn C.EVP_PKEY_eq(a &C.EVP_PKEY, b &C.EVP_PKEY) int
4646

47+
fn C.EVP_PKEY_get1_encoded_public_key(pkey &C.EVP_PKEY, ppub &&u8) int
48+
fn C.EVP_PKEY_get_bn_param(pkey &C.EVP_PKEY, key_name &u8, bn &&C.BIGNUM) int
4749
fn C.EVP_PKEY_fromdata_init(ctx &C.EVP_PKEY_CTX) int
4850
fn C.EVP_PKEY_fromdata(ctx &C.EVP_PKEY_CTX, ppkey &&C.EVP_PKEY, selection int, params &C.OSSL_PARAM) int
4951

@@ -143,6 +145,7 @@ fn C.EC_GROUP_new_by_curve_name(nid int) &C.EC_GROUP
143145
@[typedef]
144146
struct C.BIGNUM {}
145147

148+
fn C.BN_new() &C.BIGNUM
146149
fn C.BN_num_bits(a &C.BIGNUM) int
147150
fn C.BN_bn2bin(a &C.BIGNUM, to &u8) int
148151
fn C.BN_bn2binpad(a &C.BIGNUM, to &u8, tolen int) int

vlib/crypto/ecdsa/ecdsa.v

+8-4
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,12 @@ fn (pv PrivateKey) sign_digest(digest []u8) ![]u8 {
289289

290290
// bytes represent private key as bytes.
291291
pub fn (pv PrivateKey) bytes() ![]u8 {
292-
// This is the old one
293-
bn := voidptr(C.EC_KEY_get0_private_key(pv.key))
294-
if bn == 0 {
295-
return error('Failed to get private key BIGNUM')
292+
bn := C.BN_new()
293+
// retrieves a BIGNUM value associated with a 'priv' key name
294+
n := C.EVP_PKEY_get_bn_param(pv.evpkey, c'priv', &bn)
295+
if n <= 0 {
296+
C.BN_free(bn)
297+
return error('EVP_PKEY_get_bn_param failed')
296298
}
297299
num_bytes := (C.BN_num_bits(bn) + 7) / 8
298300
// Get the buffer size to store the seed.
@@ -305,8 +307,10 @@ pub fn (pv PrivateKey) bytes() ![]u8 {
305307
mut buf := []u8{len: int(size)}
306308
res := C.BN_bn2binpad(bn, buf.data, size)
307309
if res == 0 {
310+
C.BN_free(bn)
308311
return error('Failed to convert BIGNUM to bytes')
309312
}
313+
C.BN_free(bn)
310314
return buf
311315
}
312316

vlib/crypto/ecdsa/util.v

+16-40
Original file line numberDiff line numberDiff line change
@@ -62,45 +62,17 @@ pub fn pubkey_from_bytes(bytes []u8) !PublicKey {
6262

6363
// bytes gets the bytes of public key.
6464
pub fn (pbk PublicKey) bytes() ![]u8 {
65-
point := voidptr(C.EC_KEY_get0_public_key(pbk.key))
66-
// defer { C.EC_POINT_free(point)}
67-
if point == 0 {
68-
C.EC_POINT_free(point)
69-
return error('Failed to get public key BIGNUM')
70-
}
71-
72-
group := voidptr(C.EC_KEY_get0_group(pbk.key))
73-
num_bits := C.EC_GROUP_get_degree(group)
74-
// 1 byte of conversion format || x || y of EC_POINT
75-
num_bytes := 1 + 2 * ((num_bits + 7) / 8)
76-
77-
ctx := C.BN_CTX_new()
78-
defer {
79-
C.BN_CTX_free(ctx)
80-
}
81-
82-
if ctx == 0 {
83-
C.EC_POINT_free(point)
84-
C.BN_CTX_free(ctx)
85-
return error('Failed to create BN_CTX')
65+
ppub := []u8{len: default_point_bufsize}
66+
n := C.EVP_PKEY_get1_encoded_public_key(pbk.evpkey, voidptr(&ppub.data))
67+
if n <= 0 {
68+
C.OPENSSL_free(voidptr(ppub.data))
69+
return error('EVP_PKEY_get1_encoded_public_key failed')
8670
}
87-
mut buf := []u8{len: num_bytes}
71+
out := ppub[..n].clone()
72+
// ppub should be freed by calling `OPENSSL_free` or memleak happens.
73+
C.OPENSSL_free(voidptr(ppub.data))
8874

89-
// Get conversion format.
90-
//
91-
// The uncompressed form is indicated by 0x04 and the compressed form is indicated
92-
// by either 0x02 or 0x03, hybrid 0x06
93-
// The public key MUST be rejected if any other value is included in the first octet.
94-
conv_form := C.EC_KEY_get_conv_form(pbk.key)
95-
if conv_form !in [2, 3, 4, 6] {
96-
return error('bad conversion format')
97-
}
98-
n := C.EC_POINT_point2oct(group, point, conv_form, buf.data, buf.len, ctx)
99-
if n == 0 {
100-
return error('EC_POINT_point2oct failed')
101-
}
102-
// returns the clone of the buffer[..n]
103-
return buf[..n].clone()
75+
return out
10476
}
10577

10678
// pubkey_from_string loads a PublicKey from valid PEM-formatted string in s.
@@ -149,14 +121,16 @@ pub fn pubkey_from_string(s string) !PublicKey {
149121
}
150122
chk := C.EC_KEY_check_key(eckey)
151123
if chk == 0 {
124+
C.BIO_free_all(bo)
152125
C.EC_KEY_free(eckey)
126+
C.EVP_PKEY_free(evpkey)
153127
return error('EC_KEY_check_key failed')
154128
}
155-
C.EVP_PKEY_free(evpkey)
156129
C.BIO_free_all(bo)
157130
// Its OK to return
158131
return PublicKey{
159-
key: eckey
132+
evpkey: evpkey
133+
key: eckey
160134
}
161135
}
162136

@@ -212,16 +186,18 @@ pub fn privkey_from_string(s string) !PrivateKey {
212186

213187
chk := C.EC_KEY_check_key(eckey)
214188
if chk == 0 {
189+
C.BIO_free_all(bo)
215190
C.EC_KEY_free(eckey)
191+
C.EVP_PKEY_free(evpkey)
216192
return error('EC_KEY_check_key failed')
217193
}
218194
ksize := ec_key_size(eckey)!
219195

220-
C.EVP_PKEY_free(evpkey)
221196
C.BIO_free_all(bo)
222197

223198
// Its OK to return
224199
return PrivateKey{
200+
evpkey: evpkey
225201
key: eckey
226202
ks_flag: .fixed
227203
ks_size: ksize

0 commit comments

Comments
 (0)