diff -ur mozilla-1.9.1/dom/public/idl/base/nsIDOMCrypto.idl mozilla-EKM/dom/public/idl/base/nsIDOMCrypto.idl
--- mozilla-1.9.1/dom/public/idl/base/nsIDOMCrypto.idl	2009-07-16 01:34:48.000000000 +1000
+++ mozilla-EKM/dom/public/idl/base/nsIDOMCrypto.idl	2009-08-01 13:29:50.000000000 +1000
@@ -54,4 +54,7 @@
                                      in DOMString caOption /* ... */);
   void                      logout();
   void                      disableRightClick();
+  DOMString                 tlsExportKeyingMaterial(in DOMString label,
+                                                    in long numBytes,
+                                                    in DOMString context_value);
 };
diff -ur mozilla-1.9.1/netwerk/socket/base/nsISSLSocketControl.idl mozilla-EKM/netwerk/socket/base/nsISSLSocketControl.idl
--- mozilla-1.9.1/netwerk/socket/base/nsISSLSocketControl.idl	2009-07-16 01:35:12.000000000 +1000
+++ mozilla-EKM/netwerk/socket/base/nsISSLSocketControl.idl	2009-08-04 11:43:11.000000000 +1000
@@ -40,6 +40,12 @@
 
 #include "nsISupports.idl"
 
+%{C++
+#include "prio.h"
+%}
+
+[ptr] native PRFileDescStar(PRFileDesc);
+
 interface nsIInterfaceRequestor;
 
 [scriptable, uuid(a092097c-8386-4f1b-97b1-90eb70008c2d)]
@@ -48,5 +54,7 @@
 
     void proxyStartSSL();
     void StartTLS();
+
+    [noscript] void getFileDescPtr(out PRFileDescStar aFileDesc);
 };
 
diff -ur mozilla-1.9.1/security/manager/ssl/src/nsCrypto.cpp mozilla-EKM/security/manager/ssl/src/nsCrypto.cpp
--- mozilla-1.9.1/security/manager/ssl/src/nsCrypto.cpp	2009-07-16 01:35:18.000000000 +1000
+++ mozilla-EKM/security/manager/ssl/src/nsCrypto.cpp	2009-08-04 13:19:36.000000000 +1000
@@ -22,6 +22,7 @@
  *
  * Contributor(s):
  *   Javier Delgadillo <javi@netscape.com>
+ *   Douglas Stebila <douglas@stebila.ca>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -75,6 +76,8 @@
 #include "nsIFormSigningDialog.h"
 #include "nsIProxyObjectManager.h"
 #include "nsIJSContextStack.h"
+#include "nsISSLSocketControl.h"
+#include "nsNSSIOLayer.h"
 #include "jsapi.h"
 #include "jsdbgapi.h"
 #include <ctype.h>
@@ -3020,3 +3023,83 @@
   return NS_ERROR_FAILURE;
 }
 
+NS_IMETHODIMP
+nsCrypto::TlsExportKeyingMaterial(const nsAString& aLabel, 
+                                  PRInt32 aNumBytes,
+                                  const nsAString& aContextValue, 
+                                  nsAString& aReturn)
+{
+  nsresult rv = NS_OK;
+
+  // get current nsIDocument
+  nsAXPCNativeCallContext* ncc = nsnull;
+  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
+  if (xpc) {
+    xpc->GetCurrentNativeCallContext(&ncc);
+  }
+  if (!ncc) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  JSContext *cx;
+  ncc->GetJSContext(&cx);
+  if (!cx) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  nsCOMPtr<nsIDocument> document;
+  GetDocumentFromContext(cx, getter_AddRefs(document));
+  if (!document) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  // get SSL socket for current document
+  nsCOMPtr<nsISupports> securityInfo;
+  securityInfo = document->GetSecurityInfo();
+  if (!securityInfo) return NS_ERROR_ILLEGAL_VALUE;
+  nsCOMPtr<nsISSLSocketControl> ssl = do_QueryInterface(securityInfo, &rv);
+  if (NS_FAILED(rv)) return rv;
+
+  // look up PRFileDesc *fd for this connection
+  PRFileDesc *fd;
+  rv = ssl->GetFileDescPtr(&fd);
+  if (NS_FAILED(rv)) return rv;
+
+  // allocate unsigned char * out for return value
+  unsigned char *out = (unsigned char *) NS_Alloc(aNumBytes);
+  if (out == nsnull) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  // convert aLabel to char *
+  char *label = ToNewCString(aLabel);
+  if (!label) {
+    NS_Free(out);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  // convert aContextValue to char *
+  unsigned char *contextValue = reinterpret_cast<unsigned char *>(ToNewCString(aContextValue));
+  unsigned int contextValueLength = aContextValue.Length();
+  if (contextValueLength && !contextValue) {
+    NS_Free(out);
+    NS_Free(label);
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  // call keying material exporter
+  SECStatus st = SSL_ExportKeyingMaterial(fd, label, contextValue, contextValueLength, out, aNumBytes);
+  if (st != SECSuccess) {
+    NS_Free(out);
+    NS_Free(label);
+    NS_Free(contextValue);
+    return NS_ERROR_FAILURE;
+  }
+  // convert output into aReturn
+  aReturn.Assign(NS_ConvertASCIItoUTF16((char *) out, aNumBytes));
+
+  // free memory and return
+  NS_Free(out);
+  NS_Free(label);
+  NS_Free(contextValue);
+  return rv;
+}
+
diff -ur mozilla-1.9.1/security/manager/ssl/src/nsNSSIOLayer.cpp mozilla-EKM/security/manager/ssl/src/nsNSSIOLayer.cpp
--- mozilla-1.9.1/security/manager/ssl/src/nsNSSIOLayer.cpp	2009-07-16 01:35:18.000000000 +1000
+++ mozilla-EKM/security/manager/ssl/src/nsNSSIOLayer.cpp	2009-08-04 13:13:21.000000000 +1000
@@ -698,7 +698,8 @@
   return NS_OK;
 }
 
-nsresult nsNSSSocketInfo::GetFileDescPtr(PRFileDesc** aFilePtr)
+NS_IMETHODIMP
+nsNSSSocketInfo::GetFileDescPtr(PRFileDesc** aFilePtr)
 {
   *aFilePtr = mFd;
   return NS_OK;
diff -ur mozilla-1.9.1/security/manager/ssl/src/nsNSSIOLayer.h mozilla-EKM/security/manager/ssl/src/nsNSSIOLayer.h
--- mozilla-1.9.1/security/manager/ssl/src/nsNSSIOLayer.h	2009-07-16 01:35:18.000000000 +1000
+++ mozilla-EKM/security/manager/ssl/src/nsNSSIOLayer.h	2009-08-04 13:13:14.000000000 +1000
@@ -160,7 +160,8 @@
   nsresult SetForSTARTTLS(PRBool aForSTARTTLS);
   nsresult GetForSTARTTLS(PRBool *aForSTARTTLS);
 
-  nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
+  // nsresult GetFileDescPtr(PRFileDesc** aFilePtr); 
+  // is exposed in nsISSLSocketControl.idl
   nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
 
   nsresult GetHandshakePending(PRBool *aHandshakePending);
