Skip to content

Commit fe56591

Browse files
authored
Merge pull request #1379 from kernelkit/copilot/add-infix-keystore-documentation
Keystore refactor and documentation Signed-off-by: Joachim Wiberg <[email protected]>
2 parents 18c812c + 047d818 commit fe56591

File tree

28 files changed

+950
-169
lines changed

28 files changed

+950
-169
lines changed

board/aarch64/bananapi-bpi-r3/rootfs/usr/share/product/bananapi,bpi-r3/etc/factory-config.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@
218218
"symmetric-key": [
219219
{
220220
"name": "wifi",
221-
"infix-keystore:symmetric-key": "infixinfix",
222-
"infix-keystore:key-format": "infix-crypto-types:wifi-preshared-key-format"
221+
"cleartext-symmetric-key": "aW5maXhpbmZpeA==",
222+
"key-format": "infix-crypto-types:passphrase-key-format"
223223
}
224224
]
225225
}

board/aarch64/raspberrypi-rpi64/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ To configure WiFi as a client, first store your WiFi password in the keystore:
107107
```
108108
admin@infix:/> configure
109109
admin@infix:/config/> edit keystore symmetric-key mywifi
110-
admin@infix:/config/keystore/…/mywifi/> set key-format wifi-preshared-key-format
111-
admin@infix:/config/keystore/…/mywifi/> set symmetric-key YourWiFiPassword
110+
admin@infix:/config/keystore/…/mywifi/> set key-format passphrase-key-format
111+
admin@infix:/config/keystore/…/mywifi/> change cleartext-symmetric-key
112+
Passphrase: ************
113+
Retype passphrase: ************
112114
admin@infix:/config/keystore/…/mywifi/> leave
113115
```
114116

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,49 @@
11
#!/bin/sh
2+
# Prompt for a secret with confirmation, then encode and output it.
3+
#
4+
# Default mode: hash with mkpasswd (for system passwords)
5+
# askpass [OUTPUT]
6+
#
7+
# Base64 mode (-b): base64-encode (for keystore passphrases)
8+
# askpass -b [OUTPUT]
9+
#
10+
# If OUTPUT is given, result is written to the file.
11+
# If omitted, result is written to stdout.
212
# shellcheck disable=SC3045
313

14+
LABEL="New password"
15+
MODE=hash
16+
if [ "$1" = "-b" ]; then
17+
LABEL="Passphrase"
18+
MODE=base64
19+
shift
20+
fi
421
OUTPUT=$1
522

6-
read -r -s -p "New password: " password
23+
read -r -s -p "$LABEL: " secret
724
>&2 echo
8-
read -r -s -p "Retype password: " password_again
25+
read -r -s -p "Retype $LABEL: " secret_again
926
>&2 echo
1027

11-
if [ "$password" != "$password_again" ]; then
12-
echo "Passwords do not match, try again."
28+
if [ "$secret" != "$secret_again" ]; then
29+
echo "${LABEL}s do not match, try again."
1330
exit 1
1431
fi
1532

16-
if [ -z "$OUTPUT" ]; then
17-
echo "$password"
18-
exit 0
33+
if [ -z "$secret" ]; then
34+
echo "Empty $LABEL, try again."
35+
exit 1
36+
fi
37+
38+
if [ "$MODE" = "base64" ]; then
39+
encoded=$(printf '%s' "$secret" | base64 -w 0)
40+
else
41+
encoded=$(printf '%s\n' "$secret" | mkpasswd -s)
1942
fi
2043

2144
umask 0177
22-
echo "$password" | mkpasswd -s > "$OUTPUT"
23-
exit 0
45+
if [ -z "$OUTPUT" ]; then
46+
echo "$encoded"
47+
else
48+
printf '%s' "$encoded" > "$OUTPUT"
49+
fi

doc/ChangeLog.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Change Log
33

44
All notable changes to the project are documented in this file.
55

6-
[v26.01.0][UNRELEASED]
6+
[v26.01.0][] - 2026-02-03
77
-------------------------
88

99
> [!IMPORTANT]
@@ -23,7 +23,7 @@ All notable changes to the project are documented in this file.
2323

2424
Noteworthy changes and additions in this release are marked below in bold text.
2525

26-
- Upgrade Linux kernel to 6.18.8 (LTS)
26+
- **Upgrade Linux kernel from 6.12.65 to 6.18.8 (LTS)**
2727
- Upgrade Buildroot to 2025.02.10 (LTS)
2828
- Upgrade libyang to 4.2.2
2929
- Upgrade sysrepo to 4.2.10
@@ -53,6 +53,9 @@ Noteworthy changes and additions in this release are marked below in bold text.
5353
removed during upgrade (for the rest of the configuration to apply) and you
5454
need to reconfigure them again. See the [WiFi][] documentation for details
5555
- Add support for **WireGuard VPN tunnels**.
56+
- Updated CLI change command to support `cleartext-symmetric-key` (type binary).
57+
Used by both WireGuard and WiFi, with application-specific `key-format` for
58+
keys and passphrases
5659
- New default NACM privilege levels (user levels) in `factory-config`:
5760
`operator` (network & container manager) and `guest` (read-only). For
5861
details, see the updated system configuration documentation, as well as a

