From 258c544fe53ac55acecff8360509fefa97851f3b Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Tue, 26 Nov 2013 18:27:38 +0200 Subject: [PATCH] crypt: start OpenSSL implementation Implemented DES/RC4 cipher routines. NTLM tests pass with those. --- src/core/Makefile.am | 44 +++++---- src/core/sipe-crypt-openssl.c | 206 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 19 deletions(-) create mode 100755 src/core/sipe-crypt-openssl.c diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 91e33f35..64da5314 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -125,16 +125,15 @@ endif endif -libsipe_core_crypto_la_SOURCES = \ - sipe-crypt-nss.c - if SIPE_OPENSSL_CRYPTO -libsipe_core_crypto_la_SOURCES += \ +libsipe_core_crypto_la_SOURCES = \ sipe-cert-crypto-openssl.c \ + sipe-crypt-openssl.c \ sipe-digest-openssl.c else -libsipe_core_crypto_la_SOURCES += \ +libsipe_core_crypto_la_SOURCES = \ sipe-cert-crypto-nss.c \ + sipe-crypt-nss.c \ sipe-digest-nss.c endif @@ -177,10 +176,15 @@ libsipe_core_la_CFLAGS += -DHAVE_SSPI=1 endif libsipe_core_crypto_la_CFLAGS = \ - $(libsipe_core_la_CFLAGS) \ + $(libsipe_core_la_CFLAGS) +if SIPE_OPENSSL_CRYPTO +libsipe_core_crypto_la_CFLAGS += \ + $(OPENSSL_CRYPTO_CFLAGS) +else +libsipe_core_crypto_la_CFLAGS += \ $(NSS_CFLAGS) \ - $(OPENSSL_CRYPTO_CFLAGS) \ $(VALGRIND_CFLAGS) +endif libsipe_core_libxml2_la_CFLAGS = $(libsipe_core_la_CFLAGS) $(LIBXML2_CFLAGS) @@ -204,18 +208,19 @@ check_PROGRAMS += sip_sec_digest_tests sip_sec_digest_tests_SOURCES = sip-sec-digest-tests.c sip_sec_digest_tests_CFLAGS = $(libsipe_core_la_CFLAGS) sip_sec_digest_tests_LDADD = \ - libsipe_core_la-sipe-utils.lo \ - libsipe_core_crypto_la-sipe-crypt-nss.lo + libsipe_core_la-sipe-utils.lo if SIPE_OPENSSL_CRYPTO sip_sec_digest_tests_LDADD += \ - libsipe_core_crypto_la-sipe-digest-openssl.lo + libsipe_core_crypto_la-sipe-crypt-openssl.lo \ + libsipe_core_crypto_la-sipe-digest-openssl.lo \ + $(OPENSSL_CRYPTO_LIBS) else sip_sec_digest_tests_LDADD += \ - libsipe_core_crypto_la-sipe-digest-nss.lo + libsipe_core_crypto_la-sipe-crypt-nss.lo \ + libsipe_core_crypto_la-sipe-digest-nss.lo \ + $(NSS_LIBS) endif sip_sec_digest_tests_LDADD += \ - $(NSS_LIBS) \ - $(OPENSSL_CRYPTO_LIBS) \ $(GLIB_LIBS) # disables "caching" of memory blocks in tests @@ -230,20 +235,21 @@ noinst_PROGRAMS += sipe_tls_tester sipe_tls_tester_SOURCES = sipe-tls-tester.c sipe_tls_tester_CFLAGS = $(libsipe_core_la_CFLAGS) sipe_tls_tester_LDADD = \ - libsipe_core_la-sipe-tls.lo \ - libsipe_core_crypto_la-sipe-crypt-nss.lo + libsipe_core_la-sipe-tls.lo if SIPE_OPENSSL_CRYPTO sipe_tls_tester_LDADD += \ libsipe_core_crypto_la-sipe-cert-crypto-openssl.lo \ - libsipe_core_crypto_la-sipe-digest-openssl.lo + libsipe_core_crypto_la-sipe-crypt-openssl.lo \ + libsipe_core_crypto_la-sipe-digest-openssl.lo \ + $(OPENSSL_CRYPTO_LIBS) else sipe_tls_tester_LDADD += \ libsipe_core_crypto_la-sipe-cert-crypto-nss.lo \ - libsipe_core_crypto_la-sipe-digest-nss.lo + libsipe_core_crypto_la-sipe-crypt-nss.lo \ + libsipe_core_crypto_la-sipe-digest-nss.lo \ + $(NSS_LIBS) endif sipe_tls_tester_LDADD += \ - $(NSS_LIBS) \ - $(OPENSSL_CRYPTO_LIBS) \ $(GLIB_LIBS) endif diff --git a/src/core/sipe-crypt-openssl.c b/src/core/sipe-crypt-openssl.c new file mode 100755 index 00000000..f9b5d258 --- /dev/null +++ b/src/core/sipe-crypt-openssl.c @@ -0,0 +1,206 @@ + /** + * @file sipe-crypt-openssl.c + * + * pidgin-sipe + * + * Copyright (C) 2013 SIPE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * Cipher routines implementation based on OpenSSL. + */ +#include + +#include "glib.h" + +#include "sipe-common.h" +#include "sipe-backend.h" +#include "sipe-crypt.h" + +/* OpenSSL specific initialization/shutdown */ +void sipe_crypto_init(SIPE_UNUSED_PARAMETER gboolean production_mode) +{ + /* nothing to do here */ +} + +void sipe_crypto_shutdown(void) +{ + /* nothing to do here */ +} + +static void openssl_oneshot_crypt(const EVP_CIPHER *type, + const guchar *key, gsize key_length, + const guchar *plaintext, gsize plaintext_length, + guchar *encrypted_text) +{ + EVP_CIPHER_CTX ctx; + int encrypted_length = 0; + + /* initialize context */ + EVP_CIPHER_CTX_init(&ctx); + EVP_EncryptInit_ex(&ctx, type, NULL, key, NULL); + + /* set encryption parameters */ + if (key_length) + EVP_CIPHER_CTX_set_key_length(&ctx, key_length); + EVP_EncryptInit_ex(&ctx, NULL, NULL, key, NULL); + + /* encrypt */ + EVP_EncryptUpdate(&ctx, + encrypted_text, &encrypted_length, + plaintext, plaintext_length); + encrypted_text += encrypted_length; + EVP_EncryptFinal_ex(&ctx, encrypted_text, &encrypted_length); + + /* cleanup */ + EVP_CIPHER_CTX_cleanup(&ctx); +} + +/* DES CBC with 56-bit key */ +void sipe_crypt_des(const guchar *key, + const guchar *plaintext, gsize plaintext_length, + guchar *encrypted_text) +{ + openssl_oneshot_crypt(EVP_des_cbc(), + key, 0 /* fixed length */, + plaintext, plaintext_length, + encrypted_text); +} + +/* RC4 with variable length key */ +void sipe_crypt_rc4(const guchar *key, gsize key_length, + const guchar *plaintext, gsize plaintext_length, + guchar *encrypted_text) +{ + openssl_oneshot_crypt(EVP_rc4(), + key, key_length, + plaintext, plaintext_length, + encrypted_text); +} + +gboolean sipe_crypt_rsa_encrypt(gpointer public, gsize modulus_length, + const guchar *plaintext, + guchar *encrypted_text) +{ + /* TBD */ + (void) public; + (void) encrypted_text; + (void) plaintext; + (void) modulus_length; + return(FALSE); +} + +gboolean sipe_crypt_rsa_decrypt(gpointer private, gsize modulus_length, + const guchar *encrypted_text, + guchar *plaintext) +{ + /* TBD */ + (void) private; + (void) encrypted_text; + (void) plaintext; + (void) modulus_length; + return(FALSE); +} + +guchar *sipe_crypt_rsa_sign(gpointer private, + const guchar *digest, gsize digest_length, + gsize *signature_length) +{ + /* TBD */ + (void) private; + (void) digest; + (void) digest_length; + (void) signature_length; + return(NULL); +} + +gboolean sipe_crypt_verify_rsa(gpointer public, + const guchar *digest, gsize digest_length, + const guchar *signature, gsize signature_length) +{ + /* TBD */ + (void) public; + (void) digest; + (void) digest_length; + (void) signature; + (void) signature_length; + return(FALSE); +} + +static gpointer openssl_rc4_init(const guchar *key, gsize key_length) +{ + EVP_CIPHER_CTX *ctx = g_malloc(sizeof(EVP_CIPHER_CTX)); + + /* initialize context */ + EVP_CIPHER_CTX_init(ctx); + EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, key, NULL); + + /* set encryption parameters */ + EVP_CIPHER_CTX_set_key_length(ctx, key_length); + EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); + + return(ctx); +} + +/* Stream RC4 cipher for file transfer with fixed-length 128-bit key */ +gpointer sipe_crypt_ft_start(const guchar *key) +{ + return(openssl_rc4_init(key, 16)); +} + +void sipe_crypt_ft_stream(gpointer context, + const guchar *in, gsize length, + guchar *out) +{ + int tmp; + EVP_EncryptUpdate(context, out, &tmp, in, length); +} + +void sipe_crypt_ft_destroy(gpointer context) +{ + EVP_CIPHER_CTX_cleanup(context); + g_free(context); +} + +/* Stream RC4 cipher for TLS with variable key length */ +gpointer sipe_crypt_tls_start(const guchar *key, gsize key_length) +{ + return(openssl_rc4_init(key, key_length)); +} + +void sipe_crypt_tls_stream(gpointer context, + const guchar *in, gsize length, + guchar *out) +{ + int tmp; + EVP_EncryptUpdate(context, out, &tmp, in, length); +} + +void sipe_crypt_tls_destroy(gpointer context) +{ + EVP_CIPHER_CTX_cleanup(context); + g_free(context); +} + +/* + Local Variables: + mode: c + c-file-style: "bsd" + indent-tabs-mode: t + tab-width: 8 + End: +*/ -- 2.11.4.GIT