From b50e03318eeb6464f7143eb524eb7b8ed2a5d02a Mon Sep 17 00:00:00 2001 From: Jelte Jansen Date: Wed, 18 May 2011 16:41:01 +0200 Subject: [PATCH 1/4] [trac936] check for botan API version, and use appropriate calls in cryptolink Added separate checks for compatibility with 1.8 and 1.9, see configure.ac cryptolink now has 3 special cases depending on version --- configure.ac | 57 ++++++++++++++++++++++++++++--- src/lib/cryptolink/crypto_hmac.cc | 34 +++++++++++++++++- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index d47892428d..3b8a7f2b3f 100644 --- a/configure.ac +++ b/configure.ac @@ -432,6 +432,20 @@ LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$BOTAN_LDFLAGS $LDFLAGS" AC_CHECK_HEADERS([botan/botan.h],,AC_MSG_ERROR([Missing required header files.])) + +# Find out which API version we have +# We use this in cyptolink implementations +# The defined value will have six numbers, XXYYZZ, where XX is major +# version, YY is minor version, and ZZ is patch level +# We do not ask for the specific function, but try out a specific +# api call known to belong to a specific function. Therefore ZZ should, +# at least in theory, not be relevant (and always 0). But you never know. +# (We do assume that none of the version parts will be higher than 99) + +# Set to 0 so we can error if we find no compatible versions +BOTAN_API_VERSION=0 + +# API for 1.8 AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include #include @@ -439,11 +453,46 @@ AC_LINK_IFELSE( [using namespace Botan; LibraryInitializer::initialize(); HashFunction *h = get_hash("MD5"); - ])], - [AC_MSG_RESULT([checking for Botan library... yes])], - [AC_MSG_RESULT([checking for Botan library... no]) - AC_MSG_ERROR([Needs Botan library 1.8 or higher])] + // 1.8 has HASH_BLOCK_SIZE + size_t s = h->HASH_BLOCK_SIZE; + ]) + ], + [ + AC_MSG_RESULT([checking for Botan library 1.8... yes]) + BOTAN_API_VERSION="1.8" + AC_DEFINE(BOTAN_API_VERSION, [100800], [Botan API version 1.8]) + ], + [ + AC_MSG_RESULT([checking for Botan library 1.8... no]) + ] ) + +# API for 1.9 +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include + #include + ], + [using namespace Botan; + LibraryInitializer::initialize(); + HashFunction *h = get_hash("MD5"); + // 1.9 has hash_block_size() + size_t s = h->hash_block_size(); + ]) + ], + [ + AC_MSG_RESULT([checking for Botan library 1.9... yes]) + BOTAN_API_VERSION="1.9" + AC_DEFINE(BOTAN_API_VERSION, [100900], [Botan API version 1.9 (or higher)]) + ], + [ + AC_MSG_RESULT([checking for Botan library 1.9... no]) + ] +) + +if test "$BOTAN_API_VERSION" = "0"; then + AC_MSG_ERROR([Botan linking failed, need botan-1.8 or higher, and the libraries it links to]) +fi + CPPFLAGS=$CPPFLAGS_SAVED LDFLAGS=$LDFLAGS_SAVED diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc index d20c85bc3f..576471b0c9 100644 --- a/src/lib/cryptolink/crypto_hmac.cc +++ b/src/lib/cryptolink/crypto_hmac.cc @@ -12,6 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include + #include #include @@ -22,6 +24,8 @@ #include #include +// [XX] remove +#include namespace { const char* getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) { @@ -70,12 +74,32 @@ public: // If the key length is larger than the block size, we hash the // key itself first. try { - if (secret_len > hash->HASH_BLOCK_SIZE) { + // use a temp var so we don't have blocks spanning + // preprocessor directives + size_t block_length; +#if (BOTAN_API_VERSION >= 100900) + block_length = hash->hash_block_size(); +#elif (BOTAN_API_VERSION >= 100800) + block_length = hash->HASH_BLOCK_SIZE; +#else +#error "Unsupported BOTAN_API_VERSION" + // added to suppress irrelevant compiler errors + block_length = 0; +#endif + + if (secret_len > block_length) { Botan::SecureVector hashed_key = hash->process(static_cast(secret), secret_len); hmac_->set_key(hashed_key.begin(), hashed_key.size()); } else { + // Apparently 1.9 considers 0 a valid secret length. + // We do not. +#if (BOTAN_API_VERSION >= 100900) + if (secret_len == 0) { + isc_throw(BadKey, "Bad HMAC secret length: 0"); + } +#endif hmac_->set_key(static_cast(secret), secret_len); } @@ -89,7 +113,15 @@ public: ~HMACImpl() { } size_t getOutputLength() const { +#if (BOTAN_API_VERSION >= 100900) + return (hmac_->output_length()); +#elif (BOTAN_API_VERSION >= 100800) return (hmac_->OUTPUT_LENGTH); +#else +#error "Unsupported BOTAN_API_VERSION" + // added to suppress irrelevant compiler errors + return 0; +#endif } void update(const void* data, const size_t len) { From 77def12e8d0d957d9fe587816b27b6df4f88ce90 Mon Sep 17 00:00:00 2001 From: Jelte Jansen Date: Wed, 18 May 2011 18:15:22 +0200 Subject: [PATCH 2/4] [trac936] use botan-provided version macro turns out botan had a check for exactly this, so we don't need to reinvent our own --- configure.ac | 57 +++---------------------------- src/lib/cryptolink/crypto_hmac.cc | 25 ++++++-------- 2 files changed, 15 insertions(+), 67 deletions(-) diff --git a/configure.ac b/configure.ac index 3b8a7f2b3f..d47892428d 100644 --- a/configure.ac +++ b/configure.ac @@ -432,20 +432,6 @@ LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$BOTAN_LDFLAGS $LDFLAGS" AC_CHECK_HEADERS([botan/botan.h],,AC_MSG_ERROR([Missing required header files.])) - -# Find out which API version we have -# We use this in cyptolink implementations -# The defined value will have six numbers, XXYYZZ, where XX is major -# version, YY is minor version, and ZZ is patch level -# We do not ask for the specific function, but try out a specific -# api call known to belong to a specific function. Therefore ZZ should, -# at least in theory, not be relevant (and always 0). But you never know. -# (We do assume that none of the version parts will be higher than 99) - -# Set to 0 so we can error if we find no compatible versions -BOTAN_API_VERSION=0 - -# API for 1.8 AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include #include @@ -453,46 +439,11 @@ AC_LINK_IFELSE( [using namespace Botan; LibraryInitializer::initialize(); HashFunction *h = get_hash("MD5"); - // 1.8 has HASH_BLOCK_SIZE - size_t s = h->HASH_BLOCK_SIZE; - ]) - ], - [ - AC_MSG_RESULT([checking for Botan library 1.8... yes]) - BOTAN_API_VERSION="1.8" - AC_DEFINE(BOTAN_API_VERSION, [100800], [Botan API version 1.8]) - ], - [ - AC_MSG_RESULT([checking for Botan library 1.8... no]) - ] + ])], + [AC_MSG_RESULT([checking for Botan library... yes])], + [AC_MSG_RESULT([checking for Botan library... no]) + AC_MSG_ERROR([Needs Botan library 1.8 or higher])] ) - -# API for 1.9 -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([#include - #include - ], - [using namespace Botan; - LibraryInitializer::initialize(); - HashFunction *h = get_hash("MD5"); - // 1.9 has hash_block_size() - size_t s = h->hash_block_size(); - ]) - ], - [ - AC_MSG_RESULT([checking for Botan library 1.9... yes]) - BOTAN_API_VERSION="1.9" - AC_DEFINE(BOTAN_API_VERSION, [100900], [Botan API version 1.9 (or higher)]) - ], - [ - AC_MSG_RESULT([checking for Botan library 1.9... no]) - ] -) - -if test "$BOTAN_API_VERSION" = "0"; then - AC_MSG_ERROR([Botan linking failed, need botan-1.8 or higher, and the libraries it links to]) -fi - CPPFLAGS=$CPPFLAGS_SAVED LDFLAGS=$LDFLAGS_SAVED diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc index 576471b0c9..2f41e5d127 100644 --- a/src/lib/cryptolink/crypto_hmac.cc +++ b/src/lib/cryptolink/crypto_hmac.cc @@ -19,13 +19,12 @@ #include +#include #include #include #include #include -// [XX] remove -#include namespace { const char* getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) { @@ -76,17 +75,15 @@ public: try { // use a temp var so we don't have blocks spanning // preprocessor directives - size_t block_length; -#if (BOTAN_API_VERSION >= 100900) - block_length = hash->hash_block_size(); -#elif (BOTAN_API_VERSION >= 100800) - block_length = hash->HASH_BLOCK_SIZE; +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0) + size_t block_length = hash->hash_block_size(); +#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) + size_t block_length = hash->HASH_BLOCK_SIZE; #else -#error "Unsupported BOTAN_API_VERSION" +#error "Unsupported BOTAN_API_VERSION (need 1.8 or higher)" // added to suppress irrelevant compiler errors - block_length = 0; + size_t block_length = 0; #endif - if (secret_len > block_length) { Botan::SecureVector hashed_key = hash->process(static_cast(secret), @@ -95,7 +92,7 @@ public: } else { // Apparently 1.9 considers 0 a valid secret length. // We do not. -#if (BOTAN_API_VERSION >= 100900) +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0) if (secret_len == 0) { isc_throw(BadKey, "Bad HMAC secret length: 0"); } @@ -113,12 +110,12 @@ public: ~HMACImpl() { } size_t getOutputLength() const { -#if (BOTAN_API_VERSION >= 100900) +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0) return (hmac_->output_length()); -#elif (BOTAN_API_VERSION >= 100800) +#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) return (hmac_->OUTPUT_LENGTH); #else -#error "Unsupported BOTAN_API_VERSION" +#error "Unsupported BOTAN_API_VERSION (need 1.8 or higher)" // added to suppress irrelevant compiler errors return 0; #endif From 71eb80242fd144bddc06c98b3bdaa91341a65f26 Mon Sep 17 00:00:00 2001 From: Jelte Jansen Date: Wed, 18 May 2011 20:17:02 +0200 Subject: [PATCH 3/4] [trac936] addressed some comments --- src/lib/cryptolink/crypto_hmac.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc index 2f41e5d127..d5a733b281 100644 --- a/src/lib/cryptolink/crypto_hmac.cc +++ b/src/lib/cryptolink/crypto_hmac.cc @@ -12,8 +12,6 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include - #include #include @@ -80,7 +78,7 @@ public: #elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) size_t block_length = hash->HASH_BLOCK_SIZE; #else -#error "Unsupported BOTAN_API_VERSION (need 1.8 or higher)" +#error "Unsupported Botan version (need 1.8 or higher)" // added to suppress irrelevant compiler errors size_t block_length = 0; #endif @@ -115,7 +113,7 @@ public: #elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) return (hmac_->OUTPUT_LENGTH); #else -#error "Unsupported BOTAN_API_VERSION (need 1.8 or higher)" +#error "Unsupported Botan version (need 1.8 or higher)" // added to suppress irrelevant compiler errors return 0; #endif From 89e3ffaa1fb56bcc76f626a64afcc25e506d8b54 Mon Sep 17 00:00:00 2001 From: Jelte Jansen Date: Wed, 18 May 2011 21:10:06 +0200 Subject: [PATCH 4/4] [trac936] always fail on secret_len == 0 --- src/lib/cryptolink/crypto_hmac.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc index d5a733b281..9aa9d2474d 100644 --- a/src/lib/cryptolink/crypto_hmac.cc +++ b/src/lib/cryptolink/crypto_hmac.cc @@ -88,13 +88,11 @@ public: secret_len); hmac_->set_key(hashed_key.begin(), hashed_key.size()); } else { - // Apparently 1.9 considers 0 a valid secret length. - // We do not. -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,0) + // Botan 1.8 considers len 0 a bad key. 1.9 does not, + // but we won't accept it anyway, and fail early if (secret_len == 0) { isc_throw(BadKey, "Bad HMAC secret length: 0"); } -#endif hmac_->set_key(static_cast(secret), secret_len); }