Skip to content

Commit 3dcddb5

Browse files
authored
Merge branch 'master' into update-pyasn
2 parents 574e3a3 + 1f0ae0a commit 3dcddb5

24 files changed

+268
-122
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.9"]
18+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9"]
1919
os: [ubuntu-latest, macos-latest, windows-latest]
2020
exclude:
2121
- os: macos-latest
22-
python-version: "pypy3.9"
22+
python-version: "pypy3.9"
2323
- os: windows-latest
2424
python-version: "pypy3.9"
2525
runs-on: ${{ matrix.os }}
2626
name: "${{ matrix.os }} Python: ${{ matrix.python-version }}"
2727
steps:
28-
- uses: actions/checkout@v3
28+
- uses: actions/checkout@v4
2929
with:
3030
fetch-depth: 0
3131
- name: Set up Python ${{ matrix.python-version }}
32-
uses: actions/setup-python@v4
32+
uses: actions/setup-python@v5
3333
with:
3434
python-version: ${{ matrix.python-version }}
3535
- name: Install dependencies
3636
run: |
37-
pip install -U "pip>=23.1.2"
38-
pip install -U "tox-gh-actions==3.1.0" coverage
37+
pip install -U "pip>=25.1.1"
38+
pip install -U "tox-gh-actions==3.3.0" coverage
3939
- name: Log python & pip versions
4040
run: |
4141
python --version
@@ -51,23 +51,23 @@ jobs:
5151
linting:
5252
runs-on: ubuntu-latest
5353
steps:
54-
- uses: actions/checkout@v3
55-
- uses: actions/setup-python@v4
54+
- uses: actions/checkout@v4
55+
- uses: actions/setup-python@v5
5656
with:
57-
python-version: 3.9
57+
python-version: "3.12"
5858
- name: Install dependencies
5959
run: |
6060
pip install -U setuptools
61-
pip install -U "tox>=4.5.1,<5"
61+
pip install -U "tox>=4.26.0,<5"
6262
- run: tox -e lint
6363
package:
6464
name: Build & verify package
6565
runs-on: "ubuntu-latest"
6666
steps:
67-
- uses: actions/checkout@v3
68-
- uses: actions/setup-python@v4
67+
- uses: actions/checkout@v4
68+
- uses: actions/setup-python@v5
6969
with:
70-
python-version: "3.9"
70+
python-version: "3.12"
7171
- name: Install build, check-wheel-content, and twine
7272
run: "python -m pip install build twine check-wheel-contents"
7373
- name: Build package

CHANGELOG.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# Changelog #
22

3-
## 3.4.0 -- UNPUBLISHED ##
3+
## 3.4.0 -- 2025-02-14 ##
44

55
### News ###
66

7-
* Remove support for python 3.6
7+
* Remove support for Python 3.6 and 3.7
8+
* Added support for Python 3.10 and 3.11
9+
10+
### Bug fixes and Improvements ###
11+
* Updating `CryptographyAESKey::encrypt` to generate 96 bit IVs for GCM block
12+
cipher mode
13+
* Fix for PEM key comparisons caused by line lengths and new lines
14+
* Fix for CVE-2024-33664 - JWE limited to 250KiB
15+
* Fix for CVE-2024-33663 - signing JWT with public key is now forbidden
16+
* Replace usage of deprecated datetime.utcnow() with datetime.now(UTC)
817

918
### Housekeeping ###
1019

1120
* Updated Github Actions Workflows
1221
* Updated to use tox 4.x
1322
* Revise codecov integration
14-
23+
* Fixed DeprecationWarnings
1524

1625
## 3.3.0 -- 2021-06-04 ##
1726

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ This library was originally based heavily on the work of the folks over at PyJWT
8787
.. |pypi| image:: https://img.shields.io/pypi/v/python-jose?style=flat-square
8888
:target: https://pypi.org/project/python-jose/
8989
:alt: PyPI
90-
.. |Github Actions CI Status| image:: https://github.com/mpdavis/python-jose/workflows/main/badge.svg?branch=master
91-
:target: https://github.com/mpdavis/python-jose/actions?workflow=main
90+
.. |Github Actions CI Status| image:: https://github.com/mpdavis/python-jose/actions/workflows/ci.yml/badge.svg
91+
:target: https://github.com/mpdavis/python-jose/actions/workflows/ci.yml
9292
:alt: Github Actions CI Status
9393
.. |Coverage Status| image:: http://codecov.io/github/mpdavis/python-jose/coverage.svg?branch=master
9494
:target: http://codecov.io/github/mpdavis/python-jose?branch=master

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
* Refactor Algorithm logic with set Exceptions to return
1515
* Add HTML documentation
1616
* Implement ECSDA signing
17-
* Refactor JWT claims verifcation
17+
* Refactor JWT claims verification
1818
* Add actual exceptions instead of using the base exception
1919
* Audit JWT claims tests and rectify against the spec

docs/jwk/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Verifying token signatures
2626
>>> key = jwk.construct(hmac_key)
2727
>>>
2828
>>> message, encoded_sig = token.rsplit('.', 1)
29-
>>> decoded_sig = base64url_decode(encoded_sig)
29+
>>> decoded_sig = base64url_decode(encoded_sig.encode())
3030
>>> key.verify(message, decoded_sig)
3131
3232

jose/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "3.3.0"
1+
__version__ = "3.4.0"
22
__author__ = "Michael Davis"
33
__license__ = "MIT"
44
__copyright__ = "Copyright 2016 Michael Davis"

