kee

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

README (11166B)


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