Skip to content

Commit

Permalink
Push
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisballinger committed Apr 14, 2016
1 parent e3b36c0 commit 09e8cba
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 76 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.2.3
9 changes: 4 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
source 'https://rubygems.org'

gem 'jekyll'
gem 'rake'
gem 'sass'
gem 'uglifier'
gem 'github-pages'
gem 'github-pages', group: :jekyll_plugins
gem 'jekyll-paginate', group: :jekyll_plugins
gem 'kramdown', group: :jekyll_plugins
gem 'RedCloth', group: :jekyll_plugins
179 changes: 121 additions & 58 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,135 @@ GEM
remote: https://rubygems.org/
specs:
RedCloth (4.2.9)
blankslate (2.1.2.4)
classifier (1.3.4)
fast-stemmer (>= 1.0.0)
activesupport (4.2.6)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.4.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.10.0)
colorator (0.1)
commander (4.1.5)
highline (~> 1.6.11)
execjs (2.0.2)
fast-stemmer (1.0.2)
ffi (1.9.3)
github-pages (12)
ethon (0.8.1)
ffi (>= 1.3.0)
execjs (2.6.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
gemoji (2.1.0)
github-pages (68)
RedCloth (= 4.2.9)
jekyll (= 1.4.2)
kramdown (= 1.2.0)
liquid (= 2.5.4)
maruku (= 0.7.0)
rdiscount (= 2.1.7)
redcarpet (= 2.3.0)
highline (1.6.20)
jekyll (1.4.2)
classifier (~> 1.3)
github-pages-health-check (= 1.1.0)
jekyll (= 3.0.3)
jekyll-coffeescript (= 1.0.1)
jekyll-feed (= 0.4.0)
jekyll-gist (= 1.4.0)
jekyll-github-metadata (= 1.10.0)
jekyll-mentions (= 1.1.2)
jekyll-paginate (= 1.1.0)
jekyll-redirect-from (= 0.10.0)
jekyll-sass-converter (= 1.3.0)
jekyll-seo-tag (= 1.3.3)
jekyll-sitemap (= 0.10.0)
jekyll-textile-converter (= 0.1.0)
jemoji (= 0.6.2)
kramdown (= 1.10.0)
liquid (= 3.0.6)
mercenary (~> 0.3)
rdiscount (= 2.1.8)
redcarpet (= 3.3.3)
rouge (= 1.10.1)
terminal-table (~> 1.4)
github-pages-health-check (1.1.0)
addressable (~> 2.3)
net-dns (~> 0.8)
octokit (~> 4.0)
public_suffix (~> 1.4)
typhoeus (~> 0.7)
html-pipeline (2.3.0)
activesupport (>= 2, < 5)
nokogiri (>= 1.4)
i18n (0.7.0)
jekyll (3.0.3)
colorator (~> 0.1)
commander (~> 4.1.3)
liquid (~> 2.5.2)
listen (~> 1.3)
maruku (~> 0.7.0)
pygments.rb (~> 0.5.0)
redcarpet (~> 2.3.0)
safe_yaml (~> 0.9.7)
toml (~> 0.1.0)
json (1.8.1)
kramdown (1.2.0)
liquid (2.5.4)
listen (1.3.1)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 1.1)
kramdown (~> 1.3)
liquid (~> 3.0)
mercenary (~> 0.3.3)
rouge (~> 1.7)
safe_yaml (~> 1.0)
jekyll-coffeescript (1.0.1)
coffee-script (~> 2.2)
jekyll-feed (0.4.0)
jekyll-gist (1.4.0)
octokit (~> 4.2)
jekyll-github-metadata (1.10.0)
octokit (~> 4.0)
jekyll-mentions (1.1.2)
html-pipeline (~> 2.3)
jekyll (~> 3.0)
jekyll-paginate (1.1.0)
jekyll-redirect-from (0.10.0)
jekyll (>= 2.0)
jekyll-sass-converter (1.3.0)
sass (~> 3.2)
jekyll-seo-tag (1.3.3)
jekyll (~> 3.0)
jekyll-sitemap (0.10.0)
jekyll-textile-converter (0.1.0)
RedCloth (~> 4.0)
jekyll-watch (1.3.1)
listen (~> 3.0)
jemoji (0.6.2)
gemoji (~> 2.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0)
json (1.8.3)
kramdown (1.10.0)
liquid (3.0.6)
listen (3.0.6)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
maruku (0.7.0)
parslet (1.5.0)
blankslate (~> 2.0)
posix-spawn (0.3.8)
pygments.rb (0.5.4)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
rake (10.1.1)
rb-fsevent (0.9.4)
rb-inotify (0.9.3)
rb-inotify (>= 0.9.7)
mercenary (0.3.5)
mini_portile2 (2.0.0)
minitest (5.8.4)
multipart-post (2.0.0)
net-dns (0.8.0)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
octokit (4.3.0)
sawyer (~> 0.7.0, >= 0.5.3)
public_suffix (1.5.3)
rb-fsevent (0.9.7)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
rb-kqueue (0.2.0)
ffi (>= 0.5.0)
rdiscount (2.1.7)
redcarpet (2.3.0)
safe_yaml (0.9.7)
sass (3.2.13)
toml (0.1.0)
parslet (~> 1.5.0)
uglifier (2.4.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
yajl-ruby (1.1.0)
rdiscount (2.1.8)
redcarpet (3.3.3)
rouge (1.10.1)
safe_yaml (1.0.4)
sass (3.4.22)
sawyer (0.7.0)
addressable (>= 2.3.5, < 2.5)
faraday (~> 0.8, < 0.10)
terminal-table (1.5.2)
thread_safe (0.3.5)
typhoeus (0.8.0)
ethon (>= 0.8.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)

PLATFORMS
ruby

DEPENDENCIES
RedCloth
github-pages
jekyll
rake
sass
uglifier
jekyll-paginate
kramdown

BUNDLED WITH
1.11.2
9 changes: 4 additions & 5 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,20 @@ url: https://chatsecure.org
description: Free and open source encrypted chat for iPhone and Android.
source: .
destination: ./_site
plugins: ./_plugins
layouts: ./_layouts
plugins_dir: ./_plugins
layouts_dir: ./_layouts
include: ['.htaccess']
exclude: ['node_modules', 'Gemfile', 'Gemfile.lock', 'Gruntfile.js', 'LICENSE', 'package.json', 'deploy.sh']
timezone: America/Los_Angeles
encoding: UTF-8
gems: ['jekyll-paginate', 'kramdown', 'RedCloth']

# Show future posts
future: false
show_drafts: nil
limit_posts: 0
highlighter: pygments

relative_permalinks: true

permalink: /:categories/:title/
paginate_path: 'blog/page:num'
paginate: 5
Expand Down Expand Up @@ -85,7 +84,7 @@ kramdown:
entity_output: as_char
toc_levels: 1..6
smart_quotes: lsquo,rsquo,ldquo,rdquo
use_coderay: false
enable_coderay: false

coderay:
coderay_wrap: div
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: post

title: How ChatSecure Push Works
title: ChatSecure iOS v3.2 - Decentralized Interoperable Push Support
category: blog

author:
Expand All @@ -11,25 +11,24 @@ author:
bio: Founder & Lead Developer
---

# How ChatSecure Push Works
# ChatSecure iOS v3.2 - Decentralized Interoperable Push Support

With the release of ChatSecure iOS v3.2, we have enabled the first phase of a new form of push messaging that is decentralized, interoperable, and reduces identifiable metadata. Users of any app compatible with the ChatSecure Push protocol can send push messages across app boundaries, starting with the latest releases of Zom Messenger and ChatSecure. These push messages currently contain no content and are simply a way to wake up the receiving client for ~20 seconds.

Unlike centralized messaging applications like WhatsApp, Signal or Telegram, a core part of our mission is to allow users to connect any XMPP server of their choice and to encourge users to run their own servers. This privacy win also comes with a major drawback for iOS users, because Apple prevents the application from running in the background. The only way push messages can be sent are through servers run by app developers themselves, which presents a problem when trying to support push for any arbitrary XMPP server.
With the release of [ChatSecure iOS v3.2](https://itunes.apple.com/us/app/chatsecure-encrypted-messenger/id464200063), we have enabled the first phase of a new form of push messaging that is decentralized, interoperable, and reduces identifiable metadata. Users of any app compatible with the [ChatSecure Push protocol](https://github.com/ChatSecure/ChatSecure-Push-Server/tree/master/docs/v3) can send push messages across app boundaries, starting with the latest release of ChatSecure iOS and the next version of [Zom Messenger](https://zom.im). These push messages currently contain no content and are simply a way to wake up the receiving client for ~20 seconds.

There is a relatively new way for XMPP servers to interact with app push gateways called XEP-0357 but not very many servers support this extension right now. Our solution works with any XMPP server as long as you're both running a ChatSecure Push compatible client. We will also be rolling out client support for XEP-0357 to allow you to receive pushes from any contact, as long as you're connected to a compatible XMPP server.
Unlike centralized messaging applications like WhatsApp, Signal or Telegram, a core part of our mission is to allow users to connect any XMPP server of their choice and to encourge users to run their own servers. This privacy win also comes with a major drawback for iOS users, because Apple prevents the application from running in the background. The only way push messages can be sent are through servers run by app developers themselves, which presents a problem when trying to support push for any arbitrary XMPP server.

### Example Flow

Alice (`alice@example.com`) and Bob (`bob@example.com`) are both using the ChatSecure iOS app to communicate via their private XMPP server `example.com`. After each OTR session is established, they each send a payload inside the OTR channel that contains a fresh token and their push API endpoint. The token is used by the API endpoint to lookup your device APNS token, and the endpoint parameter is what allows this to work between apps from different developers. Because all of this data is exchanged by the clients themselves, the server has no idea about the JIDs of Alice or Bob, or where any of the tokens ended up.
Alice (`alice@example.com`) and Bob (`bob@example.com`) are both using the ChatSecure iOS app to communicate via their private XMPP server `example.com`. After each OTR session is established, they each send a payload inside the OTR channel that contains a fresh token and their push API endpoint. The token is used by the API endpoint to lookup your device APNS token, and the endpoint parameter is what allows this to work between apps from different developers. Because all of this data is exchanged by the clients themselves, our push server has no idea about the JIDs of Alice or Bob, or where any of the tokens ended up.

![Contact Offline](/images/contact-offline.png)

The next time Alice opens the app and she wants to talk to Bob, she sees that Bob is offline.

![Knock Sent](/images/knock-sent.png)

On the chat screen there is now a new button called Knock that has replaces the Send button when the contact is offline (and no text is entered). By pressing Knock, it looks up the token and endpoint that Bob gave her earlier, and sends a HTTP POST to that endpoint with the token.
On the chat screen there is now a new button called Knock that has replaced the Send button when the contact is offline (and no text is entered). By pressing Knock, it looks up the token and endpoint that Bob gave her earlier, and sends a HTTP POST to that endpoint with the token.

![Contact Online](/images/contact-online.png)

Expand All @@ -43,4 +42,8 @@ His device will also receive back the token he gave to Alice, do a local lookup

Having a Knock button is not the ideal user experience because it's a foreign UI concept and not immediately clear how it works. Originally we tried to automatically trigger knock messages, but hit issues with missing messages caused by sending messages to offline contacts, or when in a stale OTR session. Our message pipeline needs to be reworked to handle these cases and ensure that no message ever enters a black hole.

Although OTR has proven to be trustworthy over the years, it is showing its age in the face of more modern protocols like SignalProtocol (formerly known as Axolotl). Originally we wanted to integrate Axolotl/OMEMO but we haven't been able to acquire a license from OpenWhisperSystems. The next post will be about our options for implementing async-friendly crypto.
There is a relatively new way for XMPP servers to interact with app push gateways called [XEP-0357](http://xmpp.org/extensions/xep-0357.html) but not very many servers support this extension right now. Our current solution works immediately with any XMPP server as long as you're both running a ChatSecure Push compatible client. In the future we will roll out client support for XEP-0357 to allow you to receive pushes from any contact, as long as you're connected to a compatible XMPP server.

### The Road Ahead

Although OTR has proven to be trustworthy over the years, it is showing its age in the face of more modern protocols like [SignalProtocol](https://whispersystems.org/blog/signal-inside-and-out/) (formerly known as Axolotl). Originally we wanted to integrate Axolotl/[OMEMO](https://conversations.im/omemo/) but we haven't been able to acquire a license from Open Whisper Systems. The next post will be about our plans, in collaboration with the Conversations team, to implement a revision of OMEMO that supports [Olm](https://matrix.org/git/olm/about/) instead of SignalProtocol.

0 comments on commit 09e8cba

Please sign in to comment.