Browse Source

Merge pull request #11621 from jakesmith/hpcc-20426

HPCC-20426 cryptohelper into jlib dll, use openssl routines where available, refactor digisign

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 6 years ago
parent
commit
c86254dcd1

+ 0 - 1
dali/base/CMakeLists.txt

@@ -79,7 +79,6 @@ if(NOT PLUGIN)
     target_link_libraries(
         dalibase 
         jlib
-        cryptohelper
         mp 
         hrpc 
         remote)

+ 1 - 1
dali/base/dasess.cpp

@@ -467,7 +467,7 @@ bool createDaliSignature(const char * scope, IUserDescriptor *udesc, CDateTime &
         now.getString(timeStr, false);//get UTC timestamp
         VStringBuffer toSign("%s;%s;%s", scope, username.str(), timeStr.str());
 
-        pDSM->digiSign(toSign, b64sig);//Sign "scope;username;timeStamp"
+        pDSM->digiSign(b64sig, toSign);//Sign "scope;username;timeStamp"
         return true;
     }
     return false;

+ 0 - 1
dali/server/CMakeLists.txt

@@ -61,7 +61,6 @@ target_link_libraries ( daserver
          hrpc 
          remote 
          dalibase 
-         cryptohelper
     )
 IF (USE_OPENLDAP)
 target_link_libraries ( daserver LdapSecurity )

+ 2 - 2
dali/server/daldap.cpp

@@ -180,7 +180,7 @@ public:
                 VStringBuffer expectedStr("%s;%s;%s", obj, username.str(), requestTimestamp.str());
                 StringBuffer b64Signature(reqSignature);// signature of scope;user;timestamp
 
-                if (!pDSM->digiVerify(expectedStr, b64Signature))//does the digital signature match what we expect?
+                if (!pDSM->digiVerify(b64Signature, expectedStr))//does the digital signature match what we expect?
                 {
                     ERRLOG("LDAP: getPermissions(%s) scope=%s user=%s fails digital signature verification",key?key:"NULL",obj?obj:"NULL",username.str());
                     return SecAccess_None;//deny
@@ -268,7 +268,7 @@ public:
             if (pDSM && pDSM->isDigiVerifierConfigured())
             {
                 StringBuffer b64Signature(udesc->querySignature());
-                if (!pDSM->digiVerify(username, b64Signature))//digital signature valid?
+                if (!pDSM->digiVerify(b64Signature, username))//digital signature valid?
                 {
                     ERRLOG("LDAP: enableScopeScans(%s) : Invalid user digital signature", username.str());
                     *err = -1;

+ 20 - 8
system/jlib/CMakeLists.txt

@@ -31,17 +31,21 @@ CHECK_LIBRARY_EXISTS(crypt crypt "" HAVE_LIBCRYPT)
 endif ()
 
 if(NOT TARGET lzma)
-  add_subdirectory(../lzma ${CMAKE_BINARY_DIR}/system/lzma)
+  add_subdirectory(${HPCC_SOURCE_DIR}/system/lzma ${CMAKE_BINARY_DIR}/system/lzma)
 endif(NOT TARGET lzma)
 
 if(NOT TARGET lz4)
-  add_subdirectory(../lz4_sm ${CMAKE_BINARY_DIR}/system/lz4_sm)
+  add_subdirectory(${HPCC_SOURCE_DIR}/system/lz4_sm ${CMAKE_BINARY_DIR}/system/lz4_sm)
 endif(NOT TARGET lz4)
 
 if(NOT TARGET libbase58)
-  add_subdirectory(../libbase58 ${CMAKE_BINARY_DIR}/system/libbase58)
+  add_subdirectory(${HPCC_SOURCE_DIR}/system/libbase58 ${CMAKE_BINARY_DIR}/system/libbase58)
 endif(NOT TARGET libbase58)
 
+if(NOT TARGET cryptohelper)
+  add_subdirectory(${HPCC_SOURCE_DIR}/system/security/cryptohelper ${CMAKE_BINARY_DIR}/system/security/cryptohelper)
+endif(NOT TARGET cryptohelper)
+
 if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
   SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-switch -Wno-unused-parameter -Werror -Wno-error=delete-non-virtual-dtor")
 endif()
@@ -179,11 +183,13 @@ if (CMAKE_COMPILER_IS_GNUCC)
 endif ()
 
 include_directories ( 
-         ../../system/win32 
-         ../../system/include 
-         ../../system/lzma
-         ../../system/lz4_sm/lz4/lib
-         ../../system/libbase58
+         ${HPCC_SOURCE_DIR}/system/jlib
+         ${HPCC_SOURCE_DIR}/system/win32
+         ${HPCC_SOURCE_DIR}/system/include
+         ${HPCC_SOURCE_DIR}/system/lzma
+         ${HPCC_SOURCE_DIR}/system/lz4_sm/lz4/lib
+         ${HPCC_SOURCE_DIR}/system/libbase58
+         ${HPCC_SOURCE_DIR}/system/security/cryptohelper
          ${CMAKE_CURRENT_BINARY_DIR}  # for generated jelog.h file 
          ${CMAKE_BINARY_DIR}
          ${CMAKE_BINARY_DIR}/oss
@@ -196,6 +202,7 @@ target_link_libraries ( jlib
         lzma
         lz4
         libbase58
+        cryptohelper
        )
 
 if ( ${HAVE_LIBDL} )
@@ -206,8 +213,13 @@ if ( ${HAVE_LIBCRYPT} )
 target_link_libraries ( jlib crypt)
 endif ( ${HAVE_LIBCRYPT} )
 
+IF (USE_OPENSSL)
+target_link_libraries ( jlib ${OPENSSL_LIBRARIES})
+endif (USE_OPENSSL)
+
 if (WIN32)
  target_link_libraries ( jlib ws2_32 mpr.lib Winmm.lib psapi.lib )
+ SET_TARGET_PROPERTIES( jlib PROPERTIES LINK_FLAGS_DEBUG "/WHOLEARCHIVE:cryptohelper.lib")
 elseif (("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" ))
 else ()
  target_link_libraries ( jlib rt )

+ 29 - 2
system/jlib/jencrypt.cpp

@@ -18,6 +18,12 @@
 
 #include "jencrypt.hpp"
 
+#ifdef _USE_OPENSSL
+
+#include "ske.hpp"
+
+#endif
+
 // From rijndael.hpp and rijndael.cpp:
 //
 // Creation date : Sun Nov 5 2000 03:21:05 CEST
@@ -1766,6 +1772,8 @@ inline Rijndael::KeyLength getAesKeyType(size_t keylen)
     return Rijndael::Key32Bytes;
 }
 
+namespace jlib
+{
 
 MemoryBuffer &aesEncrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output)
 {
@@ -1780,11 +1788,9 @@ MemoryBuffer &aesEncrypt(const void *key, size_t keylen, const void *input, size
         output.setLength(len);
     else 
         throw MakeStringException(-1,"AES Encryption error: %d, %s", len, getAesErrorText(len));
-
     return output;
 }
 
-
 MemoryBuffer &aesDecrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output)
 {
     Rijndael rin;
@@ -1798,8 +1804,29 @@ MemoryBuffer &aesDecrypt(const void *key, size_t keylen, const void *input, size
         output.setLength(len);
     else 
         throw MakeStringException(-1,"AES Decryption error: %d, %s", len, getAesErrorText(len));
+    return output;
+}
 
+} // end of namespace jlib
+
+MemoryBuffer &aesEncrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output)
+{
+#if defined(_USE_OPENSSL) && !defined(_WIN32)
+    cryptohelper::aesEncrypt(output, inlen, input, keylen, (const char *)key);
+    return output;
+#else
+    return jlib::aesEncrypt(key, keylen, input, inlen, output);
+#endif
+}
+
+MemoryBuffer &aesDecrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output)
+{
+#if defined(_USE_OPENSSL) && !defined(_WIN32)
+    cryptohelper::aesDecrypt(output, inlen, input, keylen, (const char *)key);
     return output;
+#else
+    return jlib::aesDecrypt(key, keylen, input, inlen, output);
+#endif
 }
 
 #define CRYPTSIZE 32

+ 8 - 0
system/jlib/jencrypt.hpp

@@ -26,9 +26,17 @@
 
 //for AES, keylen must be 16, 24, or 32 Bytes
 
+namespace jlib
+{
+    extern jlib_decl MemoryBuffer &aesEncrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output);
+    extern jlib_decl MemoryBuffer &aesDecrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output);
+} // end of namespace jlib;
+
+// NB: these are wrappers to either the openssl versions (if USE_OPENSSL) or the jlib version.
 extern jlib_decl MemoryBuffer &aesEncrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output);
 extern jlib_decl MemoryBuffer &aesDecrypt(const void *key, size_t keylen, const void *input, size_t inlen, MemoryBuffer &output);
 
