Skip to content

Commit

Permalink
Port a tiny tiny bit of the ASN.1 parsing to Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Aug 7, 2020
1 parent 1372bc8 commit 1375576
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 52 deletions.
32 changes: 21 additions & 11 deletions .github/workflows/ci.yml
Expand Up @@ -15,11 +15,12 @@ jobs:
strategy:
matrix:
PYTHON:
- {VERSION: "2.7", TOXENV: "py27", EXTRA_CFLAGS: ""}
- {VERSION: "3.5", TOXENV: "py35", EXTRA_CFLAGS: ""}
- {VERSION: "3.6", TOXENV: "py36", EXTRA_CFLAGS: ""}
- {VERSION: "3.7", TOXENV: "py37", EXTRA_CFLAGS: ""}
- {VERSION: "3.8", TOXENV: "py38", EXTRA_CFLAGS: "-DUSE_OSRANDOM_RNG_FOR_TESTING"}
RUST:
- nightly
name: "Python ${{ matrix.PYTHON.VERSION }} on macOS"
steps:
- uses: actions/checkout@master
Expand All @@ -28,6 +29,13 @@ jobs:
with:
python-version: ${{ matrix.PYTHON.VERSION }}

- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.RUST }}
override: true
default: true

- run: python -m pip install tox requests coverage

- run: git clone https://github.com/google/wycheproof
Expand Down Expand Up @@ -57,14 +65,15 @@ jobs:
strategy:
matrix:
WINDOWS:
- {ARCH: 'x86', WINDOWS: 'win32'}
- {ARCH: 'x64', WINDOWS: 'win64'}
- {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'}
- {ARCH: 'x64', WINDOWS: 'win64', RUST_TRIPLE: 'x86_64-pc-windows-msvc'}
PYTHON:
- {VERSION: "2.7", TOXENV: "py27", MSVC_VERSION: "2010", CL_FLAGS: ""}
- {VERSION: "3.5", TOXENV: "py35", MSVC_VERSION: "2019", CL_FLAGS: ""}
- {VERSION: "3.6", TOXENV: "py36", MSVC_VERSION: "2019", CL_FLAGS: ""}
- {VERSION: "3.7", TOXENV: "py37", MSVC_VERSION: "2019", CL_FLAGS: ""}
- {VERSION: "3.8", TOXENV: "py38", MSVC_VERSION: "2019", CL_FLAGS: "/D USE_OSRANDOM_RNG_FOR_TESTING"}
RUST:
- nightly
name: "Python ${{ matrix.PYTHON.VERSION }} on ${{ matrix.WINDOWS.WINDOWS }}"
steps:
- uses: actions/checkout@master
Expand All @@ -74,13 +83,14 @@ jobs:
python-version: ${{ matrix.PYTHON.VERSION }}
architecture: ${{ matrix.WINDOWS.ARCH }}

- name: Install MSVC for Python 2.7
run: |
Invoke-WebRequest -Uri https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi -OutFile VCForPython27.msi
Start-Process msiexec -Wait -ArgumentList @('/i', 'VCForPython27.msi', '/qn', 'ALLUSERS=1')
Remove-Item VCForPython27.msi -Force
shell: powershell
if: matrix.PYTHON.VERSION == '2.7'
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.RUST }}
override: true
default: true
target: ${{ matrix.WINDOWS.RUST_TRIPLE }}

- run: python -m pip install tox requests coverage
- name: Download OpenSSL
run: |
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/wheel-builder.yml
Expand Up @@ -68,6 +68,14 @@ jobs:
name: "Python ${{ matrix.PYTHON.VERSION }} for ABI ${{ matrix.PYTHON.ABI_VERSION }} on macOS"
steps:
- uses: actions/checkout@master

- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
default: true

- run: |
curl "$PYTHON_DOWNLOAD_URL" -o python.pkg
sudo installer -pkg python.pkg -target /
Expand Down Expand Up @@ -131,6 +139,14 @@ jobs:
with:
python-version: ${{ matrix.PYTHON.VERSION }}
architecture: ${{ matrix.WINDOWS.ARCH }}

- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
default: true

