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

BLOCKED: Switch to pyelliptic for faster EC2 handling #39

Closed
wants to merge 1 commit into from

Conversation

jrconlin
Copy link

ecdsa is very flexible as a EC library, but CPU intensive. Switching to
a C lib based EC handler should make things faster and more CPU friendly
under loads.

@jrconlin jrconlin force-pushed the feat/ec-clib branch 5 times, most recently from 7d16605 to 56eeb49 Compare December 16, 2016 17:05
@jrconlin
Copy link
Author

I'm not quite sure why the 2.6 test is failing. It may be that the call out to OpenSSL is causing 'key' to be deallocated. It's clearly being defined. I know that 2.6 has reached EOL, so not sure how critical that test is.

@jrconlin jrconlin changed the title feat: Switch to pyelliptic for faster EC2 handling WIP: Switch to pyelliptic for faster EC2 handling Dec 17, 2016
@jrconlin
Copy link
Author

Sigh, there's a bug in the signature handler. Will update with fix.

@jrconlin
Copy link
Author

So, turns out that the backing library (pyelliptic) automatically runs whatever you pass it through SHA256. Obviously, that's bad. I've submitted a PR for that yann2192/pyelliptic#53.

That PR blocks this one.

@jrconlin jrconlin changed the title WIP: Switch to pyelliptic for faster EC2 handling BLOCKED: Switch to pyelliptic for faster EC2 handling Dec 22, 2016
jrconlin added a commit to mozilla-services/autopush that referenced this pull request Dec 23, 2016
This patch is dependent on two other library patches landing.
* mpdavis/python-jose#39
* yann2192/pyelliptic#53

Temporarily pointing to personal forks with patches applied.

closes #753
jrconlin added a commit to mozilla-services/autopush that referenced this pull request Dec 23, 2016
This patch is dependent on two other library patches landing.
* mpdavis/python-jose#39
* yann2192/pyelliptic#53

Temporarily pointing to personal forks with patches applied.

closes #753
jrconlin added a commit to mozilla-services/autopush that referenced this pull request Dec 23, 2016
This patch is dependent on two other library patches landing.
* mpdavis/python-jose#39
* yann2192/pyelliptic#53

Temporarily pointing to personal forks with patches applied.

closes #753
asn_set = decoder.decode(decoded)[0]
except:
raise JWKError("Invalid EC Key")
pri_key = self.bitstring_to_str(asn_set[1])
Copy link

Choose a reason for hiding this comment

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

This is only applicable for the first case; in the univ.Sequence case you end up having to shuffle this around.

I'd recommend initializing this to None, too, and moving this set into the first case block.

if pcurve:
curve = pcurve
# Shuffle the key to the right return.
pub_key = pri_key
Copy link

Choose a reason for hiding this comment

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

On the face of it, this is super alarming: setting the public value to the private value. Per the earlier comment, don't shuffle these. Basically, don't set pri_key to something that isn't a private key in the first place. If we aren't sure yet, let it remain asn_set[1]

pub_key = pri_key
pri_key = None
if not curve:
raise JWKError("Invalid EC curve type key specified.")
Copy link

Choose a reason for hiding this comment

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

Nit: It's not really that it was specified wrong, it's that the supplied data isn't one of our known formats.

@@ -161,7 +159,8 @@ def _sign_header_and_claims(encoded_header, encoded_claims, algorithm, key_data)
signing_input = b'.'.join([encoded_header, encoded_claims])
try:
key = jwk.construct(key_data, algorithm)
signature = key.sign(signing_input)
dat = signing_input.decode('utf8').encode('utf8')
Copy link

Choose a reason for hiding this comment

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

Nit: This could use a comment explaining why it's being round-tripped through the decoder/encoder

def repad(self, st):
"""Add base64 padding back to the end of a stripped character
sequence

Copy link

Choose a reason for hiding this comment

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

Nit: whitespace

raise JWKError("Invalid EC curve type key specified.")
return curve, pri_key, pub_key

def _process_jwk(self, jwk_dict, algorythm="sha256"):
Copy link

Choose a reason for hiding this comment

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

Nit: Spelling (Algorithm)

ecdsa is very flexible as a EC library, but CPU intensive. Switching to
a C lib based EC handler should make things faster and more CPU friendly
under loads.
@jrconlin
Copy link
Author

jrconlin commented Jan 3, 2017

@jcjones Thanks again for the r?s. Addressed (and did some flake8 fixes, plus a pointer to the newer pyelliptic library patch)

Copy link

@jcjones jcjones left a comment

Choose a reason for hiding this comment

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

LGTM!

# And finally the public key
pub_key = self.bitstring_to_str(asn_set[3])
# A public key starts with a sequence
if isinstance(asn_set[0], univ.Sequence):
Copy link

Choose a reason for hiding this comment

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

an elif instead of if would be a bit clearer here

@ghost
Copy link

ghost commented Mar 26, 2017

Cryptography will be included as a dependency if I succeed, and already has elliptic curve cryptography based on openssl. I'm not going to work on this, but the point is that if you use cryptography, then this won't be blocked.

@jrconlin
Copy link
Author

So, turns out that OpenSSL (and by default, python cryptography) use a DER formatted signature value, where ecdsa (and a number of others) use straight raw key data. Both contain the same info, but are incompatible. I'm working on the fix, I've filed different bugs pointing out the problem, and I'm going to contact spec authors to get some clarification about this.

The fix is "reasonably simple", (check the signature length, and if 64 octets, recompile the signature into a DER and hand that over to cryptography's EC verify. Needless to say, it's going to impact this patch, so I'm going to close this for now until the new patch is ready.

@jrconlin jrconlin closed this Mar 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants