Giter Club home page Giter Club logo

libsignal-protocol-javascript's Introduction

Deprecation Warning: It is recommended that the TypeScript interface of libsignal-client be used for all new applications. This library is no longer used by us or maintained.

libsignal-protocol-javascript

Build Status

Signal Protocol implementation for the browser based on libsignal-protocol-java.

/dist       # Distributables
/build      # Intermediate build files
/src        # JS source files
/native     # C source files for curve25519
/protos     # Protobuf definitions
/test       # Tests

Overview

A ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments.

PreKeys

This protocol uses a concept called 'PreKeys'. A PreKey is an ECPublicKey and an associated unique ID which are stored together by a server. PreKeys can also be signed.

At install time, clients generate a single signed PreKey, as well as a large list of unsigned PreKeys, and transmit all of them to the server.

Sessions

Signal Protocol is session-oriented. Clients establish a "session," which is then used for all subsequent encrypt/decrypt operations. There is no need to ever tear down a session once one has been established.

Sessions are established in one of two ways:

  1. PreKeyBundles. A client that wishes to send a message to a recipient can establish a session by retrieving a PreKeyBundle for that recipient from the server.
  2. PreKeySignalMessages. A client can receive a PreKeySignalMessage from a recipient and use it to establish a session.

State

An established session encapsulates a lot of state between two clients. That state is maintained in durable records which need to be kept for the life of the session.

State is kept in the following places:

  • Identity State. Clients will need to maintain the state of their own identity key pair, as well as identity keys received from other clients.
  • PreKey State. Clients will need to maintain the state of their generated PreKeys.
  • Signed PreKey States. Clients will need to maintain the state of their signed PreKeys.
  • Session State. Clients will need to maintain the state of the sessions they have established.

Requirements

This implementation currently depends on the presence of the following types/interfaces, which are available in most modern browsers.

Usage

Include dist/libsignal-protocol.js in your webpage.

Install time

At install time, a libsignal client needs to generate its identity keys, registration id, and prekeys.

var KeyHelper = libsignal.KeyHelper;

var registrationId = KeyHelper.generateRegistrationId();
// Store registrationId somewhere durable and safe.

KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
    // keyPair -> { pubKey: ArrayBuffer, privKey: ArrayBuffer }
    // Store identityKeyPair somewhere durable and safe.
});

KeyHelper.generatePreKey(keyId).then(function(preKey) {
    store.storePreKey(preKey.keyId, preKey.keyPair);
});

KeyHelper.generateSignedPreKey(identityKeyPair, keyId).then(function(signedPreKey) {
    store.storeSignedPreKey(signedPreKey.keyId, signedPreKey.keyPair);
});

// Register preKeys and signedPreKey with the server

Building a session

A libsignal client needs to implement a storage interface that will manage loading and storing of identity, prekeys, signed prekeys, and session state. See test/InMemorySignalProtocolStore.js for an example.

Once this is implemented, building a session is fairly straightforward:

var store   = new MySignalProtocolStore();
var address = new libsignal.SignalProtocolAddress(recipientId, deviceId);

// Instantiate a SessionBuilder for a remote recipientId + deviceId tuple.
var sessionBuilder = new libsignal.SessionBuilder(store, address);

// Process a prekey fetched from the server. Returns a promise that resolves
// once a session is created and saved in the store, or rejects if the
// identityKey differs from a previously seen identity for this address.
var promise = sessionBuilder.processPreKey({
    registrationId: <Number>,
    identityKey: <ArrayBuffer>,
    signedPreKey: {
        keyId     : <Number>,
        publicKey : <ArrayBuffer>,
        signature : <ArrayBuffer>
    },
    preKey: {
        keyId     : <Number>,
        publicKey : <ArrayBuffer>
    }
});

promise.then(function onsuccess() {
  // encrypt messages
});

promise.catch(function onerror(error) {
  // handle identity key conflict
});

Encrypting

Once you have a session established with an address, you can encrypt messages using SessionCipher.

var plaintext = "Hello world";
var sessionCipher = new libsignal.SessionCipher(store, address);
sessionCipher.encrypt(plaintext).then(function(ciphertext) {
    // ciphertext -> { type: <Number>, body: <string> }
    handle(ciphertext.type, ciphertext.body);
});

Decrypting

Ciphertexts come in two flavors: WhisperMessage and PreKeyWhisperMessage.

