Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

browser support and VFS

  • Loading branch information...
commit 5b7f8d03bb393932575edcd5f0a4e445037646a8 1 parent e11104f
@mnaamani authored
View
32 Makefile
@@ -16,29 +16,17 @@ EXPORTED_FUNCS= -s EXPORTED_FUNCTIONS="['_gcry_strerror','_malloc','_free','__gc
'_otrl_message_receiving', '_otrl_instag_generate', '_jsapi_conncontext_get_their_instance', '_jsapi_conncontext_get_our_instance', \
'_jsapi_conncontext_get_master', '_otrl_instag_read', '_otrl_instag_write', '_otrl_instag_find', '_jsapi_instag_get_tag' ]"
-OPTIMISATION_OFF= -O0 --closure 0 --llvm-opts 0 --minify 0 -s LINKABLE=1
-#O2 optimisation causing some bugs: Ohhhh jeeee: ... this is a bug (cipher.c:326:cipher_register_default)
-#llvm optimisations slowdown compilation and dont provide noticable speedup.
-OPTIMISATION_ON= -O1 --closure 1 --llvm-opts 0 --minify 0 -s LINKABLE=1 $(EXPORTED_FUNCS)
-
-OPTIMISATION= $(OPTIMISATION_OFF)
-
-module:
- mkdir -p $(BUILD_DIR)/
- $(EMCC) src/jsapi.c -I$(CRYPTO_BUILD)/include -lotr -L$(CRYPTO_BUILD)/lib \
- -o $(BUILD_DIR)/libotr4.js \
- --pre-js src/otr_pre.js \
- --post-js src/otr_post.js \
- -s TOTAL_MEMORY=1048576 -s TOTAL_STACK=409600 \
- $(OPTIMISATION)
+OPTIMISATION= -O2 --closure 0 --llvm-opts 1 --minify 0 -s LINKABLE=1 $(EXPORTED_FUNCS)
module-optimised:
mkdir -p $(BUILD_DIR)/
- cp src/otr_post.js $(BUILD_DIR)/libotr4.js
+ cp src/header.js $(BUILD_DIR)/_libotr4.js
$(EMCC) src/jsapi.c -I$(CRYPTO_BUILD)/include -lotr -L$(CRYPTO_BUILD)/lib \
- -o $(BUILD_DIR)/_libotr4.js \
- --pre-js src/otr_pre.js \
- -s TOTAL_MEMORY=1048576 -s TOTAL_STACK=409600 \
- $(OPTIMISATION_ON)
- cat $(BUILD_DIR)/_libotr4.js >> $(BUILD_DIR)/libotr4.js
- rm $(BUILD_DIR)/_libotr4.js
+ -o $(BUILD_DIR)/libotr4_tmp.js \
+ --pre-js src/otr_pre.js \
+ -s TOTAL_MEMORY=1048576 -s TOTAL_STACK=409600 \
+ $(OPTIMISATION)
+ cat $(BUILD_DIR)/libotr4_tmp.js >> $(BUILD_DIR)/_libotr4.js
+ cat src/footer.js >> $(BUILD_DIR)/_libotr4.js
+ mv $(BUILD_DIR)/_libotr4.js $(BUILD_DIR)/libotr4.js
+ rm $(BUILD_DIR)/libotr4_tmp.js
View
5 find-emcc.py
@@ -0,0 +1,5 @@
+#!/usr/bin/python
+import os
+execfile(os.path.expanduser("~/.emscripten"))
+print EMSCRIPTEN_ROOT
+
View
206 lib/libotr-js-bindings.js
@@ -1,9 +1,47 @@
-var libModule = require("./libotr4.js").getModule();//optimised and minified libotr,libgcrypt,libgpg-error
-var NODE_ASYNC = require("./async");
+;(function () {
+
+ var root = this;
+
+/*
+ * Off-the-Record Messaging bindings for node/javascript
+ * Copyright (C) 2012 Mokhtar Naamani,
+ * <mokhtar.naamani@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ var libModule, ASYNC, fs, BigInt;
+
+ if (typeof exports !== 'undefined') {
+ libModule = require("./libotr4.js").getModule();
+ ASYNC = require("./async");
+ fs = require("fs");
+ BigInt = require("./bigint.js");
+ module.exports = otrBindings;
+
+ } else {
+ libModule = root.getModule();
+ ASYNC = root.async;
+ fs = undefined;//local storage?
+ BigInt = root.BigInt;
+ root.otrBindings = otrBindings;
+ }
var otrl_ = libModule.libotrl; //cwrap()'ed functions from libotr
var gcry_ = libModule.libgcrypt; //cwrap()'ed functions from libgcrypt
var jsapi_= libModule.jsapi;
+var helper_ = libModule.helper;
var _malloc = libModule.malloc;
var _free = libModule.free;
@@ -12,21 +50,35 @@ var setValue = libModule.setValue;
var Pointer_stringify = libModule.Pointer_stringify;
libModule["ops_event"] = ops_event;
-libModule["ConnContext"] = ConnContext;
+libModule["ConnContext"] = OtrlConnContext;
var OPS_QUEUE;
var MAO = []; //OtrlMessageAppOps instances and their callback handlers
-module.exports = {
- "init": (function() {
- jsapi_.initialise();
- }),
- "version":function(){
- return otrl_.version()+"-emscripten";
- },
- "UserState":OtrlUserState,
- "ConnContext":ConnContext,
- "MessageAppOps":OtrlMessageAppOps,
+//otrBindings = Exported Interface
+function otrBindings(){
+ this.init();
+};
+
+otrBindings.prototype = {
+
+ constructor: otrBindings,
+
+ init : jsapi_.initialise, //put this in jsapi.c main() instead?
+
+ UserState : OtrlUserState,
+
+ ConnContext : OtrlConnContext,
+
+ MessageAppOps : OtrlMessageAppOps,
+
+ VFS : VirtualFileSystem,
+
+ version :function(){
+ return otrl_.version()+"-emscripten";
+ },
+
+ GcryptError: GcryptError
};
//OtrlInsTag
@@ -76,7 +128,8 @@ OtrlUserState.prototype.accounts = function(){
accounts.push({
"accountname":accountname,
"protocol":protocol,
- "fingerprint":self.fingerprint(accountname,protocol)
+ "fingerprint":self.fingerprint(accountname,protocol),
+ "privkey":p
});
p = p.next();
}
@@ -183,7 +236,7 @@ OtrlUserState.prototype.findInstag = function (accountname,protocol){
}
};
//ConnContext
-function ConnContext(userstate,accountname,protocol,recipient){
+function OtrlConnContext(userstate,accountname,protocol,recipient){
if( typeof userstate == 'object' &&
typeof accountname == 'string' &&
typeof protocol == 'string' &&
@@ -198,49 +251,49 @@ function ConnContext(userstate,accountname,protocol,recipient){
//assume arguments[0] == pointer to existing context;
this._pointer = arguments[0];
}else{
- throw("invalid arguments to ConnContext()");
+ throw("invalid arguments to OtrlConnContext()");
}
}
};
-ConnContext.prototype.protocol = function(){
+OtrlConnContext.prototype.protocol = function(){
return jsapi_.conncontext_get_protocol(this._pointer);
};
-ConnContext.prototype.username = function(){
+OtrlConnContext.prototype.username = function(){
return jsapi_.conncontext_get_username(this._pointer);
};
-ConnContext.prototype.accountname = function(){
+OtrlConnContext.prototype.accountname = function(){
return jsapi_.conncontext_get_accountname(this._pointer);
};
-ConnContext.prototype.msgstate = function(){
+OtrlConnContext.prototype.msgstate = function(){
return jsapi_.conncontext_get_msgstate(this._pointer);
};
-ConnContext.prototype.protocol_version = function(){
+OtrlConnContext.prototype.protocol_version = function(){
return jsapi_.conncontext_get_protocol_version(this._pointer);
};
-ConnContext.prototype.smstate = function(){
+OtrlConnContext.prototype.smstate = function(){
return jsapi_.conncontext_get_smstate(this._pointer);
};
-ConnContext.prototype.fingerprint = function(){
+OtrlConnContext.prototype.fingerprint = function(){
var fp = _malloc(45);
jsapi_.conncontext_get_active_fingerprint(this._pointer,fp);
var human = Pointer_stringify(fp);
_free(fp);
return human;
};
-ConnContext.prototype.trust = function(){
+OtrlConnContext.prototype.trust = function(){
return jsapi_.conncontext_get_trust(this._pointer);
};
-ConnContext.prototype.their_instance = function(){
+OtrlConnContext.prototype.their_instance = function(){
return unsigned_int(jsapi_.conncontext_get_their_instance(this._pointer));
};
-ConnContext.prototype.our_instance = function(){
+OtrlConnContext.prototype.our_instance = function(){
return unsigned_int( jsapi_.conncontext_get_our_instance(this._pointer));
};
-ConnContext.prototype.master = function(){
- return new ConnContext( jsapi_.conncontext_get_master(this._pointer));
+OtrlConnContext.prototype.master = function(){
+ return new OtrlConnContext( jsapi_.conncontext_get_master(this._pointer));
};
-ConnContext.prototype.obj = function(){
+OtrlConnContext.prototype.obj = function(){
return({
'protocol':this.protocol(),
'username':this.username(),
@@ -254,13 +307,14 @@ ConnContext.prototype.obj = function(){
'our_instance':this.our_instance()
});
};
+OtrlConnContext.prototype.fields = OtrlConnContext.prototype.obj;
//OtrlMessageAppOps
function OtrlMessageAppOps( event_handler ){
//keep track of all created instances
//index into array will be passed around as opdata to tie
//the event_handler to the relevant instance.
- if(!OPS_QUEUE) OPS_QUEUE = NODE_ASYNC.queue(ops_handle_event,1)
+ if(!OPS_QUEUE) OPS_QUEUE = ASYNC.queue(ops_handle_event,1)
var self = this;
this._event_handler = event_handler;
@@ -420,3 +474,95 @@ function unsigned_int( si ){
return si;
}
}
+
+//TODO Add a SHA1 checksum of the file system.
+//gzip and encrypt the file system?
+// *** Closure Compiler will change names of objects inside the FS ***//
+function VirtualFileSystem ( file ) {
+ var defaultFile = file || "./virtual.vfs";
+ return ({
+ "export":function(){
+ //note - devices are not properly exported because functions cannot be serialised.
+ return JSON.stringify({
+ "root": libModule.FS.root,
+ "nextInode": libModule.FS.nextInode
+ });
+ },
+ "import": function( data ){
+ var importedFS = JSON.parse(data);
+ //link devices to alreardy initialised file system.
+ //we should import a vfs early on and preferably once on initial launch of the application - (circular refrences below
+ //could keep the FS data from being garbage collected?
+ importedFS.root.contents['dev'].contents['random'].input = libModule.FS.root.contents['dev'].contents['random'].input;
+ importedFS.root.contents['dev'].contents['random'].output = libModule.FS.root.contents['dev'].contents['random'].output;
+ importedFS.root.contents['dev'].contents['urandom'].input = libModule.FS.root.contents['dev'].contents['urandom'].input;
+ importedFS.root.contents['dev'].contents['urandom'].output = libModule.FS.root.contents['dev'].contents['urandom'].output;
+ importedFS.root.contents['dev'].contents['stdout'].output = libModule.FS.root.contents['dev'].contents['stdout'].output;
+ importedFS.root.contents['dev'].contents['stdin'].intput = libModule.FS.root.contents['dev'].contents['stdin'].input;
+ importedFS.root.contents['dev'].contents['stderr'].output = libModule.FS.root.contents['dev'].contents['stderr'].output;
+ importedFS.root.contents['dev'].contents['tty'].output = libModule.FS.root.contents['dev'].contents['tty'].output;
+ importedFS.root.contents['dev'].contents['tty'].input = libModule.FS.root.contents['dev'].contents['tty'].input;
+
+ //var open_streams = libModule.FS.streams.length;
+ //if(open_streams > 3) console.log("= VFS Import Warning:",open_streams - 3," files open.");//how to handle this case?
+
+ //link default streams to imported devices -- this might not really be necessary..
+ //stdin stream
+ libModule.FS.streams[1].object = importedFS.root.contents['dev'].contents['stdin'];
+ //stdou stream
+ libModule.FS.streams[2].object = importedFS.root.contents['dev'].contents['stdout'];
+ //stderr stream
+ libModule.FS.streams[3].object = importedFS.root.contents['dev'].contents['stderr'];
+
+ libModule.FS.root = importedFS.root;
+ libModule.FS.nextInode = importedFS.nextInode;
+
+ },
+ "load": function( filename ){
+ if(!fs) return;
+ var realFile = filename || defaultFile;
+ try{
+ console.error("loading virtual file system:",realFile);
+ var data = fs.readFileSync(realFile);
+ this.import(data);
+ }catch(e){
+ console.error( e );
+ }
+ return this;
+ },
+ "save": function (filename){
+ if(!fs) return;
+ var realFile = filename || defaultFile;
+ console.error("saving virtual filesystem to:",realFile);
+ fs.writeFileSync(realFile,this.export());
+ return this;
+ },
+ "importFile": function (source,destination){
+ if(!fs) return;
+ //cp a file from real file system to virtual file system
+
+ },
+ "exportFile": function (source,destination){
+ if(!fs) return;
+ //cp a file from virtual file system to real file system
+ //TODO preserve same file permissions (mode)
+ var object = libModule.FS.findObject(source);
+ if(object){
+ var data = new Buffer(object.contents);
+ var fd = fs.openSync(destination,"w");
+ console.log("wrote",fs.writeSync(fd,data,0,data.length,0),"bytes to",destination);
+ fs.closeSync(fd);
+ }
+ }
+ });
+}
+
+
+function GcryptError( num ) {
+ this.num = num || 0;
+ this.message = gcry_.strerror(num || 0);
+}
+GcryptError.prototype = new Error();
+GcryptError.prototype.constructor = GcryptError;
+
+}).call(this);
View
160,350 lib/libotr4.js
75,552 additions, 84,798 deletions not shown
View
130 lib/otr-module.js
@@ -1,5 +1,8 @@
+(function () {
+
+ var root = this;
/*
- * Off-the-Record Messaging bindings for nodejs
+ * Off-the-Record Messaging bindings for node/javascript
* Copyright (C) 2012 Mokhtar Naamani,
* <mokhtar.naamani@gmail.com>
*
@@ -17,44 +20,78 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-//load javascript binding/interface to compiled C api
-var otr=require("./libotr-js-bindings");
-if(otr.init) otr.init();
+var debug = function(){};
-if(otr.version()!="4.0.0-emscripten"){
- console.error("Warning. Excpecting version 4.0.0-emscripten");
- process.exit();
-}
+var otr, otrBindings, util, events;
-var util = require('util');
-var events = require('events');
+if (typeof exports !== 'undefined') {
+ otrBindings = require("./libotr-js-bindings.js");
+ util = require('util');
+ events = require('events');
-//low level - wrappers to C API
-exports.version = otr.version;
-exports.UserState = otr.UserState;
-exports.ConnContext = otr.ConnContext;
-//discourage use of MessageAppOps directly
-//exports.MessageAppOps = otr.MessageAppOps;
+ otr = new otrBindings();
-//high level - javascript API
-exports.User = User;
-exports.OTRChannel = OTRChannel;
-exports.POLICY = OTRL_POLICY;
-exports.MSGEVENT = OTRL_MSGEVENT;
+ if(otr.version()!="4.0.0-emscripten"){
+ console.error("Error. excpecting libotr4.0.0-emscripten! exiting..");
+ process.exit();
+ }
-util.inherits(OTRChannel, events.EventEmitter);
+ module.exports = {
+ debugOn: function(){
+ debug = console.error;
+ },
+ debugOff: function(){
+ debug = function(){};
+ },
+ version: otr.version,
+ User: User,
+ ConnContext: otr.ConnContext,
+ Session : OTRChannel,
+ POLICY : OTRL_POLICY,
+ MSGEVENT : OTRL_MSGEVENT,
+ VFS: otr.VFS,
+ //below wil not be exposed in future version..
+ UserState: otr.UserState,
+ //discourage use of MessageAppOps
+ //MessageAppOps : otr.MessageAppOps,
+ OTRChannel: OTRChannel
+ };
-var debug = function(){};
-exports.debugOn = function(){
- debug = console.error;
-};
-exports.debugOff = function(){
- debug = function(){};
-};
+}else{
+ otrBindings = root.otrBindings;
+ events = undefined;
+ otr = new otrBindings();
+
+ if(otr.version()!="4.0.0-emscripten"){
+ alert("Warning. Excpecting libotr4.0.0-emscripten! OTR library not loaded.");
+ }else{
+ root.OTR = {
+ debugOn: function(){
+ debug = console.error;
+ },
+ debugOff: function(){
+ debug = function(){};
+ },
+ version: otr.version,
+ User: User,
+ ConnContext: otr.ConnContext,
+ Session : OTRChannel,
+ POLICY: OTRL_POLICY,
+ MSGEVENT: OTRL_MSGEVENT,
+ VFS: otr.VFS,
+ //below wil not be exposed in future version..
+ UserState: otr.UserState,
+ //discourage use of MessageAppOps
+ //MessageAppOps : otr.MessageAppOps,
+ OTRChannel: OTRChannel
+ };
+ }
+}
+
+if(util && events) util.inherits(OTRChannel, events.EventEmitter);
function User( config ){
- this.name = config.name;
this.state = new otr.UserState();
this.keys = config.keys;
this.instags = config.instags;
@@ -88,7 +125,11 @@ User.prototype.writeFingerprints = function(){
}
function OTRChannel(user, context, parameters){
- events.EventEmitter.call(this);
+ if(events) {
+ events.EventEmitter.call(this);
+ }else{
+ this._events = {};
+ }
this.user = user;
this.context = context;
@@ -96,6 +137,29 @@ function OTRChannel(user, context, parameters){
this.ops = new otr.MessageAppOps( OtrEventHandler(this) );
}
+
+if(!events){
+ //simple events API for use in the browser
+ OTRChannel.prototype.on = function(e,cb){
+ //used to register callbacks
+ //store event name e in this._events
+ this._events[e] ? this._events[e].push(cb) : this._events[e]=[cb];
+
+ };
+ OTRChannel.prototype.emit = function(e){
+ //used internally to fire events
+ //'apply' event handler function to 'this' channel pass eventname 'e' and arguemnts.slice(1)
+ var self = this;
+ var args = Array.prototype.slice.call(arguments);
+
+ if(this._events && this._events[e]){
+ this._events[e].forEach(function(cb){
+ cb.apply(self,args.length>1?args.slice(1):[undefined]);
+ });
+ }
+ };
+}
+
OTRChannel.prototype.connect = function(){
return this.send("");
};
@@ -280,3 +344,7 @@ _otrl_msgevent=[
function OTRL_MSGEVENT(e){
return _otrl_msgevent[e];
}
+
+
+})(this);
+
View
1  src/footer.js
@@ -0,0 +1 @@
+}).call(this);
View
17 src/header.js
@@ -0,0 +1,17 @@
+;(function () {
+
+ var root = this;
+
+ if (typeof exports !== 'undefined'){
+
+ module.exports.getModule=function(){
+ return root.Module;
+ };
+
+ }else{
+ this.getModule = function(){
+ return root.Module;
+ }
+ }
+
+// -- code generated by emscripten will follow ---
View
7 src/otr_post.js
@@ -1,7 +0,0 @@
-var globalScope = this;
-
-if( typeof require !== "undefined" ){
- module.exports.getModule=function(){
- return globalScope.Module;
- }
-}
View
107 src/otr_pre.js
@@ -1,19 +1,14 @@
var Module = {};
Module["preRun"]=[];
-/*
-Module["InitOTR"] = function(ConnContext){
- Module["ConnContext"] = ConnContext;
-}
-*/
-//eliminate globals, hide them safely away from the closure compiler in
-//Module["hide_me_here"]={
-// "use double quotes":something()
-//};
Module["MPI_HOOK"] = {};
-Module["MPI_HOOK"]["BigInt"]= require("./bigint");
+if (typeof exports !== 'undefined') {
+ Module["MPI_HOOK"]["BigInt"]= require("./bigint");
+}else{
+ Module["MPI_HOOK"]["BigInt"] = this["BigInt"];
+}
/* emcc is generating this code when libgpg-error is compiled to js.. :(
__ATINIT__ = __ATINIT__.concat([
@@ -22,81 +17,34 @@ __ATINIT__ = __ATINIT__.concat([
*/
function _i32______gpg_err_init_to_void_____(){};//workaround.. TODO:investigate
-function __dump_profile(){
-}
-
-//wrap these in Module also?
var _static_buffer_ptr;
var _static_new_mpi_ptr_ptr;
var gcry_ = {};
var jsapi_ = {};
var otrl_ = {};
+var helper_ = {};
//todo:copy directly between memory and bigint array.. (faster than string conversions?..)
function __mpi2bigint(mpi_ptr){
-// console.log(">__mpi2bigint");
- /* if(inmpi2bigint){
- console.log("OH OH! recursive mpi2bigint!");
- process.exit();
- }
- inmpi2bigint=true;
-
- if(mpi_ptr==0) {
- console.log("mpi_ptr==0, in __mpi2bigint!");
- process.exit();
- }
- */
-// var buffer_ptr = _malloc(4);//char**
-// var nbytes_ptr = _malloc(4)//int*
var GCRYMPI_FMT_HEX = 4; //gcrypt.h: GCRYMPI_FMT_HEX = 4, /* Hex format. */
- //gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, unsigned char **buffer, size_t *nbytes, const gcry_mpi_t a)
- //console.log("calling gcry_mpi_aprint");
-// var err = ccall('gcry_mpi_aprint','number',['number','number','number','number'],[GCRYMPI_FMT_HEX,buffer_ptr,0,mpi_ptr]);
-
//gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, unsigned char *buffer, size_t buflen, size_t *nwritten, const gcry_mpi_t a)
- //var err = ccall('gcry_mpi_print','number',['number','number','number','number','number'],[GCRYMPI_FMT_HEX,_static_buffer_ptr,4096,0,mpi_ptr]);
var err = gcry_.mpi_print(GCRYMPI_FMT_HEX,_static_buffer_ptr,4096,0,mpi_ptr);
- //console.log("gcry_mpi_aprint returned:",err);
if(err) {
var strerr = gcry_.strerror(err);
console.log("error in gcry_mpi_aprint:",strerr);
process.exit();
}
-// var mpi_str_ptr = getValue(buffer_ptr,"i32");
var mpi_str_ptr = _static_buffer_ptr;
var mpi_str = Module['Pointer_stringify'](mpi_str_ptr);
-// console.log("MPI string converted:",mpi_str);
-// _free(buffer_ptr);
-// if(mpi_str_ptr>0) _free(mpi_str_ptr); //not our buffer to free? or should be freed with gcry_free ?
-// _free(nbytes_ptr);
-// inmpi2bigint = false;
return Module["MPI_HOOK"]["BigInt"]["str2bigInt"](mpi_str,16);
}
function __bigint2mpi(mpi_ptr,bi_num){
- // console.log(">__bigint2mpi");
-
- /*if(mpi_ptr==0) {
- console.log("mpi_ptr==0, in __bigint2mpi!");
- process.exit();
- }
- if(inbigint2mpi){
- console.log("OH OH! recursive bigint2mpi!");
- process.exit();
- }
- inbigint2mpi = true;
- */
- //convert bi_num to string.. and scan it into a new mpi using gcry_mpi_scan
- //copy/set the new mpi to mpi_ptr
- //var new_mpi_ptr_ptr = _malloc(4);//gcry_mpi_t*
var new_mpi_ptr_ptr = _static_new_mpi_ptr_ptr;
- //var nscanned_ptr = _malloc(4);//size_t*
var bi_num_str = Module["MPI_HOOK"]["BigInt"]["bigInt2str"](bi_num,16);
- // console.log("converting bi_num to mpi:",bi_num_str);
//gcry_error_t gcry_mpi_scan (gcry_mpi_t *r_mpi, enum gcry_mpi_format format, const unsigned char *buffer, size_t buflen, size_t *nscanned)
- //var err = ccall('gcry_mpi_scan','number',['number','number','string','number','number'],[new_mpi_ptr_ptr,4,bi_num_str,0,nscanned_ptr]);
var err = gcry_.mpi_scan(new_mpi_ptr_ptr,4,bi_num_str,0,0);
if(err){
var strerr = gcry_.strerror(err);
@@ -108,52 +56,35 @@ function __bigint2mpi(mpi_ptr,bi_num){
console.log("NULL scanned mpi in bigint2mpi()");
process.exit();
}
- //set new_mpi_ptr -> mpi_ptr
//gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u)
- //ccall('gcry_mpi_set','number',['number','number'],[mpi_ptr,new_mpi_ptr]);
-
- //todo check if mpi_ptr can store scanned_mpi.. otherwise expand it before we set
-
var same = gcry_.mpi_set(mpi_ptr,scanned_mpi_ptr);
- //TODO: make a custom scanner that doesn't malloc new mpi
+
gcry_.mpi_release(scanned_mpi_ptr);
if(same && same != mpi_ptr){
- //console.log("unexpected: gcry_mpi_set created a new mpi!");
- //process.exit();
return same;
- }
-
- //_free(new_mpi_ptr_ptr);
- //_free(nscanned_ptr);
-
- //inbigint2mpi = false;
+ }
}
Module['preRun'].push(function(){
Module["malloc"]=_malloc;
Module["free"]=_free;
+ Module["FS"]=FS;
- //select doesn't really have a place in a JS environment.. since i/o is non-blocking
+ //select doesn't really have a place in node environment.. since i/o is non-blocking
_select = (function() {
return 3;//this means all the three socket sets passed to the function are have sockets ready for reading.
});
- //Math.random = profile(Math.random);
- //if entropy is low.. it will significantly increase time for crypto keygen..
- //FS.createDevice("/dev/", "random", (function() {
Module['FS_createDevice']("/dev/","random",(function(){
- return Math.floor(Math.random() * 256);//just temporary.. need a platform specific implementation..
+ return Math.floor(Math.random() * 256);
}));
- //FS.createDevice("/dev/", "urandom", (function() {
Module['FS_createDevice']("/dev/","urandom",(function(){
return Math.floor(Math.random() * 256);
}));
console.error("created /dev/random and /dev/urandom devices.");
-// _static_buffer_ptr = _malloc(4096);//verify _malloc works with closure compiler
-// _static_new_mpi_ptr_ptr = _malloc(4);
_static_buffer_ptr = allocate(4096,"i8",ALLOC_STATIC);
_static_new_mpi_ptr_ptr = allocate(4,"i8",ALLOC_STATIC);
_static_otr_error_message_str = allocate(512,"i8",ALLOC_STATIC);
@@ -183,7 +114,7 @@ Module['preRun'].push(function(){
Module["libotrl"]["message_initiate_smp_q"]=otrl_.message_initiate_smp_q=cwrap('otrl_message_initiate_smp_q','',['number','number','number','number','string','string','number']);
Module["libotrl"]["message_initiate_smp"]=otrl_.message_initiate_smp=cwrap('otrl_message_initiate_smp','',['number','number','number','number','string','number']);
Module["libotrl"]["message_respond_smp"]=otrl_.message_respond_smp=cwrap('otrl_message_respond_smp','',['number','number','number','number','string','number']);
- //newly used add to exported functions!
+ //new in libotr4
Module["libotrl"]["message_abort_smp"]=otrl_.message_abort_smp=cwrap('otrl_message_abort_smp','',['number','number','number','number']);
Module["libotrl"]["message_receiving"]=otrl_.message_receiving=cwrap('otrl_message_receiving','number',['number','number','number','string','string','string','string','number','number','number','number','number']);
Module["libotrl"]["instag_generate"]=otrl_.instag_generate=cwrap('otrl_instag_generate','number',['number','string','string','string']);
@@ -207,12 +138,15 @@ Module['preRun'].push(function(){
Module["jsapi"]["conncontext_get_trust"]=jsapi_.conncontext_get_trust = cwrap('jsapi_conncontext_get_trust','string',['number']);
Module["jsapi"]["initialise"]=jsapi_.initialise = cwrap('jsapi_initialise');
Module["jsapi"]["messageappops_new"]=jsapi_.messageappops_new = cwrap('jsapi_messageappops_new','number');
- //new jsapi functions to add to exported_funcs
+ //new in libotr4
Module["jsapi"]["conncontext_get_their_instance"]=jsapi_.conncontext_get_their_instance = cwrap('jsapi_conncontext_get_their_instance','number',['number']);
Module["jsapi"]["conncontext_get_our_instance"]=jsapi_.conncontext_get_our_instance = cwrap('jsapi_conncontext_get_our_instance','number',['number']);
Module["jsapi"]["conncontext_get_master"]=jsapi_.conncontext_get_master = cwrap('jsapi_conncontext_get_master','number',['number']);
Module["jsapi"]["instag_get_tag"]=jsapi_.instag_get_tag = cwrap('jsapi_instag_get_tag','number',['number']);
+ Module["helper"]={};
+ Module["helper"]["mpi2bigint"] = helper_.mpi2bigint = __mpi2bigint;
+ Module["helper"]["bigint2mpi"] = helper_.bigint2mpi = __bigint2mpi;
if(true){
// some of the MPI calculations are slow
@@ -360,18 +294,13 @@ if(true){
int (*extra_check)(void *, gcry_mpi_t),
void *extra_check_arg);*/
_gen_prime = function BigInt_Prime(nbits,secretlevel,randomlevel,xtracheck,xtracheck_args){
- // console.log(">_gen_prime()");
var mpi_prime = gcry_.mpi_new ( nbits );
- //console.log(">gcry_.mpi_new(",nbits,") returned.");
for(;;){
var bi_prime = Module["MPI_HOOK"]["BigInt"]["randTruePrime"](nbits);
- //console.log(">BI.randTruePrime(",nbits,") returned.");
__bigint2mpi(mpi_prime,bi_prime);
- //if(xtracheck && jsapi_.docallback_prime_check(xtracheck,xtracheck_args,mpi_prime) ) {
if(xtracheck && FUNCTION_TABLE[xtracheck](xtracheck_args,mpi_prime)){
continue;//prime rejected!
}
- //console.log("returning from _gen_prime()");
return mpi_prime;
}
};
@@ -389,19 +318,15 @@ function __msgops_callback_smp_request($opdata,$context,$question){
Module["ops_event"]($opdata, obj, "smp_request");
}
function __msgops_callback_smp_failed($opdata,$context){
- //console.log("__msgops_callback_smp_failed");
Module["ops_event"]($opdata, (new Module["ConnContext"]($context))["obj"](),"smp_failed");
}
function __msgops_callback_smp_aborted($opdata,$context){
- //console.log("__msgops_callback_smp_aborted");
Module["ops_event"]($opdata, (new Module["ConnContext"]($context))["obj"](),"smp_aborted");
}
function __msgops_callback_smp_complete($opdata,$context){
- //console.log("__msgops_callback_smp_compelte");
Module["ops_event"]($opdata, (new Module["ConnContext"]($context))["obj"](),"smp_complete");
}
function __msgops_callback_smp_error($opdata,$context){
- //console.log("__msgops_callback_smp_error");
Module["ops_event"]($opdata, (new Module["ConnContext"]($context))["obj"](),"smp_error");
}
View
23 test/index.html
@@ -0,0 +1,23 @@
+<html lang="en">
+ <head>
+ <title>OTR4-em</title>
+ <script>
+ var process = {
+ exit:function(){},
+ argv: []
+ };
+ </script>
+ <script src="../lib/async.js"></script>
+ <script src="../lib/seedrandom.js"></script>
+ <script src="../lib/bigint.js"></script>
+ <script src="../lib/libotr4.js"></script>
+ <script src="../lib/libotr-js-bindings.js"></script>
+ <script src="../lib/otr-module.js"></script>
+ </head>
+ <body>
+ <script>
+ document.write( "OTR_VERSION:" + OTR.version() );
+ </script>
+ <script src="index.js"></script>
+ </body>
+</html>
View
64 test/index.js
@@ -1,21 +1,41 @@
-var async = require("../lib/async");
-var libotr = require('../lib/otr-module');
+if(typeof exports !== 'undefined'){
+ var async = require("../lib/async");
+ var OTR = require("../lib/otr-module");
+}
-console.log("== loaded libotr version:",libotr.version());
+var otr = OTR;
+
+console.log("== loaded libotr version:",otr.version());
-var TEST_PASSED=false;
var debug = function(){};
-process.argv.forEach(function(arg){
- if(arg=="--verbose"){
- libotr.debugOn();
- debug = console.error;
- }
-});
+var USE_VFS = false;
+var TEST_PASSED=false;
+var verbose =false;
+var FORCE_SMP = false;
+var SUCCESSFULL_SMP = false;
+
+if(typeof process !== "undefined" ){
+ process.argv.forEach(function(arg){
+ if(arg=="--verbose") verbose = true;
+ if(arg=="--vfs") USE_VFS=true;
+ if(arg=="--force-smp") FORCE_SMP=true;
+ });
+}
+
+if(verbose){
+ otr.debugOn();
+ debug = console.error;
+}
+
+if(USE_VFS){
+ var VFS = otr.VFS(__dirname+"/default.vfs").load();
+}
-var keys_dir = "";
+var keys_dir = ".";
-var alice = new libotr.User({name:'alice',keys:keys_dir+'/alice.keys',fingerprints:keys_dir+'/alice.fp',instags:keys_dir+'/alice.instags'});
+var alice = new otr.User({name:'alice',keys:keys_dir+'/alice.keys',fingerprints:keys_dir+'/alice.fp',instags:keys_dir+'/alice.instags'});
+if(!alice.state.fingerprint("alice@telechat.org","telechat")){
alice.generateKey("alice@telechat.org","telechat",function(err){
if(err){
console.error("error generating key:",err);
@@ -26,11 +46,12 @@ alice.generateKey("alice@telechat.org","telechat",function(err){
alice.generateInstag("alice@telechat.org","telechat",function(err,instag){
console.log("generating instance tag: error=",err," tag=",instag);
});
+}
var BOB = alice.ConnContext("alice@telechat.org","telechat","BOB");
-var otrchan_a = new libotr.OTRChannel(alice, BOB,{policy:libotr.POLICY("DEFAULT"),secret:'s3cr37'});
-
-var bob = new libotr.User({name:'bob',keys:keys_dir+'/bob.keys',fingerprints:keys_dir+'/bob.fp',instags:keys_dir+'/bob.instags'});
+var otrchan_a = new otr.OTRChannel(alice, BOB,{policy:otr.POLICY("ALWAYS"),secret:'s3cr37'});
+var bob = new otr.User({name:'bob',keys:keys_dir+'/bob.keys',fingerprints:keys_dir+'/bob.fp',instags:keys_dir+'/bob.instags'});
+if(!bob.state.fingerprint("bob@telechat.org","telechat")){
bob.generateKey("bob@telechat.org","telechat",function(err){
if(err){
console.error("error generating key:",err);
@@ -41,8 +62,9 @@ bob.generateKey("bob@telechat.org","telechat",function(err){
bob.generateInstag("bob@telechat.org","telechat",function(err,instag){
console.log("generating instance tag: error=",err," tag=",instag);
});
+}
var ALICE = bob.ConnContext("bob@telechat.org","telechat","ALICE");
-var otrchan_b = new libotr.OTRChannel(bob, ALICE,{policy:libotr.POLICY("DEFAULT"),secret:'s3cr37'});
+var otrchan_b = new otr.OTRChannel(bob, ALICE,{policy:otr.POLICY("ALWAYS"),secret:'s3cr37'});
var NET_QUEUE_A = async.queue(handle_messages,1);
var NET_QUEUE_B = async.queue(handle_messages,1);
@@ -100,7 +122,7 @@ otrchan_a.on("remote_disconnected",function(){
otrchan_a.on("gone_secure",function(){
- if(!this.isAuthenticated()){
+ if(!this.isAuthenticated() || FORCE_SMP ){
console.log("Alice initiating SMP authentication to verify keys...");
otrchan_a.start_smp();
}
@@ -114,6 +136,7 @@ otrchan_b.on("smp_request",function(){
otrchan_a.on("smp_complete",function(){
otrchan_a.send("Hello Bob! - 2");
+ SUCCESSFULL_SMP = true;
});
//otrchan_a.connect();
otrchan_a.send("Hello Bob! - 1");
@@ -122,7 +145,10 @@ otrchan_a.send("Hello Bob! - 1");
var loop = setInterval(function(){
console.log("_");
- if(otrchan_a.isEncrypted() && otrchan_a.isAuthenticated()){
+ if(FORCE_SMP && !SUCCESSFULL_SMP){
+ return;
+ }
+ if(otrchan_a.isEncrypted() && otrchan_a.isAuthenticated() && otrchan_b.isEncrypted() && otrchan_b.isAuthenticated()){
console.log("Finger print verification successful");
dumpConnContext(otrchan_a,"Alice's ConnContext:");
dumpConnContext(otrchan_b,"Bob's ConnContext:");
@@ -135,9 +161,11 @@ var loop = setInterval(function(){
function exit_test(msg){
console.log(msg);
if(TEST_PASSED){ console.log("== TEST PASSED ==\n"); } else { console.log("== TEST FAILED ==\n"); }
+ if(VFS) VFS.save();
process.exit();
}
function dumpConnContext(chan,msg){
console.log(msg,"\n",chan.context.obj());
}
+
Please sign in to comment.
Something went wrong with that request. Please try again.