From 1eaa7c81fad50a641ce2fc09bfcd8603800bf8d5 Mon Sep 17 00:00:00 2001 From: blackshirt Date: Mon, 27 Jan 2025 13:03:19 +0700 Subject: [PATCH] crypto.ecdsa: split out the C wrapper to a new .c.v file (#23595) --- vlib/crypto/ecdsa/ecdsa.c.v | 109 ++++++++++++++++++++++++++++++++++++ vlib/crypto/ecdsa/ecdsa.v | 72 ++++-------------------- vlib/crypto/ecdsa/util.v | 67 ---------------------- 3 files changed, 119 insertions(+), 129 deletions(-) create mode 100644 vlib/crypto/ecdsa/ecdsa.c.v diff --git a/vlib/crypto/ecdsa/ecdsa.c.v b/vlib/crypto/ecdsa/ecdsa.c.v new file mode 100644 index 0000000000..f3f624cd98 --- /dev/null +++ b/vlib/crypto/ecdsa/ecdsa.c.v @@ -0,0 +1,109 @@ +// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module ecdsa + +// See https://docs.openssl.org/master/man7/openssl_user_macros/#description +// should be 0x30000000L, but a lot of EC_KEY method was deprecated on version 3.0 +// #define OPENSSL_API_COMPAT 0x10100000L + +#flag darwin -L /opt/homebrew/opt/openssl/lib -I /opt/homebrew/opt/openssl/include + +#flag -I/usr/include/openssl +#flag -lcrypto +#flag darwin -I/usr/local/opt/openssl/include +#flag darwin -L/usr/local/opt/openssl/lib +#include +#include +#include +#include +#include +#include +#include +#include + +// The new opaque of public key pair high level API +@[typedef] +struct C.EVP_PKEY {} + +fn C.EVP_PKEY_new() &C.EVP_PKEY +fn C.EVP_PKEY_free(key &C.EVP_PKEY) +fn C.EVP_PKEY_get1_EC_KEY(pkey &C.EVP_PKEY) &C.EC_KEY +fn C.EVP_PKEY_base_id(key &C.EVP_PKEY) int + +// Elliptic curve keypair declarations +@[typedef] +struct C.EC_KEY {} + +fn C.EC_KEY_new_by_curve_name(nid int) &C.EC_KEY +fn C.EC_KEY_generate_key(key &C.EC_KEY) int +fn C.EC_KEY_dup(src &C.EC_KEY) &C.EC_KEY +fn C.EC_KEY_free(key &C.EC_KEY) +fn C.EC_KEY_set_public_key(key &C.EC_KEY, &C.EC_POINT) int +fn C.EC_KEY_set_private_key(key &C.EC_KEY, prv &C.BIGNUM) int +fn C.EC_KEY_get0_group(key &C.EC_KEY) &C.EC_GROUP +fn C.EC_KEY_get0_private_key(key &C.EC_KEY) &C.BIGNUM +fn C.EC_KEY_get0_public_key(key &C.EC_KEY) &C.EC_POINT +fn C.EC_KEY_get_conv_form(k &C.EC_KEY) int +fn C.EC_KEY_check_key(key &C.EC_KEY) int +fn C.EC_KEY_up_ref(key &C.EC_KEY) int + +// BIO input output declarations. +@[typedef] +struct C.BIO_METHOD {} + +@[typedef] +pub struct C.BIO {} + +fn C.BIO_new(t &C.BIO_METHOD) &C.BIO +fn C.BIO_free_all(a &C.BIO) +fn C.BIO_s_mem() &C.BIO_METHOD +fn C.BIO_write(b &C.BIO, buf &u8, length int) int +fn C.PEM_read_bio_PrivateKey(bp &C.BIO, x &&C.EVP_PKEY, cb int, u &voidptr) &C.EVP_PKEY +fn C.PEM_read_bio_PUBKEY(bp &C.BIO, x &&C.EVP_PKEY, cb int, u &voidptr) &C.EVP_PKEY +fn C.d2i_PUBKEY(k &&C.EVP_PKEY, pp &&u8, length u32) &C.EVP_PKEY + +// Elliptic curve point related declarations. +@[typedef] +struct C.EC_POINT {} + +fn C.EC_POINT_new(group &C.EC_GROUP) &C.EC_POINT +fn C.EC_POINT_mul(group &C.EC_GROUP, r &C.EC_POINT, n &C.BIGNUM, q &C.EC_POINT, m &C.BIGNUM, ctx &C.BN_CTX) int +fn C.EC_POINT_point2oct(g &C.EC_GROUP, p &C.EC_POINT, form int, buf &u8, max_out int, ctx &C.BN_CTX) int +fn C.EC_POINT_cmp(group &C.EC_GROUP, a &C.EC_POINT, b &C.EC_POINT, ctx &C.BN_CTX) int +fn C.EC_POINT_free(point &C.EC_POINT) + +// Elliptic group (curve) related declarations. +@[typedef] +struct C.EC_GROUP {} + +fn C.EC_GROUP_free(group &C.EC_GROUP) +fn C.EC_GROUP_get_degree(g &C.EC_GROUP) int +fn C.EC_GROUP_get_curve_name(g &C.EC_GROUP) int +fn C.EC_GROUP_cmp(a &C.EC_GROUP, b &C.EC_GROUP, ctx &C.BN_CTX) int + +// Elliptic BIGNUM related declarations. +@[typedef] +struct C.BIGNUM {} + +fn C.BN_num_bits(a &C.BIGNUM) int +fn C.BN_bn2bin(a &C.BIGNUM, to &u8) int +fn C.BN_bn2binpad(a &C.BIGNUM, to &u8, tolen int) int +fn C.BN_cmp(a &C.BIGNUM, b &C.BIGNUM) int +fn C.BN_bin2bn(s &u8, len int, ret &C.BIGNUM) &C.BIGNUM +fn C.BN_free(a &C.BIGNUM) + +// BIGNUM context +@[typedef] +struct C.BN_CTX {} + +fn C.BN_CTX_new() &C.BN_CTX +fn C.BN_CTX_free(ctx &C.BN_CTX) + +// ELliptic ECDSA signing and verifying related declarations. +@[typedef] +struct C.ECDSA_SIG {} + +fn C.ECDSA_size(key &C.EC_KEY) u32 +fn C.ECDSA_sign(type_ int, dgst &u8, dgstlen int, sig &u8, siglen &u32, eckey &C.EC_KEY) int +fn C.ECDSA_verify(type_ int, dgst &u8, dgstlen int, sig &u8, siglen int, eckey &C.EC_KEY) int diff --git a/vlib/crypto/ecdsa/ecdsa.v b/vlib/crypto/ecdsa/ecdsa.v index 93855e3bc4..3e4ef3ee77 100644 --- a/vlib/crypto/ecdsa/ecdsa.v +++ b/vlib/crypto/ecdsa/ecdsa.v @@ -8,50 +8,6 @@ import crypto import crypto.sha256 import crypto.sha512 -// See https://docs.openssl.org/master/man7/openssl_user_macros/#description -// should be 0x30000000L, but a lot of EC_KEY method was deprecated on version 3.0 -// #define OPENSSL_API_COMPAT 0x10100000L - -#flag darwin -L /opt/homebrew/opt/openssl/lib -I /opt/homebrew/opt/openssl/include - -#flag -I/usr/include/openssl -#flag -lcrypto -#flag darwin -I/usr/local/opt/openssl/include -#flag darwin -L/usr/local/opt/openssl/lib -#include -#include -#include -#include - -// C function declarations -fn C.EC_KEY_new_by_curve_name(nid int) &C.EC_KEY -fn C.EC_KEY_dup(src &C.EC_KEY) &C.EC_KEY -fn C.EC_KEY_generate_key(key &C.EC_KEY) int -fn C.EC_KEY_free(key &C.EC_KEY) -fn C.EC_KEY_set_public_key(key &C.EC_KEY, &C.EC_POINT) int -fn C.EC_KEY_set_private_key(key &C.EC_KEY, prv &C.BIGNUM) int -fn C.EC_KEY_get0_group(key &C.EC_KEY) &C.EC_GROUP -fn C.EC_KEY_get0_private_key(key &C.EC_KEY) &C.BIGNUM -fn C.EC_KEY_get0_public_key(key &C.EC_KEY) &C.EC_POINT -fn C.EC_KEY_check_key(key &C.EC_KEY) int -fn C.EC_KEY_up_ref(key &C.EC_KEY) int -fn C.EC_POINT_new(group &C.EC_GROUP) &C.EC_POINT -fn C.EC_POINT_mul(group &C.EC_GROUP, r &C.EC_POINT, n &C.BIGNUM, q &C.EC_POINT, m &C.BIGNUM, ctx &C.BN_CTX) int -fn C.EC_POINT_cmp(group &C.EC_GROUP, a &C.EC_POINT, b &C.EC_POINT, ctx &C.BN_CTX) int -fn C.EC_POINT_free(point &C.EC_POINT) -fn C.EC_GROUP_cmp(a &C.EC_GROUP, b &C.EC_GROUP, ctx &C.BN_CTX) int -fn C.BN_num_bits(a &C.BIGNUM) int -fn C.BN_bn2bin(a &C.BIGNUM, to &u8) int -fn C.BN_bn2binpad(a &C.BIGNUM, to &u8, tolen int) int -fn C.BN_cmp(a &C.BIGNUM, b &C.BIGNUM) int -fn C.BN_CTX_new() &C.BN_CTX -fn C.BN_CTX_free(ctx &C.BN_CTX) -fn C.BN_bin2bn(s &u8, len int, ret &C.BIGNUM) &C.BIGNUM -fn C.BN_free(a &C.BIGNUM) -fn C.ECDSA_size(key &C.EC_KEY) u32 -fn C.ECDSA_sign(type_ int, dgst &u8, dgstlen int, sig &u8, siglen &u32, eckey &C.EC_KEY) int -fn C.ECDSA_verify(type_ int, dgst &u8, dgstlen int, sig &u8, siglen int, eckey &C.EC_KEY) int - // NID constants // // NIST P-256 is refered to as secp256r1 and prime256v1, defined as #define NID_X9_62_prime256v1 415 @@ -68,6 +24,9 @@ const nid_secp521r1 = C.NID_secp521r1 // Bitcoin curve, defined as #define NID_secp256k1 714 const nid_secp256k1 = C.NID_secp256k1 +// #define NID_X9_62_id_ecPublicKey 408 +const nid_ec_publickey = C.NID_X9_62_id_ecPublicKey + // The list of supported curve(s) pub enum Nid { prime256v1 @@ -87,24 +46,6 @@ pub mut: fixed_size bool } -@[typedef] -struct C.EC_KEY {} - -@[typedef] -struct C.EC_GROUP {} - -@[typedef] -struct C.BIGNUM {} - -@[typedef] -struct C.EC_POINT {} - -@[typedef] -struct C.ECDSA_SIG {} - -@[typedef] -struct C.BN_CTX {} - // enum flag to allow flexible PrivateKey size enum KeyFlag { // flexible flag to allow flexible-size of seed bytes @@ -116,6 +57,10 @@ enum KeyFlag { // PrivateKey represents ECDSA private key. Actually its a key pair, // contains private key and public key parts. pub struct PrivateKey { + // The new high level of keypair opaque, set to nil now. + evpkey &C.EVP_PKEY = unsafe { nil } + // TODO: when all has been migrated to the new one, + // removes this low level declarations. key &C.EC_KEY mut: // ks_flag with .flexible value allowing @@ -129,6 +74,9 @@ mut: // PublicKey represents ECDSA public key for verifying message. pub struct PublicKey { + // The new high level of keypair opaque, set to nil now. + evpkey &C.EVP_PKEY = unsafe { nil } + // Remove this when its fully obsoleted by the new one. key &C.EC_KEY } diff --git a/vlib/crypto/ecdsa/util.v b/vlib/crypto/ecdsa/util.v index 0ee1c8f933..b804460598 100644 --- a/vlib/crypto/ecdsa/util.v +++ b/vlib/crypto/ecdsa/util.v @@ -1,72 +1,5 @@ module ecdsa -#include -#include -#include -#include -#include - -// #define NID_X9_62_id_ecPublicKey 408 -const nid_ec_publickey = C.NID_X9_62_id_ecPublicKey - -@[typedef] -struct C.EVP_PKEY {} - -@[typedef] -struct C.BIO_METHOD {} - -@[typedef] -pub struct C.BIO {} - -// EVP_PKEY *EVP_PKEY_new(void); -fn C.EVP_PKEY_new() &C.EVP_PKEY - -// EVP_PKEY_free(EVP_PKEY *key); -fn C.EVP_PKEY_free(key &C.EVP_PKEY) - -// EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); -fn C.EVP_PKEY_get1_EC_KEY(pkey &C.EVP_PKEY) &C.EC_KEY - -// EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); -fn C.d2i_PUBKEY(k &&C.EVP_PKEY, pp &&u8, length u32) &C.EVP_PKEY - -// point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); -fn C.EC_KEY_get_conv_form(k &C.EC_KEY) int - -// EC_GROUP_get_degree -fn C.EC_GROUP_get_degree(g &C.EC_GROUP) int - -// const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); -fn C.EC_KEY_get0_public_key(key &C.EC_KEY) &C.EC_POINT - -// size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, uint8_t *buf, size_t max_out, BN_CTX *ctx); -fn C.EC_POINT_point2oct(g &C.EC_GROUP, p &C.EC_POINT, form int, buf &u8, max_out int, ctx &C.BN_CTX) int - -// int EVP_PKEY_get_base_id(const EVP_PKEY *pkey); -fn C.EVP_PKEY_base_id(key &C.EVP_PKEY) int - -// int EC_GROUP_get_curve_name(const EC_GROUP *group); -fn C.EC_GROUP_get_curve_name(g &C.EC_GROUP) int -fn C.EC_GROUP_free(group &C.EC_GROUP) - -// BIO * BIO_new(BIO_METHOD *type); -fn C.BIO_new(t &C.BIO_METHOD) &C.BIO - -// void BIO_free_all(BIO *a); -fn C.BIO_free_all(a &C.BIO) - -// BIO_METHOD * BIO_s_mem(void); -fn C.BIO_s_mem() &C.BIO_METHOD - -// int BIO_write(BIO *b, const void *buf, int len); -fn C.BIO_write(b &C.BIO, buf &u8, length int) int - -// EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); -fn C.PEM_read_bio_PrivateKey(bp &C.BIO, x &&C.EVP_PKEY, cb int, u &voidptr) &C.EVP_PKEY - -// EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); -fn C.PEM_read_bio_PUBKEY(bp &C.BIO, x &&C.EVP_PKEY, cb int, u &voidptr) &C.EVP_PKEY - // pubkey_from_bytes loads ECDSA Public Key from bytes array. // The bytes of data should be a valid of ASN.1 DER serialized SubjectPublicKeyInfo structrue of RFC 5480. // Otherwise, its should an error.