var address = new SignalProtocolAddress(recipientId, deviceId);
var sessionCipher = new SessionCipher(store, address);

// Decrypt a PreKeyWhisperMessage by first establishing a new session.
// Returns a promise that resolves when the message is decrypted or
// rejects if the identityKey differs from a previously seen identity for this
// address.
sessionCipher.decryptPreKeyWhisperMessage(ciphertext).then(function(plaintext) {
    // handle plaintext ArrayBuffer
}).catch(function(error) {
    // handle identity key conflict
});

// Decrypt a normal message using an existing session
var sessionCipher = new SessionCipher(store, address);
sessionCipher.decryptWhisperMessage(ciphertext).then(function(plaintext) {
    // handle plaintext ArrayBuffer
});

Building

To compile curve25519 from C source files in /native, install emscripten.

grunt compile

License

Copyright 2015-2018 Open Whisper Systems

Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html

libsignal-protocol-javascript's People

Contributors

dag0310 avatar jimio-signal avatar lacivert avatar liliakai avatar scottnonnenberg avatar scottnonnenberg-signal avatar tcyrus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libsignal-protocol-javascript's Issues

Webclient

Hi together :)

I am glad there there is a JS library for signal protocol, but wondered why there is no web reference client. (I know desktop client which is wrapped in electron, or better was) ...

But it would be so much easier with a webclient. Could you enlighten me, why there is no web client?

Best regards
Gino

Error running tests

After successfully running grunt compile / grunt build, I try to run the tests with grunt test, but see the following

Running "jshint:files" (jshint) task
>> 15 files lint free.

Running "jscs:all" (jscs) task
>> 15 files without code style errors.

Running "connect:server" (connect) task
Started connect web server on http://0.0.0.0:9998

Running "saucelabs-mocha:all" (saucelabs-mocha) task
=> Starting Tunnel to Sauce Labs
=> Stopping Tunnel to Sauce Labs
>> 
>> Error closing tunnel

Do contributors need to create a Sauce Labs account to run the tests? Or is something else at play?

Possibilities for secure storage in the Browser

Thanks for your great work on this library and with Signal in general! :)

I have a question regarding the storage interface.
In the documentation, it's stated that any store that implements the interface of test/InMemorySignalProtocolStore.js should work. So far so good.

Now my question is, regarding Browser environments, are there ways to securely store e.g. the keys in the browser? IndexDB/SessionStorage/LocalStorage seem unfit for this purpose because of XSS. I can't think of a secure, persistent way to store sensitive session-based information in the Browser.

Am I missing something here? And if there is a way to do this securely in a real-world scenario, I think it would be nice if it were documented here as well - at least with a link to a solution / proof of concept.

Why doesn't keyId accept strings?

A uuid has a much stronger uniqueness guarantee than a randomly generated integer.

In fact, the public key itself has a much stronger uniqueness guarantee - which makes the keyId seem entirely superfluous.

Error -1 previous counter

Sometimes when sending a message it will send -1 as the previous counter which, when encoded as a uint32 gets sent as 4294967295. This triggers the this error: Over 2000 messages into the future!

Error Running Tests

While putting together #48, I noticed I was unable to run any of the tests by connecting to sauce labs.

I get the following error:

screen shot 2018-05-10 at 9 32 47 pm

Has anyone seen this recently?

React Native support

Hey, I'm currently investigating using the library in a react native app. The JavaScriptCore runtime on iOS does not surface the WebCrypto apis though, so I'd have to create react native plugins that shim WebCrypto using native crypto primitives. I'm curious if you'd be open to accepting a PR that integrates this use case. Thanks

Unable to decrypt message sent by same user

We are using https://github.com/WhisperSystems/libsignal-protocol-javascript in our chat application to encrypt messages end to end. We have an use case where we want to store encrypted messages on the server and retrieve them in the chat app.

In order to display the messages in the chat interface, we need to decrypt them. We are able to decrypt the messages the user received but not the messages which were sent by the user.

It is looking for the private key of the receiving user during decryption which is not available. Can you let us know if we are doing something wrong, can you help us resolve the issue.

Ionic/Angular Support

I am trying to use this library for ionic application, can you please provide a support for that. I am unable to integrate this in angular

Potential bug in InMemorySignalProtocolStore

On line 41, isTrustedIdentity returns TRUE if the identity is not found.

