2017-02-09 2 views
1

Я пишу кросс-платформенную библиотеку C++, которая опирается на OpenSSL, которая связывает статически & с моей библиотекой для удобства использования. Я хотел бы иметь один каталог #include для моей библиотеки, который, очевидно, будет содержать подкаталог «openssl».Почему opensslconf.h отличается для каждой архитектуры?

К сожалению, содержимое каталога OpenSSL #include отличается для каждой архитектуры на каждой платформе. Так, например, есть (минимально) три разные версии файлов заголовков OpenSSL для iOS. Добавьте больше для поддержки ТВ-ОС и версий симуляторов. Та же проблема существует в разной степени в Windows & Android.

При ближайшем рассмотрении единственным файлом, который является общим, но другим по всем платформам &, является «opensslconf.h», и он обычно отличается только несколькими строками, а иногда и одной строкой.

Например, версия tvOS из "opensslconf.h" содержит:

#ifndef OPENSSL_NO_ASYNC 
# define OPENSSL_NO_ASYNC 
#endif 

В то время как версия IOS не делает.

Более частое различие заключается в определении RC4_INT:

// 64-bit architectures? 
#define RC4_INT unsigned int 

// 32-bit architectures? 
#define RC4_INT unsigned char 

Я хотел бы иметь только один набор OpenSSL директив #includes, который применяется для всех архитектур & платформ. Я не хочу иметь дубликаты всех этих файлов для каждой арки/платформы, тем более, что существует так много вариаций.

Мой первый вопрос: возможно ли иметь только один каталог OpenSSL #include, как мне хотелось бы? Если да, какую версию «opensslconf.h» выбрать, и как я узнаю, что она будет работать?

Мой второй вопрос - почему это проблема НА ВСЕ. Почему эти различия в платформе не могут быть инкапсулированы OpenSSL? Разве это уже не отслеживает многие другие переменные и типы, которые меняются при построении для разных архитектур?

ответ

2

В качестве обходного пути, вы можете создать несколько версий opensslconf.h (по одному для каждого из арок вы планируете поддержать), называть их opensslconf-win.h, opensslconf-tvos.h и т.д. Затем написать opensslconf, который будет содержать только включает сгенерированные файлы на основе на платформе:

#ifdef WIN32 
#include opensslconf-win.h 
#endif 
// and so for every arch 
+0

Это отличная идея. Фактически, это то, что я делаю во всех моих кросс-платформенных библиотеках. И что-то, что ИМХО OpenSSL-код должен уже делать. – Bungles

0

Почему opensslconf.h различны для каждой архитектуры?

opensslconf.h содержит информацию о конфигурации и установке конкретной платформы. Как вы отметили, примером данных конфигурации платформы является RC4_INT.

Другие примеры информации о конфигурации платформы включают в себя определения OPENSSL_NO_SSL2, если ./Configure no-ssl2; и OPENSSL_NO_SSL3, если ./Configure no-ssl3. Примеры информации установки являются OPENSSLDIR, который содержит местоположение OpenSSL's configuration file openssl.conf (среди другой информации местоположения)

Последние примеры, no-ssl2, no-ssl3 и OPENSSLDIR, указаны пользователем. Они не предназначены для платформы.

(Связанный с этим вопрос относится к полезности OPENSSLDIR в песочницах и огороженных садами, но я никогда не видел ответа на него. Также см. CONF-less OpenSSL configuration? в списке рассылки OpenSSL).


К сожалению, содержимое каталога #include OpenSSL различаются по архитектуре, на платформе ... При ближайшем рассмотрении, единственный файл, который распространен, но разные на всех платформах & архитектур «opensslconf.h» ,

Это не совсем правильно. bn.h другой, тоже.


Я хотел бы иметь только один набор OpenSSL директив #includes, который применяется для всех архитектур & платформы ... Мой первый вопрос, если это возможно, чтобы иметь только один OpenSSL каталог #include, как я как? Если да, какую версию «opensslconf.h» выбрать, и как я узнаю, что она будет работать?

Да, его можно иметь только один opensslconf.h и только одинbh.h. Но вам придется строить его вручную, и это сработает, если вы будете старательно следить за определениями интересов и транскрибировать их без ошибок. Вы не можете выбрать его и ожидать, что он будет работать для всех архитектур и платформ.

Я использовал следующую технику, чтобы объединить их в OS X и iOS для жирных библиотек. Шаги подробно описаны в Build Multiarch OpenSSL on OS X, но я предполагаю, что вы знаете, что происходит, глядя на него.