jose/backends/__init__.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
try:
2-
from jose.backends.cryptography_backend import get_random_bytes # noqa: F401
3-
except ImportError:
4-
try:
5-
from jose.backends.pycrypto_backend import get_random_bytes # noqa: F401
6-
except ImportError:
7-
from jose.backends.native import get_random_bytes # noqa: F401
1+
from jose.backends.native import get_random_bytes # noqa: F401
82

93
try:
104
from jose.backends.cryptography_backend import CryptographyRSAKey as RSAKey # noqa: F401

jose/backends/_asn1.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
Required by rsa_backend but not cryptography_backend.
44
"""
5+
56
from pyasn1.codec.der import decoder, encoder
67
from pyasn1.type import namedtype, univ
78

jose/backends/cryptography_backend.py

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from cryptography.exceptions import InvalidSignature, InvalidTag
55
from cryptography.hazmat.backends import default_backend
6-
from cryptography.hazmat.bindings.openssl.binding import Binding
76
from cryptography.hazmat.primitives import hashes, hmac, serialization
87
from cryptography.hazmat.primitives.asymmetric import ec, padding, rsa
98
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature, encode_dss_signature
@@ -16,35 +15,21 @@
1615

1716
from ..constants import ALGORITHMS
1817
from ..exceptions import JWEError, JWKError
19-
from ..utils import base64_to_long, base64url_decode, base64url_encode, ensure_binary, long_to_base64
18+
from ..utils import (
19+
base64_to_long,
20+
base64url_decode,
21+
base64url_encode,
22+
ensure_binary,
23+
is_pem_format,
24+
is_ssh_key,
25+
long_to_base64,
26+
)
27+
from . import get_random_bytes
2028
from .base import Key
2129

2230
_binding = None
2331

2432

25-
def get_random_bytes(num_bytes):
26-
"""
27-
Get random bytes
28-
29-
Currently, Cryptography returns OS random bytes. If you want OpenSSL
30-
generated random bytes, you'll have to switch the RAND engine after
31-
initializing the OpenSSL backend
32-
Args:
33-
num_bytes (int): Number of random bytes to generate and return
34-
Returns:
35-
bytes: Random bytes
36-
"""
37-
global _binding
38-
39-
if _binding is None:
40-
_binding = Binding()
41-
42-
buf = _binding.ffi.new("char[]", num_bytes)
43-
_binding.lib.RAND_bytes(buf, num_bytes)
44-
rand_bytes = _binding.ffi.buffer(buf, num_bytes)[:]
45-
return rand_bytes
46-
47-
4833
class CryptographyECKey(Key):
4934
SHA256 = hashes.SHA256
5035
SHA384 = hashes.SHA384
@@ -439,6 +424,8 @@ class CryptographyAESKey(Key):
439424
ALGORITHMS.A256KW: None,
440425
}
441426

427+
IV_BYTE_LENGTH_MODE_MAP = {"CBC": algorithms.AES.block_size // 8, "GCM": 96 // 8}
428+
442429
def __init__(self, key, algorithm):
443430
if algorithm not in ALGORITHMS.AES:
444431
raise JWKError("%s is not a valid AES algorithm" % algorithm)
@@ -468,7 +455,8 @@ def to_dict(self):
468455
def encrypt(self, plain_text, aad=None):
469456
plain_text = ensure_binary(plain_text)
470457
try:
471-
iv = get_random_bytes(algorithms.AES.block_size // 8)
458+
iv_byte_length = self.IV_BYTE_LENGTH_MODE_MAP.get(self._mode.name, algorithms.AES.block_size)
459+
iv = get_random_bytes(iv_byte_length)
472460
mode = self._mode(iv)
473461
if mode.name == "GCM":
474462
cipher = aead.AESGCM(self._key)
@@ -552,14 +540,7 @@ def __init__(self, key, algorithm):
552540
if isinstance(key, str):
553541
key = key.encode("utf-8")
554542

555-
invalid_strings = [
556-
b"-----BEGIN PUBLIC KEY-----",
557-
b"-----BEGIN RSA PUBLIC KEY-----",
558-
b"-----BEGIN CERTIFICATE-----",
559-
b"ssh-rsa",
560-
]
561-
562-
if any(string_value in key for string_value in invalid_strings):
543+
if is_pem_format(key) or is_ssh_key(key):
563544
raise JWKError(
564545
"The specified key is an asymmetric key or x509 certificate and"
565546
" should not be used as an HMAC secret."

jose/backends/native.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from jose.backends.base import Key
66
from jose.constants import ALGORITHMS
77
from jose.exceptions import JWKError
8-
from jose.utils import base64url_decode, base64url_encode
8+
from jose.utils import base64url_decode, base64url_encode, is_pem_format, is_ssh_key
99

1010

1111
def get_random_bytes(num_bytes):
@@ -36,14 +36,7 @@ def __init__(self, key, algorithm):
3636
if isinstance(key, str):
3737
key = key.encode("utf-8")
3838

39-
invalid_strings = [
40-
b"-----BEGIN PUBLIC KEY-----",
41-
b"-----BEGIN RSA PUBLIC KEY-----",
42-
b"-----BEGIN CERTIFICATE-----",
43-
b"ssh-rsa",
44-
]
45-
46-
if any(string_value in key for string_value in invalid_strings):
39+
if is_pem_format(key) or is_ssh_key(key):
4740
raise JWKError(
4841
"The specified key is an asymmetric key or x509 certificate and"
4942
" should not be used as an HMAC secret."

0 commit comments

Comments
 (0)