+
 #define encrypt _LogProcessError12
 #define decrypt _LogProcessError15
 

+ 36 - 0
system/jlib/jexcept.cpp

@@ -114,6 +114,42 @@ IException jlib_decl *makeStringException(MessageAudience aud,int code,const cha
     return new StringException(code,why,aud);
 }
 
+class jlib_thrown_decl WrappedException: public StringException
+{
+    typedef StringException PARENT;
+public:
+    WrappedException(IException *_exception, int code, const char *str, MessageAudience aud = MSGAUD_user) : StringException(code, str, aud), exception(_exception) { }
+
+    virtual StringBuffer &  errorMessage(StringBuffer &str) const override
+    {
+        PARENT::errorMessage(str);
+        if (exception)
+        {
+            str.appendf("[ %u, ", exception->errorCode());
+            exception->errorMessage(str).append(" ]");
+        }
+        return str;
+    }
+protected:
+    Owned<IException> exception;
+};
+
+IException *makeWrappedExceptionVA(IException *e, int code, const char *format, va_list args)
+{
+    StringBuffer eStr;
+    eStr.limited_valist_appendf(1024, format, args);
+    return new WrappedException(e, code, eStr.str());
+}
+
+IException *makeWrappedExceptionV(IException *e, int code, const char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    IException *ret = makeWrappedExceptionVA(e, code, format, args);
+    va_end(args);
+    return ret;
+}
+
 void jlib_decl throwStringExceptionV(int code,const char *format, ...)
 {
     va_list args;

+ 2 - 0
system/jlib/jexcept.hpp

@@ -74,6 +74,8 @@ IException jlib_decl *makeStringExceptionV(MessageAudience aud, int code, const
 IException jlib_decl *makeStringExceptionVA(MessageAudience aud, int code, const char *why, va_list args) __attribute__((format(printf, 3, 0)));
 IException jlib_decl *makeStringException(MessageAudience aud, int code, const char *why);
 __declspec(noreturn) void jlib_decl throwStringExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3), noreturn));
+IException jlib_decl *makeWrappedExceptionVA(IException *e, int code, const char *why, va_list args) __attribute__((format(printf, 3, 0)));
+IException jlib_decl *makeWrappedExceptionV(IException *e, int code, const char *why, ...) __attribute__((format(printf, 3, 4)));
 
 // Macros for legacy names of above functions
 

+ 0 - 2
system/security/CMakeLists.txt

@@ -24,8 +24,6 @@ if (USE_ZLIB)
   HPCC_ADD_SUBDIRECTORY (zcrypt)
 endif()
 
-HPCC_ADD_SUBDIRECTORY (cryptohelper)
-
 IF (USE_APR)
   HPCC_ADD_SUBDIRECTORY (plugins/htpasswdSecurity)
 ENDIF(USE_APR)

+ 0 - 1
system/security/LdapSecurity/CMakeLists.txt

@@ -55,7 +55,6 @@ HPCC_ADD_LIBRARY( LdapSecurity SHARED ${SRCS} )
 install ( TARGETS LdapSecurity RUNTIME DESTINATION ${EXEC_DIR} LIBRARY DESTINATION ${LIB_DIR} )
 target_link_libraries ( LdapSecurity
          jlib
-         cryptohelper
          dalibase
          ${OPENLDAP_LIBRARIES}
     )

+ 2 - 2
system/security/LdapSecurity/ldapsecurity.cpp