$ cat $HOME/ssl/include/openssl/opensslconf.h 
#ifndef OPENSSL_MULTIARCH_CONF_HEADER 
#define OPENSSL_MULTIARCH_CONF_HEADER 

#if __i386 || __i386__ 
# include "opensslconf-x86.h" 
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__ 
# include "opensslconf-x64.h" 
#else 
# error Unknown architecture 
#endif 

#endif /* OPENSSL_MULTIARCH_CONF_HEADER */ 

и:

$ cat $HOME/ssl/include/openssl/bn.h 
#ifndef OPENSSL_MULTIARCH_BN_HEADER 
#define OPENSSL_MULTIARCH_BN_HEADER 

#if __i386 || __i386__ 
# include "bn-x86.h" 
#elif __x86_64 || __x86_64__ || __amd64 || __amd64__ 
# include "bn-x64.h" 
#else 
# error Unknown architecture 
#endif 

#endif /* OPENSSL_MULTIARCH_BN_HEADER */ 

Мой второй вопрос, почему это вопрос ВООБЩЕ. Почему эти различия в платформе не могут быть инкапсулированы OpenSSL? Разве это уже не отслеживает многие другие переменные и типы, которые меняются при построении для разных архитектур?

Я никогда не видел окончательного ответа на эту тему. Возможно, вы должны спросить об одном из списков рассылки OpenSSL, таких как openssl-dev.

Я предполагаю, что существует слишком много платформ и вариантов конфигурации, чтобы набить их все одним opensslconf.h (и одним bn.h). Вот краткий список встроенных целей. wc -l говорит нам, что их 144.

В список не включены различные параметры конфигурации, такие как enable-ec_nistp_64_gcc_128 для определенных процессоров (это не имеет ничего общего с NIST или FIPS). Также см. Compilation and Installation | Configure Options на вики OpenSSL.

$ ./Configure LIST 
Configuring OpenSSL version 1.1.1-dev (0x10101000L) 
BS2000-OSD 
BSD-generic32 
BSD-generic64 
BSD-ia64 
BSD-sparc64 
BSD-sparcv8 
BSD-x86 
BSD-x86-elf 
BSD-x86_64 
Cygwin 
Cygwin-i386 
Cygwin-i486 
Cygwin-i586 
Cygwin-i686 
Cygwin-x86 
Cygwin-x86_64 
DJGPP 
MPE/iX-gcc 
OS390-Unix 
QNX6 
QNX6-i386 
UEFI 
UWIN 
VC-CE 
VC-WIN32 
VC-WIN64A 
VC-WIN64A-masm 
VC-WIN64I 
aix-cc 
aix-gcc 
aix64-cc 
aix64-gcc 
android 
android-armeabi 
android-mips 
android-x86 
android64 
android64-aarch64 
android64-mips64 
android64-x86_64 
bsdi-elf-gcc 
cc 
darwin-i386-cc 
darwin-ppc-cc 
darwin64-debug-test-64-clang 
darwin64-ppc-cc 
darwin64-x86_64-cc 
debug 
debug-erbridge 
debug-linux-ia32-aes 
debug-linux-pentium 
debug-linux-ppro 
debug-test-64-clang 
dist 
gcc 
haiku-x86 
haiku-x86_64 
hpux-ia64-cc 
hpux-ia64-gcc 
hpux-parisc-cc 
hpux-parisc-gcc 
hpux-parisc1_1-cc 
hpux-parisc1_1-gcc 
hpux64-ia64-cc 
hpux64-ia64-gcc 
hpux64-parisc2-cc 
hpux64-parisc2-gcc 
hurd-x86 
ios-cross 
ios64-cross 
iphoneos-cross 
irix-mips3-cc 
irix-mips3-gcc 
irix64-mips4-cc 
irix64-mips4-gcc 
linux-aarch64 
linux-alpha-gcc 
linux-aout 
linux-arm64ilp32 
linux-armv4 
linux-c64xplus 
linux-elf 
linux-generic32 
linux-generic64 
linux-ia64 
linux-mips32 
linux-mips64 
linux-ppc 
linux-ppc64 
linux-ppc64le 
linux-sparcv8 
linux-sparcv9 
linux-x32 
linux-x86 
linux-x86-clang 
linux-x86_64 
linux-x86_64-clang 
linux32-s390x 
linux64-mips64 
linux64-s390x 
linux64-sparcv9 
mingw 
mingw64 
nextstep 
nextstep3.3 
purify 
qnx4 
sco5-cc 
sco5-gcc 
solaris-sparcv7-cc 
solaris-sparcv7-gcc 
solaris-sparcv8-cc 
solaris-sparcv8-gcc 
solaris-sparcv9-cc 
solaris-sparcv9-gcc 
solaris-x86-gcc 
solaris64-sparcv9-cc 
solaris64-sparcv9-gcc 
solaris64-x86_64-cc 
solaris64-x86_64-gcc 
tru64-alpha-cc 
tru64-alpha-gcc 
uClinux-dist 
uClinux-dist64 
unixware-2.0 
unixware-2.1 
unixware-7 
unixware-7-gcc 
vms-alpha 
vms-alpha-p32 
vms-alpha-p64 
vms-ia64 
vms-ia64-p32 
vms-ia64-p64 
vos-gcc 
vxworks-mips 
vxworks-ppc405 
vxworks-ppc60x 
vxworks-ppc750 
vxworks-ppc750-debug 
vxworks-ppc860 
vxworks-ppcgen 
vxworks-simlinux 

