Генерация pem с openssl в C
Я работаю над библиотекой ключей util, и, к сожалению, у меня возникли небольшие трудности с надежным созданием pem. Я успешно создаю pem, возможно, в 98% случаев, но время от времени я получаю плохой pem. Есть идеи, что происходит?
Я компилирую с gcc key_utils.c tests.c -o key_tests -lcrypto -lssl -Wall
Заголовки:
#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] = '';
memcpy(*pem, pemholder, 221);
} else if ( buf->data[221] == 'n') {
pemholder[222] = '';
memcpy(*pem, pemholder, 223);
} else {
pemholder[223] = '';
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
1 ответ:
Оказывается, я тупой, и 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] = '\0'; memcpy(*pem, pemholder, 220); } else if ( buf->data[219] == '\n') { pemholder[220] = '\0'; memcpy(*pem, pemholder, 221); } else if ( buf->data[221] == '\n') { pemholder[222] = '\0'; memcpy(*pem, pemholder, 223); } else if (buf->data[222] == '\n') { pemholder[223] = '\0'; 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] != '\0') 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; }