@@ -671,7 +671,7 @@ bool CLdapSecManager::authenticate(ISecUser* user)
     if (pDSM && pDSM->isDigiVerifierConfigured() && !isEmptyString(user->credentials().getSignature()))
     {
         StringBuffer b64Signature(user->credentials().getSignature());
-        if (!pDSM->digiVerify(user->getName(), b64Signature))//digital signature valid?
+        if (!pDSM->digiVerify(b64Signature, user->getName()))//digital signature valid?
         {
             user->setAuthenticateStatus(AS_INVALID_CREDENTIALS);
             WARNLOG("Invalid digital signature for user %s", user->getName());
@@ -711,7 +711,7 @@ bool CLdapSecManager::authenticate(ISecUser* user)
             {
                //Set user digital signature
                StringBuffer b64Signature;
-               pDSM->digiSign(user->getName(), b64Signature);
+               pDSM->digiSign(b64Signature, user->getName());
                user->credentials().setSignature(b64Signature);
             }
         }

+ 7 - 18
system/security/cryptohelper/CMakeLists.txt

@@ -40,24 +40,13 @@ include_directories (
         ${OPENSSL_INCLUDE_DIR}
     )
 
-ADD_DEFINITIONS ( -DCRYPTOHELPER_EXPORTS -D_USRDLL )
+IF (USE_OPENSSL)
+    include_directories(${OPENSSL_INCLUDE_DIR})
+ENDIF()
 
-HPCC_ADD_LIBRARY( cryptohelper SHARED ${SRCS} )
+ADD_DEFINITIONS( -D_LIB )
+ADD_DEFINITIONS( -D_USRDLL -DJLIB_EXPORTS )
 
-install (
-        TARGETS cryptohelper
-        RUNTIME DESTINATION ${EXEC_DIR}
-        LIBRARY DESTINATION ${LIB_DIR}
-    )
-
-target_link_libraries (
-        cryptohelper
-        jlib
-    )
+#SET_SOURCE_FILES_PROPERTIES( ${SRCS} PROPERTIES LANGUAGE CXX )
+HPCC_ADD_LIBRARY( cryptohelper STATIC ${SRCS} )
 
-if (USE_OPENSSL)
-      target_link_libraries (
-          cryptohelper
-          ${OPENSSL_LIBRARIES}
-    )
-endif()

+ 36 - 2
system/security/cryptohelper/cryptocommon.cpp

@@ -17,21 +17,55 @@
 
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
 
+#include <memory>
 #include "jliball.hpp"
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#include <openssl/ssl.h>
 #include "cryptocommon.hpp"
 
 
-static void addAlgorithms()
+static unsigned numCryptoLocks = 0;
+static std::vector<std::unique_ptr<CriticalSection>> cryptoLocks;
+
+
+static void locking_function(int mode, int n, const char * file, int line)
+{
+    assertex(n < numCryptoLocks);
+    if (mode & CRYPTO_LOCK)
+        cryptoLocks[n]->enter();
+    else
+        cryptoLocks[n]->leave();
+}
+
+static unsigned long pthreads_thread_id()
 {
+    return (unsigned long)GetCurrentThreadId();
+}
+
+static void initSSLLibrary()
+{
+    SSL_load_error_strings();
+    SSLeay_add_ssl_algorithms();
+    if (!CRYPTO_get_locking_callback())
+    {
+        numCryptoLocks = CRYPTO_num_locks();
+        for (unsigned i=0; i<numCryptoLocks; i++)
+            cryptoLocks.push_back(std::unique_ptr<CriticalSection>(new CriticalSection));
+        CRYPTO_set_locking_callback(locking_function);
+    }
+#ifndef _WIN32
+    if (!CRYPTO_get_id_callback())
+        CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+#endif
     OpenSSL_add_all_algorithms();
 }
 
+
 MODULE_INIT(INIT_PRIORITY_STANDARD)
 {
-    addAlgorithms();
+    initSSLLibrary();
     return true;
 }
 MODULE_EXIT()

+ 13 - 15
system/security/cryptohelper/cryptocommon.hpp

@@ -18,29 +18,22 @@
 #ifndef CRYPTOCOMMON_HPP
 #define CRYPTOCOMMON_HPP
 
-#ifndef CRYPTOHELPER_API
-
-#ifndef CRYPTOHELPER_EXPORTS
-    #define CRYPTOHELPER_API DECL_IMPORT
-#else
-    #define CRYPTOHELPER_API DECL_EXPORT
-#endif //CRYPTOHELPER_EXPORTS
-
-#endif
-
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
 
 #include <openssl/pem.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
+#include "jiface.hpp"
+#include "jbuff.hpp"
+
 namespace cryptohelper
 {
 
-CRYPTOHELPER_API IException *makeEVPException(int code, const char *msg);
-CRYPTOHELPER_API IException *makeEVPExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3)));
-CRYPTOHELPER_API void throwEVPException(int code, const char *format);
-CRYPTOHELPER_API void throwEVPExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3)));
+jlib_decl IException *makeEVPException(int code, const char *msg);
+jlib_decl IException *makeEVPExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3)));
+jlib_decl void throwEVPException(int code, const char *format);
+jlib_decl void throwEVPExceptionV(int code, const char *format, ...) __attribute__((format(printf, 2, 3)));
 
 inline void voidBIOfree(BIO *bio) { BIO_free(bio); }
 inline void voidOpenSSLFree(void *m) { OPENSSL_free(m); }
@@ -51,10 +44,15 @@ typedef OwnedPtrCustomFree<EVP_PKEY_CTX, EVP_PKEY_CTX_free> OwnedEVPPkeyCtx;
 typedef OwnedPtrCustomFree<void, voidOpenSSLFree> OwnedEVPMemory;
 typedef OwnedPtrCustomFree<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> OwnedEVPCipherCtx;
 typedef OwnedPtrCustomFree<RSA, RSA_free> OwnedEVPRSA;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+typedef OwnedPtrCustomFree<EVP_MD_CTX, EVP_MD_CTX_destroy> OwnedEVPMdCtx;
+#else
+typedef OwnedPtrCustomFree<EVP_MD_CTX, EVP_MD_CTX_free> OwnedEVPMdCtx;
+#endif
 
 } // end of namespace cryptohelper
 
 #endif // end of #if defined(_USE_OPENSSL) && !defined(_WIN32)
 
-#endif
+#endif // CRYPTOCOMMON_HPP
 

+ 207 - 214
system/security/cryptohelper/digisign.cpp

@@ -21,7 +21,6 @@
 #include <openssl/evp.h>
 #endif
 #include "jencrypt.hpp"
-#include "cryptocommon.hpp"
 #include "digisign.hpp"
 #include <mutex>
 
@@ -31,235 +30,173 @@ namespace cryptohelper
 
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
 
-#define EVP_CLEANUP(key,ctx) EVP_PKEY_free(key);       \
-                             EVP_MD_CTX_destroy(ctx);
 
-class CDigitalSignatureManager : implements IDigitalSignatureManager, public CInterface
+//Create base 64 encoded digital signature of given data
+bool digiSign(StringBuffer &b64Signature, size32_t dataSz, const void *data, const CLoadedKey &signingKey)
 {
-private:
-    StringBuffer publicKeyBuff;
-    StringBuffer privateKeyBuff;
-    StringBuffer passphraseBuffEnc;
-    bool         signingConfigured;
-    bool         verifyingConfigured;
+    OwnedEVPMdCtx signingCtx(EVP_MD_CTX_create());
+    //initialize context for SHA-256 hashing function
+    int rc = EVP_DigestSignInit(signingCtx, nullptr, EVP_sha256(), nullptr, signingKey);
+    if (rc <= 0)
+        throwEVPException(-1, "digiSign:EVP_DigestSignInit");
 
-    bool digiInit(bool isSigning, const char * passphraseEnc, EVP_MD_CTX * * ctx, EVP_PKEY * * PKey)
-    {
-        //To avoid threading issues, the keys are created on each call. Otherwise would require
-        //serialization with a critical section or implementing locking callbacks
-        const char * keyBuff = isSigning ? privateKeyBuff.str() : publicKeyBuff.str();
+    //add string to the context
+    if (EVP_DigestSignUpdate(signingCtx, data, dataSz) <= 0)
+        throwEVPException(-1, "digiSign:EVP_DigestSignUpdate");
 
-        //create an RSA object from public key
-        BIO * keybio = BIO_new_mem_buf((void*) keyBuff, -1);
-        if (nullptr == keybio)
-            throwEVPException(-1, "digiSign:BIO_new_mem_buf");
+    //compute length of signature
+    size_t encMsgLen;
+    if (EVP_DigestSignFinal(signingCtx, nullptr, &encMsgLen) <= 0)
+        throwEVPException(-1, "digiSign:EVP_DigestSignFinal1");
 
-        RSA * rsa;
-        if (isSigning)
-        {
-            StringBuffer ppDec;
-            if (!isEmptyString(passphraseEnc))
-                decrypt(ppDec, passphraseEnc);
-            rsa = PEM_read_bio_RSAPrivateKey(keybio, nullptr, nullptr, (void*)ppDec.str());
-        }
-        else
-            rsa = PEM_read_bio_RSA_PUBKEY(keybio, nullptr, nullptr, nullptr);
-        BIO_free_all(keybio);
-        if (nullptr == rsa)
-        {
-            if (isSigning)
-                throwEVPException(-1, "digiSign:PEM_read_bio_RSAPrivateKey");
-            else
-                throwEVPException(-1, "digiSign:PEM_read_bio_RSA_PUBKEY");
-        }
+    if (encMsgLen == 0)
+        throwEVPException(-1, "digiSign:EVP_DigestSignFinal length returned 0");
 
-        EVP_PKEY* pKey = EVP_PKEY_new();
-        if (nullptr == pKey)
-        {
-            RSA_free(rsa);
-            throwEVPException(-1, "digiSign:EVP_PKEY_new");
-        }
-        EVP_PKEY_assign_RSA(pKey, rsa);//take ownership of the rsa. pKey will free rsa
+    //compute signature (signed digest)
+    OwnedEVPMemory encMsg = OPENSSL_malloc(encMsgLen);
+    if (encMsg == nullptr)
+        throw MakeStringException(-1, "digiSign:OPENSSL_malloc(%u) returned NULL", (unsigned)encMsgLen);
 
-        EVP_MD_CTX * RSACtx = EVP_MD_CTX_create();//allocate, initializes and return a digest context
-        if (nullptr == RSACtx)
-        {
-            EVP_PKEY_free(pKey);
-            throwEVPException(-1, "digiSign:EVP_MD_CTX_create");
-        }
+    if (EVP_DigestSignFinal(signingCtx, (unsigned char *)encMsg.get(), &encMsgLen) <= 0)
+        throwEVPException(-1, "digiSign:EVP_DigestSignFinal2");
 
-        //initialize context for SHA-256 hashing function
-        int rc;
-        if (isSigning)
-            rc = EVP_DigestSignInit(RSACtx, nullptr, EVP_sha256(), nullptr, pKey);
-        else
-            rc = EVP_DigestVerifyInit(RSACtx, nullptr, EVP_sha256(), nullptr, pKey);
-        if (rc <= 0)
-        {
-            EVP_CLEANUP(pKey, RSACtx);//cleans allocated key and digest context
-            if (isSigning)
-                throwEVPException(-1, "digiSign:EVP_DigestSignInit");
-            else
-                throwEVPException(-1, "digiSign:EVP_DigestVerifyInit");
-        }
-        *ctx = RSACtx;
-        *PKey = pKey;
-        return true;
-    }
+    //convert to base64
+    JBASE64_Encode(encMsg, encMsgLen, b64Signature, false);
 
-public:
-    IMPLEMENT_IINTERFACE;
+    return true;
+}
 
