fnc

Verified Builds
Login

Verified Builds

Secure Binaries

fnc deliverables are verified by SHA256 checksum—and it is the SHA256 file that is signed. Working under the premise that SHA256 checksums cannot be forged, this signing process creates a chain of trust. To wit, if the signature matches, then the checksums must be the same checksums that were signed on the build box. And if the checksums match, then it follows that the tarball is the same set of files that were archived and hashed on said build machine.

The caveat is that to seed this chain of trust, initially, the public key must be trusted; but how can you be sure that your copy of the key hasn't been interdicted and used to sign a forged set of files, thus rendering you with a verifiable, albeit ¬fnc, tarball? The fact that just 56 base-64 encoded characters constitute the key means that it is small and easily accessible. We have, therefore, made it widely available in locations that have a very high likelihood of being under our control—this website and our own DNS server, for example—which enables you to validate your copy of the key. Further, at any point in time, the current public key—and the next for a future fnc release—are in the source tree, having been committed to the repository's blockchain—a traceable and unfalsifiable historical record. In addition, each signed deliverable is linked to via a corresponding technote that contains the signed checksum. Such dissemination increases the difficulty for threat agents to intercept your public key retrieval, and decreases the risk that any such attempt would go undetected, thus mitigating this attack vector.

Signing Process

The following details how tarballs of fnc's binaries and source code are created and signed during the release process, which is performed by a script that comprises the below steps. Although the example demonstrates an OpenBSD build, the process is identical on macOS and Linux except for the use of OpenBSD's sha256(1) counterpart; namely, gsha256sum --tag and sha256sum --tag on macOS and Linux, respectively. The --tag option is needed because signify(1) expects BSD-style checksums. Similarly, the openbsd string in file paths is replaced with its corresponding platform—darwin or linux—as reported by uname(1).

  1. From the root of the source tree, build the tip of trunk (builds are done with both clang and gcc):
    fossil update trunk
    make clean
    CC="ccache egcc" make -j4
    make clean
    CC="ccache clang" make -j4
    
  2. Strip the resulting binary:
    strip ./fnc/fnc
    
  3. Create tarball of the binary executable and manual page:
    tar zcvf fnc15-openbsd.tar.gz fnc/fnc fnc/fnc.1
    
  4. Compute the SHA256 checksum of the tarball:
    sha256 fnc15-openbsd.tar.gz > fnc15-openbsd.tar.gz.SHA256
    
  5. Sign checksum and write the signature to file:
    signify -Ses $private_key -m fnc15-openbsd.tar.gz.SHA256
    
  6. Move the tarball and signature file to the repository's unversioned downloadable content:
    mv fnc15-openbsd.tar.gz* dl/
    
  7. Update and sync the files:
    fossil uv add dl/fnc15-openbsd*
    fossil uv sync
    
  8. Commit a technote with the signed checksum linked to the tarball:
    fossil wiki create "signed checksum: [/uv/dl/fnc15-openbsd.tar.gz|fnc15-openbsd.tar.gz]" -M plain -t now --technote-tags 0.15 fnc15-openbsd.tar.gz.SHA256.sig 
    

n.b. The script is run on all supported platforms to produce binary releases, and the source tarball is the same except steps 1–3 are replaced with fossil update trunk && make clean && make release from the root of the work tree.