Проверьте, поддерживает ли OpenSSL определенную кривую с помощью заголовка/определения в CMake

#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. Обновил вопрос со ссылкой на полное решение. Еще раз спасибо!