typedef enum
{
KEY_TYPE_B64_STRING = 0,
KEY_TYPE_HEX_STRING,
KEY_TYPE_LOCAL_FILE,
}eAsymmKeyForm;
typedef struct
{
const char *pub_x_hex;
const char *pub_y_hex;
const char *pri_hex;
const char *pub;
const char *pri;
}KeyFormInfo, *pKeyFormInfo;
EC_KEY *key_b64_create_ec(char *key_b64, int is_public)
{
EC_KEY *ec_key = NULL;
BIO *keybio = NULL;
keybio = BIO_new_mem_buf(key_b64, (int)strlen(key_b64));
if(keybio == NULL)
{
log_e("BIO_new_mem_buf failed");
return NULL;
}
if(is_public)
{
ec_key = PEM_read_bio_EC_PUBKEY(keybio, NULL, NULL, NULL);
}
else
{
ec_key = PEM_read_bio_ECPrivateKey(keybio, NULL, NULL, NULL);
}
if(ec_key == NULL)
{
log_e(" PEM read bio failed");
return NULL;
}
return ec_key;
}
EC_KEY *new_ec_key(const char *sk, const char *xP, const char *yP)
{
log_d("new_ec_key...");
int ok = 0;
EC_KEY *ec_key = NULL;
BIGNUM *d = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
EC_GROUP *sm2p256 = NULL;
//sm2p256 = EC_GROP_new_by_curve_name(NID_sm2p256v1); //openssl
sm2p256 = EC_GROUP_new_by_curve_name(NID_sm2p256v1);
if(sm2p256 == NULL) {
log_e("new_ec_group error");
return NULL;
}
if (!(ec_key = EC_KEY_new())) {
log_e("EC_KEY_new error");
goto end;
}
if (!EC_KEY_set_group(ec_key, sm2p256)) {
log_e("EC_KEY_set_group error");
goto end;
}
if (sk) {
if (!BN_hex2bn(&d, sk)) {
log_e("sk BN_hex2bn error");
goto end;
}
if (!EC_KEY_set_private_key(ec_key, d)) {
log_e("EC_KEY_set_private_key error");
goto end;
}
}
if (xP && yP) {
if (!BN_hex2bn(&x, xP)) {
log_e("xP BN_hex2bn error");
goto end;
}
if (!BN_hex2bn(&y, yP)) {
log_e("yP BN_hex2bn error");
goto end;
}
if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
log_e("EC_KEY_set_public_key_affine_coordinates error");
goto end;
}
}
ok = 1;
log_d("new ec key succeed");
end:
if(sm2p256) EC_GROUP_free(sm2p256);
if (d) BN_free(d);
if (x) BN_free(x);
if (y) BN_free(y);
if (!ok && ec_key) {
//ERR_print_errors_fp(stderr);
get_openssL_error("new_ec_key");
EC_KEY_free(ec_key);
ec_key = NULL;
}
return ec_key;
}
EC_KEY *key_form_conver(eAsymmKeyForm form, pKeyFormInfo key_info, int is_public)
{
log_d("key_form_conver, key form: %d", form);
EC_KEY *ec_key = NULL;
if(KEY_TYPE_LOCAL_FILE == form)
{
FILE *fp = NULL;
if(is_public)
{
fp = fopen(key_info->pub, "r");
if(NULL == fp)
{
log_e("fopen %s failed", key_info->pub);
return NULL;
}
ec_key = EC_KEY_new();
if(NULL == ec_key)
{
log_e("generate EC key failed");
fclose(fp);
return NULL;
}
PEM_read_EC_PUBKEY(fp, &ec_key, NULL, NULL);
if(NULL == ec_key)
{
log_e("read EC public key failed: errno=%lu error=%s", ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
fclose(fp);
EC_KEY_free(ec_key);
return NULL;
}
}
else
{
fp = fopen(key_info->pri, "r");
if(NULL == fp)
{
log_e("fopen %s failed", key_info->pri);
return NULL;
}
ec_key = EC_KEY_new();
if(NULL == ec_key)
{
log_e("generate EC key failed");
fclose(fp);
return NULL;
}
PEM_read_ECPrivateKey(fp, &ec_key, NULL, NULL);
if(NULL == ec_key)
{
log_e("read EC private key failed: errno=%lu error=%s", ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
fclose(fp);
EC_KEY_free(ec_key);
return NULL;
}
}
}
else if(KEY_TYPE_B64_STRING == form)
{
if(is_public)
{
log_d("public key b64: %s", key_info->pub);
if(!(ec_key = key_b64_create_ec(key_info->pub, 1)))
{
return NULL;
}
}
else
{
log_d("private key b64: %s", key_info->pri);
if(!(ec_key = key_b64_create_ec(key_info->pri, 0)))
{
return NULL;
}
}
}
else if(KEY_TYPE_HEX_STRING == form)
{
if(is_public)
{
log_d("public, pub_x_hex: %s, pub_y_hex: %s", key_info->pub_x_hex, key_info->pub_y_hex);
if(!(ec_key = new_ec_key(NULL, key_info->pub_x_hex, key_info->pub_y_hex)))
{
return NULL;
}
}
else
{
log_d("private, pri_hex: %s", key_info->pri_hex);
if(!(ec_key = new_ec_key(key_info->pri_hex, NULL, NULL)))
{
return NULL;
}
}
}
else
{
log_e("input param key type illegal");
return NULL;
}
return ec_key;
}
gmssl sm2 将公钥和私钥的十六进制、pem文件和pem base64字符串格式转EC_KEY*
于 2022-10-22 13:53:36 首次发布