Skip to content

Commit

Permalink
#54 - Change the public key representation to make it possible to get…
Browse files Browse the repository at this point in the history
… access to the content to be able to do the computation on it
  • Loading branch information
piratax007 committed Jul 18, 2022
1 parent 6eb6d4c commit f19a56a
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 23 deletions.
43 changes: 32 additions & 11 deletions ssh/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,19 @@ func (s *sshSuite) Test_access_AllKeys_ReturnsAKeyEntryListOfPublicKeysIfSSHDire
s.createEmptyFile(sshDirectory, "empty-file")

a, _ := accessWithTestLogging()
s.ElementsMatch([]api.KeyEntry{
createPublicKeyRepresentation(path.Join(sshDirectory, publicKeyFile1)),
createPublicKeyRepresentation(path.Join(sshDirectory, publicKeyFile2)),
createPublicKeyRepresentation(path.Join(sshDirectory, publicKeyFile3)),
}, a.AllKeys())
p := publicKeyRepresentationsFrom([]string{
path.Join(sshDirectory, publicKeyFile1),
path.Join(sshDirectory, publicKeyFile2),
path.Join(sshDirectory, publicKeyFile3),
})
s.ElementsMatch([]api.KeyEntry{p[0], p[1], p[2]}, a.AllKeys())
}

func createPublicKeyRepresentationForTest(path, key string) *publicKeyRepresentation {
return createPublicKeyRepresentationFromPublicKey(&publicKey{
location: path,
key: key,
})
}

func (s *sshSuite) Test_access_AllKeys_ReturnsAKeyEntryListOfKeypairsIfSSHDirectoryHasOnlyMatchingPublicAndPrivateKeys() {
Expand All @@ -108,9 +116,12 @@ func (s *sshSuite) Test_access_AllKeys_ReturnsAKeyEntryListOfKeypairsIfSSHDirect

a, _ := accessWithTestLogging()
s.ElementsMatch([]api.KeyEntry{
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile1)), createPublicKeyRepresentation(path.Join(sshDirectory, matchingPublicKeyFile1))),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile2)), createPublicKeyRepresentation(path.Join(sshDirectory, matchingPublicKeyFile2))),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile3)), createPublicKeyRepresentation(path.Join(sshDirectory, matchingPublicKeyFile3))),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile1)),
createPublicKeyRepresentationForTest(path.Join(sshDirectory, matchingPublicKeyFile1), "BBBB")),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile2)),
createPublicKeyRepresentationForTest(path.Join(sshDirectory, matchingPublicKeyFile2), "AAAA")),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKeyFile3)),
createPublicKeyRepresentation(path.Join(sshDirectory, matchingPublicKeyFile3))),
}, a.AllKeys())
}

Expand All @@ -133,7 +144,17 @@ func (s *sshSuite) Test_access_AllKeys_ReturnsAKeyEntryListIfSSHDirectoryPublicA
a, _ := accessWithTestLogging()
s.ElementsMatch([]api.KeyEntry{
createPrivateKeyRepresentation(path.Join(sshDirectory, lonelyPrivateKeyFile)),
createPublicKeyRepresentation(path.Join(sshDirectory, lonelyPublicKeyFile)),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKey)), createPublicKeyRepresentation(path.Join(sshDirectory, matchingPublicKey))),
createPublicKeyRepresentationFromPublicKey(
&publicKey{
location: path.Join(sshDirectory, lonelyPublicKeyFile),
key: "AAAA",
}),
createKeypairRepresentation(createPrivateKeyRepresentation(path.Join(sshDirectory, matchingPrivateKey)),
createPublicKeyRepresentationFromPublicKey(
&publicKey{
location: path.Join(sshDirectory, matchingPublicKey),
key: "BBBB",
}),
),
}, a.AllKeys())
}
}
17 changes: 12 additions & 5 deletions ssh/file_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func createPublicKeyRepresentationsFrom(input []string) []*publicKeyRepresentati
return transform(input, createPublicKeyRepresentation)
}

func createPublicKeyRepresentationsFromPublicKeys(input []*publicKey) []*publicKeyRepresentation {
return transform(input, createPublicKeyRepresentationFromPublicKey)
}

func createPrivateKeyRepresentationsFrom(input []string) []*privateKeyRepresentation {
return transform(input, createPrivateKeyRepresentation)
}
Expand All @@ -51,9 +55,12 @@ func (a *access) privateKeyRepresentationsFrom(input []string) []*privateKeyRepr
}

func publicKeyRepresentationsFrom(input []string) []*publicKeyRepresentation {
publicKeyFiles := concat(
filesContainingRSAPublicKeys(input),
filesContainingEd25519PublicKeys(input),
)
return createPublicKeyRepresentationsFrom(publicKeyFiles)
rsaKeys := rsaPublicKeysFrom(input)
rsaKeyRepresentations := createPublicKeyRepresentationsFromPublicKeys(rsaKeys)

publicKeyFiles := filesContainingEd25519PublicKeys(input)

return concat(
rsaKeyRepresentations,
createPublicKeyRepresentationsFrom(publicKeyFiles))
}
12 changes: 8 additions & 4 deletions ssh/file_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,11 @@ func (s *sshSuite) Test_createPublicKeyEntriesFrom_ReturnsAListOfKeyEntriesFromA

