py2docfx 0.1.9.dev1927679__py3-none-any.whl → 0.1.9.dev1929293__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py2docfx/__main__.py +18 -2
- py2docfx/convert_prepare/git.py +8 -5
- py2docfx/docfx_yaml/logger.py +13 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/__about__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/cryptography/__init__.py +13 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/fernet.py +8 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/_oid.py +2 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/backends/openssl/backend.py +8 -14
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py +10 -7
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py +12 -6
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/kdf/argon2.py +13 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py +3 -64
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/padding.py +3 -24
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py +33 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py +9 -1
- py2docfx/venv/venv1/Lib/site-packages/cryptography/hazmat/primitives/twofactor/totp.py +5 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/x509/__init__.py +8 -0
- py2docfx/venv/venv1/Lib/site-packages/cryptography/x509/base.py +4 -415
- py2docfx/venv/venv1/Lib/site-packages/cryptography/x509/certificate_transparency.py +1 -63
- py2docfx/venv/venv1/Lib/site-packages/cryptography/x509/extensions.py +286 -5
- py2docfx/venv/venv1/Lib/site-packages/cryptography/x509/ocsp.py +4 -338
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/__init__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/any.py +39 -0
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/any_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/api_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/compiler/plugin_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/descriptor_pb2.py +108 -108
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/duration.py +100 -0
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/duration_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/empty_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/field_mask_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/internal/python_message.py +7 -4
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/internal/well_known_types.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/pyext/cpp_message.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/runtime_version.py +16 -9
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/service.py +4 -4
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/source_context_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/struct_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/text_format.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/timestamp.py +112 -0
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/timestamp_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/type_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/google/protobuf/wrappers_pb2.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/jwt/__init__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/jwt/api_jwt.py +3 -3
- {py2docfx-0.1.9.dev1927679.dist-info → py2docfx-0.1.9.dev1929293.dist-info}/METADATA +1 -1
- {py2docfx-0.1.9.dev1927679.dist-info → py2docfx-0.1.9.dev1929293.dist-info}/RECORD +49 -45
- {py2docfx-0.1.9.dev1927679.dist-info → py2docfx-0.1.9.dev1929293.dist-info}/WHEEL +0 -0
- {py2docfx-0.1.9.dev1927679.dist-info → py2docfx-0.1.9.dev1929293.dist-info}/top_level.txt +0 -0
py2docfx/__main__.py
CHANGED
@@ -3,6 +3,7 @@ import asyncio
|
|
3
3
|
import argparse
|
4
4
|
import logging
|
5
5
|
import os
|
6
|
+
import stat
|
6
7
|
import sys
|
7
8
|
import shutil
|
8
9
|
|
@@ -16,6 +17,8 @@ from py2docfx.convert_prepare.params import load_file_params, load_command_param
|
|
16
17
|
from py2docfx.convert_prepare.package_info import PackageInfo
|
17
18
|
import py2docfx.convert_prepare.environment as py2docfxEnvironment
|
18
19
|
|
20
|
+
os.chdir(PACKAGE_ROOT)
|
21
|
+
|
19
22
|
def get_parser() -> argparse.ArgumentParser:
|
20
23
|
parser = argparse.ArgumentParser(
|
21
24
|
description=(
|
@@ -310,10 +313,24 @@ def prepare_out_dir(output_root: str | os.PathLike) -> os.PathLike | None:
|
|
310
313
|
else:
|
311
314
|
return None
|
312
315
|
|
316
|
+
def on_rm_error( func, path, exc_info):
|
317
|
+
# path contains the path of the file that couldn't be removed
|
318
|
+
# let's just assume that it's read-only and unlink it.
|
319
|
+
os.chmod(path, stat.S_IWRITE)
|
320
|
+
os.unlink(path)
|
321
|
+
|
322
|
+
def remove_folder(folder: str | os.PathLike) -> None:
|
323
|
+
try:
|
324
|
+
shutil.rmtree(folder)
|
325
|
+
except PermissionError:
|
326
|
+
shutil.rmtree(folder, ignore_errors=False, onerror=on_rm_error)
|
327
|
+
if os.path.exists(folder):
|
328
|
+
raise ValueError(f"Failed to remove folder {folder}")
|
329
|
+
|
313
330
|
def temp_folder_clean_up(folder_list: list[str | os.PathLike]) -> None:
|
314
331
|
for folder in folder_list:
|
315
332
|
if os.path.exists(folder):
|
316
|
-
|
333
|
+
remove_folder(folder)
|
317
334
|
|
318
335
|
def decide_global_log_level(verbose: bool, show_warning: bool) -> None:
|
319
336
|
if verbose and show_warning:
|
@@ -347,7 +364,6 @@ def main(argv) -> int:
|
|
347
364
|
py2docfx_logger.info(msg)
|
348
365
|
|
349
366
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),'docfx_yaml'))
|
350
|
-
os.chdir(PACKAGE_ROOT)
|
351
367
|
output_doc_folder = prepare_out_dir(output_root)
|
352
368
|
|
353
369
|
try:
|
py2docfx/convert_prepare/git.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import re
|
2
2
|
import subprocess
|
3
3
|
|
4
|
-
from py2docfx.docfx_yaml.logger import get_logger
|
4
|
+
from py2docfx.docfx_yaml.logger import get_logger, log_git_clone_subprocess_ouput
|
5
5
|
|
6
6
|
repoMap = {}
|
7
7
|
|
@@ -57,7 +57,8 @@ def clone(repo_location, branch, folder, extra_token=None):
|
|
57
57
|
extra_token
|
58
58
|
),
|
59
59
|
]
|
60
|
-
subprocess.run(clone_params, check=True)
|
60
|
+
output = subprocess.run(clone_params, check=True, capture_output=True, text=True)
|
61
|
+
log_git_clone_subprocess_ouput(output, py2docfx_logger)
|
61
62
|
repoMap[pureURL] = folder
|
62
63
|
msg = "<CI INFO>: Repo {} successfully cloned in {}...".format(
|
63
64
|
repo_location, repoMap[pureURL]
|
@@ -144,7 +145,7 @@ def checkout(folder, branch):
|
|
144
145
|
if "* {}".format(branch) not in branches:
|
145
146
|
# branch is not exactly current branch
|
146
147
|
if branch not in branches:
|
147
|
-
subprocess.run(
|
148
|
+
output = subprocess.run(
|
148
149
|
[
|
149
150
|
"git",
|
150
151
|
"-C",
|
@@ -153,10 +154,12 @@ def checkout(folder, branch):
|
|
153
154
|
"--quiet",
|
154
155
|
remote,
|
155
156
|
"{}:{}".format(branch, branch),
|
156
|
-
]
|
157
|
+
], capture_output=True, text=True
|
157
158
|
)
|
159
|
+
log_subprocess_ouput(output, py2docfx_logger)
|
158
160
|
|
159
|
-
subprocess.run(["git", "-C", folder, "checkout", "--quiet", branch])
|
161
|
+
output = subprocess.run(["git", "-C", folder, "checkout", "--quiet", branch], check=True, capture_output=True, text=True)
|
162
|
+
log_subprocess_ouput(output, py2docfx_logger)
|
160
163
|
msg = "<CI INFO>: Switched to branch {}.".format(branch)
|
161
164
|
py2docfx_logger.info(msg)
|
162
165
|
|
py2docfx/docfx_yaml/logger.py
CHANGED
@@ -71,6 +71,19 @@ def log_subprocess_ouput(subprocess_out: subprocess.CompletedProcess, logger: lo
|
|
71
71
|
logger.error(f"Subprocess failed with return code {subprocess_out.returncode}")
|
72
72
|
raise RuntimeError()
|
73
73
|
|
74
|
+
def log_git_clone_subprocess_ouput(subprocess_out: subprocess.CompletedProcess, logger: logging.Logger):
|
75
|
+
if subprocess_out.stdout:
|
76
|
+
logger.info(subprocess_out.stdout)
|
77
|
+
if subprocess_out.stderr:
|
78
|
+
msgs = subprocess_out.stderr.split('\n')
|
79
|
+
for msg in msgs:
|
80
|
+
if msg is None or msg == "":
|
81
|
+
continue
|
82
|
+
logger.info(msg)
|
83
|
+
if subprocess_out.returncode != 0:
|
84
|
+
logger.error(f"Subprocess failed with return code {subprocess_out.returncode}")
|
85
|
+
raise RuntimeError()
|
86
|
+
|
74
87
|
def counts_errors_warnings(log_file_path):
|
75
88
|
error_count = 0
|
76
89
|
warning_count = 0
|
@@ -4,6 +4,10 @@
|
|
4
4
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
|
+
import sys
|
8
|
+
import warnings
|
9
|
+
|
10
|
+
from cryptography import utils
|
7
11
|
from cryptography.__about__ import __author__, __copyright__, __version__
|
8
12
|
|
9
13
|
__all__ = [
|
@@ -11,3 +15,12 @@ __all__ = [
|
|
11
15
|
"__copyright__",
|
12
16
|
"__version__",
|
13
17
|
]
|
18
|
+
|
19
|
+
if sys.version_info[:2] == (3, 7):
|
20
|
+
warnings.warn(
|
21
|
+
"Python 3.7 is no longer supported by the Python core team "
|
22
|
+
"and support for it is deprecated in cryptography. A future "
|
23
|
+
"release of cryptography will remove support for Python 3.7.",
|
24
|
+
utils.CryptographyDeprecationWarning,
|
25
|
+
stacklevel=2,
|
26
|
+
)
|
@@ -213,3 +213,11 @@ class MultiFernet:
|
|
213
213
|
except InvalidToken:
|
214
214
|
pass
|
215
215
|
raise InvalidToken
|
216
|
+
|
217
|
+
def extract_timestamp(self, msg: bytes | str) -> int:
|
218
|
+
for f in self._fernets:
|
219
|
+
try:
|
220
|
+
return f.extract_timestamp(msg)
|
221
|
+
except InvalidToken:
|
222
|
+
pass
|
223
|
+
raise InvalidToken
|
@@ -39,6 +39,7 @@ class ExtensionOID:
|
|
39
39
|
PRECERT_POISON = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3")
|
40
40
|
SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5")
|
41
41
|
MS_CERTIFICATE_TEMPLATE = ObjectIdentifier("1.3.6.1.4.1.311.21.7")
|
42
|
+
ADMISSIONS = ObjectIdentifier("1.3.36.8.3.3")
|
42
43
|
|
43
44
|
|
44
45
|
class OCSPExtensionOID:
|
@@ -284,6 +285,7 @@ _OID_NAMES = {
|
|
284
285
|
),
|
285
286
|
ExtensionOID.PRECERT_POISON: "ctPoison",
|
286
287
|
ExtensionOID.MS_CERTIFICATE_TEMPLATE: "msCertificateTemplate",
|
288
|
+
ExtensionOID.ADMISSIONS: "Admissions",
|
287
289
|
CRLEntryExtensionOID.CRL_REASON: "cRLReason",
|
288
290
|
CRLEntryExtensionOID.INVALIDITY_DATE: "invalidityDate",
|
289
291
|
CRLEntryExtensionOID.CERTIFICATE_ISSUER: "certificateIssuer",
|
@@ -101,23 +101,11 @@ class Backend:
|
|
101
101
|
def openssl_version_number(self) -> int:
|
102
102
|
return rust_openssl.openssl_version()
|
103
103
|
|
104
|
-
def _evp_md_from_algorithm(self, algorithm: hashes.HashAlgorithm):
|
105
|
-
if algorithm.name in ("blake2b", "blake2s"):
|
106
|
-
alg = f"{algorithm.name}{algorithm.digest_size * 8}".encode(
|
107
|
-
"ascii"
|
108
|
-
)
|
109
|
-
else:
|
110
|
-
alg = algorithm.name.encode("ascii")
|
111
|
-
|
112
|
-
evp_md = self._lib.EVP_get_digestbyname(alg)
|
113
|
-
return evp_md
|
114
|
-
|
115
104
|
def hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
|
116
105
|
if self._fips_enabled and not isinstance(algorithm, self._fips_hashes):
|
117
106
|
return False
|
118
107
|
|
119
|
-
|
120
|
-
return evp_md != self._ffi.NULL
|
108
|
+
return rust_openssl.hashes.hash_supported(algorithm)
|
121
109
|
|
122
110
|
def signature_hash_supported(
|
123
111
|
self, algorithm: hashes.HashAlgorithm
|
@@ -132,7 +120,13 @@ class Backend:
|
|
132
120
|
if self._fips_enabled:
|
133
121
|
return False
|
134
122
|
else:
|
135
|
-
return hasattr(rust_openssl.kdf, "
|
123
|
+
return hasattr(rust_openssl.kdf.Scrypt, "derive")
|
124
|
+
|
125
|
+
def argon2_supported(self) -> bool:
|
126
|
+
if self._fips_enabled:
|
127
|
+
return False
|
128
|
+
else:
|
129
|
+
return hasattr(rust_openssl.kdf.Argon2id, "derive")
|
136
130
|
|
137
131
|
def hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool:
|
138
132
|
# FIPS mode still allows SHA1 for HMAC
|
@@ -5,6 +5,7 @@
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
7
|
import abc
|
8
|
+
import random
|
8
9
|
import typing
|
9
10
|
from math import gcd
|
10
11
|
|
@@ -212,9 +213,8 @@ def rsa_recover_private_exponent(e: int, p: int, q: int) -> int:
|
|
212
213
|
|
213
214
|
|
214
215
|
# Controls the number of iterations rsa_recover_prime_factors will perform
|
215
|
-
# to obtain the prime factors.
|
216
|
-
|
217
|
-
_MAX_RECOVERY_ATTEMPTS = 1000
|
216
|
+
# to obtain the prime factors.
|
217
|
+
_MAX_RECOVERY_ATTEMPTS = 500
|
218
218
|
|
219
219
|
|
220
220
|
def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]:
|
@@ -222,6 +222,9 @@ def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]:
|
|
222
222
|
Compute factors p and q from the private exponent d. We assume that n has
|
223
223
|
no more than two factors. This function is adapted from code in PyCrypto.
|
224
224
|
"""
|
225
|
+
# reject invalid values early
|
226
|
+
if 17 != pow(17, e * d, n):
|
227
|
+
raise ValueError("n, d, e don't match")
|
225
228
|
# See 8.2.2(i) in Handbook of Applied Cryptography.
|
226
229
|
ktot = d * e - 1
|
227
230
|
# The quantity d*e-1 is a multiple of phi(n), even,
|
@@ -235,8 +238,10 @@ def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]:
|
|
235
238
|
# See "Digitalized Signatures and Public Key Functions as Intractable
|
236
239
|
# as Factorization", M. Rabin, 1979
|
237
240
|
spotted = False
|
238
|
-
|
239
|
-
while not spotted and
|
241
|
+
tries = 0
|
242
|
+
while not spotted and tries < _MAX_RECOVERY_ATTEMPTS:
|
243
|
+
a = random.randint(2, n - 1)
|
244
|
+
tries += 1
|
240
245
|
k = t
|
241
246
|
# Cycle through all values a^{t*2^i}=a^k
|
242
247
|
while k < ktot:
|
@@ -249,8 +254,6 @@ def rsa_recover_prime_factors(n: int, e: int, d: int) -> tuple[int, int]:
|
|
249
254
|
spotted = True
|
250
255
|
break
|
251
256
|
k *= 2
|
252
|
-
# This value was not any good... let's try another!
|
253
|
-
a += 2
|
254
257
|
if not spotted:
|
255
258
|
raise ValueError("Unable to compute factors p and q from exponent d.")
|
256
259
|
# Found !
|
@@ -82,7 +82,8 @@ utils.deprecated(
|
|
82
82
|
__name__,
|
83
83
|
"ARC4 has been moved to "
|
84
84
|
"cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and "
|
85
|
-
"will be removed from
|
85
|
+
"will be removed from "
|
86
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.",
|
86
87
|
utils.DeprecatedIn43,
|
87
88
|
name="ARC4",
|
88
89
|
)
|
@@ -93,7 +94,8 @@ utils.deprecated(
|
|
93
94
|
__name__,
|
94
95
|
"TripleDES has been moved to "
|
95
96
|
"cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and "
|
96
|
-
"will be removed from
|
97
|
+
"will be removed from "
|
98
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.",
|
97
99
|
utils.DeprecatedIn43,
|
98
100
|
name="TripleDES",
|
99
101
|
)
|
@@ -103,7 +105,8 @@ utils.deprecated(
|
|
103
105
|
__name__,
|
104
106
|
"Blowfish has been moved to "
|
105
107
|
"cryptography.hazmat.decrepit.ciphers.algorithms.Blowfish and "
|
106
|
-
"will be removed from
|
108
|
+
"will be removed from "
|
109
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.",
|
107
110
|
utils.DeprecatedIn37,
|
108
111
|
name="Blowfish",
|
109
112
|
)
|
@@ -114,7 +117,8 @@ utils.deprecated(
|
|
114
117
|
__name__,
|
115
118
|
"CAST5 has been moved to "
|
116
119
|
"cryptography.hazmat.decrepit.ciphers.algorithms.CAST5 and "
|
117
|
-
"will be removed from
|
120
|
+
"will be removed from "
|
121
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.",
|
118
122
|
utils.DeprecatedIn37,
|
119
123
|
name="CAST5",
|
120
124
|
)
|
@@ -125,7 +129,8 @@ utils.deprecated(
|
|
125
129
|
__name__,
|
126
130
|
"IDEA has been moved to "
|
127
131
|
"cryptography.hazmat.decrepit.ciphers.algorithms.IDEA and "
|
128
|
-
"will be removed from
|
132
|
+
"will be removed from "
|
133
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.",
|
129
134
|
utils.DeprecatedIn37,
|
130
135
|
name="IDEA",
|
131
136
|
)
|
@@ -136,7 +141,8 @@ utils.deprecated(
|
|
136
141
|
__name__,
|
137
142
|
"SEED has been moved to "
|
138
143
|
"cryptography.hazmat.decrepit.ciphers.algorithms.SEED and "
|
139
|
-
"will be removed from
|
144
|
+
"will be removed from "
|
145
|
+
"cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.",
|
140
146
|
utils.DeprecatedIn37,
|
141
147
|
name="SEED",
|
142
148
|
)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file is dual licensed under the terms of the Apache License, Version
|
2
|
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
3
|
+
# for complete details.
|
4
|
+
|
5
|
+
from __future__ import annotations
|
6
|
+
|
7
|
+
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
8
|
+
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
9
|
+
|
10
|
+
Argon2id = rust_openssl.kdf.Argon2id
|
11
|
+
KeyDerivationFunction.register(Argon2id)
|
12
|
+
|
13
|
+
__all__ = ["Argon2id"]
|
@@ -5,76 +5,15 @@
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
7
|
import sys
|
8
|
-
import typing
|
9
8
|
|
10
|
-
from cryptography import utils
|
11
|
-
from cryptography.exceptions import (
|
12
|
-
AlreadyFinalized,
|
13
|
-
InvalidKey,
|
14
|
-
UnsupportedAlgorithm,
|
15
|
-
)
|
16
9
|
from cryptography.hazmat.bindings._rust import openssl as rust_openssl
|
17
|
-
from cryptography.hazmat.primitives import constant_time
|
18
10
|
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
|
19
11
|
|
20
12
|
# This is used by the scrypt tests to skip tests that require more memory
|
21
13
|
# than the MEM_LIMIT
|
22
14
|
_MEM_LIMIT = sys.maxsize // 2
|
23
15
|
|
16
|
+
Scrypt = rust_openssl.kdf.Scrypt
|
17
|
+
KeyDerivationFunction.register(Scrypt)
|
24
18
|
|
25
|
-
|
26
|
-
def __init__(
|
27
|
-
self,
|
28
|
-
salt: bytes,
|
29
|
-
length: int,
|
30
|
-
n: int,
|
31
|
-
r: int,
|
32
|
-
p: int,
|
33
|
-
backend: typing.Any = None,
|
34
|
-
):
|
35
|
-
from cryptography.hazmat.backends.openssl.backend import (
|
36
|
-
backend as ossl,
|
37
|
-
)
|
38
|
-
|
39
|
-
if not ossl.scrypt_supported():
|
40
|
-
raise UnsupportedAlgorithm(
|
41
|
-
"This version of OpenSSL does not support scrypt"
|
42
|
-
)
|
43
|
-
self._length = length
|
44
|
-
utils._check_bytes("salt", salt)
|
45
|
-
if n < 2 or (n & (n - 1)) != 0:
|
46
|
-
raise ValueError("n must be greater than 1 and be a power of 2.")
|
47
|
-
|
48
|
-
if r < 1:
|
49
|
-
raise ValueError("r must be greater than or equal to 1.")
|
50
|
-
|
51
|
-
if p < 1:
|
52
|
-
raise ValueError("p must be greater than or equal to 1.")
|
53
|
-
|
54
|
-
self._used = False
|
55
|
-
self._salt = salt
|
56
|
-
self._n = n
|
57
|
-
self._r = r
|
58
|
-
self._p = p
|
59
|
-
|
60
|
-
def derive(self, key_material: bytes) -> bytes:
|
61
|
-
if self._used:
|
62
|
-
raise AlreadyFinalized("Scrypt instances can only be used once.")
|
63
|
-
self._used = True
|
64
|
-
|
65
|
-
utils._check_byteslike("key_material", key_material)
|
66
|
-
|
67
|
-
return rust_openssl.kdf.derive_scrypt(
|
68
|
-
key_material,
|
69
|
-
self._salt,
|
70
|
-
self._n,
|
71
|
-
self._r,
|
72
|
-
self._p,
|
73
|
-
_MEM_LIMIT,
|
74
|
-
self._length,
|
75
|
-
)
|
76
|
-
|
77
|
-
def verify(self, key_material: bytes, expected_key: bytes) -> None:
|
78
|
-
derived_key = self.derive(key_material)
|
79
|
-
if not constant_time.bytes_eq(derived_key, expected_key):
|
80
|
-
raise InvalidKey("Keys do not match.")
|
19
|
+
__all__ = ["Scrypt"]
|
@@ -11,8 +11,8 @@ from cryptography import utils
|
|
11
11
|
from cryptography.exceptions import AlreadyFinalized
|
12
12
|
from cryptography.hazmat.bindings._rust import (
|
13
13
|
PKCS7PaddingContext,
|
14
|
+
PKCS7UnpaddingContext,
|
14
15
|
check_ansix923_padding,
|
15
|
-
check_pkcs7_padding,
|
16
16
|
)
|
17
17
|
|
18
18
|
|
@@ -115,32 +115,11 @@ class PKCS7:
|
|
115
115
|
return PKCS7PaddingContext(self.block_size)
|
116
116
|
|
117
117
|
def unpadder(self) -> PaddingContext:
|
118
|
-
return
|
119
|
-
|
120
|
-
|
121
|
-
class _PKCS7UnpaddingContext(PaddingContext):
|
122
|
-
_buffer: bytes | None
|
123
|
-
|
124
|
-
def __init__(self, block_size: int):
|
125
|
-
self.block_size = block_size
|
126
|
-
# TODO: more copies than necessary, we should use zero-buffer (#193)
|
127
|
-
self._buffer = b""
|
128
|
-
|
129
|
-
def update(self, data: bytes) -> bytes:
|
130
|
-
self._buffer, result = _byte_unpadding_update(
|
131
|
-
self._buffer, data, self.block_size
|
132
|
-
)
|
133
|
-
return result
|
134
|
-
|
135
|
-
def finalize(self) -> bytes:
|
136
|
-
result = _byte_unpadding_check(
|
137
|
-
self._buffer, self.block_size, check_pkcs7_padding
|
138
|
-
)
|
139
|
-
self._buffer = None
|
140
|
-
return result
|
118
|
+
return PKCS7UnpaddingContext(self.block_size)
|
141
119
|
|
142
120
|
|
143
121
|
PaddingContext.register(PKCS7PaddingContext)
|
122
|
+
PaddingContext.register(PKCS7UnpaddingContext)
|
144
123
|
|
145
124
|
|
146
125
|
class ANSIX923:
|
@@ -263,6 +263,11 @@ class PKCS7EnvelopeBuilder:
|
|
263
263
|
return rust_pkcs7.encrypt_and_serialize(self, encoding, options)
|
264
264
|
|
265
265
|
|
266
|
+
pkcs7_decrypt_der = rust_pkcs7.decrypt_der
|
267
|
+
pkcs7_decrypt_pem = rust_pkcs7.decrypt_pem
|
268
|
+
pkcs7_decrypt_smime = rust_pkcs7.decrypt_smime
|
269
|
+
|
270
|
+
|
266
271
|
def _smime_signed_encode(
|
267
272
|
data: bytes, signature: bytes, micalg: str, text_mode: bool
|
268
273
|
) -> bytes:
|
@@ -328,6 +333,34 @@ def _smime_enveloped_encode(data: bytes) -> bytes:
|
|
328
333
|
return m.as_bytes(policy=m.policy.clone(linesep="\n", max_line_length=0))
|
329
334
|
|
330
335
|
|
336
|
+
def _smime_enveloped_decode(data: bytes) -> bytes:
|
337
|
+
m = email.message_from_bytes(data)
|
338
|
+
if m.get_content_type() not in {
|
339
|
+
"application/x-pkcs7-mime",
|
340
|
+
"application/pkcs7-mime",
|
341
|
+
}:
|
342
|
+
raise ValueError("Not an S/MIME enveloped message")
|
343
|
+
return bytes(m.get_payload(decode=True))
|
344
|
+
|
345
|
+
|
346
|
+
def _smime_remove_text_headers(data: bytes) -> bytes:
|
347
|
+
m = email.message_from_bytes(data)
|
348
|
+
# Using get() instead of get_content_type() since it has None as default,
|
349
|
+
# where the latter has "text/plain". Both methods are case-insensitive.
|
350
|
+
content_type = m.get("content-type")
|
351
|
+
if content_type is None:
|
352
|
+
raise ValueError(
|
353
|
+
"Decrypted MIME data has no 'Content-Type' header. "
|
354
|
+
"Please remove the 'Text' option to parse it manually."
|
355
|
+
)
|
356
|
+
if "text/plain" not in content_type:
|
357
|
+
raise ValueError(
|
358
|
+
f"Decrypted MIME data content type is '{content_type}', not "
|
359
|
+
"'text/plain'. Remove the 'Text' option to parse it manually."
|
360
|
+
)
|
361
|
+
return bytes(m.get_payload(decode=True))
|
362
|
+
|
363
|
+
|
331
364
|
class OpenSSLMimePart(email.message.MIMEPart):
|
332
365
|
# A MIMEPart subclass that replicates OpenSSL's behavior of not including
|
333
366
|
# a newline if there are no headers.
|
@@ -67,6 +67,9 @@ class HOTP:
|
|
67
67
|
self._algorithm = algorithm
|
68
68
|
|
69
69
|
def generate(self, counter: int) -> bytes:
|
70
|
+
if not isinstance(counter, int):
|
71
|
+
raise TypeError("Counter parameter must be an integer type.")
|
72
|
+
|
70
73
|
truncated_value = self._dynamic_truncate(counter)
|
71
74
|
hotp = truncated_value % (10**self._length)
|
72
75
|
return "{0:0{1}}".format(hotp, self._length).encode()
|
@@ -77,7 +80,12 @@ class HOTP:
|
|
77
80
|
|
78
81
|
def _dynamic_truncate(self, counter: int) -> int:
|
79
82
|
ctx = hmac.HMAC(self._key, self._algorithm)
|
80
|
-
|
83
|
+
|
84
|
+
try:
|
85
|
+
ctx.update(counter.to_bytes(length=8, byteorder="big"))
|
86
|
+
except OverflowError:
|
87
|
+
raise ValueError(f"Counter must be between 0 and {2 ** 64 - 1}.")
|
88
|
+
|
81
89
|
hmac_value = ctx.finalize()
|
82
90
|
|
83
91
|
offset = hmac_value[len(hmac_value) - 1] & 0b1111
|
@@ -31,6 +31,11 @@ class TOTP:
|
|
31
31
|
)
|
32
32
|
|
33
33
|
def generate(self, time: int | float) -> bytes:
|
34
|
+
if not isinstance(time, (int, float)):
|
35
|
+
raise TypeError(
|
36
|
+
"Time parameter must be an integer type or float type."
|
37
|
+
)
|
38
|
+
|
34
39
|
counter = int(time / self._time_step)
|
35
40
|
return self._hotp.generate(counter)
|
36
41
|
|
@@ -30,6 +30,8 @@ from cryptography.x509.base import (
|
|
30
30
|
)
|
31
31
|
from cryptography.x509.extensions import (
|
32
32
|
AccessDescription,
|
33
|
+
Admission,
|
34
|
+
Admissions,
|
33
35
|
AuthorityInformationAccess,
|
34
36
|
AuthorityKeyIdentifier,
|
35
37
|
BasicConstraints,
|
@@ -55,6 +57,7 @@ from cryptography.x509.extensions import (
|
|
55
57
|
KeyUsage,
|
56
58
|
MSCertificateTemplate,
|
57
59
|
NameConstraints,
|
60
|
+
NamingAuthority,
|
58
61
|
NoticeReference,
|
59
62
|
OCSPAcceptableResponses,
|
60
63
|
OCSPNoCheck,
|
@@ -63,6 +66,7 @@ from cryptography.x509.extensions import (
|
|
63
66
|
PolicyInformation,
|
64
67
|
PrecertificateSignedCertificateTimestamps,
|
65
68
|
PrecertPoison,
|
69
|
+
ProfessionInfo,
|
66
70
|
ReasonFlags,
|
67
71
|
SignedCertificateTimestamps,
|
68
72
|
SubjectAlternativeName,
|
@@ -174,6 +178,8 @@ __all__ = [
|
|
174
178
|
"OID_CA_ISSUERS",
|
175
179
|
"OID_OCSP",
|
176
180
|
"AccessDescription",
|
181
|
+
"Admission",
|
182
|
+
"Admissions",
|
177
183
|
"Attribute",
|
178
184
|
"AttributeNotFound",
|
179
185
|
"Attributes",
|
@@ -216,6 +222,7 @@ __all__ = [
|
|
216
222
|
"NameAttribute",
|
217
223
|
"NameConstraints",
|
218
224
|
"NameOID",
|
225
|
+
"NamingAuthority",
|
219
226
|
"NoticeReference",
|
220
227
|
"OCSPAcceptableResponses",
|
221
228
|
"OCSPNoCheck",
|
@@ -226,6 +233,7 @@ __all__ = [
|
|
226
233
|
"PolicyInformation",
|
227
234
|
"PrecertPoison",
|
228
235
|
"PrecertificateSignedCertificateTimestamps",
|
236
|
+
"ProfessionInfo",
|
229
237
|
"PublicKeyAlgorithmOID",
|
230
238
|
"RFC822Name",
|
231
239
|
"ReasonFlags",
|