mirror of
https://github.com/vlang/v.git
synced 2025-09-14 23:12:33 +03:00
crypto.ecdsa: clean out old deprecated keypair opaque from the module, make -cstrict pass for all the tests, and with both gcc and clang (#23887)
This commit is contained in:
parent
03d033fa4b
commit
309aebfaf1
4 changed files with 119 additions and 417 deletions
|
@ -37,26 +37,34 @@ pub fn pubkey_from_bytes(bytes []u8) !PublicKey {
|
|||
return error('Get an nid of non ecPublicKey')
|
||||
}
|
||||
|
||||
eckey := C.EVP_PKEY_get1_EC_KEY(pub_key)
|
||||
if eckey == 0 {
|
||||
C.EC_KEY_free(eckey)
|
||||
return error('Failed to get ec key')
|
||||
// check the key
|
||||
pctx := C.EVP_PKEY_CTX_new(pub_key, 0)
|
||||
if pctx == 0 {
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(pub_key)
|
||||
return error('EVP_PKEY_CTX_new failed')
|
||||
}
|
||||
// check the group for the supported curve(s)
|
||||
group := voidptr(C.EC_KEY_get0_group(eckey))
|
||||
if group == 0 {
|
||||
C.EC_GROUP_free(group)
|
||||
return error('Failed to load group from key')
|
||||
// performs public-only evpkey check
|
||||
nck := C.EVP_PKEY_public_check(pctx)
|
||||
if nck != 1 {
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(pub_key)
|
||||
return error('EVP_PKEY_check failed')
|
||||
}
|
||||
nidgroup := C.EC_GROUP_get_curve_name(group)
|
||||
if nidgroup != nid_prime256v1 && nidgroup != nid_secp384r1 && nidgroup != nid_secp521r1
|
||||
&& nidgroup != nid_secp256k1 {
|
||||
// Matching the supported group
|
||||
gn := key_group_name(pub_key)!
|
||||
// TODO: using shortname constant
|
||||
if gn != 'secp256k1' && gn != 'secp384r1' && gn != 'secp521r1' && gn != 'prime256v1' {
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(pub_key)
|
||||
return error('Unsupported group')
|
||||
}
|
||||
C.EVP_PKEY_free(pub_key)
|
||||
// Cleans up
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
|
||||
// Its OK to return
|
||||
return PublicKey{
|
||||
key: eckey
|
||||
evpkey: pub_key
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,10 +91,13 @@ pub fn pubkey_from_string(s string) !PublicKey {
|
|||
mut evpkey := C.EVP_PKEY_new()
|
||||
bo := C.BIO_new(C.BIO_s_mem())
|
||||
if bo == 0 {
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
C.BIO_free_all(bo)
|
||||
return error('Failed to create BIO_new')
|
||||
}
|
||||
n := C.BIO_write(bo, s.str, s.len)
|
||||
if n <= 0 {
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
C.BIO_free_all(bo)
|
||||
return error('BIO_write failed')
|
||||
}
|
||||
|
@ -104,33 +115,38 @@ pub fn pubkey_from_string(s string) !PublicKey {
|
|||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Get an nid of non ecPublicKey')
|
||||
}
|
||||
// Gets the ec key
|
||||
eckey := C.EVP_PKEY_get1_EC_KEY(evpkey)
|
||||
if eckey == 0 {
|
||||
// check the key
|
||||
pctx := C.EVP_PKEY_CTX_new(evpkey, 0)
|
||||
if pctx == 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Failed to get ec key')
|
||||
return error('EVP_PKEY_CTX_new failed')
|
||||
}
|
||||
// check the group for the supported curve(s)
|
||||
if !is_valid_supported_group(eckey) {
|
||||
// performs public-only evpkey check
|
||||
nck := C.EVP_PKEY_public_check(pctx)
|
||||
if nck != 1 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('EVP_PKEY_check failed')
|
||||
}
|
||||
// Matching the supported group
|
||||
gn := key_group_name(evpkey)!
|
||||
// TODO: using shortname constant
|
||||
if gn != 'secp256k1' && gn != 'secp384r1' && gn != 'secp521r1' && gn != 'prime256v1' {
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Unsupported group')
|
||||
}
|
||||
chk := C.EC_KEY_check_key(eckey)
|
||||
if chk == 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('EC_KEY_check_key failed')
|
||||
}
|
||||
// Cleans up
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
|
||||
// Its OK to return
|
||||
return PublicKey{
|
||||
evpkey: evpkey
|
||||
key: eckey
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,11 +162,14 @@ pub fn privkey_from_string(s string) !PrivateKey {
|
|||
mut evpkey := C.EVP_PKEY_new()
|
||||
bo := C.BIO_new(C.BIO_s_mem())
|
||||
if bo == 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Failed to create BIO_new')
|
||||
}
|
||||
n := C.BIO_write(bo, s.str, s.len)
|
||||
if n <= 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('BIO_write failed')
|
||||
}
|
||||
evpkey = C.PEM_read_bio_PrivateKey(bo, &evpkey, 0, 0)
|
||||
|
@ -168,66 +187,61 @@ pub fn privkey_from_string(s string) !PrivateKey {
|
|||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Get an nid of non ecPublicKey')
|
||||
}
|
||||
|
||||
eckey := C.EVP_PKEY_get1_EC_KEY(evpkey)
|
||||
if eckey == 0 {
|
||||
pctx := C.EVP_PKEY_CTX_new(evpkey, 0)
|
||||
if pctx == 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Failed to get ec key')
|
||||
return error('EVP_PKEY_CTX_new failed')
|
||||
}
|
||||
// check the group for the supported curve(s)
|
||||
if !is_valid_supported_group(eckey) {
|
||||
// performs evpkey check
|
||||
nck := C.EVP_PKEY_check(pctx)
|
||||
if nck != 1 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('EVP_PKEY_check failed')
|
||||
}
|
||||
// Matching the supported group
|
||||
gn := key_group_name(evpkey)!
|
||||
// TODO: using shortname constant
|
||||
if gn != 'secp256k1' && gn != 'secp384r1' && gn != 'secp521r1' && gn != 'prime256v1' {
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('Unsupported group')
|
||||
}
|
||||
|
||||
chk := C.EC_KEY_check_key(eckey)
|
||||
if chk == 0 {
|
||||
C.BIO_free_all(bo)
|
||||
C.EC_KEY_free(eckey)
|
||||
C.EVP_PKEY_free(evpkey)
|
||||
return error('EC_KEY_check_key failed')
|
||||
}
|
||||
ksize := ec_key_size(eckey)!
|
||||
|
||||
// Cleans up
|
||||
C.BIO_free_all(bo)
|
||||
C.EVP_PKEY_CTX_free(pctx)
|
||||
|
||||
// Its OK to return
|
||||
return PrivateKey{
|
||||
evpkey: evpkey
|
||||
key: eckey
|
||||
ks_flag: .fixed
|
||||
ks_size: ksize
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
//
|
||||
// is_valid_supported_group checks whether this eckey has valid group of supported curve.
|
||||
@[inline]
|
||||
fn is_valid_supported_group(eckey &C.EC_KEY) bool {
|
||||
group := voidptr(C.EC_KEY_get0_group(eckey))
|
||||
if group == 0 {
|
||||
return false
|
||||
}
|
||||
nidgroup := C.EC_GROUP_get_curve_name(group)
|
||||
if nidgroup == nid_prime256v1 || nidgroup == nid_secp384r1 || nidgroup == nid_secp521r1
|
||||
|| nidgroup == nid_secp256k1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// key_size get the key size of this ec key
|
||||
fn ec_key_size(ec_key &C.EC_KEY) !int {
|
||||
group := voidptr(C.EC_KEY_get0_group(ec_key))
|
||||
if group == 0 {
|
||||
return error('Unable to load group')
|
||||
}
|
||||
num_bits := C.EC_GROUP_get_degree(group)
|
||||
// evp_key_size get the key size of this ec key
|
||||
fn evp_key_size(key &C.EVP_PKEY) !int {
|
||||
num_bits := C.EVP_PKEY_get_bits(key)
|
||||
key_size := (num_bits + 7) / 8
|
||||
|
||||
return key_size
|
||||
}
|
||||
|
||||
const default_groupname_size = 25 // short name commonly only take 10-15 length
|
||||
|
||||
// key_group_name returns underlying group name of the key as a string.
|
||||
fn key_group_name(key &C.EVP_PKEY) !string {
|
||||
gname := []u8{len: default_groupname_size}
|
||||
gname_len := usize(0)
|
||||
mut s := C.EVP_PKEY_get_group_name(key, gname.data, u32(gname.len), &gname_len)
|
||||
if s == 0 {
|
||||
unsafe { gname.free() }
|
||||
return error('fail to get group name')
|
||||
}
|
||||
group := gname[..gname_len].bytestr()
|
||||
unsafe { gname.free() }
|
||||
return group
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue