francoismichel / ssh3

SSH3: faster and rich secure shell using HTTP/3, checkout our article here: https://arxiv.org/abs/2312.08396 and our Internet-Draft: https://datatracker.ietf.org/doc/draft-michel-ssh3/
https://arxiv.org/abs/2312.08396
Apache License 2.0
3.19k stars 82 forks source link

`Unknown signing method: ed25519.PublicKey` error? #38

Closed RaitoBezarius closed 6 months ago

RaitoBezarius commented 6 months ago

Hi there, thank you for this amazing piece of software that I have been waiting for so long (but now, I can even contribute to it!).

I am packaging ssh3 inside the NixOS distribution for mostly experimental users (not as a sshd replacement obviously) and I am writing an integration test for it and I see on the client:

client # 4:40PM DBG dialing QUIC host at server.ssh.acme.test:443
client # 4:40PM DBG QUIC handshake complete
client # 4:40PM WRN Could not load private key: unknown signing method: ed25519.PublicKey
client # 4:40PM ERR no suitable identity found

with an ED25519 key generated by ssh-keygen from OpenSSH tooling, does that ring a bell? Reading the source code, I cannot understand why this pattern match case fails, I am not a big Go developer in general so I may be missing something I assume.

Thank you!

TheoTechnicguy commented 6 months ago

Hi! The problem seems to come from the JWTSigningMethodFromCryptoPubkey function. Apparently, the input from cryptoSigner.Public() returns a *rsa.PublicKey for RSA keys but an ed25519.PublicKey for ED25519 keys. The former matches the first switch case, but the latter does not match any, as it is not a pointer.

If you're up for it, remove the * from this line here, in util/util.go

func JWTSigningMethodFromCryptoPubkey(pubkey crypto.PublicKey) (jwt.SigningMethod, error) {
    switch pubkey.(type) {
    case *rsa.PublicKey:
        return jwt.SigningMethodRS256, nil
    case *ed25519.PublicKey:  // <-- this here, before
    case ed25519.PublicKey:   // <-- this here, after
        return jwt.SigningMethodEdDSA, nil
    }
    return nil, UnknownSSHPubkeyType{pubkey: pubkey}
}

, then try again.

Here are my debug messages:

For the RSA key

11:58PM DBG parsing user known hosts
11:58PM DBG parsed known hosts Certificates=0 InvalidLines=0
11:58PM DBG got url ConnectionURL=https://127.0.0.1:41443/
11:58PM DBG got command cmd="echo hi ssh3!"
11:58PM DBG parsed ssh config ConfigBytes=2827 SSHConfigFilePath=/home/theo/.ssh/config
11:58PM DBG parsed URL ParsedURL={"ForceQuery":false,"Fragment":"","Host":"127.0.0.1:41443","OmitHost":false,"Opaque":"","Path":"/","RawFragment":"","RawPath":"","RawQuery":"","Scheme":"https","User":null}
11:58PM DBG parsed url and port Host=127.0.0.1 Port=41443
11:58PM DBG fetched Host config ConfigHost= ConfigPort=-1 ConfigUser=theo Host=127.0.0.1 Port=41443
11:58PM DBG set hostname ConfigHostname= DialHostname=127.0.0.1 URLHostname=127.0.0.1
11:58PM DBG set port ConfigPort=-1 Port=41443 URLPort=41443
11:58PM DBG dialing QUIC host at 127.0.0.1:41443
11:58PM DBG QUIC handshake complete
11:58PM DBG attempting pk auth
11:58PM DBG running into identity HasPassphrase=false MethodFilename=id_rsa
11:58PM DBG padded filename Filename=id_rsa
11:58PM DBG read file Filename=id_rsa ReadBytes=1831
11:58PM DBG parsed with no password given
11:58PM DBG attempting transformation to crypto.Signer
fetching signing method of type *rsa.PublicKey
found out it is an *RSA key!
11:58PM DBG fetched signing method from public key SigningMethod={"Hash":5,"Name":"RS256"}
11:58PM DBG attempted loading key without password
11:58PM DBG try the following Identity: pubkey-identity: ALG=RS256
11:58PM DBG send CONNECT request to the server
11:58PM DBG opened new session channel
11:58PM DBG sent exec request for command "echo hi ssh3!"
Could not get message: stream 4 canceled by remote with error code 269
exit status 255

For the ED25519 key (before the change)