-    CDigitalSignatureManager(const char * _pubKeyBuff, const char * _privKeyBuff, const char * _passPhrase)
-        : signingConfigured(false), verifyingConfigured(false)
+//Verify the given data was used to create the given digital signature
+bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data, const CLoadedKey &verifyingKey)
+{
+    OwnedEVPMdCtx verifyingCtx(EVP_MD_CTX_create());
+    int rc = EVP_DigestVerifyInit(verifyingCtx, nullptr, EVP_sha256(), nullptr, verifyingKey);
+    if (rc <= 0)
+        throwEVPException(-1, "digiVerify:EVP_DigestVerifyInit");
+
+    //decode base64 signature
+    StringBuffer decodedSig;
+    JBASE64_Decode(b64Signature, decodedSig);
+
+    if (EVP_DigestVerifyUpdate(verifyingCtx, data, dataSz) <= 0)
+        throwEVPException(-1, "digiVerify:EVP_DigestVerifyUpdate");
+
+    return 1 == EVP_DigestVerifyFinal(verifyingCtx, (unsigned char *)decodedSig.str(), decodedSig.length());
+}
+
+
+class CDigitalSignatureManager : public CSimpleInterfaceOf<IDigitalSignatureManager>
+{
+private:
+    Linked<CLoadedKey> pubKey, privKey;
+    bool         signingConfigured = false;
+    bool         verifyingConfigured = false;
+
+public:
+    CDigitalSignatureManager(CLoadedKey *_pubKey, CLoadedKey *_privKey) : pubKey(_pubKey), privKey(_privKey)
     {
-        publicKeyBuff.set(_pubKeyBuff);
-        privateKeyBuff.set(_privKeyBuff);
-        passphraseBuffEnc.set(_passPhrase);//MD5 encrypted passphrase
-        signingConfigured = !privateKeyBuff.isEmpty();
-        verifyingConfigured = !publicKeyBuff.isEmpty();
+        signingConfigured = nullptr != privKey.get();
+        verifyingConfigured = nullptr != pubKey.get();
     }
 
-    bool isDigiSignerConfigured()
+    virtual bool isDigiSignerConfigured() const override
     {
         return signingConfigured;
     }
 
-    bool isDigiVerifierConfigured()
+    virtual bool isDigiVerifierConfigured() const override
     {
         return verifyingConfigured;
     }
 
-    //Create base 64 encoded digital signature of given text string
-    bool digiSign(const char * text, StringBuffer & b64Signature)
+    //Create base 64 encoded digital signature of given data
+    virtual bool digiSign(StringBuffer & b64Signature, size32_t dataSz, const void *data) const override
     {
         if (!signingConfigured)
             throw MakeStringException(-1, "digiSign:Creating Digital Signatures not configured");
 
-        EVP_MD_CTX * signingCtx;
-        EVP_PKEY *   signingKey;
-        digiInit(true, passphraseBuffEnc.str(), &signingCtx, &signingKey);
-
-        //add string to the context
-        if (EVP_DigestSignUpdate(signingCtx, (size_t*)text, strlen(text)) <= 0)
-        {
-            EVP_CLEANUP(signingKey, signingCtx);
-            throwEVPException(-1, "digiSign:EVP_DigestSignUpdate");
-        }
-
-        //compute length of signature
-        size_t encMsgLen;
-        if (EVP_DigestSignFinal(signingCtx, nullptr, &encMsgLen) <= 0)
-        {
-            EVP_CLEANUP(signingKey, signingCtx);
-            throwEVPException(-1, "digiSign:EVP_DigestSignFinal1");
-        }
-
-        if (encMsgLen == 0)
-        {
-            EVP_CLEANUP(signingKey, signingCtx);
-            throwEVPException(-1, "digiSign:EVP_DigestSignFinal length returned 0");
-        }
-
-        //compute signature (signed digest)
-        unsigned char * encMsg = (unsigned char*) malloc(encMsgLen);
-        if (encMsg == nullptr)
-        {
-            EVP_CLEANUP(signingKey, signingCtx);
-            throw MakeStringException(-1, "digiSign:malloc(%u) returned NULL",(unsigned)encMsgLen);
-        }
-
-        if (EVP_DigestSignFinal(signingCtx, encMsg, &encMsgLen) <= 0)
-        {
-            free(encMsg);
-            EVP_CLEANUP(signingKey, signingCtx);
-            throwEVPException(-1, "digiSign:EVP_DigestSignFinal2");
-        }
-
-
-        //convert to base64
-        JBASE64_Encode(encMsg, encMsgLen, b64Signature, false);
-
-        //cleanup
-        free(encMsg);
-        EVP_CLEANUP(signingKey, signingCtx);
-        return true;//success
+        return cryptohelper::digiSign(b64Signature, dataSz, data, *privKey);
     }
 
+    virtual bool digiSign(StringBuffer & b64Signature, const char *text) const override
+    {
+        return digiSign(b64Signature, strlen(text), text);
+    }
 
-    //Verify the given text was used to create the given digital signature
-    bool digiVerify(const char * text, StringBuffer & b64Signature)
+    //Verify the given data was used to create the given digital signature
+    virtual bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data) const override
     {
         if (!verifyingConfigured)
             throw MakeStringException(-1, "digiVerify:Verifying Digital Signatures not configured");
 
-        EVP_MD_CTX * verifyingCtx;
-        EVP_PKEY *   verifyingKey;
-        digiInit(false, passphraseBuffEnc.str(), &verifyingCtx, &verifyingKey);
-
-        //decode base64 signature
-        StringBuffer decodedSig;
-        JBASE64_Decode(b64Signature.str(), decodedSig);
-
-        if (EVP_DigestVerifyUpdate(verifyingCtx, text, strlen(text)) <= 0)
-        {
-            EVP_CLEANUP(verifyingKey, verifyingCtx);
-            throwEVPException(-1, "digiVerify:EVP_DigestVerifyUpdate");
-        }
+        return cryptohelper::digiVerify(b64Signature, dataSz, data, *pubKey);
+    }
 
