swarmauri_certs_self_signed 0.3.0.dev5__tar.gz → 0.11.0.dev2__tar.gz

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.
@@ -1,25 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swarmauri_certs_self_signed
3
- Version: 0.3.0.dev5
3
+ Version: 0.11.0.dev2
4
4
  Summary: Self-signed certificate builder for Swarmauri
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
7
7
  Keywords: swarmauri,sdk,standards,certs,self,signed,certificates,self-signed-certificates,certificate-builder,development-certificates,x509-format
8
8
  Author: Jacob Stewart
9
9
  Author-email: jacob@swarmauri.com
10
- Requires-Python: >=3.10,<3.13
10
+ Requires-Python: >=3.10,<3.15
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Natural Language :: English
13
- Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
13
  Classifier: Development Status :: 3 - Alpha
18
14
  Classifier: Topic :: Security :: Cryptography
19
15
  Classifier: Intended Audience :: Developers
20
16
  Classifier: Programming Language :: Python
21
17
  Classifier: Programming Language :: Python :: 3
22
18
  Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
23
24
  Provides-Extra: ocsp
24
25
  Requires-Dist: cryptography
25
26
  Requires-Dist: pyopenssl ; extra == "ocsp"
@@ -27,23 +28,21 @@ Requires-Dist: swarmauri_base
27
28
  Requires-Dist: swarmauri_core
28
29
  Description-Content-Type: text/markdown
29
30
 