https://github.com/WhisperSystems/libsignal-protocol-javascript/blob/master/test/InMemorySignalProtocolStore.js#L41

Either
a) this is a typo, and this function should reject unknown identities
b) there is no typo, and this is a "pinning" function that trusts all NEW identities and only rejects on id/key mismatch

Can you please clarify which is correct? The unit tests do not indicate which behaviour is expected in this scenario:

https://github.com/WhisperSystems/libsignal-protocol-javascript/blob/master/test/IdentityKeyStore_test.js#L35

The wording of the error messages in lines 13 and 61 of SessionBuilder don't really make it clear either:

https://github.com/WhisperSystems/libsignal-protocol-javascript/blob/master/src/SessionBuilder.js#L13
https://github.com/WhisperSystems/libsignal-protocol-javascript/blob/master/src/SessionBuilder.js#L61

IS THIS REPO STILL MANAGED

I'm trying to figure out if this repo is still managed?

Your documentation is all over the place and seems to declare variables out of no where.

On Install:

"server" not defined - what "server" are you referring to? A node server? A server somewhere else?
"keyId" not defined - WTF did this come from? Just out of thin air?
"store" not defined - WTF did this come from? Just out of thin air?

Is this the official signal protocol or a knockoff?

Why is your documentation so unclear? Is this on purpose?

Error: Bad MAC

I tried to write code to encrypt and decrypt the message. But every time I get an error Error: Bad MAC at libsignal-protocol.js:35296. Here is my code. Tell me please, what's wrong?

const generateKeys = async (preKeyId, signedPreKeyId) => {
    const keys = {};

    const keyHelper = libsignal.KeyHelper;

    const registrationId = await keyHelper.generateRegistrationId();
    keys.registrationId = registrationId;

    const identityKeyPair = await keyHelper.generateIdentityKeyPair();
    keys.identityKeyPair = identityKeyPair;

    const preKey = await keyHelper.generatePreKey(preKeyId);
    keys.preKey = preKey;

    const signedPreKey = await keyHelper.generateSignedPreKey(keys.identityKeyPair, signedPreKeyId);
    keys.signedPreKey = signedPreKey;

    return keys;
};

const serverStorage = {};

const aliceRecipientId = 1;
const aliceDeviceId = '053289b8-e0dd-11e7-a7c1-02420a00000b';
const aliceStorage = new SignalProtocolStore();

const bobRecipientId = 2;
const bobDeviceId = '053289b8-e0dd-11e7-a7c1-02420a000001';
const bobStorage = new SignalProtocolStore();

