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)