This article documents Proton Calendar’s security model and illustrates how our product protects calendar-related sensitive data. We examine the advantages and limitations of our approach.
This document is somewhat technical, discussing how encryption protects the different layers of data. Still, it is meant to be accessible to a general audience and attempts to explain how Proton Calendar works in plain language.
The Proton Calendar(nova janela) app is now available on the web, iOS(nova janela), and Android(nova janela).
Overview
Proton Calendar is an online calendar that is integrated within the Proton suite of products. It is designed to deliver the convenience of a calendar app with the security and privacy of a Proton product. When developing Proton Calendar, we knew it had to support the following features:
- Send and receive event invitations, both from other Proton Calendar users and non-Proton users
- Send and receive event updates
- Add attendees to an event
- Add reminders to an event
- Support multiple calendars
- Share an event between multiple calendars
- Share calendars
Threat model
The goal is to prevent the server or any adversary that gains access to the server from accessing sensitive user data. They must not be able to:
- Access the private content of events
- Modify the public content of events undetected
- Forge an event on behalf of an existing member of a calendar
- Add a member to a calendar.
Calendar model
At its most basic, a calendar is just a collection of events. It would be a relatively easy task to secure such a calendar app with encryption. However, to be useful, a calendar should let you share an event with other users and across multiple calendars. You may also want to share your calendar with other users. These interactions are what make encrypting Proton Calendar so tricky.
When you start using Proton Calendar, you will join or create a calendar using one of your Proton Mail email addresses. You will become a member of that calendar, and your email address will be used as your identity within it. Any action you take, like creating, editing, or deleting an event, will be digitally signed using a primary address key that is linked to the Proton Mail address you used to join the calendar.
Each member will have a set of permissions that allow them to edit events, view event details, check availability, see the list of members, and invite new members.
For every calendar, we will generate a calendar key (for those interested, it will be an ECC Curve25519 PGP key). This calendar key will be used to encrypt the event data. (To see more details about the event encryption, skip down to the “Event encryption” section.)
This calendar key will then be symmetrically encrypted (PGP standard) using a 32-byte passphrase that is randomly generated on your device. Once it is encrypted, your calendar key will be stored on the Proton Calendar backend server.
Each member of a calendar will have a copy of the same passphrase that is encrypted and signed using their primary address key. The signature ensures that no one, not our server or any third-party adversary, changed the passphrase. This is crucial because if an attacker could change a member’s passphrase, they could then modify the calendar key without the calendar members’ knowledge. This would allow the attacker to decrypt any new event created by the calendar’s members.
Thus a calendar is composed of:
- A Calendar Key with the corresponding passphrase
- Members
- Events
A member is a user, represented by an email address that is linked to the calendar and is composed of:
- An encrypted and signed passphrase
- A permission set
This allows multiple members to be part of the same calendar and share the same events without having to encrypt them with multiple keys.
Calendar invitation
You can share your Proton Calendar with multiple Proton users. We implemented a secure invitation protocol that cryptographically guarantees that the user inviting you is who they say they are.
The calendar invitation cryptosystem
To invite a new member to your calendar, you need to grant them access to the calendar private key and make sure that they can decrypt it. This is the only way they would be able to decrypt and read the calendar’s events.
If you invite a new member, Proton Calendar first has to fetch the invited member’s public key that is linked to their email address. Your Proton Calendar client will then encrypt the calendar’s passphrase on your device using the invited member’s public key. The passphrase is then signed using your email address key.
The invited member, if they decide to join the calendar, can decrypt the passphrase using their address key. They can also verify that the signature on the passphrase belongs to your email address key. This lets the invited member cryptographically verify that you invited them. To accept the invitation, Proton Calendar will then pin the passphrase for the invited member by replacing your signature with one created using their own email address key. This signature will later be used by the invited member to verify the passphrase at each application start.
Event encryption
A member with write-access can add a new event to a calendar.
Event splitting
Events have three types of data. They are:
- Shared event data, which is shared with all calendars that have that event
- Calendar data, which is specific to a calendar but shared with all a calendar’s members
- Member data, which is specific to a unique calendar and member
This division allows the main properties of an event to be shared between all calendars, while each calendar can have different comments for the same event. Furthermore, each member can set their own personalized alarms.
The shared event data that is the same on multiple calendars includes:
- Unique event identifier
- Start and end date of the event, repetition rule and date/time exclusions
- Description, summary (title), location
- Attendees
The calendar data that can be customized on each calendar includes:
- Comments
And the member data that each member can customize includes:
- Alarms
All event data can also be split into two categories:
- Encrypted and signed properties
- Signed-only properties
Our server needs to be able to access some properties of an event so that it can retrieve and index the events efficiently. The properties that our server must access are the signed-only properties, which include:
- The start/end time of an event, along with its time zone information
- The repetition rule and the date/time exclusions
- The unique event identifier
- Time information for alarms
All the remaining properties will be encrypted and signed on your device before they are stored on our servers. In other words, all of an event’s critical information, like the title, description, location, and attendees, will be stored securely and privately with end-to-end encryption.
The event cryptosystem
An event’s encrypted data will be encrypted as a PGP message using the calendar private key. This data will also be signed as a PGP message using the author’s primary address key.
An event’s signed-only data will be signed as a PGP message using the author’s primary address key.
The signature of the data cryptographically ensures that each type of data was created and edited by the specified author and guarantees that nobody (not even Proton Mail) has tampered with your events.
When you create a new event, Proton Calendar automatically takes the following actions to encrypt it:
- It generates two session keys. A session key is a random binary string of 32 bytes.
- Using the first session key, it encrypts the encrypted category of the shared event data. This session key is called the Shared Session Key.
- Using the second session key, it encrypts the encrypted category of the calendar and member data. This session key is called the Calendar Session Key.
- It then encrypts the Shared Session Key using the calendar private key. The result is called the Shared Key Packet.
- Next, it encrypts the Calendar Session Key using the calendar private key. The result is called Calendar Key Packet.
- Finally, the encrypted Shared Session Key and the encrypted Calendar Session Key are stored on the server along with the encrypted event data.
Sharing an event
As a Proton Calendar user, you can invite anyone, including non-Proton users, to your event.
If you accept an event invitation from another user’s Proton Calendar, then the event will automatically be added to your calendar and linked to the original event of the organizer. This way, if you or the organizer of the event update a shared component of the event (like the start time or location), the other user’s calendar will automatically be updated. They will be able to decrypt the new event data and verify the digital signature to ensure that the event modification was made by the claimed author.
The diagram below represents a single event. Some properties are shared across the calendars to which the event is linked, others are calendar level, and finally, some are member level as described in the “Event splitting” section.
Shared event encryption
Sharing an event with a different calendar is done by sharing the shared event data and shared event session key. Both calendars will access the same shared event data that is encrypted using the shared session key. Thus, if you want to share an event from your calendar to someone else’s calendar, you will have to send your shared session key (decrypted shared key packet) to the other user. The other user will use this shared session key to access the shared event data.
When the other user adds the shared event data into their calendar, their device will generate a new Calendar Session Key. It will use that new Calendar Session Key to encrypt any calendar data or member data from their calendar. The Shared Session Key received in the event invitation will be encrypted using the private key of the user’s calendar key and will be stored as a new Shared Key Packet.
Or, as this illustration shows, Shared Key Packet B will be different from Shared Key Packet A as Calendar Key A and B will be different. But the unencrypted Shared Key Packet A and unencrypted Shared Key Packet B will be identical and equal to the Shared Session Key.
Attendees
The ability to send invitations to an event is an essential feature for every calendar. Proton Calendar will support it with an added security layer. We decided to partially encrypt an event’s attendee list so that the email addresses of attendees cannot be accessed by Proton Mail or by any eavesdropper. This significantly enhances the anonymity of the participants.
To be interoperable with other email and calendar services, Proton Calendar needs to allow external participants to respond to event invitations. We designed a system that enables RSVP updates from external users without the need to decrypt or sign any data. (This would be impossible as external users don’t have address keys or access to the calendar key.)
For each external attendee, Proton Calendar generates a unique random token (a string of 40 random characters). This token is encrypted and stored along with the attendee’s email and attendee role. The user’s token is also stored unencrypted and unsigned along with their RSVP status to allow external updates.
This ensures that the attendee can respond to their invitation, even if they are an external user, and that the attendee list cannot be read from the event data.
Automatically added invites
While Proton Calendar has always allowed you to respond to invites, it used to require you to go into the Proton Mail client to see pending invites. This can break your flow, forcing you to switch between tabs, and is especially annoying on mobile clients. To resolve this, we’ve added a feature that automatically adds pending invitations to your calendar. The goal is to improve your experience with Proton Calendar by allowing you to see when pending events will happen and respond directly from your calendar.
How it works
When the organizer uses Proton Calendar
On the invite sender’s side:
- During the event creation, the organizer’s client requests the address keys of all Proton attendees it wants to invite from the Proton API servers. If no address key is found for an attendee, they must be an external attendee. Thus only the normal email flow can be used.
- The shared session key, as defined in “The event cryptosystem”, is encrypted for each Proton attendee’s address public key.
- The list of Proton attendees and their linked encrypted shared session keys are sent to the Proton API servers during the event creation API request.
- The Proton API servers automatically create the invites in the provided Proton attendees’ calendars.
On the invited user side:
- When the invite is shown in the current view, the client decrypts the event using the user’s address key.
- On the first user interaction with the invite (reply to the invite), the client re-encrypts it with their calendar key and persists it on the backend side.
When the organizer uses an external calendar
Proton Calendar can now also automatically add unencrypted invites coming from other calendar providers. When the Proton Mail servers receive an email with an invite, the server encrypts the invite using the invited member’s address key and inserts it into the calendar. The same re-encryption process is applied on the invited user side.
If a user wishes to opt out of this feature, they can do so from the calendar settings.
Conclusion
At Proton, we’re committed to maintaining the highest levels of security and privacy through rigorously applied cryptography, while retaining a high level of usability. We are cognizant of the heightened security needs of many of our users who have entrusted their lives to us(nova janela), and your protection and safety will always be our first priority.
To members of the Proton community, thank you for your patience and for affording us the time to properly build Proton Calendar to meet the highest standards of security. We welcome all comments and feedback about Proton Calendar’s security model via the bug report feature inside the app. Proton Calendar is also eligible for our bug bounty program. Additionally, you can always reach us at security@proton.me. Thank you for your support!
Best Regards,
The Proton Team
This post was authored by Valentin Bonneaud, Daniel Huigens, Giuseppe Arcuti from the Proton team.
Interested in building products like this? Join us.(nova janela)
UPDATE November 2, 2022: The section about automatically added invites, a new feature, was added.
You can get a free secure email account from Proton Mail here(nova janela).
We also provide a free VPN service(nova janela) to protect your privacy.
Proton Mail and Proton VPN are funded by community contributions. If you would like to support our development efforts, you can upgrade to a paid plan(nova janela). Thank you for your support.