Documentation ¶
Overview ¶
Package secpkg implements the secpkg package format.
A secure package (.secpkg file) contains a JSON object with the following keys:
{ "Name": "the project's package name", "Head": "head of project's Codechain", "DNS": "fully qualified domain name for Codechain's TXT records", }
Example .secpkg file for Codechain itself:
{ "Name": "codechain", "Head": "53f2c26d92e173306e83d54e3103ef2e0bd87a561315bc4b49e1ee6c78dfb583", "DNS": "codechain.secpkg.net", }
If in the root of a package source tree the directory .secdep exists and contains any .secpkg files, then these secure dependencies are installed and kept up-to-date by the install and update procedures specified below.
Install specification ¶
Installing software described by a .secpkg file works as follows:
Parse .secpkg file and validate it. Save head as HEAD_PKG.
Make sure the project with NAME has not been installed before. That is, the directory ~/.config/secpkg/pkgs/NAME does not exist.
Create directory ~/.config/secpkg/pkgs/NAME
Save .secpkg file to ~/.config/secpkg/pkgs/NAME/.secpkg
Query TXT record from _codechain-head.DNS and validate the signed head contained in it (see ssot package). Save head from TXT record (HEAD_SSOT).
Query all TXT records from _codechain-url.DNS and save it as URLs.
Store the signed head to ~/.config/secpkg/pkgs/NAME/signed_head
Select next URL from URLs. If no such URL exists, exit with error.
Download distribution file from URL/HEAD_SSOT.tar.gz and save it to ~/.config/secpkg/pkgs/NAME/dists If it fails: Goto 8.
Apply ~/.config/secpkg/pkgs/NAME/dists/HEAD_SSOT.tar.gz to ~/.config/secpkg/pkgs/NAME/src with `codechain apply -f ~/.config/secpkg/pkgs/NAME/dists/HEAD_SSOT.tar.gz -head HEAD_SSOT` If it fails: Goto 8.
Make sure HEAD_PKG is contained in ~/.config/secpkg/pkgs/NAME/src/.codchain/hashchain If it fails: Goto 8.
If the directory ~/.config/secpkg/pkgs/NAME/src/.secdep exists and contains any .secpkg files, ensure these secure dependencies are installed and up-to-date.
`cp -r ~/.config/secpkg/pkgs/NAME/src ~/.config/secpkg/pkgs/NAME/build`
Call `make prefix=~/.config/secpkg/local` in ~/.config/secpkg/pkgs/NAME/build
Call `make prefix= ~/.config/secpkg/local install` in ~/.config/secpkg/pkgs/NAME/build
`mv ~/.config/secpkg/pkgs/NAME/build ~/.config/secpkg/pkgs/NAME/installed`
If the installation process fails at any stage during the procedure described above, report the error and remove the directory ~/.config/secpkg/pkgs/NAME.
For the process above to work, the projects distributed as secure packages must contain a Makefile (for GNU Make) with the "all" target building the software and the "install" target installing it.
The software must be self-contained without any external dependencies, except for the compiler. For Go software that means at least Go 1.11 must be installed (with module support) and all dependencies must be vendored.
Update specification ¶
Updating a software package with NAME works as follows:
Make sure the project with NAME has been installed before. That is, the directory ~/.config/secpkg/pkgs/NAME exists. Set SKIP_BUILD to false.
Load .secpkg file from ~/.config/secpkg/pkgs/NAME/.secpkg
Load signed head from ~/.config/secpkg/pkgs/NAME/signed_head (as DISK)
Query TXT record from _codechain-head.DNS, if it is the same as DISK, set SKIP_BUILD to true.
Query all TXT records from _codechain-url.DNS and save it as URLs.
If not SKIP_BUILD, validate signed head from TXT (also see ssot package) and store HEAD:
- pubKey from TXT must be the same as pubKey or pubKeyRotate from DISK, if the signed head from DISK is not expired. - The counter from TXT must be larger than the counter from DISK. - The signed head must be valid (as defined by validFrom and validTo).
If the validation fails, abort update procedure and report error.
If not SKIP_BUILD and if signed head from TXT record is the same as the one from DISK, set SKIP_BUILD to true.
If SKIP_BUILD, check if HEAD is contained in ~/.config/secpkg/pkgs/NAME/src/.codchain/hashchain. If not, set SKIP_BUILD to false. This can happend if we checked for updates.
Select next URL from URLs. If no such URL exists, exit with error.
If not SKIP_BUILD, download distribution file from URL/HEAD.tar.gz and save it to ~/.config/secpkg/pkgs/NAME/dists If it fails: Goto 9.
If not SKIP_BUILD, apply ~/.config/secpkg/pkgs/NAME/dists/HEAD.tar.gz to ~/.config/secpkg/pkgs/NAME/src with `codechain apply -f ~/.config/secpkg/pkgs/NAME/dists/HEAD.tar.gz -head HEAD`. If it fails: Goto 9.
If the directory ~/.config/secpkg/pkgs/NAME/src/.secdep exists and contains any .secpkg files, ensure these secure dependencies are installed and up-to-date. If at least one dependency was updated, set SKIP_BUILD to false.
If not SKIP_BUILD, call `make prefix=~/.config/secpkg/local uninstall` in ~/.config/secpkg/pkgs/NAME/installed
If not SKIP_BUILD, `rm -rf ~/.config/secpkg/pkgs/NAME/build`
If not SKIP_BUILD, `cp -r ~/.config/secpkg/pkgs/NAME/src ~/.config/secpkg/pkgs/NAME/build`
If not SKIP_BUILD, call `make prefix=~/.config/secpkg/local` in ~/.config/secpkg/pkgs/NAME/build
If not SKIP_BUILD, call `make prefix= ~/.config/secpkg/local install` in ~/.config/secpkg/pkgs/NAME/build
If not SKIP_BUILD, `mv ~/.config/secpkg/pkgs/NAME/build ~/.config/secpkg/pkgs/NAME/installed`
Update signed head:
- `cp -f ~/.config/secpkg/pkgs/NAME/signed_head ~/.config/secpkg/pkgs/NAME/previous_signed_head` - Save new signed head to ~/.config/secpkg/pkgs/NAME/signed_head (atomic).
The software has been successfully updated.
CheckUpdate specification ¶
Checking if a software package with NAME needs an update works as follows:
Make sure the project with NAME has been installed before. That is, the directory ~/.config/secpkg/pkgs/NAME exists. Set SKIP_CHECK and NEEDS_UPDATE to false.
Load .secpkg file from ~/.config/secpkg/pkgs/NAME/.secpkg
Load signed head from ~/.config/secpkg/pkgs/NAME/signed_head (as DISK)
Query TXT record from _codechain-head.DNS, if it is the same as DISK, set SKIP_CHECK to true.
If not SKIP_CHECK, validate signed head from TXT (also see ssot package) and store HEAD:
- pubKey from TXT must be the same as pubKey or pubKeyRotate from DISK, if the signed head from DISK is not expired. - The counter from TXT must be larger than the counter from DISK. - The signed head must be valid (as defined by validFrom and validTo).
If the validation fails, abort check update procedure and report error.
If not SKIP_CHECK and if signed head from TXT record not the same as the one from DISK, set SKIP_CHECK and NEEDS_UPDATE to true.
If not NEEDS_UPDATE, check if HEAD is contained in ~/.config/secpkg/pkgs/NAME/src/.codchain/hashchain. If not, set NEEDS_UPDATE to true.
If NEEDS_UPDATE is false, check if the directory ~/.config/secpkg/pkgs/NAME/src/.secdep exists and contains any .secpkg files, ensure these secure dependencies are installed and up-to-date. If at least one dependency needs an update, set NEEDS_UPDATE to true.
Update signed head:
- `cp -f ~/.config/secpkg/pkgs/NAME/signed_head ~/.config/secpkg/pkgs/NAME/previous_signed_head` - Save new signed head to ~/.config/secpkg/pkgs/NAME/signed_head (atomic).
Return NEEDS_UPDATE.
Index ¶
Constants ¶
const File = ".secpkg"
File defines the default file (ending) for a secure package.
Variables ¶
var ErrNoKey = errors.New("secpkg: package has no secretbox encryption key")
ErrNoKey is returned if a package has no secretbox encryption key.
var ErrNotInstalled = errors.New("secpkg: package not installed")
ErrNotInstalled is returned if a package is not installed.
var ErrPkgNameWhitespace = errors.New("secpkg: package name contains white space character")
ErrPkgNameWhitespace is returned if a package name contains a white space character.
Functions ¶
func CheckUpdate ¶
CheckUpdate checks installed package with name for updates, see specification for details.
func UpToDate ¶
UpToDate ensures that the package with name is up-to-date, if it is installed as a secure package. If the package is not installed as a secure package a corresponding message is shown on stderr.
UpToDate times out after a while if DNS cannot be queried and return nil.
func UpToDateIfInstalled ¶
UpToDateIfInstalled ensures that the package with name is up-to-date, if it is installed as a secure package. If the package is not installed as a secure package a corresponding message is shown on stderr.
Types ¶
type Package ¶
type Package struct { Name string // the project's package name Head string // head of project's Codechain DNS string // fully qualified domain name for Codechain's TXT records (SSOT) Key string `json:",omitempty"` // optional secretbox encryption key }
Package defines a package in secpkg format (stored in .secpkg files).
func (*Package) GetKey ¶
GetKey returns the secretbox encryption key or an error if the key does not exist or is not parsable.