30
- ![Swarmauri Logo](https://github.com/swarmauri/swarmauri-sdk/blob/3d4d1cfa949399d7019ae9d8f296afba773dfb7f/assets/swarmauri.brand.theme.svg)
31
-
31
+ ![Swarmauri Logo](https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/swarmauri_sdk_brand.png)
32
32
 
33
33
  <p align="center">
34
- <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
35
- <img src="https://img.shields.io/pypi/dm/swarmauri_certs_self_signed" alt="PyPI - Downloads"/></a>
34
+ <a href="https://pepy.tech/project/swarmauri_certs_self_signed/">
35
+ <img src="https://static.pepy.tech/badge/swarmauri_certs_self_signed/month" alt="PyPI - Downloads"/></a>
36
36
  <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_certs_self_signed/">
37
37
  <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_certs_self_signed.svg"/></a>
38
38
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
39
- <img src="https://img.shields.io/pypi/pyversions/swarmauri_certs_self_signed" alt="PyPI - Python Version"/></a>
39
+ <img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
40
40
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
41
41
  <img src="https://img.shields.io/pypi/l/swarmauri_certs_self_signed" alt="PyPI - License"/></a>
42
42
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
43
43
  <img src="https://img.shields.io/pypi/v/swarmauri_certs_self_signed?label=swarmauri_certs_self_signed&color=green" alt="PyPI - swarmauri_certs_self_signed"/></a>
44
- </p>
45
-
46
- ---
44
+ <a href="https://discord.gg/N4UpBuQv8T">
45
+ <img src="https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white" alt="Discord"/></a></p>
47
46
 
48
47
  # Swarmauri Self-Signed Certificate Builder
49
48
 
@@ -123,3 +122,5 @@ This package registers `SelfSignedCertificate` under both the `swarmauri.cert_se
123
122
  If you want to contribute to swarmauri-sdk, read up on our
124
123
  [guidelines for contributing](https://github.com/swarmauri/swarmauri-sdk/blob/master/CONTRIBUTING.md)
125
124
  that will help you get started.
125
+
126
+
@@ -1,20 +1,18 @@
1
- ![Swarmauri Logo](https://github.com/swarmauri/swarmauri-sdk/blob/3d4d1cfa949399d7019ae9d8f296afba773dfb7f/assets/swarmauri.brand.theme.svg)
2
-
1
+ ![Swarmauri Logo](https://raw.githubusercontent.com/swarmauri/swarmauri-sdk/master/assets/swarmauri_sdk_brand.png)
3
2
 
4
3
  <p align="center">
5
- <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
6
- <img src="https://img.shields.io/pypi/dm/swarmauri_certs_self_signed" alt="PyPI - Downloads"/></a>
4
+ <a href="https://pepy.tech/project/swarmauri_certs_self_signed/">
5
+ <img src="https://static.pepy.tech/badge/swarmauri_certs_self_signed/month" alt="PyPI - Downloads"/></a>
7
6
  <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_certs_self_signed/">
8
7
  <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/swarmauri_certs_self_signed.svg"/></a>
9
8
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
10
- <img src="https://img.shields.io/pypi/pyversions/swarmauri_certs_self_signed" alt="PyPI - Python Version"/></a>
9
+ <img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue" alt="PyPI - Python Version"/></a>
11
10
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
12
11
  <img src="https://img.shields.io/pypi/l/swarmauri_certs_self_signed" alt="PyPI - License"/></a>
13
12
  <a href="https://pypi.org/project/swarmauri_certs_self_signed/">
14
13
  <img src="https://img.shields.io/pypi/v/swarmauri_certs_self_signed?label=swarmauri_certs_self_signed&color=green" alt="PyPI - swarmauri_certs_self_signed"/></a>
15
- </p>
16
-
17
- ---
14
+ <a href="https://discord.gg/N4UpBuQv8T">
15
+ <img src="https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white" alt="Discord"/></a></p>
18
16
 
19
17
  # Swarmauri Self-Signed Certificate Builder
20
18
 
@@ -93,4 +91,5 @@ This package registers `SelfSignedCertificate` under both the `swarmauri.cert_se
93
91
 
94
92
  If you want to contribute to swarmauri-sdk, read up on our
95
93
  [guidelines for contributing](https://github.com/swarmauri/swarmauri-sdk/blob/master/CONTRIBUTING.md)
96
- that will help you get started.
94
+ that will help you get started.
95
+
@@ -1,24 +1,25 @@
1
1
  [project]
2
2
  name = "swarmauri_certs_self_signed"
3
- version = "0.3.0.dev5"
3
+ version = "0.11.0.dev2"
4
4
  description = "Self-signed certificate builder for Swarmauri"
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
7
- requires-python = ">=3.10,<3.13"
7
+ requires-python = ">=3.10,<3.15"
8
8
  authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
9
9
  classifiers = [
10
10
  "License :: OSI Approved :: Apache Software License",
11
11
  "Natural Language :: English",
12
- "Programming Language :: Python :: 3.10",
13
- "Programming Language :: Python :: 3.11",
14
- "Programming Language :: Python :: 3.12",
15
- "Programming Language :: Python :: 3.13",
16
12
  "Development Status :: 3 - Alpha",
17
13
  "Topic :: Security :: Cryptography",
18
14
  "Intended Audience :: Developers",
19
15
  "Programming Language :: Python",
20
16
  "Programming Language :: Python :: 3",
21
17
  "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
22
23
  ]
23
24
  dependencies = [
24
25
  "swarmauri_core",
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import ipaddress
3
4
  from datetime import datetime, timedelta, timezone
4
5
  from typing import Any, Dict, Iterable, Mapping, Optional, Sequence
5
6
 
@@ -39,15 +40,21 @@ def _name_from_subject(spec: SubjectSpec) -> x509.Name:
39
40
  if "C" in spec and spec["C"]:
40
41
  rdns.append(x509.NameAttribute(NameOID.COUNTRY_NAME, spec["C"]))
41
42
  if "ST" in spec and spec["ST"]:
42
- rdns.append(x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, spec["ST"]))
43
+ rdns.append(
44
+ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, spec["ST"])
45
+ )
43
46
  if "L" in spec and spec["L"]:
44
47
  rdns.append(x509.NameAttribute(NameOID.LOCALITY_NAME, spec["L"]))
45
48
  if "O" in spec and spec["O"]:
46
49
  rdns.append(x509.NameAttribute(NameOID.ORGANIZATION_NAME, spec["O"]))
47
50
  if "OU" in spec and spec["OU"]:
48
- rdns.append(x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, spec["OU"]))
51
+ rdns.append(
52
+ x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, spec["OU"])
53
+ )
49
54
  if "emailAddress" in spec and spec["emailAddress"]:
50
- rdns.append(x509.NameAttribute(NameOID.EMAIL_ADDRESS, spec["emailAddress"]))
55
+ rdns.append(
56
+ x509.NameAttribute(NameOID.EMAIL_ADDRESS, spec["emailAddress"])
57
+ )
51
58
  if "CN" in spec and spec["CN"]:
