cert-utils 1.2.0__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.
Files changed (79) hide show
  1. cert_utils/__init__.py +8 -0
  2. cert_utils/compat/__init__.py +0 -0
  3. cert_utils/compat/cryptography.py +172 -0
  4. cert_utils/compat/openssl.py +860 -0
  5. cert_utils/compat/pyopenssl.py +207 -0
  6. cert_utils/compat/signatures.py +114 -0
  7. cert_utils/conditionals.py +121 -0
  8. cert_utils/convert.py +307 -0
  9. cert_utils/core.py +3075 -0
  10. cert_utils/errors.py +54 -0
  11. cert_utils/letsencrypt-certs/deprecated/e5-cross.pem +26 -0
  12. cert_utils/letsencrypt-certs/deprecated/e5.pem +17 -0
  13. cert_utils/letsencrypt-certs/deprecated/e6-cross.pem +26 -0
  14. cert_utils/letsencrypt-certs/deprecated/e6.pem +17 -0
  15. cert_utils/letsencrypt-certs/deprecated/e7-cross.pem +26 -0
  16. cert_utils/letsencrypt-certs/deprecated/e7.pem +17 -0
  17. cert_utils/letsencrypt-certs/deprecated/e8-cross.pem +26 -0
  18. cert_utils/letsencrypt-certs/deprecated/e8.pem +17 -0
  19. cert_utils/letsencrypt-certs/deprecated/e9-cross.pem +26 -0
  20. cert_utils/letsencrypt-certs/deprecated/e9.pem +17 -0
  21. cert_utils/letsencrypt-certs/deprecated/fakeleintermediatex1.pem +28 -0
  22. cert_utils/letsencrypt-certs/deprecated/fakelerootx1.pem +29 -0
  23. cert_utils/letsencrypt-certs/deprecated/isrg-root-ocsp-x1.pem +28 -0
  24. cert_utils/letsencrypt-certs/deprecated/isrg-root-x1-cross-signed.pem +31 -0
  25. cert_utils/letsencrypt-certs/deprecated/isrg-root-x2-cross-signed.pem +26 -0
  26. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-e1.pem +17 -0
  27. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-e2.pem +17 -0
  28. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-r3-cross-signed.pem +26 -0
  29. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-r3.pem +30 -0
  30. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-r4-cross-signed.pem +26 -0
  31. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-r4.pem +30 -0
  32. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-x1-cross-signed.pem +27 -0
  33. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-x2-cross-signed.pem +27 -0
  34. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-x3-cross-signed.pem +27 -0
  35. cert_utils/letsencrypt-certs/deprecated/lets-encrypt-x4-cross-signed.pem +27 -0
  36. cert_utils/letsencrypt-certs/deprecated/letsencrypt-stg-root-x2-signed-by-x1.pem +27 -0
  37. cert_utils/letsencrypt-certs/deprecated/letsencryptauthorityx1.pem +32 -0
  38. cert_utils/letsencrypt-certs/deprecated/letsencryptauthorityx2.pem +32 -0
  39. cert_utils/letsencrypt-certs/deprecated/letsencryptauthorityx3.pem +32 -0
  40. cert_utils/letsencrypt-certs/deprecated/letsencryptauthorityx4.pem +32 -0
  41. cert_utils/letsencrypt-certs/deprecated/r10.pem +29 -0
  42. cert_utils/letsencrypt-certs/deprecated/r11.pem +29 -0
  43. cert_utils/letsencrypt-certs/deprecated/r12.pem +29 -0
  44. cert_utils/letsencrypt-certs/deprecated/r13.pem +29 -0
  45. cert_utils/letsencrypt-certs/deprecated/r14.pem +29 -0
  46. cert_utils/letsencrypt-certs/deprecated/trustid-x3-root.p7c +0 -0
  47. cert_utils/letsencrypt-certs/deprecated/trustid-x3-root.pem +20 -0
  48. cert_utils/letsencrypt-certs/int-ye1.pem +16 -0
  49. cert_utils/letsencrypt-certs/int-ye2.pem +16 -0
  50. cert_utils/letsencrypt-certs/int-ye3.pem +16 -0
  51. cert_utils/letsencrypt-certs/int-yr1.pem +28 -0
  52. cert_utils/letsencrypt-certs/int-yr2.pem +28 -0
  53. cert_utils/letsencrypt-certs/int-yr3.pem +28 -0
  54. cert_utils/letsencrypt-certs/isrg-root-x2.pem +14 -0
  55. cert_utils/letsencrypt-certs/isrgrootx1.pem +31 -0
  56. cert_utils/letsencrypt-certs/isrgrootx1.pkix +0 -0
  57. cert_utils/letsencrypt-certs/letsencrypt-stg-root-x1.pem +32 -0
  58. cert_utils/letsencrypt-certs/letsencrypt-stg-root-x2.pem +15 -0
  59. cert_utils/letsencrypt-certs/root-x2-by-x1.pem +26 -0
  60. cert_utils/letsencrypt-certs/root-ye-by-x2.pem +17 -0
  61. cert_utils/letsencrypt-certs/root-ye.pem +12 -0
  62. cert_utils/letsencrypt-certs/root-yr-by-x1.pem +34 -0
  63. cert_utils/letsencrypt-certs/root-yr.pem +30 -0
  64. cert_utils/letsencrypt_info/__init__.py +6 -0
  65. cert_utils/letsencrypt_info/certificates.py +1074 -0
  66. cert_utils/letsencrypt_info/rate_limits.py +414 -0
  67. cert_utils/letsencrypt_info/types.py +120 -0
  68. cert_utils/model.py +181 -0
  69. cert_utils/network.py +28 -0
  70. cert_utils/py.typed +0 -0
  71. cert_utils/scripts/__init__.py +0 -0
  72. cert_utils/scripts/cert_info.py +332 -0
  73. cert_utils/utils.py +388 -0
  74. cert_utils-1.2.0.dist-info/METADATA +259 -0
  75. cert_utils-1.2.0.dist-info/RECORD +79 -0
  76. cert_utils-1.2.0.dist-info/WHEEL +5 -0
  77. cert_utils-1.2.0.dist-info/entry_points.txt +2 -0
  78. cert_utils-1.2.0.dist-info/licenses/LICENSE.txt +224 -0
  79. cert_utils-1.2.0.dist-info/top_level.txt +1 -0
