diff -up bitlbee-3.0.1/configure.des3 bitlbee-3.0.1/configure
--- bitlbee-3.0.1/configure.des3 2010-12-28 16:07:35.074260735 +0100
+++ bitlbee-3.0.1/configure 2010-12-28 16:07:35.082260713 +0100
@@ -429,10 +431,10 @@ if [ "$ret" = "0" ]; then
exit 1
fi;
-if [ "$msn" = "1" -a "$ssl" != "openssl" -a "$ssl" != "gnutls" ]; then
- # Needed for MSN only. OpenSSL exports nice cipher functions already,
+if [ "$msn" = "1" -a "$ssl" != "openssl" -a "$ssl" != "gnutls" -a "$ssl" != "nss" ]; then
+ # Needed for MSN only. OpenSSL and NSS export nice cipher functions already,
# in case of GnuTLS we should be able to use gcrypt. Otherwise, use
- # built-in stuff. (Since right now those are the only two supported
+ # built-in stuff. (Since right now those are the only three supported
# SSL modules anyway, this is mostly unnecessary.)
echo 'DES=des.o' >> Makefile.settings
fi
diff -up bitlbee-3.0.1/lib/ssl_nss.c.des3 bitlbee-3.0.1/lib/ssl_nss.c
--- bitlbee-3.0.1/lib/ssl_nss.c.des3 2010-12-28 16:07:35.077260726 +0100
+++ bitlbee-3.0.1/lib/ssl_nss.c 2010-12-28 16:09:02.408014610 +0100
@@ -39,6 +39,7 @@
#include <seccomon.h>
#include <secerr.h>
#include <sslerr.h>
+#include <assert.h>
int ssl_errno = 0;
@@ -238,3 +239,91 @@ b_input_condition ssl_getdirection( void
/* Just in case someone calls us, let's return the most likely case: */
return 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)
+{
+#define CIPHER_MECH CKM_DES3_CBC
+#define MAX_OUTPUT_LEN 72
+
+ int len1;
+ unsigned int len2;
+
+ PK11Context *ctx = NULL;
+ PK11SlotInfo *slot = NULL;
+ SECItem keyItem;
+ SECItem ivItem;
+ SECItem *secParam = NULL;
+ PK11SymKey *symKey = NULL;
+
+ size_t rc;
+ SECStatus rv;
+
+ if (!initialized) {
+ ssl_init();
+ }
+
+ keyItem.data = (unsigned char *) key;
+ keyItem.len = key_len;
+
+ slot = PK11_GetBestSlot(CIPHER_MECH, NULL);
+ if (slot == NULL) {
+ fprintf(stderr, "PK11_GetBestSlot failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ symKey = PK11_ImportSymKey(slot, CIPHER_MECH, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
+ if (symKey == NULL) {
+ fprintf(stderr, "PK11_ImportSymKey failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ ivItem.data = (unsigned char *) iv;
+ /* See msn_soap_passport_sso_handle_response in protocols/msn/soap.c */
+ ivItem.len = 8;
+
+ secParam = PK11_ParamFromIV(CIPHER_MECH, &ivItem);
+ if (secParam == NULL) {
+ fprintf(stderr, "PK11_ParamFromIV failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ ctx = PK11_CreateContextBySymKey(CIPHER_MECH, CKA_ENCRYPT, symKey, secParam);
+ if (ctx == NULL) {
+ fprintf(stderr, "PK11_CreateContextBySymKey failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ *res = g_new0(unsigned char, MAX_OUTPUT_LEN);
+
+ rv = PK11_CipherOp(ctx, *res, &len1, MAX_OUTPUT_LEN, (unsigned char *) input, input_len);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "PK11_CipherOp failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ assert(len1 <= MAX_OUTPUT_LEN);
+
+ rv = PK11_DigestFinal(ctx, *res + len1, &len2, (unsigned int) MAX_OUTPUT_LEN - len1);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "PK11_DigestFinal failed (err %d)\n", PR_GetError());
+ rc = 0;
+ goto out;
+ }
+
+ rc = len1 + len2;
+
+out:
+ if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
+ if (symKey) PK11_FreeSymKey(symKey);
+ if (secParam) SECITEM_FreeItem(secParam, PR_TRUE);
+ if (slot) PK11_FreeSlot(slot);
+
+ return rc;
+}