- name: Install MSVC for Python 2.7
run: |
Invoke-WebRequest -Uri https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi -OutFile VCForPython27.msi
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -12,3 +12,5 @@ htmlcov/
.eggs/
*.py[cdo]
.hypothesis/
target/
Cargo.lock
30 changes: 6 additions & 24 deletions .travis.yml
Expand Up @@ -19,26 +19,18 @@ branches:
matrix:
include:
- python: 3.8
env: TOXENV=pep8,packaging
env: TOXENV=pep8,rust,packaging
# Setting 'python' is just to make travis's UI a bit prettier
- python: 3.6
env: TOXENV=py36
# Travis lists available Pythons (including PyPy) by arch and distro here:
# https://docs.travis-ci.com/user/languages/python/#python-versions
- python: pypy2.7-7.3.1
env: TOXENV=pypy-nocoverage
- python: pypy3.6-7.3.1
env: TOXENV=pypy3-nocoverage
- python: 3.8
env: TOXENV=py38 OPENSSL=1.0.2u
- python: 2.7
env: TOXENV=py27 OPENSSL=1.1.0l
- python: 2.7
env: TOXENV=py27-ssh OPENSSL=1.1.0l
- python: 3.8
env: TOXENV=py38 OPENSSL=1.1.0l
- python: 2.7
env: TOXENV=py27 OPENSSL=1.1.1g
- python: 3.8
env: TOXENV=py38 OPENSSL=1.1.1g
- python: 3.8
Expand All @@ -54,21 +46,12 @@ matrix:
- python: 3.8
env: TOXENV=py38 LIBRESSL=3.2.0

- python: 2.7
services: docker
env: TOXENV=py27 DOCKER=pyca/cryptography-runner-centos7
- python: 2.7
services: docker
env: TOXENV=py27 DOCKER=pyca/cryptography-runner-centos8
- python: 3.6
services: docker
env: TOXENV=py36 DOCKER=pyca/cryptography-runner-centos8
- python: 3.6
services: docker
env: TOXENV=py36 OPENSSL_FORCE_FIPS_MODE=1 DOCKER=pyca/cryptography-runner-centos8-fips
- python: 2.7
services: docker
env: TOXENV=py27 DOCKER=pyca/cryptography-runner-stretch
- python: 3.5
services: docker
env: TOXENV=py35 DOCKER=pyca/cryptography-runner-stretch
Expand All @@ -87,9 +70,6 @@ matrix:
- python: 3.8
services: docker
env: TOXENV=py38 DOCKER=pyca/cryptography-runner-ubuntu-focal
- python: 2.7
services: docker
env: TOXENV=py27 DOCKER=pyca/cryptography-runner-ubuntu-rolling
- python: 3.8
services: docker
env: TOXENV=py38 DOCKER=pyca/cryptography-runner-ubuntu-rolling
Expand Down Expand Up @@ -118,11 +98,11 @@ matrix:
env: DOWNSTREAM=pyopenssl
- python: 3.7
env: DOWNSTREAM=twisted OPENSSL=1.1.1g
- python: 2.7
- python: 3.7
env: DOWNSTREAM=paramiko
- python: 2.7
- python: 3.7
env: DOWNSTREAM=aws-encryption-sdk
- python: 2.7
- python: 3.7
# BOTO_CONFIG works around this boto issue on travis:
# https://github.com/boto/boto/issues/3717
env: DOWNSTREAM=dynamodb-encryption-sdk BOTO_CONFIG=/dev/null
Expand All @@ -136,9 +116,11 @@ matrix:
dist: xenial

install:
- curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly --component rustmft
- ./.travis/install.sh

script:
- source $HOME/.cargo/env
- ./.travis/run.sh

after_success:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -14,6 +14,8 @@ Changelog
* Deprecated OpenSSL 1.0.2 support. OpenSSL 1.0.2 is no longer supported by
the OpenSSL project. The next version of ``cryptography`` will drop support
for it.
* Building ``cryptography`` from source now requires Rust be installed and
available. Users of the ``cryptography`` wheels will not need to do anything.
* Added initial support for parsing certificates from PKCS7 files with
:func:`~cryptography.hazmat.primitives.serialization.pkcs7.load_pem_pkcs7_certificates`
and
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -11,6 +11,7 @@ include pyproject.toml

recursive-include docs *
recursive-include src/_cffi_src *.py *.c *.h
recursive-include src/rust Cargo.toml *.rs
prune docs/_build
recursive-include tests *.py
exclude vectors
Expand Down
6 changes: 6 additions & 0 deletions docs/installation.rst
Expand Up @@ -64,6 +64,8 @@ platforms). ``cryptography`` links against the new 1.1.0 names by default. If
you need to compile ``cryptography`` against an older version then you **must**
set ``CRYPTOGRAPHY_WINDOWS_LINK_LEGACY_OPENSSL`` or else installation will fail.

You will also need to have Rust installed and available.

