22from jose .constants import ALGORITHMS
33from jose .exceptions import JOSEError , JWKError
44
5- from jose .backends .ecdsa_backend import ECDSAECKey
6- from jose .backends .cryptography_backend import CryptographyECKey
5+ from jose .backends import ECKey
6+ try :
7+ from jose .backends .ecdsa_backend import ECDSAECKey
8+ import ecdsa
9+ except ImportError :
10+ ECDSAECKey = ecdsa = None
11+
12+ try :
13+ from jose .backends .cryptography_backend import CryptographyECKey
14+ except ImportError :
15+ CryptographyECKey = None
716
8- import ecdsa
917import pytest
1018
1119private_key = """-----BEGIN EC PRIVATE KEY-----
1422WkG0HJWIORlPbvXME+DRh6G/yVOKnTm88Q==
1523-----END EC PRIVATE KEY-----"""
1624
25+ # Private key generated using NIST256p curve
26+ TOO_SHORT_PRIVATE_KEY = b"""\
27+ -----BEGIN EC PRIVATE KEY-----
28+ MHcCAQEEIMlUyYGOpjV4bbW0C9FKS2zkspD0L/5vJLnr6sJoLdc+oAoGCCqGSM49
29+ AwEHoUQDQgAE6TDUNj5QXl+RKdZvBV+cg7Td6cJRB+Ta8XAhIuCAzonq0Ix//1+C
30+ pNSsy11sIKmMl61YJzxvZ6WkNluBmkDPCQ==
31+ -----END EC PRIVATE KEY-----
32+ """
33+
34+
35+ def _backend_exception_types ():
36+ """Build the backend exception types based on available backends."""
37+ if None not in (ECDSAECKey , ecdsa ):
38+ yield ECDSAECKey , ecdsa .BadDigestError
39+
40+ if CryptographyECKey is not None :
41+ yield CryptographyECKey , TypeError
1742
18- class TestECAlgorithm :
1943
20- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
21- def test_key_from_pem (self , Backend ):
22- assert not Backend (private_key , ALGORITHMS .ES256 ).is_public ()
44+ @pytest .mark .ecdsa
45+ @pytest .mark .skipif (
46+ None in (ECDSAECKey , ecdsa ),
47+ reason = "python-ecdsa backend not available"
48+ )
49+ def test_key_from_ecdsa ():
50+ key = ecdsa .SigningKey .from_pem (private_key )
51+ assert not ECKey (key , ALGORITHMS .ES256 ).is_public ()
52+
53+
54+ class TestECAlgorithm :
2355
24- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
25- def test_key_from_ecdsa (self , Backend ):
26- key = ecdsa .SigningKey .from_pem (private_key )
27- assert not Backend (key , ALGORITHMS .ES256 ).is_public ()
56+ def test_key_from_pem (self ):
57+ assert not ECKey (private_key , ALGORITHMS .ES256 ).is_public ()
2858
29- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
30- def test_to_pem (self , Backend ):
31- key = Backend (private_key , ALGORITHMS .ES256 )
59+ def test_to_pem (self ):
60+ key = ECKey (private_key , ALGORITHMS .ES256 )
3261 assert not key .is_public ()
3362 assert key .to_pem ().strip () == private_key .strip ().encode ('utf-8' )
3463
3564 public_pem = key .public_key ().to_pem ()
36- assert Backend (public_pem , ALGORITHMS .ES256 ).is_public ()
37-
38- @pytest .mark .parametrize (
39- "Backend,ExceptionType" ,
40- [
41- (ECDSAECKey , ecdsa .BadDigestError ),
42- (CryptographyECKey , TypeError )
43- ]
44- )
65+ assert ECKey (public_pem , ALGORITHMS .ES256 ).is_public ()
66+
67+ @pytest .mark .parametrize ("Backend,ExceptionType" , _backend_exception_types ())
4568 def test_key_too_short (self , Backend , ExceptionType ):
46- priv_key = ecdsa .SigningKey .generate (curve = ecdsa .NIST256p ).to_pem ()
47- key = Backend (priv_key , ALGORITHMS .ES512 )
69+ key = Backend (TOO_SHORT_PRIVATE_KEY , ALGORITHMS .ES512 )
4870 with pytest .raises (ExceptionType ):
4971 key .sign (b'foo' )
5072
51- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
52- def test_get_public_key (self , Backend ):
53- key = Backend (private_key , ALGORITHMS .ES256 )
73+ def test_get_public_key (self ):
74+ key = ECKey (private_key , ALGORITHMS .ES256 )
5475 pubkey = key .public_key ()
5576 pubkey2 = pubkey .public_key ()
5677 assert pubkey == pubkey2
5778
58- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
59- def test_string_secret (self , Backend ):
79+ def test_string_secret (self ):
6080 key = 'secret'
6181 with pytest .raises (JOSEError ):
62- Backend (key , ALGORITHMS .ES256 )
82+ ECKey (key , ALGORITHMS .ES256 )
6383
64- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
65- def test_object (self , Backend ):
84+ def test_object (self ):
6685 key = object ()
6786 with pytest .raises (JOSEError ):
68- Backend (key , ALGORITHMS .ES256 )
87+ ECKey (key , ALGORITHMS .ES256 )
6988
70- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
71- def test_invalid_algorithm (self , Backend ):
89+ def test_invalid_algorithm (self ):
7290 with pytest .raises (JWKError ):
73- Backend (private_key , 'nonexistent' )
91+ ECKey (private_key , 'nonexistent' )
7492
7593 with pytest .raises (JWKError ):
76- Backend ({'kty' : 'bla' }, ALGORITHMS .ES256 )
94+ ECKey ({'kty' : 'bla' }, ALGORITHMS .ES256 )
7795
78- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
79- def test_EC_jwk (self , Backend ):
96+ def test_EC_jwk (self ):
8097 key = {
8198 "kty" : "EC" ,
8299@@ -87,22 +104,21 @@ def test_EC_jwk(self, Backend):
87104 "d" : "AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt" ,
88105 }
89106
90- assert not Backend (key , ALGORITHMS .ES512 ).is_public ()
107+ assert not ECKey (key , ALGORITHMS .ES512 ).is_public ()
91108
92109 del key ['d' ]
93110
94111 # We are now dealing with a public key.
95- assert Backend (key , ALGORITHMS .ES512 ).is_public ()
112+ assert ECKey (key , ALGORITHMS .ES512 ).is_public ()
96113
97114 del key ['x' ]
98115
99116 # This key is missing a required parameter.
100117 with pytest .raises (JWKError ):
101- Backend (key , ALGORITHMS .ES512 )
118+ ECKey (key , ALGORITHMS .ES512 )
102119
103- @pytest .mark .parametrize ("Backend" , [ECDSAECKey ])
104- def test_verify (self , Backend ):
105- key = Backend (private_key , ALGORITHMS .ES256 )
120+ def test_verify (self ):
121+ key = ECKey (private_key , ALGORITHMS .ES256 )
106122 msg = b'test'
107123 signature = key .sign (msg )
108124 public_key = key .public_key ()
@@ -129,23 +145,7 @@ def assert_parameters(self, as_dict, private):
129145 # Private parameters should be absent
130146 assert 'd' not in as_dict
131147
132- @pytest .mark .parametrize ("Backend" , [ECDSAECKey , CryptographyECKey ])
133- def test_to_dict (self , Backend ):
134- key = Backend (private_key , ALGORITHMS .ES256 )
148+ def test_to_dict (self ):
149+ key = ECKey (private_key , ALGORITHMS .ES256 )
135150 self .assert_parameters (key .to_dict (), private = True )
136151 self .assert_parameters (key .public_key ().to_dict (), private = False )
137-
138- @pytest .mark .parametrize ("BackendSign" , [ECDSAECKey , CryptographyECKey ])
139- @pytest .mark .parametrize ("BackendVerify" , [ECDSAECKey , CryptographyECKey ])
140- def test_signing_parity (self , BackendSign , BackendVerify ):
141- key_sign = BackendSign (private_key , ALGORITHMS .ES256 )
142- key_verify = BackendVerify (private_key , ALGORITHMS .ES256 ).public_key ()
143-
144- msg = b'test'
145- sig = key_sign .sign (msg )
146-
147- # valid signature
148- assert key_verify .verify (msg , sig )
149-
150- # invalid signature
151- assert not key_verify .verify (msg , b'n' * 64 )
0 commit comments