Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not panic on unexpected key format #85

Merged
merged 3 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

// The version in the current branch
var Version = "1.8.0"
var Version = "1.8.1"

// If this is "" (empty string) then it means that it is a final release.
// Otherwise, this is a pre-release e.g. "dev", "beta", "rc1", etc.
Expand Down
16 changes: 15 additions & 1 deletion keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ func ReadPrivateKey(reader io.Reader, passPhrase []byte) (privateKey [chacha20po
// Not OpenSSH private key, assuming OpenSSL private key, trying to figure out type (Ed25519 or X25519)
block, _ := pem.Decode(allBytes)

if block == nil {
return [chacha20poly1305.KeySize]byte{}, fmt.Errorf("Read of unrecognized private key format failed; " +
"expected PEM encoded key")
}

var openSSLPrivateKey openSSLPrivateKey
if _, err = asn1.Unmarshal(block.Bytes, &openSSLPrivateKey); err == nil {
// Trying to read OpenSSL Ed25519 private key and convert to X25519 private key
Expand All @@ -115,7 +120,7 @@ func ReadPrivateKey(reader io.Reader, passPhrase []byte) (privateKey [chacha20po
}

// Interpreting bytes as Crypt4GH private key bytes (https://crypt4gh.readthedocs.io/en/latest/keys.html)
if string(block.Bytes[:7]) == magic {
if len(block.Bytes) > 8 && string(block.Bytes[:7]) == magic {
return readCrypt4GHPrivateKey(block.Bytes, passPhrase)
}

Expand Down Expand Up @@ -233,6 +238,12 @@ func ReadPublicKey(reader io.Reader) (publicKey [chacha20poly1305.KeySize]byte,

// Not OpenSSH public key, assuming OpenSSL public key
block, _ := pem.Decode(allBytes)

if block == nil {
return [chacha20poly1305.KeySize]byte{}, fmt.Errorf("Read of unrecognized public key format failed; " +
"expected PEM encoded key")
}

var openSSLPublicKey openSSLPublicKey
if _, err = asn1.Unmarshal(block.Bytes, &openSSLPublicKey); err == nil {
// Trying to read OpenSSL Ed25519 public key and convert to X25519 public key
Expand All @@ -250,6 +261,9 @@ func ReadPublicKey(reader io.Reader) (publicKey [chacha20poly1305.KeySize]byte,
}
}

if len(block.Bytes) < chacha20poly1305.KeySize {
return publicKey, fmt.Errorf("Unsupported key file format")
}
// Interpreting bytes as Crypt4GH public key bytes (X25519)
copy(publicKey[:], block.Bytes[len(block.Bytes)-chacha20poly1305.KeySize:])

Expand Down
37 changes: 34 additions & 3 deletions keys/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ const crypt4ghX25519Pub = `-----BEGIN CRYPT4GH PUBLIC KEY-----
y67skGFKqYN+0n+1P0FyxYa/lHPUWiloN4kdrx7J3BA=
-----END CRYPT4GH PUBLIC KEY-----
`

const badPEM = `-----BEGIN SOMETHING-----
y67s
-----END SOMETHING-----
`
const sshEd25519SecEnc = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCKYb3joJ
xaRg4JDkveDbaTAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIA65hmgJeJakva2c
Expand Down Expand Up @@ -173,13 +176,17 @@ func TestReadKey(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {

var err error
var key [chacha20poly1305.KeySize]byte
if test.readPrivateKeyFunction != nil {
key, _ = test.readPrivateKeyFunction(strings.NewReader(test.content), test.passPhrase)
key, err = test.readPrivateKeyFunction(strings.NewReader(test.content), test.passPhrase)
} else {
key, _ = test.readPublicKeyFunction(strings.NewReader(test.content))
key, err = test.readPublicKeyFunction(strings.NewReader(test.content))
}

if err != nil {
t.Errorf("Unexpected error: %v for test %s", err, test.name)
}
if hex.EncodeToString(key[:]) != test.hash {
t.Fail()
}
Expand Down Expand Up @@ -318,3 +325,27 @@ func TestGenerateSharedKey(t *testing.T) {
})
}
}

func TestReadBrokenKey(t *testing.T) {

if _, err := ReadPrivateKey(strings.NewReader("error"), nil); err == nil {
t.Errorf("Didn't get an error on a faulty private key")
}

if _, err := ReadPublicKey(strings.NewReader("error")); err == nil {
t.Errorf("Didn't get an error on a faulty public key")
}

if _, err := ReadPrivateKey(strings.NewReader(badPEM), nil); err == nil {
t.Errorf("Didn't get an error on a faulty private key")
}

if _, err := ReadPublicKey(strings.NewReader(badPEM)); err == nil {
t.Errorf("Didn't get an error on a faulty public key")
}

if _, err := ReadPrivateKey(strings.NewReader(crypt4ghX25519Sec), nil); err == nil {
t.Errorf("Didn't get an error on an encrypted private key without password")
}

}
Loading