52
59
  rdns.append(x509.NameAttribute(NameOID.COMMON_NAME, spec["CN"]))
53
60
 
@@ -57,21 +64,25 @@ def _name_from_subject(spec: SubjectSpec) -> x509.Name:
57
64
  continue
58
65
  rdns.append(
59
66
  x509.NameAttribute(
60
- x509.ObjectIdentifier(k) if k.count(".") >= 2 else NameOID.COMMON_NAME,
67
+ x509.ObjectIdentifier(k)
68
+ if k.count(".") >= 2
69
+ else NameOID.COMMON_NAME,
61
70
  v,
62
71
  )
63
72
  )
64
73
  return x509.Name(rdns)
65
74
 
66
75
 
67
- def _san_from_spec(san: Optional[AltNameSpec]) -> Optional[x509.SubjectAlternativeName]:
76
+ def _san_from_spec(
77
+ san: Optional[AltNameSpec],
78
+ ) -> Optional[x509.SubjectAlternativeName]:
68
79
  if not san:
69
80
  return None
70
81
  gns = []
71
82
  for d in san.get("dns") or []:
72
83
  gns.append(x509.DNSName(d))
73
84
  for ip in san.get("ip") or []:
74
- gns.append(x509.IPAddress(x509.ipaddress.ip_address(ip))) # type: ignore[attr-defined]
85
+ gns.append(x509.IPAddress(ipaddress.ip_address(ip)))
75
86
  for uri in san.get("uri") or []:
76
87
  gns.append(x509.UniformResourceIdentifier(uri))
77
88
  for email in san.get("email") or []:
@@ -120,7 +131,9 @@ def _bc_from_spec(
120
131
 
121
132
 
122
133
  def _choose_sig_hash(private_key) -> Optional[hashes.HashAlgorithm]:
123
- if isinstance(private_key, (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)):
134
+ if isinstance(
135
+ private_key, (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)
136
+ ):
124
137
  return None
125
138
  return hashes.SHA256()
126
139
 
@@ -129,7 +142,9 @@ def _choose_sig_hash(private_key) -> Optional[hashes.HashAlgorithm]:
129
142
  class SelfSignedCertificate(CertServiceBase):
130
143
  """Minimal self-signed certificate builder exposed as a cert service."""
131
144
 
132
- subject: SubjectSpec = Field(default_factory=lambda: SubjectSpec(CN="localhost"))
145
+ subject: SubjectSpec = Field(
146
+ default_factory=lambda: SubjectSpec(CN="localhost")
147
+ )
133
148
  san: Optional[AltNameSpec] = None
134
149
  extensions: Optional[CertExtensionSpec] = None
135
150
  not_before: Optional[int] = None
@@ -163,7 +178,10 @@ class SelfSignedCertificate(CertServiceBase):
163
178
  ) -> bytes:
164
179
  if key.material is None:
165
180
  raise ValueError(
166
- "Self-signed issuance requires a private key in KeyRef.material (PEM)."
181
+ (
182
+ "Self-signed issuance requires a private key in "
183
+ "KeyRef.material (PEM)."
184
+ )
167
185
  )
168
186
 
169
187
  pwd = password if password is not None else self.password
@@ -178,7 +196,9 @@ class SelfSignedCertificate(CertServiceBase):
178
196
  else key.tags["passphrase"]
179
197
  )
180
198
 
181
- private_key = serialization.load_pem_private_key(key.material, password=pwd)
199
+ private_key = serialization.load_pem_private_key(
200
+ key.material, password=pwd
201
+ )
182
202
  public_key = private_key.public_key()
183
203
 
184
204
  subject_spec = subject or self.subject
@@ -196,11 +216,17 @@ class SelfSignedCertificate(CertServiceBase):
196
216
  if na_epoch is not None:
197
217
  na = datetime.fromtimestamp(int(na_epoch), tz=timezone.utc)
198
218
  else:
199
- life = lifetime_days if lifetime_days is not None else self.lifetime_days
219
+ life = (
220
+ lifetime_days
221
+ if lifetime_days is not None
222
+ else self.lifetime_days
223
+ )
200
224
  na = nb + timedelta(days=int(life))
201
225
 
202
226
  serial_number = (
203
- serial if serial is not None else self.serial or x509.random_serial_number()
227
+ serial
228
+ if serial is not None
229
+ else self.serial or x509.random_serial_number()
204
230
  )
