Tutanota on Mac OS X

In the past few months I was thinking to try some new email providers that support end-to-end encryption. I kept reading privacytools.io, with the idea to try some of the solutions listed there.

Then, I finally had the time to start playing around with some of them.

I decided to start with Tutanota. Even though the debate on how much secure is browser cryptography is still active, I’d like to give it a try.

What I like about Tutanota is that you can compile the web UI locally, so it doesn’t reside on their webservers (not that I don’t trust Tutanota, but I prefer to have as much control as possible over my own stuff, even more if it deals with emails and cryptography).

So I followed the instructions on their Github repo (https://github.com/tutao/tutanota/). They have detailed steps on how to do that. Let’s start (I’m assuming that you already have installed git and npm):

MacBook-Pro:~ db$ git clone https://github.com/tutao/tutanota.git
Cloning into 'tutanota'...
remote: Counting objects: 15278, done.
remote: Total 15278 (delta 0), reused 0 (delta 0), pack-reused 15278
Receiving objects: 100% (15278/15278), 29.76 MiB | 6.04 MiB/s, done.
Resolving deltas: 100% (10726/10726), done.
Checking connectivity... done.
MacBook-Pro:~ db$ cd tutanota/web/
MacBook-Pro:web db$ git checkout tutanota-release-2.0.5
error: pathspec 'tutanota-release-2.0.5' did not match any file(s) known to git.

Umhh. Step nr. 3 says I have to checkout the branch ‘tutanota-release-2.0.5‘ but it doesn’t appear to be there. Let’s check thought:

MacBook-Pro:web db$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
MacBook-Pro:web db$ cd ..
MacBook-Pro:tutanota db$ git remote show origin
* remote origin
Fetch URL: https://github.com/tutao/tutanota.git
Push URL: https://github.com/tutao/tutanota.git
HEAD branch: master
Remote branches:
android_beta tracked
master tracked
tutanota-1.9.2+ tracked
tutanota-ios-release-1.8.1 tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

Yep. It seems like the branch is no longer there. I’m quite sure they merged the branch into master (didn’t check the commits, sorry), so they need to update the Readme.md file. Anyway, let’s continue.

MacBook-Pro:tutanota db$ cd web/
MacBook-Pro:web db$ npm install
npm WARN package.json tutanota@2.0.5 No repository field.
npm WARN deprecated gulp-clean@0.3.1: use gulp-rimraf instead
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine get-stdin@5.0.0: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine cryptiles@2.0.5: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.33","npm":"2.1.6"})
npm WARN engine hoek@2.15.0: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.33","npm":"2.1.6"})

Cool, step 4 done. Let’s build now:

MacBook-Pro:web db$ gulp dist
-bash: gulp: command not found

Ok, nice. I knew nothing about gulp until now. After a quick search, I found out that a simple sudo npm install -g gulp should work. And it worked. So now we can go ahead with our steps:

MacBook-Pro:web db$ gulp dist
[11:38:57] Using gulpfile ~/github-repo/tutanota/web/gulpfile.js
[11:38:57] Starting 'clean'...
[11:38:57] Finished 'clean' after 7.71 ms
[11:38:57] Starting 'dist'...
[11:38:57] Starting 'copyMessages'...
[11:38:57] Starting 'copyOperative'...
[11:38:57] Starting 'copyFonts'...
[11:38:57] Starting 'copyGraphics'...
[11:38:57] Starting 'copyMochaStylesheet'...
[11:38:57] Starting 'less'...
[11:38:57] Starting 'minify'...
[11:38:57] Starting 'minifyWorker'...
[11:38:57] Finished 'minifyWorker' after 2.98 ms
[11:38:57] Starting 'processHtml'...
[11:38:57] Starting 'distPayment'...
[11:38:57] Starting 'copyPayment'...
[11:38:57] Starting 'minifyPayment'...
[11:38:57] Starting 'processPaymentHtml'...
[11:38:58] Finished 'copyMochaStylesheet' after 413 ms
[11:38:58] Finished 'copyPayment' after 387 ms
[11:38:58] Finished 'copyOperative' after 418 ms
[11:38:58] Finished 'copyMessages' after 421 ms
[11:38:58] Finished 'processHtml' after 393 ms
[11:38:58] Finished 'processPaymentHtml' after 380 ms
[11:39:00] Finished 'less' after 2.28 s
[11:39:04] Finished 'copyFonts' after 6.48 s
[11:39:04] Finished 'copyGraphics' after 6.48 s
[11:39:04] Starting 'copy'...
[11:39:04] Finished 'copy' after 4.16 μs
[11:39:07] Finished 'minifyPayment' after 10 s
[11:39:07] Finished 'distPayment' after 10 s
[11:39:15] Finished 'minify' after 18 s
[11:39:15] Starting 'manifest'...
[11:39:15] Finished 'manifest' after 22 ms
[11:39:15] Starting 'gzip'...
[11:39:16] Finished 'gzip' after 372 ms
[11:39:16] Finished 'dist' after 18 s
MacBook-Pro:web db$ cd build/
MacBook-Pro:build db$ pwd
MacBook-Pro:build davidebarbato$ ls
app.min.js fonts init.js operative-0.3.1.js payment.html.gz worker.min.js
app.min.js.gz graphics init.js.gz operative-0.3.1.js.gz test worker.min.js.gz
app.min.js.map index.html messages.html pay tutanota.appcache worker.min.js.map
css index.html.gz messages.html.gz payment.html tutanota.appcache.gz

Sorted! To access the web UI you have to open the index.html throught your favourite browser. I use Firefox, so next steps will be focused on this browser, but you can adapt them to other browsers as well.

First, I wanted to create a brand new profile to use only with Tutanota to segregates data between Firefox instances.

MacBook-Pro:~ db$ /Applications/Firefox.app/Contents/MacOS/firefox-bin --ProfileManager

After choosing a name and creating the profile, I created an Automator App like the following image (if you don’t know what Automator is or how to create one, read this link):

Screen Shot 2015-09-15 at 19.27.32saved, renamed and moved to the Dock. If you want to change the app icon, you can follow the instructions outlined in this good blog post: http://osxdaily.com/2013/06/04/change-icon-mac/.

The final aspect of my app is:

Screen Shot 2015-09-15 at 12.26.09If you need more security, you can run the newly created Tutanota app in an encrypted container so your browser cache will be encrypted as well, leaving no traces of plain-text emails. But this is a story for the next post.

5 thoughts on “Tutanota on Mac OS X”

  1. What is the point though, running this on a proprietary operating system from the USA?

    I’m not trying to troll, but unless you have an audit or at least the source of your whole stack, you could still be compromised without knowing. Apple is known for playing shitty games like doctoring their copy of dtrace so it won’t work when they choose it not to work, e.g. when running iTunes. They could easily have poisoned anything else in their stack.


    1. Hi Psy-Q,
      while I agree with you, this statement can easily escalate to everything. It can be applied to Linux as well, not only the kernel but also to firmware. Just as reminder, FBI backdoor in OpenBSD, an open source project (https://marc.info/?l=openbsd-tech&m=129236621626462&w=2), Plus, there is a talk at Defcon 2015 about backdooring Git (https://media.defcon.org/DEF%20CON%2023/DEF%20CON%2023%20presentations/John%20Menerick/DEFCON-23-John-Menerick-Backdooring-Git.pdf).
      My point is: I’m not trying to defend myself againt NSA or FBI or three-letter-agencies: they have much more power, money and resources than me. I’m trying to make a generic attacker life harder, expecially regarding online data and not data at rest/endpoint.


      1. Yes, it can and should be escalated! Paranoia is a useful attribute in computing.

        At least for GNU/Linux, you have the source, for OS X you don’t even have that so who knows what lurks there. On the hardware front, I grant you that it’s not great yet. What we have for halfway privacy-conscious hardware today is the Libreboot X200: http://minifree.org/product/libreboot-x200/, hardly sexy. But ARM is becoming ubiquitous, and with that a chance for us to bake our own silicon for PCs and laptops. Retrofitting a BIOS replacement has proved a bit more of a crappy experience than anyone would like to have, but with U-Boot and Coreboot we have some major stumbling blocks out of the way.

        The Linux kernel gets a lot more eyeballs than OpenBSD, but a full audit wouldn’t hurt. It’s equal rules for every piece of security-related software IMHO, the source is required, an audit is welcome.


        1. I tend to agree with you almost completely. We should take into account that actually everything can be backdoored/compromised, if not already done. As you pointed out, rightly, we should push for free and open solution like Coreboot (Libreboot X200 is more like a geekyish solution that will not scale). But we should deal with UEFI and dodgy firmwares. Yet, even if I don’t trust my BIOS/UEFI, my network card and SSD firmwares, even if I don’t trust my GPU card, I still think it’s worth spending time setting up an environment as much secure as possibile. Said that and following your point, it would be pointless even using LUKS/dm-crypt on a GNU/Linux box.

          I think a better and more realistic approach is threat modeling, more or less as outlined here: https://ssd.eff.org/en/module/introduction-threat-modeling. I believe that with this kind of approach we can define exactly what to protect and find better ways to do that, creating a more effective security model, choosing the right tools that fit our needs.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s