1+ from __future__ import division
2+
3+ import math
4+
15import six
2- import ecdsa
3- from ecdsa .util import sigdecode_string , sigencode_string , sigdecode_der , sigencode_der
6+
7+ try :
8+ from ecdsa import SigningKey as EcdsaSigningKey , VerifyingKey as EcdsaVerifyingKey
9+ except ImportError :
10+ EcdsaSigningKey = EcdsaVerifyingKey = None
411
512from jose .backends .base import Key
613from jose .utils import base64_to_long , long_to_base64
1118from cryptography .hazmat .backends import default_backend
1219from cryptography .hazmat .primitives import hashes , serialization
1320from cryptography .hazmat .primitives .asymmetric import ec , rsa , padding
21+ from cryptography .hazmat .primitives .asymmetric .utils import decode_dss_signature , encode_dss_signature
1422from cryptography .hazmat .primitives .serialization import load_pem_private_key , load_pem_public_key
23+ from cryptography .utils import int_from_bytes , int_to_bytes
1524from cryptography .x509 import load_pem_x509_certificate
1625
1726
@@ -37,7 +46,7 @@ def __init__(self, key, algorithm, cryptography_backend=default_backend):
3746 self .prepared_key = key
3847 return
3948
40- if isinstance (key , (ecdsa . SigningKey , ecdsa . VerifyingKey )):
49+ if None not in ( EcdsaSigningKey , EcdsaVerifyingKey ) and isinstance (key , (EcdsaSigningKey , EcdsaVerifyingKey )):
4150 # convert to PEM and let cryptography below load it as PEM
4251 key = key .to_pem ().decode ('utf-8' )
4352
@@ -90,19 +99,42 @@ def _process_jwk(self, jwk_dict):
9099 else :
91100 return public .public_key (self .cryptography_backend ())
92101
102+ def _sig_component_length (self ):
103+ """Determine the correct serialization length for an encoded signature component.
104+
105+ This is the number of bytes required to encode the maximum key value.
106+ """
107+ return int (math .ceil (self .prepared_key .key_size / 8.0 ))
108+
109+ def _der_to_raw (self , der_signature ):
110+ """Convert signature from DER encoding to RAW encoding."""
111+ r , s = decode_dss_signature (der_signature )
112+ component_length = self ._sig_component_length ()
113+ return int_to_bytes (r , component_length ) + int_to_bytes (s , component_length )
114+
115+ def _raw_to_der (self , raw_signature ):
116+ """Convert signature from RAW encoding to DER encoding."""
117+ component_length = self ._sig_component_length ()
118+ if len (raw_signature ) != int (2 * component_length ):
119+ raise ValueError ("Invalid signature" )
120+
121+ r_bytes = raw_signature [:component_length ]
122+ s_bytes = raw_signature [component_length :]
123+ r = int_from_bytes (r_bytes , "big" )
124+ s = int_from_bytes (s_bytes , "big" )
125+ return encode_dss_signature (r , s )
126+
93127 def sign (self , msg ):
94128 if self .hash_alg .digest_size * 8 > self .prepared_key .curve .key_size :
95129 raise TypeError ("this curve (%s) is too short "
96130 "for your digest (%d)" % (self .prepared_key .curve .name ,
97131 8 * self .hash_alg .digest_size ))
98132 signature = self .prepared_key .sign (msg , ec .ECDSA (self .hash_alg ()))
99- order = (2 ** self .prepared_key .curve .key_size ) - 1
100- return sigencode_string (* sigdecode_der (signature , order ), order = order )
133+ return self ._der_to_raw (signature )
101134
102135 def verify (self , msg , sig ):
103- order = (2 ** self .prepared_key .curve .key_size ) - 1
104- signature = sigencode_der (* sigdecode_string (sig , order ), order = order )
105136 try :
137+ signature = self ._raw_to_der (sig )
106138 self .prepared_key .verify (signature , msg , ec .ECDSA (self .hash_alg ()))
107139 return True
108140 except Exception :
0 commit comments