在 C 中使用 openssl 生成 pem
Generating a pem with openssl in C
我正在开发一个关键的实用程序库,不幸的是,我在可靠地创建 pem 时遇到了一些困难。我成功地创建了一个 pem,可能有 98% 的时间,但时不时地我会得到一个坏的 pem。知道发生了什么事吗?
我正在编译 gcc key_utils.c tests.c -o key_tests -lcrypto -lssl -Wall
Headers:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/ecdsa.h>
#include <openssl/pem.h>
.
int generatePem(char **pem) {
char *pemholder = calloc(224, sizeof(char));
EC_KEY *eckey = NULL;
BIO *out = BIO_new(BIO_s_mem());
BUF_MEM *buf = NULL;
EC_GROUP *group = NULL;
group = EC_GROUP_new_by_curve_name(NID_secp256k1);
buf = BUF_MEM_new();
eckey = EC_KEY_new();
createNewKey(group, eckey);
EC_GROUP_clear_free(group);
PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL);
BIO_get_mem_ptr(out, &buf);
memcpy(pemholder, buf->data, 223);
if ( buf->data[219] == '\n') {
pemholder[220] = '[=11=]';
memcpy(*pem, pemholder, 221);
} else if ( buf->data[221] == '\n') {
pemholder[222] = '[=11=]';
memcpy(*pem, pemholder, 223);
} else {
pemholder[223] = '[=11=]';
memcpy(*pem, pemholder, 224);
}
free(pemholder);
EC_KEY_free(eckey);
BIO_free_all(out);
return NOERROR;
};
坏的 pem 看起来像这样:
-----BEGIN EC PRIVATE KEY-----
MHMCAQEEH8kO/hjEyM2hvQk//LSsp1xRBIYNDRjAi4b8N78odyCgBwYFK4EEAAqh
RANCAAQ43017I40ci8YMLJnguD/DHUjohY4blKoJ4lXYbgYqyjWvJfVnsNPMU8H9
o3IdPwAitnJjCOG11n9DIQoS3S/o
-----END EC PRIVATE KEY-----
6T
原来我很笨,220 字节是一个有效的 PEM。
这是工作代码,以备日后其他人需要查看。
int generatePem(char **pem) {
int returnError = NOERROR;
char * errorMessage = "";
char *pemholder = calloc(240, sizeof(char));
EC_KEY *eckey = NULL;
BIO *out = NULL;
if ((out = BIO_new(BIO_s_mem())) == NULL) {
returnError = ERROR;
errorMessage = "Error in BIO_new(BIO_s_mem())";
goto clearVariables;
}
BUF_MEM *buf = NULL;
EC_GROUP *group = NULL;
if ((group = EC_GROUP_new_by_curve_name(NID_secp256k1)) == NULL) {
returnError = ERROR;
errorMessage = "Error in EC_GROUP_new_by_curve_name(NID_secp256k1))";
goto clearVariables;
}
if (((eckey = EC_KEY_new()) == NULL) ||
((buf = BUF_MEM_new()) == NULL)) {
returnError = ERROR;
errorMessage = "Error in EC_KEY_new())";
goto clearVariables;
};
if (createNewKey(group, eckey) == ERROR) {
returnError = ERROR;
errorMessage = "createNewKey(group, eckey)";
goto clearVariables;
}
if (PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL) == 0) {
printf("PEM_write_bio_ECPrivateKey error");
}
BIO_get_mem_ptr(out, &buf);
memcpy(pemholder, buf->data, 224);
if (buf->data[218] == '\n') {
pemholder[219] = '[=10=]';
memcpy(*pem, pemholder, 220);
} else if ( buf->data[219] == '\n') {
pemholder[220] = '[=10=]';
memcpy(*pem, pemholder, 221);
} else if ( buf->data[221] == '\n') {
pemholder[222] = '[=10=]';
memcpy(*pem, pemholder, 223);
} else if (buf->data[222] == '\n') {
pemholder[223] = '[=10=]';
memcpy(*pem, pemholder, 224);
} else {
returnError = ERROR;
errorMessage = "invalid PEM generated";
goto clearVariables;
}
goto clearVariables;
clearVariables:
if (group != NULL)
EC_GROUP_clear_free(group);
if (pemholder != NULL)
free(pemholder);
if (eckey != NULL)
EC_KEY_free(eckey);
if (out != NULL)
BIO_free_all(out);
if (errorMessage[0] != '[=10=]')
printf("Error: %s\n", errorMessage);
return returnError;
};
static int createNewKey(EC_GROUP *group, EC_KEY *eckey) {
int asn1Flag = OPENSSL_EC_NAMED_CURVE;
int form = POINT_CONVERSION_UNCOMPRESSED;
EC_GROUP_set_asn1_flag(group, asn1Flag);
EC_GROUP_set_point_conversion_form(group, form);
int setGroupError = EC_KEY_set_group(eckey, group);
int resultFromKeyGen = EC_KEY_generate_key(eckey);
if (resultFromKeyGen != 1 || setGroupError != 1){
return ERROR;
}
return NOERROR;
}
我正在开发一个关键的实用程序库,不幸的是,我在可靠地创建 pem 时遇到了一些困难。我成功地创建了一个 pem,可能有 98% 的时间,但时不时地我会得到一个坏的 pem。知道发生了什么事吗?
我正在编译 gcc key_utils.c tests.c -o key_tests -lcrypto -lssl -Wall
Headers:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <openssl/ecdsa.h>
#include <openssl/pem.h>
.
int generatePem(char **pem) {
char *pemholder = calloc(224, sizeof(char));
EC_KEY *eckey = NULL;
BIO *out = BIO_new(BIO_s_mem());
BUF_MEM *buf = NULL;
EC_GROUP *group = NULL;
group = EC_GROUP_new_by_curve_name(NID_secp256k1);
buf = BUF_MEM_new();
eckey = EC_KEY_new();
createNewKey(group, eckey);
EC_GROUP_clear_free(group);
PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL);
BIO_get_mem_ptr(out, &buf);
memcpy(pemholder, buf->data, 223);
if ( buf->data[219] == '\n') {
pemholder[220] = '[=11=]';
memcpy(*pem, pemholder, 221);
} else if ( buf->data[221] == '\n') {
pemholder[222] = '[=11=]';
memcpy(*pem, pemholder, 223);
} else {
pemholder[223] = '[=11=]';
memcpy(*pem, pemholder, 224);
}
free(pemholder);
EC_KEY_free(eckey);
BIO_free_all(out);
return NOERROR;
};
坏的 pem 看起来像这样:
-----BEGIN EC PRIVATE KEY-----
MHMCAQEEH8kO/hjEyM2hvQk//LSsp1xRBIYNDRjAi4b8N78odyCgBwYFK4EEAAqh
RANCAAQ43017I40ci8YMLJnguD/DHUjohY4blKoJ4lXYbgYqyjWvJfVnsNPMU8H9
o3IdPwAitnJjCOG11n9DIQoS3S/o
-----END EC PRIVATE KEY-----
6T
原来我很笨,220 字节是一个有效的 PEM。
这是工作代码,以备日后其他人需要查看。
int generatePem(char **pem) {
int returnError = NOERROR;
char * errorMessage = "";
char *pemholder = calloc(240, sizeof(char));
EC_KEY *eckey = NULL;
BIO *out = NULL;
if ((out = BIO_new(BIO_s_mem())) == NULL) {
returnError = ERROR;
errorMessage = "Error in BIO_new(BIO_s_mem())";
goto clearVariables;
}
BUF_MEM *buf = NULL;
EC_GROUP *group = NULL;
if ((group = EC_GROUP_new_by_curve_name(NID_secp256k1)) == NULL) {
returnError = ERROR;
errorMessage = "Error in EC_GROUP_new_by_curve_name(NID_secp256k1))";
goto clearVariables;
}
if (((eckey = EC_KEY_new()) == NULL) ||
((buf = BUF_MEM_new()) == NULL)) {
returnError = ERROR;
errorMessage = "Error in EC_KEY_new())";
goto clearVariables;
};
if (createNewKey(group, eckey) == ERROR) {
returnError = ERROR;
errorMessage = "createNewKey(group, eckey)";
goto clearVariables;
}
if (PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL) == 0) {
printf("PEM_write_bio_ECPrivateKey error");
}
BIO_get_mem_ptr(out, &buf);
memcpy(pemholder, buf->data, 224);
if (buf->data[218] == '\n') {
pemholder[219] = '[=10=]';
memcpy(*pem, pemholder, 220);
} else if ( buf->data[219] == '\n') {
pemholder[220] = '[=10=]';
memcpy(*pem, pemholder, 221);
} else if ( buf->data[221] == '\n') {
pemholder[222] = '[=10=]';
memcpy(*pem, pemholder, 223);
} else if (buf->data[222] == '\n') {
pemholder[223] = '[=10=]';
memcpy(*pem, pemholder, 224);
} else {
returnError = ERROR;
errorMessage = "invalid PEM generated";
goto clearVariables;
}
goto clearVariables;
clearVariables:
if (group != NULL)
EC_GROUP_clear_free(group);
if (pemholder != NULL)
free(pemholder);
if (eckey != NULL)
EC_KEY_free(eckey);
if (out != NULL)
BIO_free_all(out);
if (errorMessage[0] != '[=10=]')
printf("Error: %s\n", errorMessage);
return returnError;
};
static int createNewKey(EC_GROUP *group, EC_KEY *eckey) {
int asn1Flag = OPENSSL_EC_NAMED_CURVE;
int form = POINT_CONVERSION_UNCOMPRESSED;
EC_GROUP_set_asn1_flag(group, asn1Flag);
EC_GROUP_set_point_conversion_form(group, form);
int setGroupError = EC_KEY_set_group(eckey, group);
int resultFromKeyGen = EC_KEY_generate_key(eckey);
if (resultFromKeyGen != 1 || setGroupError != 1){
return ERROR;
}
return NOERROR;
}