aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-08-11 09:08:39 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-08-11 09:08:39 +0100
commit523fb2324a351e9607ad2a803c6e866c5175aa16 (patch)
tree52e1d753a149196a50630415d51bb22f46b9b94e /lib
parent7db65b7df08a3c7cab28e065b2ffa3d9941ceccb (diff)
Implement MSNP15 SSO (Sadistic Sign-On).
Diffstat (limited to 'lib')
-rw-r--r--lib/sha1.c47
-rw-r--r--lib/sha1.h1
-rw-r--r--lib/ssl_client.h2
-rw-r--r--lib/ssl_openssl.c24
4 files changed, 74 insertions, 0 deletions
diff --git a/lib/sha1.c b/lib/sha1.c
index ee4fcc19..7ee90640 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -35,6 +35,7 @@
*
*/
+#include <string.h>
#include "sha1.h"
/*
@@ -373,3 +374,49 @@ static void sha1_pad(sha1_state_t * context)
sha1_process_block(context);
}
+
+#define HMAC_BLOCK_SIZE 64
+
+/* BitlBee addition: */
+void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size])
+{
+ sha1_state_t sha1;
+ uint8_t hash[sha1_hash_size];
+ uint8_t key[HMAC_BLOCK_SIZE+1];
+ int i;
+
+ if( key_len == 0 )
+ key_len = strlen( key_ );
+ if( payload_len == 0 )
+ payload_len = strlen( payload );
+
+ /* Create K. If our current key is >64 chars we have to hash it,
+ otherwise just pad. */
+ memset( key, 0, HMAC_BLOCK_SIZE + 1 );
+ if( key_len > HMAC_BLOCK_SIZE )
+ {
+ sha1_init( &sha1 );
+ sha1_append( &sha1, (uint8_t*) key_, key_len );
+ sha1_finish( &sha1, key );
+ }
+ else
+ {
+ memcpy( key, key_, key_len );
+ }
+
+ /* Inner part: H(K XOR 0x36, text) */
+ sha1_init( &sha1 );
+ for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
+ key[i] ^= 0x36;
+ sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
+ sha1_append( &sha1, (const uint8_t*) payload, payload_len );
+ sha1_finish( &sha1, hash );
+
+ /* Final result: H(K XOR 0x5C, inner stuff) */
+ sha1_init( &sha1 );
+ for( i = 0; i < HMAC_BLOCK_SIZE; i ++ )
+ key[i] ^= 0x36 ^ 0x5c;
+ sha1_append( &sha1, key, HMAC_BLOCK_SIZE );
+ sha1_append( &sha1, hash, sha1_hash_size );
+ sha1_finish( &sha1, Message_Digest );
+}
diff --git a/lib/sha1.h b/lib/sha1.h
index 4ef8ac92..a87410eb 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -66,5 +66,6 @@ typedef struct SHA1Context {
G_MODULE_EXPORT int sha1_init(sha1_state_t *);
G_MODULE_EXPORT int sha1_append(sha1_state_t *, const uint8_t *, unsigned int);
G_MODULE_EXPORT int sha1_finish(sha1_state_t *, uint8_t Message_Digest[sha1_hash_size]);
+G_MODULE_EXPORT void sha1_hmac(const char *key_, size_t key_len, const char *payload, size_t payload_len, uint8_t Message_Digest[sha1_hash_size]);
#endif
diff --git a/lib/ssl_client.h b/lib/ssl_client.h
index 0a8e82d8..787d528a 100644
--- a/lib/ssl_client.h
+++ b/lib/ssl_client.h
@@ -77,3 +77,5 @@ G_MODULE_EXPORT int ssl_getfd( void *conn );
adding an event handler to the queue. (And it should perform exactly
the same action as the handler that just received the SSL_AGAIN.) */
G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
+
+G_MODULE_EXPORT size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res);
diff --git a/lib/ssl_openssl.c b/lib/ssl_openssl.c
index 8abff390..1c70eb0f 100644
--- a/lib/ssl_openssl.c
+++ b/lib/ssl_openssl.c
@@ -271,3 +271,27 @@ b_input_condition ssl_getdirection( void *conn )
{
return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ );
}
+
+size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res)
+{
+ OpenSSL_add_all_algorithms();
+ int output_length = 0;
+
+ *res = g_new0(unsigned char, 72);
+
+ EVP_CIPHER_CTX ctx;
+ /* Don't set key or IV because we will modify the parameters */
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1);
+ EVP_CIPHER_CTX_set_key_length(&ctx, key_len);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+ /* We finished modifying parameters so now we can set key and IV */
+ EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1);
+ EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len);
+ EVP_CipherFinal_ex(&ctx, *res, &output_length);
+
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_cleanup();
+
+ return output_length;
+}