Promise.all([generateKeys(1, 2), generateKeys(3, 4)])
    // Alice and Bob initialize web clients
    .then(results => {
        console.log('Alice stores keys in the secure local storage');
        aliceStorage.put('identityKey', results[0].identityKeyPair);
        aliceStorage.put('registrationId', results[0].registrationId);
        aliceStorage.storePreKey(results[0].preKey.keyId, results[0].preKey.keyPair);
        aliceStorage.storeSignedPreKey(results[0].signedPreKey.keyId, results[0].signedPreKey.keyPair);

        console.log('Alice sends public pre keys to the server');
        serverStorage.alice = {
            identityKey: results[0].identityKeyPair.pubKey,
            signedPreKey: {
                keyId: results[0].signedPreKey.keyId,
                publicKey: results[0].signedPreKey.keyPair.pubKey,
                signature: results[0].signedPreKey.signature,
            },
            preKey: {
                keyId: results[0].preKey.keyId,
                publicKey: results[0].preKey.keyPair.pubKey,
            }
        };

        console.log('Bob stores keys in the secure local storage');
        bobStorage.put('identityKey', results[1].identityKeyPair);
        bobStorage.put('registrationId', results[1].registrationId);
        bobStorage.storePreKey(results[1].preKey.keyId, results[0].preKey.keyPair);
        bobStorage.storeSignedPreKey(results[1].signedPreKey.keyId, results[1].signedPreKey.keyPair);

        console.log('Bob sends public pre keys to the server');
        serverStorage.bob = {
            identityKey: results[1].identityKeyPair.pubKey,
            signedPreKey: {
                keyId: results[1].signedPreKey.keyId,
                publicKey: results[1].signedPreKey.keyPair.pubKey,
                signature: results[1].signedPreKey.signature,
            },
            preKey: {
                keyId: results[1].preKey.keyId,
                publicKey: results[1].preKey.keyPair.pubKey,
            }
        };
    })
    // Alice tries to create session with Bob to send a message
    .then(() => {
        console.log("Alice gets Bob's public pre keys from the server");
        const bobPublicPreKeys = serverStorage.bob;
        const bobAddress = new libsignal.SignalProtocolAddress(bobDeviceId, bobRecipientId);

        console.log('Alice creates session with Bob');
        const aliceSessionBuilder = new libsignal.SessionBuilder(aliceStorage, bobAddress);

        // Process a prekey fetched from the server.
        // Returns a promise that resolves once a session is created and saved
        // in the store, or rejects if the identityKey differs from a previously
        // seen identity for this address.
        return aliceSessionBuilder.processPreKey({
            registrationId: aliceStorage.getLocalRegistrationId(),
            identityKey: bobPublicPreKeys.identityKey,
            signedPreKey: bobPublicPreKeys.signedPreKey,
            preKey: bobPublicPreKeys.preKey,
        });
    })
    // Alice tries to encrypt and send a message to Bob
    .then(() => {
        console.log('Alise encrypts new message');
        const bobAddress = new libsignal.SignalProtocolAddress(bobDeviceId, bobRecipientId);
        const aliceSessionCipher = new libsignal.SessionCipher(aliceStorage, bobAddress);
        const message = util.toArrayBuffer('Hello Bob!');
        // const message = 'Hello Bob!';
        return aliceSessionCipher.encrypt(message).then(ciphertext => {
            console.log('ciphertext', ciphertext);
            console.log('Alice sends encrypted message to Bob');
            // sourceDevice, destinationDevice, ciphertext
            return ciphertext;
        });
    })
    // Bob receives the encrypted message from the server
    .then(ciphertext => {
        console.log('Bob gets encrypted message from the server');
        const aliceAddress = new libsignal.SignalProtocolAddress(aliceDeviceId, aliceRecipientId);
        const bobSessionCipher = new libsignal.SessionCipher(bobStorage, aliceAddress);

        if (ciphertext.type === 3) { // PREKEY_BUNDLE
            // Decrypt a PreKeyWhisperMessage by first establishing a new session.
            // Returns a promise that resolves when the message is decrypted or
            // rejects if the identityKey differs from a previously seen identity for this
            // address.
            bobSessionCipher.decryptPreKeyWhisperMessage(ciphertext.body, 'binary')
                .then(plaintext => {
                    console.log('decrypted message', plaintext);
                }).catch(error => {
                    console.log('decrypted error', error);
                });
        } else {
            bobSessionCipher.decryptWhisperMessage(ciphertext.body, 'binary')
                .then(plaintext => {
                    console.log('decrypted message', plaintext);
                }).catch(error => {
                    console.log('decrypted error', error);
                });
        }
    })
    .catch(error => {
        console.log('error', error);
    });

Group Code is MIssing

As we have Group Code in libsignal-protocol-java for
GroupCipher
GroupSessionBuidler
When we will have it for javascript

SessionCipher::encrypt setting wrong registrationId?

I believe there is an error when building the message to be sent in SessionCipher::encrypt.

registrationId : session.registrationId
and
registrationId : session.registrationId

set the registrationId of the message to be posted. This should be the sender's ID, and the ID in the session is, AFAIK, always the remote ID, which in this case is the recipient. So I think these lines should be using the value myRegistrationId like in
preKeyMsg.registrationId = myRegistrationId;

Or am I just missing something?

Simultaneous session initialization

When 2 peers try to establish sessions with each other at the same time, they can end up with different sessions and unable to decrypt each others messages.

Scenario:
Alice creates a session from Bobs bundle. Bob does the same with Alice's bundle.
Alice receives a PreKeyWhisperMessage from Bob and processes it. This will then overwrite the previous session in Alice's store.
Bob also receives a PreKeyWhisperMessage from Alice and processes it. This will overwrite the previous session in Bob's store.

The end result is that Alice has a session to Bob that was initialized by Bob and Bob has a session to Alice that was initialized by Alice. Because they were established using different one time pre keys they are unable to exchange any messages other than what is in the PreKeyWhisperMessage ciphertext.

Encryption of Media Files

Hi,
Encrypting simple messages is clean and straight as from the docs. What we couldn’t figure out is, encrypting media files (.pdf, .png, .jpeg etc).
Is there a way to do that in this lib? If so can someone point me how this can be achieved?
Sorry if there is a answer for this question already, but I couldn’t find one.

