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

Create verifier #314

Merged
merged 5 commits into from
Jan 24, 2017
Merged

Create verifier #314

merged 5 commits into from
Jan 24, 2017

Conversation

gdbelvin
Copy link
Contributor

In KeyManager:

  • Adds support for keys that are not password protected.
  • Supports getting the public key for private keys that are loaded.

glog.Warningf("error parsing EC key: %s", err)
return nil, trillian.SignatureAlgorithm_ANONYMOUS, errors.New("could not parse private key")
return key2, trillian.SignatureAlgorithm_ECDSA, nil

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't immediately see - what's the benefit of the change here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go style stipulates that the main code path should be not be indented. This puts the error case inside the if block and the success case at the outer level of indentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I think keeping the symmetry of the different cases is more helpful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to change it back, though when reading the code, this deviation from the style guide caused me confusion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware of the style guide recommendation, but I think consistency is better here -- all the arms above have the "non-error" path indented.

R, S *big.Int
}
rest, err := asn1.Unmarshal(sig, &ecdsaSig)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nicer to propagate more error information, e.g.:

  fmt.Errorf("failed to unmarshal signature: %v", err)
  fmt.Errorf("trailing data in signature")
  fmt.Errorf("failed to verify signature")

(which probably also means the general ErrVerify isn't needed)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errors are obscured for security reasons. I could log them, but I'm not clear on what logging scheme is preferred in Trillian.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow the security concern -- wouldn't a concern about a Bleichenbacher-style oracle attack only apply at the point where results are exposed over a remote interface? Or to put it another way: a direct caller of this code could figure out the same error details themselves, by examining the inputs to the function.

(I just know that it's a pain in the neck to debug what's wrong when signatures don't immediately verify.)

Copy link
Contributor Author

@gdbelvin gdbelvin Jan 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but we don't know how people will use this library. Prefer to have secure defaults. I know it's a pain in the neck too. - but I find that that pain tends to only happen during development, when inserting Printfs is a great debugging strategy. After the code is stable, it rarely comes up.

)

const (
// openssl ecparam -name prime256v1 -genkey -out p256-key.pem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay for including a comment that indicates how the key data was generated!

MHcCAQEEIGbhE2+z8d5lHzb0gmkS78d86gm5gHUtXCpXveFbK3pcoAoGCCqGSM49
AwEHoUQDQgAEUxX42oxJ5voiNfbjoz8UgsGqh1bD1NXK9m8VivPmQSoYUdVFgNav
csFaQhohkiCEthY51Ga6Xa+ggn+eTZtf9Q==
-----END EC PRIVATE KEY-----`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the key in testonly/keys.go work here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or is there something special about this key for this test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works, and I've used it.
This particular key does not have a password attached, testing a new code path, so it's remained.

)

func TestSignVerify(t *testing.T) {
for _, tc := range []struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm told test is more usual than tc


km := NewPEMKeyManager()
if err := km.LoadPrivateKey(tc.PEM, ""); err != nil {
t.Error(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More information in failure messages would be good (throughout); Go form seems to normally be like t.Errorf("MyFunc(arg)=%v; want %v", got, want), so this one would be:

t.Errorf("LoadPrivateKey(pem)=%v; want nil", err)

}
hasher, err := NewHasher(test.HashAlgo)
if err != nil {
t.Errorf("NewHasher(%v)=%v, want nil", test.HashAlgo, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to give a clue about which return value is unexpected, e.g.

t.Errorf("NewHasher(%v)=(_,%v), want (_,nil)", test.HashAlgo, err)

(passim)

In KeyManager:
* Adds support for keys that are not password protected.
* Supports getting the public key for private keys that are loaded.
Copy link
Contributor

@daviddrysdale daviddrysdale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as long as Travis is happy

@gdbelvin gdbelvin merged commit a7e8e00 into google:master Jan 24, 2017
@gdbelvin gdbelvin deleted the verifier branch January 24, 2017 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants