Skip to content

Commit

Permalink
draft: fix ed25519 pubkey auth (#48)
Browse files Browse the repository at this point in the history
ed25519 keys passed by the crypto package, but are still valid keys. This
commit fixes this bug by adding the non-pointer types. fix: 38

* add integration test for ed25519 keys

* only match on the actual type implementing crypto.PublicKey

---------

Co-authored-by: François Michel <francois.michel@uclouvain.be>
  • Loading branch information
TheoTechnicguy and francoismichel authored Dec 18, 2023
1 parent 96b63cc commit 6127e06
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
33 changes: 22 additions & 11 deletions integration_tests/ssh3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ var ssh3ServerPath string
const DEFAULT_URL_PATH = "/ssh3-tests"
var serverCommand *exec.Cmd
var serverSession *Session
var privKeyPath string
var rsaPrivKeyPath string
var ed25519PrivKeyPath string
var attackerPrivKeyPath string
var username string
// must exist on the machine to successfully run the tests
Expand Down Expand Up @@ -65,10 +66,11 @@ var _ = BeforeSuite(func() {
serverSession, err = Start(serverCommand, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())

privKeyPath = os.Getenv("TESTUSER_PRIVKEY")
rsaPrivKeyPath = os.Getenv("TESTUSER_PRIVKEY")
ed25519PrivKeyPath = os.Getenv("TESTUSER_ED25519_PRIVKEY")
attackerPrivKeyPath = os.Getenv("ATTACKER_PRIVKEY")
username = os.Getenv("TESTUSER_USERNAME")
Expect(fileExists(privKeyPath)).To(BeTrue())
Expect(fileExists(rsaPrivKeyPath)).To(BeTrue())
Expect(fileExists(attackerPrivKeyPath)).To(BeTrue())
}
})
Expand Down Expand Up @@ -113,8 +115,17 @@ var _ = Describe("Testing the ssh3 cli", func() {
}

Context("Client behaviour", func() {
It("Should connect using privkey", func() {
clientArgs = append(getClientArgs(privKeyPath), "echo", "Hello, World!")
It("Should connect using an RSA privkey", func() {
clientArgs = append(getClientArgs(rsaPrivKeyPath), "echo", "Hello, World!")
command := exec.Command(ssh3Path, clientArgs...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(session).Should(Exit(0))
Eventually(session).Should(Say("Hello, World!\n"))
})

It("Should connect using an ed25519 privkey", func() {
clientArgs = append(getClientArgs(ed25519PrivKeyPath), "echo", "Hello, World!")
command := exec.Command(ssh3Path, clientArgs...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Expand All @@ -123,10 +134,10 @@ var _ = Describe("Testing the ssh3 cli", func() {
})

It("Should return the correct exit status", func() {
clientArgs0 := append(getClientArgs(privKeyPath), "exit", "0")
clientArgs1 := append(getClientArgs(privKeyPath), "exit", "1")
clientArgs255 := append(getClientArgs(privKeyPath), "exit", "255")
clientArgsMinus1 := append(getClientArgs(privKeyPath), "exit", "-1")
clientArgs0 := append(getClientArgs(rsaPrivKeyPath), "exit", "0")
clientArgs1 := append(getClientArgs(rsaPrivKeyPath), "exit", "1")
clientArgs255 := append(getClientArgs(rsaPrivKeyPath), "exit", "255")
clientArgsMinus1 := append(getClientArgs(rsaPrivKeyPath), "exit", "-1")

command0 := exec.Command(ssh3Path, clientArgs0...)
session, err := Start(command0, GinkgoWriter, GinkgoWriter)
Expand Down Expand Up @@ -192,7 +203,7 @@ var _ = Describe("Testing the ssh3 cli", func() {

Eventually(serverStarted).Should(Receive())
// Execute the client with TCP port forwarding
clientArgs := getClientArgs(privKeyPath, "-forward-tcp", fmt.Sprintf("%d/%s@%d", localPort, remoteAddr.IP, remoteAddr.Port))
clientArgs := getClientArgs(rsaPrivKeyPath, "-forward-tcp", fmt.Sprintf("%d/%s@%d", localPort, remoteAddr.IP, remoteAddr.Port))
command := exec.Command(ssh3Path, clientArgs...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Expand Down Expand Up @@ -301,7 +312,7 @@ var _ = Describe("Testing the ssh3 cli", func() {

Eventually(serverStarted).Should(Receive())
// Execute the client with UDP port forwarding
clientArgs := getClientArgs(privKeyPath, "-forward-udp", fmt.Sprintf("%d/%s@%d", localPort, remoteAddr.IP, remoteAddr.Port))
clientArgs := getClientArgs(rsaPrivKeyPath, "-forward-udp", fmt.Sprintf("%d/%s@%d", localPort, remoteAddr.IP, remoteAddr.Port))
command := exec.Command(ssh3Path, clientArgs...)
session, err := Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Expand Down
23 changes: 21 additions & 2 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/golang-jwt/jwt/v5"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/cryptobyte"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
)
Expand Down Expand Up @@ -164,13 +165,31 @@ func (q *DatagramsQueue) WaitNext(ctx context.Context) ([]byte, error) {
}

func JWTSigningMethodFromCryptoPubkey(pubkey crypto.PublicKey) (jwt.SigningMethod, error) {
log.Debug().Type("SigningMethodType", pubkey).Msg("fetching singing method from crypto.PublicKey")

switch pubkey.(type) {
case *rsa.PublicKey:
log.
Trace().
Type("SigningMethodType", pubkey).
Str("FoundSigningMethod", "RSA").
Msg("found public key type")
return jwt.SigningMethodRS256, nil
case *ed25519.PublicKey:
case ed25519.PublicKey:
log.
Trace().
Type("SigningMethodType", pubkey).
Str("FoundSigningMethod", "ED25519").
Msg("found public key type")
return jwt.SigningMethodEdDSA, nil
default:
log.
Error().
Type("SigningMethodType", pubkey).
Str("FoundSigningMethod", "unknown").
Msg("did not find public key type")
return nil, UnknownSSHPubkeyType{pubkey: pubkey}
}
return nil, UnknownSSHPubkeyType{pubkey: pubkey}
}

func Sha256Fingerprint(in []byte) string {
Expand Down

0 comments on commit 6127e06

Please sign in to comment.