swarmauri_certs_azure 0.3.0.dev4__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.
File without changes
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ import base64
4
+ import datetime as dt
5
+ import random
6
+ from typing import Any, Dict, Iterable, Literal, Mapping, Optional
7
+
8
+ from azure.identity import DefaultAzureCredential
9
+ from azure.keyvault.keys import KeyClient
10
+ from cryptography import x509
11
+ from cryptography.hazmat.primitives import hashes, serialization
12
+ from cryptography.x509.oid import NameOID
13
+
14
+ from swarmauri_base.certs.CertServiceBase import CertServiceBase
15
+ from swarmauri_core.certs.ICertService import AltNameSpec, SubjectSpec
16
+ from swarmauri_core.crypto.types import KeyRef
17
+
18
+
19
+ # ---------------------------------------------------------------------------
20
+ # Helpers
21
+ # ---------------------------------------------------------------------------
22
+
23
+
24
+ def _now_utc() -> dt.datetime:
25
+ """Return current UTC time."""
26
+ return dt.datetime.utcnow().replace(tzinfo=dt.timezone.utc)
27
+
28
+
29
+ def _serial_or_random(serial: Optional[int]) -> int:
30
+ """Return provided serial number or a random 128-bit value per RFC 5280."""
31
+ if serial is not None:
32
+ return int(serial)
33
+ return random.SystemRandom().getrandbits(128)
34
+
35
+
36
+ def _pem_cert(der_bytes: bytes) -> bytes:
37
+ """Encode DER certificate bytes into PEM as described in RFC 7468."""
38
+ b64 = base64.encodebytes(der_bytes).decode("ascii").replace("\n", "")
39
+ lines = [b64[i : i + 64] for i in range(0, len(b64), 64)]
40
+ return (
41
+ "-----BEGIN CERTIFICATE-----\n"
42
+ + "\n".join(lines)
43
+ + "\n-----END CERTIFICATE-----\n"
44
+ ).encode("ascii")
45
+
46
+
47
+ def _to_x509_name(spec: SubjectSpec) -> x509.Name:
48
+ rdns = []
49
+ if cn := spec.get("CN"):
50
+ rdns.append(x509.NameAttribute(NameOID.COMMON_NAME, cn))
51
+ return x509.Name(rdns)
52
+
53
+
54
+ # ---------------------------------------------------------------------------
55
+ # Service
56
+ # ---------------------------------------------------------------------------
57
+
58
+
59
+ class AzureKeyVaultCertService(CertServiceBase):
60
+ """Minimal Azure Key Vault backed certificate service."""
61
+
62
+ type: Literal["AzureKeyVaultCertService"] = "AzureKeyVaultCertService"
63
+
64
+ def __init__(self, vault_url: str, *, credential: Optional[Any] = None) -> None:
65
+ super().__init__()
66
+ self._cred = credential or DefaultAzureCredential()
67
+ self._keys = KeyClient(vault_url=vault_url, credential=self._cred)
68
+
69
+ def supports(self) -> Mapping[str, Iterable[str]]:
70
+ return {
71
+ "key_algs": ("RSA-2048",),
72
+ "sig_algs": ("RSA-SHA256",),
73
+ "features": ("csr",),
74
+ }
75
+
76
+ async def create_csr(
77
+ self,
78
+ key: KeyRef,
79
+ subject: SubjectSpec,
80
+ *,
81
+ san: Optional[AltNameSpec] = None,
82
+ extensions: Optional[Dict[str, Any]] = None,
83
+ sig_alg: Optional[str] = None,
84
+ challenge_password: Optional[str] = None,
85
+ output_der: bool = False,
86
+ opts: Optional[Dict[str, Any]] = None,
87
+ ) -> bytes:
88
+ """Create a PKCS#10 CSR using the supplied key material."""
89
+ pem_priv = key.material
90
+ if not pem_priv:
91
+ raise NotImplementedError(
92
+ "Non-exportable keys are not supported in this simplified service."
93
+ )
94
+ subject_name = _to_x509_name(subject)
95
+ builder = x509.CertificateSigningRequestBuilder().subject_name(subject_name)
96
+ priv = serialization.load_pem_private_key(pem_priv, password=None)
97
+ csr = builder.sign(priv, hashes.SHA256())
98
+ encoding = (
99
+ serialization.Encoding.DER if output_der else serialization.Encoding.PEM
100
+ )
101
+ return csr.public_bytes(encoding)
File without changes
@@ -0,0 +1,39 @@
1
+ Metadata-Version: 2.3
2
+ Name: swarmauri_certs_azure
3
+ Version: 0.3.0.dev4
4
+ Summary: Azure Key Vault certificate utilities for the Swarmauri ecosystem
5
+ License: Apache-2.0
6
+ Author: Community
7
+ Requires-Python: >=3.10,<3.13
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Provides-Extra: azure
13
+ Provides-Extra: crypto
14
+ Requires-Dist: asn1crypto
15
+ Requires-Dist: asn1crypto ; extra == "crypto"
16
+ Requires-Dist: azure-identity
17
+ Requires-Dist: azure-identity ; extra == "azure"
18
+ Requires-Dist: azure-keyvault-keys
19
+ Requires-Dist: azure-keyvault-keys ; extra == "azure"
20
+ Requires-Dist: cryptography
21
+ Requires-Dist: cryptography ; extra == "crypto"
22
+ Requires-Dist: swarmauri_base
23
+ Requires-Dist: swarmauri_core
24
+ Description-Content-Type: text/markdown
25
+
26
+ # swarmauri_certs_azure
27
+
28
+ Community-maintained utilities for working with X.509 certificates via Azure Key Vault.
29
+
30
+ ## Features
31
+ - AzureKeyVaultCertService for issuing and managing certificates.
32
+ - Helper utilities aligned with RFC 5280 and RFC 7468.
33
+
34
+ ## Testing
35
+ Run tests with:
36
+ ```bash
37
+ uv run --package swarmauri_certs_azure --directory community pytest
38
+ ```
39
+
@@ -0,0 +1,6 @@
1
+ swarmauri_certs_azure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ swarmauri_certs_azure/certs/AzureKeyVaultCertService.py,sha256=KLfDE1Ppch6m00w89qYj807nf3rFvlnKRyzMTIlcH44,3555
3
+ swarmauri_certs_azure/certs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ swarmauri_certs_azure-0.3.0.dev4.dist-info/METADATA,sha256=wOLxK_MaGCplSaoK5sMSEZe6jWFGbqqUxYYO_-jQiPs,1247
5
+ swarmauri_certs_azure-0.3.0.dev4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
6
+ swarmauri_certs_azure-0.3.0.dev4.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.1.3
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any