Summary
OpenSession in the Linux keychain store sends the client's Diffie-Hellman public key as public.Bytes(). math/big.Int.Bytes returns the minimal big-endian encoding and strips leading zero bytes, so about 1 in 256 sessions send a 127-byte key instead of the 128-byte value the 1024-bit Second Oakley Group expects.
kwalletd5 (KDE Frameworks 5.115, Ubuntu 24.04) rejects the short key and OpenSession fails:
failed to open secretservice session: Client public key size is invalid
gnome-keyring and KeePassXC accept the short key, so the failure only shows against KWallet, and only intermittently.
Where
store/keychain/internal/go-keychain/secretservice/secretservice.go, in OpenSession:
sessionAlgorithmInput = dbus.MakeVariant(public.Bytes()) // math/big.Int.Bytes is big endian
Related
This is the same class of bug as #547, fixed in 11a73bf ("pad DH shared secret to fixed length on Linux"). That fix padded the shared secret fed into HKDF with FillBytes into a 128-byte buffer. The client public key sent on the wire in OpenSession still uses the unpadded Bytes() encoding.
How it was found
Live test in an Ubuntu 24.04 GNOME (Wayland) VM with kwalletd5 owning org.freedesktop.secrets. Ten secrets were saved and then fetched one Get each. One of about sixty sessions opened during the run failed with the error above. Every other backend and every other session succeeded.
Fix
Encode the public key into a fixed 128-byte buffer with FillBytes, mirroring the shared-secret fix, and add a regression test that pins a key with a leading zero byte to the padded encoding.
publicBytes := make([]byte, 128) // group prime size, matches the shared-secret padding
public.FillBytes(publicBytes)
sessionAlgorithmInput = dbus.MakeVariant(publicBytes)
Summary
OpenSessionin the Linux keychain store sends the client's Diffie-Hellman public key aspublic.Bytes().math/big.Int.Bytesreturns the minimal big-endian encoding and strips leading zero bytes, so about 1 in 256 sessions send a 127-byte key instead of the 128-byte value the 1024-bit Second Oakley Group expects.kwalletd5 (KDE Frameworks 5.115, Ubuntu 24.04) rejects the short key and
OpenSessionfails:gnome-keyring and KeePassXC accept the short key, so the failure only shows against KWallet, and only intermittently.
Where
store/keychain/internal/go-keychain/secretservice/secretservice.go, inOpenSession:Related
This is the same class of bug as #547, fixed in 11a73bf ("pad DH shared secret to fixed length on Linux"). That fix padded the shared secret fed into HKDF with
FillBytesinto a 128-byte buffer. The client public key sent on the wire inOpenSessionstill uses the unpaddedBytes()encoding.How it was found
Live test in an Ubuntu 24.04 GNOME (Wayland) VM with kwalletd5 owning
org.freedesktop.secrets. Ten secrets were saved and then fetched oneGeteach. One of about sixty sessions opened during the run failed with the error above. Every other backend and every other session succeeded.Fix
Encode the public key into a fixed 128-byte buffer with
FillBytes, mirroring the shared-secret fix, and add a regression test that pins a key with a leading zero byte to the padded encoding.