paths = []string{"a path"}
l = createPublicKeyRepresentationsFrom(paths)
s.Equal([]*publicKeyRepresentation{{"a path"}}, l)
s.Equal([]*publicKeyRepresentation{{path: "a path", key: nil}}, l)

paths = []string{"a path", "another path"}
l = createPublicKeyRepresentationsFrom(paths)
s.Equal([]*publicKeyRepresentation{{"a path"}, {"another path"}}, l)
s.Equal([]*publicKeyRepresentation{{path: "a path", key: nil}, {path: "another path"}}, l)
}

func (s *sshSuite) Test_createPrivateKeyEntriesFrom_ReturnsAListOfKeyEntriesFromAllTheProvidedPaths() {
Expand Down Expand Up @@ -450,10 +450,14 @@ func (s *sshSuite) Test_publicKeyEntriesFrom_ReturnsAListOfPublicKeyEntriesFromA
}

l = publicKeyRepresentationsFrom(paths)
s.Equal([]*publicKeyRepresentation{
s.Equal(publicKeyRepresentationsFrom([]string{
filepath.Join(s.tdir, publicRSAKeyFile1),
filepath.Join(s.tdir, publicRSAKeyFile2),
}), l)
/*s.Equal([]*publicKeyRepresentation{
createPublicKeyRepresentation(filepath.Join(s.tdir, publicRSAKeyFile1)),
createPublicKeyRepresentation(filepath.Join(s.tdir, publicRSAKeyFile2)),
}, l)
}, l)*/
}

func (s *sshSuite) Test_partitionKeyEntries_ReturnsAListOfKeyEntriesWithPublicPrivateAndKeyPairsFromPublicAndPrivateKeyRepresentations() {
Expand Down
1 change: 1 addition & 0 deletions ssh/key_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func listFilesIn(dir string) []string {
}

type publicKey struct {
location string
algorithm string
key string
comment string
Expand Down
2 changes: 1 addition & 1 deletion ssh/key_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (s *sshSuite) Test_CheckIfThePublicKeyTypeIdentifierIsRSA() {
s.False(pub.isRSA(), "A key with the algorithm identifier ssh-ecdsa is not an RSA key")
}

func (s *sshSuite) Test_CheckIfAStringHasTheFormatOfAnRSAPublicKey() {
func (s *sshSuite) Test_isRSAPublicKey_checkIfAStringHasTheFormatOfAnRSAPublicKey() {
k := ""
s.False(isRSAPublicKey(k), "An empty string is not an SSH public key representation thus it is not an RSA key")

Expand Down
17 changes: 16 additions & 1 deletion ssh/key_representation.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package ssh

import "github.com/digitalautonomy/keymirror/api"
import (
"github.com/digitalautonomy/keymirror/api"
)

type privateKeyRepresentation struct {
path string
}

type publicKeyRepresentation struct {
path string
key []byte
}

type keypairRepresentation struct {
Expand All @@ -21,6 +24,14 @@ func createPublicKeyRepresentation(path string) *publicKeyRepresentation {
}
}

func createPublicKeyRepresentationFromPublicKey(key *publicKey) *publicKeyRepresentation {
return &publicKeyRepresentation{
path: key.location,
// TODO: this should decode the base64 before setting it
key: []byte(key.key),
}
}

func createPrivateKeyRepresentation(path string) *privateKeyRepresentation {
return &privateKeyRepresentation{
path: path,
Expand Down Expand Up @@ -86,6 +97,10 @@ func (k *publicKeyRepresentation) KeyType() api.KeyType {
return api.PublicKeyType
}

func (k *publicKeyRepresentation) WithDigestContent(f func([]byte) []byte) []byte {
return f(k.key)
}

// Locations implement the KeyEntry interface
func (k *keypairRepresentation) Locations() []string {
return append(k.private.Locations(), k.public.Locations()...)
Expand Down
39 changes: 38 additions & 1 deletion ssh/key_representation_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package ssh

import "github.com/digitalautonomy/keymirror/api"
import (
"crypto/sha256"
"encoding/base64"
"github.com/digitalautonomy/keymirror/api"
)

func (s *sshSuite) Test_createPublicKeyRepresentation_createsTheObject() {
r := createPublicKeyRepresentation("foo_rsa.pub")
Expand Down Expand Up @@ -269,3 +273,36 @@ func (s *sshSuite) Test_pairKeyRepresentation_KeyType_returnsPair() {

s.Equal(api.PairKeyType, kp.KeyType())
}

func decode(b64 string) []byte {
r, _ := base64.StdEncoding.DecodeString(b64)
return r
}

const originalKey = "AAAAB3NzaC1yc2EAAAADAQABAAABgQDjXHGj/u27siLdKDii3ijK8xjKwRgYw6f2r+qfk9f5Nc3CD71Hpxndh3kg3GTdiQauPtzJHeFsm2dFW6lxz0nFqIkrxqTV+maJ57bABehbnFP25IxSKSG/8JBqNDdkipQq14mHmCHCmtU4KTzonHqOssvOkjKSs1iPPK0PBONGKXWMrrNm8U9ProLcwtHsNkJNXcq1qhAdbn+ICVcOB19Wibjp5noLZ2NRxxuzJHPwAXuXT22LpVobaeD/HvqoXPXP5R91smlfFvRSgvoRDr+ufeEL8sUO++emu3+ThG+iEvLGeucR1o4+UFweXM9UdPQW4HFrIpvMPHnbg8ysT07vqH/tA0+TxJocFcADxM89+k/4mS7nRZgCnqpe50JuuJYOBWhZxaaanasEY/+lIdni9u3ZTwhPHG8trokPxdpklKQnN2Pg2Y2SX2N8u3s+IYaTO6s9Cs6fokiK475w1UexTMYW0XuJdN8wFRfDMJpZm+ICVc+K6BpxAyABe4u1RPc="
const otherKey = "AAAAB3NzaC1yc2EAAAADAQABAAABgQC6CyfdeOltbKbISAuuvH27pLNxsNsJ18z29jiZLJ5kvJ9kOXXiZxvZW1a394G9YgDpbUFwjbMz4WgkFNPW7+VVdz07JXpxzs4IrCSE8zl944v98k1kwZ5n6jZR3A51jmb55KjvzFeRv2fqbxb7ylV1R5oNpSYu8l7HaWpR0YSjtuZcSahhPZS4hSbgAKrLm+mn6gfLHyYKEeQ0NRpwxybmrM+dEBdR/bs0JxEgJvrfsOahYEbZhL627NQx9F1NfPq2yGr13lLmA7wIIu633WAyxJDGaCfRQTXR67W16Hl+0LIbhe4b5iKJH/7+tf13C2VMewDPCZwDxf6XAwD1XmEC4L64rhGhFp51u9qrbFQnaDAfTRfgm8sS4oxsHMnWc3TRes3PKcQ08CGkSV42EPiQuIyQaUojVcNo+xhCJzqv77/GcwyxCtm3FN/gjlXLxPtFrWjcvd91Z8v/7npjzJDAOUnAV8QFijCzC688oSuoBr5q9G9zcWd7MVY2vpms1L8="

func (s *sshSuite) Test_publicKeyRepresentation_WithDigestContent_returnsTheFingerPrint() {
key := &publicKeyRepresentation{key: decode(originalKey)}
fingerprint := key.key
result := key.WithDigestContent(func(in []byte) []byte {
return in
})
s.Equal(result, fingerprint)

key = &publicKeyRepresentation{key: decode(originalKey)}
fingerprint = decode("rPPC5HJW2WNPqThrwNnL7szNtrEC7lUjKLlt0Jnunoo=")
result = key.WithDigestContent(func(in []byte) []byte {
res := sha256.Sum256(in)
return res[:]
})
s.Equal(result, fingerprint)

key = &publicKeyRepresentation{key: decode(otherKey)}
fingerprint = decode("Az/Dp2M/PXj/fsxRQWWj954BgtKRX8DJ1t7nDrS+TTw=")
result = key.WithDigestContent(func(in []byte) []byte {
res := sha256.Sum256(in)
return res[:]
})
s.Equal(result, fingerprint)
}
23 changes: 23 additions & 0 deletions ssh/rsa_file_reader.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ssh

import "os"

func checkIfFileContainsAPublicRSAKey(fileName string) (bool, error) {
return fileContentMatches(fileName, isRSAPublicKey)
}
Expand All @@ -12,6 +14,27 @@ func filesContainingRSAPublicKeys(fileNameList []string) []string {
return filter(fileNameList, ignoringErrors(checkIfFileContainsAPublicRSAKey))
}

func rsaPublicKeysFrom(fileNameList []string) []*publicKey {
return filter(transform(fileNameList, func(fileName string) *publicKey {
content, e := os.ReadFile(fileName)
if e != nil {
return nil
}

pub, ok := parsePublicKey(string(content))
if !ok {
return nil
}
pub.location = fileName
return &pub
}), func(pub *publicKey) bool {
if pub == nil {
return false
}
return pub.isRSA()
})
}

func (a *access) filesContainingRSAPrivateKeys(fileNameList []string) []string {
a.log.WithField("file names to check", fileNameList).Trace("filesContainingRSAPrivateKeys()")
result := filter(fileNameList, loggingErrors(a.log, "an error happened while checking if a file contains a private key", a.checkIfFileContainsAPrivateRSAKey))
Expand Down

0 comments on commit f19a56a

Please sign in to comment.