This is part of a larger epic integrating the new PIU prototype.
Part of this work has been done in relation to #33 but there needs to be more work both on the client side (DIU) and server side.
Overview
New DIUs should accept QR codes as fare media.
QR codes should be generated so that riders can present them to the camera (new PIU) and be accepted
Preliminarily, the QR code will map to an underlying fare media (magstripe for now)
To prevent snooping a public/private string will be distributed to the DIUs coordinated through the server (discussed below)
Technical Overview
QR codes are of the form @<pubkey>%<b64(xor(privkey,credential))>$
The server will keep a list of (pubkey,privkey) pairs, along with a flag to denote whether it's been used or not (stored in a DB table)
The server will setup a new fareqr server that will listen to DIU connections and push out the current snapshot of active (pubkey,privkey) pairs
This should be the same idea as the active_rider_table in that the DIU will offer the current sequence number it has locally and the server will give the delta changes from the reported sequence number to the most active
The server will listen (either through the new fareqr server or listening for some type of debug/diagnostic billing log message) for fareqr updates from the DIUs that use them to invalidate any (pubkey,privkey) pair that's been used
The DIU will keep a local database of (pubkey,privkey) along with whether they are active or have been deactivated locally
The DIU will update the billdb daemon to listen for /Q:... messages from the new PIU
The /Q:... message will have the payload as described above
The privkey will be retrieved from the local DIU database, using pubkey as the lookup
The credential will be retrieved from the decoded (base64 and XOR with privkey) payload and be processed as normal
Once a DIU has received fareqr message locally, it will send a local FAREQR message
A new daemon local to the DIU will listen for FAREQR messages and connect back to the server to push out which (pubkey,privkey) pair has been used
Motivation
If a rider creates a QR code for a fare, as a PDF say, the resulting QR code should:
not be able to be used more than once
as a precaution, someone seeing the QR code should not be able to deduce the underlying credential information
Issuing a one time pubkey allows the private key to be looked up when needed. Stuffing in information into the payload of the fareqr string without knowledge of the privkey or credential will lead to a random string which will lead to a random nonsensical credential.
A rider with knowledge of their credential could deduce the privkey but this can only be used to create a new fareqr string for a valid credential, so perhaps this is fine (?).
The server needs to communicate the key pairs to the fleet and the fleet needs to communicate back which key pairs have been used. In addition, the change to the infrastructure should be as light as possible and not disrupt legacy DIUs connecting back to the server.
Since the server side fareqr server will be "opt-in" from new DIUs that have the daemon local to connect server side, this should have no impact on legacy DIUs.
TODO
Setup server side table for key pairs
work out structure, specifically the sequence number issue
Setup server side daemon to update the database table, receive messages from the DIU about key pair updates and distribute key pair updates to DIUs that connect to it
Setup the DIU daemon to manage the key pairs locally, listen to local messages of key pair updates and communicate back to the server
Setup example web application that will generate a fareqr string given a magstripe credential for testing/demo purposes
This is part of a larger epic integrating the new PIU prototype.
Part of this work has been done in relation to #33 but there needs to be more work both on the client side (DIU) and server side.
Overview
---
New DIUs should accept QR codes as fare media.
* QR codes should be generated so that riders can present them to the camera (new PIU) and be accepted
* Preliminarily, the QR code will map to an underlying fare media (magstripe for now)
* To prevent snooping a public/private string will be distributed to the DIUs coordinated through the server (discussed below)
Technical Overview
---
* QR codes are of the form `@<pubkey>%<b64(xor(privkey,credential))>$`
* The server will keep a list of `(pubkey,privkey)` pairs, along with a flag to denote whether it's been used or not (stored in a DB table)
* The server will setup a new `fareqr` server that will listen to DIU connections and push out the current snapshot of active `(pubkey,privkey)` pairs
- This should be the same idea as the `active_rider_table` in that the DIU will offer the current sequence number it has locally and the server will give the delta changes from the reported sequence number to the most active
* The server will listen (either through the new `fareqr` server or listening for some type of debug/diagnostic billing log message) for `fareqr` updates from the DIUs that use them to invalidate any `(pubkey,privkey)` pair that's been used
* The DIU will keep a local database of `(pubkey,privkey)` along with whether they are active or have been deactivated locally
* The DIU will update the `billdb` daemon to listen for `/Q:...` messages from the new PIU
- The `/Q:...` message will have the payload as described above
- The `privkey` will be retrieved from the local DIU database, using `pubkey` as the lookup
- The credential will be retrieved from the decoded (base64 and XOR with `privkey`) payload and be processed as normal
* Once a DIU has received `fareqr` message locally, it will send a local FAREQR message
* A new daemon local to the DIU will listen for FAREQR messages and connect back to the server to push out which `(pubkey,privkey)` pair has been used
Motivation
---
If a rider creates a QR code for a fare, as a PDF say, the resulting QR code should:
* not be able to be used more than once
* as a precaution, someone seeing the QR code should not be able to deduce the underlying credential information
Issuing a one time `pubkey` allows the private key to be looked up when needed. Stuffing in information into the payload of the `fareqr` string without knowledge of the `privkey` or credential will lead to a random string which will lead to a random nonsensical credential.
A rider with knowledge of their credential could deduce the `privkey` but this can only be used to create a new `fareqr` string for a valid credential, so perhaps this is fine (?).
The server needs to communicate the key pairs to the fleet and the fleet needs to communicate back which key pairs have been used. In addition, the change to the infrastructure should be as light as possible and not disrupt legacy DIUs connecting back to the server.
Since the server side `fareqr` server will be "opt-in" from new DIUs that have the daemon local to connect server side, this should have no impact on legacy DIUs.
TODO
---
* Setup server side table for key pairs
- work out structure, specifically the sequence number issue
* Setup server side daemon to update the database table, receive messages from the DIU about key pair updates and distribute key pair updates to DIUs that connect to it
* Setup the DIU daemon to manage the key pairs locally, listen to local messages of key pair updates and communicate back to the server
* Setup example web application that will generate a `fareqr` string given a magstripe credential for testing/demo purposes
On further reflection, using AES encryption might be better.
The fareqr code is constructed in much the same way except for the encrypted portion, which is now done with AES. The possibility of someone acting in bad faith to deduce the underlying secret keys is mitigated.
fareqr.c has the relevant code as well as a standalone program that can be used to explore some of the functionality. (see fareqr.c in busunit/passdb)
On further reflection, using AES encryption might be better.
The `fareqr` code is constructed in much the same way except for the encrypted portion, which is now done with AES. The possibility of someone acting in bad faith to deduce the underlying secret keys is mitigated.
`fareqr.c` has the relevant code as well as a standalone program that can be used to explore some of the functionality. (see [fareqr.c](https://tree.clementinecomputing.com/clementinecomputing/popufare/src/release/busunit/passdb/fareqr.c) in `busunit/passdb`)
This is part of a larger epic integrating the new PIU prototype.
Part of this work has been done in relation to #33 but there needs to be more work both on the client side (DIU) and server side.
Overview
New DIUs should accept QR codes as fare media.
Technical Overview
@<pubkey>%<b64(xor(privkey,credential))>$(pubkey,privkey)pairs, along with a flag to denote whether it's been used or not (stored in a DB table)fareqrserver that will listen to DIU connections and push out the current snapshot of active(pubkey,privkey)pairsactive_rider_tablein that the DIU will offer the current sequence number it has locally and the server will give the delta changes from the reported sequence number to the most activefareqrserver or listening for some type of debug/diagnostic billing log message) forfareqrupdates from the DIUs that use them to invalidate any(pubkey,privkey)pair that's been used(pubkey,privkey)along with whether they are active or have been deactivated locallybilldbdaemon to listen for/Q:...messages from the new PIU/Q:...message will have the payload as described aboveprivkeywill be retrieved from the local DIU database, usingpubkeyas the lookupprivkey) payload and be processed as normalfareqrmessage locally, it will send a local FAREQR message(pubkey,privkey)pair has been usedMotivation
If a rider creates a QR code for a fare, as a PDF say, the resulting QR code should:
Issuing a one time
pubkeyallows the private key to be looked up when needed. Stuffing in information into the payload of thefareqrstring without knowledge of theprivkeyor credential will lead to a random string which will lead to a random nonsensical credential.A rider with knowledge of their credential could deduce the
privkeybut this can only be used to create a newfareqrstring for a valid credential, so perhaps this is fine (?).The server needs to communicate the key pairs to the fleet and the fleet needs to communicate back which key pairs have been used. In addition, the change to the infrastructure should be as light as possible and not disrupt legacy DIUs connecting back to the server.
Since the server side
fareqrserver will be "opt-in" from new DIUs that have the daemon local to connect server side, this should have no impact on legacy DIUs.TODO
fareqrstring given a magstripe credential for testing/demo purposesOn further reflection, using AES encryption might be better.
The
fareqrcode is constructed in much the same way except for the encrypted portion, which is now done with AES. The possibility of someone acting in bad faith to deduce the underlying secret keys is mitigated.fareqr.chas the relevant code as well as a standalone program that can be used to explore some of the functionality. (see fareqr.c inbusunit/passdb)