Add stubs for pyjks (#10797)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Marti Raudsepp
2023-10-01 14:31:34 +03:00
committed by GitHub
parent 559d31c4a3
commit 1163a5ecfb
10 changed files with 398 additions and 0 deletions

View File

@@ -61,6 +61,7 @@
"stubs/pyasn1",
"stubs/pyflakes",
"stubs/Pygments",
"stubs/pyjks",
"stubs/PyMySQL",
"stubs/python-dateutil",
"stubs/python-jose",

View File

@@ -0,0 +1,60 @@
# Attributes implemented by __getattr__
jks.jks.PrivateKeyEntry.algorithm_oid
jks.jks.PrivateKeyEntry.pkey
jks.jks.PrivateKeyEntry.pkey_pkcs8
jks.jks.SecretKeyEntry.algorithm
jks.jks.SecretKeyEntry.key
jks.jks.SecretKeyEntry.key_size
jks.PrivateKeyEntry.algorithm_oid
jks.PrivateKeyEntry.pkey
jks.PrivateKeyEntry.pkey_pkcs8
jks.SecretKeyEntry.algorithm
jks.SecretKeyEntry.key
jks.SecretKeyEntry.key_size
# Implicit imports, not re-exported
jks.DSA_OID
jks.DSA_WITH_SHA1_OID
jks.ENTRY_TYPE_CERTIFICATE
jks.ENTRY_TYPE_KEY
jks.ENTRY_TYPE_SEALED
jks.ENTRY_TYPE_SECRET
jks.KEY_TYPE_PRIVATE
jks.KEY_TYPE_PUBLIC
jks.KEY_TYPE_SECRET
jks.MAGIC_NUMBER_JCEKS
jks.MAGIC_NUMBER_JKS
jks.RSA_ENCRYPTION_OID
jks.SIGNATURE_WHITENING
jks.b1
jks.b2
jks.b4
jks.b8
jks.py23basestring
jks.bks.DSA_OID
jks.bks.DSA_WITH_SHA1_OID
jks.bks.RSA_ENCRYPTION_OID
jks.bks.b1
jks.bks.b2
jks.bks.b4
jks.bks.b8
jks.bks.py23basestring
jks.jks.DSA_OID
jks.jks.DSA_WITH_SHA1_OID
jks.jks.RSA_ENCRYPTION_OID
jks.jks.b1
jks.jks.b2
jks.jks.b4
jks.jks.b8
jks.jks.py23basestring
jks.sun_crypto.DSA_OID
jks.sun_crypto.DSA_WITH_SHA1_OID
jks.sun_crypto.RSA_ENCRYPTION_OID
jks.sun_crypto.b1
jks.sun_crypto.b2
jks.sun_crypto.b4
jks.sun_crypto.b8
jks.sun_crypto.py23basestring
# Unintended reexports due to `from .utils import *` imports at runtime
jks\..*print_function

View File

@@ -0,0 +1,3 @@
version = "20.0.*"
upstream_repository = "https://github.com/kurtbrose/pyjks"
requires = ["types-pyasn1"]

View File

@@ -0,0 +1,48 @@
# pyjks exports lots of junk such as jks.jks.SIGNATURE_WHITENING, jks.util.b8 etc.
# We don't mark those as re-exported as those don't seem like intended part of the public API.
from .bks import (
AbstractBksEntry as AbstractBksEntry,
BksKeyEntry as BksKeyEntry,
BksKeyStore as BksKeyStore,
BksSealedKeyEntry as BksSealedKeyEntry,
BksSecretKeyEntry as BksSecretKeyEntry,
BksTrustedCertEntry as BksTrustedCertEntry,
UberKeyStore as UberKeyStore,
)
from .jks import (
KeyStore as KeyStore,
PrivateKeyEntry as PrivateKeyEntry,
SecretKeyEntry as SecretKeyEntry,
TrustedCertEntry as TrustedCertEntry,
__version__ as __version__,
__version_info__ as __version_info__,
)
from .util import (
AbstractKeystore as AbstractKeystore,
AbstractKeystoreEntry as AbstractKeystoreEntry,
BadDataLengthException as BadDataLengthException,
BadHashCheckException as BadHashCheckException,
BadKeystoreFormatException as BadKeystoreFormatException,
BadPaddingException as BadPaddingException,
DecryptionFailureException as DecryptionFailureException,
DuplicateAliasException as DuplicateAliasException,
KeystoreException as KeystoreException,
KeystoreSignatureException as KeystoreSignatureException,
NotYetDecryptedException as NotYetDecryptedException,
UnexpectedAlgorithmException as UnexpectedAlgorithmException,
UnexpectedJavaTypeException as UnexpectedJavaTypeException,
UnexpectedKeyEncodingException as UnexpectedKeyEncodingException,
UnsupportedKeyFormatException as UnsupportedKeyFormatException,
UnsupportedKeystoreEntryTypeException as UnsupportedKeystoreEntryTypeException,
UnsupportedKeystoreTypeException as UnsupportedKeystoreTypeException,
UnsupportedKeystoreVersionException as UnsupportedKeystoreVersionException,
add_pkcs7_padding as add_pkcs7_padding,
as_hex as as_hex,
as_pem as as_pem,
bitstring_to_bytes as bitstring_to_bytes,
pkey_as_pem as pkey_as_pem,
print_pem as print_pem,
strip_pkcs5_padding as strip_pkcs5_padding,
strip_pkcs7_padding as strip_pkcs7_padding,
xor_bytearrays as xor_bytearrays,
)

69
stubs/pyjks/jks/bks.pyi Normal file
View File

@@ -0,0 +1,69 @@
from _typeshed import Incomplete
from typing_extensions import Final, Self
from .jks import TrustedCertEntry
from .util import AbstractKeystore, AbstractKeystoreEntry
ENTRY_TYPE_CERTIFICATE: Final = 1
ENTRY_TYPE_KEY: Final = 2
ENTRY_TYPE_SECRET: Final = 3
ENTRY_TYPE_SEALED: Final = 4
KEY_TYPE_PRIVATE: Final = 0
KEY_TYPE_PUBLIC: Final = 1
KEY_TYPE_SECRET: Final = 2
class AbstractBksEntry(AbstractKeystoreEntry):
cert_chain: Incomplete
def __init__(self, **kwargs) -> None: ...
class BksTrustedCertEntry(TrustedCertEntry): ...
class BksKeyEntry(AbstractBksEntry):
type: Incomplete
format: Incomplete
algorithm: Incomplete
encoded: Incomplete
pkey_pkcs8: Incomplete
pkey: Incomplete
algorithm_oid: Incomplete
public_key_info: Incomplete
public_key: Incomplete
key: Incomplete
key_size: Incomplete
def __init__(self, type, format, algorithm, encoded, **kwargs) -> None: ...
def is_decrypted(self): ...
def decrypt(self, key_password) -> None: ...
@classmethod
def type2str(cls, t): ...
class BksSecretKeyEntry(AbstractBksEntry):
key: Incomplete
def __init__(self, **kwargs) -> None: ...
def is_decrypted(self): ...
def decrypt(self, key_password) -> None: ...
class BksSealedKeyEntry(AbstractBksEntry):
def __init__(self, **kwargs) -> None: ...
def __getattr__(self, name): ...
def is_decrypted(self): ...
def decrypt(self, key_password) -> None: ...
class BksKeyStore(AbstractKeystore):
version: Incomplete
def __init__(self, store_type, entries, version: int = 2) -> None: ...
@property
def certs(self): ...
@property
def secret_keys(self): ...
@property
def sealed_keys(self): ...
@property
def plain_keys(self): ...
@classmethod
def loads(cls, data, store_password, try_decrypt_keys: bool = True) -> Self: ...
class UberKeyStore(BksKeyStore):
@classmethod
def loads(cls, data, store_password, try_decrypt_keys: bool = True) -> Self: ...
version: Incomplete
def __init__(self, store_type, entries, version: int = 1) -> None: ...

109
stubs/pyjks/jks/jks.pyi Normal file
View File

@@ -0,0 +1,109 @@
from _typeshed import Incomplete, SupportsKeysAndGetItem
from collections.abc import Iterable
from typing import Any, NoReturn
from typing_extensions import Final, Literal, Self, TypeAlias
from .util import AbstractKeystore, AbstractKeystoreEntry
__version_info__: Final[tuple[int, int, int] | tuple[int, int, int, str]]
__version__: Final[str]
MAGIC_NUMBER_JKS: Final[bytes]
MAGIC_NUMBER_JCEKS: Final[bytes]
SIGNATURE_WHITENING: Final[bytes]
_JksType: TypeAlias = Literal["jks", "jceks"]
_CertType: TypeAlias = Literal["X.509"]
_KeyFormat: TypeAlias = Literal["pkcs8", "rsa_raw"]
class TrustedCertEntry(AbstractKeystoreEntry):
store_type: _JksType | None
type: _CertType | None
cert: bytes
def __init__(
self,
*,
type: _CertType = ...,
cert: bytes = ...,
store_type: _JksType = ...,
alias: str = ...,
timestamp: int = ...,
**kwargs: Any,
) -> None: ...
@classmethod
def new(cls, alias: str, cert: bytes) -> Self: ... # type: ignore[override]
def is_decrypted(self) -> Literal[True]: ...
class PrivateKeyEntry(AbstractKeystoreEntry):
store_type: _JksType | None
cert_chain: list[tuple[_CertType, bytes]]
# Properties provided by __getattr__ after decryption
@property
def pkey(self) -> bytes: ...
@property
def pkey_pkcs8(self) -> bytes: ...
@property
def algorithm_oid(self) -> tuple[int, ...]: ...
def __init__(
self,
*,
cert_chain: list[tuple[_CertType, bytes]] = ...,
encrypted: bool = ...,
pkey: bytes = ...,
pkey_pkcs8: bytes = ...,
algorithm_oid: tuple[int, ...] = ...,
store_type: _JksType = ...,
alias: str = ...,
timestamp: int = ...,
**kwargs: Any,
) -> None: ...
@classmethod
def new( # type: ignore[override]
cls, alias: str, certs: Iterable[bytes], key: bytes, key_format: _KeyFormat = "pkcs8"
) -> Self: ...
class SecretKeyEntry(AbstractKeystoreEntry):
store_type: _JksType | None
# Properties provided by __getattr__
@property
def algorithm(self) -> str: ...
@property
def key(self) -> bytes: ...
@property
def key_size(self) -> int: ...
def __init__(
self,
*,
sealed_obj: Incomplete = ...,
algorithm: str = ...,
key: bytes = ...,
key_size: int = ...,
store_type: _JksType = ...,
alias: str = ...,
timestamp: int = ...,
**kwargs: Any,
) -> None: ...
# Not implemented by pyjks
@classmethod
def new( # type: ignore[override]
cls, alias: str, sealed_obj: bool, algorithm: str, key: bytes, key_size: int
) -> NoReturn: ...
# Not implemented by pyjks
def encrypt(self, key_password: str) -> NoReturn: ...
class KeyStore(AbstractKeystore):
entries: dict[str, TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry] # type: ignore[assignment]
store_type: _JksType
@classmethod
def new(cls, store_type: _JksType, store_entries: Iterable[TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry]) -> Self: ...
@classmethod
def loads(cls, data: bytes, store_password: str | None, try_decrypt_keys: bool = True) -> Self: ...
def saves(self, store_password: str) -> bytes: ...
def __init__(
self, store_type: _JksType, entries: SupportsKeysAndGetItem[str, TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry]
) -> None: ...
@property
def certs(self) -> dict[str, TrustedCertEntry]: ...
@property
def secret_keys(self) -> dict[str, SecretKeyEntry]: ...
@property
def private_keys(self) -> dict[str, PrivateKeyEntry]: ...

View File

@@ -0,0 +1,6 @@
from _typeshed import Incomplete
from pyasn1.type import univ
class PBEParameter(univ.Sequence):
componentType: Incomplete

View File

@@ -0,0 +1,28 @@
from _typeshed import Incomplete
from hashlib import _Hash
from typing_extensions import Final, Literal, TypeAlias
from pyasn1.type import univ
PBE_WITH_SHA1_AND_TRIPLE_DES_CBC_OID: Final[tuple[int, ...]]
PURPOSE_KEY_MATERIAL: Final = 1
PURPOSE_IV_MATERIAL: Final = 2
PURPOSE_MAC_MATERIAL: Final = 3
_Purpose: TypeAlias = Literal[1, 2, 3]
class Pkcs12PBEParams(univ.Sequence):
componentType: Incomplete
def derive_key(
hashfn: _Hash, purpose_byte: _Purpose, password_str: str, salt: bytes, iteration_count: int, desired_key_size: int
) -> bytes: ...
def decrypt_PBEWithSHAAnd3KeyTripleDESCBC(
data: bytes | bytearray, password_str: str, salt: bytes, iteration_count: int
) -> bytes: ...
def decrypt_PBEWithSHAAndTwofishCBC(
encrypted_data: bytes | bytearray, password: str, salt: bytes, iteration_count: int
) -> bytes: ...
def encrypt_PBEWithSHAAndTwofishCBC(
plaintext_data: bytes | bytearray, password: str, salt: bytes, iteration_count: int
) -> bytes: ...

View File

@@ -0,0 +1,8 @@
from typing_extensions import Final
SUN_JKS_ALGO_ID: Final[tuple[int, ...]]
SUN_JCE_ALGO_ID: Final[tuple[int, ...]]
def jks_pkey_encrypt(key: bytes | bytearray, password_str: str) -> bytes: ...
def jks_pkey_decrypt(data: bytes | bytearray, password_str: str) -> bytes: ...
def jce_pbe_decrypt(data: bytes | bytearray, password: str, salt: bytes, iteration_count: int) -> bytes: ...

66
stubs/pyjks/jks/util.pyi Normal file
View File

@@ -0,0 +1,66 @@
from _typeshed import FileDescriptorOrPath, SupportsKeysAndGetItem
from collections.abc import Iterable
from struct import Struct
from typing import Any
from typing_extensions import Final, Literal, Self, TypeAlias
from .bks import BksKeyEntry
from .jks import PrivateKeyEntry
b8: Final[Struct]
b4: Final[Struct]
b2: Final[Struct]
b1: Final[Struct]
py23basestring: Final[tuple[type[str], type[str]]]
RSA_ENCRYPTION_OID: Final[tuple[int, ...]]
DSA_OID: Final[tuple[int, ...]]
DSA_WITH_SHA1_OID: Final[tuple[int, ...]]
_KeystoreType: TypeAlias = Literal["jks", "jceks", "bks", "uber"]
_PemType: TypeAlias = Literal["CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY", "RSA PRIVATE KEY"]
class KeystoreException(Exception): ...
class KeystoreSignatureException(KeystoreException): ...
class DuplicateAliasException(KeystoreException): ...
class NotYetDecryptedException(KeystoreException): ...
class BadKeystoreFormatException(KeystoreException): ...
class BadDataLengthException(KeystoreException): ...
class BadPaddingException(KeystoreException): ...
class BadHashCheckException(KeystoreException): ...
class DecryptionFailureException(KeystoreException): ...
class UnsupportedKeystoreVersionException(KeystoreException): ...
class UnexpectedJavaTypeException(KeystoreException): ...
class UnexpectedAlgorithmException(KeystoreException): ...
class UnexpectedKeyEncodingException(KeystoreException): ...
class UnsupportedKeystoreTypeException(KeystoreException): ...
class UnsupportedKeystoreEntryTypeException(KeystoreException): ...
class UnsupportedKeyFormatException(KeystoreException): ...
class AbstractKeystore:
store_type: _KeystoreType
entries: dict[str, AbstractKeystoreEntry]
def __init__(self, store_type: _KeystoreType, entries: SupportsKeysAndGetItem[str, AbstractKeystoreEntry]) -> None: ...
@classmethod
def load(cls, filename: FileDescriptorOrPath, store_password: str | None, try_decrypt_keys: bool = True) -> Self: ...
def save(self, filename: FileDescriptorOrPath, store_password: str) -> None: ...
class AbstractKeystoreEntry:
store_type: _KeystoreType | None
alias: str
timestamp: int
def __init__(self, *, store_type: _KeystoreType = ..., alias: str = ..., timestamp: int = ..., **kwargs: Any) -> None: ...
@classmethod
def new(cls, alias: str) -> Self: ...
def is_decrypted(self) -> bool: ...
def decrypt(self, key_password: str) -> None: ...
def encrypt(self, key_password: str) -> None: ...
def as_hex(ba: bytes | bytearray) -> str: ...
def as_pem(der_bytes: bytes, type: _PemType) -> str: ...
def bitstring_to_bytes(bitstr: Iterable[int]) -> bytes: ...
def xor_bytearrays(a: bytes | bytearray, b: bytes | bytearray) -> bytearray: ...
def print_pem(der_bytes: bytes, type: _PemType) -> None: ...
def pkey_as_pem(pk: PrivateKeyEntry | BksKeyEntry) -> str: ...
def strip_pkcs5_padding(m: bytes | bytearray) -> bytes: ...
def strip_pkcs7_padding(m: bytes | bytearray, block_size: int) -> bytes: ...
def add_pkcs7_padding(m: bytes | bytearray, block_size: int) -> bytes: ...