@@ -62,45 +62,17 @@ pub fn pubkey_from_bytes(bytes []u8) !PublicKey {
6262
6363// bytes gets the bytes of public key.
6464pub 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