zalando / go-keyring

Cross-platform keyring interface for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DecodeString corrupts valid single line hex strings

jaroslaw-bochniak opened this issue · comments

Assumption taken in the following breaking change 41dbcc1 is problematic as it corrupts single line valid hex strings (that were not encoded) and returns them in a decoded form.

In this case it is not enough to check whenever dec, err := hex.DecodeString(trimStr) does return an error to determine whenever value was stored in encoded form.

One of the propositions might be to perform decoding as an optional operation during obtaining stored value, or keep additional metadata after storing the value which will indicate whenever the value was encoded or not.

Test Case:

// TestGetSingleLineHexString tests getting a single line hex string password from the keyring.
func TestGetSingleLineHexString(t *testing.T) {
	hexPassword :=  "abcdef123abcdef123"
	err := Set(service, user, hexPassword)
	if err != nil {
		t.Errorf("Should not fail, got: %s", err)
	}

	pw, err := Get(service, user)
	if err != nil {
		t.Errorf("Should not fail, got: %s", err)
	}

	if hexPassword != pw {
		t.Errorf("Expected password %s, got %s", hexPassword, pw)
	}
}

or keep additional metadata after storing the value which will indicate whenever the value was encoded or not.

I think this is the right way to go!

Confirming this bug from my side. We use this library to store keychain secrets on our local machines, and anyone who updates to the newer commit sha has multiple secrets corrupted on output.

I'm sorry I haven't had time to look into a fix. PRs are very welcome otherwise I will try to look into it next week after my vacation.

Hmm, so I'm poking at this a bit. New to security but what I'm finding is that the -G option (generic attribute) only allows specifying a single value. Subsequent uses of -G override the previous. This in addition to having to extract and parse it from the output would be unpleasant.

A second thought might be to create a struct and JSON encode it into the comment field. This will at least allow future expansions of the metadata.

What are your thoughts? What would the best, least intrusive, most future-proofed method be?

Alternatively we can prefix encoded passwords with some string which will not be in any valid passwords e.g.: go-keyring-encoded: and look for this prefix when determining how to handle the password.