33import hmac
44import six
55
6- import ecdsa
7-
86from jose .constants import ALGORITHMS
97from jose .exceptions import JWKError
10- from jose .utils import base64url_decode , base64_to_long
8+ from jose .utils import base64url_decode
119from jose .utils import constant_time_string_compare
1210from jose .backends .base import Key
13- from jose .backends import RSAKey
11+ from jose .backends import RSAKey , ECKey
1412
1513
1614def get_key (algorithm ):
@@ -122,90 +120,3 @@ def sign(self, msg):
122120
123121 def verify (self , msg , sig ):
124122 return constant_time_string_compare (sig , self .sign (msg ))
125-
126-
127- class ECKey (Key ):
128- """
129- Performs signing and verification operations using
130- ECDSA and the specified hash function
131-
132- This class requires the ecdsa package to be installed.
133-
134- This is based off of the implementation in PyJWT 0.3.2
135- """
136- SHA256 = hashlib .sha256
137- SHA384 = hashlib .sha384
138- SHA512 = hashlib .sha512
139-
140- CURVE_MAP = {
141- SHA256 : ecdsa .curves .NIST256p ,
142- SHA384 : ecdsa .curves .NIST384p ,
143- SHA512 : ecdsa .curves .NIST521p ,
144- }
145-
146- def __init__ (self , key , algorithm ):
147- if algorithm not in ALGORITHMS .EC :
148- raise JWKError ('hash_alg: %s is not a valid hash algorithm' % algorithm )
149- self .hash_alg = get_algorithm_object (algorithm )
150- self ._algorithm = algorithm
151-
152- self .curve = self .CURVE_MAP .get (self .hash_alg )
153-
154- if isinstance (key , (ecdsa .SigningKey , ecdsa .VerifyingKey )):
155- self .prepared_key = key
156- return
157-
158- if isinstance (key , dict ):
159- self .prepared_key = self ._process_jwk (key )
160- return
161-
162- if isinstance (key , six .string_types ):
163- if isinstance (key , six .text_type ):
164- key = key .encode ('utf-8' )
165-
166- # Attempt to load key. We don't know if it's
167- # a Signing Key or a Verifying Key, so we try
168- # the Verifying Key first.
169- try :
170- key = ecdsa .VerifyingKey .from_pem (key )
171- except ecdsa .der .UnexpectedDER :
172- key = ecdsa .SigningKey .from_pem (key )
173- except Exception as e :
174- raise JWKError (e )
175-
176- self .prepared_key = key
177- return
178-
179- raise JWKError ('Unable to parse an ECKey from key: %s' % key )
180-
181- def _process_jwk (self , jwk_dict ):
182- if not jwk_dict .get ('kty' ) == 'EC' :
183- raise JWKError ("Incorrect key type. Expected: 'EC', Recieved: %s" % jwk_dict .get ('kty' ))
184-
185- x = base64_to_long (jwk_dict .get ('x' ))
186- y = base64_to_long (jwk_dict .get ('y' ))
187-
188- if not ecdsa .ecdsa .point_is_valid (self .curve .generator , x , y ):
189- raise JWKError ("Point: %s, %s is not a valid point" % (x , y ))
190-
191- point = ecdsa .ellipticcurve .Point (self .curve .curve , x , y , self .curve .order )
192- verifying_key = ecdsa .keys .VerifyingKey .from_public_point (point , self .curve )
193-
194- return verifying_key
195-
196- def sign (self , msg ):
197- return self .prepared_key .sign (msg , hashfunc = self .hash_alg , sigencode = ecdsa .util .sigencode_string )
198-
199- def verify (self , msg , sig ):
200- try :
201- return self .prepared_key .verify (sig , msg , hashfunc = self .hash_alg , sigdecode = ecdsa .util .sigdecode_string )
202- except :
203- return False
204-
205- def public_key (self ):
206- if isinstance (self .prepared_key , ecdsa .VerifyingKey ):
207- return self
208- return self .__class__ (self .prepared_key .get_verifying_key (), self ._algorithm )
209-
210- def to_pem (self ):
211- return self .prepared_key .to_pem ()
0 commit comments