Public Access
Refuse a pinned host that answers with a key of another type, rather than asking whether to trust it
Pins are stored per algorithm, so an endpoint pinned for ssh-ed25519 that was answered with only an ECDSA or RSA key found no pin and raised SshHostKeyUnknownException: the first-use question, where a pin exists to produce a hard refusal. Anybody in the middle needed nothing more than a key of a different type. The connection factory now reads every pin for the endpoint before the handshake, offers the pinned algorithms first so a server that still holds its pinned key negotiates it, and in the gate accepts a key under an unpinned algorithm only when its fingerprint matches one of the endpoint's pins (one RSA key signs as rsa-sha2-256 and rsa-sha2-512). Anything else is a mismatch. IKnownHostStore gains FindForEndpointAsync for this.
This commit is contained in:
1 parent
412c314aec
commit
4c7f47c026
4 files changed
+193
-2
No files matched your search
@@ -145,6 +145,26 @@ public sealed class VaultKnownHostStore : IKnownHostStore
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>From the snapshot, like <see cref="FindAsync"/>, and for the same reason.</remarks>
|
||||
public ValueTask<IReadOnlyList<HostKeyPresentation>> FindForEndpointAsync(
|
||||
string host,
|
||||
int port,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
lock (gate)
|
||||
{
|
||||
IReadOnlyList<HostKeyPresentation> found = pins.Values
|
||||
.Where(pin =>
|
||||
KnownHostIdentity.Comparer.Equals(pin.Secret.Host, host) && pin.Secret.Port == port)
|
||||
.Select(pin => new HostKeyPresentation(
|
||||
pin.Secret.Host, pin.Secret.Port, pin.Secret.Algorithm, pin.Secret.Fingerprint))
|
||||
.ToArray();
|
||||
|
||||
return ValueTask.FromResult(found);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// The vault is not open, so there is nowhere to record trust.
|
||||
|
||||
Reference in new issue
Block a user