A privacy-focused app using Apple's soon-to-be-released contact tracing framework.

Overview

TracePrivately

A functioning app using Apple's contact tracing framework, as documented here:

https://www.apple.com/covid19/contacttracing

7 May 2020: App is now updated for iOS 13.5 beta 2 changes. The framework now has a more defined structure for how the server should work, so we'll likely be making some additional changes to further integrate with protocol buffers.

Note: To run the app the Apple framework, a special entitlement is required, only available to authorized organizations. More Info

This app will be evolving quickly as I'm trying to publish new functionality as quickly as possible.

Objectives

  • Create a fully-functioning prototype that governments can use as an almost-turnkey solution that they can rebrand as necessary and use
  • Implement correct security and privacy principles to maximise uptake of said government apps
  • Remain open source for independent verification
  • Properly use the Apple / Google contact tracing specification
  • Accessible to as many users as possible:
    • Localized to many langauges
    • Adopt correct accessibility principles and functions
    • Support older devices
  • Be easily configurable to suit needs of different jurisdictions:
    • Different privacy statements
    • Different data gathered for positive diagnoses
    • Different server/authorization needs
    • Different thresholds to define a contact (attenuation and duration)
  • Create a functioning server prototype that can be used as a basis for more robust solutions that fit into governments' existing architecture.

How Can You Help?

There are a number of ways you can help. You can:

Instructions

Key Server

The mobile app communicates with a server to retrieve infected keys. API specification: https://github.com/CrunchyBagel/TracePrivately/blob/master/KeyServer/KeyServer.yaml

Current server options:

  1. PHP: This project contains a reference implementation in PHP: https://github.com/CrunchyBagel/TracePrivately/tree/master/KeyServer
  2. Ruby: https://github.com/tatey/trace_privately by @tatey.
    • Includes a 1-click setup process for quick deployment
  3. Vapor (Swift): https://github.com/kevinrmblr/traceprivately-server
  4. Go: https://github.com/dstotijn/ct-diag-server
  5. Create your own, either according to the above OpenAPI specification or by creating your own adapter implementing KeyServerAdapter.

iOS App

  1. Configure KeyServer.plist to point to your server
    • The endpoints are constructed by joining BaseUrl with each corresponding endpoint value.
    • Authentication is optional. Remove the Authenticaftion key to disable. Otherwise, the types available are:
      • receipt: Submit the App Store receipt data to the auth endpoint. This data isn't available in development
      • deviceCheck: Submit the info from DeviceCheck to the auth endpoint. This is only available from iOS 11.
  2. Configure ExposureNotifications.plist to control how exposures are scored.
    • This is based on weighting of attenuation, duration, days since exposed and risk level.
    • Defaults in app are based on Apple's example in their documentation.
    • Refer to Apple's documentation for more info: https://www.apple.com/covid19/contacttracing
  3. Configure SubmitConfig.plist if you want the user to submit additional information with a positive diagnosis.
    • This system is extensible and localizable.
    • You will need to configure your server to save and use this data accordingly.
    • For example, your workflow for approving new infected keys may involve reviewing this data before approving the submission.
  4. Build and run in Xcode

Workflow

If you're using the sample PHP implementation, it goes something like:

  1. App: Enable tracing in the app
  2. App: Submit that you're infected
  3. Server: Approve submission using the ./tools/pending.php and ./tools/approve.php scripts.

Those keys are now in the infected list so they can be matched against.

Localizations

If you can help translate the app, please help our crowd-sourced effort here:

https://traceprivately.oneskyapp.com/collaboration/project?id=170066

Currently available in: English, French, Spanish (ES, MX), Portuguese (PT, BR), German, Chinese (Simplified and Traditional), Croatian, Serbian, Japanese, Estonian, Latvian, Dutch, Italian, Ukrainian, Hindi, Arabic, Catalan, Hebrew.

Screenshots

Screenshots

This screenshot shows how you can use the start/stop tracing shortcuts with automations. User is still manually prompted to start tracing, but this will initiate it automatically when you leave home:

Siri Shortcuts

Other

  • Please submit suggestions and pull requests so this can function as best as possible.
  • Refer to the KeyServer directory for information about the server-side aspect of contact tracing.
  • Android? If you would like to build a clone of this iOS app in Android we can include or link to it from this repo.

License

Refer to the LICENSE file.

