1414from .exception import UnknownKeyType
1515from .exception import UpdateFailed
1616from .jwk .ec import ECKey
17+ from .jwk .ec import import_private_key_from_file
1718from .jwk .ec import new_ec_key
1819from .jwk .hmac import SYMKey
1920from .jwk .jwk import dump_jwk
@@ -134,14 +135,15 @@ def ec_init(spec):
134135
135136 :return: A KeyBundle instance
136137 """
138+ curve = spec .get ("crv" , "P-256" )
137139
138140 _kb = KeyBundle (keytype = "EC" )
139141 if 'use' in spec :
140142 for use in spec ["use" ]:
141- eck = new_ec_key (crv = spec [ 'crv' ] , use = use )
143+ eck = new_ec_key (crv = curve , use = use )
142144 _kb .append (eck )
143145 else :
144- eck = new_ec_key (crv = spec [ 'crv' ] )
146+ eck = new_ec_key (crv = curve )
145147 _kb .append (eck )
146148
147149 return _kb
@@ -167,7 +169,7 @@ def __init__(self, keys=None, source="", cache_time=300, verify_ssl=True,
167169 :param verify_ssl: Verify the SSL cert used by the server
168170 :param fileformat: For a local file either "jwks" or "der"
169171 :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.
171173 :param keyusage: What the key loaded from file should be used for.
172174 Only applicable for DER files
173175 :param httpc: A HTTP client function
@@ -229,7 +231,7 @@ def _set_source(self, source, fileformat):
229231 def _do_local (self , kid ):
230232 if self .fileformat in ['jwks' , "jwk" ]:
231233 self .do_local_jwk (self .source )
232- elif self .fileformat == "der" : # Only valid for RSA keys
234+ elif self .fileformat == "der" :
233235 self .do_local_der (self .source , self .keytype , self .keyusage , kid )
234236
235237 def do_keys (self , keys ):
@@ -285,12 +287,16 @@ def do_local_der(self, filename, keytype, keyusage=None, kid=''):
285287 Load a DER encoded file amd create a key from it.
286288
287289 :param filename: Name of the file
288- :param keytype: Presently only 'rsa' supported
290+ :param keytype: Presently 'rsa' and 'ec ' supported
289291 :param keyusage: encryption ('enc') or signing ('sig') or both
290292 """
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 :
294300 raise NotImplementedError ('No support for DER decoding of that key type' )
295301
296302 if not keyusage :
@@ -299,7 +305,6 @@ def do_local_der(self, filename, keytype, keyusage=None, kid=''):
299305 keyusage = harmonize_usage (keyusage )
300306
301307 for use in keyusage :
302- _key = RSAKey ().load_key (_bkey )
303308 _key .use = use
304309 if kid :
305310 _key .kid = kid
@@ -632,21 +637,25 @@ def difference(self, bundle):
632637 return [k for k in self ._keys if k not in bundle ]
633638
634639
635- def keybundle_from_local_file (filename , typ , usage ):
640+ def keybundle_from_local_file (filename , typ , usage , keytype = "RSA" ):
636641 """
637642 Create a KeyBundle based on the content in a local file.
638643
639644 :param filename: Name of the file
640645 :param typ: Type of content
641646 :param usage: What the key should be used for
647+ :param keytype: Type of key, e.g. "RSA", "EC". Only used with typ='der'
642648 :return: The created KeyBundle
643649 """
644650 usage = harmonize_usage (usage )
645651
646652 if typ .lower () == "jwks" :
647653 _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 )
650659 else :
651660 raise UnknownKeyType ("Unsupported key type" )
652661
@@ -713,8 +722,8 @@ def build_key_bundle(key_conf, kid_template=""):
713722 The type of key. Presently only 'rsa', 'ec' and 'oct' supported.
714723
715724 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.
718727
719728 use
720729 What the key should be used for
@@ -752,7 +761,17 @@ def build_key_bundle(key_conf, kid_template=""):
752761 else :
753762 _bundle = rsa_init (spec )
754763 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 )
756775 elif typ .upper () == "OCT" :
757776 _bundle = sym_init (spec )
758777 else :
0 commit comments