14
14
from .exception import UnknownKeyType
15
15
from .exception import UpdateFailed
16
16
from .jwk .ec import ECKey
17
+ from .jwk .ec import import_private_key_from_file
17
18
from .jwk .ec import new_ec_key
18
19
from .jwk .hmac import SYMKey
19
20
from .jwk .jwk import dump_jwk
@@ -134,14 +135,15 @@ def ec_init(spec):
134
135
135
136
:return: A KeyBundle instance
136
137
"""
138
+ curve = spec .get ("crv" , "P-256" )
137
139
138
140
_kb = KeyBundle (keytype = "EC" )
139
141
if 'use' in spec :
140
142
for use in spec ["use" ]:
141
- eck = new_ec_key (crv = spec [ 'crv' ] , use = use )
143
+ eck = new_ec_key (crv = curve , use = use )
142
144
_kb .append (eck )
143
145
else :
144
- eck = new_ec_key (crv = spec [ 'crv' ] )
146
+ eck = new_ec_key (crv = curve )
145
147
_kb .append (eck )
146
148
147
149
return _kb
@@ -167,7 +169,7 @@ def __init__(self, keys=None, source="", cache_time=300, verify_ssl=True,
167
169
:param verify_ssl: Verify the SSL cert used by the server
168
170
:param fileformat: For a local file either "jwks" or "der"
169
171
:param keytype: Iff local file and 'der' format what kind of key it is.
170
- presently only 'rsa' is supported.
172
+ presently 'rsa' and 'ec' are supported.
171
173
:param keyusage: What the key loaded from file should be used for.
172
174
Only applicable for DER files
173
175
:param httpc: A HTTP client function
@@ -229,7 +231,7 @@ def _set_source(self, source, fileformat):
229
231
def _do_local (self , kid ):
230
232
if self .fileformat in ['jwks' , "jwk" ]:
231
233
self .do_local_jwk (self .source )
232
- elif self .fileformat == "der" : # Only valid for RSA keys
234
+ elif self .fileformat == "der" :
233
235
self .do_local_der (self .source , self .keytype , self .keyusage , kid )
234
236
235
237
def do_keys (self , keys ):
@@ -285,12 +287,16 @@ def do_local_der(self, filename, keytype, keyusage=None, kid=''):
285
287
Load a DER encoded file amd create a key from it.
286
288
287
289
:param filename: Name of the file
288
- :param keytype: Presently only 'rsa' supported
290
+ :param keytype: Presently 'rsa' and 'ec ' supported
289
291
:param keyusage: encryption ('enc') or signing ('sig') or both
290
292
"""
291
- _bkey = import_private_rsa_key_from_file (filename )
292
-
293
- if keytype .lower () != 'rsa' :
293
+ if keytype .lower () == 'rsa' :
294
+ _bkey = import_private_rsa_key_from_file (filename )
295
+ _key = RSAKey ().load_key (_bkey )
296
+ elif keytype .lower () == 'ec' :
297
+ _bkey = import_private_key_from_file (filename )
298
+ _key = ECKey ().load_key (_bkey )
299
+ else :
294
300
raise NotImplementedError ('No support for DER decoding of that key type' )
295
301
296
302
if not keyusage :
@@ -299,7 +305,6 @@ def do_local_der(self, filename, keytype, keyusage=None, kid=''):
299
305
keyusage = harmonize_usage (keyusage )
300
306
301
307
for use in keyusage :
302
- _key = RSAKey ().load_key (_bkey )
303
308
_key .use = use
304
309
if kid :
305
310
_key .kid = kid
@@ -632,21 +637,25 @@ def difference(self, bundle):
632
637
return [k for k in self ._keys if k not in bundle ]
633
638
634
639
635
- def keybundle_from_local_file (filename , typ , usage ):
640
+ def keybundle_from_local_file (filename , typ , usage , keytype = "RSA" ):
636
641
"""
637
642
Create a KeyBundle based on the content in a local file.
638
643
639
644
:param filename: Name of the file
640
645
:param typ: Type of content
641
646
:param usage: What the key should be used for
647
+ :param keytype: Type of key, e.g. "RSA", "EC". Only used with typ='der'
642
648
:return: The created KeyBundle
643
649
"""
644
650
usage = harmonize_usage (usage )
645
651
646
652
if typ .lower () == "jwks" :
647
653
_bundle = KeyBundle (source = filename , fileformat = "jwks" , keyusage = usage )
648
- elif typ .lower () == 'der' :
649
- _bundle = KeyBundle (source = filename , fileformat = "der" , keyusage = usage )
654
+ elif typ .lower () == "der" :
655
+ _bundle = KeyBundle (source = filename ,
656
+ fileformat = "der" ,
657
+ keyusage = usage ,
658
+ keytype = keytype )
650
659
else :
651
660
raise UnknownKeyType ("Unsupported key type" )
652
661
@@ -713,8 +722,8 @@ def build_key_bundle(key_conf, kid_template=""):
713
722
The type of key. Presently only 'rsa', 'ec' and 'oct' supported.
714
723
715
724
key
716
- A name of a file where a key can be found. Only works with PEM encoded
717
- RSA keys
725
+ A name of a file where a key can be found. Works with PEM encoded
726
+ RSA and EC private keys.
718
727
719
728
use
720
729
What the key should be used for
@@ -752,7 +761,17 @@ def build_key_bundle(key_conf, kid_template=""):
752
761
else :
753
762
_bundle = rsa_init (spec )
754
763
elif typ == "EC" :
755
- _bundle = ec_init (spec )
764
+ if "key" in spec and spec ["key" ]:
765
+ error_to_catch = (OSError , IOError ,
766
+ DeSerializationNotPossible )
767
+ try :
768
+ _bundle = KeyBundle (source = "file://%s" % spec ["key" ],
769
+ fileformat = "der" ,
770
+ keytype = typ , keyusage = spec ["use" ])
771
+ except error_to_catch :
772
+ _bundle = ec_init (spec )
773
+ else :
774
+ _bundle = ec_init (spec )
756
775
elif typ .upper () == "OCT" :
757
776
_bundle = sym_init (spec )
758
777
else :
0 commit comments