How does the sender decrypts his own messages ?

I am creating a secure chat app based on Signal protocol. The sender encrypts messages with receiver's keys and sends it to the server. The receiver can retrieve and decrypt the messages.

Now, we don't store the sent messages on the device after the sender logs out. So when logging in again, all his messages are retrieved again from the server.

Now, if only receiver can decrypt those messages how will the sender have his own messages decrypted?

Protobuf error in electron application

Hi,

I am attempting to implement libsignal into an electron application.

I have created a basic html page which includes the library and generates a registration id. When opening the .html file from chrome, everything works fine.

However when I use electron to open the same html file in a new browser window. The alert with a registration id appears but I also notice two errors in the console.

Heres the HTML page

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SaltIM</title>
        <script  type="text/javascript" src="./dist/libsignal-protocol.js"></script>
        <script type="text/javascript">
            var KeyHelper = libsignal.KeyHelper;
            var registrationId = KeyHelper.generateRegistrationId();
            alert(registrationId);
        </script>
    </head>
    <body>
        <a>Test libsignal</a>
    </body>
</html>

This is the error (Its repeated twice)

libsignal-protocol.js:35490 Uncaught TypeError: Cannot read property 'loadProto' of undefined
loadProtoBufs @ libsignal-protocol.js:35490
(anonymous function) @ libsignal-protocol.js:35493
(anonymous function) @ libsignal-protocol.js:35499
(anonymous function) @ libsignal-protocol.js:36511

And heres the relevant section of code within libsignal

Internal.protobuf = function() {
    'use strict';

    function loadProtoBufs(filename) {
            console.log('dcodeIO', dcodeIO);
        return dcodeIO.ProtoBuf.loadProto(Internal.protoText['./src/protos/' + filename]).build('textsecure');
    }

    var protocolMessages = loadProtoBufs('WhisperTextProtocol.proto');

    return {
        WhisperMessage            : protocolMessages.WhisperMessage,
        PreKeyWhisperMessage      : protocolMessages.PreKeyWhisperMessage
    };
}();

Would you happen to have any advice as what the issue may be, so I can investigate further.

Thanks,
Emmet

Possbile bug, identifier will be just a jid, device id missing.

var address = new libsignal.SignalProtocolAddress.fromString(identifier);

I was using that and could not get it to work since libsignal complains for address.toString() with error can not found device or similar. Adding

let address = new this.libsignal.SignalProtocolAddress.fromString(identifier + "." + this.get("registrationId").toString());

resolved issue.

Babel import/require .etc

Any way to use this library as library ?

in case trying to import or require to in to the project

require('./libsignal-protocol');
// lead to => libsignal-protocol.js:4 Uncaught ReferenceError: window is not defined 

Documentation

NOT A DEFECT

Hi, I am sorry to post here because I am not sure where I can communicate with the project management. I really like Signal, it has all the features that I look for and so I am using it on the phone. But I am using Chromebook all time and I see that the Chrome extension is not deprecated and all moved to desktop app. While Signal for Linux works on Chromebook, it is very slow. I do appreciate the effort of building it but I am not satisfied with my situation.

So I am thinking about contributing to using my own domain to host PWA version of Signal since Signal has this beautiful JavaScript protocol library available. My high level design is to use:

PWA + Google Firebase Cloud Functions (I have not used AWS nor Azure before) to connect to Signal but I am not too sure if this JavaScript library is an end-client JavaScript or server side Node.js library.

Therefore, I am looking for some more documentation about what this library is for (client or server), and if it is for client (end-to-end encryption), then how does it communicate back to Signal server (cross-domain as in PWA).

For Google Firebase Cloud Functions, there is a monthly limit and I am able to financially support it but I am sure if I could put up the PWA, I can go find some donations to the project so more people will be beneficial from using PWA version of Signal.

I will try to make my code on GitHub but I am not too familiar with that. Please contact me through my email: [email protected].

Again I am sorry to post here.

Regards,

Andy

identityKeyPair "empty" ?

Is it normal that the library gives me an "empty" ArrayBuffers inside identityKeyPair? I am using the example in the README file.

Look at the console.

screen shot 2017-11-08 at 9 57 17 am

I am not able to make an encryption test. And I think this is the main issue. What am I doing wrong?

Wrong prefix match

