Python Implementation of the CoronaWarnApp (CWA) Event Registration

Overview

Python implementation of the Corona-Warn-App (CWA) Event Registration

GitHub PyPI

This is an implementation of the Protocol used to generate event and location QR codes for the Corona-Warn-App (CWA) as described in Corona-Warn-App: Documentation – Event Registration - Summary.

This is not an official implementation – use it at your own risk (as far as that's possible, these days…).

State

The Interface described in the Document is implemented, the undocumented pieces (Public Key Value, Seed Length, Versions etc.) have been taken from the Open Source iOS Client Application. As far as I know the interface has been fully implemented, but without an actual positive Corona Test there is no way to do an End-to-End verification.

Usage

Use as follows:

#!/usr/bin/env python3

import io
from datetime import datetime, time, timezone

import cwa_qr
import qrcode.image.svg

# Construct Event-Descriptor
event_description = cwa_qr.CwaEventDescription()
event_description.location_description = 'Zuhause'
event_description.location_address = 'Gau-Odernheim'
event_description.start_date_time = datetime(2021, 4, 25, 8, 0).astimezone(timezone.utc)
event_description.end_date_time = datetime(2021, 4, 25, 18, 0).astimezone(timezone.utc)
event_description.location_type = cwa_qr.lowlevel.LOCATION_TYPE_PERMANENT_WORKPLACE
event_description.default_check_in_length_in_minutes = 4 * 60

# Renew QR-Code every night at 4:00
event_description.seed = cwa_qr.rollover_date(datetime.now(), time(4, 0))

# Generate QR-Code
qr = cwa_qr.generate_qr_code(event_description)

# Render QR-Code to PNG-File
img = qr.make_image(fill_color="black", back_color="white")
img.save('example.png')
print("generated example.png")

# Render QR-Code to PNG BytesIO-Object for further usage
img_bytes = io.BytesIO()
img.save(img_bytes)
print(len(img_bytes.getvalue()), " bytes of png")

# Render QR-Code to SVG-File
svg = qr.make_image(image_factory=qrcode.image.svg.SvgPathFillImage)
svg.save('example.svg')

# Render QR-Code to SVG BytesIO-Object for further usage
svg_bytes = io.BytesIO()
svg.save(svg_bytes)
print(len(svg_bytes.getvalue()), " bytes of svg")

CwaEventDescription

  • location_description: Description of the Location, Optional, String, max 100 Characters
  • location_address: Address of the Location, Optional, String, max 100 Characters
  • start_date_time: Start of the Event, Optional, datetime in UTC
  • end_date_time: End of the Event, Optional, datetime in UTC Caution, QR-Codes generated with different start/end times will have different Event-IDs and not warn users that have checked in with the other Code. Do not use datetime.now() for start/end-date. For repeating Events use cwa_qr.rollover_date to get a defined rollover.
  • location_type: Type of the Location, Optional, one of
    • cwa.lowlevel.LOCATION_TYPE_UNSPECIFIED = 0
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_OTHER = 1
    • cwa.lowlevel.LOCATION_TYPE_TEMPORARY_OTHER = 2
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_RETAIL = 3
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_FOOD_SERVICE = 4
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_CRAFT = 5
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_WORKPLACE = 6
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_EDUCATIONAL_INSTITUTION = 7
    • cwa.lowlevel.LOCATION_TYPE_PERMANENT_PUBLIC_BUILDING = 8
    • cwa.lowlevel.LOCATION_TYPE_TEMPORARY_CULTURAL_EVENT = 9
    • cwa.lowlevel.LOCATION_TYPE_TEMPORARY_CLUB_ACTIVITY = 10
    • cwa.lowlevel.LOCATION_TYPE_TEMPORARY_PRIVATE_EVENT = 11
    • cwa.lowlevel.LOCATION_TYPE_TEMPORARY_WORSHIP_SERVICE = 12
  • default_check_in_length_in_minutes: Default Check-out time in minutes, Optional
  • seed: Seed to rotate the QR-Code, Optional, [str, bytes, int, float, date, datetime] or None (Default). Use with caution & read below! If unsure, leave blank.

Rotating QR-Codes

From the Documentation:

Profiling of Venues

An adversary can collect this information for a single venue by scanning the QR code and extracting and storing the data. To mitigate the risk, CWA encourages owners to regularly generate new QR codes for their venues. The more frequent QR codes are updated, the more difficult it is to keep a central database with venue data up-to-date. However, a new QR code should only be generated when no visitor is at the event or location, because visitors can only warn each other with the same QR code.

From an Application-Developers point of view, special care must be taken to decide if and when QR codes should be changed. A naive approach, i.e. changing the QR-Code on every call, would render the complete Warning-Chain totally useless without anyone noticing. Therefore, the Default of this Library as of 2021/04/26 is to not seed the QR-Codes with random values. This results in every QR-Code being generated without an explicit Seed to be identical, which minimizes the Risk of having QR-Codes that do not warn users as expected at the increased risk of profiling of Venues.

As an Application-Developer you are encouraged to ask you user if and when they want their QR-Codes to change and explain to them that they should only rotate their Codes when they are sure that nobody is at the location or in the venue for at least 30 Minutes, to allow airborne particles to settle or get filtered out. Do not make assumptions regarding a good time to rotate QR-Codes (i.e. always at 4:00 am) because they will fail so warn people in some important Situations (nightclubs, hotels, night-shift working) without anyone noticing.

To disable rotation of QR-Codes, specify None as the Seed (Default behaviour).

The Library also gives you a utility to allow rotating QR-Codes at a given time of the day. Please make sure to also integrate some kind of Secret into the seed, to prevent an adversary from calculating future QR-Codes. The Secret must stay constant over time, or the resulting QR-Codes will not correctly trigger warnings.

import io
from datetime import datetime, time

import cwa_qr

# Construct Event-Descriptor
event_description = cwa_qr.CwaEventDescription()
# …
seed_date = cwa_qr.rollover_date(datetime.now(), time(4, 0))
event_description.seed = "Some Secret" + str(seed_date)

this will keep the date-based seed until 4:00 am on the next day and only then roll over to the next day. See test_rollover.py for an in-depth look at the rollover code.

Python 2/3

This library supports Python 3.6+, however there is a backport to Python 2 available at https://github.com/MaZderMind/cwa-qr/tree/py2

Comments
  • Add poster generating capabilities

    Add poster generating capabilities

    This PR adds a small helper class/function to generate CWA-posters.

    Two layouts are included - the official portrait one as well as a landscape-version which has been inspired by the first one.

    Since I'm not very good at graphics stuff, this might not be the best way to achieve the desired result - so feel free to discard this PR if it's not up to your standards :-)

    (Since I ìsorted the imports of the files I touched with this PR, some sorting of the imports has occurred)

    opened by pc-coholic 5
  • Change Default to not Seed QR-Codes and provide Utility for custom rollover Seed

    Change Default to not Seed QR-Codes and provide Utility for custom rollover Seed

    From the Documentation:

    Profiling of Venues

    An adversary can collect this information for a single venue by scanning the QR code and extracting and storing the data. To mitigate the risk, CWA encourages owners to regularly generate new QR codes for their venues. The more frequent QR codes are updated, the more difficult it is to keep a central database with venue data up-to-date. However, a new QR code should only be generated when no visitor is at the event or location, because visitors can only warn each other with the same QR code.

    From an Application-Developers point of view, special care must be taken to decide if and when QR codes should be changed. A naive approach, i.e. changing the QR-Code on every call, would render the complete Warning-Chain totally useless without anyone noticing. Therefore, the Default of this Library changed in this PR is to not seed the QR-Codes with random values. This results in every QR-Code being generated without an explicit Seed to be identical, which minimizes the Risk of having QR-Codes that do not warn users as expected at the increased risk of profiling of Venues.

    As an Application-Developer you are encouraged to ask you user if and when they want their QR-Codes to change and explain to them that they should only rotate their Codes when they are sure that nobody is at the location or in the venue for at least 30 Minutes, to allow airborne particles to settle or get filtered out. Do not make assumptions regarding a good time to rotate QR-Codes (i.e. always at 4:00 am) because they will fail so warn people in some important Situations (nightclubs, hotels, night-shift working) without anyone noticing.

    To disable rotation of QR-Codes, specify None as the Seed (Default behaviour). This PR gives authors a utility to allow rotating QR-Codes at a time of day specified by your user:

    import io
    from datetime import datetime, time
    
    import cwa
    
    # Construct Event-Descriptor
    eventDescription = cwa.CwaEventDescription()
    # …
    eventDescription.seed = cwa.rolloverDate(datetime.now(), time(4, 0))
    

    this will keep the date-based seed until 4:00 am on the next day and only then roll over to the next day. See test_rollover.py for an in-depth look at the rollover code.

    opened by MaZderMind 4
  • Bump pillow from 8.3.2 to 9.0.0

    Bump pillow from 8.3.2 to 9.0.0

    Bumps pillow from 8.3.2 to 9.0.0.

    Release notes

    Sourced from pillow's releases.

    9.0.0

    https://pillow.readthedocs.io/en/stable/releasenotes/9.0.0.html

    Changes

    ... (truncated)

    Changelog

    Sourced from pillow's changelog.

    9.0.0 (2022-01-02)

    • Restrict builtins for ImageMath.eval(). CVE-2022-22817 #5923 [radarhere]

    • Ensure JpegImagePlugin stops at the end of a truncated file #5921 [radarhere]

    • Fixed ImagePath.Path array handling. CVE-2022-22815, CVE-2022-22816 #5920 [radarhere]

    • Remove consecutive duplicate tiles that only differ by their offset #5919 [radarhere]

    • Improved I;16 operations on big endian #5901 [radarhere]

    • Limit quantized palette to number of colors #5879 [radarhere]

    • Fixed palette index for zeroed color in FASTOCTREE quantize #5869 [radarhere]

    • When saving RGBA to GIF, make use of first transparent palette entry #5859 [radarhere]

    • Pass SAMPLEFORMAT to libtiff #5848 [radarhere]

    • Added rounding when converting P and PA #5824 [radarhere]

    • Improved putdata() documentation and data handling #5910 [radarhere]

    • Exclude carriage return in PDF regex to help prevent ReDoS #5912 [hugovk]

    • Fixed freeing pointer in ImageDraw.Outline.transform #5909 [radarhere]

    • Added ImageShow support for xdg-open #5897 [m-shinder, radarhere]

    • Support 16-bit grayscale ImageQt conversion #5856 [cmbruns, radarhere]

    • Convert subsequent GIF frames to RGB or RGBA #5857 [radarhere]

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • CWA-Posters

    CWA-Posters

    This builds upon and supersedes #9

    This PR adds a small helper class/function to generate CWA-posters. Two layouts are included - the official portrait one as well as a landscape-version which has been inspired by the first one.

    Thanks to @pc-coholic for doing the hard work ;)

    opened by MaZderMind 1
  • Add explicit exports to the main module

    Add explicit exports to the main module

    I'm not a 100% sure on this since this isn't on PyPI and I just copied the cwa module as suggested in the README. However, I think the example in the README is wrong when it says

    import cwa
    …
    eventDescription = cwa.CwaEventDescription()
    

    It should either be

    from cwa import cwa
    

    Or the cwa main module should expose the public API directly, as this PR proposes.

    opened by raphaelm 1
  • Fix README

    Fix README

    The README file contains some typos and capitalization mistakes. This PR aims to fix that in order to make the file more aesthetically pleasing.

    Many thanks for creating this tool.

    opened by fynngodau 1
  • Loosen version requirements

    Loosen version requirements

    It makes sense for a Python project to pin specific versions, but it can be annoying for a dependency. In our case, we could not use cwa-qr in an environment where we also use protobuf 3.19, even though they work fine together. I therefore propose loosening the constraint.

    opened by raphaelm 0
  • Bump pillow from 8.2.0 to 8.3.2

    Bump pillow from 8.2.0 to 8.3.2

    Bumps pillow from 8.2.0 to 8.3.2.

    Release notes

    Sourced from pillow's releases.

    8.3.2

    https://pillow.readthedocs.io/en/stable/releasenotes/8.3.2.html

    Security

    • CVE-2021-23437 Raise ValueError if color specifier is too long [hugovk, radarhere]

    • Fix 6-byte OOB read in FliDecode [wiredfool]

    Python 3.10 wheels

    • Add support for Python 3.10 #5569, #5570 [hugovk, radarhere]

    Fixed regressions

    • Ensure TIFF RowsPerStrip is multiple of 8 for JPEG compression #5588 [kmilos, radarhere]

    • Updates for ImagePalette channel order #5599 [radarhere]

    • Hide FriBiDi shim symbols to avoid conflict with real FriBiDi library #5651 [nulano]

    8.3.1

    https://pillow.readthedocs.io/en/stable/releasenotes/8.3.1.html

    Changes

    8.3.0

    https://pillow.readthedocs.io/en/stable/releasenotes/8.3.0.html

    Changes

    ... (truncated)

    Changelog

    Sourced from pillow's changelog.

    8.3.2 (2021-09-02)

    • CVE-2021-23437 Raise ValueError if color specifier is too long [hugovk, radarhere]

    • Fix 6-byte OOB read in FliDecode [wiredfool]

    • Add support for Python 3.10 #5569, #5570 [hugovk, radarhere]

    • Ensure TIFF RowsPerStrip is multiple of 8 for JPEG compression #5588 [kmilos, radarhere]

    • Updates for ImagePalette channel order #5599 [radarhere]

    • Hide FriBiDi shim symbols to avoid conflict with real FriBiDi library #5651 [nulano]

    8.3.1 (2021-07-06)

    • Catch OSError when checking if fp is sys.stdout #5585 [radarhere]

    • Handle removing orientation from alternate types of EXIF data #5584 [radarhere]

    • Make Image.array take optional dtype argument #5572 [t-vi, radarhere]

    8.3.0 (2021-07-01)

    • Use snprintf instead of sprintf. CVE-2021-34552 #5567 [radarhere]

    • Limit TIFF strip size when saving with LibTIFF #5514 [kmilos]

    • Allow ICNS save on all operating systems #4526 [baletu, radarhere, newpanjing, hugovk]

    • De-zigzag JPEG's DQT when loading; deprecate convert_dict_qtables #4989 [gofr, radarhere]

    • Replaced xml.etree.ElementTree #5565 [radarhere]

    ... (truncated)

    Commits
    • 8013f13 8.3.2 version bump
    • 23c7ca8 Update CHANGES.rst
    • 8450366 Update release notes
    • a0afe89 Update test case
    • 9e08eb8 Raise ValueError if color specifier is too long
    • bd5cf7d FLI tests for Oss-fuzz crash.
    • 94a0cf1 Fix 6-byte OOB read in FliDecode
    • cece64f Add 8.3.2 (2021-09-02) [CI skip]
    • e422386 Add release notes for Pillow 8.3.2
    • 08dcbb8 Pillow 8.3.2 supports Python 3.10 [ci skip]
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Change API to Python-Style

    Change API to Python-Style

    I do too much java… therefore the API does not use snake_case for methods and variables. This should be changed before a tagged & published release.

    Also the Module-Name should be changed to "cwa_qr" to match the Github-Name.

    opened by MaZderMind 0
  • qr-code alignment on poster

    qr-code alignment on poster

    First of all: Thank you! That's great work.

    I have just a little design issue: example_full.py generates a svg_bytes with 70198 bytes length. With that amount of data the qr-code is aligned into the center of the poster/portrait.svg

    In my test i had smaller amounts of data in my event_description. And with e.g. only 61444 bytes you get a smaller qr-code and its alignment is a little more left then it should be. Perhaps it would help to check svg_bytes.getbuffer().nbytes to determine the necessary scale dynamically

    (i guess with the landscape template it is the same, but i didn't test it.) grafik

    opened by wolf128058 1
Releases(v1.2.2)
Owner
MaZderMind
Program everything.
MaZderMind
Torchyolo - Yolov3 ve Yolov4 modellerin Pytorch uygulamasıdır

TORCHYOLO : Yolo Modellerin Pytorch Uygulaması Yapılacaklar: Yolov3 model.py ve

Kadir Nar 3 Aug 22, 2022
Locationinfo - A script helps the user to show network information such as ip address

Description This script helps the user to show network information such as ip ad

Roxcoder 1 Dec 30, 2021
Tensorflow2.0 🍎🍊 is delicious, just eat it! 😋😋

How to eat TensorFlow2 in 30 days ? 🔥 🔥 Click here for Chinese Version(中文版) 《10天吃掉那只pyspark》 🚀 github项目地址: https://github.com/lyhue1991/eat_pyspark

lyhue1991 9.7k Jan 01, 2023
Large scale embeddings on a single machine.

Marius Marius is a system under active development for training embeddings for large-scale graphs on a single machine. Training on large scale graphs

Marius 107 Jan 03, 2023
TensorFlow Similarity is a python package focused on making similarity learning quick and easy.

TensorFlow Similarity is a python package focused on making similarity learning quick and easy.

912 Jan 08, 2023
Code release for General Greedy De-bias Learning

General Greedy De-bias for Dataset Biases This is an extention of "Greedy Gradient Ensemble for Robust Visual Question Answering" (ICCV 2021, Oral). T

4 Mar 15, 2022
This repository contains notebook implementations of the following Neural Process variants: Conditional Neural Processes (CNPs), Neural Processes (NPs), Attentive Neural Processes (ANPs).

The Neural Process Family This repository contains notebook implementations of the following Neural Process variants: Conditional Neural Processes (CN

DeepMind 892 Dec 28, 2022
Code for Two-stage Identifier: "Locate and Label: A Two-stage Identifier for Nested Named Entity Recognition"

Code for Two-stage Identifier: "Locate and Label: A Two-stage Identifier for Nested Named Entity Recognition", accepted at ACL 2021. For details of the model and experiments, please see our paper.

tricktreat 87 Dec 16, 2022
Circuit Training: An open-source framework for generating chip floor plans with distributed deep reinforcement learning

Circuit Training: An open-source framework for generating chip floor plans with distributed deep reinforcement learning. Circuit Training is an open-s

Google Research 479 Dec 25, 2022
A chemical analysis of lipophilicities & molecule drawings including ML

A chemical analysis of lipophilicity & molecule drawings including a bit of ML analysis. This is a simple project that includes two Jupyter files (one

Aurimas A. Nausėdas 7 Nov 22, 2022
Official PyTorch implementation of "RMGN: A Regional Mask Guided Network for Parser-free Virtual Try-on" (IJCAI-ECAI 2022)

RMGN-VITON RMGN: A Regional Mask Guided Network for Parser-free Virtual Try-on In IJCAI-ECAI 2022(short oral). [Paper] [Supplementary Material] Abstra

27 Dec 01, 2022
FedScale: Benchmarking Model and System Performance of Federated Learning

FedScale: Benchmarking Model and System Performance of Federated Learning (Paper) This repository contains scripts and instructions of building FedSca

268 Jan 01, 2023
BADet: Boundary-Aware 3D Object Detection from Point Clouds (Pattern Recognition 2022)

BADet: Boundary-Aware 3D Object Detection from Point Clouds (Pattern Recognition

Rui Qian 17 Dec 12, 2022
A Python library created to assist programmers with complex mathematical functions

libmaths libmaths was created not only as a learning experience for me, but as a way to make mathematical models in seconds for Python users using mat

Simple 73 Oct 02, 2022
A simple command line tool for text to image generation, using OpenAI's CLIP and a BigGAN.

Ryan Murdock has done it again, combining OpenAI's CLIP and the generator from a BigGAN! This repository wraps up his work so it is easily accessible to anyone who owns a GPU.

Phil Wang 2.3k Jan 09, 2023
QKeras: a quantization deep learning library for Tensorflow Keras

QKeras github.com/google/qkeras QKeras 0.8 highlights: Automatic quantization using QKeras; Stochastic behavior (including stochastic rouding) is disa

Google 437 Jan 03, 2023
Training data extraction on GPT-2

Training data extraction from GPT-2 This repository contains code for extracting training data from GPT-2, following the approach outlined in the foll

Florian Tramer 62 Dec 07, 2022
A Human-in-the-Loop workflow for creating HD images from text

A Human-in-the-Loop? workflow for creating HD images from text DALL·E Flow is an interactive workflow for generating high-definition images from text

Jina AI 2.5k Jan 02, 2023
public repo for ESTER dataset and modeling (EMNLP'21)

Project / Paper Introduction This is the project repo for our EMNLP'21 paper: https://arxiv.org/abs/2104.08350 Here, we provide brief descriptions of

PlusLab 19 Oct 27, 2022
Code, Models and Datasets for OpenViDial Dataset

OpenViDial This repo contains downloading instructions for the OpenViDial dataset in 《OpenViDial: A Large-Scale, Open-Domain Dialogue Dataset with Vis

119 Dec 08, 2022