Skip to content

Commit

Permalink
Key.to_dict() now always returns JSON encodeable keys and values.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gasper Zejn committed Apr 14, 2019
1 parent 1c3c1a6 commit f8e2c92
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 32 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Bugfixes

* Fix invalid RSA private key PKCS8 encoding by python-rsa backend.
`#120 <https://github.com/mpdavis/python-jose/pull/120>`_
* Fix to_dict output, which should always be JSON encodeable.
`#139 <https://github.com/mpdavis/python-jose/pull/139>`_

Housekeeping
""""""""""""
Expand Down
22 changes: 11 additions & 11 deletions jose/backends/cryptography_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,15 @@ def to_dict(self):
'alg': self._algorithm,
'kty': 'EC',
'crv': crv,
'x': long_to_base64(public_key.public_numbers().x, size=key_size),
'y': long_to_base64(public_key.public_numbers().y, size=key_size),
'x': long_to_base64(public_key.public_numbers().x, size=key_size).decode('ASCII'),
'y': long_to_base64(public_key.public_numbers().y, size=key_size).decode('ASCII'),
}

if not self.is_public():
data['d'] = long_to_base64(
self.prepared_key.private_numbers().private_value,
size=key_size
)
).decode('ASCII')

return data

Expand Down Expand Up @@ -354,18 +354,18 @@ def to_dict(self):
data = {
'alg': self._algorithm,
'kty': 'RSA',
'n': long_to_base64(public_key.public_numbers().n),
'e': long_to_base64(public_key.public_numbers().e),
'n': long_to_base64(public_key.public_numbers().n).decode('ASCII'),
'e': long_to_base64(public_key.public_numbers().e).decode('ASCII'),
}

if not self.is_public():
data.update({
'd': long_to_base64(self.prepared_key.private_numbers().d),
'p': long_to_base64(self.prepared_key.private_numbers().p),
'q': long_to_base64(self.prepared_key.private_numbers().q),
'dp': long_to_base64(self.prepared_key.private_numbers().dmp1),
'dq': long_to_base64(self.prepared_key.private_numbers().dmq1),
'qi': long_to_base64(self.prepared_key.private_numbers().iqmp),
'd': long_to_base64(self.prepared_key.private_numbers().d).decode('ASCII'),
'p': long_to_base64(self.prepared_key.private_numbers().p).decode('ASCII'),
'q': long_to_base64(self.prepared_key.private_numbers().q).decode('ASCII'),
'dp': long_to_base64(self.prepared_key.private_numbers().dmp1).decode('ASCII'),
'dq': long_to_base64(self.prepared_key.private_numbers().dmq1).decode('ASCII'),
'qi': long_to_base64(self.prepared_key.private_numbers().iqmp).decode('ASCII'),
})

return data
6 changes: 3 additions & 3 deletions jose/backends/ecdsa_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ def to_dict(self):
'alg': self._algorithm,
'kty': 'EC',
'crv': crv,
'x': long_to_base64(public_key.pubkey.point.x(), size=key_size),
'y': long_to_base64(public_key.pubkey.point.y(), size=key_size),
'x': long_to_base64(public_key.pubkey.point.x(), size=key_size).decode('ASCII'),
'y': long_to_base64(public_key.pubkey.point.y(), size=key_size).decode('ASCII'),
}

if not self.is_public():
data['d'] = long_to_base64(
self.prepared_key.privkey.secret_multiplier,
size=key_size
)
).decode('ASCII')

return data
16 changes: 8 additions & 8 deletions jose/backends/pycrypto_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ def to_dict(self):
data = {
'alg': self._algorithm,
'kty': 'RSA',
'n': long_to_base64(self.prepared_key.n),
'e': long_to_base64(self.prepared_key.e),
'n': long_to_base64(self.prepared_key.n).decode('ASCII'),
'e': long_to_base64(self.prepared_key.e).decode('ASCII'),
}