isEqual: function(a, b) {
// TODO: Special-case arraybuffers, etc
if (a === undefined || b === undefined) {
return false;
}
a = util.toString(a);
b = util.toString(b);
var maxLength = Math.max(a.length, b.length);
if (maxLength < 5) {
throw new Error("a/b compare too short");
}
return a.substring(0, Math.min(maxLength, a.length)) == b.substring(0, Math.min(maxLength, b.length));
}

I think someone tried here to implement a prefix match, but it should not work, because it's the same as

return a.substring(0, a.length) == b.substring(0, b.length);

Am I right, or did I overlook something? Are you interested in a pr?

expand readme

Thanks for this great library.
I believe this is exactly what I need to send messages from my website.

However, I don't understand how to implement it exactly.

So I have to include dist/libsignal-protocol.js

Than what?
How exactly do I install, build session, and send a message?

I found this example but that one is not working and last updated 3 years ago..

License?

Hi guys,

can someone explain why this lib is under such an, lets say, problematic to include license? I would like to add omemo to my chat app (jsxc/jsxc#228), but this is currently not possible because of the license. Is there a chance to dual-license this in any way?

Thank you in advance.

Converse.js v4.2.0 unable send OMEMO message

Hi Dev!
I state that I don't know if this could be a libsignal bug, I've try to ask on Github Converse.js without answer.

I've just installed (from git) on VPS Debian Stretch, Prosody 0.11, Fail2ban 0.9.6-2, Shorewall 5.0.15.6-1, Apache 2.4.25, modsecurity 3.0.0-3, php7 7.0.33, Converse.js v4.2.0, gitted libsignal-protocol-javascript and include it into converse html code.

I write just to understand if it could be a Libsingal or a Converse.js problem. If possible.

Here my Converse installation.

Thanks!

Upgrade jquery and other dev dependencies

I received a security alert from github:

Known moderate severity security vulnerability detected in jquery < 3.0.0 defined in package.json.

I have dismissed the alert because we only use jquery in the test suite (hence it's inclusion in package.json under devDependencies and not dependencies).

We should probably upgrade dev dependencies some day though.

Questions about libsignal for js

Hello, there

Congratulations. I've been waiting for signal protocol in js. I have some questions.

  1. When I read the protocol, it says that generates multiple pre keys at install time. Does KeyHelper only generate one? generatePreKey is the only function I see.
  2. When reading the README.md, is keyId == registrationId?
  3. I wrote this code to make it work (not wishful thinking here, I wanted to see it working):
  var KeyHelper = libsignal.KeyHelper;
  console.log(KeyHelper);

  // Store registrationId somewhere durable and safe.
  var registrationId = KeyHelper.generateRegistrationId();

  // is keyId == registrationId?
  var keyId = registrationId;

  var data = {};
  data.registrationId = registrationId;

  KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
    // keyPair -> { pubKey: ArrayBuffer, privKey: ArrayBuffer }
    // Store identityKeyPair somewhere durable and safe.
    data.identityKeyPair = identityKeyPair;
    return data;
  }).then(function(data) {
    return KeyHelper.generatePreKey(keyId);
  }).then(function(preKey) {
    //store.storePreKey(preKey.keyId, preKey.keyPair);
    data.preKey = preKey;
    return data;
  }).then(function(data) {
    return KeyHelper.generateSignedPreKey(data.identityKeyPair, keyId);
  }).then(function(signedPreKey) {
    //store.storeSignedPreKey(signedPreKey.keyId, signedPreKey.keyPair);
    data.signedPreKey = signedPreKey;

    // Register preKeys and signedPreKey with the server
    console.log(data.registrationId);
    console.log(data.identityKeyPair);
    console.log(data.preKey);
    console.log(data.signedPreKey);
  });

I would like to contribute, understanding the protocol now.

Thank you all

curve25519 sign and verify issue

I use my private key to sign, my public to verify, but always false. when I scan the source code, i find the verify function return "res !== 0;". But in the java library, their verify funtion return "res == 0", is that right?

Install time Error "KeyId" not defined

