1
+ """A basic class on which to build the JWS and JWE classes."""
1
2
import json
2
3
import logging
3
4
4
5
import requests
5
6
6
7
from cryptojwt .jwk import JWK
7
8
from cryptojwt .key_bundle import KeyBundle
8
-
9
+ from . exception import HeaderError
9
10
from .jwk .jwk import key_from_jwk_dict
11
+ from .jwk .rsa import RSAKey
10
12
from .jwk .rsa import import_rsa_key
11
13
from .jwk .rsa import load_x509_cert
12
- from .jwk . rsa import RSAKey
13
- from .exception import HeaderError
14
- from .utils import b64d , as_bytes , as_unicode
14
+ from .utils import as_bytes
15
+ from .utils import as_unicode
16
+ from .utils import b64d
15
17
16
- logger = logging .getLogger (__name__ )
18
+ LOGGER = logging .getLogger (__name__ )
17
19
18
20
__author__ = 'Roland Hedberg'
19
21
20
22
21
- class JWx (object ):
22
- args = ["alg" , "jku" , "jwk" , "x5u" , "x5t" , "x5c" , "kid" , "typ" , "cty" ,
23
- "crit" ]
24
- """
23
+ class JWx :
24
+ """A basic class with the commonalities between the JWS and JWE classes.
25
+
25
26
:param alg: The signing algorithm
26
27
:param jku: a URI that refers to a resource for a set of JSON-encoded
27
28
public keys, one of which corresponds to the key used to digitally
@@ -45,6 +46,8 @@ class JWx(object):
45
46
:param kwargs: Extra header parameters
46
47
:return: A class instance
47
48
"""
49
+ args = ["alg" , "jku" , "jwk" , "x5u" , "x5t" , "x5c" , "kid" , "typ" , "cty" ,
50
+ "crit" ]
48
51
49
52
def __init__ (self , msg = None , with_digest = False , httpc = None , ** kwargs ):
50
53
self .msg = msg
@@ -69,21 +72,7 @@ def __init__(self, msg=None, with_digest=False, httpc=None, **kwargs):
69
72
continue
70
73
71
74
if key == "jwk" :
72
- # value MUST be a string
73
- if isinstance (_val , dict ):
74
- _k = key_from_jwk_dict (_val )
75
- self ._dict ["jwk" ] = _val
76
- elif isinstance (_val , str ):
77
- # verify that it's a real JWK
78
- _val = json .loads (_val )
79
- _j = key_from_jwk_dict (_val )
80
- self ._dict ["jwk" ] = _val
81
- elif isinstance (_val , JWK ):
82
- self ._dict ['jwk' ] = _val .to_dict ()
83
- else :
84
- raise ValueError (
85
- 'JWK must be a string a JSON object or a JWK '
86
- 'instance' )
75
+ self ._set_jwk (_val )
87
76
self ._jwk = self ._dict ['jwk' ]
88
77
elif key == "x5c" :
89
78
self ._dict ["x5c" ] = _val
@@ -102,6 +91,20 @@ def __init__(self, msg=None, with_digest=False, httpc=None, **kwargs):
102
91
else :
103
92
self ._dict [key ] = _val
104
93
94
+ def _set_jwk (self , val ):
95
+ if isinstance (val , dict ):
96
+ _k = key_from_jwk_dict (val )
97
+ self ._dict ["jwk" ] = val
98
+ elif isinstance (val , str ):
99
+ # verify that it's a real JWK
100
+ _val = json .loads (val )
101
+ _j = key_from_jwk_dict (_val )
102
+ self ._dict ["jwk" ] = _val
103
+ elif isinstance (val , JWK ):
104
+ self ._dict ['jwk' ] = val .to_dict ()
105
+ else :
106
+ raise ValueError ('JWK must be a string a JSON object or a JWK instance' )
107
+
105
108
def __contains__ (self , item ):
106
109
return item in self ._dict
107
110
@@ -118,9 +121,31 @@ def __getattr__(self, item):
118
121
raise AttributeError (item )
119
122
120
123
def keys (self ):
124
+ """Return all keys."""
121
125
return list (self ._dict .keys ())
122
126
127
+ def _set_header_jwk (self , header , ** kwargs ):
128
+ if "jwk" in self :
129
+ header ["jwk" ] = self ["jwk" ]
130
+ else :
131
+ try :
132
+ _jwk = kwargs ['jwk' ]
133
+ except KeyError :
134
+ pass
135
+ else :
136
+ try :
137
+ header ["jwk" ] = _jwk .serialize () # JWK instance
138
+ except AttributeError :
139
+ if isinstance (_jwk , dict ):
140
+ header ['jwk' ] = _jwk # dictionary
141
+ else :
142
+ _d = json .loads (_jwk ) # JSON
143
+ # Verify that it's a valid JWK
144
+ _k = key_from_jwk_dict (_d )
145
+ header ['jwk' ] = _d
146
+
123
147
def headers (self , ** kwargs ):
148
+ """Return the JWE/JWS header."""
124
149
_header = self ._header .copy ()
125
150
for param in self .args :
126
151
try :
@@ -132,28 +157,7 @@ def headers(self, **kwargs):
132
157
except KeyError :
133
158
pass
134
159
135
- if "jwk" in self :
136
- _header ["jwk" ] = self ["jwk" ]
137
- else :
138
- try :
139
- _jwk = kwargs ['jwk' ]
140
- except KeyError :
141
- pass
142
- else :
143
- try :
144
- _header ["jwk" ] = _jwk .serialize () # JWK instance
145
- except AttributeError :
146
- if isinstance (_jwk , dict ):
147
- _header ['jwk' ] = _jwk # dictionary
148
- else :
149
- try :
150
- _d = json .loads (_jwk ) # JSON
151
- # Verify that it's a valid JWK
152
- _k = key_from_jwk_dict (_d )
153
- except Exception :
154
- raise
155
- else :
156
- _header ['jwk' ] = _d
160
+ self ._set_header_jwk (_header , ** kwargs )
157
161
158
162
if "kid" in self :
159
163
if not isinstance (self ["kid" ], str ):
@@ -170,7 +174,8 @@ def _get_keys(self):
170
174
return _keys
171
175
172
176
def alg2keytype (self , alg ):
173
- raise NotImplemented ()
177
+ """Convert an algorithm identifier to a key type identifier."""
178
+ raise NotImplementedError ()
174
179
175
180
def pick_keys (self , keys , use = "" , alg = "" ):
176
181
"""
@@ -190,10 +195,10 @@ def pick_keys(self, keys, use="", alg=""):
190
195
191
196
_k = self .alg2keytype (alg )
192
197
if _k is None :
193
- logger .error ("Unknown algorithm '%s'" % alg )
198
+ LOGGER .error ("Unknown algorithm '%s'" , alg )
194
199
raise ValueError ('Unknown cryptography algorithm' )
195
200
196
- logger .debug ("Picking key by key type={0}" . format ( _k ) )
201
+ LOGGER .debug ("Picking key by key type=%s" , _k )
197
202
_kty = [_k .lower (), _k .upper (), _k .lower ().encode ("utf-8" ),
198
203
_k .upper ().encode ("utf-8" )]
199
204
_keys = [k for k in keys if k .kty in _kty ]
@@ -205,14 +210,12 @@ def pick_keys(self, keys, use="", alg=""):
205
210
except (AttributeError , KeyError ):
206
211
_kid = None
207
212
208
- logger .debug ("Picking key based on alg={0}, kid={1} and use={2}" .format (
209
- alg , _kid , use ))
213
+ LOGGER .debug ("Picking key based on alg=%s, kid=%s and use=%s" , alg , _kid , use )
210
214
211
215
pkey = []
212
216
for _key in _keys :
213
- logger .debug (
214
- "Picked: kid:{}, use:{}, kty:{}" .format (
215
- _key .kid , _key .use , _key .kty ))
217
+ LOGGER .debug (
218
+ "Picked: kid:%s, use:%s, kty:%s" , _key .kid , _key .use , _key .kty )
216
219
if _kid :
217
220
if _kid != _key .kid :
218
221
continue
@@ -251,4 +254,5 @@ def _decode(self, payload):
251
254
return _msg
252
255
253
256
def dump_header (self ):
254
- return dict ([(x , self ._dict [x ]) for x in self .args if x in self ._dict ])
257
+ """Return all attributes with values."""
258
+ return {x : self ._dict [x ] for x in self .args if x in self ._dict }
0 commit comments