mirror of
https://github.com/saymrwulf/cryptography.git
synced 2026-05-14 20:37:55 +00:00
3.4.5 backports and changelog/version bump (#5827)
* Bump pyo3 and lower MSRV (#5823) * fix signature of EllipticCurvePublicKey.verify() (#5808) The signature change was introduced in https://github.com/pyca/cryptography/pull/5729 but is inconsistent with respect to related methods, breaks backward compatibility and compatibility with the OpenSSL backend (and maybe other backends) when named arguments are used. * Name: update get_attributes_for_oid return type (#5809) `List` gives more power to the caller. Note that `RelativeDistinguishedName`, the same function returns a `List`. Is there a reason this was `Iterable` only for `Name`? If we don't want to promise `List`, `Sequence` is another alternative. * Start typing a bunch of stuff from x509 extensions (#5812) * part 2 of typing x509 extensions (#5815) * 3.4.5 changelog and version bump * spelling * fix a false positive from the latest clippy (#5813) Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com> Co-authored-by: Markus Wamser <wamserma@users.noreply.github.com> Co-authored-by: Dan Halperin <dhalperi@users.noreply.github.com>
This commit is contained in:
parent
4a3018e6ae
commit
4d77fb9d3e
17 changed files with 414 additions and 158 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
|
@ -143,7 +143,8 @@ jobs:
|
|||
PYTHON:
|
||||
- {VERSION: "3.9", TOXENV: "py39"}
|
||||
RUST:
|
||||
# Cover MSRV and in-dev versions
|
||||
# Cover MSRV (and likely next MSRV) and in-dev versions
|
||||
- 1.41.0
|
||||
- 1.45.0
|
||||
- beta
|
||||
- nightly
|
||||
|
|
|
|||
|
|
@ -1,6 +1,19 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
.. _v3-4-5:
|
||||
|
||||
3.4.5 - 2021-02-13
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Various improvements to type hints.
|
||||
* Lower the minimum supported Rust version (MSRV) to >=1.41.0. This change
|
||||
improves compatibility with system-provided Rust on several Linux
|
||||
distributions.
|
||||
* ``cryptography`` will be switching to a new versioning scheme with its next
|
||||
feature release. More information is available in our
|
||||
:doc:`/api-stability` documentation.
|
||||
|
||||
.. _v3-4-4:
|
||||
|
||||
3.4.4 - 2021-02-09
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ You can install ``cryptography`` with ``pip``:
|
|||
|
||||
$ pip install cryptography
|
||||
|
||||
If this does not work please **upgrade your pip** first, as that is the
|
||||
single most common cause of installation problems.
|
||||
|
||||
Supported platforms
|
||||
-------------------
|
||||
|
||||
|
|
@ -72,18 +75,26 @@ local `wheel cache`_.
|
|||
Building cryptography on Linux
|
||||
------------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
If you are on RHEL/CentOS/Fedora/Debian/Ubuntu or another distribution
|
||||
derived from the preceding list, then you should **upgrade pip** and
|
||||
attempt to install ``cryptography`` again before following the instructions
|
||||
to compile it below. These platforms will receive a binary wheel and
|
||||
require no compiler if you have an updated ``pip``!
|
||||
|
||||
``cryptography`` ships ``manylinux`` wheels (as of 2.0) so all dependencies
|
||||
are included. For users on pip 19.0 or above running on a ``manylinux2010`` (or
|
||||
greater) compatible distribution (almost everything except Alpine) all you
|
||||
should need to do is:
|
||||
are included. For users on **pip 19.0** or above running on a ``manylinux2010``
|
||||
(or greater) compatible distribution (almost everything **except Alpine**) all
|
||||
you should need to do is:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install cryptography
|
||||
|
||||
If you are on Alpine or just want to compile it yourself then
|
||||
``cryptography`` requires a compiler, headers for Python (if you're not
|
||||
using ``pypy``), and headers for the OpenSSL and ``libffi`` libraries
|
||||
``cryptography`` requires a C compiler, a Rust compiler, headers for Python (if
|
||||
you're not using ``pypy``), and headers for the OpenSSL and ``libffi`` libraries
|
||||
available on your system.
|
||||
|
||||
On all Linux distributions you will need to have :ref:`Rust installed and
|
||||
|
|
@ -92,21 +103,57 @@ available<installation:Rust>`.
|
|||
Alpine
|
||||
~~~~~~
|
||||
|
||||
.. warning::
|
||||
|
||||
The Rust available by default in Alpine < 3.12 is older than the minimum
|
||||
supported version. See the :ref:`Rust installation instructions
|
||||
<installation:Rust>` for information about installing a newer Rust.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo apk add gcc musl-dev python3-dev libffi-dev openssl-dev
|
||||
$ sudo apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo
|
||||
|
||||
If you get an error with ``openssl-dev`` you may have to use ``libressl-dev``.
|
||||
|
||||
Debian/Ubuntu
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
.. warning::
|
||||
|
||||
The Rust available in current Debian stable and some Ubuntu versions is
|
||||
older than the minimum supported version. Ubuntu 18.04 and 20.04 are
|
||||
sufficiently new, but otherwise please see the
|
||||
:ref:`Rust installation instructions <installation:Rust>` for information
|
||||
about installing a newer Rust.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo apt-get install build-essential libssl-dev libffi-dev python3-dev
|
||||
$ sudo apt-get install build-essential libssl-dev libffi-dev \
|
||||
python3-dev cargo
|
||||
|
||||
RHEL/CentOS
|
||||
~~~~~~~~~~~
|
||||
Fedora/RHEL 8/CentOS 8
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. warning::
|
||||
|
||||
For RHEL and CentOS you must be on version 8.3 or newer for the command
|
||||
below to install a sufficiently new Rust. If your Rust is less than 1.41.0
|
||||
please see the :ref:`Rust installation instructions <installation:Rust>`
|
||||
for information about installing a newer Rust.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo dnf install redhat-rpm-config gcc libffi-devel python3-devel \
|
||||
openssl-devel cargo
|
||||
|
||||
RHEL 7/CentOS 7
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. warning::
|
||||
|
||||
You must install Rust using the :ref:`Rust installation instructions
|
||||
<installation:Rust>`. ``cryptography`` requires a Rust version newer than
|
||||
what is provided in the distribution packages.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
|
|
@ -226,10 +273,12 @@ This will install a compiler (clang) along with (most of) the required
|
|||
development headers.
|
||||
|
||||
You will also need to have :ref:`Rust installed and
|
||||
available<installation:Rust>`.
|
||||
available<installation:Rust>`, which can be obtained from `Homebrew`_,
|
||||
`MacPorts`_, or directly from the Rust website.
|
||||
|
||||
You'll also need OpenSSL, which you can obtain from `Homebrew`_ or `MacPorts`_.
|
||||
Cryptography does **not** support Apple's deprecated OpenSSL distribution.
|
||||
Finally you need OpenSSL, which you can obtain from `Homebrew`_ or `MacPorts`_.
|
||||
Cryptography does **not** support the OpenSSL/LibreSSL libraries Apple ships
|
||||
in its base operating system.
|
||||
|
||||
To build cryptography and dynamically link it:
|
||||
|
||||
|
|
@ -237,14 +286,14 @@ To build cryptography and dynamically link it:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ brew install openssl@1.1
|
||||
$ brew install openssl@1.1 rust
|
||||
$ env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography
|
||||
|
||||
`MacPorts`_:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo port install openssl
|
||||
$ sudo port install openssl rust
|
||||
$ env LDFLAGS="-L/opt/local/lib" CFLAGS="-I/opt/local/include" pip install cryptography
|
||||
|
||||
You can also build cryptography statically:
|
||||
|
|
@ -253,14 +302,14 @@ You can also build cryptography statically:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ brew install openssl@1.1
|
||||
$ brew install openssl@1.1 rust
|
||||
$ env CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 LDFLAGS="$(brew --prefix openssl@1.1)/lib/libssl.a $(brew --prefix openssl@1.1)/lib/libcrypto.a" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography
|
||||
|
||||
`MacPorts`_:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo port install openssl
|
||||
$ sudo port install openssl rust
|
||||
$ env CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 LDFLAGS="/opt/local/lib/libssl.a /opt/local/lib/libcrypto.a" CFLAGS="-I/opt/local/include" pip install cryptography
|
||||
|
||||
If you need to rebuild ``cryptography`` for any reason be sure to clear the
|
||||
|
|
@ -269,13 +318,31 @@ local `wheel cache`_.
|
|||
Rust
|
||||
----
|
||||
|
||||
.. note::
|
||||
|
||||
If you are on RHEL/CentOS/Fedora/Debian/Ubuntu or another distribution
|
||||
derived from the preceding list, then you should **upgrade pip** (in
|
||||
a virtual environment!) and attempt to install ``cryptography`` again
|
||||
before trying to install the Rust toolchain. These platforms will receive
|
||||
a binary wheel and require no compiler if you have an updated ``pip``!
|
||||
|
||||
Building ``cryptography`` requires having a working Rust toolchain. The current
|
||||
minimum supported Rust version is 1.45.0.
|
||||
minimum supported Rust version is 1.41.0. **This is newer than the Rust most
|
||||
package managers ship**, so users will likely need to install with the
|
||||
instructions below.
|
||||
|
||||
Instructions for installing Rust can be found on `the Rust Project's website`_.
|
||||
We recommend installing Rust with ``rustup`` (as documented by the Rust
|
||||
Project) in order to ensure you have a recent version.
|
||||
|
||||
Rust is only required when building ``cryptography``, meaning that you may
|
||||
install it for the duration of your ``pip install`` command and then remove it
|
||||
from a system. A Rust toolchain is not required to **use** ``cryptography``. In
|
||||
deployments such as ``docker``, you may use a multi-stage ``Dockerfile`` where
|
||||
you install Rust during the build phase but do not install it in the runtime
|
||||
image. This is the same as the C compiler toolchain which is also required to
|
||||
build ``cryptography``, but not afterwards.
|
||||
|
||||
.. _`Homebrew`: https://brew.sh
|
||||
.. _`MacPorts`: https://www.macports.org
|
||||
.. _`a binary distribution`: https://wiki.openssl.org/index.php/Binaries
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Botan
|
|||
Brainpool
|
||||
Bullseye
|
||||
Capitan
|
||||
CentOS
|
||||
changelog
|
||||
Changelog
|
||||
ciphertext
|
||||
|
|
@ -80,6 +81,7 @@ online
|
|||
paddings
|
||||
Parallelization
|
||||
personalization
|
||||
RHEL
|
||||
pickleable
|
||||
plaintext
|
||||
Poly
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -59,7 +59,7 @@ else:
|
|||
if platform.python_implementation() == "PyPy"
|
||||
else ["pyo3/abi3-py36"]
|
||||
),
|
||||
rust_version=">=1.45.0",
|
||||
rust_version=">=1.41.0",
|
||||
)
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ __summary__ = (
|
|||
)
|
||||
__uri__ = "https://github.com/pyca/cryptography"
|
||||
|
||||
__version__ = "3.4.4"
|
||||
__version__ = "3.4.5"
|
||||
|
||||
__author__ = "The Python Cryptographic Authority and individual contributors"
|
||||
__email__ = "cryptography-dev@python.org"
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ def _asn1_string_to_ascii(backend, asn1_string):
|
|||
return _asn1_string_to_bytes(backend, asn1_string).decode("ascii")
|
||||
|
||||
|
||||
def _asn1_string_to_utf8(backend, asn1_string):
|
||||
def _asn1_string_to_utf8(backend, asn1_string) -> str:
|
||||
buf = backend._ffi.new("unsigned char **")
|
||||
res = backend._lib.ASN1_STRING_to_UTF8(buf, asn1_string)
|
||||
if res == -1:
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ class EllipticCurvePublicKey(metaclass=abc.ABCMeta):
|
|||
self,
|
||||
signature: bytes,
|
||||
data: bytes,
|
||||
algorithm: EllipticCurveSignatureAlgorithm,
|
||||
signature_algorithm: EllipticCurveSignatureAlgorithm,
|
||||
) -> None:
|
||||
"""
|
||||
Verifies the signature of the data.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from cryptography.hazmat._der import (
|
|||
OBJECT_IDENTIFIER,
|
||||
SEQUENCE,
|
||||
)
|
||||
from cryptography.hazmat._types import _PUBLIC_KEY_TYPES
|
||||
from cryptography.hazmat.primitives import constant_time, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey
|
||||
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
|
||||
|
|
@ -33,7 +34,7 @@ from cryptography.x509.oid import (
|
|||
)
|
||||
|
||||
|
||||
def _key_identifier_from_public_key(public_key):
|
||||
def _key_identifier_from_public_key(public_key: _PUBLIC_KEY_TYPES) -> bytes:
|
||||
if isinstance(public_key, RSAPublicKey):
|
||||
data = public_key.public_bytes(
|
||||
serialization.Encoding.DER,
|
||||
|
|
@ -54,7 +55,7 @@ def _key_identifier_from_public_key(public_key):
|
|||
reader = DERReader(serialized)
|
||||
with reader.read_single_element(SEQUENCE) as public_key_info:
|
||||
algorithm = public_key_info.read_element(SEQUENCE)
|
||||
public_key = public_key_info.read_element(BIT_STRING)
|
||||
public_key_data = public_key_info.read_element(BIT_STRING)
|
||||
|
||||
# Double-check the algorithm structure.
|
||||
with algorithm:
|
||||
|
|
@ -65,10 +66,10 @@ def _key_identifier_from_public_key(public_key):
|
|||
|
||||
# BIT STRING contents begin with the number of padding bytes added. It
|
||||
# must be zero for SubjectPublicKeyInfo structures.
|
||||
if public_key.read_byte() != 0:
|
||||
if public_key_data.read_byte() != 0:
|
||||
raise ValueError("Invalid public key encoding")
|
||||
|
||||
data = public_key.data
|
||||
data = public_key_data.data
|
||||
|
||||
return hashlib.sha1(data).digest()
|
||||
|
||||
|
|
@ -110,14 +111,14 @@ class Extensions(object):
|
|||
def __init__(self, extensions: typing.List["Extension"]):
|
||||
self._extensions = extensions
|
||||
|
||||
def get_extension_for_oid(self, oid):
|
||||
def get_extension_for_oid(self, oid: ObjectIdentifier) -> "Extension":
|
||||
for ext in self:
|
||||
if ext.oid == oid:
|
||||
return ext
|
||||
|
||||
raise ExtensionNotFound("No {} extension was found".format(oid), oid)
|
||||
|
||||
def get_extension_for_class(self, extclass):
|
||||
def get_extension_for_class(self, extclass) -> "Extension":
|
||||
if extclass is UnrecognizedExtension:
|
||||
raise TypeError(
|
||||
"UnrecognizedExtension can't be used with "
|
||||
|
|
@ -142,7 +143,7 @@ class Extensions(object):
|
|||
class CRLNumber(ExtensionType):
|
||||
oid = ExtensionOID.CRL_NUMBER
|
||||
|
||||
def __init__(self, crl_number):
|
||||
def __init__(self, crl_number: int):
|
||||
if not isinstance(crl_number, int):
|
||||
raise TypeError("crl_number must be an integer")
|
||||
|
||||
|
|
@ -171,9 +172,9 @@ class AuthorityKeyIdentifier(ExtensionType):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
key_identifier,
|
||||
authority_cert_issuer,
|
||||
authority_cert_serial_number,
|
||||
key_identifier: typing.Optional[bytes],
|
||||
authority_cert_issuer: typing.Optional[typing.Iterable[GeneralName]],
|
||||
authority_cert_serial_number: typing.Optional[int],
|
||||
):
|
||||
if (authority_cert_issuer is None) != (
|
||||
authority_cert_serial_number is None
|
||||
|
|
@ -203,7 +204,9 @@ class AuthorityKeyIdentifier(ExtensionType):
|
|||
self._authority_cert_serial_number = authority_cert_serial_number
|
||||
|
||||
@classmethod
|
||||
def from_issuer_public_key(cls, public_key):
|
||||
def from_issuer_public_key(
|
||||
cls, public_key: _PUBLIC_KEY_TYPES
|
||||
) -> "AuthorityKeyIdentifier":
|
||||
digest = _key_identifier_from_public_key(public_key)
|
||||
return cls(
|
||||
key_identifier=digest,
|
||||
|
|
@ -212,7 +215,9 @@ class AuthorityKeyIdentifier(ExtensionType):
|
|||
)
|
||||
|
||||
@classmethod
|
||||
def from_issuer_subject_key_identifier(cls, ski):
|
||||
def from_issuer_subject_key_identifier(
|
||||
cls, ski: "SubjectKeyIdentifier"
|
||||
) -> "AuthorityKeyIdentifier":
|
||||
return cls(
|
||||
key_identifier=ski.digest,
|
||||
authority_cert_issuer=None,
|
||||
|
|
@ -260,11 +265,13 @@ class AuthorityKeyIdentifier(ExtensionType):
|
|||
class SubjectKeyIdentifier(ExtensionType):
|
||||
oid = ExtensionOID.SUBJECT_KEY_IDENTIFIER
|
||||
|
||||
def __init__(self, digest):
|
||||
def __init__(self, digest: bytes):
|
||||
self._digest = digest
|
||||
|
||||
@classmethod
|
||||
def from_public_key(cls, public_key):
|
||||
def from_public_key(
|
||||
cls, public_key: _PUBLIC_KEY_TYPES
|
||||
) -> "SubjectKeyIdentifier":
|
||||
return cls(_key_identifier_from_public_key(public_key))
|
||||
|
||||
digest = utils.read_only_property("_digest")
|
||||
|
|
@ -288,7 +295,7 @@ class SubjectKeyIdentifier(ExtensionType):
|
|||
class AuthorityInformationAccess(ExtensionType):
|
||||
oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS
|
||||
|
||||
def __init__(self, descriptions):
|
||||
def __init__(self, descriptions: typing.Iterable["AccessDescription"]):
|
||||
descriptions = list(descriptions)
|
||||
if not all(isinstance(x, AccessDescription) for x in descriptions):
|
||||
raise TypeError(
|
||||
|
|
@ -319,7 +326,7 @@ class AuthorityInformationAccess(ExtensionType):
|
|||
class SubjectInformationAccess(ExtensionType):
|
||||
oid = ExtensionOID.SUBJECT_INFORMATION_ACCESS
|
||||
|
||||
def __init__(self, descriptions):
|
||||
def __init__(self, descriptions: typing.Iterable["AccessDescription"]):
|
||||
descriptions = list(descriptions)
|
||||
if not all(isinstance(x, AccessDescription) for x in descriptions):
|
||||
raise TypeError(
|
||||
|
|
@ -348,7 +355,9 @@ class SubjectInformationAccess(ExtensionType):
|
|||
|
||||
|
||||
class AccessDescription(object):
|
||||
def __init__(self, access_method, access_location):
|
||||
def __init__(
|
||||
self, access_method: ObjectIdentifier, access_location: GeneralName
|
||||
):
|
||||
if not isinstance(access_method, ObjectIdentifier):
|
||||
raise TypeError("access_method must be an ObjectIdentifier")
|
||||
|
||||
|
|
@ -386,7 +395,7 @@ class AccessDescription(object):
|
|||
class BasicConstraints(ExtensionType):
|
||||
oid = ExtensionOID.BASIC_CONSTRAINTS
|
||||
|
||||
def __init__(self, ca, path_length):
|
||||
def __init__(self, ca: bool, path_length: typing.Optional[int]):
|
||||
if not isinstance(ca, bool):
|
||||
raise TypeError("ca must be a boolean value")
|
||||
|
||||
|
|
@ -427,7 +436,7 @@ class BasicConstraints(ExtensionType):
|
|||
class DeltaCRLIndicator(ExtensionType):
|
||||
oid = ExtensionOID.DELTA_CRL_INDICATOR
|
||||
|
||||
def __init__(self, crl_number):
|
||||
def __init__(self, crl_number: int):
|
||||
if not isinstance(crl_number, int):
|
||||
raise TypeError("crl_number must be an integer")
|
||||
|
||||
|
|
@ -454,7 +463,9 @@ class DeltaCRLIndicator(ExtensionType):
|
|||
class CRLDistributionPoints(ExtensionType):
|
||||
oid = ExtensionOID.CRL_DISTRIBUTION_POINTS
|
||||
|
||||
def __init__(self, distribution_points):
|
||||
def __init__(
|
||||
self, distribution_points: typing.Iterable["DistributionPoint"]
|
||||
):
|
||||
distribution_points = list(distribution_points)
|
||||
if not all(
|
||||
isinstance(x, DistributionPoint) for x in distribution_points
|
||||
|
|
@ -489,7 +500,9 @@ class CRLDistributionPoints(ExtensionType):
|
|||
class FreshestCRL(ExtensionType):
|
||||
oid = ExtensionOID.FRESHEST_CRL
|
||||
|
||||
def __init__(self, distribution_points):
|
||||
def __init__(
|
||||
self, distribution_points: typing.Iterable["DistributionPoint"]
|
||||
):
|
||||
distribution_points = list(distribution_points)
|
||||
if not all(
|
||||
isinstance(x, DistributionPoint) for x in distribution_points
|
||||
|
|
@ -522,7 +535,13 @@ class FreshestCRL(ExtensionType):
|
|||
|
||||
|
||||
class DistributionPoint(object):
|
||||
def __init__(self, full_name, relative_name, reasons, crl_issuer):
|
||||
def __init__(
|
||||
self,
|
||||
full_name: typing.Optional[typing.Iterable[GeneralName]],
|
||||
relative_name: typing.Optional[RelativeDistinguishedName],
|
||||
reasons: typing.Optional[typing.FrozenSet["ReasonFlags"]],
|
||||
crl_issuer: typing.Optional[typing.Iterable[GeneralName]],
|
||||
):
|
||||
if full_name and relative_name:
|
||||
raise ValueError(
|
||||
"You cannot provide both full_name and relative_name, at "
|
||||
|
|
@ -631,7 +650,11 @@ class ReasonFlags(Enum):
|
|||
class PolicyConstraints(ExtensionType):
|
||||
oid = ExtensionOID.POLICY_CONSTRAINTS
|
||||
|
||||
def __init__(self, require_explicit_policy, inhibit_policy_mapping):
|
||||
def __init__(
|
||||
self,
|
||||
require_explicit_policy: typing.Optional[int],
|
||||
inhibit_policy_mapping: typing.Optional[int],
|
||||
):
|
||||
if require_explicit_policy is not None and not isinstance(
|
||||
require_explicit_policy, int
|
||||
):
|
||||
|
|
@ -691,7 +714,7 @@ class PolicyConstraints(ExtensionType):
|
|||
class CertificatePolicies(ExtensionType):
|
||||
oid = ExtensionOID.CERTIFICATE_POLICIES
|
||||
|
||||
def __init__(self, policies):
|
||||
def __init__(self, policies: typing.Iterable["PolicyInformation"]):
|
||||
policies = list(policies)
|
||||
if not all(isinstance(x, PolicyInformation) for x in policies):
|
||||
raise TypeError(
|
||||
|
|
@ -720,7 +743,13 @@ class CertificatePolicies(ExtensionType):
|
|||
|
||||
|
||||
class PolicyInformation(object):
|
||||
def __init__(self, policy_identifier, policy_qualifiers):
|
||||
def __init__(
|
||||
self,
|
||||
policy_identifier: ObjectIdentifier,
|
||||
policy_qualifiers: typing.Optional[
|
||||
typing.Iterable[typing.Union[str, "UserNotice"]]
|
||||
],
|
||||
):
|
||||
if not isinstance(policy_identifier, ObjectIdentifier):
|
||||
raise TypeError("policy_identifier must be an ObjectIdentifier")
|
||||
|
||||
|
|
@ -769,7 +798,11 @@ class PolicyInformation(object):
|
|||
|
||||
|
||||
class UserNotice(object):
|
||||
def __init__(self, notice_reference, explicit_text):
|
||||
def __init__(
|
||||
self,
|
||||
notice_reference: typing.Optional["NoticeReference"],
|
||||
explicit_text: typing.Optional[str],
|
||||
):
|
||||
if notice_reference and not isinstance(
|
||||
notice_reference, NoticeReference
|
||||
):
|
||||
|
|
@ -806,7 +839,11 @@ class UserNotice(object):
|
|||
|
||||
|
||||
class NoticeReference(object):
|
||||
def __init__(self, organization, notice_numbers):
|
||||
def __init__(
|
||||
self,
|
||||
organization: typing.Optional[str],
|
||||
notice_numbers: typing.Iterable[int],
|
||||
):
|
||||
self._organization = organization
|
||||
notice_numbers = list(notice_numbers)
|
||||
if not all(isinstance(x, int) for x in notice_numbers):
|
||||
|
|
@ -842,7 +879,7 @@ class NoticeReference(object):
|
|||
class ExtendedKeyUsage(ExtensionType):
|
||||
oid = ExtensionOID.EXTENDED_KEY_USAGE
|
||||
|
||||
def __init__(self, usages):
|
||||
def __init__(self, usages: typing.Iterable[ObjectIdentifier]):
|
||||
usages = list(usages)
|
||||
if not all(isinstance(x, ObjectIdentifier) for x in usages):
|
||||
raise TypeError(
|
||||
|
|
@ -910,7 +947,7 @@ class PrecertPoison(ExtensionType):
|
|||
class TLSFeature(ExtensionType):
|
||||
oid = ExtensionOID.TLS_FEATURE
|
||||
|
||||
def __init__(self, features):
|
||||
def __init__(self, features: typing.Iterable["TLSFeatureType"]):
|
||||
features = list(features)
|
||||
if (
|
||||
not all(isinstance(x, TLSFeatureType) for x in features)
|
||||
|
|
@ -958,7 +995,7 @@ _TLS_FEATURE_TYPE_TO_ENUM = {x.value: x for x in TLSFeatureType}
|
|||
class InhibitAnyPolicy(ExtensionType):
|
||||
oid = ExtensionOID.INHIBIT_ANY_POLICY
|
||||
|
||||
def __init__(self, skip_certs):
|
||||
def __init__(self, skip_certs: int):
|
||||
if not isinstance(skip_certs, int):
|
||||
raise TypeError("skip_certs must be an integer")
|
||||
|
||||
|
|
@ -990,15 +1027,15 @@ class KeyUsage(ExtensionType):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
digital_signature,
|
||||
content_commitment,
|
||||
key_encipherment,
|
||||
data_encipherment,
|
||||
key_agreement,
|
||||
key_cert_sign,
|
||||
crl_sign,
|
||||
encipher_only,
|
||||
decipher_only,
|
||||
digital_signature: bool,
|
||||
content_commitment: bool,
|
||||
key_encipherment: bool,
|
||||
data_encipherment: bool,
|
||||
key_agreement: bool,
|
||||
key_cert_sign: bool,
|
||||
crl_sign: bool,
|
||||
encipher_only: bool,
|
||||
decipher_only: bool,
|
||||
):
|
||||
if not key_agreement and (encipher_only or decipher_only):
|
||||
raise ValueError(
|
||||
|
|
@ -1101,7 +1138,11 @@ class KeyUsage(ExtensionType):
|
|||
class NameConstraints(ExtensionType):
|
||||
oid = ExtensionOID.NAME_CONSTRAINTS
|
||||
|
||||
def __init__(self, permitted_subtrees, excluded_subtrees):
|
||||
def __init__(
|
||||
self,
|
||||
permitted_subtrees: typing.Optional[typing.Iterable[GeneralName]],
|
||||
excluded_subtrees: typing.Optional[typing.Iterable[GeneralName]],
|
||||
):
|
||||
if permitted_subtrees is not None:
|
||||
permitted_subtrees = list(permitted_subtrees)
|
||||
if not all(isinstance(x, GeneralName) for x in permitted_subtrees):
|
||||
|
|
@ -1180,7 +1221,9 @@ class NameConstraints(ExtensionType):
|
|||
|
||||
|
||||
class Extension(object):
|
||||
def __init__(self, oid, critical, value):
|
||||
def __init__(
|
||||
self, oid: ObjectIdentifier, critical: bool, value: ExtensionType
|
||||
):
|
||||
if not isinstance(oid, ObjectIdentifier):
|
||||
raise TypeError(
|
||||
"oid argument must be an ObjectIdentifier instance."
|
||||
|
|
@ -1221,7 +1264,7 @@ class Extension(object):
|
|||
|
||||
|
||||
class GeneralNames(object):
|
||||
def __init__(self, general_names):
|
||||
def __init__(self, general_names: typing.Iterable[GeneralName]):
|
||||
general_names = list(general_names)
|
||||
if not all(isinstance(x, GeneralName) for x in general_names):
|
||||
raise TypeError(
|
||||
|
|
@ -1233,7 +1276,7 @@ class GeneralNames(object):
|
|||
|
||||
__len__, __iter__, __getitem__ = _make_sequence_methods("_general_names")
|
||||
|
||||
def get_values_for_type(self, type):
|
||||
def get_values_for_type(self, type: typing.Type[GeneralName]):
|
||||
# Return the value of each GeneralName, except for OtherName instances
|
||||
# which we return directly because it has two important properties not
|
||||
# just one value.
|
||||
|
|
@ -1261,7 +1304,7 @@ class GeneralNames(object):
|
|||
class SubjectAlternativeName(ExtensionType):
|
||||
oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME
|
||||
|
||||
def __init__(self, general_names):
|
||||
def __init__(self, general_names: typing.Iterable[GeneralName]):
|
||||
self._general_names = GeneralNames(general_names)
|
||||
|
||||
__len__, __iter__, __getitem__ = _make_sequence_methods("_general_names")
|
||||
|
|
@ -1288,7 +1331,7 @@ class SubjectAlternativeName(ExtensionType):
|
|||
class IssuerAlternativeName(ExtensionType):
|
||||
oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME
|
||||
|
||||
def __init__(self, general_names):
|
||||
def __init__(self, general_names: typing.Iterable[GeneralName]):
|
||||
self._general_names = GeneralNames(general_names)
|
||||
|
||||
__len__, __iter__, __getitem__ = _make_sequence_methods("_general_names")
|
||||
|
|
@ -1315,7 +1358,7 @@ class IssuerAlternativeName(ExtensionType):
|
|||
class CertificateIssuer(ExtensionType):
|
||||
oid = CRLEntryExtensionOID.CERTIFICATE_ISSUER
|
||||
|
||||
def __init__(self, general_names):
|
||||
def __init__(self, general_names: typing.Iterable[GeneralName]):
|
||||
self._general_names = GeneralNames(general_names)
|
||||
|
||||
__len__, __iter__, __getitem__ = _make_sequence_methods("_general_names")
|
||||
|
|
@ -1342,7 +1385,7 @@ class CertificateIssuer(ExtensionType):
|
|||
class CRLReason(ExtensionType):
|
||||
oid = CRLEntryExtensionOID.CRL_REASON
|
||||
|
||||
def __init__(self, reason):
|
||||
def __init__(self, reason: ReasonFlags):
|
||||
if not isinstance(reason, ReasonFlags):
|
||||
raise TypeError("reason must be an element from ReasonFlags")
|
||||
|
||||
|
|
@ -1369,7 +1412,7 @@ class CRLReason(ExtensionType):
|
|||
class InvalidityDate(ExtensionType):
|
||||
oid = CRLEntryExtensionOID.INVALIDITY_DATE
|
||||
|
||||
def __init__(self, invalidity_date):
|
||||
def __init__(self, invalidity_date: datetime.datetime):
|
||||
if not isinstance(invalidity_date, datetime.datetime):
|
||||
raise TypeError("invalidity_date must be a datetime.datetime")
|
||||
|
||||
|
|
@ -1398,7 +1441,12 @@ class InvalidityDate(ExtensionType):
|
|||
class PrecertificateSignedCertificateTimestamps(ExtensionType):
|
||||
oid = ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS
|
||||
|
||||
def __init__(self, signed_certificate_timestamps):
|
||||
def __init__(
|
||||
self,
|
||||
signed_certificate_timestamps: typing.Iterable[
|
||||
SignedCertificateTimestamp
|
||||
],
|
||||
):
|
||||
signed_certificate_timestamps = list(signed_certificate_timestamps)
|
||||
if not all(
|
||||
isinstance(sct, SignedCertificateTimestamp)
|
||||
|
|
@ -1438,7 +1486,12 @@ class PrecertificateSignedCertificateTimestamps(ExtensionType):
|
|||
class SignedCertificateTimestamps(ExtensionType):
|
||||
oid = ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS
|
||||
|
||||
def __init__(self, signed_certificate_timestamps):
|
||||
def __init__(
|
||||
self,
|
||||
signed_certificate_timestamps: typing.Iterable[
|
||||
SignedCertificateTimestamp
|
||||
],
|
||||
):
|
||||
signed_certificate_timestamps = list(signed_certificate_timestamps)
|
||||
if not all(
|
||||
isinstance(sct, SignedCertificateTimestamp)
|
||||
|
|
@ -1476,7 +1529,7 @@ class SignedCertificateTimestamps(ExtensionType):
|
|||
class OCSPNonce(ExtensionType):
|
||||
oid = OCSPExtensionOID.NONCE
|
||||
|
||||
def __init__(self, nonce):
|
||||
def __init__(self, nonce: bytes):
|
||||
if not isinstance(nonce, bytes):
|
||||
raise TypeError("nonce must be bytes")
|
||||
|
||||
|
|
@ -1642,7 +1695,7 @@ class IssuingDistributionPoint(ExtensionType):
|
|||
|
||||
|
||||
class UnrecognizedExtension(ExtensionType):
|
||||
def __init__(self, oid, value):
|
||||
def __init__(self, oid: ObjectIdentifier, value: bytes):
|
||||
if not isinstance(oid, ObjectIdentifier):
|
||||
raise TypeError("oid must be an ObjectIdentifier")
|
||||
self._oid = oid
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ class GeneralName(metaclass=abc.ABCMeta):
|
|||
"""
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class RFC822Name(object):
|
||||
class RFC822Name(GeneralName):
|
||||
def __init__(self, value: str):
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
|
|
@ -87,8 +86,7 @@ class RFC822Name(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class DNSName(object):
|
||||
class DNSName(GeneralName):
|
||||
def __init__(self, value: str):
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
|
|
@ -128,8 +126,7 @@ class DNSName(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class UniformResourceIdentifier(object):
|
||||
class UniformResourceIdentifier(GeneralName):
|
||||
def __init__(self, value: str):
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
|
|
@ -169,8 +166,7 @@ class UniformResourceIdentifier(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class DirectoryName(object):
|
||||
class DirectoryName(GeneralName):
|
||||
def __init__(self, value: Name):
|
||||
if not isinstance(value, Name):
|
||||
raise TypeError("value must be a Name")
|
||||
|
|
@ -195,8 +191,7 @@ class DirectoryName(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class RegisteredID(object):
|
||||
class RegisteredID(GeneralName):
|
||||
def __init__(self, value: ObjectIdentifier):
|
||||
if not isinstance(value, ObjectIdentifier):
|
||||
raise TypeError("value must be an ObjectIdentifier")
|
||||
|
|
@ -221,8 +216,7 @@ class RegisteredID(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class IPAddress(object):
|
||||
class IPAddress(GeneralName):
|
||||
def __init__(
|
||||
self,
|
||||
value: typing.Union[
|
||||
|
|
@ -267,8 +261,7 @@ class IPAddress(object):
|
|||
return hash(self.value)
|
||||
|
||||
|
||||
@utils.register_interface(GeneralName)
|
||||
class OtherName(object):
|
||||
class OtherName(GeneralName):
|
||||
def __init__(self, type_id: ObjectIdentifier, value: bytes):
|
||||
if not isinstance(type_id, ObjectIdentifier):
|
||||
raise TypeError("type_id must be an ObjectIdentifier")
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ class Name(object):
|
|||
attr.rfc4514_string() for attr in reversed(self._attributes)
|
||||
)
|
||||
|
||||
def get_attributes_for_oid(self, oid) -> typing.Iterable[NameAttribute]:
|
||||
def get_attributes_for_oid(self, oid) -> typing.List[NameAttribute]:
|
||||
return [i for i in self if i.oid == oid]
|
||||
|
||||
@property
|
||||
|
|
|
|||
74
src/rust/Cargo.lock
generated
74
src/rust/Cargo.lock
generated
|
|
@ -1,5 +1,11 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
|
@ -36,10 +42,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "1.0.3"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5a75aeaaef0ce18b58056d306c27b07436fbb34b8816c53094b76dd81803136"
|
||||
checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8"
|
||||
dependencies = [
|
||||
"indoc-impl",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc-impl"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unindent",
|
||||
]
|
||||
|
||||
|
|
@ -102,9 +122,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
|
|
@ -116,9 +136,28 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.4"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5d65c4d95931acda4498f675e332fcbdc9a06705cd07086c510e9b6009cd1c1"
|
||||
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
||||
dependencies = [
|
||||
"paste-impl",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste-impl"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
|
|
@ -131,9 +170,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.13.1"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00ca634cf3acd58a599b535ed6cb188223298977d471d146121792bfa23b754c"
|
||||
checksum = "4837b8e8e18a102c23f79d1e9a110b597ea3b684c95e874eb1ad88f8683109c3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"ctor",
|
||||
|
|
@ -148,9 +187,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.13.1"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "483ac516dbda6789a5b4be0271e7a31b9ad4ec8c0a5955050e8076f72bdbef8f"
|
||||
checksum = "a47f2c300ceec3e58064fd5f8f5b61230f2ffd64bde4970c81fdd0563a2db1bb"
|
||||
dependencies = [
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
|
|
@ -159,9 +198,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.13.1"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15230cabcda008f03565ed8bac40f094cbb5ee1b46e6551f1ec3a0e922cf7df9"
|
||||
checksum = "87b097e5d84fcbe3e167f400fbedd657820a375b034c78bd852050749a575d66"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -170,18 +209,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.8"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
// for complete details.
|
||||
|
||||
#[pyo3::prelude::pymodule]
|
||||
// False positive: https://github.com/rust-lang/rust-clippy/issues/6721
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn _rust(_py: pyo3::Python<'_>, _m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -726,7 +726,9 @@ class TestOCSPResponseBuilder(object):
|
|||
class TestSignedCertificateTimestampsExtension(object):
|
||||
def test_init(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.SignedCertificateTimestamps([object()])
|
||||
x509.SignedCertificateTimestamps(
|
||||
[object()] # type: ignore[list-item]
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
assert repr(x509.SignedCertificateTimestamps([])) == (
|
||||
|
|
|
|||
|
|
@ -4070,7 +4070,9 @@ class TestCertificateSigningRequestBuilder(object):
|
|||
x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "SAN")])
|
||||
)
|
||||
.add_extension(
|
||||
x509.SubjectAlternativeName([FakeGeneralName("")]),
|
||||
x509.SubjectAlternativeName(
|
||||
[FakeGeneralName("")] # type:ignore[list-item]
|
||||
),
|
||||
critical=False,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import binascii
|
|||
import datetime
|
||||
import ipaddress
|
||||
import os
|
||||
import typing
|
||||
|
||||
import pretend
|
||||
|
||||
|
|
@ -56,12 +57,16 @@ class TestExtension(object):
|
|||
def test_not_an_oid(self):
|
||||
bc = x509.BasicConstraints(ca=False, path_length=None)
|
||||
with pytest.raises(TypeError):
|
||||
x509.Extension("notanoid", True, bc)
|
||||
x509.Extension("notanoid", True, bc) # type:ignore[arg-type]
|
||||
|
||||
def test_critical_not_a_bool(self):
|
||||
bc = x509.BasicConstraints(ca=False, path_length=None)
|
||||
with pytest.raises(TypeError):
|
||||
x509.Extension(ExtensionOID.BASIC_CONSTRAINTS, "notabool", bc)
|
||||
x509.Extension(
|
||||
ExtensionOID.BASIC_CONSTRAINTS,
|
||||
"notabool", # type:ignore[arg-type]
|
||||
bc,
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
bc = x509.BasicConstraints(ca=False, path_length=None)
|
||||
|
|
@ -73,16 +78,38 @@ class TestExtension(object):
|
|||
)
|
||||
|
||||
def test_eq(self):
|
||||
ext1 = x509.Extension(x509.ObjectIdentifier("1.2.3.4"), False, "value")
|
||||
ext2 = x509.Extension(x509.ObjectIdentifier("1.2.3.4"), False, "value")
|
||||
ext1 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.4"),
|
||||
False,
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
)
|
||||
ext2 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.4"),
|
||||
False,
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
)
|
||||
assert ext1 == ext2
|
||||
|
||||
def test_ne(self):
|
||||
ext1 = x509.Extension(x509.ObjectIdentifier("1.2.3.4"), False, "value")
|
||||
ext2 = x509.Extension(x509.ObjectIdentifier("1.2.3.5"), False, "value")
|
||||
ext3 = x509.Extension(x509.ObjectIdentifier("1.2.3.4"), True, "value")
|
||||
ext1 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.4"),
|
||||
False,
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
)
|
||||
ext2 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.5"),
|
||||
False,
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
)
|
||||
ext3 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.4"),
|
||||
True,
|
||||
x509.BasicConstraints(ca=False, path_length=None),
|
||||
)
|
||||
ext4 = x509.Extension(
|
||||
x509.ObjectIdentifier("1.2.3.4"), False, "value4"
|
||||
x509.ObjectIdentifier("1.2.3.4"),
|
||||
False,
|
||||
x509.BasicConstraints(ca=True, path_length=None),
|
||||
)
|
||||
assert ext1 != ext2
|
||||
assert ext1 != ext3
|
||||
|
|
@ -112,7 +139,7 @@ class TestExtension(object):
|
|||
class TestTLSFeature(object):
|
||||
def test_not_enum_type(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.TLSFeature([3])
|
||||
x509.TLSFeature([3]) # type:ignore[list-item]
|
||||
|
||||
def test_empty_list(self):
|
||||
with pytest.raises(TypeError):
|
||||
|
|
@ -181,7 +208,9 @@ class TestTLSFeature(object):
|
|||
class TestUnrecognizedExtension(object):
|
||||
def test_invalid_oid(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.UnrecognizedExtension("notanoid", b"somedata")
|
||||
x509.UnrecognizedExtension(
|
||||
"notanoid", b"somedata" # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_eq(self):
|
||||
ext1 = x509.UnrecognizedExtension(
|
||||
|
|
@ -289,7 +318,7 @@ class TestCertificateIssuer(object):
|
|||
class TestCRLReason(object):
|
||||
def test_invalid_reason_flags(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.CRLReason("notareason")
|
||||
x509.CRLReason("notareason") # type:ignore[arg-type]
|
||||
|
||||
def test_eq(self):
|
||||
reason1 = x509.CRLReason(x509.ReasonFlags.unspecified)
|
||||
|
|
@ -318,7 +347,7 @@ class TestCRLReason(object):
|
|||
class TestDeltaCRLIndicator(object):
|
||||
def test_not_int(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.DeltaCRLIndicator("notanint")
|
||||
x509.DeltaCRLIndicator("notanint") # type:ignore[arg-type]
|
||||
|
||||
def test_eq(self):
|
||||
delta1 = x509.DeltaCRLIndicator(1)
|
||||
|
|
@ -346,7 +375,7 @@ class TestDeltaCRLIndicator(object):
|
|||
class TestInvalidityDate(object):
|
||||
def test_invalid_invalidity_date(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.InvalidityDate("notadate")
|
||||
x509.InvalidityDate("notadate") # type:ignore[arg-type]
|
||||
|
||||
def test_eq(self):
|
||||
invalid1 = x509.InvalidityDate(datetime.datetime(2015, 1, 1, 1, 1))
|
||||
|
|
@ -376,11 +405,13 @@ class TestInvalidityDate(object):
|
|||
class TestNoticeReference(object):
|
||||
def test_notice_numbers_not_all_int(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.NoticeReference("org", [1, 2, "three"])
|
||||
x509.NoticeReference(
|
||||
"org", [1, 2, "three"] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_notice_numbers_none(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.NoticeReference("org", None)
|
||||
x509.NoticeReference("org", None) # type:ignore[arg-type]
|
||||
|
||||
def test_iter_input(self):
|
||||
numbers = [1, 3, 4]
|
||||
|
|
@ -419,7 +450,7 @@ class TestNoticeReference(object):
|
|||
class TestUserNotice(object):
|
||||
def test_notice_reference_invalid(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.UserNotice("invalid", None)
|
||||
x509.UserNotice("invalid", None) # type:ignore[arg-type]
|
||||
|
||||
def test_notice_reference_none(self):
|
||||
un = x509.UserNotice(None, "text")
|
||||
|
|
@ -463,7 +494,7 @@ class TestUserNotice(object):
|
|||
class TestPolicyInformation(object):
|
||||
def test_invalid_policy_identifier(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.PolicyInformation("notanoid", None)
|
||||
x509.PolicyInformation("notanoid", None) # type:ignore[arg-type]
|
||||
|
||||
def test_none_policy_qualifiers(self):
|
||||
pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), None)
|
||||
|
|
@ -478,7 +509,10 @@ class TestPolicyInformation(object):
|
|||
|
||||
def test_invalid_policy_identifiers(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), [1, 2])
|
||||
x509.PolicyInformation(
|
||||
x509.ObjectIdentifier("1.2.3"),
|
||||
[1, 2], # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_iter_input(self):
|
||||
qual = ["foo", "bar"]
|
||||
|
|
@ -486,7 +520,10 @@ class TestPolicyInformation(object):
|
|||
assert list(pi.policy_qualifiers) == qual
|
||||
|
||||
def test_repr(self):
|
||||
pq = ["string", x509.UserNotice(None, "hi")]
|
||||
pq: typing.List[typing.Union[str, x509.UserNotice]] = [
|
||||
"string",
|
||||
x509.UserNotice(None, "hi"),
|
||||
]
|
||||
pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq)
|
||||
assert repr(pi) == (
|
||||
"<PolicyInformation(policy_identifier=<ObjectIdentifier(oid=1."
|
||||
|
|
@ -537,7 +574,7 @@ class TestCertificatePolicies(object):
|
|||
pq = ["string"]
|
||||
pi = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), pq)
|
||||
with pytest.raises(TypeError):
|
||||
x509.CertificatePolicies([1, pi])
|
||||
x509.CertificatePolicies([1, pi]) # type:ignore[list-item]
|
||||
|
||||
def test_iter_len(self):
|
||||
pq = ["string"]
|
||||
|
|
@ -620,7 +657,7 @@ class TestCertificatePolicies(object):
|
|||
)
|
||||
cp2 = x509.CertificatePolicies([pi2])
|
||||
pi3 = x509.PolicyInformation(
|
||||
x509.ObjectIdentifier("1.2.3"), [x509.UserNotice(None, b"text")]
|
||||
x509.ObjectIdentifier("1.2.3"), [x509.UserNotice(None, "text")]
|
||||
)
|
||||
cp3 = x509.CertificatePolicies([pi3])
|
||||
assert hash(cp) == hash(cp2)
|
||||
|
|
@ -1005,7 +1042,9 @@ class TestSubjectKeyIdentifier(object):
|
|||
class TestAuthorityKeyIdentifier(object):
|
||||
def test_authority_cert_issuer_not_generalname(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.AuthorityKeyIdentifier(b"identifier", ["notname"], 3)
|
||||
x509.AuthorityKeyIdentifier(
|
||||
b"identifier", ["notname"], 3 # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_authority_cert_serial_number_not_integer(self):
|
||||
dirname = x509.DirectoryName(
|
||||
|
|
@ -1021,7 +1060,9 @@ class TestAuthorityKeyIdentifier(object):
|
|||
)
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
x509.AuthorityKeyIdentifier(b"identifier", [dirname], "notanint")
|
||||
x509.AuthorityKeyIdentifier(
|
||||
b"identifier", [dirname], "notanint" # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_authority_issuer_none_serial_not_none(self):
|
||||
with pytest.raises(ValueError):
|
||||
|
|
@ -1120,7 +1161,9 @@ class TestAuthorityKeyIdentifier(object):
|
|||
class TestBasicConstraints(object):
|
||||
def test_ca_not_boolean(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.BasicConstraints(ca="notbool", path_length=None)
|
||||
x509.BasicConstraints(
|
||||
ca="notbool", path_length=None # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_path_length_not_ca(self):
|
||||
with pytest.raises(ValueError):
|
||||
|
|
@ -1128,10 +1171,14 @@ class TestBasicConstraints(object):
|
|||
|
||||
def test_path_length_not_int(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.BasicConstraints(ca=True, path_length=1.1)
|
||||
x509.BasicConstraints(
|
||||
ca=True, path_length=1.1 # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
x509.BasicConstraints(ca=True, path_length="notint")
|
||||
x509.BasicConstraints(
|
||||
ca=True, path_length="notint" # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_path_length_negative(self):
|
||||
with pytest.raises(TypeError):
|
||||
|
|
@ -1165,7 +1212,7 @@ class TestBasicConstraints(object):
|
|||
class TestExtendedKeyUsage(object):
|
||||
def test_not_all_oids(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.ExtendedKeyUsage(["notoid"])
|
||||
x509.ExtendedKeyUsage(["notoid"]) # type:ignore[list-item]
|
||||
|
||||
def test_iter_len(self):
|
||||
eku = x509.ExtendedKeyUsage(
|
||||
|
|
@ -1990,7 +2037,12 @@ class TestGeneralNames(object):
|
|||
|
||||
def test_invalid_general_names(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.GeneralNames([x509.DNSName("cryptography.io"), "invalid"])
|
||||
x509.GeneralNames(
|
||||
[
|
||||
x509.DNSName("cryptography.io"),
|
||||
"invalid", # type:ignore[list-item]
|
||||
]
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
gns = x509.GeneralNames([x509.DNSName("cryptography.io")])
|
||||
|
|
@ -2049,7 +2101,10 @@ class TestIssuerAlternativeName(object):
|
|||
def test_invalid_general_names(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.IssuerAlternativeName(
|
||||
[x509.DNSName("cryptography.io"), "invalid"]
|
||||
[
|
||||
x509.DNSName("cryptography.io"),
|
||||
"invalid", # type:ignore[list-item]
|
||||
]
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
|
|
@ -2115,7 +2170,7 @@ class TestCRLNumber(object):
|
|||
|
||||
def test_invalid_number(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.CRLNumber("notanumber")
|
||||
x509.CRLNumber("notanumber") # type:ignore[arg-type]
|
||||
|
||||
def test_hash(self):
|
||||
c1 = x509.CRLNumber(1)
|
||||
|
|
@ -2157,7 +2212,10 @@ class TestSubjectAlternativeName(object):
|
|||
def test_invalid_general_names(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.SubjectAlternativeName(
|
||||
[x509.DNSName("cryptography.io"), "invalid"]
|
||||
[
|
||||
x509.DNSName("cryptography.io"),
|
||||
"invalid", # type:ignore[list-item]
|
||||
]
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
|
|
@ -2521,12 +2579,15 @@ class TestExtendedKeyUsageExtension(object):
|
|||
class TestAccessDescription(object):
|
||||
def test_invalid_access_method(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.AccessDescription("notanoid", x509.DNSName("test"))
|
||||
x509.AccessDescription(
|
||||
"notanoid", x509.DNSName("test") # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_invalid_access_location(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.AccessDescription(
|
||||
AuthorityInformationAccessOID.CA_ISSUERS, "invalid"
|
||||
AuthorityInformationAccessOID.CA_ISSUERS,
|
||||
"invalid", # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_valid_nonstandard_method(self):
|
||||
|
|
@ -2595,11 +2656,11 @@ class TestAccessDescription(object):
|
|||
class TestPolicyConstraints(object):
|
||||
def test_invalid_explicit_policy(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.PolicyConstraints("invalid", None)
|
||||
x509.PolicyConstraints("invalid", None) # type:ignore[arg-type]
|
||||
|
||||
def test_invalid_inhibit_policy(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.PolicyConstraints(None, "invalid")
|
||||
x509.PolicyConstraints(None, "invalid") # type:ignore[arg-type]
|
||||
|
||||
def test_both_none(self):
|
||||
with pytest.raises(ValueError):
|
||||
|
|
@ -2672,7 +2733,9 @@ class TestPolicyConstraintsExtension(object):
|
|||
class TestAuthorityInformationAccess(object):
|
||||
def test_invalid_descriptions(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.AuthorityInformationAccess(["notanAccessDescription"])
|
||||
x509.AuthorityInformationAccess(
|
||||
["notanAccessDescription"] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_iter_len(self):
|
||||
aia = x509.AuthorityInformationAccess(
|
||||
|
|
@ -2856,7 +2919,9 @@ class TestAuthorityInformationAccess(object):
|
|||
class TestSubjectInformationAccess(object):
|
||||
def test_invalid_descriptions(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.SubjectInformationAccess(["notanAccessDescription"])
|
||||
x509.SubjectInformationAccess(
|
||||
["notanAccessDescription"] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_iter_len(self):
|
||||
sia = x509.SubjectInformationAccess(
|
||||
|
|
@ -3335,11 +3400,11 @@ class TestNameConstraints(object):
|
|||
|
||||
def test_invalid_permitted_subtrees(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.NameConstraints("badpermitted", None)
|
||||
x509.NameConstraints("badpermitted", None) # type:ignore[arg-type]
|
||||
|
||||
def test_invalid_excluded_subtrees(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.NameConstraints(None, "badexcluded")
|
||||
x509.NameConstraints(None, "badexcluded") # type:ignore[arg-type]
|
||||
|
||||
def test_no_subtrees(self):
|
||||
with pytest.raises(ValueError):
|
||||
|
|
@ -3577,26 +3642,34 @@ class TestNameConstraintsExtension(object):
|
|||
class TestDistributionPoint(object):
|
||||
def test_distribution_point_full_name_not_general_names(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.DistributionPoint(["notgn"], None, None, None)
|
||||
x509.DistributionPoint(
|
||||
["notgn"], None, None, None # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_distribution_point_relative_name_not_name(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.DistributionPoint(None, "notname", None, None)
|
||||
x509.DistributionPoint(
|
||||
None, "notname", None, None # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_distribution_point_full_and_relative_not_none(self):
|
||||
with pytest.raises(ValueError):
|
||||
x509.DistributionPoint("data", "notname", None, None)
|
||||
x509.DistributionPoint(
|
||||
"data", "notname", None, None # type:ignore[arg-type]
|
||||
)
|
||||
|
||||
def test_crl_issuer_not_general_names(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.DistributionPoint(None, None, None, ["notgn"])
|
||||
x509.DistributionPoint(
|
||||
None, None, None, ["notgn"] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_reason_not_reasonflags(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.DistributionPoint(
|
||||
[x509.UniformResourceIdentifier("http://crypt.og/crl")],
|
||||
None,
|
||||
frozenset(["notreasonflags"]),
|
||||
frozenset(["notreasonflags"]), # type:ignore[list-item]
|
||||
None,
|
||||
)
|
||||
|
||||
|
|
@ -3605,7 +3678,7 @@ class TestDistributionPoint(object):
|
|||
x509.DistributionPoint(
|
||||
[x509.UniformResourceIdentifier("http://crypt.og/crl")],
|
||||
None,
|
||||
[x509.ReasonFlags.ca_compromise],
|
||||
[x509.ReasonFlags.ca_compromise], # type:ignore[arg-type]
|
||||
None,
|
||||
)
|
||||
|
||||
|
|
@ -3785,7 +3858,9 @@ class TestDistributionPoint(object):
|
|||
class TestFreshestCRL(object):
|
||||
def test_invalid_distribution_points(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.FreshestCRL(["notadistributionpoint"])
|
||||
x509.FreshestCRL(
|
||||
["notadistributionpoint"] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_iter_len(self):
|
||||
fcrl = x509.FreshestCRL(
|
||||
|
|
@ -4018,7 +4093,9 @@ class TestFreshestCRL(object):
|
|||
class TestCRLDistributionPoints(object):
|
||||
def test_invalid_distribution_points(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.CRLDistributionPoints(["notadistributionpoint"])
|
||||
x509.CRLDistributionPoints(
|
||||
["notadistributionpoint"], # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_iter_len(self):
|
||||
cdp = x509.CRLDistributionPoints(
|
||||
|
|
@ -4646,7 +4723,7 @@ class TestOCSPNoCheckExtension(object):
|
|||
class TestInhibitAnyPolicy(object):
|
||||
def test_not_int(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.InhibitAnyPolicy("notint")
|
||||
x509.InhibitAnyPolicy("notint") # type:ignore[arg-type]
|
||||
|
||||
def test_negative_int(self):
|
||||
with pytest.raises(ValueError):
|
||||
|
|
@ -5365,7 +5442,9 @@ class TestSignedCertificateTimestamps(object):
|
|||
class TestPrecertificateSignedCertificateTimestampsExtension(object):
|
||||
def test_init(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.PrecertificateSignedCertificateTimestamps([object()])
|
||||
x509.PrecertificateSignedCertificateTimestamps(
|
||||
[object()] # type:ignore[list-item]
|
||||
)
|
||||
|
||||
def test_repr(self):
|
||||
assert repr(x509.PrecertificateSignedCertificateTimestamps([])) == (
|
||||
|
|
@ -5566,7 +5645,7 @@ class TestInvalidExtension(object):
|
|||
class TestOCSPNonce(object):
|
||||
def test_non_bytes(self):
|
||||
with pytest.raises(TypeError):
|
||||
x509.OCSPNonce(38)
|
||||
x509.OCSPNonce(38) # type:ignore[arg-type]
|
||||
|
||||
def test_eq(self):
|
||||
nonce1 = x509.OCSPNonce(b"0" * 5)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ __summary__ = "Test vectors for the cryptography package."
|
|||
|
||||
__uri__ = "https://github.com/pyca/cryptography"
|
||||
|
||||
__version__ = "3.4.4"
|
||||
__version__ = "3.4.5"
|
||||
|
||||
__author__ = "The Python Cryptographic Authority and individual contributors"
|
||||
__email__ = "cryptography-dev@python.org"
|
||||
|
|
|
|||
Loading…
Reference in a new issue