205
231
 
206
232
  builder = (
@@ -215,7 +241,11 @@ class SelfSignedCertificate(CertServiceBase):
215
241
 
216
242
  ext_spec = extensions if extensions is not None else self.extensions
217
243
 
218
- bc = _bc_from_spec(ext_spec.get("basic_constraints")) if ext_spec else None
244
+ bc = (
245
+ _bc_from_spec(ext_spec.get("basic_constraints"))
246
+ if ext_spec
247
+ else None
248
+ )
219
249
  if bc:
220
250
  builder = builder.add_extension(bc, critical=True)
221
251
 
@@ -223,7 +253,11 @@ class SelfSignedCertificate(CertServiceBase):
223
253
  if ku:
224
254
  builder = builder.add_extension(ku, critical=True)
225
255
 
226
- eku = _eku_from_spec(ext_spec.get("extended_key_usage")) if ext_spec else None
256
+ eku = (
257
+ _eku_from_spec(ext_spec.get("extended_key_usage"))
258
+ if ext_spec
259
+ else None
260
+ )
227
261
  if eku:
228
262
  builder = builder.add_extension(eku, critical=False)
229
263
 
@@ -243,16 +277,20 @@ class SelfSignedCertificate(CertServiceBase):
243
277
 
244
278
  if ext_spec and ext_spec.get("name_constraints"):
245
279
  nc = ext_spec["name_constraints"]
246
- permitted_dns = [x509.DNSName(d) for d in (nc.get("permitted_dns") or [])]
247
- excluded_dns = [x509.DNSName(d) for d in (nc.get("excluded_dns") or [])]
280
+ permitted_dns = [
281
+ x509.DNSName(d) for d in (nc.get("permitted_dns") or [])
282
+ ]
283
+ excluded_dns = [
284
+ x509.DNSName(d) for d in (nc.get("excluded_dns") or [])
285
+ ]
248
286
  permitted_ip = [
249
- x509.IPAddress(x509.ipaddress.ip_address(ip))
287
+ x509.IPAddress(ipaddress.ip_network(ip))
250
288
  for ip in (nc.get("permitted_ip") or [])
251
- ] # type: ignore[attr-defined]
289
+ ]
252
290
  excluded_ip = [
253
- x509.IPAddress(x509.ipaddress.ip_address(ip))
291
+ x509.IPAddress(ipaddress.ip_network(ip))
254
292
  for ip in (nc.get("excluded_ip") or [])
255
- ] # type: ignore[attr-defined]
293
+ ]
256
294
  permitted_uri = [
257
295
  x509.UniformResourceIdentifier(u)
258
296
  for u in (nc.get("permitted_uri") or [])
@@ -271,11 +309,17 @@ class SelfSignedCertificate(CertServiceBase):
271
309
  builder = builder.add_extension(
272
310
  x509.NameConstraints(
273
311
  permitted_subtrees=(
274
- permitted_dns + permitted_ip + permitted_uri + permitted_email
312
+ permitted_dns
313
+ + permitted_ip
314
+ + permitted_uri
315
+ + permitted_email
275
316
  )
276
317
  or None,
277
318
  excluded_subtrees=(
278
- excluded_dns + excluded_ip + excluded_uri + excluded_email
319
+ excluded_dns
320
+ + excluded_ip
321
+ + excluded_uri
322
+ + excluded_email
279
323
  )
280
324
  or None,
281
325
  ),
@@ -350,7 +394,10 @@ class SelfSignedCertificate(CertServiceBase):
350
394
  subject_alt_name=san,
351
395
  )
352
396
  return cls(
353
- subject=subject, san=san, extensions=ext, lifetime_days=lifetime_days
397
+ subject=subject,
398
+ san=san,
399
+ extensions=ext,
400
+ lifetime_days=lifetime_days,
354
401
  )
355
402
 
356
403
  @classmethod
@@ -379,5 +426,8 @@ class SelfSignedCertificate(CertServiceBase):
379
426
  subject_alt_name=san,
380
427
  )
381
428
  return cls(
382
- subject=subject, san=san, extensions=ext, lifetime_days=lifetime_days
429
+ subject=subject,
430
+ san=san,
431
+ extensions=ext,
432
+ lifetime_days=lifetime_days,
383
433
  )