Parcourir la source

[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
Jelte Jansen il y a 14 ans
Parent
commit
b50e03318e
2 fichiers modifiés avec 86 ajouts et 5 suppressions
  1. 53 4
      configure.ac
  2. 33 1
      src/lib/cryptolink/crypto_hmac.cc

+ 53 - 4
configure.ac

@@ -432,6 +432,20 @@ LDFLAGS_SAVED="$LDFLAGS"
 LDFLAGS="$BOTAN_LDFLAGS $LDFLAGS"
 LDFLAGS="$BOTAN_LDFLAGS $LDFLAGS"
 
 
 AC_CHECK_HEADERS([botan/botan.h],,AC_MSG_ERROR([Missing required header files.]))
 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_LINK_IFELSE(
         [AC_LANG_PROGRAM([#include <botan/botan.h>
         [AC_LANG_PROGRAM([#include <botan/botan.h>
                           #include <botan/hash.h>
                           #include <botan/hash.h>
@@ -439,11 +453,46 @@ AC_LINK_IFELSE(
                          [using namespace Botan;
                          [using namespace Botan;
                           LibraryInitializer::initialize();
                           LibraryInitializer::initialize();
                           HashFunction *h = get_hash("MD5");
                           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 <botan/botan.h>
+                          #include <botan/hash.h>
+                         ],
+                         [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
 CPPFLAGS=$CPPFLAGS_SAVED
 LDFLAGS=$LDFLAGS_SAVED
 LDFLAGS=$LDFLAGS_SAVED
 
 

+ 33 - 1
src/lib/cryptolink/crypto_hmac.cc

@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
+#include <config.h>
+
 #include <cryptolink.h>
 #include <cryptolink.h>
 #include <cryptolink/crypto_hmac.h>
 #include <cryptolink/crypto_hmac.h>
 
 
@@ -22,6 +24,8 @@
 #include <botan/hash.h>
 #include <botan/hash.h>
 #include <botan/types.h>
 #include <botan/types.h>
 
 
+// [XX] remove
+#include <iostream>
 namespace {
 namespace {
 const char*
 const char*
 getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) {
 getBotanHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm) {
@@ -70,12 +74,32 @@ public:
         // If the key length is larger than the block size, we hash the
         // If the key length is larger than the block size, we hash the
         // key itself first.
         // key itself first.
         try {
         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<Botan::byte> hashed_key =
                 Botan::SecureVector<Botan::byte> hashed_key =
                     hash->process(static_cast<const Botan::byte*>(secret),
                     hash->process(static_cast<const Botan::byte*>(secret),
                                   secret_len);
                                   secret_len);
                 hmac_->set_key(hashed_key.begin(), hashed_key.size());
                 hmac_->set_key(hashed_key.begin(), hashed_key.size());
             } else {
             } 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<const Botan::byte*>(secret),
                 hmac_->set_key(static_cast<const Botan::byte*>(secret),
                                secret_len);
                                secret_len);
             }
             }
@@ -89,7 +113,15 @@ public:
     ~HMACImpl() { }
     ~HMACImpl() { }
 
 
     size_t getOutputLength() const {
     size_t getOutputLength() const {
+#if (BOTAN_API_VERSION >= 100900)
+        return (hmac_->output_length());
+#elif (BOTAN_API_VERSION >= 100800)
         return (hmac_->OUTPUT_LENGTH);
         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) {
     void update(const void* data, const size_t len) {