Compare commits

..

2 Commits

Author SHA1 Message Date
Ryan Heywood d759982853
scripts: add publishing scripts 2024-05-16 02:01:10 -04:00
Ryan Heywood 491d19469a
crates: bump versions 2024-05-16 00:29:28 -04:00
17 changed files with 261 additions and 38 deletions

141
CHANGELOG.md Normal file
View File

@ -0,0 +1,141 @@
# Keyfork v0.2.0
Some of the changes in this release are based on feedback from audits
(publications coming soon!). The previous version of Keyfork, in almost every
configuration, is safe to use. The most significant change in this version
affects Keyfork Shard, which has an incompatible difference between this
version and the previous version. Information about shards, such as the length
of the shard, could be leaked and discovered by an attacker when using the
Remote Shard recovery mechanism.
An additional change is the requirement of hardened indices on the first two
levels of key derivation. This is due to Keyfork potentially leaking private
keys when hardened derivation is not used. To be completely honest, I don't
entirely understand the math behind it.
There is no reason to upgrade if Keyfork has been used as-is, as all supported
provisioners at this point in time require hardened derivation at all steps.
### Changes in keyfork:
```
d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct
5d2309e keyfork-prompt: add SecurePinValidator for making new, secure, PINs
cdf4015 keyfork wizard: use correct derivation path for re-deriving shard decryption keys
f0e5ae9 keyfork-derive-openpgp: document KEYFORK_OPENPGP_EXPIRE
289cec3 keyfork wizard: upcast i and index to avoid wrapping add
9394500 keyfork-shard: generate nonce using hkdf
```
### Changes in keyfork-derive-openpgp:
```
f0e5ae9 keyfork-derive-openpgp: document KEYFORK_OPENPGP_EXPIRE
9f089e7 keyfork-derive-openpgp: use .first() in place of .get(0)
```
### Changes in keyfork-derive-util:
```
de4e98a keyfork-derive-util: black-box checking all zeroes
48ccd7c keyfork-derive-util: add note about potential side-channel when verifying keys
d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct
1de466c keyfork-derive-util: allow zeroable input for non-master-key derivation
61871a7 keyfork-derive-util: make private and public test keys more visible
2bca0a1 keyfork-derive-util: make Test{Public,Private}Key public, rename Internal algorithm
```
### Changes in keyfork-entropy:
```
5438f4e keyfork-entropy: downgrade entropy size limit to warning
```
### Changes in keyfork-mnemonic-util:
```
001fc0b remove trailing hitespace :(
6a265ad keyfork-mnemonic-util: add MnemonicBase::from_nonstandard_bytes
```
### Changes in keyfork-prompt:
```
5d2309e keyfork-prompt: add SecurePinValidator for making new, secure, PINs
```
### Changes in keyfork-qrcode:
```
fa125e7 keyfork-qrcode: prefer Instant over SystemTime for infallible time comparison
```
### Changes in keyfork-shard:
```
d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct
1a036a0 keyfork-shard: clean up documentation for encrypted shard padding
e068743 keyfork-shard: display error message on duplicate key fingerprints found
23db509 keyfork-shard: improve wording for counting shardholders
9461772 keyfork-shard: ignore duplicate certificate entries
6a265ad keyfork-mnemonic-util: add MnemonicBase::from_nonstandard_bytes
c0b19e2 keyfork-shard: assert shared secrets are contributory
0fe5301 keyfork-shard: add in bug messages
08a66e2 keyfork-shard: base64 encode content instead of base16
6fa434e keyfork-shard: shorten length and pad inside encrypted block
9394500 keyfork-shard: generate nonce using hkdf
194d475 keyfork-shard: validate signatures using shard-specific validation requirements
```
### Changes in keyfork-zbar:
```
0c76869 .cargo/config.toml: add registry configuration :)
```
### Changes in keyforkd:
```
bcfcc87 keyforkd: add warning when loading seed with less than 128 bits
40551a5 keyforkd: require hardened derivation on two highest indexes
```
### Changes in keyforkd-client:
```
d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct
1de466c keyfork-derive-util: allow zeroable input for non-master-key derivation
40551a5 keyforkd: require hardened derivation on two highest indexes
```
### Changes in keyforkd-models:
```
40551a5 keyforkd: require hardened derivation on two highest indexes
```
# Keyfork v0.1.0
### Tagged releases:
* `keyfork-bin 0.1.0`
* `keyfork-bug 0.1.0`
* `keyfork-crossterm 0.27.1`
* `keyfork-derive-key 0.1.0`
* `keyfork-derive-openpgp 0.1.0`
* `keyfork-derive-path-data 0.1.0`
* `keyfork-derive-util 0.1.0`
* `keyfork-entropy 0.1.0`
* `keyfork-frame 0.1.0`
* `keyfork-mnemonic-util 0.2.0`
* `keyfork-prompt 0.1.0`
* `keyfork-qrcode 0.1.0`
* `keyfork-shard 0.1.0`
* `keyfork-slip10-test-data 0.1.0`
* `keyfork 0.1.0`
* `keyfork-zbar-sys 0.1.0`
* `keyfork-zbar 0.1.0`
* `keyforkd-client 0.1.0`
* `keyforkd-models 0.1.0`
* `keyforkd 0.1.0`
* `smex 0.1.0`