-        int match = EVP_DigestVerifyFinal(verifyingCtx, (unsigned char *)decodedSig.str(), decodedSig.length());
-        EVP_CLEANUP(verifyingKey, verifyingCtx);
-        return match == 1;
+    virtual bool digiVerify(const char *b64Signature, const char *text) const override
+    {
+        return digiVerify(b64Signature, strlen(text), text);
     }
 };
 
 #else
 
 //Dummy implementation if no OPENSSL available.
-class CDigitalSignatureManager : implements IDigitalSignatureManager, public CInterface
+
+bool digiSign(StringBuffer &b64Signature, const char *text, const CLoadedKey &signingKey)
 {
-public:
-    IMPLEMENT_IINTERFACE;
+    throwStringExceptionV(-1, "digiSign: unavailable without openssl");
+}
+
+bool digiVerify(const char *b64Signature, const char *text, const CLoadedKey &verifyingKey)
+{
+    throwStringExceptionV(-1, "digiVerify: unavailable without openssl");
+}
 
+class CDigitalSignatureManager : public CSimpleInterfaceOf<IDigitalSignatureManager>
+{
+public:
     CDigitalSignatureManager(const char * _pubKeyBuff, const char * _privKeyBuff, const char * _passPhrase)
     {
         WARNLOG("CDigitalSignatureManager: Platform built without OPENSSL!");
     }
 
-    bool isDigiSignerConfigured()
+    virtual bool isDigiSignerConfigured() const override
     {
         return false;
     }
 
-    bool isDigiVerifierConfigured()
+    virtual bool isDigiVerifierConfigured() const override
     {
         return false;
     }
 
-    //Create base 64 encoded digital signature of given text string
-    bool digiSign(const char * text, StringBuffer & b64Signature)
+
+    virtual bool digiSign(StringBuffer & b64Signature, size32_t dataSz, const void *data) const override
     {
-        //convert to base64
-        JBASE64_Encode(text, strlen(text), b64Signature, false);
-        return true;//success
+        throwStringExceptionV(-1, "digiSign: unavailable without openssl");
     }
 
-    //Verify the given text was used to create the given digital signature
-    bool digiVerify(const char * text, StringBuffer & b64Signature)
+    virtual bool digiSign(StringBuffer & b64Signature, const char * text) const override
     {
-        //decode base64 signature
-        StringBuffer decodedSig;
-        JBASE64_Decode(b64Signature.str(), decodedSig);
-        return streq(text, decodedSig);
+        throwStringExceptionV(-1, "digiSign: unavailable without openssl");
+    }
+
+    virtual bool digiVerify(const char *b64Signature, const char * text) const override
+    {
+        throwStringExceptionV(-1, "digiVerify: unavailable without openssl");
+    }
+
+    virtual bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data) const override
+    {
+        throwStringExceptionV(-1, "digiVerify: unavailable without openssl");
     }
 };
 
 #endif
 
 
-static IDigitalSignatureManager * dsm;
+static IDigitalSignatureManager * dsm = nullptr;
 static std::once_flag dsmInitFlag;
-static std::once_flag dsmAddAlgoFlag;
 
 MODULE_INIT(INIT_PRIORITY_STANDARD)
 {
@@ -277,79 +214,135 @@ static void createDigitalSignatureManagerInstance(IDigitalSignatureManager * * p
     *ppDSM = createDigitalSignatureManagerInstanceFromFiles(pubKey, privKey, passPhrase);
 }
 
-static void addAlgorithms()
+
+//Returns reference to singleton instance created from environment.conf key file settings
+IDigitalSignatureManager * queryDigitalSignatureManagerInstanceFromEnv()
 {
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
-    OpenSSL_add_all_algorithms();
+    std::call_once(dsmInitFlag, createDigitalSignatureManagerInstance, &dsm);
+    return dsm;
+#else
+    return nullptr;
 #endif
 }
 
-extern "C"
+//Create using given key filespecs
+//Caller must release when no longer needed
+IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromFiles(const char * pubKeyFileName, const char *privKeyFileName, const char * passPhrase)
 {
-    //Returns reference to singleton instance created from environment.conf key file settings
-    CRYPTOHELPER_API IDigitalSignatureManager * queryDigitalSignatureManagerInstanceFromEnv()
-    {
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
-        std::call_once(dsmInitFlag, createDigitalSignatureManagerInstance, &dsm);
-        return dsm;
-#else
-        return nullptr;
-#endif
+    Owned<CLoadedKey> pubKey, privKey;
+
+    Owned<IMultiException> exceptions;
+    if (!isEmptyString(pubKeyFileName))
+    {
+        try
+        {
+            pubKey.setown(loadPublicKeyFromFile(pubKeyFileName, passPhrase));
+        }
+        catch (IException * e)
+        {
+            if (!exceptions)
+                exceptions.setown(makeMultiException("createDigitalSignatureManagerInstanceFromFiles"));
+
+            exceptions->append(* makeWrappedExceptionV(e, -1, "createDigitalSignatureManagerInstanceFromFiles:Cannot load public key file"));
+            e->Release();
+        }
+    }
+
+    if (!isEmptyString(privKeyFileName))
+    {
+        try
+        {
+            privKey.setown(loadPrivateKeyFromFile(privKeyFileName, passPhrase));
+        }
+        catch (IException * e)
+        {
+            if (!exceptions)
+                exceptions.setown(makeMultiException("createDigitalSignatureManagerInstanceFromFiles"));
+
+            exceptions->append(* makeWrappedExceptionV(e, -1, "createDigitalSignatureManagerInstanceFromFiles:Cannot load private key file"));
+            e->Release();
+        }
     }
 
-    //Create using given key filespecs
-    //Caller must release when no longer needed
-    CRYPTOHELPER_API IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromFiles(const char * _pubKey, const char *_privKey, const char * _passPhrase)
+    // NB: allow it continue if 1 of the keys successfully loaded.
+    if (exceptions && exceptions->ordinality())
     {
+        if (!pubKey && !privKey)
+            throw exceptions.getClear();
+        else
+            EXCLOG(exceptions, nullptr);
+    }
+
+    return new CDigitalSignatureManager(pubKey, privKey);
+#else
+    return nullptr;
+#endif
+}
+
+//Create using given PEM formatted keys
+//Caller must release when no longer needed
+IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(const char * pubKeyString, const char * privKeyString, const char * passPhrase)
+{
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
-        StringBuffer privateKeyBuff;
-        StringBuffer publicKeyBuff;
+    Owned<CLoadedKey> pubKey, privKey;
 
-        if (!isEmptyString(_pubKey))
+    Owned<IMultiException> exceptions;
+    if (!isEmptyString(pubKeyString))
+    {
+        try
         {
-            try
-            {
-                publicKeyBuff.loadFile(_pubKey);
-            }
-            catch (IException * e)
-            {
-                e->Release();
-            }
-            if (publicKeyBuff.isEmpty())
-                throw MakeStringException(-1, "digiSign:Cannot load public key file");
+            pubKey.setown(loadPublicKeyFromMemory(pubKeyString, passPhrase));
         }
+        catch (IException * e)
+        {
+            if (!exceptions)
+                exceptions.setown(makeMultiException("createDigitalSignatureManagerInstanceFromKeys"));
 
-        if (!isEmptyString(_privKey))
+            exceptions->append(* makeWrappedExceptionV(e, -1, "createDigitalSignatureManagerInstanceFromFiles:Cannot load public key"));
+            e->Release();
+        }
+    }
+    if (!isEmptyString(privKeyString))
+    {
+        try
         {
-            try
-            {
-                privateKeyBuff.loadFile(_privKey);
-            }
-            catch (IException * e)
-            {
-                e->Release();
-            }
-            if (privateKeyBuff.isEmpty())
-                throw MakeStringException(-1, "digiSign:Cannot load private key file");
+            privKey.setown(loadPrivateKeyFromMemory(privKeyString, passPhrase));
         }
+        catch (IException * e)
+        {
+            if (!exceptions)
+                exceptions.setown(makeMultiException("createDigitalSignatureManagerInstanceFromKeys"));
 
-        return createDigitalSignatureManagerInstanceFromKeys(publicKeyBuff, privateKeyBuff, _passPhrase);
-#else
-        return nullptr;
-#endif
+            exceptions->append(* makeWrappedExceptionV(e, -1, "createDigitalSignatureManagerInstanceFromFiles:Cannot load private key"));
+            e->Release();
+        }
     }
 
-    //Create using given PEM formatted keys
-    //Caller must release when no longer needed
-    CRYPTOHELPER_API IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(StringBuffer & _pubKeyBuff, StringBuffer & _privKeyBuff, const char * _passPhrase)
+    // NB: allow it continue if 1 of the keys successfully loaded.
+    if (exceptions && exceptions->ordinality())
     {
+        if (!pubKey && !privKey)
+            throw exceptions.getClear();
+        else
+            EXCLOG(exceptions, nullptr);
+    }
+    return new CDigitalSignatureManager(pubKey, privKey);
+#else
+    return nullptr;
+#endif
+}
+
+//Create using preloaded keys
+//Caller must release when no longer needed
+IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(CLoadedKey *pubKey, CLoadedKey *privKey)
+{
 #if defined(_USE_OPENSSL) && !defined(_WIN32)
-        std::call_once(dsmAddAlgoFlag, addAlgorithms);
-        return new CDigitalSignatureManager(_pubKeyBuff, _privKeyBuff, _passPhrase);
+    return new CDigitalSignatureManager(pubKey, privKey);
 #else
-        return nullptr;
+    return nullptr;
 #endif
-    }
 }
 
 } // namespace cryptohelper

