Blob Blame History Raw
diff -up bitlbee-3.0/configure.nss bitlbee-3.0/configure
--- bitlbee-3.0/configure.nss	2010-11-22 13:36:02.000000000 +0100
+++ bitlbee-3.0/configure	2010-11-22 13:36:12.000000000 +0100
@@ -290,10 +291,10 @@ EOF

 detect_nss()
 {
-	if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG mozilla-nss; then
+	if $PKG_CONFIG --version > /dev/null 2>/dev/null && $PKG_CONFIG nss; then
 		cat<<EOF>>Makefile.settings
-EFLAGS+=`$PKG_CONFIG --libs mozilla-nss`
-CFLAGS+=`$PKG_CONFIG --cflags mozilla-nss`
+EFLAGS+=`$PKG_CONFIG --libs nss`
+CFLAGS+=`$PKG_CONFIG --cflags nss`
 EOF

 		ssl=nss
diff -up bitlbee-3.0/lib/ssl_nss.c.nss bitlbee-3.0/lib/ssl_nss.c
--- bitlbee-3.0/lib/ssl_nss.c.nss	2010-10-22 02:51:31.000000000 +0200
+++ bitlbee-3.0/lib/ssl_nss.c	2010-11-22 13:35:48.000000000 +0100
@@ -33,8 +33,10 @@
 #include <prio.h>
 #include <sslproto.h>
 #include <nss.h>
+#include <pk11pub.h>
 #include <private/pprio.h>
 #include <ssl.h>
+#include <seccomon.h>
 #include <secerr.h>
 #include <sslerr.h>
 
@@ -52,6 +54,7 @@ struct scd
 };
 
 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
+static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
 
 
 static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver)
@@ -121,6 +124,35 @@ void *ssl_connect( char *host, int port,
 	return( conn );
 }
 
+static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+
+	return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );
+}
+
+void *ssl_starttls( int fd, ssl_input_function func, gpointer data )
+{
+	struct scd *conn = g_new0( struct scd, 1 );
+
+	conn->fd = fd;
+	conn->func = func;
+	conn->data = data;
+
+	/* This function should be called via a (short) timeout instead of
+	   directly from here, because these SSL calls are *supposed* to be
+	   *completely* asynchronous and not ready yet when this function
+	   (or *_connect, for examle) returns. Also, errors are reported via
+	   the callback function, not via this function's return value.
+
+	   In short, doing things like this makes the rest of the code a lot
+	   simpler. */
+
+	b_timeout_add( 1, ssl_starttls_real, conn );
+
+	return conn;
+}
+
 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
 {
 	struct scd *conn = data;
@@ -200,3 +232,94 @@ b_input_condition ssl_getdirection( void
 	/* Just in case someone calls us, let's return the most likely case: */
 	return B_EV_IO_READ;
 }
+
+#if 0
+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)
+{
+  int output_length = 0;
+
+  CK_MECHANISM_TYPE cipherMech;
+  PK11SlotInfo* slot = NULL;
+  PK11SymKey* SymKey = NULL;
+  SECItem* SecParam = NULL;
+  PK11Context* EncContext = NULL;
+  SECItem keyItem, ivItem;
+  SECStatus rv1, rv2;
+  int tmp1_outlen, tmp2_outlen;
+
+  if (!initialized)
+    {
+      ssl_init();
+    }
+
+  *res = g_new0(unsigned char, 1024);
+
+  cipherMech = CKM_DES3_CBC_PAD;
+  slot = PK11_GetBestSlot(cipherMech, NULL);
+
+  if (slot == NULL)
+    {
+      fprintf(stderr, "Unable to find security device (err %d)\n",
+          PR_GetError());
+      goto out;
+    }
+
+  // Converts "raw key" into a key object.
+  keyItem.type = siBuffer;
+  keyItem.data = (unsigned char*)key;
+  keyItem.len = key_len;
+
+  SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT,
+                             &keyItem, NULL);
+
+  if (SymKey == NULL)
+  {
+    fprintf(stderr, "Failure to import key into NSS (err %d)\n",
+            PR_GetError());
+    goto out;
+  }
+
+  /* set up the PKCS11 encryption paramters.
+   * when not using CBC mode, ivItem.data and ivItem.len can be 0, or you
+   * can simply pass NULL for the iv parameter in PK11_ParamFromIV func
+   */
+  ivItem.type = siBuffer;
+  ivItem.data = iv;
+  ivItem.len = strlen(iv); // ??? Is it right? FIXME
+  SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
+  if (SecParam == NULL)
+  {
+    fprintf(stderr, "Failure to set up PKCS11 param (err %d)\n",
+            PR_GetError());
+    goto out;
+  }
+
+  /* ========================= START SECTION ============================= */
+  /* If using the the same key and iv over and over, stuff before this     */
+  /* section and after this section needs to be done only ONCE             */
+  /* ENCRYPT data into buf1. buf1 len must be atleast (data len + 8) */
+  tmp1_outlen = tmp2_outlen = 0;
+
+  /* Create cipher context */
+  EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT,
+                                          SymKey, SecParam);
+  rv1 = PK11_CipherOp(EncContext, res, &tmp1_outlen, sizeof(res),
+                      input, input_len+1);
+  rv2 = PK11_DigestFinal(EncContext, res+tmp1_outlen, &tmp2_outlen,
+                         sizeof(res)-tmp1_outlen);
+  PK11_DestroyContext(EncContext, PR_TRUE);
+  output_length = tmp1_outlen + tmp2_outlen;
+  if (rv1 != SECSuccess || rv2 != SECSuccess)
+    goto out;
+
+  return output_length;
+
+  out:
+    if (SymKey)
+      PK11_FreeSymKey(SymKey);
+    if (SecParam)
+      SECITEM_FreeItem(SecParam, PR_TRUE);
+}
+#endif