Skip to content

Commit 091cfa9

Browse files
committed
Add gitlab-sshd acceptance tests for all supported SSH key types
This will ensure future changes to crypto configurations are properly vetted.
1 parent 88d8b28 commit 091cfa9

File tree

3 files changed

+61
-34
lines changed

3 files changed

+61
-34
lines changed

.gitlab-ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ tests:fips:
186186
- .test-job
187187
variables:
188188
FIPS_MODE: 1
189-
GOLANG_FIPS: 1
190189
script:
191190
- make test_fancy
192191

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ifeq (${FIPS_MODE}, 1)
2828
# If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be
2929
# explicitly switched on.
3030
export CGO_ENABLED=1
31+
export GOLANG_FIPS=1
3132

3233
# Go 1.19 now requires GOEXPERIMENT=boringcrypto for FIPS compilation.
3334
# See https://github.com/golang/go/issues/51940 for more details.

cmd/gitlab-sshd/acceptance_test.go

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package main_test
33
import (
44
"bufio"
55
"context"
6+
"crypto/ecdsa"
67
"crypto/ed25519"
8+
"crypto/elliptic"
79
"crypto/rand"
810
"crypto/rsa"
911
"encoding/json"
@@ -38,6 +40,14 @@ import (
3840
var (
3941
sshdPath = ""
4042
gitalyConnInfo *gitalyConnectionInfo
43+
keyTypes = []string{
44+
"rsa-2048",
45+
"rsa-4096",
46+
"ed25519",
47+
"ecdsa-p256",
48+
"ecdsa-p384",
49+
"ecdsa-p521",
50+
}
4151
)
4252

4353
const (
@@ -51,6 +61,26 @@ type gitalyConnectionInfo struct {
5161
Storage string `json:"storage"`
5262
}
5363

64+
func generateKey(keyType string) (interface{}, error) {
65+
switch strings.ToLower(keyType) {
66+
case "rsa-2048":
67+
return rsa.GenerateKey(rand.Reader, 2048)
68+
case "rsa-4096":
69+
return rsa.GenerateKey(rand.Reader, 4096)
70+
case "ed25519":
71+
_, priv, err := ed25519.GenerateKey(rand.Reader)
72+
return priv, err
73+
case "ecdsa-p256":
74+
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
75+
case "ecdsa-p384":
76+
return ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
77+
case "ecdsa-p521":
78+
return ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
79+
default:
80+
return nil, fmt.Errorf("unsupported key type: %s", keyType)
81+
}
82+
}
83+
5484
func init() {
5585
rootDir := rootDir()
5686
sshdPath = filepath.Join(rootDir, "bin", "gitlab-sshd")
@@ -214,20 +244,15 @@ sshd:
214244
- "` + hostKeyPath + `"`)
215245
}
216246

217-
func buildClient(t *testing.T, addr string, hostKey ed25519.PublicKey) *ssh.Client {
247+
func buildClient(t *testing.T, addr string, clientKeyType string, hostKey ed25519.PublicKey) *ssh.Client {
218248
t.Helper()
219249

220250
pubKey, err := ssh.NewPublicKey(hostKey)
221251
require.NoError(t, err)
222252

223253
var clientPrivKey interface{}
224254

225-
if os.Getenv("FIPS_MODE") == "1" {
226-
clientPrivKey, err = rsa.GenerateKey(rand.Reader, 2048)
227-
} else {
228-
_, clientPrivKey, err = ed25519.GenerateKey(nil)
229-
}
230-
255+
clientPrivKey, err = generateKey(clientKeyType)
231256
require.NoError(t, err)
232257

233258
clientSigner, err := ssh.NewSignerFromKey(clientPrivKey)
@@ -328,7 +353,7 @@ func startSSHD(t *testing.T, dir string) string {
328353

329354
// Starts an instance of gitlab-sshd with the given arguments, returning an SSH
330355
// client already connected to it
331-
func runSSHD(t *testing.T, apiHandler http.Handler) *ssh.Client {
356+
func runSSHD(t *testing.T, clientKeyType string, apiHandler http.Handler) *ssh.Client {
332357
t.Helper()
333358

334359
// Set up a stub gitlab server
@@ -342,7 +367,7 @@ func runSSHD(t *testing.T, apiHandler http.Handler) *ssh.Client {
342367
dir, hostKey := configureSSHD(t, apiServer.URL)
343368
listenAddr := startSSHD(t, dir)
344369

345-
return buildClient(t, listenAddr, hostKey)
370+
return buildClient(t, listenAddr, clientKeyType, hostKey)
346371
}
347372

348373
func TestDiscoverSuccess(t *testing.T) {
@@ -352,7 +377,7 @@ func TestDiscoverSuccess(t *testing.T) {
352377
fmt.Fprint(w, `{"id": 1000, "name": "Test User", "username": "test-user"}`)
353378
},
354379
}
355-
client := runSSHD(t, successAPI(t, handler))
380+
client := runSSHD(t, "ed25519", successAPI(t, handler))
356381

357382
session, err := client.NewSession()
358383
require.NoError(t, err)
@@ -370,7 +395,7 @@ func TestPersonalAccessTokenSuccess(t *testing.T) {
370395
fmt.Fprint(w, `{"success": true, "token": "testtoken", "scopes": ["api"], "expires_at": "9001-01-01"}`)
371396
},
372397
}
373-
client := runSSHD(t, successAPI(t, handler))
398+
client := runSSHD(t, "ed25519", successAPI(t, handler))
374399

375400
session, err := client.NewSession()
376401
require.NoError(t, err)
@@ -388,7 +413,7 @@ func TestTwoFactorAuthRecoveryCodesSuccess(t *testing.T) {
388413
fmt.Fprint(w, `{"success": true, "recovery_codes": ["code1", "code2"]}`)
389414
},
390415
}
391-
client := runSSHD(t, successAPI(t, handler))
416+
client := runSSHD(t, "ed25519", successAPI(t, handler))
392417
session, stdin, stdout := newSession(t, client)
393418

394419
reader := bufio.NewReader(stdout)
@@ -428,7 +453,7 @@ func TwoFactorAuthVerifySuccess(t *testing.T) {
428453
fmt.Fprint(w, `{"success": true}`)
429454
},
430455
}
431-
client := runSSHD(t, successAPI(t, handler))
456+
client := runSSHD(t, "ed25519", successAPI(t, handler))
432457
session, stdin, stdout := newSession(t, client)
433458

434459
reader := bufio.NewReader(stdout)
@@ -455,7 +480,7 @@ func TestGitLfsAuthenticateSuccess(t *testing.T) {
455480
fmt.Fprint(w, `{"username": "test-user", "lfs_token": "testlfstoken", "repo_path": "foo", "expires_in": 7200}`)
456481
},
457482
}
458-
client := runSSHD(t, successAPI(t, handler))
483+
client := runSSHD(t, "ed25519", successAPI(t, handler))
459484

460485
session, err := client.NewSession()
461486
require.NoError(t, err)
@@ -471,27 +496,29 @@ func TestGitLfsAuthenticateSuccess(t *testing.T) {
471496
func TestGitReceivePackSuccess(t *testing.T) {
472497
ensureGitalyRepository(t)
473498

474-
client := runSSHD(t, successAPI(t))
475-
session, stdin, stdout := newSession(t, client)
476-
477-
err := session.Start(fmt.Sprintf("git-receive-pack %s", testRepo))
478-
require.NoError(t, err)
499+
for _, keyType := range keyTypes {
500+
t.Run(keyType, func(t *testing.T) {
501+
client := runSSHD(t, keyType, successAPI(t))
502+
session, stdin, stdout := newSession(t, client)
479503

480-
// Gracefully close connection
481-
_, err = fmt.Fprintln(stdin, "0000")
482-
require.NoError(t, err)
483-
stdin.Close()
504+
err := session.Start(fmt.Sprintf("git-receive-pack %s", testRepo))
505+
require.NoError(t, err)
484506

485-
output, err := io.ReadAll(stdout)
486-
require.NoError(t, err)
507+
// Gracefully close connection
508+
_, err = fmt.Fprintln(stdin, "0000")
509+
require.NoError(t, err)
510+
stdin.Close()
487511

488-
outputLines := strings.Split(string(output), "\n")
512+
output, err := io.ReadAll(stdout)
513+
require.NoError(t, err)
489514

490-
for i := 0; i < (len(outputLines) - 1); i++ {
491-
require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i])
515+
outputLines := strings.Split(string(output), "\n")
516+
for i := 0; i < (len(outputLines) - 1); i++ {
517+
require.Regexp(t, "^[0-9a-f]{44} refs/(heads|tags)/[^ ]+", outputLines[i])
518+
}
519+
require.Equal(t, "0000", outputLines[len(outputLines)-1])
520+
})
492521
}
493-
494-
require.Equal(t, "0000", outputLines[len(outputLines)-1])
495522
}
496523

497524
func TestGeoGitReceivePackSuccess(t *testing.T) {
@@ -508,7 +535,7 @@ func TestGeoGitReceivePackSuccess(t *testing.T) {
508535
assert.NoError(t, err)
509536
},
510537
}
511-
client := runSSHD(t, successAPI(t, handler))
538+
client := runSSHD(t, "ed25519", successAPI(t, handler))
512539
session, stdin, stdout := newSession(t, client)
513540

514541
err := session.Start(fmt.Sprintf("git-receive-pack %s", testRepo))
@@ -534,7 +561,7 @@ func TestGeoGitReceivePackSuccess(t *testing.T) {
534561
func TestGitUploadPackSuccess(t *testing.T) {
535562
ensureGitalyRepository(t)
536563

537-
client := runSSHD(t, successAPI(t))
564+
client := runSSHD(t, "ed25519", successAPI(t))
538565
defer client.Close()
539566

540567
numberOfSessions := 3
@@ -571,7 +598,7 @@ func TestGitUploadPackSuccess(t *testing.T) {
571598
func TestGitUploadArchiveSuccess(t *testing.T) {
572599
ensureGitalyRepository(t)
573600

574-
client := runSSHD(t, successAPI(t))
601+
client := runSSHD(t, "ed25519", successAPI(t))
575602
session, stdin, stdout := newSession(t, client)
576603
reader := bufio.NewReader(stdout)
577604

0 commit comments

Comments
 (0)