paramiko-cloud 1.3.1__tar.gz → 1.3.2__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.
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/PKG-INFO +2 -2
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/pki.py +4 -4
- paramiko_cloud-1.3.2/paramiko_cloud/protobuf/csr_pb2.pyi +72 -0
- paramiko_cloud-1.3.2/paramiko_cloud/protobuf/rpc_pb2.pyi +51 -0
- paramiko_cloud-1.3.2/paramiko_cloud/py.typed +1 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/test_pki.py +17 -1
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud.egg-info/PKG-INFO +2 -2
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud.egg-info/SOURCES.txt +3 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/pyproject.toml +8 -4
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/README.md +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/aws/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/aws/keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/aws/test_keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/azure/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/azure/keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/azure/test_keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/base.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/dummy/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/dummy/keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/dummy/test_keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/gcp/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/gcp/keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/gcp/test_keys.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/grpc_server.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/protobuf/__init__.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/protobuf/csr_pb2.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/protobuf/rpc_pb2.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/protobuf/rpc_pb2_grpc.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/test_grpc_server.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud/test_helpers.py +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud.egg-info/dependency_links.txt +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud.egg-info/requires.txt +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/paramiko_cloud.egg-info/top_level.txt +0 -0
- {paramiko_cloud-1.3.1 → paramiko_cloud-1.3.2}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paramiko-cloud
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Use cloud-managed keys to sign SSH certificates
|
|
5
5
|
Author-email: Jason Rigby <hello@jasonrig.by>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/jasonrig/paramiko-cloud/
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: paramiko
|
|
11
11
|
Requires-Dist: cryptography
|
|
@@ -14,7 +14,7 @@ try:
|
|
|
14
14
|
except ImportError: # pragma: no cover - only reached on newer Paramiko versions
|
|
15
15
|
DSSKey = None
|
|
16
16
|
|
|
17
|
-
from paramiko_cloud.protobuf.csr_pb2 import CSR
|
|
17
|
+
from paramiko_cloud.protobuf.csr_pb2 import CSR
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CertificateBlob(PublicBlob):
|
|
@@ -167,7 +167,7 @@ class CertificateExtensions(enum.Enum):
|
|
|
167
167
|
The serialized enum value
|
|
168
168
|
"""
|
|
169
169
|
|
|
170
|
-
return getattr(CSR.
|
|
170
|
+
return getattr(CSR.Extension, self.name)
|
|
171
171
|
|
|
172
172
|
@classmethod
|
|
173
173
|
def from_pb_enum(cls, value: int) -> "CertificateExtensions":
|
|
@@ -303,12 +303,12 @@ class CertificateSigningRequest:
|
|
|
303
303
|
csr.validBefore = self.cert_params.valid_before
|
|
304
304
|
for opt, val in self.cert_params.critical_opts:
|
|
305
305
|
option_value = CSR.CriticalOptionValue()
|
|
306
|
-
option_value.type = opt.pb_enum()
|
|
306
|
+
option_value.type = cast(CSR.CriticalOption, opt.pb_enum())
|
|
307
307
|
option_value.value = val
|
|
308
308
|
csr.criticalOptions.append(option_value)
|
|
309
309
|
for ext, val in self.cert_params.extensions:
|
|
310
310
|
extension_value = CSR.ExtensionValue()
|
|
311
|
-
extension_value.type = ext.pb_enum()
|
|
311
|
+
extension_value.type = cast(CSR.Extension, ext.pb_enum())
|
|
312
312
|
extension_value.value = val
|
|
313
313
|
csr.extensions.append(extension_value)
|
|
314
314
|
csr.publicKeyType = self.public_key.get_name()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from google.protobuf.internal import containers as _containers
|
|
2
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
3
|
+
from google.protobuf import descriptor as _descriptor
|
|
4
|
+
from google.protobuf import message as _message
|
|
5
|
+
from collections.abc import Iterable as _Iterable, Mapping as _Mapping
|
|
6
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
7
|
+
|
|
8
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
9
|
+
|
|
10
|
+
class CSR(_message.Message):
|
|
11
|
+
__slots__ = ("type", "criticalOptions", "extensions", "keyId", "serial", "principals", "validAfter", "validBefore", "publicKeyType", "publicKey")
|
|
12
|
+
class Type(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
13
|
+
__slots__ = ()
|
|
14
|
+
USER: _ClassVar[CSR.Type]
|
|
15
|
+
HOST: _ClassVar[CSR.Type]
|
|
16
|
+
USER: CSR.Type
|
|
17
|
+
HOST: CSR.Type
|
|
18
|
+
class CriticalOption(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
19
|
+
__slots__ = ()
|
|
20
|
+
FORCE_COMMAND: _ClassVar[CSR.CriticalOption]
|
|
21
|
+
SOURCE_ADDRESS: _ClassVar[CSR.CriticalOption]
|
|
22
|
+
FORCE_COMMAND: CSR.CriticalOption
|
|
23
|
+
SOURCE_ADDRESS: CSR.CriticalOption
|
|
24
|
+
class Extension(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
25
|
+
__slots__ = ()
|
|
26
|
+
NO_TOUCH_REQUIRED: _ClassVar[CSR.Extension]
|
|
27
|
+
PERMIT_X11_FORWARDING: _ClassVar[CSR.Extension]
|
|
28
|
+
PERMIT_AGENT_FORWARDING: _ClassVar[CSR.Extension]
|
|
29
|
+
PERMIT_PORT_FORWARDING: _ClassVar[CSR.Extension]
|
|
30
|
+
PERMIT_PTY: _ClassVar[CSR.Extension]
|
|
31
|
+
PERMIT_USER_RC: _ClassVar[CSR.Extension]
|
|
32
|
+
NO_TOUCH_REQUIRED: CSR.Extension
|
|
33
|
+
PERMIT_X11_FORWARDING: CSR.Extension
|
|
34
|
+
PERMIT_AGENT_FORWARDING: CSR.Extension
|
|
35
|
+
PERMIT_PORT_FORWARDING: CSR.Extension
|
|
36
|
+
PERMIT_PTY: CSR.Extension
|
|
37
|
+
PERMIT_USER_RC: CSR.Extension
|
|
38
|
+
class CriticalOptionValue(_message.Message):
|
|
39
|
+
__slots__ = ("type", "value")
|
|
40
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
41
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
42
|
+
type: CSR.CriticalOption
|
|
43
|
+
value: str
|
|
44
|
+
def __init__(self, type: _Optional[_Union[CSR.CriticalOption, str]] = ..., value: _Optional[str] = ...) -> None: ...
|
|
45
|
+
class ExtensionValue(_message.Message):
|
|
46
|
+
__slots__ = ("type", "value")
|
|
47
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
48
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
49
|
+
type: CSR.Extension
|
|
50
|
+
value: str
|
|
51
|
+
def __init__(self, type: _Optional[_Union[CSR.Extension, str]] = ..., value: _Optional[str] = ...) -> None: ...
|
|
52
|
+
TYPE_FIELD_NUMBER: _ClassVar[int]
|
|
53
|
+
CRITICALOPTIONS_FIELD_NUMBER: _ClassVar[int]
|
|
54
|
+
EXTENSIONS_FIELD_NUMBER: _ClassVar[int]
|
|
55
|
+
KEYID_FIELD_NUMBER: _ClassVar[int]
|
|
56
|
+
SERIAL_FIELD_NUMBER: _ClassVar[int]
|
|
57
|
+
PRINCIPALS_FIELD_NUMBER: _ClassVar[int]
|
|
58
|
+
VALIDAFTER_FIELD_NUMBER: _ClassVar[int]
|
|
59
|
+
VALIDBEFORE_FIELD_NUMBER: _ClassVar[int]
|
|
60
|
+
PUBLICKEYTYPE_FIELD_NUMBER: _ClassVar[int]
|
|
61
|
+
PUBLICKEY_FIELD_NUMBER: _ClassVar[int]
|
|
62
|
+
type: CSR.Type
|
|
63
|
+
criticalOptions: _containers.RepeatedCompositeFieldContainer[CSR.CriticalOptionValue]
|
|
64
|
+
extensions: _containers.RepeatedCompositeFieldContainer[CSR.ExtensionValue]
|
|
65
|
+
keyId: str
|
|
66
|
+
serial: int
|
|
67
|
+
principals: _containers.RepeatedScalarFieldContainer[str]
|
|
68
|
+
validAfter: int
|
|
69
|
+
validBefore: int
|
|
70
|
+
publicKeyType: str
|
|
71
|
+
publicKey: bytes
|
|
72
|
+
def __init__(self, type: _Optional[_Union[CSR.Type, str]] = ..., criticalOptions: _Optional[_Iterable[_Union[CSR.CriticalOptionValue, _Mapping]]] = ..., extensions: _Optional[_Iterable[_Union[CSR.ExtensionValue, _Mapping]]] = ..., keyId: _Optional[str] = ..., serial: _Optional[int] = ..., principals: _Optional[_Iterable[str]] = ..., validAfter: _Optional[int] = ..., validBefore: _Optional[int] = ..., publicKeyType: _Optional[str] = ..., publicKey: _Optional[bytes] = ...) -> None: ...
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from paramiko_cloud.protobuf import csr_pb2 as _csr_pb2
|
|
2
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
3
|
+
from google.protobuf import descriptor as _descriptor
|
|
4
|
+
from google.protobuf import message as _message
|
|
5
|
+
from collections.abc import Mapping as _Mapping
|
|
6
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
7
|
+
|
|
8
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
9
|
+
|
|
10
|
+
class CloudProvider(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
11
|
+
__slots__ = ()
|
|
12
|
+
AWS: _ClassVar[CloudProvider]
|
|
13
|
+
AZURE: _ClassVar[CloudProvider]
|
|
14
|
+
GCP: _ClassVar[CloudProvider]
|
|
15
|
+
AWS: CloudProvider
|
|
16
|
+
AZURE: CloudProvider
|
|
17
|
+
GCP: CloudProvider
|
|
18
|
+
|
|
19
|
+
class CloudCertificateSigningRequest(_message.Message):
|
|
20
|
+
__slots__ = ("provider", "kmsKeyId", "signingRequestPayload")
|
|
21
|
+
PROVIDER_FIELD_NUMBER: _ClassVar[int]
|
|
22
|
+
KMSKEYID_FIELD_NUMBER: _ClassVar[int]
|
|
23
|
+
SIGNINGREQUESTPAYLOAD_FIELD_NUMBER: _ClassVar[int]
|
|
24
|
+
provider: CloudProvider
|
|
25
|
+
kmsKeyId: str
|
|
26
|
+
signingRequestPayload: _csr_pb2.CSR
|
|
27
|
+
def __init__(self, provider: _Optional[_Union[CloudProvider, str]] = ..., kmsKeyId: _Optional[str] = ..., signingRequestPayload: _Optional[_Union[_csr_pb2.CSR, _Mapping]] = ...) -> None: ...
|
|
28
|
+
|
|
29
|
+
class CloudCertificateSigningResponse(_message.Message):
|
|
30
|
+
__slots__ = ("certificateType", "certificate")
|
|
31
|
+
CERTIFICATETYPE_FIELD_NUMBER: _ClassVar[int]
|
|
32
|
+
CERTIFICATE_FIELD_NUMBER: _ClassVar[int]
|
|
33
|
+
certificateType: str
|
|
34
|
+
certificate: bytes
|
|
35
|
+
def __init__(self, certificateType: _Optional[str] = ..., certificate: _Optional[bytes] = ...) -> None: ...
|
|
36
|
+
|
|
37
|
+
class GetCertificateAuthorityRequest(_message.Message):
|
|
38
|
+
__slots__ = ("provider", "kmsKeyId")
|
|
39
|
+
PROVIDER_FIELD_NUMBER: _ClassVar[int]
|
|
40
|
+
KMSKEYID_FIELD_NUMBER: _ClassVar[int]
|
|
41
|
+
provider: CloudProvider
|
|
42
|
+
kmsKeyId: str
|
|
43
|
+
def __init__(self, provider: _Optional[_Union[CloudProvider, str]] = ..., kmsKeyId: _Optional[str] = ...) -> None: ...
|
|
44
|
+
|
|
45
|
+
class GetCertificateAuthorityResponse(_message.Message):
|
|
46
|
+
__slots__ = ("keyType", "publicKey")
|
|
47
|
+
KEYTYPE_FIELD_NUMBER: _ClassVar[int]
|
|
48
|
+
PUBLICKEY_FIELD_NUMBER: _ClassVar[int]
|
|
49
|
+
keyType: str
|
|
50
|
+
publicKey: bytes
|
|
51
|
+
def __init__(self, keyType: _Optional[str] = ..., publicKey: _Optional[bytes] = ...) -> None: ...
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -3,7 +3,13 @@ from unittest import TestCase
|
|
|
3
3
|
from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1
|
|
4
4
|
from paramiko import ECDSAKey, RSAKey
|
|
5
5
|
|
|
6
|
-
from paramiko_cloud.pki import
|
|
6
|
+
from paramiko_cloud.pki import (
|
|
7
|
+
CertificateExtensions,
|
|
8
|
+
CertificateParameters,
|
|
9
|
+
CertificateSigningRequest,
|
|
10
|
+
DSSKey,
|
|
11
|
+
)
|
|
12
|
+
from paramiko_cloud.protobuf.csr_pb2 import CSR
|
|
7
13
|
|
|
8
14
|
rsa_key = RSAKey.generate(1024)
|
|
9
15
|
ecdsa_key = ECDSAKey.generate(SECP256R1())
|
|
@@ -43,3 +49,13 @@ class PKITest(TestCase):
|
|
|
43
49
|
CertificateSigningRequest.from_proto(csr)
|
|
44
50
|
else:
|
|
45
51
|
CertificateSigningRequest.from_proto(csr)
|
|
52
|
+
|
|
53
|
+
def test_certificate_extensions_serialize_to_proto(self):
|
|
54
|
+
csr = CertificateSigningRequest(
|
|
55
|
+
rsa_key,
|
|
56
|
+
CertificateParameters(
|
|
57
|
+
extensions={CertificateExtensions.NO_TOUCH_REQUIRED: ""}
|
|
58
|
+
),
|
|
59
|
+
).to_proto()
|
|
60
|
+
|
|
61
|
+
self.assertEqual(CSR.Extension.NO_TOUCH_REQUIRED, csr.extensions[0].type)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: paramiko-cloud
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Use cloud-managed keys to sign SSH certificates
|
|
5
5
|
Author-email: Jason Rigby <hello@jasonrig.by>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/jasonrig/paramiko-cloud/
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
Requires-Dist: paramiko
|
|
11
11
|
Requires-Dist: cryptography
|
|
@@ -4,6 +4,7 @@ paramiko_cloud/__init__.py
|
|
|
4
4
|
paramiko_cloud/base.py
|
|
5
5
|
paramiko_cloud/grpc_server.py
|
|
6
6
|
paramiko_cloud/pki.py
|
|
7
|
+
paramiko_cloud/py.typed
|
|
7
8
|
paramiko_cloud/test_grpc_server.py
|
|
8
9
|
paramiko_cloud/test_helpers.py
|
|
9
10
|
paramiko_cloud/test_pki.py
|
|
@@ -26,5 +27,7 @@ paramiko_cloud/gcp/keys.py
|
|
|
26
27
|
paramiko_cloud/gcp/test_keys.py
|
|
27
28
|
paramiko_cloud/protobuf/__init__.py
|
|
28
29
|
paramiko_cloud/protobuf/csr_pb2.py
|
|
30
|
+
paramiko_cloud/protobuf/csr_pb2.pyi
|
|
29
31
|
paramiko_cloud/protobuf/rpc_pb2.py
|
|
32
|
+
paramiko_cloud/protobuf/rpc_pb2.pyi
|
|
30
33
|
paramiko_cloud/protobuf/rpc_pb2_grpc.py
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "paramiko-cloud"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.2"
|
|
8
8
|
description = "Use cloud-managed keys to sign SSH certificates"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
authors = [
|
|
13
13
|
{ name = "Jason Rigby", email = "hello@jasonrig.by" },
|
|
@@ -44,6 +44,10 @@ packages = [
|
|
|
44
44
|
"paramiko_cloud.protobuf",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
|
+
[tool.setuptools.package-data]
|
|
48
|
+
paramiko_cloud = ["py.typed"]
|
|
49
|
+
"paramiko_cloud.protobuf" = ["*.pyi"]
|
|
50
|
+
|
|
47
51
|
[dependency-groups]
|
|
48
52
|
dev = ["pytest", "pytest-cov", "ruff", "mypy"]
|
|
49
53
|
build = ["build"]
|
|
@@ -60,7 +64,7 @@ docs = [
|
|
|
60
64
|
]
|
|
61
65
|
|
|
62
66
|
[tool.mypy]
|
|
63
|
-
python_version = "3.
|
|
67
|
+
python_version = "3.10"
|
|
64
68
|
ignore_missing_imports = true
|
|
65
69
|
exclude = "(^|/)test_.*\\.py$|(^|/)paramiko_cloud/protobuf/.*_pb2.*\\.py$"
|
|
66
70
|
disable_error_code = ["import-untyped"]
|
|
@@ -70,4 +74,4 @@ module = ["paramiko_cloud.protobuf.*"]
|
|
|
70
74
|
ignore_errors = true
|
|
71
75
|
|
|
72
76
|
[tool.ruff]
|
|
73
|
-
target-version = "
|
|
77
|
+
target-version = "py310"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|