elseif("${SSL}" STREQUAL "gnutls")
find_package(GnuTLS REQUIRED)
if(GNUTLS_FOUND)
+ set(USE_GNUTLS ON)
set(SSLIMP_LIBRARIES ${GNUTLS_LIBRARIES})
set(SSLIMP_INCLUDE_DIR ${GNUTLS_INCLUDE_DIR})
set(SSLIMP_LIBRARY_DIR ${GNUTLS_LIB_DIR})
endif(GNUTLS_FOUND)
+ find_package(Nettle REQUIRED)
+ if(NETTLE_FOUND)
+ set(CRYPTO_LIBRARIES "${NETTLE_LIBRARIES}")
+ endif(NETTLE_FOUND)
endif("${SSL}" STREQUAL "openssl")
check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME_RT)
if(NOT HAVE_CLOCK_GETTIME)
check_library_exists(c clock_get_time "mach/time.h" HAVE_CLOCK_GET_TIME)
if(NOT HAVE_CLOCK_GET_TIME)
- message(FATAL_ERROR "Didn't find clock_gettime() or clock_get_time!")
+ message(FATAL_ERROR "Didn't find clock_gettime() or clock_get_time()!")
endif()
endif()
else()
endif(NOT OLD_CONFIG_FILE)
add_definitions(${SSLIMP_CFLAGS})
-target_link_libraries(umurmurd ${LIBCONFIG_LIBRARIES} ${PROTOBUFC_LIBRARIES} ${SSLIMP_LIBRARIES} ${LIBRT})
+
+target_link_libraries(umurmurd ${LIBCONFIG_LIBRARIES} ${PROTOBUFC_LIBRARIES} ${SSLIMP_LIBRARIES} ${LIBRT} ${CRYPTO_LIBRARIES})
--- /dev/null
+# https://github.com/Kitware/CMake/blob/master/Utilities/cmlibarchive/build/cmake/FindNettle.cmake
+#
+# - Find Nettle
+# Find the Nettle include directory and library
+#
+# NETTLE_INCLUDE_DIR - where to find <nettle/sha.h>, etc.
+# NETTLE_LIBRARIES - List of libraries when using libnettle.
+# NETTLE_FOUND - True if libnettle found.
+
+IF (NETTLE_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(NETTLE_FIND_QUIETLY TRUE)
+ENDIF (NETTLE_INCLUDE_DIR)
+
+FIND_PATH(NETTLE_INCLUDE_DIR nettle/md5.h nettle/ripemd160.h nettle/sha.h)
+FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle libnettle)
+
+# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR)
+
+IF(NETTLE_FOUND)
+ SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
+ENDIF(NETTLE_FOUND)
client->tokencount++;
}
-bool_t Client_token_match(client_t *client, char *str)
+bool_t Client_token_match(client_t *client, char const *str)
{
token_t *token;
struct dlist *itr;
void Client_codec_free(client_t *client);
codec_t *Client_codec_iterate(client_t *client, codec_t **codec_itr);
void Client_textmessage(client_t *client, char *text);
+bool_t Client_token_match(client_t *client, char const *str);
+void Client_token_free(client_t *client);
+void Client_token_add(client_t *client, char *token_string);
#endif
#ifndef CONFIG_H
#define CONFIG_H
+#cmakedefine USE_GNUTLS
#cmakedefine USE_POLARSSL
#cmakedefine USE_POLARSSL_TESTCERT
#cmakedefine USE_POLARSSL_HAVEGE
return cs->bInit;
}
-void CryptState_genKey(cryptState_t *cs) {
- RAND_bytes(cs->raw_key, AES_BLOCK_SIZE);
- RAND_bytes(cs->encrypt_iv, AES_BLOCK_SIZE);
- RAND_bytes(cs->decrypt_iv, AES_BLOCK_SIZE);
-#ifndef USE_POLARSSL
- AES_set_encrypt_key(cs->raw_key, 128, &cs->encrypt_key);
- AES_set_decrypt_key(cs->raw_key, 128, &cs->decrypt_key);
-#else
- aes_setkey_enc(&cs->aes_enc, cs->raw_key, 128);
- aes_setkey_dec(&cs->aes_dec, cs->raw_key, 128);
-#endif
+void CryptState_genKey(cryptState_t *cs)
+{
+ CRYPT_RANDOM_BYTES(&cs->raw_key, AES_BLOCK_SIZE);
+ CRYPT_RANDOM_BYTES(&cs->encrypt_iv, AES_BLOCK_SIZE);
+ CRYPT_RANDOM_BYTES(&cs->decrypt_iv, AES_BLOCK_SIZE);
+
+ CRYPT_SET_ENC_KEY(&cs->encrypt_key, cs->raw_key, 128);
+ CRYPT_SET_DEC_KEY(&cs->decrypt_key, cs->raw_key, 128);
+
cs->bInit = true;
}
memcpy(cs->raw_key, rkey, AES_BLOCK_SIZE);
memcpy(cs->encrypt_iv, eiv, AES_BLOCK_SIZE);
memcpy(cs->decrypt_iv, div, AES_BLOCK_SIZE);
-#ifndef USE_POLARSSL
- AES_set_encrypt_key(cs->decrypt_iv, 128, &cs->encrypt_key);
- AES_set_decrypt_key(cs->raw_key, 128, &cs->decrypt_key);
-#else
- aes_setkey_enc(&cs->aes_enc, cs->decrypt_iv, 128);
- aes_setkey_dec(&cs->aes_dec, cs->raw_key, 128);
-#endif
+
+ CRYPT_SET_ENC_KEY(&cs->encrypt_key, cs->decrypt_iv, 128);
+ CRYPT_SET_DEC_KEY(&cs->decrypt_key, cs->raw_key, 128);
+
cs->bInit = true;
}
block[i]=0;
}
-#ifdef USE_POLARSSL
-#define AESencrypt(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->aes_enc, AES_ENCRYPT, (unsigned char *)(src), (unsigned char *)(dst));
-#define AESdecrypt(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->aes_dec, AES_DECRYPT, (unsigned char *)(src), (unsigned char *)(dst));
-#else
-#define AESencrypt(src, dst, cryptstate) AES_encrypt((unsigned char *)(src), (unsigned char *)(dst), &(cryptstate)->encrypt_key);
-#define AESdecrypt(src, dst, cryptstate) AES_decrypt((unsigned char *)(src), (unsigned char *)(dst), &(cryptstate)->decrypt_key);
-#endif
-
void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
// Initialize
- AESencrypt(nonce, delta, cs);
+ CRYPT_AES_ENCRYPT(nonce, delta, cs);
ZERO(checksum);
while (len > AES_BLOCK_SIZE) {
S2(delta);
XOR(tmp, delta, (const subblock *)(plain));
- AESencrypt(tmp, tmp, cs);
+ CRYPT_AES_ENCRYPT(tmp, tmp, cs);
XOR((subblock *)(encrypted), delta, tmp);
XOR(checksum, checksum, (subblock *)(plain));
len -= AES_BLOCK_SIZE;
ZERO(tmp);
tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
XOR(tmp, tmp, delta);
- AESencrypt(tmp, pad, cs);
+ CRYPT_AES_ENCRYPT(tmp, pad, cs);
memcpy(tmp, plain, len);
memcpy((unsigned char *)tmp + len, (unsigned char *)pad + len, AES_BLOCK_SIZE - len);
XOR(checksum, checksum, tmp);
S3(delta);
XOR(tmp, delta, checksum);
- AESencrypt(tmp, tag, cs);
+ CRYPT_AES_ENCRYPT(tmp, tag, cs);
}
void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
// Initialize
- AESencrypt(nonce, delta, cs);
+ CRYPT_AES_ENCRYPT(nonce, delta, cs);
ZERO(checksum);
while (len > AES_BLOCK_SIZE) {
S2(delta);
XOR(tmp, delta, (const subblock *)(encrypted));
- AESdecrypt(tmp, tmp, cs);
+ CRYPT_AES_DECRYPT(tmp, tmp, cs);
XOR((subblock *)(plain), delta, tmp);
XOR(checksum, checksum, (const subblock *)(plain));
len -= AES_BLOCK_SIZE;
ZERO(tmp);
tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
XOR(tmp, tmp, delta);
- AESencrypt(tmp, pad, cs);
+ CRYPT_AES_ENCRYPT(tmp, pad, cs);
memset(tmp, 0, AES_BLOCK_SIZE);
memcpy(tmp, encrypted, len);
XOR(tmp, tmp, pad);
S3(delta);
XOR(tmp, delta, checksum);
- AESencrypt(tmp, tag, cs);
+ CRYPT_AES_ENCRYPT(tmp, tag, cs);
}
#include "byteorder.h"
#include "config.h"
-#ifdef USE_POLARSSL
+#if defined(USE_POLARSSL)
+
#include <polarssl/havege.h>
#include <polarssl/aes.h>
+
+#define CRYPT_AES_KEY aes_context
#define AES_BLOCK_SIZE 16
+
+#define CRYPT_RANDOM_BYTES(dest, size) RAND_bytes((dest), (size))
+#define CRYPT_SET_ENC_KEY(dest, source, size) aes_setkey_enc((dest), (source), (size));
+#define CRYPT_SET_DEC_KEY(dest, source, size) aes_setkey_dec((dest), (source), (size));
+
+#define CRYPT_AES_ENCRYPT(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->encrypt_key, AES_ENCRYPT, (unsigned char *)(src), (unsigned char *)(dst));
+#define CRYPT_AES_DECRYPT(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->decrypt_key, AES_DECRYPT, (unsigned char *)(src), (unsigned char *)(dst));
+
+#elif defined(USE_GNUTLS)
+
+#include <nettle/aes.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+#define CRYPT_AES_KEY struct aes_ctx
+#define CRYPT_RANDOM_BYTES(dest, size) gnutls_rnd(GNUTLS_RND_KEY, (dest), (size))
+#define CRYPT_SET_ENC_KEY(dest, source, size) aes_set_encrypt_key((dest), (size)/8, (source));
+#define CRYPT_SET_DEC_KEY(dest, source, size) aes_set_decrypt_key((dest), (size)/8, (source));
+
+#define CRYPT_AES_ENCRYPT(src, dest, ctx) aes_encrypt(&(ctx)->encrypt_key, AES_BLOCK_SIZE, (uint8_t *)(dest), (uint8_t *)(src))
+#define CRYPT_AES_DECRYPT(src, dest, ctx) aes_decrypt(&(ctx)->decrypt_key, AES_BLOCK_SIZE, (uint8_t *)(dest), (uint8_t *)(src))
+
#else
+
#include <openssl/rand.h>
#include <openssl/aes.h>
+
+#define CRYPT_AES_KEY AES_KEY
+#define CRYPT_RANDOM_BYTES(dest, size) RAND_bytes((dest), (size))
+#define CRYPT_SET_ENC_KEY(dest, source, size) AES_set_encrypt_key((source), (size), (dest));
+#define CRYPT_SET_DEC_KEY(dest, source, size) AES_set_decrypt_key((source), (size), (dest));
+
+#define CRYPT_AES_ENCRYPT(src, dst, cryptstate) AES_encrypt((unsigned char *)(src), (unsigned char *)(dst), &(cryptstate)->encrypt_key);
+#define CRYPT_AES_DECRYPT(src, dst, cryptstate) AES_decrypt((unsigned char *)(src), (unsigned char *)(dst), &(cryptstate)->decrypt_key);
+
#endif
#include <stdint.h>
unsigned int uiRemoteLate;
unsigned int uiRemoteLost;
unsigned int uiRemoteResync;
-#ifndef USE_POLARSSL
- AES_KEY encrypt_key;
- AES_KEY decrypt_key;
-#else
- aes_context aes_enc;
- aes_context aes_dec;
-#endif
+
+ CRYPT_AES_KEY encrypt_key;
+ CRYPT_AES_KEY decrypt_key;
+
etimer_t tLastGood;
etimer_t tLastRequest;
bool_t bInit;
#include "version.h"
#include "config.h"
#include "sharedmemory.h"
+#include "ban.h"
char system_string[64], version_string[64];
int bindport;
Chan_init();
Client_init();
Ban_init();
-
-#ifdef USE_SHAREDMEMORY_API
+
+#ifdef USE_SHAREDMEMORY_API
Sharedmemory_init( bindport, bindport6 );
#endif
-
+
#ifdef POSIX_PRIORITY_SCHEDULING
if (realtime)
setscheduler();
/* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
- Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
+ Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
#define SSL_H_987698
#include "config.h"
+#include "types.h"
-#ifdef USE_POLARSSL
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(USE_POLARSSL)
#include <polarssl/ssl.h>
#include <polarssl/version.h>
-#ifdef POLARSSL_VERSION_MAJOR
+#if defined(POLARSSL_VERSION_MAJOR)
#if (POLARSSL_VERSION_MAJOR < 1)
#error PolarSSL version 1.0.0 or greater is required!
#endif
#error PolarSSL version 1.0.0 or greater is required!
#endif
-#ifdef USE_POLARSSL_HAVEGE
+#if defined(USE_POLARSSL_HAVEGE)
#include <polarssl/havege.h>
#if (POLARSSL_VERSION_MINOR >= 1)
#define HAVEGE_RAND (havege_random)
#define POLARSSL_API_V1_3_ABOVE
#endif
-#else /* OpenSSL */
-#include <openssl/x509v3.h>
-#include <openssl/ssl.h>
-#endif
-
-#include "types.h"
-#include <inttypes.h>
-
-#ifdef USE_POLARSSL
#define SSLI_ERROR_WANT_READ -0x0F300 /* PolarSSL v0.x.x uses -0x0f00 -> --0x0f90, v1.x.x uses -0x7080 -> -0x7e80 */
#define SSLI_ERROR_WANT_WRITE -0x0F310
typedef ssl_context SSL_handle_t;
-#else
+#elif defined(USE_GNUTLS)
+
+#include <gnutls/gnutls.h>
+
+#define SSLI_ERROR_WANT_READ GNUTLS_E_AGAIN
+#define SSLI_ERROR_WANT_WRITE GNUTLS_E_AGAIN
+#define SSLI_ERROR_ZERO_RETURN GNUTLS_E_PREMATURE_TERMINATION
+#define SSLI_ERROR_CONNRESET GNUTLS_E_PREMATURE_TERMINATION
+#define SSLI_ERROR_SYSCALL GNUTLS_E_PREMATURE_TERMINATION
+
+typedef gnutls_session_t SSL_handle_t;
+
+#else /* OpenSSL */
+#include <openssl/x509v3.h>
+#include <openssl/ssl.h>
#define SSLI_ERROR_WANT_READ SSL_ERROR_WANT_READ
#define SSLI_ERROR_WANT_WRITE SSL_ERROR_WANT_WRITE
for (i = 0; i < 20; i++)
offset += sprintf(out + offset, "%02x", hash[i]);
}
+
static inline void SSLi_hex2hash(char *in, uint8_t *hash)
{
int i;
}
}
#endif
+
+/* Copyright (C) 2015, Felix Morgner <felix.morgner@gmail.com>
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ - Neither the name of the Developers nor the names of its contributors may
+ be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "ssl.h"
+#include "conf.h"
+#include "log.h"
+
+#include <stdlib.h>
+
+static gnutls_dh_params_t dhParameters;
+static gnutls_certificate_credentials_t certificate;
+
+static const char * ciphers = "NORMAL";
+static gnutls_priority_t cipherCache;
+
+void initializeCertificate()
+{
+ char* certificatePath = (char*) getStrConf(CERTIFICATE);
+
+ if(!certificatePath) {
+ Log_fatal("No certificate file specified.");
+ }
+
+ char* keyPath = (char*) getStrConf(KEY);
+
+ if(!keyPath) {
+ Log_fatal("No key file specified");
+ }
+
+ gnutls_certificate_allocate_credentials(&certificate);
+
+ int error = gnutls_certificate_set_x509_key_file(certificate, certificatePath, keyPath, GNUTLS_X509_FMT_PEM);
+
+ if( error != GNUTLS_E_SUCCESS ) {
+ Log_fatal("Could not open key (%s) or certificate (%s).", keyPath, certificatePath);
+ }
+
+}
+
+void SSLi_init()
+{
+ unsigned const bitCount = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM);
+
+ gnutls_dh_params_init(&dhParameters);
+ gnutls_dh_params_generate2(dhParameters, bitCount);
+
+#if GNUTLS_VERSION_NUMBER < 0x030300
+ gnutls_global_init();
+#endif
+
+ gnutls_priority_init(&cipherCache, ciphers, NULL);
+
+ initializeCertificate();
+
+ Log_info("Sucessfully initialized GNUTLS version %s", gnutls_check_version(NULL));
+
+}
+
+void SSLi_deinit()
+{
+ gnutls_certificate_free_credentials(certificate);
+ gnutls_priority_deinit(cipherCache);
+ gnutls_global_deinit();
+}
+
+SSL_handle_t * SSLi_newconnection( int * fileDescriptor, bool_t * isSSLReady )
+{
+ gnutls_session_t * session = calloc(1, sizeof(gnutls_session_t));
+
+ gnutls_init(session, GNUTLS_SERVER);
+ gnutls_priority_set(*session, cipherCache);
+ gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, certificate);
+
+ gnutls_certificate_server_set_request(*session, GNUTLS_CERT_REQUIRE);
+
+ gnutls_transport_set_int(*session, *fileDescriptor);
+
+ if(isSSLReady && SSLi_nonblockaccept(session, isSSLReady))
+ *isSSLReady = true;
+
+ return session;
+}
+
+bool_t SSLi_getSHA1Hash(SSL_handle_t *session, uint8_t *hash)
+{
+ gnutls_datum_t const * certificateData = gnutls_certificate_get_peers(*session, NULL);
+
+ size_t resultSize = 0;
+ int error = gnutls_fingerprint( GNUTLS_DIG_SHA1, certificateData, hash, &resultSize);
+ return error == GNUTLS_E_SUCCESS && resultSize == 20;
+}
+
+int SSLi_nonblockaccept( SSL_handle_t *session, bool_t * isSSLReady )
+{
+ int error;
+ do {
+ error = gnutls_handshake(*session);
+ } while(error < GNUTLS_E_SUCCESS && !gnutls_error_is_fatal(error));
+
+ if ( error < GNUTLS_E_SUCCESS ) {
+ Log_warn("TLS handshake failed with error %i (%s).", error, gnutls_strerror(error));
+ }
+
+ if(isSSLReady)
+ *isSSLReady = true;
+
+ return error;
+}
+
+int SSLi_read(SSL_handle_t *session, uint8_t *buffer, int length)
+{
+ return gnutls_record_recv(*session, buffer, length);
+}
+
+int SSLi_write(SSL_handle_t *session, uint8_t *buffer, int length)
+{
+ return gnutls_record_send(*session, buffer, length);
+}
+
+int SSLi_get_error(SSL_handle_t *session, int code)
+{
+ return code;
+}
+
+bool_t SSLi_data_pending(SSL_handle_t *session)
+{
+ return gnutls_record_check_pending(*session);
+}
+
+void SSLi_shutdown(SSL_handle_t *session)
+{
+ gnutls_bye(*session, GNUTLS_SHUT_WR);
+}
+
+void SSLi_free(SSL_handle_t *session)
+{
+ gnutls_deinit(*session);
+ free(session);
+}
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
#include "conf.h"
#include "log.h"
#include "ssl.h"
-/*
- * PolarSSL interface
- */
+#include <stdlib.h>
+#include <fcntl.h>
#include <polarssl/config.h>
#include <polarssl/havege.h>