cert_utils/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ from .convert import * # noqa: F401, F403
2
+ from .core import * # noqa: F401, F403
3
+ from .model import * # noqa: F401, F403
4
+ from .utils import * # noqa: F401, F403
5
+
6
+ # ==============================================================================
7
+
8
+ __VERSION__ = "1.2.0"
File without changes
@@ -0,0 +1,172 @@
1
+ # stdlib
2
+ import base64
3
+ import binascii
4
+ import hashlib
5
+ from typing import List
6
+ from typing import Optional
7
+ from typing import Tuple
8
+ from typing import TYPE_CHECKING
9
+ from typing import Union
10
+
11
+ # locals
12
+ from .. import conditionals
13
+ from ..utils import CERT_PEM_REGEX
14
+ from ..utils import curve_to_nist
15
+ from ..utils import TECHNOLOGY_RETURN_VALUES
16
+
17
+ if TYPE_CHECKING:
18
+ from cryptography.x509 import Certificate
19
+ from cryptography.x509 import CertificateSigningRequest
20
+ from cryptography.x509.name import Name
21
+
22
+ from ..core import _PublicKeySPKI
23
+ from ..core import _TYPES_CRYPTOGRAPHY_PUBLICKEY
24
+
25
+
26
+ # ==============================================================================
27
+
28
+
29
+ def _format_cryptography_components(
30
+ x509_name: "Name",
31
+ ) -> str:
32
+ """
33
+ :param data: input
34
+
35
+
36
+ `get_components()` is somewhat structured
37
+ the following are valid:
38
+ * [('CN', 'Pebble Intermediate CA 601ea1')]
39
+ * [('C', 'US'), ('O', 'Internet Security Research Group'), ('CN', 'ISRG Root X2')]
40
+ * [('C', 'US'), ('O', 'Internet Security Research Group'), ('CN', 'ISRG Root X1')]
41
+ * [('O', 'Digital Signature Trust Co.'), ('CN', 'DST Root CA X3')]
42
+ cert = openssl_crypto.load_certificate(openssl_crypto.FILETYPE_PEM, cert_pem)
43
+ _issuer = cert.get_issuer().get_components()
44
+ _subject = cert.get_subject().get_components()
45
+ """
46
+ # ";".join(["%s=%s" % (i[0], i[1]) for i in x509_name])
47
+ _out = []
48
+ for attr in x509_name:
49
+ _converted = [i.decode("utf8") if isinstance(i, bytes) else i for i in (attr.rfc4514_attribute_name, attr.value)] # type: ignore[attr-defined]
50
+ _out.append("=".join(_converted))
51
+ out = "\n".join(_out).strip()
52
+ return out
53
+
54
+
55
+ def _cryptography__public_key_technology(
56
+ publickey: "_TYPES_CRYPTOGRAPHY_PUBLICKEY",
57
+ ) -> Optional[TECHNOLOGY_RETURN_VALUES]:
58
+ """
59
+ :param key: key object
60
+ :type key: instance of
61
+ :returns: If the key is valid, it will return a Tuple wherein
62
+ - The first element is the Key's technology (EC, RSA)
63
+ - The second element is a Tuple with the key's type.
64
+ (RSA, (bits, ))
65
+ (EC, (curve_name, ))
66
+ """
67
+ if TYPE_CHECKING:
68
+ assert conditionals.crypto_rsa is not None
69
+ assert conditionals.crypto_ec is not None
70
+ if isinstance(publickey, conditionals.crypto_rsa.RSAPublicKey):
71
+ return ("RSA", (publickey.key_size,))
72
+ elif isinstance(publickey, conditionals.crypto_ec.EllipticCurvePublicKey):
73
+ curve_name = curve_to_nist(publickey.curve.name)
74
+ return ("EC", (curve_name,))
75
+ return None
76
+
77
+
78
+ def _cryptography__public_key_spki_sha256(
79
+ cryptography_publickey: "_PublicKeySPKI",
80
+ as_b64: Optional[bool] = None,
81
+ ) -> str:
82
+ """
83
+ :param cryptography_publickey: a PublicKey from the cryptography package
84
+ :type cryptography_publickey: cryptography.hazmat.backends.openssl.rsa._RSAPublicKey
85
+ :param as_b64: Should the result be returned in Base64 encoding? default None
86
+ :type as_b64: boolean
87
+ :returns: spki_sha256
88
+ :rtype: str
89
+ """
90
+ assert (
91
+ conditionals.crypto_serialization is not None
92
+ ) # nest under `if TYPE_CHECKING` not needed
93
+ _public_bytes = cryptography_publickey.public_bytes( # type: ignore[union-attr]
94
+ conditionals.crypto_serialization.Encoding.DER,
95
+ conditionals.crypto_serialization.PublicFormat.SubjectPublicKeyInfo,
96
+ )
97
+ spki_sha256 = hashlib.sha256(_public_bytes).digest()
98
+ if as_b64:
99
+ spki_sha256 = base64.b64encode(spki_sha256)
100
+ else:
101
+ spki_sha256 = binascii.b2a_hex(spki_sha256)
102
+ spki_sha256 = spki_sha256.upper()
103
+ _spki_sha256 = spki_sha256.decode("utf8")
104
+ return _spki_sha256
105
+
106
+
107
+ def _cryptography__cert_or_req__all_names(
108
+ loaded_cert_or_req: Union["Certificate", "CertificateSigningRequest"],
109
+ ) -> List[str]:
110
+ assert conditionals.cryptography is not None
111
+ cn: Optional[str] = None
112
+ try:
113
+ _cn = loaded_cert_or_req.subject.get_attributes_for_oid(
114
+ conditionals.cryptography.x509.oid.NameOID.COMMON_NAME
115
+ )[0].value
116
+ cn = _cn.decode() if isinstance(_cn, bytes) else _cn
117
+ except IndexError:
118
+ pass
119
+ sans: List[str] = []
120
+ try:
121
+ ext = loaded_cert_or_req.extensions.get_extension_for_oid(
122
+ conditionals.cryptography.x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME
123
+ )
124
+ _sans = ext.value.get_values_for_type(conditionals.cryptography.x509.DNSName) # type: ignore[attr-defined]
125
+ sans = [san.decode() if isinstance(san, bytes) else san for san in _sans]
126
+
127
+ except conditionals.cryptography.x509.ExtensionNotFound:
128
+ pass
129
+ if cn is None:
130
+ return sans
131
+ return [cn] + [d for d in sans if d != cn]
132
+
133
+
134
+ def cryptography__cert_and_chain_from_fullchain(fullchain_pem: str) -> Tuple[str, str]:
135
+ """Split fullchain_pem into cert_pem and chain_pem
136
+
137
+ :param str fullchain_pem: concatenated cert + chain
138
+
139
+ :returns: tuple of string cert_pem and chain_pem
140
+ :rtype: tuple
141
+
142
+ :raises errors.Error: If there are less than 2 certificates in the chain.
143
+
144
+ """
145
+ # First pass: find the boundary of each certificate in the chain.
146
+ # TODO: This will silently skip over any "explanatory text" in between boundaries,
147
+ # which is prohibited by RFC8555.
148
+ if TYPE_CHECKING:
149
+ assert conditionals.cryptography is not None
150
+ assert conditionals.crypto_serialization is not None
151
+
152
+ certs = CERT_PEM_REGEX.findall(fullchain_pem)
153
+ if len(certs) < 2:
154
+ raise ValueError(
155
+ "failed to parse fullchain into cert and chain: "
156
+ + "less than 2 certificates in chain"
157
+ )
158
+
159
+ # Second pass: for each certificate found, parse it using OpenSSL and re-encode it,
160
+ # with the effect of normalizing any encoding variations (e.g. CRLF, whitespace).
161
+ certs_normalized = []
162
+ for cert_pem in certs:
163
+ cert = conditionals.cryptography.x509.load_pem_x509_certificate(
164
+ cert_pem.encode()
165
+ )
166
+ cert_pem = cert.public_bytes(
167
+ conditionals.crypto_serialization.Encoding.PEM
168
+ ).decode()
169
+ certs_normalized.append(cert_pem)
170
+
171
+ # Since each normalized cert has a newline suffix, no extra newlines are required.
172
+ return (certs_normalized[0], "".join(certs_normalized[1:]))