From 9359ec3b6f687745e2e2995ba30b442396c7d4cf Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Sun, 30 Aug 2015 11:33:42 +0200 Subject: steam_rsa: add libgcrypt as crypto backend --- steam-mobile/Makefile | 21 +++++- steam-mobile/steam_rsa.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 178 insertions(+), 5 deletions(-) diff --git a/steam-mobile/Makefile b/steam-mobile/Makefile index 5c4ed38..fee9927 100644 --- a/steam-mobile/Makefile +++ b/steam-mobile/Makefile @@ -2,8 +2,23 @@ COMPILER = gcc PKG_CONFIG ?= pkg-config -LIBPURPLE_CFLAGS += $(shell ${PKG_CONFIG} --cflags glib-2.0 json-glib-1.0 purple nss gnome-keyring-1) -LIBPURPLE_LIBS += $(shell ${PKG_CONFIG} --libs glib-2.0 json-glib-1.0 purple nss) +# Global libraries +LIBPURPLE_CFLAGS += $(shell ${PKG_CONFIG} --cflags glib-2.0 json-glib-1.0 purple gnome-keyring-1) +LIBPURPLE_LIBS += $(shell ${PKG_CONFIG} --libs glib-2.0 json-glib-1.0 purple) + +CFLAGS = ${LIBPURPLE_CFLAGS} +LIBS = ${LIBPURPLE_LIBS} + +# Crypt backend to use +CRYPT_BACKEND = nss + +ifeq (${CRYPT_BACKEND}, nss) + CFLAGS += $(shell ${PKG_CONFIG} --cflags nss) + LIBS += $(shell ${PKG_CONFIG} --libs nss) +else ifeq (${CRYPT_BACKEND}, gcrypt) + CFLAGS += $(shell libgcrypt-config --cflags) -DUSE_GCRYPT_CRYPTO + LIBS += $(shell libgcrypt-config --libs) +endif STEAM_SOURCES = \ steam_connection.c \ @@ -15,4 +30,4 @@ clean: rm -f libsteam.so libsteam.so: ${STEAM_SOURCES} - ${COMPILER} -Wall -I. -g -O2 -fPIC -pipe ${STEAM_SOURCES} -o $@ ${LIBPURPLE_CFLAGS} ${LIBPURPLE_LIBS} -shared + ${COMPILER} -Wall -I. -g -O2 -fPIC -pipe ${STEAM_SOURCES} -o $@ ${CFLAGS} ${LIBS} -shared diff --git a/steam-mobile/steam_rsa.c b/steam-mobile/steam_rsa.c index 4aa5e5d..45986f1 100644 --- a/steam-mobile/steam_rsa.c +++ b/steam-mobile/steam_rsa.c @@ -13,7 +13,7 @@ password=&username=&emailauth=&captchagid= #undef USE_OPENSSL_CRYPTO #endif -#if !defined USE_POLARSSL_CRYPTO && !defined USE_OPENSSL_CRYPTO && !defined USE_NSS_CRYPTO +#if !defined USE_POLARSSL_CRYPTO && !defined USE_OPENSSL_CRYPTO && !defined USE_NSS_CRYPTO && !defined USE_GCRYPT_CRYPTO #define USE_NSS_CRYPTO #endif @@ -138,6 +138,164 @@ steam_encrypt_password(const gchar *modulus_str, const gchar *exponent_str, cons return output; } +#elif defined USE_GCRYPT_CRYPTO + +#include +#include + +// The following functions steam_util_str_hex2bytes, steam_crypt_rsa_enc and steam_encrypt_password +// (originally steam_crypt_rsa_enc_str) have been taken directly from steam-util.c and steam-crypt.c +// from the bitlbee-steam source code. The original files are released under the GNU General Public +// License version 2 and can be found at https://github.com/jgeboski/bitlbee-steam. +// All credit goes to the original author of bitlbee-steam, James Geboski . + +GByteArray * +steam_util_str_hex2bytes(const gchar *str) +{ + GByteArray *ret; + gboolean hax; + gsize size; + gchar val; + guint i; + guint d; + + g_return_val_if_fail(str != NULL, NULL); + + size = strlen(str); + hax = (size % 2) != 0; + + ret = g_byte_array_new(); + g_byte_array_set_size(ret, (size + 1) / 2); + memset(ret->data, 0, ret->len); + + for (d = i = 0; i < size; i++, hax = !hax) { + val = g_ascii_xdigit_value(str[i]); + + if (val < 0) { + g_byte_array_free(ret, TRUE); + return NULL; + } + + if (hax) + ret->data[d++] |= val & 0x0F; + else + ret->data[d] |= (val << 4) & 0xF0; + } + + return ret; +} + +GByteArray * +steam_crypt_rsa_enc(const GByteArray *mod, const GByteArray *exp, const GByteArray *bytes) +{ + GByteArray *ret; + gcry_mpi_t mmpi; + gcry_mpi_t empi; + gcry_mpi_t dmpi; + gcry_sexp_t kata; + gcry_sexp_t data; + gcry_sexp_t cata; + gcry_error_t res; + gsize size; + + g_return_val_if_fail(mod != NULL, NULL); + g_return_val_if_fail(exp != NULL, NULL); + g_return_val_if_fail(bytes != NULL, NULL); + + mmpi = empi = dmpi = NULL; + kata = data = cata = NULL; + ret = NULL; + + res = gcry_mpi_scan(&mmpi, GCRYMPI_FMT_USG, mod->data, mod->len, NULL); + res |= gcry_mpi_scan(&empi, GCRYMPI_FMT_USG, exp->data, exp->len, NULL); + res |= gcry_mpi_scan(&dmpi, GCRYMPI_FMT_USG, bytes->data, bytes->len, NULL); + + if (G_UNLIKELY(res == 0)) { + res = gcry_sexp_build(&kata, NULL, "(public-key(rsa(n %m)(e %m)))", mmpi, empi); + res |= gcry_sexp_build(&data, NULL, "(data(flags pkcs1)(value %m))", dmpi); + + if (G_UNLIKELY(res == 0)) { + res = gcry_pk_encrypt(&cata, data, kata); + + if (G_UNLIKELY(res == 0)) { + gcry_sexp_release(data); + data = gcry_sexp_find_token(cata, "a", 0); + + if (G_UNLIKELY(data != NULL)) { + gcry_mpi_release(dmpi); + dmpi = gcry_sexp_nth_mpi(data, 1, GCRYMPI_FMT_USG); + + if (G_UNLIKELY(dmpi != NULL)) { + ret = g_byte_array_new(); + g_byte_array_set_size(ret, mod->len); + + gcry_mpi_print(GCRYMPI_FMT_USG, ret->data, ret->len, &size, dmpi); + + g_warn_if_fail(size <= mod->len); + g_byte_array_set_size(ret, size); + } else { + g_warn_if_reached(); + } + } else { + g_warn_if_reached(); + } + } + } + } + + gcry_sexp_release(cata); + gcry_sexp_release(data); + gcry_sexp_release(kata); + + gcry_mpi_release(dmpi); + gcry_mpi_release(empi); + gcry_mpi_release(mmpi); + + return ret; +} + +gchar * +steam_encrypt_password(const gchar *mod, const gchar *exp, const gchar *str) +{ + GByteArray *bytes; + GByteArray *mytes; + GByteArray *eytes; + GByteArray *enc; + gchar *ret; + + g_return_val_if_fail(mod != NULL, NULL); + g_return_val_if_fail(exp != NULL, NULL); + g_return_val_if_fail(str != NULL, NULL); + + mytes = steam_util_str_hex2bytes(mod); + + if (G_UNLIKELY(mytes == NULL)) + return NULL; + + eytes = steam_util_str_hex2bytes(exp); + + if (G_UNLIKELY(eytes == NULL)) { + g_byte_array_free(mytes, TRUE); + return NULL; + } + + bytes = g_byte_array_new(); + g_byte_array_append(bytes, (guint8*) str, strlen(str)); + enc = steam_crypt_rsa_enc(mytes, eytes, bytes); + + g_byte_array_free(bytes, TRUE); + g_byte_array_free(eytes, TRUE); + g_byte_array_free(mytes, TRUE); + + if (G_UNLIKELY(enc == NULL)) + return NULL; + + ret = g_base64_encode(enc->data, enc->len); + g_byte_array_free(enc, TRUE); + + return ret; +} + #elif defined USE_POLARSSL_CRYPTO #include "polarssl/config.h" @@ -280,4 +438,4 @@ steam_encrypt_password_openssl(const gchar *modulus_str, const gchar *exponent_s return output; } -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 9abb26301c2b4700b75efb8186e375cd66a9c634 Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Sun, 30 Aug 2015 11:56:02 +0200 Subject: steam_rsa: G_UNLIKELY -> G_LIKELY. --- steam-mobile/steam_rsa.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/steam-mobile/steam_rsa.c b/steam-mobile/steam_rsa.c index 45986f1..3f02538 100644 --- a/steam-mobile/steam_rsa.c +++ b/steam-mobile/steam_rsa.c @@ -210,22 +210,22 @@ steam_crypt_rsa_enc(const GByteArray *mod, const GByteArray *exp, const GByteArr res |= gcry_mpi_scan(&empi, GCRYMPI_FMT_USG, exp->data, exp->len, NULL); res |= gcry_mpi_scan(&dmpi, GCRYMPI_FMT_USG, bytes->data, bytes->len, NULL); - if (G_UNLIKELY(res == 0)) { + if (G_LIKELY(res == 0)) { res = gcry_sexp_build(&kata, NULL, "(public-key(rsa(n %m)(e %m)))", mmpi, empi); res |= gcry_sexp_build(&data, NULL, "(data(flags pkcs1)(value %m))", dmpi); - if (G_UNLIKELY(res == 0)) { + if (G_LIKELY(res == 0)) { res = gcry_pk_encrypt(&cata, data, kata); - if (G_UNLIKELY(res == 0)) { + if (G_LIKELY(res == 0)) { gcry_sexp_release(data); data = gcry_sexp_find_token(cata, "a", 0); - if (G_UNLIKELY(data != NULL)) { + if (G_LIKELY(data != NULL)) { gcry_mpi_release(dmpi); dmpi = gcry_sexp_nth_mpi(data, 1, GCRYMPI_FMT_USG); - if (G_UNLIKELY(dmpi != NULL)) { + if (G_LIKELY(dmpi != NULL)) { ret = g_byte_array_new(); g_byte_array_set_size(ret, mod->len); -- cgit v1.2.3