4
4
import logging
5
5
import math
6
6
7
- from typing import Dict , Optional , Sequence , Type , Union
7
+ from typing import Dict , Optional , Sequence , Tuple , Type , Union
8
8
9
9
import cryptography .exceptions
10
10
from cryptography .hazmat .backends import default_backend
18
18
)
19
19
20
20
from josepy import errors , json_util , util
21
- from josepy .util import ComparableOKPKey
22
21
23
22
logger = logging .getLogger (__name__ )
24
23
@@ -341,9 +340,7 @@ def fields_to_partial_json(self):
341
340
params ['d' ] = private .private_value
342
341
else :
343
342
raise errors .SerializationError (
344
- 'Supplied key is neither of type EllipticCurvePublicKey '
345
- 'nor EllipticCurvePrivateKey'
346
- )
343
+ 'Supplied key is neither of type EllipticCurvePublicKey nor EllipticCurvePrivateKey' )
347
344
params ['x' ] = public .x
348
345
params ['y' ] = public .y
349
346
params = {
@@ -388,7 +385,7 @@ class JWKOKP(JWK):
388
385
or :class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`
389
386
or :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`
390
387
or :class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`
391
- or :ivar: :key : class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey`
388
+ or :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey`
392
389
or :class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey`
393
390
or :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey`
394
391
or :class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey`
@@ -405,6 +402,12 @@ class JWKOKP(JWK):
405
402
x448 .X448PrivateKey , x448 .X448PublicKey ,
406
403
)
407
404
required = ('crv' , JWK .type_field_name , 'x' )
405
+ crv_to_pub_priv : Dict [str , Tuple ] = {
406
+ "Ed25519" : (ed25519 .Ed25519PublicKey , ed25519 .Ed25519PrivateKey ),
407
+ "Ed448" : (ed448 .Ed448PublicKey , ed448 .Ed448PrivateKey ),
408
+ "X25519" : (x25519 .X25519PublicKey , x25519 .X25519PrivateKey ),
409
+ "X448" : (x448 .X448PublicKey , x448 .X448PrivateKey ),
410
+ }
408
411
409
412
def __init__ (self , * args , ** kwargs ):
410
413
if 'key' in kwargs and not isinstance (kwargs ['key' ], util .ComparableOKPKey ):
@@ -415,41 +418,38 @@ def public_key(self):
415
418
return self .key ._wrapped .__class__ .public_key ()
416
419
417
420
def _key_to_crv (self ):
418
- if isinstance (self .key ._wrapped , (ed25519 .Ed25519PrivateKey , ed25519 .Ed25519PrivateKey )):
421
+ if isinstance (self .key ._wrapped , (ed25519 .Ed25519PublicKey , ed25519 .Ed25519PrivateKey )):
419
422
return "Ed25519"
420
- elif isinstance (self .key ._wrapped , (ed448 .Ed448PrivateKey , ed448 .Ed448PrivateKey )):
423
+ elif isinstance (self .key ._wrapped , (ed448 .Ed448PublicKey , ed448 .Ed448PrivateKey )):
421
424
return "Ed448"
422
- elif isinstance (self .key ._wrapped , (x25519 .X25519PrivateKey , x25519 .X25519PrivateKey )):
425
+ elif isinstance (self .key ._wrapped , (x25519 .X25519PublicKey , x25519 .X25519PrivateKey )):
423
426
return "X25519"
424
- elif isinstance (self .key ._wrapped , (x448 .X448PrivateKey , x448 .X448PrivateKey )):
427
+ elif isinstance (self .key ._wrapped , (x448 .X448PublicKey , x448 .X448PrivateKey )):
425
428
return "X448"
426
429
return NotImplemented
427
430
428
431
def fields_to_partial_json (self ) -> Dict :
429
432
params = {}
430
- print (dir (self ))
431
433
if self .key .is_private ():
432
434
params ['d' ] = json_util .encode_b64jose (self .key .private_bytes (
433
- encoding = serialization .Encoding .PEM ,
434
- format = serialization .PrivateFormat .PKCS8 ,
435
+ encoding = serialization .Encoding .Raw ,
436
+ format = serialization .PrivateFormat .Raw ,
435
437
encryption_algorithm = serialization .NoEncryption ()
436
438
))
437
439
params ['x' ] = self .key .public_key ().public_bytes (
438
- encoding = serialization .Encoding .PEM ,
439
- format = serialization .PublicFormat .SubjectPublicKeyInfo ,
440
+ encoding = serialization .Encoding .Raw ,
441
+ format = serialization .PublicFormat .Raw ,
440
442
)
441
443
else :
442
444
params ['x' ] = json_util .encode_b64jose (self .key .public_bytes (
443
445
serialization .Encoding .Raw ,
444
446
serialization .PublicFormat .Raw ,
445
- serialization .NoEncryption (),
446
447
))
447
448
params ['crv' ] = self ._key_to_crv ()
448
449
return params
449
450
450
451
@classmethod
451
- def fields_from_json (cls , jobj ) -> ComparableOKPKey :
452
- # this was mostly copy/pasted from some source. Find out which.
452
+ def fields_from_json (cls , jobj ):
453
453
try :
454
454
if isinstance (jobj , str ):
455
455
obj = json .loads (jobj )
@@ -464,17 +464,30 @@ def fields_from_json(cls, jobj) -> ComparableOKPKey:
464
464
raise errors .DeserializationError ("Not an Octet Key Pair" )
465
465
466
466
curve = obj .get ("crv" )
467
- if curve not in ( "Ed25519" , "Ed448" , "X25519" , "X448" ) :
467
+ if curve not in cls . crv_to_pub_priv :
468
468
raise errors .DeserializationError (f"Invalid curve: { curve } " )
469
469
470
470
if "x" not in obj :
471
471
raise errors .DeserializationError ('OKP should have "x" parameter' )
472
472
x = json_util .decode_b64jose (jobj .get ("x" ))
473
473
474
474
try :
475
- if "d" not in obj :
476
- return jobj ["key" ]._wrapped .__class__ .from_public_bytes (x ) # noqa
477
- d = json_util .decode_b64jose (obj .get ("d" ))
478
- return jobj ["key" ]._wrapped .__class__ .from_private_bytes (d ) # noqa
475
+ if "d" not in obj : # public key
476
+ pub_class : Union [
477
+ ed25519 .Ed25519PublicKey ,
478
+ ed448 .Ed448PublicKey ,
479
+ x25519 .X25519PublicKey ,
480
+ x448 .X448PublicKey ,
481
+ ] = cls .crv_to_pub_priv [curve ][0 ]
482
+ return cls (key = pub_class .from_public_bytes (x ))
483
+ else : # private key
484
+ d = json_util .decode_b64jose (obj .get ("d" ))
485
+ priv_key_class : Union [
486
+ ed25519 .Ed25519PrivateKey ,
487
+ ed448 .Ed448PrivateKey ,
488
+ x25519 .X25519PrivateKey ,
489
+ x448 .X448PrivateKey ,
490
+ ] = cls .crv_to_pub_priv [curve ][1 ]
491
+ return cls (key = priv_key_class .from_private_bytes (d ))
479
492
except ValueError as err :
480
493
raise errors .DeserializationError ("Invalid key parameter" ) from err
0 commit comments