+ 26 - 24
system/security/cryptohelper/digisign.hpp

@@ -17,43 +17,45 @@
 #ifndef DIGISIGN_HPP
 #define DIGISIGN_HPP
 
-#ifndef CRYPTOHELPER_API
+#include "jiface.hpp"
 
-#ifndef CRYPTOHELPER_EXPORTS
-    #define CRYPTOHELPER_API DECL_IMPORT
-#else
-    #define CRYPTOHELPER_API DECL_EXPORT
-#endif //CRYPTOHELPER_EXPORTS
-
-#endif
+#include "pke.hpp"
 
 namespace cryptohelper
 {
 
+//Create base 64 encoded digital signature of given data
+jlib_decl bool digiSign(StringBuffer &b64Signature, size32_t dataSz, const void *data, const CLoadedKey &signingKey);
+
+//Verify the given data was used to create the given digital signature
+jlib_decl bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data, const CLoadedKey &verifyingKey);
+
 //General purpose digital signature manager
-//Useful to sign a text string, so the consumer can be assured it has not been altered
-interface IDigitalSignatureManager : extends IInterface //Public/Private key message signer/verifyer
+//Useful to sign data, so the consumer can be assured it has not been altered
+interface jlib_decl IDigitalSignatureManager : extends IInterface //Public/Private key message signer/verifyer
 {
 public:
-    virtual bool isDigiSignerConfigured() = 0;
-    virtual bool isDigiVerifierConfigured() = 0;
-    virtual bool digiSign(const char * text, StringBuffer & b64Signature) = 0;//signs, using private key
-    virtual bool digiVerify(const char * text, StringBuffer & b64Signature) = 0;//verifies, using public key
+    virtual bool isDigiSignerConfigured() const = 0;
+    virtual bool isDigiVerifierConfigured() const = 0;
+    virtual bool digiSign(StringBuffer & b64Signature, size32_t dataSz, const void *data) const = 0;//signs, using private key
+    virtual bool digiSign(StringBuffer & b64Signature, const char *text) const = 0;
+    virtual bool digiVerify(const char *b64Signature, size32_t dataSz, const void *data) const = 0;//verifies, using public key
+    virtual bool digiVerify(const char *b64Signature, const char *text) const = 0;
 };
 
-extern "C"
-{
-    //Uses the HPCCPublicKey/HPCCPrivateKey key files specified in environment.conf
-    CRYPTOHELPER_API IDigitalSignatureManager * queryDigitalSignatureManagerInstanceFromEnv();
+//Uses the HPCCPublicKey/HPCCPrivateKey key files specified in environment.conf
+jlib_decl IDigitalSignatureManager * queryDigitalSignatureManagerInstanceFromEnv();
+
+//Create using the given key files
+jlib_decl IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromFiles(const char *pubKeyFileName, const char *privKeyFileName, const char *passPhrase);
 
-    //Create using the given key files
-    CRYPTOHELPER_API IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromFiles(const char * _pubKey, const char *_privKey, const char * _passPhrase);
+//Create using the given PEM formatted keys
+jlib_decl IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(const char *pubKeyString, const char *privKeyString, const char *passPhrase);
 
-    //Create using the given PEM formatted keys
-    CRYPTOHELPER_API IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(StringBuffer & _pubKeyBuff, StringBuffer & _privKeyBuff, const char * _passPhrase);
-}
+//Create using preloaded keys.
+jlib_decl IDigitalSignatureManager * createDigitalSignatureManagerInstanceFromKeys(CLoadedKey *pubKey, CLoadedKey *privKey);
 
 } // namespace cryptohelper
 
-#endif
+#endif // DIGISIGN_HPP
 

+ 13 - 26
system/security/cryptohelper/pke.hpp

@@ -20,27 +20,14 @@
 #ifndef PKE_HPP
 #define PKE_HPP
 
