Skip to content

Commit 9917060

Browse files
nindanaotoclaude
andcommitted
FIDO2: check SkPublicKey before Ed25519 in authenticatePublicKey
Move the `instanceof SkPublicKey` check before the `isEd25519Key()` check in AuthenticationManager.authenticatePublicKey(). SK Ed25519 keys (sk-ssh-ed25519@openssh.com) match isEd25519Key() because their algorithm is "Ed25519", causing them to enter the generic Ed25519 path which tries DER encoding and fails with InvalidKeySpecException. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b9dc743 commit 9917060

1 file changed

Lines changed: 26 additions & 25 deletions

File tree

src/main/java/com/trilead/ssh2/auth/AuthenticationManager.java

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -317,34 +317,11 @@ else if (publicKey instanceof ECPublicKey)
317317

318318
tm.sendMessage(ua.getPayload());
319319
}
320-
else if (PublicKeyUtils.isEd25519Key(publicKey))
321-
{
322-
final String algo = Ed25519Verify.ED25519_ID;
323-
324-
byte[] pk_enc = Ed25519Verify.get().encodePublicKey(publicKey);
325-
326-
byte[] msg = this.generatePublicKeyUserAuthenticationRequest(user, algo, pk_enc);
327-
328-
byte[] ed_sig_enc;
329-
if (signatureProxy != null)
330-
{
331-
ed_sig_enc = signatureProxy.sign(msg, SignatureProxy.SHA512);
332-
}
333-
else
334-
{
335-
Ed25519PrivateKey pk = Ed25519Verify.convertPrivateKey(privateKey);
336-
ed_sig_enc = Ed25519Verify.get().generateSignature(msg, pk, rnd);
337-
}
338-
339-
PacketUserauthRequestPublicKey ua = new PacketUserauthRequestPublicKey("ssh-connection", user,
340-
algo, pk_enc, ed_sig_enc);
341-
342-
tm.sendMessage(ua.getPayload());
343-
}
344320
else if (publicKey instanceof SkPublicKey)
345321
{
346322
// FIDO2 Security Key (SK) authentication
347-
// SK keys require external signing via SignatureProxy
323+
// This check must come before the Ed25519 check because
324+
// SK Ed25519 keys match isEd25519Key() but require SK-specific encoding.
348325
if (signatureProxy == null)
349326
{
350327
throw new IOException("SK key authentication requires a SignatureProxy for signing.");
@@ -380,6 +357,30 @@ else if (publicKey instanceof SkPublicKey)
380357

381358
tm.sendMessage(ua.getPayload());
382359
}
360+
else if (PublicKeyUtils.isEd25519Key(publicKey))
361+
{
362+
final String algo = Ed25519Verify.ED25519_ID;
363+
364+
byte[] pk_enc = Ed25519Verify.get().encodePublicKey(publicKey);
365+
366+
byte[] msg = this.generatePublicKeyUserAuthenticationRequest(user, algo, pk_enc);
367+
368+
byte[] ed_sig_enc;
369+
if (signatureProxy != null)
370+
{
371+
ed_sig_enc = signatureProxy.sign(msg, SignatureProxy.SHA512);
372+
}
373+
else
374+
{
375+
Ed25519PrivateKey pk = Ed25519Verify.convertPrivateKey(privateKey);
376+
ed_sig_enc = Ed25519Verify.get().generateSignature(msg, pk, rnd);
377+
}
378+
379+
PacketUserauthRequestPublicKey ua = new PacketUserauthRequestPublicKey("ssh-connection", user,
380+
algo, pk_enc, ed_sig_enc);
381+
382+
tm.sendMessage(ua.getPayload());
383+
}
383384
else
384385
{
385386
throw new IOException("Unknown public key type.");

0 commit comments

Comments
 (0)