OTR4 - Off-the-Record Messaging
=====================

This is the documentation for old API, for npm module "otr4" version 0.0.5

## Getting started

Require the otr4 module (underlying gcrypt and otr libraries will be
initialised. 

    var otr = require("otr4");
    
## otr.version()
Returns version information of the underlying libotr:

     console.log("Using version:", otr.version() );

## otr.User( config )
The User object is used to manage a user's accounts (public keys) and known fingerprints.

    var otr = require("otr4");
    
    var user = new otr.User({ 
        keys:'/alice.keys',      //path to OTR keys file (required)
        fingerprints:'/alice.fp' //path to fingerprints file (required)
        instags:'/alice.instags' //path to instance tags file (required)
    });

All data is loaded in memory (UserState) and persisted on the file system.

If specified files exist the keys, fingerprints and instance tags will be loaded automatically.
A warning will be logged to the console otherwise.

### user.accounts()

We can check what accounts have been load..

    user.accounts().forEach(function(account){
        console.log(account.fingerprint);
    });

	[ { accountname: 'alice@jabber.org',
	    protocol: 'xmpp',
	    fingerprint: '65D366AF CF9B065F 41708CB0 1DC26F61 D3DF5935',
	    privkey: [Object] } ]

### user.generateKey(accountname,protocol,function (err,privkey) )

To generate an OTR key for a given accountname and protocol:
(If a key already exists it will be overwritten)

    user.generateKey("alice@jabber.org", "xmpp", function(err, privkey){
        if(err){
        	console.log("something went wrong!",err.message);
        }else{
        	console.log("Generated Key Successfully:",privkey.exportPublic() );
        }
    });

### user.generateInstag(accountname,protocol, function(err,instag) )
Creating an instance tag for account/protocol:

   alice.generateInstag("alice@jabber.org","xmpp",function(err,instag){
        if(err){
            console.log("failed to generate instance tag.",err);
        }else{
            console.log("new instance tag:",instag);
        }
   });
   
### user.fingerprint(accountname,protocol)

To retreive the fingerprint of a key:

	user.fingerprint("alice@jabber.org","xmpp");

returns

	'65D366AF CF9B065F 41708CB0 1DC26F61 D3DF5935'

### user.findKey(accountname,protocol)
Returns a PrivateKey() instance if it exists. (null otherwise)
	
	var privkey = user.findKey("alice@jabber.org","xmpp");

### user.deleteKey(accountname,protocol)
Deleted a key from memory and file if it exists.

### user.ConnContext(accountname, protocol, buddy_name)
Create a ConnContext(). accountname and protocol will select the key to use in this context, and buddy_name 
is our chosen name for the remote party which is stored in the fingerprints file.

### user.writeFingerprints()
Writes fingerprints out to file.

### user.writeKeys()
Writes keys out to file.

### user.prototype.exportKeyHex(accountname,protocol)
Exports the DSA key for the account/protocol. (Can be imported to another User using user.importKey())

### user.prototype.exportKeyBigInt(accountname,protocol)
Exports the DSA key for the account/protocol. (Can be imported to another User using user.importKey())

### user.prototype.importKey(accountname,protocol,dsa)
Will import a DSA key (exported using user.exportKeyHex or user.exportBigInt) and assign it to accountname/protocol.

## PrivateKey()
This is the 'privkey' object returned by user.findKey() and in the callback of user.accounts() and user.generateKey().

**privkey.accountname()** - Accountname the key is associated with.

**privkey.protocol()** - Protocol the key is associated with.

**privkey.export(format)** - Exports the private DSA key. format can be "HEX" or "BIGINT"

**privkey.exportPublic(format)** - Exports only the public components of the DSA key. format can be "HEX" or "BINGINT"


## otr.ConnContext()
A ConnContext with buddy 'BOB' is created from a User() object. The last argument is
our selected name for buddy Bob.

    var context = user.ConnContext("alice@jabber.org","xmpp","BOB");

To get the state of a ConnContext:

**context.protocol()**

returns string: protocol name

**context.username()**

return string: name we have given to buddy "BOB"

**context.accountname()**

return string: account name of the otr key, eg. "alice@jabber.org"

**context.fingerprint()**

return string: fingerprint of buddy in an active Session()

**context.protocol_version()**

return number: otr protocol version in use, eg. 3

**context.msgstate()**

returns number: 0 = plaintext, 1 = encrypted

**context.smstate()**

returns number: current state of the SMP (Socialist Millionaire's Protocol)

**context.trust()**

returns string: 'smp' if buddy's fingerprint has been verified by SMP.

**context.their_instance()**

returns number: instance tag of buddy

**context.our_instance()**

returns number: our instance tag


## otr.Session()

To setup an OTR conversation with a buddy, create a Session(). As arguments
it takes a User, ConnContext, and a set of parameters for the session. Session instances
are event emitters.

###Setting up a Session()###

    var session = new otr.Session(user, context, {
        policy: otr.POLICY("ALWAYS"), //optional policy - default = otr.POLICY("DEFAULT")
        MTU: 5000,          //optional - max fragment size in bytes - default=0,no-fragmentation
        secret: "SECRET",   //secret for SMP authentication.                           
        secrets: {'question-1':'secret-1',
                  'question-2':'secret-2'} //questions,answers pairs for SMP Authentication.
    });

### Starting and Ending an OTR conversation

**session.connect()**

Initiates the otr protocol. This can be used if we wish to initiate the protocol without sending an actual message.

**session.close()**

End the session.

###Exchanging Messages

**session.send(message,[instag])**

Fragment and send message.toString(). Optional instag can be specified.

**session.recv(message)**

Should be called when receiving a message from buddy.

###Authenticating with SMP (Socialist Millionaire's Protocol)

**session.start_smp([secret])**

Starts SMP authentication. If otional [secret] is not passed it is taken from the parameters.

**session.start_smp_question(question,[secret])**

Starts SMP authentication with a question and optional [secret]. If secret is not passed 
it is taken from the parameters.

**session.respond_smp([secret])**

Responds to SMP authentication request with optional [secret]. If secret is not passed 
it is taken from the parameters.

### State of a Session

**session.isEncrypted()**

True only if current session is encrypted.

**session.isAuthenticated()**

True only if the fingerprint of the buddy has been authenticated/verified by SMP.

### Handling Session events

* message(msg, encrypted) - received message **msg**. If message was encrypted **encrypted** will be true. 

* inject_message(msg_fragment) - encrypted msg_fragment to be sent to buddy

* gone_secure() - message exchange is now encrypted.
* still_secure() - encryption re-negotiated. message exchange is encrypted.

* create_privkey(accountname,protocol) - a private key for account/protocol specified was not found and needs to be created.
* create_instag(accountname,protocol) - an instance tag for account/protocol specified was not found and needs to be created.
* new_fingerprint(fingerprint) - first time we are seeing remote buddy's fingerprint. This is a que to begin authentication. 'gone_secure' fire immediately after.

* smp_request(question) - buddy has started a SMP authentication. (possibly with a question)
* smp_complete() - SMP authentication completed successfully.
* smp_failed() - SMP failed (usually buddy doesn't know the secret)
* smp_aborted() - SMP (something went wrong at the protocol level)

* remote_disconnected() - channel closed() [remotely]
* update_context_list() - fired when underlying ConnContext changes (inteded mostly for UI updates)
* shutdown() - channel was closed [locally]

* msg_event(event_no, message, err) - event_no, message if appropriate and an err if any.
* received_symkey(use_num, usedata_buff, key_buff) - buddy wants to use the current extra symmetric key.
buddy has sent additional use information and use-specific data in **use_num** (number) and **usedata_buff** (ArrayBuffer).
**key_buff** is the 32-byte ArrayBuffer() holding the synchronised symmetric key.

## otr.MSGEVENT(event_number)
Returns one of the corresponding event names below of event_number

    NONE
    ENCRYPTION_REQUIRED
    ENCRYPTION_ERROR
    CONNECTION_ENDED
    SETUP_ERROR
    MSG_REFLECTED
    MSG_RESENT
    RCVDMSG_NOT_IN_PRIVATE
    RCVDMSG_UNREADABLE
    RCVDMSG_MALFORMED
    LOG_HEARTBEAT_RCVD
    LOG_HEARTBEAT_SENT
    RCVDMSG_GENERAL_ERR
    RCVDMSG_UNENCRYPTED  //'message' event will also be fired with encrypted parameter = false
    RCVDMSG_UNRECOGNIZED
    RCVDMSG_FOR_OTHER_INSTANCE

## otr.POLICY(name)

The policy is used as a parameter when setting up a Session().

    var otr = require("otr4");
    var policy = otr.POLICY("DEFAULT");

    //available policies
    NEVER
    ALLOW_V1
    ALLOW_V2
    ALLOW_V3
    REQUIRE_ENCRYPTION
    SEND_WHITESPACE_TAG
    WHITESPACE_START_AKE
    ERROR_START_AKE
    VERSION_MASK
    OPPORTUNISTIC
    MANUAL
    ALWAYS
    DEFAULT