If you need to rebuild ``cryptography`` for any reason be sure to clear the
local `wheel cache`_.

Expand All @@ -86,6 +88,8 @@ If you are on Alpine or just want to compile it yourself then
using ``pypy``), and headers for the OpenSSL and ``libffi`` libraries
available on your system.

On all Linux distributions you will need to have Rust installed and available.

Alpine
~~~~~~

Expand Down Expand Up @@ -236,6 +240,8 @@ open a terminal window and run:
This will install a compiler (clang) along with (most of) the required
development headers.

You will also need to have Rust installed and available.

You'll also need OpenSSL, which you can obtain from `Homebrew`_ or `MacPorts`_.
Cryptography does **not** support Apple's deprecated OpenSSL distribution.

Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Expand Up @@ -6,6 +6,8 @@ requires = [
"wheel",
# Must be kept in sync with the `setup_requirements` in `setup.py`
"cffi>=1.8,!=1.11.3; platform_python_implementation != 'PyPy'",

"setuptools-rust>=0.11.1",
]
build-backend = "setuptools.build_meta"

Expand Down
7 changes: 6 additions & 1 deletion setup.py
Expand Up @@ -17,6 +17,8 @@
from setuptools import find_packages, setup
from setuptools.command.install import install

from setuptools_rust import RustExtension


if pkg_resources.parse_version(
setuptools.__version__
Expand All @@ -39,7 +41,7 @@


# `setup_requirements` must be kept in sync with `pyproject.toml`
setup_requirements = ["cffi>=1.8,!=1.11.3"]
setup_requirements = ["cffi>=1.8,!=1.11.3", "setuptools-rust>=0.11.1"]

if platform.python_implementation() == "PyPy":
if sys.pypy_version_info < (5, 4):
Expand Down Expand Up @@ -156,6 +158,9 @@ def argument_without_setup_requirements(argv, i):
return {
"setup_requires": setup_requirements,
"cffi_modules": cffi_modules,
"rust_extensions": [
RustExtension("_rust", "src/rust/Cargo.toml"),
],
}


Expand Down
23 changes: 7 additions & 16 deletions src/cryptography/hazmat/backends/openssl/decode_asn1.py
Expand Up @@ -10,8 +10,7 @@
import six

from cryptography import x509
from cryptography.hazmat._der import DERReader, INTEGER, NULL, SEQUENCE
from cryptography.x509.extensions import _TLS_FEATURE_TYPE_TO_ENUM
from cryptography.hazmat.bindings import _rust
from cryptography.x509.name import _ASN1_TYPE_TO_ENUM
from cryptography.x509.oid import (
CRLEntryExtensionOID,
Expand Down Expand Up @@ -209,25 +208,17 @@ def parse(self, backend, x509_obj):
# The extension contents are a SEQUENCE OF INTEGERs.
data = backend._lib.X509_EXTENSION_get_data(ext)
data_bytes = _asn1_string_to_bytes(backend, data)
features = DERReader(data_bytes).read_single_element(SEQUENCE)
parsed = []
while not features.is_empty():
parsed.append(features.read_element(INTEGER).as_integer())
# Map the features to their enum value.
value = x509.TLSFeature(
[_TLS_FEATURE_TYPE_TO_ENUM[x] for x in parsed]
)
value = _rust.parse_tls_feature(data_bytes)

extensions.append(x509.Extension(oid, critical, value))
seen_oids.add(oid)
continue
elif oid == ExtensionOID.PRECERT_POISON:
data = backend._lib.X509_EXTENSION_get_data(ext)
# The contents of the extension must be an ASN.1 NULL.
reader = DERReader(_asn1_string_to_bytes(backend, data))
reader.read_single_element(NULL).check_empty()
extensions.append(
x509.Extension(oid, critical, x509.PrecertPoison())
)
data_bytes = _asn1_string_to_bytes(backend, data)
value = _rust.parse_precert_poison(data_bytes)

extensions.append(x509.Extension(oid, critical, value))
seen_oids.add(oid)
continue

Expand Down
14 changes: 14 additions & 0 deletions src/rust/Cargo.toml
@@ -0,0 +1,14 @@
[package]
name = "cryptography-rust"
version = "0.1.0"
authors = ["The cryptography developers <cryptography-dev@python.org>"]
edition = "2018"
publish = false

[dependencies]
asn1 = { git = "https://github.com/alex/rust-asn1" }
pyo3 = { version = "0.11", features = ["extension-module"] }

[lib]
name = "cryptography_rust"
crate-type = ["cdylib"]

0 comments on commit 1375576

Please sign in to comment.