-#ifndef CRYPTOHELPER_API
-
-#ifndef CRYPTOHELPER_EXPORTS
-    #define CRYPTOHELPER_API DECL_IMPORT
-#else
-    #define CRYPTOHELPER_API DECL_EXPORT
-#endif //CRYPTOHELPER_EXPORTS
-
-#endif
+#if defined(_USE_OPENSSL) && !defined(_WIN32)
 
 #include "cryptocommon.hpp"
 
 namespace cryptohelper
 {
 
-#if defined(_USE_OPENSSL) && !defined(_WIN32)
-
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-class CLoadedKey : public CSimpleInterfaceOf<IInterface>
+class jlib_decl CLoadedKey : public CSimpleInterfaceOf<IInterface>
 {
 protected:
     MemoryBuffer keyMb;
@@ -61,21 +48,21 @@ public:
     const char *queryKeyName() const  { return keyName; }
 };
 
-CRYPTOHELPER_API CLoadedKey *loadPublicKeyFromFile(const char *keyFile, const char *passPhrase);
-CRYPTOHELPER_API CLoadedKey *loadPublicKeyFromMemory(const char *key, const char *passPhrase);
-CRYPTOHELPER_API CLoadedKey *loadPrivateKeyFromFile(const char *keyFile, const char *passPhrase);
-CRYPTOHELPER_API CLoadedKey *loadPrivateKeyFromMemory(const char *key, const char *passPhrase);
-
-CRYPTOHELPER_API size32_t publicKeyEncrypt(MemoryBuffer &out, size32_t inLen, const void *inBytes, const CLoadedKey &key);
-CRYPTOHELPER_API size32_t privateKeyDecrypt(MemoryBuffer &out, size32_t inLen, const void *inBytes, const CLoadedKey &key);
-CRYPTOHELPER_API size32_t publicKeyEncrypt(void *dst, size32_t dstMaxSz, size32_t inLen, const void *inBytes, const CLoadedKey &key);
-CRYPTOHELPER_API size32_t privateKeyDecrypt(void *dst, size32_t dstMaxSz, size32_t inLen, const void *inBytes, const CLoadedKey &key);
-
+jlib_decl CLoadedKey *loadPublicKeyFromFile(const char *keyFile, const char *passPhrase);
+jlib_decl CLoadedKey *loadPublicKeyFromMemory(const char *key, const char *passPhrase);
+jlib_decl CLoadedKey *loadPrivateKeyFromFile(const char *keyFile, const char *passPhrase);
+jlib_decl CLoadedKey *loadPrivateKeyFromMemory(const char *key, const char *passPhrase);
 
-#endif // end of #if defined(_USE_OPENSSL) && !defined(_WIN32)
+jlib_decl size32_t publicKeyEncrypt(MemoryBuffer &out, size32_t inLen, const void *inBytes, const CLoadedKey &key);
+jlib_decl size32_t privateKeyDecrypt(MemoryBuffer &out, size32_t inLen, const void *inBytes, const CLoadedKey &key);
+jlib_decl size32_t publicKeyEncrypt(void *dst, size32_t dstMaxSz, size32_t inLen, const void *inBytes, const CLoadedKey &key);
+jlib_decl size32_t privateKeyDecrypt(void *dst, size32_t dstMaxSz, size32_t inLen, const void *inBytes, const CLoadedKey &key);
 
 } // end of namespace cryptohelper
 
+#else
+class CLoadedKey;
+#endif // end of #if defined(_USE_OPENSSL) && !defined(_WIN32)
 
 #endif // PKE_HPP
 

+ 5 - 14
system/security/cryptohelper/ske.hpp

@@ -20,15 +20,8 @@
 #ifndef SKE_HPP
 #define SKE_HPP
 
-#ifndef CRYPTOHELPER_API
+#include "cryptocommon.hpp"
 
-#ifndef CRYPTOHELPER_EXPORTS
-    #define CRYPTOHELPER_API DECL_IMPORT
-#else
-    #define CRYPTOHELPER_API DECL_EXPORT
-#endif //CRYPTOHELPER_EXPORTS
-
-#endif
 
 namespace cryptohelper
 {
@@ -38,16 +31,14 @@ namespace cryptohelper
 const unsigned aesMaxKeySize = 256/8; // 256 bits
 const unsigned aesBlockSize = 128/8; // 128 bits
 
-// for AES, keyLen must be 16, 24, or 32 Bytes
-
-CRYPTOHELPER_API size32_t aesEncrypt(MemoryBuffer &out, size32_t inSz, const void *inBytes, size32_t keyLen, const char *key, const char iv[aesBlockSize] = nullptr);
-CRYPTOHELPER_API size32_t aesDecrypt(MemoryBuffer &out, size32_t inSz, const void *inBytes, size32_t keyLen, const char *key, const char iv[aesBlockSize] = nullptr);
+jlib_decl size32_t aesEncrypt(MemoryBuffer &out, size32_t inSz, const void *inBytes, size32_t keyLen, const char *key, const char iv[aesBlockSize] = nullptr);
+jlib_decl size32_t aesDecrypt(MemoryBuffer &out, size32_t inSz, const void *inBytes, size32_t keyLen, const char *key, const char iv[aesBlockSize] = nullptr);
 
 class CLoadedKey;
 // aesEncryptWithRSAEncryptedKey serializes encrypted data along with an RSA encrypted key in the format { RSA-encrypted-AES-key, aes-IV, AES-encrypted-data }
-CRYPTOHELPER_API size32_t aesEncryptWithRSAEncryptedKey(MemoryBuffer &out, size32_t inSz, const void *inBytes, const CLoadedKey &publicKey);
+jlib_decl size32_t aesEncryptWithRSAEncryptedKey(MemoryBuffer &out, size32_t inSz, const void *inBytes, const CLoadedKey &publicKey);
 // aesDecryptWithRSAEncryptedKey deserializes data created by aesEncryptWithRSAEncryptedKey
-CRYPTOHELPER_API size32_t aesDecryptWithRSAEncryptedKey(MemoryBuffer &out, size32_t inSz, const void *inBytes, const CLoadedKey &privateKey);
+jlib_decl size32_t aesDecryptWithRSAEncryptedKey(MemoryBuffer &out, size32_t inSz, const void *inBytes, const CLoadedKey &privateKey);
 
 
 #endif // end of #if defined(_USE_OPENSSL) && !defined(_WIN32)

+ 0 - 43
system/security/securesocket/securesocket.cpp

@@ -862,46 +862,6 @@ const char* strtok__(const char* s, const char* d, StringBuffer& tok)
     return s;
 }
 
