diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..ac663e9f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+Makefile
+Makefile.in
+*.o
+*.a
+/config.*
+/src/tincd
+/autom4te.cache
+/aclocal.m4
+/compile
+/configure
+/depcomp
+/install-sh
+/missing
+INSTALL
+.deps
+stamp-h1
+/src/device.c
diff --git a/README.android b/README.android
new file mode 100644
index 00000000..6fffe418
--- /dev/null
+++ b/README.android
@@ -0,0 +1,20 @@
+Quick how-o cross compile tinc for android (done from $HOME/android/):
+
+- Download android NDK and setup local ARM toolchain:
+wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2
+tar xfj android-ndk-r8b-linux-x86.tar.bz2
+./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain
+
+- Download and cross-compile openSSL for ARM:
+wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
+tar xfz openssl-1.0.1c.tar.gz
+cd openssl-1.0.1c
+./Configure dist
+make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib
+
+- Clone and cross-compile tinc:
+git clone git://tinc-vpn.org/tinc
+cd tinc
+autoreconf -fsi
+CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/
+make -j5
diff --git a/THANKS b/THANKS
index f7e45bb9..7d91271d 100644
--- a/THANKS
+++ b/THANKS
@@ -28,6 +28,7 @@ We would like to thank the following people for their contributions to tinc:
 * Mark Glines
 * Markus Goetz
 * Martin Kihlgren
+* Martin Schürrer
 * Matias Carrasco
 * Max Rijevski
 * Menno Smits
@@ -45,6 +46,7 @@ We would like to thank the following people for their contributions to tinc:
 * Teemu Kiviniemi
 * Timothy Redaelli
 * Tonnerre Lombard
+* Vil Brekin
 * Wessel Dankers
 * Wouter van Heyst
 
diff --git a/src/net_setup.c b/src/net_setup.c
index ba2ad5fc..c033e220 100644
--- a/src/net_setup.c
+++ b/src/net_setup.c
@@ -229,7 +229,7 @@ static bool read_rsa_private_key(void) {
 		result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d);
 		free(n);
 		free(d);
-		return true;
+		return result;
 	}
 
 	/* Else, check for PrivateKeyFile statement and read it */
diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c
index 9c880e69..efd63d53 100644
--- a/src/openssl/rsa.c
+++ b/src/openssl/rsa.c
@@ -29,16 +29,21 @@
 
 bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) {
 	*rsa = RSA_new();
-	BN_hex2bn(&(*rsa)->n, n);
-	BN_hex2bn(&(*rsa)->e, e);
+	if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
+		return false;
+	if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
+		return false;
 	return true;
 }
 
 bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) {
 	*rsa = RSA_new();
-	BN_hex2bn(&(*rsa)->n, n);
-	BN_hex2bn(&(*rsa)->e, e);
-	BN_hex2bn(&(*rsa)->d, d);
+	if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
+		return false;
+	if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
+		return false;
+	if(BN_hex2bn(&(*rsa)->d, d) != strlen(d))
+		return false;
 	return true;
 }
 
diff --git a/src/process.c b/src/process.c
index 0e33f264..362b678c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -229,6 +229,7 @@ bool execute_script(const char *name, char **envp) {
 	int status, len;
 	char *scriptname;
 	int i;
+	char *interpreter = NULL;
 
 #ifndef HAVE_MINGW
 	len = xasprintf(&scriptname, "\"%s" SLASH "%s\"", confbase, name);
@@ -249,8 +250,19 @@ bool execute_script(const char *name, char **envp) {
 	}
 #endif
 
+	// Custom scripts interpreter
+	if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &interpreter)) {
+		// Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard)
+		free(scriptname);
+		len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name);
+		free(interpreter);
+		if(len < 0)
+			return false;
+	}
+
 	logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name);
 
+
 #ifdef HAVE_PUTENV
 	/* Set environment */
 	
diff --git a/src/protocol_key.c b/src/protocol_key.c
index fbd3c16f..802f7ca6 100644
--- a/src/protocol_key.c
+++ b/src/protocol_key.c
@@ -334,6 +334,9 @@ bool ans_key_h(connection_t *c, const char *request) {
 		return send_request(to->nexthop->connection, "%s", request);
 	}
 
+	/* Don't use key material until every check has passed. */
+	from->status.validkey = false;
+
 	if(compression < 0 || compression > 11) {
 		logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
 		return true;
diff --git a/src/tincd.c b/src/tincd.c
index 0fd2f8d7..fc92f0b1 100644
--- a/src/tincd.c
+++ b/src/tincd.c
@@ -329,8 +329,11 @@ static bool drop_privs(void) {
 			       "initgroups", strerror(errno));
 			return false;
 		}
+#ifndef __ANDROID__
+// Not supported in android NDK
 		endgrent();
 		endpwent();
+#endif
 	}
 	if (do_chroot) {
 		tzset();	/* for proper timestamps in logs */
diff --git a/src/utils.c b/src/utils.c
index e750450e..129622b2 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -48,7 +48,7 @@ static int charb64decode(char c) {
 
 int hex2bin(const char *src, char *dst, int length) {
 	int i;
-	for(i = 0; i < length && src[i * 2] && src[i * 2 + 1]; i++)
+	for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++)
 		dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
 	return i;
 }