11:52PM DBG parsing user known hosts
11:52PM DBG parsed known hosts Certificates=0 InvalidLines=0
11:52PM DBG got url ConnectionURL=https://127.0.0.1:41443/
11:52PM DBG got command cmd="echo hi ssh3!"
11:52PM DBG parsed ssh config ConfigBytes=2827 SSHConfigFilePath=/home/theo/.ssh/config
11:52PM DBG parsed URL ParsedURL={"ForceQuery":false,"Fragment":"","Host":"127.0.0.1:41443","OmitHost":false,"Opaque":"","Path":"/","RawFragment":"","RawPath":"","RawQuery":"","Scheme":"https","User":null}
11:52PM DBG parsed url and port Host=127.0.0.1 Port=41443
11:52PM DBG fetched Host config ConfigHost= ConfigPort=-1 ConfigUser=theo Host=127.0.0.1 Port=41443
11:52PM DBG set hostname ConfigHostname= DialHostname=127.0.0.1 URLHostname=127.0.0.1
11:52PM DBG set port ConfigPort=-1 Port=41443 URLPort=41443
11:52PM DBG dialing QUIC host at 127.0.0.1:41443
11:52PM DBG QUIC handshake complete
11:52PM DBG attempting pk auth
11:52PM DBG running into identity HasPassphrase=false MethodFilename=id_ed25519
11:52PM DBG padded filename Filename=id_ed25519
11:52PM DBG read file Filename=id_ed25519 ReadBytes=411
11:52PM DBG parsed with no password given
11:52PM DBG attempting transformation to crypto.Signer
fetching signing method of type ed25519.PublicKey
doesn't match any key type known
11:52PM DBG fetched signing method from public key error="unknown signing method: ed25519.PublicKey" SigningMethod=null
11:52PM DBG attempted loading key without password error="unknown signing method: ed25519.PublicKey"
11:52PM WRN Could not load private key: unknown signing method: ed25519.PublicKey
11:52PM ERR no suitable identity found
exit status 255

For the ED25519 key (after the change)

11:58PM DBG parsing user known hosts
11:58PM DBG parsed known hosts Certificates=0 InvalidLines=0
11:58PM DBG got url ConnectionURL=https://127.0.0.1:41443/
11:58PM DBG got command cmd="echo hi ssh3!"
11:58PM DBG parsed ssh config ConfigBytes=2827 SSHConfigFilePath=/home/theo/.ssh/config
11:58PM DBG parsed URL ParsedURL={"ForceQuery":false,"Fragment":"","Host":"127.0.0.1:41443","OmitHost":false,"Opaque":"","Path":"/","RawFragment":"","RawPath":"","RawQuery":"","Scheme":"https","User":null}
11:58PM DBG parsed url and port Host=127.0.0.1 Port=41443
11:58PM DBG fetched Host config ConfigHost= ConfigPort=-1 ConfigUser=theo Host=127.0.0.1 Port=41443
11:58PM DBG set hostname ConfigHostname= DialHostname=127.0.0.1 URLHostname=127.0.0.1
11:58PM DBG set port ConfigPort=-1 Port=41443 URLPort=41443
11:58PM DBG dialing QUIC host at 127.0.0.1:41443
11:58PM DBG QUIC handshake complete
11:58PM DBG attempting pk auth
11:58PM DBG running into identity HasPassphrase=false MethodFilename=id_ed25519
11:58PM DBG padded filename Filename=id_ed25519
11:58PM DBG read file Filename=id_ed25519 ReadBytes=411
11:58PM DBG parsed with no password given
11:58PM DBG attempting transformation to crypto.Signer
fetching signing method of type ed25519.PublicKey
found out it is an ED25519 key!
11:58PM DBG fetched signing method from public key SigningMethod={}
11:58PM DBG attempted loading key without password
11:58PM DBG try the following Identity: pubkey-identity: ALG=EdDSA
11:58PM DBG send CONNECT request to the server
11:58PM DBG opened new session channel
11:58PM DBG sent exec request for command "echo hi ssh3!"
Could not get message: stream 4 canceled by remote with error code 269
exit status 255

Don't mind the connection errors — the client connects, so the authentication works.

RaitoBezarius commented 6 months ago

Thank you for the tip!

francoismichel commented 6 months ago

@RaitoBezarius This is fixed now.

Myzel394 commented 6 months ago

I'm also facing a no suitable identity found error