-static Mutex** mutexArray = NULL;
-static int numMutexes = 0;
-static CriticalSection mutexCrit;
-
-static void locking_function(int mode, int n, const char * file, int line)
-{
-    assertex(mutexArray != NULL && n < numMutexes);
-    if (mode & CRYPTO_LOCK)
-        mutexArray[n]->lock();
-    else
-        mutexArray[n]->unlock();
-}
-
-#ifndef _WIN32
-unsigned long pthreads_thread_id(void)
-{
-    return((unsigned long)pthread_self());
-}
-#endif
-
-static void initSSLLibrary()
-{
-    CriticalBlock b(mutexCrit);
-    if(mutexArray == NULL)
-    {
-        SSL_load_error_strings();
-        SSLeay_add_ssl_algorithms();
-        numMutexes= CRYPTO_num_locks();
-        mutexArray = new Mutex*[numMutexes];
-        for(int i = 0; i < numMutexes; i++)
-        {
-            mutexArray[i] = new Mutex;
-        }
-        CRYPTO_set_locking_callback(locking_function);
-#ifndef _WIN32
-        CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
-#endif
-    }
-}
-
 
 class CSecureSocketContext : implements ISecureSocketContext, public CInterface
 {
@@ -924,7 +884,6 @@ public:
     {
         m_verify = false;
         m_address_match = false;
-        initSSLLibrary();
 
         if(sockettype == ClientSocket)
             m_meth = SSLv23_client_method();
@@ -944,7 +903,6 @@ public:
     {
         m_verify = false;
         m_address_match = false;
-        initSSLLibrary();
 
         if(sockettype == ClientSocket)
             m_meth = SSLv23_client_method();
@@ -988,7 +946,6 @@ public:
         assertex(config);
         m_verify = false;
         m_address_match = false;
-        initSSLLibrary();
 
         if(sockettype == ClientSocket)
             m_meth = SSLv23_client_method();

+ 1 - 1
system/security/shared/caching.cpp

@@ -449,7 +449,7 @@ void CPermissionsCache::add(ISecUser& sec_user)
         {
             //Set user digital signature
             StringBuffer b64Signature;
-            pDSM->digiSign(sec_user.getName(), b64Signature);
+            pDSM->digiSign(b64Signature, sec_user.getName());
             sec_user.credentials().setSignature(b64Signature);//callers sec_user will now contain signature
         }
     }

+ 1 - 2
testing/unittests/CMakeLists.txt

@@ -58,8 +58,7 @@ target_link_libraries ( unittests
          dalibase
          deftype
          libbase58
-         cryptohelper
          ${CPPUNIT_LIBRARIES}
     )
 
-endif ()
+endif ()

+ 24 - 27
testing/unittests/cryptotests.cpp

@@ -108,7 +108,7 @@ protected:
             {
                 VStringBuffer text("I am here %d", idx);
                 StringBuffer sig;
-                bool ok = dsm->digiSign(text, sig);
+                bool ok = dsm->digiSign(sig, text);
                 if (!ok)
                     printf("Asynchronous asyncDigiSignUnitTest() test %d failed!\n", idx);
                 ASSERT(ok);
@@ -140,7 +140,7 @@ protected:
             }
             void Do(unsigned idx)
             {
-                bool ok = dsm->digiVerify(text, sig);
+                bool ok = dsm->digiVerify(sig, text);
                 if (!ok)
                     printf("Asynchronous asyncDigiVerifyUnitTest() test %d failed!\n", idx);
                 ASSERT(ok);
@@ -172,7 +172,7 @@ protected:
                     printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
                 ASSERT(ok);
 
-                ok = dsm->digiVerify(text, sig);
+                ok = dsm->digiVerify(sig, text);
                 if (!ok)
                     printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
                 ASSERT(ok);
@@ -201,66 +201,63 @@ protected:
             printf("\nExecuting digiSign() unit tests\n");
 
             //Create instance of digital signature manager
-            StringBuffer _pubKeyBuff(pubKey);
-            StringBuffer _privKeyBuff(privKey);
-            Owned<IDigitalSignatureManager> dsm(createDigitalSignatureManagerInstanceFromKeys(_pubKeyBuff, _privKeyBuff, nullptr));
-
+            Owned<IDigitalSignatureManager> dsm(createDigitalSignatureManagerInstanceFromKeys(pubKey, privKey, nullptr));
 
             printf("digiSign() test 1\n");
             StringBuffer txt(text1);
-            bool ok = dsm->digiSign(text1, sig1.clear());
+            bool ok = dsm->digiSign(sig1.clear(), text1);
             ASSERT(ok);
             ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
             ASSERT(!sig1.isEmpty());//signature should be populated
 
             StringBuffer sig(sig1);
-            ok = dsm->digiVerify(text1, sig1);
+            ok = dsm->digiVerify(sig1, text1);
             ASSERT(ok);
             ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
             ASSERT(0 == strcmp(sig.str(), sig1.str()));//signature should be unchanged
 
             printf("digiSign() test 2\n");
-            ok = dsm->digiVerify(text1, sig1);
+            ok = dsm->digiVerify(sig1, text1);
             ASSERT(ok);
-            ok = dsm->digiVerify(text1, sig1);
+            ok = dsm->digiVerify(sig1, text1);
             ASSERT(ok);
 
             printf("digiSign() test 3\n");
-            ok = dsm->digiSign(text2, sig2.clear());
+            ok = dsm->digiSign(sig2.clear(), text2);
             ASSERT(ok);
-            ok = dsm->digiVerify(text2, sig2);
+            ok = dsm->digiVerify(sig2, text2);
             ASSERT(ok);
-            ok = dsm->digiSign(text2, sig2.clear());
+            ok = dsm->digiSign(sig2.clear(), text2);
             ASSERT(ok);
-            ok = dsm->digiVerify(text2, sig2);
+            ok = dsm->digiVerify(sig2, text2);
             ASSERT(ok);
 
             printf("digiSign() test 4\n");
-            ok = dsm->digiVerify(text1, sig1);
+            ok = dsm->digiVerify(sig1, text1);
             ASSERT(ok);
 
             printf("digiSign() test 5\n");
-            ok = dsm->digiVerify(text2, sig2);
+            ok = dsm->digiVerify(sig2, text2);
             ASSERT(ok);
 
             printf("digiSign() test 6\n");
-            ok = dsm->digiVerify(text1, sig2);
+            ok = dsm->digiVerify(sig2, text1);
             ASSERT(!ok);//should fail
 
             printf("digiSign() test 7\n");
-            ok = dsm->digiVerify(text2, sig1);
+            ok = dsm->digiVerify(sig1, text2);
             ASSERT(!ok);//should fail
 
             printf("digiSign() test 8\n");
-            ok = dsm->digiSign(text3, sig3.clear());
+            ok = dsm->digiSign(sig3.clear(), text3);
             ASSERT(ok);
 
             printf("digiSign() test 9\n");
-            ok = dsm->digiVerify(text3, sig1);
+            ok = dsm->digiVerify(sig1, text3);
             ASSERT(!ok);//should fail
-            ok = dsm->digiVerify(text3, sig2);
+            ok = dsm->digiVerify(sig2, text3);
             ASSERT(!ok);//should fail
-            ok = dsm->digiVerify(text3, sig3);
+            ok = dsm->digiVerify(sig3, text3);
             ASSERT(ok);
 
             //Perform
@@ -268,7 +265,7 @@ protected:
             unsigned now = msTick();
             for (int x=0; x<1000; x++)
             {
-                dsm->digiSign(text3, sig3.clear());
+                dsm->digiSign(sig3.clear(), text3);
             }
             printf("digiSign() 1000 iterations took %d MS\n", msTick() - now);
 
@@ -276,7 +273,7 @@ protected:
             now = msTick();
             for (int x=0; x<1000; x++)
             {
-                dsm->digiVerify(text3, sig3);
+                dsm->digiVerify(sig3, text3);
             }
             printf("digiverify 1000 iterations took %d MS\n", msTick() - now);
 
@@ -569,12 +566,12 @@ public:
 
         encryptedMessageMb.clear();
         timer.reset();
-        ::aesEncrypt(aesKey, aesMaxKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
+        jlib::aesEncrypt(aesKey, aesMaxKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
         printf("JLIB    AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
 
         decryptedMessageMb.clear();
         timer.reset();
-        ::aesDecrypt(aesKey, aesMaxKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
+        jlib::aesDecrypt(aesKey, aesMaxKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
         printf("JLIB    AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
 
         ASSERT(messageMb.length() == decryptedMessageMb.length());