sshkey-tools
Advanced tools
+8
-8
| Metadata-Version: 2.1 | ||
| Name: sshkey-tools | ||
| Version: 0.9.3 | ||
| Version: 0.10.1 | ||
| Summary: A Python module for generating, parsing and handling OpenSSH keys and certificates | ||
@@ -21,3 +21,3 @@ Home-page: https://github.com/scheiblingco/sshkey-tools | ||
| # Notice | ||
| ## Notice | ||
| The DSA algorithm has been deprecated and is removed in pyca/cryptography 41.x, meaning **version 0.9.* of this package will be the last to support DSA keys and certificates** for SSH. If there is any demand to reintroduce DSA support, please open an issue regarding this and we'll look into it. | ||
@@ -27,6 +27,6 @@ | ||
| ## Background | ||
| ### Background | ||
| The DSA algorithm is considered deprecated and will be removed in a future version. If possible, use RSA, [(ECDSA)](https://billatnapier.medium.com/ecdsa-weakness-where-nonces-are-reused-2be63856a01a) or ED25519 as a first-hand choice. | ||
| ## Notice from OpenSSH: | ||
| ### Notice from OpenSSH: | ||
| ``` | ||
@@ -40,3 +40,3 @@ OpenSSH 7.0 and greater similarly disable the ssh-dss (DSA) public key algorithm. It too is weak and we recommend against its use. It can be re-enabled using the HostKeyAlgorithms configuration option: sshd_config(5) HostKeyAlgorithms | ||
| ### SSH Keys | ||
| - Supports RSA, DSA (Note: Deprecated), ECDSA and ED25519 keys | ||
| - Supports RSA, ECDSA and ED25519 keys | ||
| - Import existing keys from file, string, byte data or [pyca/cryptography](https://github.com/pyca/cryptography) class | ||
@@ -50,3 +50,3 @@ - Generate new keys | ||
| ### OpenSSH Certificates | ||
| - Supports RSA, DSA, ECDSA and ED25519 certificates | ||
| - Supports RSA, ECDSA and ED25519 certificates | ||
| - Import existing certificates from file, string or bytes | ||
@@ -95,3 +95,2 @@ - Verify certificate signature against internal or separate public key | ||
| RsaPrivateKey, | ||
| DsaPrivateKey, | ||
| EcdsaPrivateKey, | ||
@@ -111,3 +110,4 @@ Ed25519PrivateKey, | ||
| # Generate DSA keys (since SSH only supports 1024-bit keys, this is the default) | ||
| dsa_priv = DsaPrivateKey.generate() | ||
| # DEPRECATED | ||
| # dsa_priv = DsaPrivateKey.generate() | ||
@@ -114,0 +114,0 @@ # Generate ECDSA keys (The default curve is P521) |
+7
-7
@@ -5,3 +5,3 @@ # sshkey-tools | ||
| # Notice | ||
| ## Notice | ||
| The DSA algorithm has been deprecated and is removed in pyca/cryptography 41.x, meaning **version 0.9.* of this package will be the last to support DSA keys and certificates** for SSH. If there is any demand to reintroduce DSA support, please open an issue regarding this and we'll look into it. | ||
@@ -11,6 +11,6 @@ | ||
| ## Background | ||
| ### Background | ||
| The DSA algorithm is considered deprecated and will be removed in a future version. If possible, use RSA, [(ECDSA)](https://billatnapier.medium.com/ecdsa-weakness-where-nonces-are-reused-2be63856a01a) or ED25519 as a first-hand choice. | ||
| ## Notice from OpenSSH: | ||
| ### Notice from OpenSSH: | ||
| ``` | ||
@@ -24,3 +24,3 @@ OpenSSH 7.0 and greater similarly disable the ssh-dss (DSA) public key algorithm. It too is weak and we recommend against its use. It can be re-enabled using the HostKeyAlgorithms configuration option: sshd_config(5) HostKeyAlgorithms | ||
| ### SSH Keys | ||
| - Supports RSA, DSA (Note: Deprecated), ECDSA and ED25519 keys | ||
| - Supports RSA, ECDSA and ED25519 keys | ||
| - Import existing keys from file, string, byte data or [pyca/cryptography](https://github.com/pyca/cryptography) class | ||
@@ -34,3 +34,3 @@ - Generate new keys | ||
| ### OpenSSH Certificates | ||
| - Supports RSA, DSA, ECDSA and ED25519 certificates | ||
| - Supports RSA, ECDSA and ED25519 certificates | ||
| - Import existing certificates from file, string or bytes | ||
@@ -79,3 +79,2 @@ - Verify certificate signature against internal or separate public key | ||
| RsaPrivateKey, | ||
| DsaPrivateKey, | ||
| EcdsaPrivateKey, | ||
@@ -95,3 +94,4 @@ Ed25519PrivateKey, | ||
| # Generate DSA keys (since SSH only supports 1024-bit keys, this is the default) | ||
| dsa_priv = DsaPrivateKey.generate() | ||
| # DEPRECATED | ||
| # dsa_priv = DsaPrivateKey.generate() | ||
@@ -98,0 +98,0 @@ # Generate ECDSA keys (The default curve is P521) |
| Metadata-Version: 2.1 | ||
| Name: sshkey-tools | ||
| Version: 0.9.3 | ||
| Version: 0.10.1 | ||
| Summary: A Python module for generating, parsing and handling OpenSSH keys and certificates | ||
@@ -21,3 +21,3 @@ Home-page: https://github.com/scheiblingco/sshkey-tools | ||
| # Notice | ||
| ## Notice | ||
| The DSA algorithm has been deprecated and is removed in pyca/cryptography 41.x, meaning **version 0.9.* of this package will be the last to support DSA keys and certificates** for SSH. If there is any demand to reintroduce DSA support, please open an issue regarding this and we'll look into it. | ||
@@ -27,6 +27,6 @@ | ||
| ## Background | ||
| ### Background | ||
| The DSA algorithm is considered deprecated and will be removed in a future version. If possible, use RSA, [(ECDSA)](https://billatnapier.medium.com/ecdsa-weakness-where-nonces-are-reused-2be63856a01a) or ED25519 as a first-hand choice. | ||
| ## Notice from OpenSSH: | ||
| ### Notice from OpenSSH: | ||
| ``` | ||
@@ -40,3 +40,3 @@ OpenSSH 7.0 and greater similarly disable the ssh-dss (DSA) public key algorithm. It too is weak and we recommend against its use. It can be re-enabled using the HostKeyAlgorithms configuration option: sshd_config(5) HostKeyAlgorithms | ||
| ### SSH Keys | ||
| - Supports RSA, DSA (Note: Deprecated), ECDSA and ED25519 keys | ||
| - Supports RSA, ECDSA and ED25519 keys | ||
| - Import existing keys from file, string, byte data or [pyca/cryptography](https://github.com/pyca/cryptography) class | ||
@@ -50,3 +50,3 @@ - Generate new keys | ||
| ### OpenSSH Certificates | ||
| - Supports RSA, DSA, ECDSA and ED25519 certificates | ||
| - Supports RSA, ECDSA and ED25519 certificates | ||
| - Import existing certificates from file, string or bytes | ||
@@ -95,3 +95,2 @@ - Verify certificate signature against internal or separate public key | ||
| RsaPrivateKey, | ||
| DsaPrivateKey, | ||
| EcdsaPrivateKey, | ||
@@ -111,3 +110,4 @@ Ed25519PrivateKey, | ||
| # Generate DSA keys (since SSH only supports 1024-bit keys, this is the default) | ||
| dsa_priv = DsaPrivateKey.generate() | ||
| # DEPRECATED | ||
| # dsa_priv = DsaPrivateKey.generate() | ||
@@ -114,0 +114,0 @@ # Generate ECDSA keys (The default curve is P521) |
| click | ||
| cryptography<41.0.0 | ||
| cryptography | ||
| bcrypt | ||
@@ -4,0 +4,0 @@ enum34 |
@@ -27,3 +27,2 @@ # pylint: disable=super-with-arguments | ||
| "rsa-sha2-512-cert-v01@openssh.com": ("RsaCertificate", "RsaPubkeyField"), | ||
| "ssh-dss-cert-v01@openssh.com": ("DsaCertificate", "DsaPubkeyField"), | ||
| "ecdsa-sha2-nistp256-cert-v01@openssh.com": ( | ||
@@ -583,10 +582,7 @@ "EcdsaCertificate", | ||
| """The DSA Certificate class (DEPRECATED)""" | ||
| DEFAULT_KEY_TYPE = "ssh-dss-cert-v01@openssh.com" | ||
| def __post_init__(self): | ||
| """Display the deprecation notice""" | ||
| warnings.warn( | ||
| "SSH DSA keys and certificates are deprecated and will be removed in version 0.10 of sshkey-tools", | ||
| stacklevel=2, | ||
| def __init__(self, *args, **kwargs): | ||
| """DEPRECATED CERTIFICATE CLASS""" | ||
| raise _EX.DeprecatedClassCalled( | ||
| "DSA certificates are deprecated and have been removed since version 0.10 of sshkey-tools" | ||
| ) | ||
@@ -593,0 +589,0 @@ |
@@ -110,1 +110,6 @@ """ | ||
| """ | ||
| class DeprecatedClassCalled(ValueError): | ||
| """ | ||
| Raised when trying to instantiate a deprecated class | ||
| """ |
@@ -19,4 +19,2 @@ """ | ||
| from .keys import ( | ||
| DsaPrivateKey, | ||
| DsaPublicKey, | ||
| EcdsaPrivateKey, | ||
@@ -57,3 +55,2 @@ EcdsaPublicKey, | ||
| RsaPublicKey: "RsaPubkeyField", | ||
| DsaPublicKey: "DsaPubkeyField", | ||
| EcdsaPublicKey: "EcdsaPubkeyField", | ||
@@ -65,3 +62,2 @@ Ed25519PublicKey: "Ed25519PubkeyField", | ||
| RsaPrivateKey: "RsaSignatureField", | ||
| DsaPrivateKey: "DsaSignatureField", | ||
| EcdsaPrivateKey: "EcdsaSignatureField", | ||
@@ -73,3 +69,2 @@ Ed25519PrivateKey: "Ed25519SignatureField", | ||
| b"rsa": "RsaSignatureField", | ||
| b"dss": "DsaSignatureField", | ||
| b"ecdsa": "EcdsaSignatureField", | ||
@@ -477,7 +472,4 @@ b"ed25519": "Ed25519SignatureField", | ||
| if isinstance(value, str): | ||
| if value == "forever": | ||
| return Integer64Field.encode(MAX_INT64 - 1) | ||
| value = cls.parse_string_value(value) | ||
| value = int((datetime.now() + str_to_time_delta(value)).timestamp()) | ||
| if isinstance(value, datetime): | ||
@@ -489,2 +481,21 @@ value = int(value.timestamp()) | ||
| @staticmethod | ||
| def parse_string_value(value: str) -> int: | ||
| """ | ||
| Parses a string value into an integer timestamp | ||
| Args: | ||
| value (str): String value to parse | ||
| Returns: | ||
| int: Integer timestamp | ||
| """ | ||
| if value == "forever": | ||
| return MAX_INT64 - 1 | ||
| if value == "always": | ||
| return 1 | ||
| return int((datetime.now() + str_to_time_delta(value)).timestamp()) | ||
| @staticmethod | ||
| def decode(data: bytes) -> datetime: | ||
@@ -511,3 +522,8 @@ """Decodes a datetime object from a block of bytes | ||
| check = self.value if isinstance(self.value, int) else self.value.timestamp() | ||
| check = self.value | ||
| if isinstance(check, str): | ||
| check = self.parse_string_value(check) | ||
| if isinstance(check, datetime): | ||
| check = int(check.timestamp()) | ||
@@ -737,3 +753,2 @@ if check < MAX_INT64: | ||
| "rsa-sha2-512-cert-v01@openssh.com", | ||
| "ssh-dss-cert-v01@openssh.com", | ||
| "ecdsa-sha2-nistp256-cert-v01@openssh.com", | ||
@@ -878,7 +893,4 @@ "ecdsa-sha2-nistp384-cert-v01@openssh.com", | ||
| DEFAULT = None | ||
| DATA_TYPE = DsaPublicKey | ||
| @staticmethod | ||
| def decode(data: bytes) -> Tuple[DsaPublicKey, bytes]: | ||
| def decode(data: bytes): | ||
| """ | ||
@@ -894,10 +906,5 @@ Decode the certificate field from a byte string | ||
| """ | ||
| p, data = MpIntegerField.decode(data) | ||
| q, data = MpIntegerField.decode(data) | ||
| g, data = MpIntegerField.decode(data) | ||
| y, data = MpIntegerField.decode(data) | ||
| raise _EX.DeprecatedClassCalled("DSA is deprecated, use RSA or ECDSA instead") | ||
| return DsaPublicKey.from_numbers(p=p, q=q, g=g, y=y), data | ||
| class EcdsaPubkeyField(PublicKeyField): | ||
@@ -1052,3 +1059,3 @@ """ | ||
| DEFAULT = datetime.now() | ||
| DATA_TYPE = (datetime, int) | ||
| DATA_TYPE = (datetime, int, str) | ||
@@ -1063,3 +1070,3 @@ | ||
| DEFAULT = datetime.now() + timedelta(minutes=10) | ||
| DATA_TYPE = (datetime, int) | ||
| DATA_TYPE = (datetime, int, str) | ||
@@ -1079,9 +1086,12 @@ def __validate_value__(self) -> Union[bool, Exception]: | ||
| super().__validate_value__() | ||
| check = ( | ||
| self.value | ||
| if isinstance(self.value, datetime) | ||
| else datetime.fromtimestamp(self.value) | ||
| ) | ||
| if check < datetime.now(): | ||
| check = self.value | ||
| if isinstance(check, str): | ||
| check = self.parse_string_value(check) | ||
| if isinstance(check, datetime): | ||
| check = int(check.timestamp()) | ||
| if check < int(datetime.now().timestamp()): | ||
| return _EX.InvalidCertificateFieldException( | ||
@@ -1485,12 +1495,9 @@ "The certificate validity period is invalid" | ||
| DEFAULT = None | ||
| DATA_TYPE = bytes | ||
| def __init__(self, *args, **kwargs) -> None: | ||
| raise _EX.DeprecatedClassCalled( | ||
| "DSA signatures are deprecated and have been removed" | ||
| ) | ||
| def __init__( | ||
| self, private_key: DsaPrivateKey = None, signature: bytes = None | ||
| ) -> None: | ||
| super().__init__(private_key, signature) | ||
| @classmethod | ||
| def encode(cls, value: bytes): | ||
| def encode(cls, value = None): | ||
| """ | ||
@@ -1505,59 +1512,12 @@ Encodes the signature to a byte string | ||
| """ | ||
| cls.__validate_type__(value, True) | ||
| cls() | ||
| r, s = decode_dss_signature(value) | ||
| return BytestringField.encode( | ||
| StringField.encode("ssh-dss") | ||
| + BytestringField.encode(long_to_bytes(r, 20) + long_to_bytes(s, 20)) | ||
| ) | ||
| @staticmethod | ||
| def decode(data: bytes) -> Tuple[bytes, bytes]: | ||
| """ | ||
| Decodes a bytestring containing a signature | ||
| def decode(data = None): | ||
| DsaSignatureField() | ||
| Args: | ||
| data (bytes): The bytestring starting with the Signature | ||
| Returns: | ||
| Tuple[ bytes, bytes ]: signature, remainder of the data | ||
| """ | ||
| signature, data = BytestringField.decode(data) | ||
| signature = BytestringField.decode(BytestringField.decode(signature)[1])[0] | ||
| r = bytes_to_long(signature[:20]) | ||
| s = bytes_to_long(signature[20:]) | ||
| signature = encode_dss_signature(r, s) | ||
| return signature, data | ||
| @classmethod | ||
| def from_decode(cls, data: bytes) -> Tuple["DsaSignatureField", bytes]: | ||
| """ | ||
| Creates a signature field class from the encoded signature | ||
| def from_decode(cls, data = None): | ||
| cls() | ||
| Args: | ||
| data (bytes): The bytestring starting with the Signature | ||
| Returns: | ||
| Tuple[ DsaSignatureField, bytes ]: signature, remainder of the data | ||
| """ | ||
| signature, data = cls.decode(data) | ||
| return cls(private_key=None, signature=signature), data | ||
| # pylint: disable=unused-argument | ||
| def sign(self, data: bytes, **kwargs) -> None: | ||
| """ | ||
| Signs the provided data with the provided private key | ||
| Args: | ||
| data (bytes): The data to be signed | ||
| """ | ||
| self.value = self.private_key.sign(data) | ||
| self.is_signed = True | ||
| class EcdsaSignatureField(SignatureField): | ||
@@ -1564,0 +1524,0 @@ """ |
+17
-99
@@ -11,3 +11,2 @@ """ | ||
| from cryptography.exceptions import InvalidSignature | ||
| from cryptography.hazmat.backends.openssl.dsa import _DSAPrivateKey, _DSAPublicKey | ||
| from cryptography.hazmat.backends.openssl.ec import ( | ||
@@ -17,6 +16,4 @@ _EllipticCurvePrivateKey, | ||
| ) | ||
| from cryptography.hazmat.backends.openssl.ed25519 import ( | ||
| _Ed25519PrivateKey, | ||
| _Ed25519PublicKey, | ||
| ) | ||
| from cryptography.hazmat.bindings import _rust as _RustBinding | ||
| from cryptography.hazmat.backends.openssl.rsa import _RSAPrivateKey, _RSAPublicKey | ||
@@ -39,5 +36,4 @@ from cryptography.hazmat.primitives import hashes as _HASHES | ||
| _RSAPublicKey: "RsaPublicKey", | ||
| _DSAPublicKey: "DsaPublicKey", | ||
| _EllipticCurvePublicKey: "EcdsaPublicKey", | ||
| _Ed25519PublicKey: "Ed25519PublicKey", | ||
| _RustBinding.openssl.ed25519.Ed25519PublicKey: "Ed25519PublicKey", | ||
| } | ||
@@ -47,6 +43,5 @@ | ||
| _RSAPrivateKey: "RsaPrivateKey", | ||
| _DSAPrivateKey: "DsaPrivateKey", | ||
| _EllipticCurvePrivateKey: "EcdsaPrivateKey", | ||
| # trunk-ignore(gitleaks/generic-api-key) | ||
| _Ed25519PrivateKey: "Ed25519PrivateKey", | ||
| _RustBinding.openssl.ed25519.Ed25519PrivateKey: "Ed25519PrivateKey", | ||
| } | ||
@@ -606,63 +601,13 @@ | ||
| def __init__( | ||
| self, | ||
| key: _DSA.DSAPublicKey, | ||
| comment: Union[str, bytes] = None, | ||
| key_type: Union[str, bytes] = None, | ||
| serialized: bytes = None, | ||
| ): | ||
| super().__init__( | ||
| key=key, | ||
| comment=comment, | ||
| key_type=key_type, | ||
| public_numbers=key.public_numbers(), | ||
| serialized=serialized, | ||
| def __init__(self, key = None, comment = None, key_type = None, serialized = None): | ||
| raise _EX.DeprecatedClassCalled( | ||
| "SSH DSA keys and certificates are deprecated and are removed since version 0.10 of sshkey-tools", | ||
| ) | ||
| self.parameters = key.parameters().parameter_numbers() | ||
| warnings.warn( | ||
| "SSH DSA keys and certificates are deprecated and will be removed in version 0.10 of sshkey-tools", | ||
| stacklevel=2, | ||
| ) | ||
| @classmethod | ||
| # pylint: disable=invalid-name | ||
| def from_numbers(cls, p: int, q: int, g: int, y: int) -> "DsaPublicKey": | ||
| """ | ||
| Create a DSA public key from public numbers and parameters | ||
| return cls() | ||
| Args: | ||
| p (int): P parameter, the prime modulus | ||
| q (int): Q parameter, the order of the subgroup | ||
| g (int): G parameter, the generator | ||
| y (int): The public number Y | ||
| Returns: | ||
| DsaPublicKey: An instance of DsaPublicKey | ||
| """ | ||
| return cls( | ||
| key=_DSA.DSAPublicNumbers( | ||
| y=y, parameter_numbers=_DSA.DSAParameterNumbers(p=p, q=q, g=g) | ||
| ).public_key() | ||
| ) | ||
| def verify(self, data: bytes, signature: bytes) -> None: | ||
| """ | ||
| Verifies a signature | ||
| Args: | ||
| data (bytes): The data to verify | ||
| signature (bytes): The signature to verify | ||
| Raises: | ||
| Raises an sshkey_tools.exceptions.InvalidSignatureException if the signature is invalid | ||
| """ | ||
| try: | ||
| return self.key.verify(signature, data, _HASHES.SHA1()) | ||
| except InvalidSignature: | ||
| raise _EX.InvalidSignatureException( | ||
| "The signature is invalid for the given data" | ||
| ) from InvalidSignature | ||
| class DsaPrivateKey(PrivateKey): | ||
@@ -673,17 +618,10 @@ """ | ||
| def __init__(self, key: _DSA.DSAPrivateKey): | ||
| super().__init__( | ||
| key=key, | ||
| public_key=DsaPublicKey(key.public_key()), | ||
| private_numbers=key.private_numbers(), | ||
| def __init__(self, key = None): | ||
| raise _EX.DeprecatedClassCalled( | ||
| "SSH DSA keys and certificates are deprecated and are removed since version 0.10 of sshkey-tools", | ||
| ) | ||
| warnings.warn( | ||
| "SSH DSA keys and certificates are deprecated and will be removed in version 0.10 of sshkey-tools", | ||
| stacklevel=2, | ||
| ) | ||
| @classmethod | ||
| # pylint: disable=invalid-name,too-many-arguments | ||
| def from_numbers(cls, p: int, q: int, g: int, y: int, x: int) -> "DsaPrivateKey": | ||
| def from_numbers(cls, p, q, g, y, x): | ||
| """ | ||
@@ -702,11 +640,4 @@ Creates a new DsaPrivateKey object from parameters and public/private numbers | ||
| """ | ||
| return cls( | ||
| key=_DSA.DSAPrivateNumbers( | ||
| public_numbers=_DSA.DSAPublicNumbers( | ||
| y=y, parameter_numbers=_DSA.DSAParameterNumbers(p=p, q=q, g=g) | ||
| ), | ||
| x=x, | ||
| ).private_key() | ||
| ) | ||
| return cls() | ||
| @classmethod | ||
@@ -721,17 +652,4 @@ def generate(cls) -> "DsaPrivateKey": | ||
| """ | ||
| return cls.from_class(_DSA.generate_private_key(key_size=1024)) | ||
| return cls() | ||
| def sign(self, data: bytes): | ||
| """ | ||
| Signs a block of data and returns the signature | ||
| Args: | ||
| data (bytes): Block of byte data to sign | ||
| Returns: | ||
| bytes: The signature bytes | ||
| """ | ||
| return self.key.sign(data, _HASHES.SHA1()) | ||
| class EcdsaPublicKey(PublicKey): | ||
@@ -738,0 +656,0 @@ """ |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
198447
-1.98%2940
-3.42%