#c #cmake #openssl #cryptography
Вопрос:
Мне нужно проверить, поддерживает ли OpenSSL определенные эллиптические кривые через CMake. В то время как доступность шифра и хэша может быть проверена с помощью функций openssl/evp.h
, например check_cxx_symbol_exists("EVP_md4", openssl/evp.h, _openssl_has_md4)
, я не вижу способа сделать то же самое для кривых.
Я что-то пропустил, или нет лучшего способа, чем проверить вывод openssl ecparam list_curves
?
Обновление: Поскольку мой код не требует исполняемого файла openssl, было бы весьма желательно избежать зависимости от него при построении.
Обновление 2: благодаря ответу Дэвида в итоге появился следующий модуль: https://github.com/rnpgp/cmake-modules/blob/master/FindOpenSSLFeatures.cmake
Комментарии:
1. Если есть программа, которая может перечислять функциональные возможности фреймворка, то использование этой программы представляется гораздо предпочтительнее, чем использование
check_cxx_symbol_exists
или аналогичные методы.2. Но что делать в случае, если исполняемый файл недоступен? Является ли хорошей практикой требовать исполняемый файл в дополнение к библиотеке при компиляции проекта?
3. Хм, я не эксперт в OpenSSL, но если можно установить библиотеки OpenSSL без
openssl
исполняемого файла, то попытка избежать требования этого исполняемого файла выглядит вполне разумным намерением. Вы можете обновить вопрос и добавить, что вы намерены (пытаясь избежать требованияopenssl
установки исполняемого файла вместе с библиотекой OpenSSL). Кстати, понижающий голос не мой.4. Спасибо. Другой способ, который я вижу, — это скомпилировать небольшой фрагмент кода, который пытается использовать необходимые функции и проверить его код возврата, но на данный момент кажется чрезмерно сложным…
Ответ №1:
Этот код (в основном взятый из openssl) содержит список доступных ECs:
#include <stdio.h>
#include <openssl/ec.h>
#include <openssl/objects.h>
int
main ()
{
int ret = 1;
EC_builtin_curve *curves = NULL;
size_t n, crv_len = EC_get_builtin_curves (NULL, 0);
curves = OPENSSL_malloc((int)sizeof(*curves) * crv_len);
if (curves == NULL)
goto end;
if (!EC_get_builtin_curves (curves, crv_len))
goto memfree;
for (n = 0; n < crv_len; n )
{
const char *comment = curves[n].comment;
const char *sname = OBJ_nid2sn (curves[n].nid);
if (comment == NULL)
comment = "CURVE DESCRIPTION NOT AVAILABLE";
if (sname == NULL)
sname = "";
printf ("%st%sn", sname, comment);
}
ret = 0;
memfree:
OPENSSL_free (curves);
end:
return ret;
}
Вывод на моем ноутбуке:
$ gcc -Wall -L /usr/lib64 -lcrypto -lssl eclist.c -o eclist
$ ./eclist
secp224r1 NIST/SECG curve over a 224 bit prime field
secp256k1 SECG curve over a 256 bit prime field
secp384r1 NIST/SECG curve over a 384 bit prime field
secp521r1 NIST/SECG curve over a 521 bit prime field
prime256v1 X9.62/SECG curve over a 256 bit prime field
Двоичный файл openssl дает мне тот же результат:
$ openssl ecparam -list_curves
secp224r1 : NIST/SECG curve over a 224 bit prime field
secp256k1 : SECG curve over a 256 bit prime field
secp384r1 : NIST/SECG curve over a 384 bit prime field
secp521r1 : NIST/SECG curve over a 521 bit prime field
prime256v1: X9.62/SECG curve over a 256 bit prime field
Конечно, печать значений таким образом может быть не очень полезной, но, надеюсь, код может послужить основой для тестового CMake.
Комментарии:
1. Спасибо за фрагмент кода! Как только вы закончите, я вернусь со ссылкой на все решение.
2. Обновил вопрос со ссылкой на полное решение. Еще раз спасибо!