if not self.is_public():
Expand All @@ -201,12 +201,12 @@ def to_dict(self):
dp = self.prepared_key.d % (self.prepared_key.p - 1)
dq = self.prepared_key.d % (self.prepared_key.q - 1)
data.update({
'd': long_to_base64(self.prepared_key.d),
'p': long_to_base64(self.prepared_key.q),
'q': long_to_base64(self.prepared_key.p),
'dp': long_to_base64(dq),
'dq': long_to_base64(dp),
'qi': long_to_base64(self.prepared_key.u),
'd': long_to_base64(self.prepared_key.d).decode('ASCII'),
'p': long_to_base64(self.prepared_key.q).decode('ASCII'),
'q': long_to_base64(self.prepared_key.p).decode('ASCII'),
'dp': long_to_base64(dq).decode('ASCII'),
'dq': long_to_base64(dp).decode('ASCII'),
'qi': long_to_base64(self.prepared_key.u).decode('ASCII'),
})

return data
16 changes: 8 additions & 8 deletions jose/backends/rsa_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,18 @@ def to_dict(self):
data = {
'alg': self._algorithm,
'kty': 'RSA',
'n': long_to_base64(public_key.n),
'e': long_to_base64(public_key.e),
'n': long_to_base64(public_key.n).decode('ASCII'),
'e': long_to_base64(public_key.e).decode('ASCII'),
}

if not self.is_public():
data.update({
'd': long_to_base64(self._prepared_key.d),
'p': long_to_base64(self._prepared_key.p),
'q': long_to_base64(self._prepared_key.q),
'dp': long_to_base64(self._prepared_key.exp1),
'dq': long_to_base64(self._prepared_key.exp2),
'qi': long_to_base64(self._prepared_key.coef),
'd': long_to_base64(self._prepared_key.d).decode('ASCII'),
'p': long_to_base64(self._prepared_key.p).decode('ASCII'),
'q': long_to_base64(self._prepared_key.q).decode('ASCII'),
'dp': long_to_base64(self._prepared_key.exp1).decode('ASCII'),
'dq': long_to_base64(self._prepared_key.exp2).decode('ASCII'),
'qi': long_to_base64(self._prepared_key.coef).decode('ASCII'),
})

return data
2 changes: 1 addition & 1 deletion jose/jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,5 @@ def to_dict(self):
return {
'alg': self._algorithm,
'kty': 'oct',
'k': base64url_encode(self.prepared_key),
'k': base64url_encode(self.prepared_key).decode('ascii'),
}
4 changes: 4 additions & 0 deletions tests/algorithms/test_EC.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ def assert_parameters(self, as_dict, private):
# Private parameters should be absent
assert 'd' not in as_dict

# as_dict should be serializable to JSON
import json
json.dumps(as_dict)

def test_to_dict(self):
key = ECKey(private_key, ALGORITHMS.ES256)
self.assert_parameters(key.to_dict(), private=True)
Expand Down
6 changes: 5 additions & 1 deletion tests/algorithms/test_HMAC.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_RSA_key(self):

def test_to_dict(self):
passphrase = 'The quick brown fox jumps over the lazy dog'
encoded = b'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw'
encoded = 'VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw'
key = HMACKey(passphrase, ALGORITHMS.HS256)

as_dict = key.to_dict()
Expand All @@ -43,3 +43,7 @@ def test_to_dict(self):

assert 'k' in as_dict
assert as_dict['k'] == encoded

# as_dict should be serializable to JSON
import json
json.dumps(as_dict)
4 changes: 4 additions & 0 deletions tests/algorithms/test_RSA.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ def assert_parameters(self, as_dict, private):
assert 'dq' not in as_dict
assert 'qi' not in as_dict

# as_dict should be serializable to JSON
import json
json.dumps(as_dict)

def assert_roundtrip(self, key):
assert RSAKey(
key.to_dict(),
Expand Down

0 comments on commit f8e2c92

Please sign in to comment.