Skip to content

Commit b927499

Browse files
committed
use O(n) when filtering pub keys
1 parent 18ecf34 commit b927499

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

nodes/vr_sros/sshKey.go

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,41 +9,52 @@ import (
99

1010
"github.com/hairyhenderson/gomplate/v3"
1111
"github.com/hairyhenderson/gomplate/v3/data"
12+
log "github.com/sirupsen/logrus"
1213
"golang.org/x/crypto/ssh"
13-
"golang.org/x/exp/slices"
1414
)
1515

1616
// importing Default Config template at compile time
1717
//
1818
//go:embed ssh_keys.go.tpl
1919
var SROSSSHKeysTemplate string
2020

21-
// filterSSHPubKeys returns marshalled SSH keys that match either of the
22-
// provided key algorithms.
21+
// filterSSHPubKeys returns rsa and ecdsa keys from the list of ssh keys stored at s.sshPubKeys.
2322
// Since SR OS supports only certain key types, we need to filter out the rest.
24-
func (s *vrSROS) filterSSHPubKeys(sshKeyAlgos []string) []string {
25-
keyValues := make([]string, 0, len(s.sshPubKeys))
23+
func (s *vrSROS) filterSSHPubKeys(supportedSSHKeyAlgos map[string]struct{}) (rsaKeys []string, ecdsaKeys []string) {
24+
rsaKeys = make([]string, 0, len(s.sshPubKeys))
25+
ecdsaKeys = make([]string, 0, len(s.sshPubKeys))
2626

2727
for _, k := range s.sshPubKeys {
28-
if slices.Contains(sshKeyAlgos, k.Type()) {
29-
30-
keyType := k.Type()
31-
keyString := string(ssh.MarshalAuthorizedKey(k))
32-
33-
// Remove the key type prefix
34-
keyString = strings.TrimPrefix(keyString, keyType+" ")
28+
if _, ok := supportedSSHKeyAlgos[k.Type()]; !ok {
29+
log.Debugf("unsupported SSH Key Algo %q, skipping key", k.Type())
30+
continue
31+
}
3532

36-
// Remove the suffix (usually a comment or username)
37-
parts := strings.Fields(keyString)
38-
if len(parts) > 1 {
39-
keyString = parts[0]
40-
}
33+
// extract the fields
34+
// <keytype> <key> <comment>
35+
keyFields := strings.Fields(string(ssh.MarshalAuthorizedKey(k)))
4136

42-
keyValues = append(keyValues, keyString)
37+
switch {
38+
case isRSAKey(k):
39+
rsaKeys = append(rsaKeys, keyFields[1])
40+
case isECDSAKey(k):
41+
ecdsaKeys = append(ecdsaKeys, keyFields[1])
4342
}
4443
}
4544

46-
return keyValues
45+
return rsaKeys, ecdsaKeys
46+
}
47+
48+
func isRSAKey(key ssh.PublicKey) bool {
49+
return key.Type() == ssh.KeyAlgoRSA
50+
}
51+
52+
func isECDSAKey(key ssh.PublicKey) bool {
53+
kType := key.Type()
54+
55+
return kType == ssh.KeyAlgoECDSA521 ||
56+
kType == ssh.KeyAlgoECDSA384 ||
57+
kType == ssh.KeyAlgoECDSA256
4758
}
4859

4960
// SROSTemplateData holds ssh keys for template generation.
@@ -59,13 +70,15 @@ func (s *vrSROS) configureSSHPublicKeys(
5970
username, password string, pubKeys []ssh.PublicKey) error {
6071
tplData := SROSTemplateData{}
6172

62-
// creating a list of ECDSA Key Types
63-
rsaKeyTypes := []string{"ssh-rsa"}
64-
ecdsaKeyTypes := []string{"ssh-ed25519", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521"}
73+
// a map of supported SSH key algorithms
74+
supportedSSHKeyAlgos := map[string]struct{}{
75+
ssh.KeyAlgoRSA: {},
76+
ssh.KeyAlgoECDSA521: {},
77+
ssh.KeyAlgoECDSA384: {},
78+
ssh.KeyAlgoECDSA256: {},
79+
}
6580

66-
// checking on existence of SSH Public Keys and populating tplData
67-
tplData.SSHPubKeysRSA = s.filterSSHPubKeys(rsaKeyTypes)
68-
tplData.SSHPubKeysECDSA = s.filterSSHPubKeys(ecdsaKeyTypes)
81+
tplData.SSHPubKeysRSA, tplData.SSHPubKeysECDSA = s.filterSSHPubKeys(supportedSSHKeyAlgos)
6982

7083
t, err := template.New("SSHKeys").Funcs(
7184
gomplate.CreateFuncs(context.Background(), new(data.Data))).Parse(SROSSSHKeysTemplate)

0 commit comments

Comments
 (0)