diff options
author | Eion Robb <eion@robbmob.com> | 2015-08-30 15:21:21 +0300 |
---|---|---|
committer | Eion Robb <eion@robbmob.com> | 2015-08-30 15:21:21 +0300 |
commit | ab22c62ffeaab903b0ca34f88da73307c870196d (patch) | |
tree | f1acaf8e3b2c5a7a6aa21c390a6b0bb51ad609cd /steam-mobile | |
parent | 0a8a5dec32fa45d931bb11598d40bec0eb345616 (diff) | |
parent | 9abb26301c2b4700b75efb8186e375cd66a9c634 (diff) |
Merge pull request #109 from flocke/master
steam_rsa: add libgcrypt as crypto backend
Diffstat (limited to 'steam-mobile')
-rw-r--r-- | steam-mobile/Makefile | 21 | ||||
-rw-r--r-- | 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 9706fc8..67ee9da 100644 --- a/steam-mobile/steam_rsa.c +++ b/steam-mobile/steam_rsa.c @@ -13,7 +13,7 @@ password=<base64rsaencryptedpwd>&username=<steamusername>&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 <gcrypt.h>
+#include <string.h>
+
+// 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 <jgeboski@gmail.com>.
+
+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_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_LIKELY(res == 0)) {
+ res = gcry_pk_encrypt(&cata, data, kata);
+
+ if (G_LIKELY(res == 0)) {
+ gcry_sexp_release(data);
+ data = gcry_sexp_find_token(cata, "a", 0);
+
+ if (G_LIKELY(data != NULL)) {
+ gcry_mpi_release(dmpi);
+ dmpi = gcry_sexp_nth_mpi(data, 1, GCRYMPI_FMT_USG);
+
+ if (G_LIKELY(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(const gchar *modulus_str, const gchar *exponent_str, cons return output;
}
-#endif
\ No newline at end of file +#endif
|