Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 54 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,20 +166,71 @@ jobs:
- {IMAGE: "ubuntu-noble", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "ubuntu-rolling", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "fedora", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "alpine", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "centos-stream9", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "centos-stream9-fips", NOXSESSION: "tests", RUNNER: "ubuntu-latest", FIPS: true}
- {IMAGE: "centos-stream10", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "centos-stream10-fips", NOXSESSION: "tests", RUNNER: "ubuntu-latest", FIPS: true}

- {IMAGE: "ubuntu-rolling:aarch64", NOXSESSION: "tests", RUNNER: "ubuntu-24.04-arm"}
- {IMAGE: "alpine:aarch64", NOXSESSION: "tests", RUNNER: "ubuntu-24.04-arm"}

- {IMAGE: "ubuntu-rolling:armv7l", NOXSESSION: "tests", RUNNER: "ubuntu-24.04-arm"}
timeout-minutes: 15
env:
RUSTUP_HOME: /root/.rustup
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
timeout-minutes: 3
with:
persist-credentials: false
- name: Cache rust and pip
uses: ./.github/actions/cache
timeout-minutes: 2
with:
key: ${{ matrix.IMAGE.IMAGE }}
- name: Clone test vectors
timeout-minutes: 2
uses: ./.github/actions/fetch-vectors
# When run in a docker container the home directory doesn't have the same owner as the
# apparent user so pip refuses to create a cache dir
- name: create pip cache dir
run: mkdir -p "${HOME}/.cache/pip"
- run: |
echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV
if: matrix.IMAGE.FIPS
- run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox[uv]' 'tomli; python_version < "3.11"'
- run: '/venv/bin/nox -v --install-only'
env:
# OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream
OPENSSL_ENABLE_SHA1_SIGNATURES: 1
NOXSESSION: ${{ matrix.IMAGE.NOXSESSION }}
- run: '/venv/bin/nox --no-install -- --color=yes --wycheproof-root="wycheproof" --x509-limbo-root="x509-limbo"'
env:
COLUMNS: 80
# OPENSSL_ENABLE_SHA1_SIGNATURES is for CentOS 9 Stream
OPENSSL_ENABLE_SHA1_SIGNATURES: 1
NOXSESSION: ${{ matrix.IMAGE.NOXSESSION }}
- uses: ./.github/actions/upload-coverage

