diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sha1.c | 47 | ||||
| -rw-r--r-- | lib/sha1.h | 1 | ||||
| -rw-r--r-- | lib/ssl_client.h | 2 | ||||
| -rw-r--r-- | lib/ssl_openssl.c | 24 | 
4 files changed, 74 insertions, 0 deletions
| @@ -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 ); +} @@ -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; +} | 