18
Cargo.lock generated
View File

@ -1674,7 +1674,7 @@ dependencies = [
[[package]]
name = "keyfork"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"card-backend-pcsc",
"clap",
@ -1734,7 +1734,7 @@ dependencies = [
[[package]]
name = "keyfork-derive-key"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"keyfork-derive-util",
"keyforkd-client",
@ -1744,7 +1744,7 @@ dependencies = [
[[package]]
name = "keyfork-derive-openpgp"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"anyhow",
"ed25519-dalek",
@ -1756,14 +1756,14 @@ dependencies = [
[[package]]
name = "keyfork-derive-path-data"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"keyfork-derive-util",
]
[[package]]
name = "keyfork-derive-util"
version = "0.1.1"
version = "0.2.0"
dependencies = [
"digest",
"ed25519-dalek",
@ -1799,7 +1799,7 @@ dependencies = [
[[package]]
name = "keyfork-mnemonic-util"
version = "0.2.0"
version = "0.3.0"
dependencies = [
"bip39",
"hex",
@ -1813,7 +1813,7 @@ dependencies = [
[[package]]
name = "keyfork-prompt"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"keyfork-bug",
"keyfork-crossterm",
@ -1908,7 +1908,7 @@ dependencies = [
[[package]]
name = "keyforkd-client"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"bincode",
"ed25519-dalek",
@ -1923,7 +1923,7 @@ dependencies = [
[[package]]
name = "keyforkd-models"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"keyfork-derive-util",
"serde",

View File

@ -1,6 +1,6 @@
[package]
name = "keyforkd-client"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT"
@ -12,9 +12,9 @@ ed25519 = ["keyfork-derive-util/ed25519", "ed25519-dalek"]
secp256k1 = ["keyfork-derive-util/secp256k1", "k256"]
[dependencies]
keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" }
keyfork-frame = { version = "0.1.0", path = "../../util/keyfork-frame", registry = "distrust" }
keyforkd-models = { version = "0.1.0", path = "../keyforkd-models", registry = "distrust" }
keyforkd-models = { version = "0.2.0", path = "../keyforkd-models", registry = "distrust" }
bincode = "1.3.3"
thiserror = "1.0.49"
k256 = { version = "0.13.3", optional = true }

View File

@ -1,12 +1,12 @@
[package]
name = "keyforkd-models"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" }
serde = { version = "1.0.190", features = ["derive"] }
thiserror = "1.0.50"

View File

@ -13,11 +13,11 @@ multithread = ["tokio/rt-multi-thread"]
[dependencies]
keyfork-bug = { version = "0.1.0", path = "../../util/keyfork-bug", registry = "distrust" }
keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", registry = "distrust" }
keyfork-frame = { version = "0.1.0", path = "../../util/keyfork-frame", features = ["async"], registry = "distrust" }
keyfork-mnemonic-util = { version = "0.2.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-mnemonic-util = { version = "0.3.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-derive-path-data = { version = "0.1.0", path = "../../derive/keyfork-derive-path-data", registry = "distrust" }
keyforkd-models = { version = "0.1.0", path = "../keyforkd-models", registry = "distrust" }
keyforkd-models = { version = "0.2.0", path = "../keyforkd-models", registry = "distrust" }
# Not personally audited
bincode = "1.3.3"

View File

@ -1,13 +1,13 @@
[package]
name = "keyfork-derive-key"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
license = "AGPL-3.0-only"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", registry = "distrust" }
keyforkd-client = { version = "0.1.0", path = "../../daemon/keyforkd-client", registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", registry = "distrust" }
keyforkd-client = { version = "0.2.0", path = "../../daemon/keyforkd-client", registry = "distrust" }
smex = { version = "0.1.0", path = "../../util/smex", registry = "distrust" }
thiserror = "1.0.48"

View File

@ -1,6 +1,6 @@
[package]
name = "keyfork-derive-openpgp"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
license = "AGPL-3.0-only"
@ -10,8 +10,8 @@ default = ["bin"]
bin = ["sequoia-openpgp/crypto-nettle"]
[dependencies]
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" }
keyforkd-client = { version = "0.1.0", path = "../../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" }
keyforkd-client = { version = "0.2.0", path = "../../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" }
ed25519-dalek = "2.0.0"
sequoia-openpgp = { version = "1.17.0", default-features = false }
anyhow = "1.0.75"

View File

@ -1,10 +1,10 @@
[package]
name = "keyfork-derive-path-data"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", default-features = false, registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", default-features = false, registry = "distrust" }

View File

@ -1,6 +1,6 @@
[package]
name = "keyfork-derive-util"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
license = "MIT"
@ -12,7 +12,7 @@ secp256k1 = ["k256"]
ed25519 = ["ed25519-dalek"]
[dependencies]
keyfork-mnemonic-util = { version = "0.2.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-mnemonic-util = { version = "0.3.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-bug = { version = "0.1.0", path = "../../util/keyfork-bug", registry = "distrust" }
# Included in Rust

View File

@ -15,15 +15,15 @@ qrcode = ["keyfork-qrcode"]
[dependencies]
keyfork-bug = { version = "0.1.0", path = "../util/keyfork-bug", registry = "distrust" }
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"], registry = "distrust" }
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", optional = true, default-features = false, registry = "distrust" }
keyfork-prompt = { version = "0.1.1", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"], registry = "distrust" }
keyfork-qrcode = { version = "0.1.1", path = "../qrcode/keyfork-qrcode", optional = true, default-features = false, registry = "distrust" }
smex = { version = "0.1.0", path = "../util/smex", registry = "distrust" }
sharks = "0.5.0"
thiserror = "1.0.50"
# Remote operator mode
keyfork-mnemonic-util = { version = "0.2.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-mnemonic-util = { version = "0.3.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" }
x25519-dalek = { version = "2.0.0", features = ["getrandom"] }
aes-gcm = { version = "0.10.3", features = ["std"] }
hkdf = { version = "0.12.4", features = ["std"] }

View File

@ -1,6 +1,6 @@
[package]
name = "keyfork"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "AGPL-3.0-only"
@ -25,11 +25,11 @@ sequoia-crypto-backend-openssl = ["sequoia-openpgp/crypto-openssl"]
[dependencies]
keyfork-bin = { version = "0.1.0", path = "../util/keyfork-bin", registry = "distrust" }
keyforkd = { version = "0.1.0", path = "../daemon/keyforkd", features = ["tracing"], registry = "distrust" }
keyforkd-client = { version = "0.1.0", path = "../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" }
keyfork-derive-openpgp = { version = "0.1.0", path = "../derive/keyfork-derive-openpgp", registry = "distrust" }
keyfork-derive-util = { version = "0.1.0", path = "../derive/keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" }
keyforkd-client = { version = "0.2.0", path = "../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" }
keyfork-derive-openpgp = { version = "0.1.1", path = "../derive/keyfork-derive-openpgp", registry = "distrust" }
keyfork-derive-util = { version = "0.2.0", path = "../derive/keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" }
keyfork-entropy = { version = "0.1.0", path = "../util/keyfork-entropy", registry = "distrust" }
keyfork-mnemonic-util = { version = "0.2.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-mnemonic-util = { version = "0.3.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" }
keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", registry = "distrust" }
keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", default-features = false, registry = "distrust" }
keyfork-shard = { version = "0.2.0", path = "../keyfork-shard", default-features = false, features = ["openpgp", "openpgp-card", "qrcode"], registry = "distrust" }

View File

@ -1,6 +1,6 @@
[package]
name = "keyfork-mnemonic-util"
version = "0.2.0"
version = "0.3.0"
description = "Utilities to generate and manage seeds based on BIP-0039 mnemonics."
repository = "https://git.distrust.co/public/keyfork"
edition = "2021"

View File

@ -1,6 +1,6 @@
[package]
name = "keyfork-prompt"
version = "0.1.0"
version = "0.1.1"
description = "Prompt management utilities for Keyfork"
repository = "https://git.distrust.co/public/keyfork"
edition = "2021"
@ -15,5 +15,5 @@ mnemonic = ["keyfork-mnemonic-util"]
[dependencies]
keyfork-bug = { version = "0.1.0", path = "../keyfork-bug", registry = "distrust" }
keyfork-crossterm = { version = "0.27.1", path = "../keyfork-crossterm", default-features = false, features = ["use-dev-tty", "events", "bracketed-paste"], registry = "distrust" }
keyfork-mnemonic-util = { version = "0.2.0", path = "../keyfork-mnemonic-util", optional = true, registry = "distrust" }
keyfork-mnemonic-util = { version = "0.3.0", path = "../keyfork-mnemonic-util", optional = true, registry = "distrust" }
thiserror = "1.0.51"

View File

@ -0,0 +1,18 @@
import json
import sys
priority_queue = []
packages = json.load(sys.stdin)["packages"]
def iter_packages(package_name):
package = next((package for package in packages if package["name"] == package_name), None)
if package is not None and package["source"] is None:
for dependency in package["dependencies"]:
iter_packages(dependency["name"])
if package_name not in priority_queue:
priority_queue.append(package_name)
iter_packages("keyfork")
for package_name in priority_queue:
package = next((package for package in packages if package["name"] == package_name), None)
print(" ".join([package["name"], package["version"]]))

View File

@ -0,0 +1,20 @@
set -eu
set -o pipefail
LAST_REF="$1"
CURRENT_REF="${2:-HEAD}"
cargo metadata --format-version=1 | \
jq -r '.packages[] | select(.source == null) | .name + " " + .manifest_path' | \
while read crate manifest_path; do
crate_path="$(dirname $manifest_path)"
git_log="$(git log --format='%h %s' "$LAST_REF"..HEAD "$crate_path")"
if test ! -z "$git_log"; then
echo "### Changes in $crate:"
echo ""
echo "\`\`\`"
echo "$git_log"
echo "\`\`\`"
echo ""
fi
done

15
scripts/publish.sh Normal file
View File

@ -0,0 +1,15 @@
set -eu
set -o pipefail
scripts_dir="$(dirname $0)"
python_script="$scripts_dir/generate-dependency-queue.py"
registry_url="https://git.distrust.co/api/packages/public/cargo"
search_url="${registry_url}/api/v1/crates"
cargo metadata --format-version=1 | python3 "$python_script" | while read crate version; do
# Verify the package does not exist
if ! curl "${search_url}?q=${crate}" 2>/dev/null | jq -e "$(printf '.crates | .[] | select(.name == "%s" and .max_version == "%s")' "$crate" "$version")" >/dev/null; then
cargo publish --registry distrust -p "$crate"
fi
done

View File

@ -0,0 +1,29 @@
set -eu
set -o pipefail
LAST_REF="$1"
CURRENT_REF="${2:-HEAD}"
temp_file="$(mktemp)"
cargo metadata --format-version=1 | jq -r '.packages[] | select(.source == null) | .name + " " + .manifest_path + " " + .version' > "$temp_file"
while read crate manifest_path version <&3; do
crate_path="$(dirname $manifest_path)"
git_log="$(git log --format='%h %s' "$LAST_REF"..HEAD "$crate_path")"
git_tag="$(git tag --list "$crate-v${version}")"
if test ! -z "$git_log" -a -z "$git_tag"; then
{
echo "${crate} v${version}"
echo ""
echo "\`\`\`"
echo "$git_log"
echo "\`\`\`"
echo ""
echo "# Crate: ${crate} ${version}"
} | git tag --sign "${crate}-v${version}" -F - -e
echo "Making new tag: ${crate}-v${version}"
fi
done 3<"$temp_file"
rm "$temp_file"