Та же проблема существует и в разной степени на Windows, Android & ...

Я думаю «не очень». Вы не можете создавать живые библиотеки на этих платформах, поэтому проблема на самом деле не существует. Вам все еще нужно указать конкретный путь для конкретной платформы, поэтому what's the problem with headers?

Есть кое-что сообразительное, поскольку я вспоминаю о чем-то в Linux (я не могу найти ссылку на данный момент), но у Android его нет.


Связанные, вы можете увидеть полный список платформ и конфигураций параметров пользователя с:

$ openssl version -a 
OpenSSL 1.0.2g 1 Mar 2016 
built on: reproducible build, date unspecified 
platform: debian-amd64 
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) 
compiler: cc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REE 
NTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -g -O2 -fstack-protector-stron 
g -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wl,-Bsymboli 
c-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32 
_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ 
ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIR 
LPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM 
OPENSSLDIR: "/usr/lib/ssl" 
+0

Я не вижу различий между платформами в файле «bn.h», хотя я не компилирую для ВСЕХ платформ. – Bungles

+0

@Bungle - В прошлый раз, когда я проверил (OpenSSL 1.0.1 или 1.0.2), 'bn.h' имел некоторую структуру, зависящую от размера слова. Знаете ли вы, какую версию OpenSSL вы используете? – jww

+0

Я строю 1.1.0d – Bungles

0

Alien_AV дал ответ, но я отправляю это для того, чтобы следить за этим с некоторым кодом, которые могут отображаться только в ответе.

Ниже приводится решение, которое сработало для меня. Я все еще думаю, что это то, что должно быть интегрированной частью процесса сборки OpenSSL, а не чем-то, что может понадобиться каждому пользователю.

Его следует довольно легко реализовать, поскольку в этом файле нет ничего специфичного для платформы - нужно просто знать все поддерживаемые платформы.

#ifndef __OPENSSLCONF_H__ 
#define __OPENSSLCONF_H__ 

// ************************************************ ANDROID 
#if defined(__ANDROID__) 
    #if defined (__i386__) 
     #include <openssl/opensslconf-android-x86.h> 
    #elif defined (__arm__) 
     #include <openssl/opensslconf-android-arm.h> 
    #elif defined (_MIPS_ARCH) 
     // Unsupported 
    #endif 

// ************************************************ IOS 
// Reference:  http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system 
#elif defined(__APPLE__) && defined(__MACH__) 
    #include <TargetConditionals.h> 
    #ifdef TARGET_OS_WATCHOS 
     // Unsupported 
    #elif TARGET_OS_TV 
     #if TARGET_OS_SIMULATOR 
      #include <openssl/opensslconf-atv-sim64.h> 
     #elif 
      #include <openssl/opensslconf-atv-arm64.h> 
     #endif 
    #elif TARGET_OS_IOS 
     #if TARGET_OS_SIMULATOR 
      #include <openssl/opensslconf-ios-sim32.h> 
      #include <openssl/opensslconf-ios-sim64.h> 
     #else 
      #include <openssl/opensslconf-ios-arm32.h> 
      #include <openssl/opensslconf-ios-arm64.h> 
     #endif 
    #endif 

// ************************************************ WINDOWS 
// Reference: https://msdn.microsoft.com/en-us/library/b0084kay(v=vs.120).aspx 
#elif defined(_WIN32) 
    #if defined(_M_X64) 
     #include <openssl/opensslconf-win64.h> 
    #else 
     #include <openssl/opensslconf-win32.h> 
    #endif 
#endif 

#endif // __OPENSSLCONF_H__ 
Смежные вопросы