kee

Offline IOU signer with QR as transport
git clone git://holbrook.no/kee-gtk4.git
Info | Log | Files | Refs | README | LICENSE

README.md (11890B)


      1 # kee
      2 
      3 **The upstream respository is [git://holbrook.no/kee-gtk4.git](git://holbrook.no/kee-gtk4.git)**
      4 
      5 I am building a cryptographically counter-signed IOU application with linux phones ([GTK4](https://www.gtk.org/), [phosh](https://phosh.mobi/)) as the primary targets.
      6 
      7 It will maintain bi-lateral mutual channels of credit and collateral. Each change is linked as a chain, and documentation for each change in embedded as [email-link MIME structures](https://datatracker.ietf.org/doc/html/rfc2049)
      8 
      9 It is currently in alpha state, and does not yet have a friendly introduction.
     10 
     11 See "Protocol" and "Concepts" headings below for more details on what this actually is aiming to become.
     12 
     13 
     14 ## What it can do (currently)
     15 
     16 The UI state is still fragmented and does not yet implement a full sequence of actions for creating and mutually signing ledger.
     17 
     18 However, a ledger can be created, counter-signed and imported by restarting UI as Alice, Bob and Alice respectively, and manually use the import option.
     19 
     20 What it _does_ have is:
     21 
     22 * GTK interface pages for
     23     - Unlock wallet key
     24     - List IOUs
     25     - List IOU details and deltas (transactions)
     26     - Import data and/or delta (QR or pasted text)
     27     - Import summary and accept page
     28     - Create new ledger entry page
     29 * Testdata generator for tests and demonstrating state of UI:
     30     - Create keys for Alice and (main) Bob, as well as two additional Bobs
     31     - Symlinks to use (main) Bob key instead of Alice as identity for UI
     32     - A configurable number of randomized ledger entries and deltas
     33 * CLI tool:
     34     - Show details about a ledger entry
     35     - Sign a ledger delta
     36     
     37 
     38 ## Dependencies
     39 
     40 Below are the library versions of the [archlinux](https://archlinux.org/) component packages I am using for dependencies and tooling while working on my own system.
     41 
     42 | package | version |
     43 |---|---|
     44 | gcc | 13.2.1 |
     45 | graphicsmagick | 1.3.42 |
     46 | gst-plugins-bad  | 1.24.0 |
     47 | gstreamer | 1.24.0 |
     48 | gtk4 | 4.12.5 |
     49 | libb64 | 1.2.1 |
     50 | libgcrypt | 1.10.3 |
     51 | qrencode | 4.1.1 |
     52 | libxdg-basedir | 1.2.3 |
     53 | lmdb | 0.9.32 |
     54 | openldap | 2.6.7 |
     55 | rustup | 1.26.0 |
     56 | zbar | 0.23.90 |
     57 | zlib | 1.3.1 |
     58 
     59 The `gst-plugins-bad` provides [libgstzbar.so](https://gstreamer.freedesktop.org/documentation/zbar/index.html?gi-language=c#zbar-page), used as part of QR scanning.
     60 
     61 
     62 ### Other sources
     63 
     64 The code expects objects from these source trees to be available somehow:
     65 
     66 |project | upstream source | version | tar.gz sha256 |
     67 |---|---|---|---|
     68 | liblash* | [https://holbrook.no/src/liblash](https://holbrook.no/src/liblash) `(193dd4032e8088ada2dc9dcedab8d7486e9305f5)` | `0.1.0` | `333cdf49bb7e9f44b37e5bc9f594a01e4b3b8ecb3fcd3d9ffec3ea6dcdeaec7b` |
     69 | libcmime | [https://github.com/spmfilter/libcmime.git](https://github.com/spmfilter/libcmime.git) `(dd21eb096d162656e30243f60fc4bc35ad39ae6e)` | `0.2.2` | `18a8d46ebec575a79212acc2dc6af7fd7bdeba3a9b85a70677ed0b7785c5c04e` |
     70 | gst-plugins-rs | [https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs) `(a84bbc66f30573b62871db163c48afef75adf6ec)` | `1.22.10 (gstreamer)` | `691d5d52f59ec6322a2f6ddc1039ef47c9ac5e6328e2df1ef920629b46c659df` |
     71 
     72 You can clone `liblash` with `git clone git://holbrook.no/liblash`
     73 
     74 (\*liblash is now bundled in the `src/aux` directory)
     75 
     76 
     77 ## Building
     78 
     79 **There are instructions on building and running with [qemu](https://www.qemu.org/) and [Debian Bookworm (12)](https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso) in `README.qemu.adoc`**
     80 
     81 There is no magic pathfinder implemented currently. Thus, you must configure the environment for building and linking the external sources yourself.
     82 
     83 Here is what I use in my local setup.
     84 
     85 
     86 ### libcmime
     87 
     88 I can't seem to set the cmake build prefix so that the `libcmime.pc` file is generated correctly. Unfortunately, `pkg-config` is thus off the table.
     89 
     90 ```
     91 git clone -b 0.2.2 https://github.com/spmfilter/libcmime.git
     92 https://github.com/spmfilter/libcmime.git
     93 mkdir -p libcmime/build
     94 cd libcmime/build
     95 cmake ..
     96 make install DESTDIR=.
     97 ```
     98 
     99 Your include path, relative to the repository root directory, will be `<repo_root>/build/usr/include/lib64` and your ld path will be `build/usr/include/lib64`.
    100 
    101 
    102 ### libgstgtk4 (gst-plugin-rs)
    103 
    104 The `gtk4` part of the code uses the `gtk4paintablesink` gstreamer plugin (for QR scanning). It is part of the `gst-plugins-rs` source above, built as the `libgstgtk4.so` shared library file.
    105 
    106 The specific package to build is `gst-plugin-gtk4`, which builds the plugin at version `0.9.13`.
    107 
    108 I was able to build with toolchain `1.75-x86_64-unknown-linux-gnu`.
    109 
    110 ```
    111 rustup default 1.75.0
    112 cargo install cargo-c
    113 git clone -b gstreamer-1.22.10 https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs
    114 cd gst-plugins-rs
    115 cargo cbuild -p gst-plugin-gtk4
    116 ```
    117 
    118 
    119 ## Environment 
    120 
    121 ```
    122 #!/bin/bash
    123 
    124 set -x
    125 
    126 export GST_PLUGIN_PATH=/home/lash/src/build/gst-plugins-rs/target/x86_64-unknown-linux-gnu/debug/
    127 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64/pkgconfig
    128 export LIBRARY_PATH=$LIBRARY_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64:/home/lash/src/home/liblash/src
    129 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64:/home/lash/src/home/liblash/src
    130 export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/include:/home/lash/src/home/liblash/src
    131 
    132 make run
    133 
    134 set +x
    135 ```
    136 
    137 Here is some background if you need:
    138 
    139 * [C_INCLUDE_PATH](https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html)
    140 * [LIBRARY_PATH](https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-LIBRARY_005fPATH)
    141 * [LD_LIBRARY_PATH](https://www.man7.org/linux/man-pages/man8/ld.so.8.html#ENVIRONMENT)
    142 * [Difference between LD_LIBRARY_PATH and LIBRARY_PATH](https://www.baeldung.com/linux/library_path-vs-ld_library_path)
    143 * [PKG_CONFIG_PATH](https://man.archlinux.org/man/pkgconf.1.en#ENVIRONMENT)
    144 * [GST_PLUGIN_PATH](https://gstreamer.freedesktop.org/documentation/gstreamer/running.html?gi-language=c)
    145 * [cargo-c](https://github.com/lu-zero/cargo-c)
    146 
    147 
    148 ## Running
    149 
    150 In order to run the GTK application in its current condition, generated test data should be used as data path.
    151 
    152 Take care to install python dependencies in `requirements.txt` before the first command. Using a [virtual environment](https://docs.python.org/3/library/venv.html) is recommended. The author is using `python 3.12.x`.
    153 
    154 ```
    155 make testdata
    156 export KEE_PATH=$(realpath ./testdata)
    157 make run
    158 ``` 
    159 
    160 The testdata contains private keys for both Alice and Bob in the generated entries. To start as Bob, add before running:
    161 
    162 ```
    163 export KEE_KEY_PATH=$(realpath ./testdata/crypt_reverse)
    164 ```
    165 
    166 
    167 ## Protocol
    168 
    169 TODO: The terms need to be tightened up; don't use different terms for same thing.
    170 
    171 The serialization format of the credit issuance is defined in `src/asb1/schema_entry.txt`. The serialization method is _der-encoding_.
    172 
    173 More about `asn1` here: [https://luca.ntop.org/Teaching/Appunti/asn1.html](https://luca.ntop.org/Teaching/Appunti/asn1.html).
    174 
    175 
    176 The protocol uses Elliptic Curve signatures. The curve used is `Ed25519`.
    177 
    178 
    179 ### Concepts
    180 
    181 The protocol consists of a series of ledgers, each with two participants, Alice and Bob.
    182 
    183 Alice and Bob are identified by their public keys.
    184 
    185 The protocol tracks an amount of credit issued by one party to another.
    186 
    187 The ledger may also define an amount of collateral that has been pledged against the credit.
    188 
    189 Credit and collateral are defined by a unit of account, which is defined for the entire ledger.
    190 
    191 Each credit issuance consists of one or more deltas (KeeEntry) changing the balance of the credit, and some identical metadata (KeeEntryHead) embedded in each one, together called an _entry item_.
    192 
    193 
    194 ### Creating a new entry
    195 
    196 We call the creator of the entry Alice.
    197 
    198 The default values of `signatureRequest` and `signatureResponse` is an empty octet string (length 0).
    199 
    200 The default value for `response` is `False`.
    201 
    202 If the entry is the first in the ledger, the value of `parent` is 64 0-bytes. If not, it is the sha512 sum of the preceding _entry item_.
    203 
    204 Alice generates the _entry item_ and signs it:
    205 
    206 ```
    207 head = der(KeeEntryHead)
    208 headsum = sha512(head)
    209 entry = der(KeeEntry)
    210 msg = sha512(concat(head, entry))
    211 sig = sign(msg) # TODO verify whether an additional sha512 on the message is performed by the internals
    212 copy(KeeEntry.signatureRequest, sig)
    213 ```
    214 
    215 ### Counter-signing an entry
    216 
    217 Alice shares KeeEntryHead and KeeEntry with Bob.
    218 
    219 Bob verifies Alice's signature.
    220 
    221 If Bob accepts the contents of the _entry item_, he sets `response` to `True`.
    222 
    223 Bob proceeds to sign the _entry item_:
    224 
    225 ```
    226 set(KeeEntry.response, bobs_decision)
    227 head = der(KeeEntryHead)
    228 headsum = sha512(head)
    229 entry = der(KeeEntry)
    230 msg = sha512(concat(head, entry)
    231 sig = sign(msg)
    232 copy(KeeEntry.signatureResponse, sig)
    233 ```
    234 
    235 Bob then adds the counter-signed _entry item_ to his persistent storage.
    236 
    237 
    238 ### Sharing the result
    239 
    240 Bob shares KeeEntryHead and KeeEntry with Alice.
    241 
    242 Alice verifies both signatures.
    243 
    244 Alice adds the counter-signed _entry_item_ to her persistent storage.
    245 
    246 Alice and Bob now have the same ledger state, adjusted by the deltas in the _entry item_.
    247 
    248 
    249 ### Sanity checks
    250 
    251 Checking that the delta in an _entry item_ makes sense is the responsibility of both parties, e.g. that the delta does not incur a negative credit value.
    252 
    253 
    254 ### Descriptive content
    255 
    256 Both the KeeEntryHead and KeeEntry structures include an optional `body` value, which is a sha512 hash of some content offering some description of what the ledger and individual changes consist of. If no description is provided, 64 0-bytes are used for the data field.
    257 
    258 This implementation uses, as previously mentioned, [MIME-structures](https://datatracker.ietf.org/doc/html/rfc2049) for this purpose.
    259 
    260 
    261 ## Data carriers
    262 
    263 A final implementation should define several ways of sharing content, including:
    264 
    265 * Copy and paste 
    266 * File sharing
    267 * Network retrieval
    268 * QR codes
    269 This implementation uses QR codes to exchange signature requests and signatures.
    270 
    271 
    272 ### QR exchange
    273 
    274 A separate transport container, `KeeTransport`, is used for this exchange, as well as some additional encoding.
    275 
    276 ```
    277 container = KeeTransport(KeeEntryHead, KeeEntry)
    278 raw = der(container)
    279 compressed = zlib_compress(raw)
    280 payload = base64(compressed)
    281 transport = concat(0x02, readable) # 0x02 = KEE_CMD_LEDGER, defined in src/transport.h
    282 qrencode(transport)
    283 ```
    284 
    285 
    286 #### Sharing descriptive content
    287 
    288 Descriptive content is currently not shared as part of the signature exchange.
    289 
    290 Since decriptive content can potentially be of some size, a transport protocol should be considered which can span multiple sequential QR codes, and allow of the same kind of offline exchange as the signature exchange itself.
    291 
    292 
    293 ## Examples
    294 
    295 The `make testdata` script creates several useful data examples:
    296 
    297 - `testdata/mdb` which is the persistent storage of a ledger and required indicies. Can be easily viewed using the `mdb_dump` command. Key prefixes are defined in `src/db.h:enum DbKey`
    298 - `testdata/crypt` contains alice and bob's private and public keys in sexp format, as well as an encrypted version of the private keys. The encryption used is `CHACHA20-POLY1305`, and password for both keys is `1234`. The `kee.key` symlink points to the private key (Alice) used by the GTK application.
    299 - `testdata/crypt_reverse` contains a symlink `kee.key` to Bob's encrypted private key, enabling use of the GTK application as Bob.
    300 - `testdata/import` Three files respresenting all phases of the _entry item_ format:
    301     * `request` - without signatures.
    302     * `response` - with Alice's signature.
    303     * `final` - with both signatures.
    304 - `testdata/resource` All descriptive content for the generated _ledgers_ and _entry items_.
    305 
    306 
    307 ## License
    308 
    309 [GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt)