Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Off-the-Record Messaging Protocol implemented in JavaScript

Fetching latest commit…

Cannot retrieve the latest commit at this time

readme.md

Off-the Record Messaging Protocol in JavaScript

Build Status


Warning

This library hasn't been properly vetted by security researchers. Do not use in life and death situations!

Math.random() is replaced by seedrandom.js, seeded with either window.crypto.getRandomValues() in the browser, or crypto.randomBytes() in node.js.


Install

Include the build files on the page,

<!-- Load dependencies -->
<script src="build/dep/seedrandom.js"></script>
<script src="build/dep/bigint.js"></script>
<script src="build/dep/crypto.js"></script>

<!-- Load otr.js or otr.min.js -->
<script src="build/otr.min.js"></script>

Here's an example use in the browser.

Although this is a client library, it can be used on the server.

npm install otr

And then,

var DSA = require('otr').DSA
var OTR = require('otr').OTR

Usage

Initial setup: Compute your long-lived key beforehand. Currently this is expensive and can take several seconds.

// precompute your DSA key
var myKey = new DSA()

For each user you're communicating with, instantiate an OTR object.

// provide some callbacks to otr
var uicb = function (msg) {
  console.log("message to display to the user: " + msg)
}
var iocb = function (msg) {
  console.log("message to send to buddy: " + msg)
}

// provide options
var options = {
    fragment_size: 140  // fragment the message in case of char limits
  , send_interval: 200  // ms delay between sending fragmented msgs, avoid rate limits
}

var buddyList = {
    'userA': new OTR(myKey, uicb, iocb, options)
  , 'userB': new OTR(myKey, uicb, iocb, options)
}

New message from userA received: Pass the received message to the receiveMsg method.

var rcvmsg = "Message from userA."
buddyList.userA.receiveMsg(rcvmsg)

Send a message to userA: Pass the message to the sendMsg method.

var newmsg = "Message to userA."
buddyList.userA.sendMsg(newmsg)

Going encrypted: Initially, messages are sent in plaintext. To manually initiate the authenticated key exchange.

buddyList.userA.sendQueryMsg()

Alternatively, one can set the policy REQUIRE_ENCRYPTION and send a plaintext message. This will store the message, initiate the authentication and then, upon success, send it out.

buddyList.userA.REQUIRE_ENCRYPTION = true
buddyList.userA.sendMsg('My plaintext message to be encrypted.')

Another policy, SEND_WHITESPACE_TAG, will append tags to plaintext messages, indicating a willingness to speak OTR. If the recipient in turn has set the policy WHITESPACE_START_AKE, the AKE will be initiated.


Policies

To be set on a per-correspondent basis. The defaults are as follows:

// Allow version 2 or 3 of the OTR protocol to be used.
ALLOW_V2 = true
ALLOW_V3 = true

// Refuse to send unencrypted messages.
REQUIRE_ENCRYPTION = false

// Advertise your support of OTR using the whitespace tag.
SEND_WHITESPACE_TAG = false

// Start the OTR AKE when you receive a whitespace tag.
WHITESPACE_START_AKE = false

// Start the OTR AKE when you receive an OTR Error Message.
ERROR_START_AKE = false

Instance Tags

These are intended to be persistent and can be precomputed.

var myTag = OTR.makeInstanceTag()
var options = { instance_tag: myTag }

var userA = new OTR(myKey, uicb, iocb, options)
var userB = new OTR(myKey, uicb, iocb, options)

Fingerprints

OTR public key fingerprints can be obtained as follows:

// assume you've gone through the ake with userA
var userA = new OTR(myKey, uicb, iocb, options)

// for my key, either one of the following
myKey.fingerprint()
// or,
userA.priv.fingerprint()

// for their key
userA.their_priv_pk.fingerprint()

Links

Spec:

Using:


In The Wild

A sampling of projects that use this library:


License

LGPL. Mainly because that's what libotr is using.

Something went wrong with that request. Please try again.