ax_crypto.m4 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. # Simplified, non-caching AC_CHECK_PROG
  2. # Searches $PATH for the existence of argument 2,
  3. # and sets the full path to the variable in argument 1.
  4. # if not found, and a third argument is given, the value
  5. # is set to that. If not, the value is untouched.
  6. # Does not take absolute paths into account at this point,
  7. # and also works for single files only (arguments are not
  8. # stripped like in AC_CHECK_PROG)
  9. AC_DEFUN([ACX_CHECK_PROG_NONCACHE], [
  10. RESULT=""
  11. IFS_SAVED="$IFS"
  12. IFS=${PATH_SEPARATOR}
  13. for cur_path in ${PATH} ; do
  14. if test -e "${cur_path}/$2" ; then
  15. RESULT="${cur_path}/$2"
  16. fi
  17. done
  18. if test "$RESULT" = "" ; then
  19. :
  20. m4_ifvaln([$3], [$1=$3])
  21. else
  22. $1=$RESULT
  23. fi
  24. IFS="$IFS_SAVED"
  25. ])
  26. AC_DEFUN([ACX_TRY_BOTAN_TOOL], [
  27. TOOL=$1
  28. TOOL_ARG=$2
  29. BOTAN_TOOL=""
  30. ACX_CHECK_PROG_NONCACHE([BOTAN_TOOL], [${TOOL}])
  31. AC_MSG_CHECKING([usability of ${TOOL} ${TOOL_ARG}])
  32. if test "$BOTAN_TOOL" != "" ; then
  33. if test -x ${BOTAN_TOOL}; then
  34. CRYPTO_LIBS=`$BOTAN_TOOL $TOOL_ARG --libs`
  35. LIBS_SAVED=${LIBS}
  36. LIBS="$LIBS $CRYPTO_LIBS"
  37. CRYPTO_INCLUDES=`$BOTAN_TOOL $TOOL_ARG --cflags`
  38. CPPFLAGS_SAVED=${CPPFLAGS}
  39. CPPFLAGS="$CRYPTO_INCLUDES $CPPFLAGS"
  40. #AC_MSG_RESULT([found])
  41. AC_LINK_IFELSE(
  42. [AC_LANG_PROGRAM([#include <botan/botan.h>
  43. #include <botan/init.h>
  44. #include <botan/hash.h>
  45. ],
  46. [using namespace Botan;
  47. LibraryInitializer::initialize();
  48. HashFunction *h = get_hash("MD5");
  49. ])],
  50. [ AC_MSG_RESULT([ok])
  51. $3
  52. ],
  53. [ AC_MSG_RESULT([not usable]) ]
  54. )
  55. LIBS=${LIBS_SAVED}
  56. CPPFLAGS=${CPPFLAGS_SAVED}
  57. else
  58. AC_MSG_RESULT([not executable])
  59. fi
  60. else
  61. AC_MSG_RESULT([not found])
  62. fi
  63. BOTAN_TOOL=""
  64. AC_SUBST(BOTAN_TOOL)
  65. ]
  66. )
  67. # End of ACX_TRY_BOTAN_TOOL
  68. AC_DEFUN([AX_CRYPTO], [
  69. # Check for Botan
  70. #
  71. # Unless --with-botan-config is given, we first try to find these config
  72. # scripts ourselves. Unfortunately, on some systems, these scripts do not
  73. # provide the correct implementation, so for each script found, we try
  74. # a compilation test (ACX_TRY_BOTAN_TOOL). If none are found, or none of
  75. # them work, we see if pkg-config is available. If so, we try the several
  76. # potential pkg-config .pc files. Again, on some systems, these can return
  77. # incorrect information as well, so the try-compile test is repeated for
  78. # each.
  79. #
  80. # If a working config script or pkgconfig file is found, we then munge its
  81. # output for use in our Makefiles, and to make sure it works, another header
  82. # and compilation test is done (this should also check whether we can compile
  83. # against botan should neither -config scripts nor pkgconfig data exist).
  84. #
  85. # Avoid checking Botan if OpenSSL is wanted
  86. AC_ARG_WITH([openssl],
  87. [AS_HELP_STRING([--with-openssl[[=PATH]]], [Enables OpenSSL,
  88. location can be specified optionally])],
  89. [use_openssl="$withval"],
  90. [use_openssl="auto"])
  91. botan_config="yes"
  92. if test "${use_openssl}" != "auto" -a "${use_openssl}" != "no" ; then
  93. botan_config="no"
  94. fi
  95. AC_ARG_WITH([botan-config],
  96. AC_HELP_STRING([--with-botan-config=PATH],
  97. [specify the path to the botan-config script]),
  98. [botan_config="$withval"])
  99. distcheck_botan="--with-botan-config=$botan_config"
  100. if test "${botan_config}" = "no" ; then
  101. if test "${use_openssl}" = "no" ; then
  102. AC_MSG_ERROR([Need Botan or OpenSSL for libcryptolink])
  103. fi
  104. elif test "${botan_config}" != "yes" ; then
  105. if test -x "${botan_config}" ; then
  106. if test -d "${botan_config}" ; then
  107. AC_MSG_ERROR([${botan_config} is a directory])
  108. else
  109. BOTAN_CONFIG="${botan_config}"
  110. fi
  111. else
  112. AC_MSG_ERROR([--with-botan-config should point to a botan-config program and not a directory (${botan_config})])
  113. fi
  114. else
  115. BOTAN_CONFIG=""
  116. # first try several possible names of the config script
  117. # (botan-config-1.8 is there just in case, the official name change
  118. # came later)
  119. BOTAN_CONFIG_VERSIONS="botan-config-1.10 botan-config-1.9 botan-config-1.8 botan-config"
  120. for botan_config in $BOTAN_CONFIG_VERSIONS; do
  121. ACX_TRY_BOTAN_TOOL([$botan_config],,
  122. [ BOTAN_CONFIG="$botan_config" ]
  123. )
  124. if test "$BOTAN_CONFIG" != "" ; then
  125. break
  126. fi
  127. done
  128. if test "$BOTAN_CONFIG" = "" ; then
  129. AC_PATH_PROG([PKG_CONFIG], [pkg-config])
  130. if test "$PKG_CONFIG" != "" ; then
  131. # Ok so no script found, see if pkg-config knows of it.
  132. # Unfortunately, the botan.pc files also have their minor version
  133. # in their name, so we need to try them one by one
  134. BOTAN_VERSIONS="botan-2 botan-1.11 botan-1.10 botan-1.9 botan-1.8"
  135. for version in $BOTAN_VERSIONS; do
  136. ACX_TRY_BOTAN_TOOL([pkg-config], ["$version --silence-errors"],
  137. [ BOTAN_CONFIG="$PKG_CONFIG $version" ]
  138. )
  139. if test "$BOTAN_CONFIG" != "" ; then
  140. break
  141. fi
  142. done
  143. fi
  144. fi
  145. fi
  146. if test "x${BOTAN_CONFIG}" != "x"
  147. then
  148. CRYPTO_LIBS=`${BOTAN_CONFIG} --libs`
  149. CRYPTO_INCLUDES=`${BOTAN_CONFIG} --cflags`
  150. # We expect botan-config --libs to contain -L<path_to_libbotan>, but
  151. # this is not always the case. As a heuristics workaround we add
  152. # -L`botan-config --prefix/lib` in this case (if not present already).
  153. # Same for CRYPTO_INCLUDES (but using include instead of lib) below.
  154. if [ ${BOTAN_CONFIG} --prefix >/dev/null 2>&1 ] ; then
  155. echo ${CRYPTO_LIBS} | grep -- -L > /dev/null || \
  156. CRYPTO_LIBS="-L`${BOTAN_CONFIG} --prefix`/lib ${CRYPTO_LIBS}"
  157. echo ${CRYPTO_INCLUDES} | grep -- -I > /dev/null || \
  158. CRYPTO_INCLUDES="-I`${BOTAN_CONFIG} --prefix`/include ${CRYPTO_INCLUDES}"
  159. fi
  160. fi
  161. if test "x${CRYPTO_LIBS}" != "x"
  162. then
  163. dnl Determine the Botan version
  164. AC_MSG_CHECKING([Botan version])
  165. cat > conftest.cpp << EOF
  166. #include <botan/version.h>
  167. AUTOCONF_BOTAN_VERSION=BOTAN_VERSION_MAJOR . BOTAN_VERSION_MINOR . BOTAN_VERSION_PATCH
  168. EOF
  169. CRYPTO_VERSION=`$CPPP $CPPFLAGS $CRYPTO_INCLUDES conftest.cpp | grep '^AUTOCONF_BOTAN_VERSION=' | $SED -e 's/^AUTOCONF_BOTAN_VERSION=//' -e 's/[[ ]]//g' -e 's/"//g' 2> /dev/null`
  170. if test -z "$CRYPTO_VERSION"; then
  171. CRYPTO_VERSION="unknown"
  172. fi
  173. $RM -f conftest.cpp
  174. AC_MSG_RESULT([$CRYPTO_VERSION])
  175. # botan-config script (and the way we call pkg-config) returns -L and -l
  176. # as one string, but we need them in separate values
  177. CRYPTO_LDFLAGS=
  178. for flag in ${CRYPTO_LIBS}; do
  179. CRYPTO_LDFLAGS="${CRYPTO_LDFLAGS} `echo $flag | ${SED} -ne '/^\(\-L\)/p'`"
  180. CRYPTO_LIBS="${CRYPTO_LIBS} `echo $flag | ${SED} -ne '/^\(\-l\)/p'`"
  181. done
  182. # # check -R, "-Wl,-R" or -rpath
  183. AX_ISC_RPATH
  184. # See crypto_rpath for some info on why we do this
  185. if test "x$ISC_RPATH_FLAG" != "x"; then
  186. CRYPTO_RPATH=
  187. for flag in ${CRYPTO_LIBS}; do
  188. CRYPTO_RPATH="${CRYPTO_RPATH} `echo $flag | ${SED} -ne "s/^\(\-L\)/${ISC_RPATH_FLAG}/p"`"
  189. done
  190. # According to the libtool manual, it should be sufficient if we
  191. # specify the "-R libdir" in our wrapper library of botan (no other
  192. # programs will need libbotan directly); "libdir" should be added to
  193. # the program's binary image. But we've seen in our build environments
  194. # that (some versions of?) libtool doesn't propagate -R as documented,
  195. # and it caused a linker error at run time. To work around this, we
  196. # also add the rpath to the global LDFLAGS.
  197. LDFLAGS="$CRYPTO_RPATH $LDFLAGS"
  198. fi
  199. # Even though chances are high we already performed a real compilation check
  200. # in the search for the right (pkg)config data, we try again here, to
  201. # be sure.
  202. CPPFLAGS_SAVED=$CPPFLAGS
  203. CPPFLAGS="$CRYPTO_INCLUDES $CPPFLAGS"
  204. LIBS_SAVED="$LIBS"
  205. LIBS="$LIBS $CRYPTO_LIBS"
  206. # ac_header_preproc is an autoconf symbol (undocumented but stable) that
  207. # is set if the pre-processor phase passes. Thus by adding a custom
  208. # failure handler we can detect the difference between a header not existing
  209. # (or not even passing the pre-processor phase) and a header file resulting
  210. # in compilation failures.
  211. AC_CHECK_HEADERS([botan/botan.h],,[
  212. CRYPTO_INCLUDES=""
  213. CRYPTO_LIBS=""
  214. CRYPTO_LDFLAGS=""
  215. CRYPTO_RPATH=""
  216. if test "x$ac_header_preproc" = "xyes"; then
  217. AC_MSG_RESULT([
  218. botan/botan.h was found but is unusable. The most common cause of this problem
  219. is attempting to use an updated C++ compiler with older C++ libraries, such as
  220. the version of Botan that comes with your distribution. If you have updated
  221. your C++ compiler we highly recommend that you use support libraries such as
  222. Boost and Botan that were compiled with the same compiler version.])
  223. else
  224. AC_MSG_RESULT([Missing required header files.])
  225. fi]
  226. )
  227. CPPFLAGS=$CPPFLAGS_SAVED
  228. LIBS=$LIBS_SAVED
  229. fi
  230. if test "x${CRYPTO_LIBS}" != "x"
  231. then
  232. CPPFLAGS_SAVED=$CPPFLAGS
  233. CPPFLAGS="$CRYPTO_INCLUDES $CPPFLAGS"
  234. LIBS_SAVED="$LIBS"
  235. LIBS="$LIBS $CRYPTO_LIBS"
  236. AC_LINK_IFELSE(
  237. [AC_LANG_PROGRAM([#include <botan/botan.h>
  238. #include <botan/init.h>
  239. #include <botan/hash.h>
  240. ],
  241. [using namespace Botan;
  242. LibraryInitializer::initialize();
  243. HashFunction *h = get_hash("MD5");
  244. ])],
  245. [AC_MSG_RESULT([checking for Botan library... yes])],
  246. [AC_MSG_RESULT([checking for Botan library... no])
  247. CRYPTO_INCLUDES=""
  248. CRYPTO_LIBS=""
  249. CRYPTO_LDFLAGS=""
  250. CRYPTO_RPATH=""
  251. AC_MSG_RESULT([Needs Botan library 1.8 or higher. On some systems,
  252. the botan package has a few missing dependencies (libbz2 and
  253. libgmp), if libbotan has been installed and you see this message,
  254. try upgrading to a higher version of botan or installing libbz2
  255. and libgmp.])]
  256. )
  257. CPPFLAGS=$CPPFLAGS_SAVED
  258. LIBS=$LIBS_SAVED
  259. fi
  260. if test "x${CRYPTO_LIBS}" != "x"
  261. then
  262. CRYPTO_NAME="Botan"
  263. DISABLED_CRYPTO="OpenSSL"
  264. CRYPTO_PACKAGE="botan-1.8"
  265. CRYPTO_CFLAGS=""
  266. DISTCHECK_CRYPTO_CONFIGURE_FLAG="$distcheck_botan"
  267. AC_DEFINE_UNQUOTED([WITH_BOTAN], [], [Compile with Botan crypto])
  268. else
  269. CRYPTO_NAME="OpenSSL"
  270. DISABLED_CRYPTO="Botan"
  271. CRYPTO_PACKAGE="openssl-1.0.2"
  272. AC_DEFINE_UNQUOTED([WITH_OPENSSL], [], [Compile with OpenSSL crypto])
  273. AC_MSG_CHECKING(for OpenSSL library)
  274. # from bind9
  275. if test "${use_openssl}" = "auto" ; then
  276. use_openssl="yes"
  277. fi
  278. if test "${use_openssl}" = "yes" ; then
  279. for d in /usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw; do
  280. if test -f $d/include/openssl/opensslv.h; then
  281. use_openssl=$d; break
  282. fi
  283. done
  284. fi
  285. if test "${use_openssl}" = "yes" ; then
  286. AC_MSG_ERROR([OpenSSL auto detection failed])
  287. fi
  288. if ! test -f "${use_openssl}"/include/openssl/opensslv.h ; then
  289. AC_MSG_ERROR([OpenSSL not found at ${use_openssl}])
  290. fi
  291. AC_MSG_RESULT(yes)
  292. if test "${use_openssl}" = "/usr" ; then
  293. CRYPTO_CFLAGS=""
  294. CRYPTO_INCLUDES=""
  295. CRYPTO_LIBS="-lcrypto"
  296. DISTCHECK_CRYPTO_CONFIGURE_FLAG="--with-openssl"
  297. else
  298. CRYPTO_CFLAGS=""
  299. CRYPTO_INCLUDES="-I${use_openssl}/include"
  300. DISTCHECK_CRYPTO_CONFIGURE_FLAG="--with-openssl=${use_openssl}"
  301. case $host in
  302. *-solaris*)
  303. CRYPTO_LIBS="-L${use_openssl}/lib -R${use_openssl}/lib -lcrypto"
  304. ;;
  305. *-hp-hpux*)
  306. CRYPTO_LIBS="-L${use_openssl}/lib -Wl,+b: -lcrypto"
  307. ;;
  308. *-apple-darwin*)
  309. if test -f "${use_openssl}/lib/libcrypto.dylib" ; then
  310. CRYPTO_LIBS="-L${use_openssl}/lib -lcrypto"
  311. else
  312. CRYPTO_LIBS="${use_openssl}/lib/libcrypto.a"
  313. fi
  314. ;;
  315. *)
  316. CRYPTO_LIBS="-L${use_openssl}/lib -lcrypto"
  317. ;;
  318. esac
  319. fi
  320. dnl Determine the OpenSSL version
  321. # Officially we support >= 1.0.1, 0.9.8 should fail the HMAC API,
  322. # 1.0.0 could work but is not recommended.
  323. AC_MSG_CHECKING([OpenSSL version])
  324. cat > conftest.cpp << EOF
  325. #include <openssl/opensslv.h>
  326. AUTOCONF_OPENSSL_VERSION=OPENSSL_VERSION_TEXT
  327. EOF
  328. CRYPTO_VERSION=`$CPPP $CPPFLAGS $CRYPTO_INCLUDES conftest.cpp | grep '^AUTOCONF_OPENSSL_VERSION=' | $SED -e 's/^AUTOCONF_OPENSSL_VERSION=//' -e 's/"//g' 2> /dev/null`
  329. if test -z "$CRYPTO_VERSION" ; then
  330. CRYPTO_VERSION="unknown"
  331. fi
  332. $RM -f conftest.cpp
  333. AC_MSG_RESULT([$CRYPTO_VERSION])
  334. #CRYPTO_LDFLAGS="-ldl"
  335. CRYPTO_LDFLAGS=""
  336. CRYPTO_RPATH=""
  337. dnl Check availability of SHA-2
  338. AC_MSG_CHECKING([support of SHA-2])
  339. LIBS_SAVED=${LIBS}
  340. LIBS="$LIBS $CRYPTO_LIBS"
  341. CPPFLAGS_SAVED=${CPPFLAGS}
  342. CPPFLAGS="$CRYPTO_INCLUDES $CPPFLAGS"
  343. AC_LINK_IFELSE(
  344. [AC_LANG_PROGRAM([#include <openssl/evp.h>],
  345. [const EVP_MD* h224 = EVP_sha224();
  346. const EVP_MD* h256 = EVP_sha256();
  347. const EVP_MD* h384 = EVP_sha384();
  348. const EVP_MD* h512 = EVP_sha512();
  349. ])],
  350. [AC_MSG_RESULT([yes])],
  351. [AC_MSG_ERROR([missing EVP entry for SHA-2])])
  352. dnl Check HMAC API
  353. AC_MSG_CHECKING([HMAC functions returning ints])
  354. AC_LINK_IFELSE(
  355. [AC_LANG_PROGRAM([#include <openssl/opensslv.h>
  356. #include <openssl/hmac.h>],
  357. [#if OPENSSL_VERSION_NUMBER < 0x10100000L
  358. HMAC_CTX ctx, tmp;
  359. int n = HMAC_Init(&ctx, NULL, 0, NULL);
  360. n += HMAC_Update(&ctx, NULL, 0);
  361. n += HMAC_CTX_copy(&tmp, &ctx);
  362. n += HMAC_Final(&tmp, NULL, NULL);
  363. #endif
  364. ])],
  365. [AC_MSG_RESULT([yes])],
  366. [AC_MSG_ERROR([HMAC functions return void: please use OpenSSL version 1.0.1 or later])])
  367. LIBS=${LIBS_SAVED}
  368. CPPFLAGS=${CPPFLAGS_SAVED}
  369. fi
  370. AM_CONDITIONAL(HAVE_BOTAN, test "$CRYPTO_NAME" = "Botan")
  371. AM_CONDITIONAL(HAVE_OPENSSL, test "$CRYPTO_NAME" = "OpenSSL")
  372. AC_SUBST(CRYPTO_INCLUDES)
  373. AC_SUBST(CRYPTO_CFLAGS)
  374. AC_SUBST(CRYPTO_LIBS)
  375. AC_SUBST(CRYPTO_LDFLAGS)
  376. AC_SUBST(CRYPTO_PACKAGE)
  377. AC_SUBST(CRYPTO_RPATH)
  378. AC_SUBST(DISTCHECK_CRYPTO_CONFIGURE_FLAG)
  379. ]
  380. )