Comments
  • Ability to authenticate with the server

    Ability to authenticate with the server

    In order to ensure only the app communicates with the server, it should be possible to authentication.

    In the feat/server_authentication branch (3176a966f94c6c5feec1e39b61531714a1b24c4e) I've implemented this in a modular way.

    The workflow of this is:

    1. The specific authentication to use is specified in KeyServer.plist
    2. There is now an auth endpoint required on the server in order to use token validation
    3. Forks can easily create their own authentication module (and these can be merged back in)
    4. If the app receives a 401 Unauthorized and authentication is configured, then it will request a token from the server
    5. App will store and retrieve the token automatically
    6. The server auth endpoint should read the bearer token from the HTTP headers and act accordingly. Likewise, the other endpoints should validate this token. The token format is not specified.

    (currently only "receipt validation" option is available, which submits the App Store receipt to the auth endpoint)

    opened by HendX 19
  • Server API changes

    Server API changes

    Add support for expires_at (#29 and #46); breaking change to key submission: each key element is now an object instead of a string. This is so additional data can be included with each key if necessary.

    opened by HendX 11
  • Ability to return infected keys in binary format

    Ability to return infected keys in binary format

    Related to #48, the current method of returning keys in base 64 encoded JSON won't scale as well it should.

    The API should be updated as follows:

    • [ ] Ability to return application/octet-stream the infected keys. Either the server can decide to return this or the client can ask for it
    • [ ] Update the app to handle binary data

    Before jumping into this, some issues need to be addressed:

    • [ ] How will since the since data be returned?
    • [ ] How will the deleted_keys be returned?
    • [ ] In #51, this could a new parameter in the JSON returned from infected endpoint. How would this be included in a binary stream?

    I propose it be implemented something like the following:

    • [ ] Include the since data in the response headers
    • [ ] A header which includes:
      • [ ] The version number,
      • [ ] The number of keys / size of the key payload
      • [ ] The number of deleted keys / size of the key payload
      • [ ] The length of a key (16 bytes in the spec)
    • [ ] Each key in the format: key data + UInt32. The specs indicate the key data is 16 bytes
    Key Server 
    opened by HendX 9
  • Why base64?

    Why base64?

    I'm wondering why you chose base64 encoding for downloading keys, e.g. in your OpenAPI spec and in the client code.

    When downloading a large set of diagnosis keys, using base64 is not size efficient. Because the length of a DiagnosisKey is 20 bytes (16 bytes for the key, 4 bytes for the ENIntervalNumber), and 20 is not a multiple of 3, the encoded output needs padding added so it's a multiple of 4 (ref). The length of a base64 string for one DiagnosisKey would be 28 bytes (example).

    Example of how this affects the size of data transfer:

    • Each DiagnosisKey consists of 20 bytes: 16 bytes for the TemporaryExposureKey, and 4 bytes for the ENIntervalNumber.
    • Let's say 100.000 users each uploaded 14 days of keys, so the keyset on the server is 100.000 * 20 * 14 = 28.000.000 bytes = 28 MB.

    Encoding 28 MB as a Base64 string would takeceil(28.000.000 / 3) * 4 = 37.333.336 bytes = 37,3 MB to download. That's an increase of 33%. Given a broad user base, this can impact both CDNs, government proxies and individual users with small mobile data plans.

    I would suggest changing the content type of the download endpoint to application/octet-stream; e.g. a binarystream. I'm working on a reference server for Apple/Google's framework, which uses this strategy: https://github.com/dstotijn/ct-diag-server

    Note: For uploading, it's a non-issue, because the content length will always be small; at most 14 days worth of data per upload, e.g. 20 * 14 = 280 bytes. Using Base64 encoding would make it: ceil(20 * 14 / 3) * 4 = 376 bytes (slightly more than 33%). But of course this size increase would hardly make a difference.

    Key Server 
    opened by dstotijn 8
  • Thoughts on public demo server for developers

    Thoughts on public demo server for developers

    I've made the Ruby implementation of the key server available on a demo server. You can point the BaseUrl in KeyServer.plist to https://trace-privately-demo.herokuapp.com/api. Here's a GIF of it in action built against 21323284a722ae2ce4d8a7f39049e9eb077d1520.

    ScreenFlow 2020-04-24 22_41_05

    There's currently no authentication or ~protection~ on the server. It's using a free tier on Heroku. It's limited to 10,000 rows in the database and the server "sleeps" after not being used for 30 minutes (Delay when booting up, but completely automatic). It will be locked down a little more after https://github.com/tatey/trace_privately/issues/12 and https://github.com/tatey/trace_privately/issues/4 are implemented.

    You can access the admin section yourself by going to https://trace-privately-demo.herokuapp.com/.


    Update: Server is now rate limiting API clients to 10 requests per minute. You'll get a 429 if you make too many requests.

    opened by tatey 8
  • Feat/apple framework

    Feat/apple framework

    This contains the changes to app and the mock framework to use the ExposureNotification framework.

    Note that you need the following entitlement to actually use the real framework, which must be manually given to you by Apple.

    com.apple.developer.exposure-notification entitlement
    
    opened by HendX 7
  • Updated main storyboard to allow scrolling

    Updated main storyboard to allow scrolling

    On smaller devices, the stackview became too large, causing layout constraint errors. Moving the view into a scrollview allows the stack to grow and fixes the layout on smaller devices.

    opened by kevinrmblr 3
  • Ability to send push notifications when new keys are detected

    Ability to send push notifications when new keys are detected

    This may not scale if you have to ping every single client with a push notification, but it may be useful way to wake up people's phones for exposure checking.

    enhancement 
    opened by HendX 3
  • UX suggestions

    UX suggestions

    Hey Quentin, kudos on your work on this, I'm loving following along and really hope government(s) take advantage of it!

    I just wanted to suggest a couple of minor UX improvements based on a quick look at the most recent screenshots. I know it's only a proof of concept but here are my thoughts anyway :)

    • It's not immediately obvious to me that the orange "You May Have Been Exposed" button is tappable, because that phrase isn't a verb. Maybe you could align the text to the left and add a little arrow on the right? Or add a "tap for more info" sub-label?

    • You could change "Privacy" to say "Privacy Info" and make it a blue text link instead of a grey button. As it is the buttons being different heights looks a little odd.

    • The "Submit Diagnosis" button being at the bottom of the screen is very far away from the explanatory text. Could move it up like the "Next Steps" button?

    • The red exposure info box ("April 18...") has the same style as a button, but I presume it's not tappable?

    opened by tobyzerner 2
  • Siri Shortcuts and automations support

    Siri Shortcuts and automations support

    Add shortcuts to start, stop and check stays of tracing.

    Provide detail or sample shortcut for “leaving home”. Doing it in this manner means location tracking is not required.

    opened by HendX 2
  • Thoughts on GPS tracking

    Thoughts on GPS tracking

    GPS tracking could make for a useful addition to this app, but it would likely be controversial.

    I'm going to use this thread to discuss how this could possibly be implemented in a sane and useful way.

    opened by HendX 2
  • Compatibility with Vapor 4 implementation

    Compatibility with Vapor 4 implementation

    Hi there!

    I've been working on a server reference implementation based in the Swagger file. I'd love your help with testing and keeping it compatible moving forward.

    It can be found here: https://github.com/kevinrmblr/traceprivately-server

    There's some open ends, such as limits on updating daily keys and updating the related data, but mostly it should be ready:

    • It saves the form fields (as plain text) alongside the batch
    • Saves the risk level
    • Calls support both plan JSON and MessagePack

    I also left room to submit data in the auth call, so a token can be added, like a PushToken or a DeviceId token. Depending on the app setup, it'll either require this or also accept an empty body (which is currently the default to be compatible with the iOS app), an auth body could look like this:

    {
    	"strategy": "IOS_DEVICE_ID",
    	"token": "SOMETOKEN"
    }
    

    Let me know your thoughts!

    opened by kevinrmblr 5
  • Ability to update risk level

    Ability to update risk level

    Since a submission now has a risk level associated with it, in theory the authorities could adjust this (say from "very low" to "very high" after they learned you were on a cruise ship).

    The key server should then serve this key up again and the client apps should update their cache.

    Key Server Priority Low 
    opened by HendX 0
  • Schedule a daily notification to remind the user to enable contact tracing

    Schedule a daily notification to remind the user to enable contact tracing

    Daily, every 2 days, whatever..

    Include an option to disable this, otherwise the user may completely disable notifications and therefore miss the important "exposed" notification

    enhancement Priority High 
    opened by HendX 0
  • Server should implement rate limiting for appended keys

    Server should implement rate limiting for appended keys

    After an approved positive diagnosis, user device should continue to submit keys on following days. This is allowed by an authenticated device with a previous submission ID.

    Since the subsequent keys are associated with an existing submission, to avoid having to re-approve the diagnosis each time, the server can simply accept up to 1 key per day for that submission (for X number of days beyond the initial submission).

    Key Server 
    opened by HendX 3
Owner
Crunchy Bagel Pty Ltd
We make iOS, tvOS and Android apps and we blog about Swift.
Crunchy Bagel Pty Ltd
The IDAGIO WatchOS app using swift

IDAGIORedesignWatchOS I redesigned the IDAGIO WatchOS app as an exercise Old App

Francesco Junior Iaccarino 0 Dec 23, 2021
CryptoTrack - iOS app using API to receive updated crypto prices

CryptoTrack Tools used: Swift Xcode by Jose Sahagun jsahagun.io.

Jose Sahagun 0 Jan 3, 2022
CryptoExchange - A fully functional structure for Crypto Exchange app without using many third party assests

cryptoExchange A fully functional structure for Crypto Exchange app without usin

Shwait Kumar 0 Jan 6, 2022
A framework for the JOSE standards JWS, JWE, and JWK written in Swift.

JOSESwift is a modular and extensible framework for the JOSE standards JWS, JWE, and JWK written in Swift. ?? Please note that this implementation of

Airside Mobile, Inc. 162 Dec 15, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Dec 30, 2022
Framework for biometric authentication (via TouchID) in your application

Features Requirements Communication Installation Usage Intro Biometric authentication availability Feature enabled/disabled for biometric authenticati

Igor Vasilenko 29 Sep 16, 2022
Swift framework wrapping CommonCrypto's SHA256 methods.

SHA256-Swift Swift framework wrapping CommonCrypto's SHA256 methods. This is experimental. Do not use this in a production system. Installation instru

Cryptocoin for Swift 70 Dec 26, 2022
Helps you define secure storages for your properties using Swift property wrappers.

?? Secure Property Storage Helps you define secure storages for your properties using Swift property wrappers. ?? Features All keys are hashed using S

Alex Rupérez 443 Jan 4, 2023
Swift cross-platform crypto library using CommonCrypto/libcrypto

BlueCryptor Swift cross-platform crypto library derived from IDZSwiftCommonCrypto. IMPORTANT NOTE: This release is NOT entirely source code compatible

Kitura 183 Oct 15, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

Kitura 122 Dec 16, 2022
Swift cross-platform crypto library using CommonCrypto/libcrypto

BlueCryptor Swift cross-platform crypto library derived from IDZSwiftCommonCrypto. IMPORTANT NOTE: This release is NOT entirely source code compatible

Kitura 183 Oct 15, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

Kitura 122 Dec 16, 2022
A tiny and easy to use Swift class to encrypt strings using HMAC algorithms.

#Sweet HMAC SweetHMAC is a tiny and easy to use Swift class to encrypt strings using HMAC algorithms. A special thanks to jernejstrasner for shared HM

Jan Cássio 37 Jul 27, 2022
a bunch of random programs using Swift

Random-SwiftStuff (WORK IN PROGRESS) a bunch of random programs using Swift: apps mini programs calculators password generators random number generato

Kaival Shah 2 Oct 16, 2021
LocalAuth - Another Fusion library to implement the local authentication using Biometry

FusionLocalAuth Another Fusion library to implement the local authentication usi

Vedant Jha 0 Jan 13, 2022
Oversecured Vulnerable iOS App is an iOS app that aggregates all the platform's known and popular security vulnerabilities.

Description Oversecured Vulnerable iOS App is an iOS app that aggregates all the platform's known and popular security vulnerabilities. List of vulner

Oversecured Inc 135 Dec 15, 2022
APT repository app for jailbroken iOS devices

Find Your Repos! RepoFinder is here to bring you a seamless way to add all of your favorite repositories right into the package manager of your choice

Jacob Singer 25 Dec 20, 2022
Simple class to check if app has been cracked, being debugged or enriched with custom dylib

iOS-App-Security-Class Simple class to check if iOS app has been cracked, being debugged or enriched with custom dylib and as well detect jailbroken e

Unhandled Exception 74 Mar 11, 2022
Demotivator: A simple app for practice

Demotivator This is a simple app for practice. Programmatically Quick recap: .Ph

Dmitry Yatsyuk 0 Dec 17, 2021