alpine:
runs-on: ${{ matrix.IMAGE.RUNNER }}
container:
image: ghcr.io/pyca/cryptography-runner-${{ matrix.IMAGE.IMAGE }}
volumes:
- /staticnodehost:/staticnodecontainer:rw,rshared
- /staticnodehost:/__e/node20:ro,rshared
strategy:
fail-fast: false
matrix:
IMAGE:
- {IMAGE: "alpine", NOXSESSION: "tests", RUNNER: "ubuntu-latest"}
- {IMAGE: "alpine:aarch64", NOXSESSION: "tests", RUNNER: "ubuntu-24.04-arm"}
timeout-minutes: 15
env:
RUSTUP_HOME: /root/.rustup
steps:
- name: Ridiculous-er workaround for static node20
run: |
cp -R /staticnode/* /staticnodecontainer/
- name: Ridiculous alpine workaround for actions support on arm64
run: |
# This modifies /etc/os-release so the JS actions
Expand Down Expand Up @@ -414,7 +465,7 @@ jobs:
all-green:
# https://github.community/t/is-it-possible-to-require-all-github-actions-tasks-to-pass-without-enumerating-them/117957/4?u=graingert
runs-on: ubuntu-latest
needs: [linux, distros, macos, windows, linux-downstream]
needs: [linux, alpine, distros, macos, windows, linux-downstream]
if: ${{ always() }}
timeout-minutes: 3
steps:
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

.. _v45-0-4:

45.0.4 - 2025-06-09
~~~~~~~~~~~~~~~~~~~

* Fixed decrypting PKCS#8 files encrypted with SHA1-RC4. (This is not
considered secure, and is supported only for backwards compatibility.)

.. _v45-0-3:

45.0.3 - 2025-05-25
Expand Down
2 changes: 2 additions & 0 deletions docs/development/test-vectors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ Asymmetric ciphers
* ``asymmetric/PKCS8/rsa-rc2-cbc-effective-key-length.pem`` a PKCS8 encoded key
encrypted with ``RC2-CBC`` with the ``effectiveKeyLength`` parameter set to
258. This is an invalid key.
* ``asymmetric/PKCS8/enc-ec-sha1-128-rc4.pem`` a PKCS8 encoded ECDSA P-256 key
encrypted with ``pbeWithSHA1And128BitRC4``. The password is ``password``.


Custom asymmetric vectors
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ build-backend = "maturin"

[project]
name = "cryptography"
version = "45.0.3"
version = "45.0.4"
authors = [
{ name = "The Python Cryptographic Authority and individual contributors", email = "[email protected]" },
]
Expand Down Expand Up @@ -65,7 +65,7 @@ ssh = ["bcrypt >=3.1.5"]
# All the following are used for our own testing.
nox = ["nox >=2024.04.15", "nox[uv] >=2024.03.02; python_version >= '3.8'"]
test = [
"cryptography_vectors==45.0.3",
"cryptography_vectors==45.0.4",
"pytest >=7.4.0",
"pytest-benchmark >=4.0",
"pytest-cov >=2.10.1",
Expand Down
2 changes: 1 addition & 1 deletion src/cryptography/__about__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"__version__",
]

__version__ = "45.0.3"
__version__ = "45.0.4"


__author__ = "The Python Cryptographic Authority and individual contributors"
Expand Down
2 changes: 1 addition & 1 deletion src/rust/cryptography-key-parsing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ cryptography-crypto = { path = "../cryptography-crypto" }
cryptography-x509 = { path = "../cryptography-x509" }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(CRYPTOGRAPHY_IS_LIBRESSL)', 'cfg(CRYPTOGRAPHY_IS_BORINGSSL)', 'cfg(CRYPTOGRAPHY_OSSLCONF, values("OPENSSL_NO_RC2"))', 'cfg(CRYPTOGRAPHY_IS_AWSLC)'] }
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(CRYPTOGRAPHY_IS_LIBRESSL)', 'cfg(CRYPTOGRAPHY_IS_BORINGSSL)', 'cfg(CRYPTOGRAPHY_OSSLCONF, values("OPENSSL_NO_RC2", "OPENSSL_NO_RC4"))', 'cfg(CRYPTOGRAPHY_IS_AWSLC)'] }
8 changes: 8 additions & 0 deletions src/rust/cryptography-key-parsing/src/pkcs8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ pub fn parse_encrypted_private_key(
openssl::hash::MessageDigest::sha1(),
&params,
)?,
#[cfg(not(CRYPTOGRAPHY_OSSLCONF = "OPENSSL_NO_RC4"))]
AlgorithmParameters::PbeWithShaAnd128BitRc4(params) => pkcs12_pbe_decrypt(
epki.encrypted_data,
password,
openssl::symm::Cipher::rc4(),
openssl::hash::MessageDigest::sha1(),
&params,
)?,
AlgorithmParameters::Pbes2(params) => {
let (cipher, iv) = match params.encryption_scheme.params {
AlgorithmParameters::DesEde3Cbc(ref iv) => {
Expand Down
2 changes: 2 additions & 0 deletions src/rust/cryptography-x509/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ pub enum AlgorithmParameters<'a> {

#[defined_by(oid::PBE_WITH_MD5_AND_DES_CBC)]
PbeWithMd5AndDesCbc(PbeParams),
#[defined_by(oid::PBE_WITH_SHA_AND_128_BIT_RC4)]
PbeWithShaAnd128BitRc4(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_3KEY_TRIPLEDES_CBC)]
PbeWithShaAnd3KeyTripleDesCbc(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_40_BIT_RC2_CBC)]
Expand Down
2 changes: 2 additions & 0 deletions src/rust/cryptography-x509/src/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ pub const PBKDF2_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1,
pub const PBE_WITH_MD5_AND_DES_CBC: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 5, 3);
pub const SCRYPT_OID: asn1::ObjectIdentifier = asn1::oid!(1, 3, 6, 1, 4, 1, 11591, 4, 11);

pub const PBE_WITH_SHA_AND_128_BIT_RC4: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 12, 1, 1);
pub const PBE_WITH_SHA_AND_3KEY_TRIPLEDES_CBC: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 12, 1, 3);
pub const PBE_WITH_SHA_AND_40_BIT_RC2_CBC: asn1::ObjectIdentifier =
Expand Down
17 changes: 16 additions & 1 deletion tests/hazmat/primitives/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pytest

from cryptography.hazmat.bindings._rust import openssl as rust_openssl
from cryptography.hazmat.decrepit.ciphers.algorithms import _DES, RC2
from cryptography.hazmat.decrepit.ciphers.algorithms import _DES, ARC4, RC2
from cryptography.hazmat.primitives.asymmetric import (
dsa,
ec,
Expand Down Expand Up @@ -552,6 +552,21 @@ def test_load_pkcs8_rc2_cbc_effective_key_length(self):
with pytest.raises(ValueError):
load_pem_private_key(data, password=b"password")

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
ARC4(b"\x00" * 16), None
),
skip_message="Does not support RC4",
)
def test_load_pkcs8_rc4_sha1_128bit(self):
key = load_vectors_from_file(
os.path.join("asymmetric", "PKCS8", "enc-ec-sha1-128-rc4.pem"),
lambda f: load_pem_private_key(f.read(), password=b"password"),
mode="rb",
)
assert isinstance(key, ec.EllipticCurvePrivateKey)
assert isinstance(key.curve, ec.SECP256R1)

def test_load_pkcs8_aes_192_cbc(self):
key = load_vectors_from_file(
os.path.join("asymmetric", "PKCS8", "rsa-aes-192-cbc.pem"),
Expand Down
2 changes: 1 addition & 1 deletion vectors/cryptography_vectors/__about__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
"__version__",
]

__version__ = "45.0.3"
__version__ = "45.0.4"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIGrMBwGCiqGSIb3DQEMAQEwDgQIprjt98myskECAggABIGKdJJyNgMqiLL0EWI3
ZVto6g9msWT2ovpySiGxZyoUDfFrqfBuHY4IqwL/PYr9La1u/F/VuP5DRLf47YWp
iwfxc6sYedBU85f0c14Ha2Yc6hUEakCbQEzCqEg8RmJ2oDETbTO9STlMyk9ou8XV
7hdRkBqKNj3RIdgf01Aj5t8YmYsrKTx9VUDBpij0
-----END ENCRYPTED PRIVATE KEY-----
2 changes: 1 addition & 1 deletion vectors/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"

[project]
name = "cryptography_vectors"
version = "45.0.3"
version = "45.0.4"
authors = [
{name = "The Python Cryptographic Authority and individual contributors", email = "[email protected]"}
]
Expand Down
Loading