I copied the following code from the Install time section:

      var KeyHelper = libsignal.KeyHelper;

      var registrationId = KeyHelper.generateRegistrationId();
      // Store registrationId somewhere durable and safe.

      KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
        // keyPair -> { pubKey: ArrayBuffer, privKey: ArrayBuffer }
        // Store identityKeyPair somewhere durable and safe.
      });

      KeyHelper.generatePreKey(keyId).then(function(preKey) {
        store.storePreKey(preKey.keyId, preKey.keyPair);
      });

      KeyHelper.generateSignedPreKey(identityKeyPair, keyId).then(function(signedPreKey) {
        store.storeSignedPreKey(signedPreKey.keyId, signedPreKey.keyPair);
      });

      // Register preKeys and signedPreKey with the server

I receive an Uncaught ReferenceError: keyId is not defined error.

What is keyId and where does it come from?

Wrong environment detected in meteor package

I'm trying to use this library on the client side of a meteor package, but it keeps detecting the environment as NodeJS, which causes some things like require('fs') to fail, and errors appearing in the browser console.

The relevant part from my package.js file for meteor is:

api.addFiles([
		'client/lib/libsignal.js',
		'client/helper.js',
		'client/store.js'
	], 'client');

Any idea what could be going wrong?

Illegal buffer when decrypting whisper message

I could successfully encrypt the message but when I derive that message on receiver side and try to decrypt it, it says illegal buffer. I have tried following things already.

  1. Giving both full whisper message just as generated from the sender, and just the body as a message.

I went to deep debugging and it throws error where it expects an arrayBuffer or UintArray as input for the cipherText. But because generated message was not arraybuffer, how can the ciphertext be an arraybuffer?

Please respond as soon as possible.

Thanks a lot in advance.

getIdentityKeyPair returns undefined

I am starting to implement this protocol. I just want to test the encryption and decryption in a simulated environment.

var KeyHelper = libsignal.KeyHelper;
		var store   = new SignalProtocolStore();

		generateKeys(123, function(aliceKeys){

			generateKeys(456, function(bobKeys){

				var recipientId = "daniel123";
				var deviceId = 0;
				var address = new libsignal.SignalProtocolAddress(recipientId, deviceId);

				// Instantiate a SessionBuilder for a remote recipientId + deviceId tuple.
				var sessionBuilder = new libsignal.SessionBuilder(store, address);

				// Process a prekey fetched from the server. Returns a promise that resolves
				// once a session is created and saved in the store, or rejects if the
				// identityKey differs from a previously seen identity for this address.
				var promise = sessionBuilder.processPreKey({
				    registrationId: bobKeys.registrationId,
				    identityKey: bobKeys.identityKeyPair.pubKey,
				    signedPreKey: {
				        keyId     : bobKeys.signedPreKey.keyId,
				        publicKey : bobKeys.signedPreKey.keyPair.pubKey,
				        signature : bobKeys.signedPreKey.signature
				    },
				    preKey: {
				        keyId     : bobKeys.preKey.keyId,
				        publicKey : bobKeys.preKey.keyPair.pubKey
				    }
				});

				promise.then(function onsuccess() {
				  // encrypt messages
				  console.log("Vamo a encriptar");
				});

				promise.catch(function onerror(error) {
				  // handle identity key conflict
				  console.log(error);
				});


			});

		});
		

		function generateKeys(keyId, callback){

			var keys = {};
			keys.registrationId = KeyHelper.generateRegistrationId();
			// Store registrationId somewhere durable and safe.
			KeyHelper.generateIdentityKeyPair().then(function(identityKeyPair) {
			    // keyPair -> { pubKey: ArrayBuffer, privKey: ArrayBuffer }
			    // Store identityKeyPair somewhere durable and safe.
			    keys.identityKeyPair = identityKeyPair;

			    KeyHelper.generatePreKey(keyId).then(function(preKey) {
				    store.storePreKey(preKey.keyId, preKey.keyPair);
				    keys.preKey = preKey;

				    KeyHelper.generateSignedPreKey(identityKeyPair, keyId).then(function(signedPreKey) {
					    store.storeSignedPreKey(signedPreKey.keyId, signedPreKey.keyPair);
					    keys.signedPreKey = signedPreKey;
					    callback(keys);
					});
				});				
			});

		}

I have the following error at sessionBuilder.processPreKey:

libsignal-protocol.js:35952 Uncaught (in promise) TypeError: Cannot read property 'privKey' of undefined
    at SessionBuilder.<anonymous> (libsignal-protocol.js:35952)

The library is calling the function getIdentityKeyPair of my store interface (I am using the InMemorySignalProtocolStore.js). This function is trying to get data with the key identityKey but I never store any data with that key.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.