doc/keystore.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Keystore
2+
3+
The Infix keystore is a centralized storage system for cryptographic keys
4+
used throughout the system. It is based on the IETF standards [RFC 9641][1]
5+
(Keystore) and [RFC 9640][2] (Cryptographic Types), with Infix extensions
6+
for WiFi and WireGuard key formats.
7+
8+
## Overview
9+
10+
The keystore supports two types of cryptographic keys:
11+
12+
1. **Asymmetric Keys** — public/private key pairs used for:
13+
- SSH host authentication (RSA keys)
14+
- WireGuard VPN tunnels (X25519 keys)
15+
16+
2. **Symmetric Keys** — shared secrets used for:
17+
- WiFi authentication (WPA2/WPA3 pre-shared keys)
18+
- WireGuard VPN pre-shared keys
19+
20+
All keys are stored under the `ietf-keystore` configuration path and can be
21+
managed via CLI, NETCONF, or RESTCONF.
22+
23+
### Supported Formats
24+
25+
| **Asymmetric Key Format** | **Use Case** | **Key Type** |
26+
|----------------------------------------------------------|---------------|--------------|
27+
| `rsa-private-key-format` / `ssh-public-key-format` | SSH host keys | RSA |
28+
| `x25519-private-key-format` / `x25519-public-key-format` | WireGuard VPN | Curve25519 |
29+
30+
| **Symmetric Key Format** | **Use Case** |
31+
|-----------------------------|-----------------------------------|
32+
| `passphrase-key-format` | Human-readable passphrases (WiFi) |
33+
| `octet-string-key-format` | Raw symmetric keys (WireGuard) |
34+
35+
## Asymmetric Keys
36+
37+
Asymmetric keys consist of a public/private key pair. The public key can be
38+
shared freely, while the private key must be kept secure.
39+
40+
### SSH Host Keys
41+
42+
SSH host keys identify the system during SSH and NETCONF connections. The
43+
default host key is automatically generated on first boot and stored in the
44+
keystore with the name `genkey`.
45+
46+
See [SSH Management](management.md) for details on generating and importing
47+
custom SSH host keys.
48+
49+
### WireGuard Keys
50+
51+
WireGuard uses X25519 elliptic curve cryptography for key exchange. Each
52+
WireGuard interface requires a public/private key pair stored as an asymmetric
53+
key in the keystore. Key pairs can be generated directly from the CLI:
54+
55+
<pre class="cli"><code>admin@example:/> <b>wireguard genkey</b>
56+
Private: aMqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP=
57+
Public: bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP=
58+
</code></pre>
59+
60+
See [WireGuard VPN](vpn-wireguard.md) for key generation and configuration
61+
examples.
62+
63+
## Symmetric Keys
64+
65+
Symmetric keys are shared secrets where the same key must be configured on
66+
all systems that need to communicate.
67+
68+
### WiFi Pre-Shared Keys
69+
70+
WiFi networks secured with WPA2 or WPA3 use pre-shared keys stored as
71+
symmetric keys in the keystore with `passphrase-key-format`. The
72+
passphrase must be 8-63 printable ASCII characters.
73+
74+
Since symmetric keys are stored as binary (base64-encoded), the CLI
75+
provides the `change` command to enter passphrases interactively:
76+
77+
<pre class="cli"><code>admin@example:/config/keystore/…/my-wifi-key/> <b>change cleartext-symmetric-key</b>
78+
Passphrase: ************
79+
Retype passphrase: ************
80+
</code></pre>
81+
82+
See [WiFi](wifi.md) for complete configuration examples.
83+
84+
### WireGuard Pre-Shared Keys
85+
86+
WireGuard supports optional pre-shared keys (PSK) that add a layer of
87+
symmetric encryption alongside Curve25519. PSKs use the standard IETF
88+
`octet-string-key-format` (32 random bytes). This provides defense-in-depth
89+
against future quantum computers that might break elliptic curve cryptography.
90+
Note, however, that WireGuard’s authentication and initial key agreement
91+
remain Curve25519-based, so PSKs only protect the session encryption,
92+
not the handshake itself.
93+
94+
PSKs can be generated directly from the CLI:
95+
96+
<pre class="cli"><code>admin@example:/> <b>wireguard genpsk</b>
97+
cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=
98+
</code></pre>
99+
100+
See [WireGuard VPN](vpn-wireguard.md) for PSK generation and usage examples.
101+
102+
## Viewing Keys
103+
104+
The `show keystore` command in admin-exec mode gives an overview of all
105+
keys in the keystore. Passphrases (WiFi passwords) are decoded and shown
106+
in cleartext, while binary keys (WireGuard PSKs) are shown as base64:
107+
108+
<pre class="cli"><code>admin@example:/> <b>show keystore</b>
109+
────────────────────────────────────────────────────────────────────────
110+
<span class="title">Symmetric Keys</span>
111+
<span class="header">NAME FORMAT VALUE </span>
112+
my-wifi-key passphrase MySecretPassword
113+
wg-psk octet-string zYr83O4Ykj9i1gN+/aaosJxQx...
114+
115+
────────────────────────────────────────────────────────────────────────
116+
<span class="title">Asymmetric Keys</span>
117+
<span class="header">NAME TYPE PUBLIC KEY </span>
118+
genkey rsa MIIBCgKCAQEAnj0YinjhYDgYbEGuh7...
119+
wg-tunnel x25519 bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1...
120+
</code></pre>
121+
122+
To see the full (untruncated) details of a specific key, use the
123+
`symmetric` or `asymmetric` qualifier with the key name:
124+
125+
<pre class="cli"><code>admin@example:/> <b>show keystore symmetric my-wifi-key</b>
126+
name : my-wifi-key
127+
format : passphrase
128+
value : MySecretPassword
129+
130+
admin@example:/> <b>show keystore asymmetric genkey</b>
131+
name : genkey
132+
algorithm : rsa
133+
public key format : ssh-public-key
134+
public key : MIIBCgKCAQEAnj0YinjhY...full key...IDAQAB
135+
</code></pre>
136+
137+
> [!NOTE]
138+
> The `show keystore` command is protected by NACM. Only users in the
139+
> `admin` group can view keystore data. Operator-level users will see a
140+
> message indicating that no keystore data is available.
141+
142+
The full configuration-mode view (including private keys) is still
143+
available via `configure` and then `show keystore`:
144+
145+
<pre class="cli"><code>admin@example:/config/> <b>show keystore</b>
146+
</code></pre>
147+
148+
> [!WARNING]
149+
> The configuration-mode `show keystore` displays private keys in
150+
> cleartext. Be careful when viewing keys on shared screens or in
151+
> logged sessions. The admin-exec `show keystore` command never
152+
> displays private keys.
153+
154+
## Deleting Keys
155+
156+
<pre class="cli"><code>admin@example:/> <b>configure</b>
157+
admin@example:/config/> <b>delete keystore asymmetric-key mykey</b>
158+
admin@example:/config/> <b>leave</b>
159+
</code></pre>
160+
161+
> [!CAUTION]
162+
> Deleting a key that is referenced by a service (SSH, WireGuard, WiFi) will
163+
> cause that service to fail. Verify the key is not in use before deletion.
164+
165+
## Security Considerations
166+
167+
The keystore is protected by NACM (Network Access Control Model) rules.
168+
Only users in the `admin` group can view or modify cryptographic keys.
169+
See [NACM](nacm.md) for details on access control.
170+
171+
Private keys are stored in cleartext in the configuration database.
172+
Configuration files and backups containing the keystore should be treated
173+
as sensitive and protected accordingly.
174+
175+
### Key Validation
176+
177+
Symmetric key values are stored as binary (base64-encoded). The system
178+
validates them based on their declared format:
179+
180+
- `passphrase-key-format`: Used by WiFi, must decode to 8-63 ASCII characters
181+
- `octet-string-key-format`: Used by Wireguard, must decode to exactly 32 bytes (256 bits)
182+
183+
## References
184+
185+
- [RFC 9641 - A YANG Data Model for a Keystore][1]
186+
- [RFC 9640 - YANG Data Types and Groupings for Cryptography][2]
187+
- [WiFi Documentation](wifi.md)
188+
- [WireGuard VPN Documentation](vpn-wireguard.md)
189+
- [SSH Management](management.md)
190+
- [NACM Access Control](nacm.md)
191+
192+
[1]: https://datatracker.ietf.org/doc/html/rfc9641
193+
[2]: https://datatracker.ietf.org/doc/html/rfc9640

doc/management.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ RSA for now, thus the private key must be
4747
`ietf-crypto-types:rsa-private-key-format` and the public key
4848
`ietf-crypto-types:ssh-public-key-format`
4949

50+
> [!TIP]
51+
> For comprehensive information about the keystore, including key management,
52+
> security considerations, and examples for different key types, see the
53+
> [Keystore documentation](keystore.md).
54+
5055
### Use your own SSH hostkeys
5156

5257
Hostkeys can be generated with OpenSSL:

0 commit comments

Comments
 (0)