Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pyjks] Fill in jks.bks and other modules, improved constructors #10815

Merged
merged 8 commits into from
Oct 6, 2023
133 changes: 94 additions & 39 deletions stubs/pyjks/jks/bks.pyi
Original file line number Diff line number Diff line change
@@ -1,69 +1,124 @@
from _typeshed import Incomplete
from typing_extensions import Final, Self
from _typeshed import SupportsKeysAndGetItem, Unused
from typing_extensions import Final, Literal, Self, TypeAlias

from .jks import TrustedCertEntry
from .util import AbstractKeystore, AbstractKeystoreEntry

_BksType: TypeAlias = Literal["bks", "uber"]
_CertType: TypeAlias = Literal["X.509"]
_EntryFormat: TypeAlias = Literal["PKCS8", "PKCS#8", "X.509", "X509", "RAW"]
_BksVersion: TypeAlias = Literal[1, 2]

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
_KeyType: TypeAlias = Literal[0, 1, 2]

class AbstractBksEntry(AbstractKeystoreEntry):
cert_chain: Incomplete
def __init__(self, **kwargs) -> None: ...
store_type: _BksType | None
cert_chain: list[tuple[_CertType, bytes]]
def __init__(
self,
*,
cert_chain: list[tuple[_CertType, bytes]] = ...,
encrypted: bytes | None = None,
store_type: _BksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...

class BksTrustedCertEntry(TrustedCertEntry): ...
class BksTrustedCertEntry(TrustedCertEntry):
store_type: _BksType | None # type: ignore[assignment]

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: ...
type: _KeyType
format: _EntryFormat
algorithm: str
encoded: bytes
# type == KEY_TYPE_PRIVATE
pkey_pkcs8: bytes
pkey: bytes
algorithm_oid: tuple[int, ...]
# type == KEY_TYPE_PUBLIC
public_key_info: bytes
public_key: bytes
# type == KEY_TYPE_SECRET
key: bytes
key_size: int
def __init__(
self,
type: _KeyType,
format: _EntryFormat,
algorithm: str,
encoded: bytes,
*,
cert_chain: list[tuple[_CertType, bytes]] = ...,
encrypted: bytes | None = None,
store_type: _BksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...
@classmethod
def type2str(cls, t): ...
def type2str(cls, t: _KeyType) -> Literal["PRIVATE", "PUBLIC", "SECRET"]: ...
def is_decrypted(self) -> Literal[True]: ...

class BksSecretKeyEntry(AbstractBksEntry):
key: Incomplete
def __init__(self, **kwargs) -> None: ...
def is_decrypted(self): ...
def decrypt(self, key_password) -> None: ...
key: bytes
def is_decrypted(self) -> Literal[True]: ...

class BksSealedKeyEntry(AbstractBksEntry):
def __init__(self, **kwargs) -> None: ...
def __getattr__(self, name): ...
def is_decrypted(self): ...
def decrypt(self, key_password) -> None: ...
# Properties provided by __getattr__
nested: BksKeyEntry | None
# __getattr__ proxies all attributes of nested BksKeyEntry after decrypting
type: _KeyType
format: _EntryFormat
algorithm: str
encoded: bytes
# if type == KEY_TYPE_PRIVATE
pkey_pkcs8: bytes
pkey: bytes
algorithm_oid: tuple[int, ...]
# if type == KEY_TYPE_PUBLIC
public_key_info: bytes
public_key: bytes
# if type == KEY_TYPE_SECRET
key: bytes
key_size: int

class BksKeyStore(AbstractKeystore):
version: Incomplete
def __init__(self, store_type, entries, version: int = 2) -> None: ...
store_type: Literal["bks"]
entries: dict[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry] # type: ignore[assignment]
version: _BksVersion
def __init__(
self,
store_type: Literal["bks"],
entries: SupportsKeysAndGetItem[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry],
version: _BksVersion = 2,
) -> None: ...
@property
def certs(self): ...
def certs(self) -> dict[str, BksTrustedCertEntry]: ...
@property
def secret_keys(self): ...
def plain_keys(self) -> dict[str, BksKeyEntry]: ...
@property
def sealed_keys(self): ...
def sealed_keys(self) -> dict[str, BksSealedKeyEntry]: ...
@property
def plain_keys(self): ...
def secret_keys(self) -> dict[str, BksSecretKeyEntry]: ...
@classmethod
def loads(cls, data, store_password, try_decrypt_keys: bool = True) -> Self: ...
def loads(cls, data: bytes, store_password: str, 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: ...
store_type: Literal["uber"] # type: ignore[assignment]
version: Literal[1]
def __init__(
self,
store_type: Literal["uber"],
entries: SupportsKeysAndGetItem[str, BksTrustedCertEntry | BksKeyEntry | BksSealedKeyEntry | BksSecretKeyEntry],
version: Literal[1] = 1,
) -> None: ...
70 changes: 45 additions & 25 deletions stubs/pyjks/jks/jks.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from _typeshed import Incomplete, SupportsKeysAndGetItem
from _typeshed import SupportsKeysAndGetItem, Unused
from collections.abc import Iterable
from typing import Any, NoReturn
from typing import NoReturn, overload
from typing_extensions import Final, Literal, Self, TypeAlias

from .util import AbstractKeystore, AbstractKeystoreEntry
Expand All @@ -19,15 +19,16 @@ class TrustedCertEntry(AbstractKeystoreEntry):
store_type: _JksType | None
type: _CertType | None
cert: bytes
# NB! For most use cases, use TrustedCertEntry.new() classmethod.
def __init__(
self,
*,
type: _CertType = ...,
cert: bytes = ...,
store_type: _JksType = ...,
alias: str = ...,
timestamp: int = ...,
**kwargs: Any,
type: _CertType | None = None,
cert: bytes,
store_type: _JksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...
@classmethod
def new(cls, alias: str, cert: bytes) -> Self: ... # type: ignore[override]
Expand All @@ -43,18 +44,31 @@ class PrivateKeyEntry(AbstractKeystoreEntry):
def pkey_pkcs8(self) -> bytes: ...
@property
def algorithm_oid(self) -> tuple[int, ...]: ...
# NB! For most use cases, use PrivateKeyEntry.new() classmethod.
# Overloaded: must provide `encrypted` OR `pkey`, `pkey_pkcs8`, `algorithm_oid`
@overload
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,
cert_chain: list[tuple[_CertType, bytes]],
encrypted: bytes,
store_type: _JksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...
@overload
def __init__(
self,
*,
cert_chain: list[tuple[_CertType, bytes]],
pkey: bytes,
pkey_pkcs8: bytes,
algorithm_oid: tuple[int, ...],
store_type: _JksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...
@classmethod
def new( # type: ignore[override]
Expand All @@ -70,17 +84,22 @@ class SecretKeyEntry(AbstractKeystoreEntry):
def key(self) -> bytes: ...
@property
def key_size(self) -> int: ...
# Overloaded: must provide `sealed_obj` OR `algorithm`, `key`, `key_size`
@overload
def __init__(
self, *, sealed_obj: bytes, store_type: _JksType | None = None, alias: str, timestamp: int, **kwargs: Unused
) -> None: ...
@overload
def __init__(
self,
*,
sealed_obj: Incomplete = ...,
algorithm: str = ...,
key: bytes = ...,
key_size: int = ...,
store_type: _JksType = ...,
alias: str = ...,
timestamp: int = ...,
**kwargs: Any,
algorithm: str,
key: bytes,
key_size: int,
store_type: _JksType | None = None,
alias: str,
timestamp: int,
**kwargs: Unused,
) -> None: ...
# Not implemented by pyjks
@classmethod
Expand All @@ -98,6 +117,7 @@ class KeyStore(AbstractKeystore):
@classmethod
def loads(cls, data: bytes, store_password: str | None, try_decrypt_keys: bool = True) -> Self: ...
def saves(self, store_password: str) -> bytes: ...
# NB! For most use cases, use KeyStore.new() classmethod.
def __init__(
self, store_type: _JksType, entries: SupportsKeysAndGetItem[str, TrustedCertEntry | PrivateKeyEntry | SecretKeyEntry]
) -> None: ...
Expand Down
9 changes: 4 additions & 5 deletions stubs/pyjks/jks/rfc2898.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from _typeshed import Incomplete
from pyasn1.type.namedtype import NamedTypes
from pyasn1.type.univ import Sequence

from pyasn1.type import univ

class PBEParameter(univ.Sequence):
componentType: Incomplete
class PBEParameter(Sequence):
componentType: NamedTypes
8 changes: 4 additions & 4 deletions stubs/pyjks/jks/rfc7292.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from _typeshed import Incomplete
from hashlib import _Hash
from typing_extensions import Final, Literal, TypeAlias

from pyasn1.type import univ
from pyasn1.type.namedtype import NamedTypes
from pyasn1.type.univ import Sequence

PBE_WITH_SHA1_AND_TRIPLE_DES_CBC_OID: Final[tuple[int, ...]]
PURPOSE_KEY_MATERIAL: Final = 1
Expand All @@ -11,8 +11,8 @@ PURPOSE_MAC_MATERIAL: Final = 3

_Purpose: TypeAlias = Literal[1, 2, 3]

class Pkcs12PBEParams(univ.Sequence):
componentType: Incomplete
class Pkcs12PBEParams(Sequence):
componentType: NamedTypes

def derive_key(
hashfn: _Hash, purpose_byte: _Purpose, password_str: str, salt: bytes, iteration_count: int, desired_key_size: int
Expand Down
5 changes: 2 additions & 3 deletions stubs/pyjks/jks/util.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from _typeshed import FileDescriptorOrPath, SupportsKeysAndGetItem
from _typeshed import FileDescriptorOrPath, SupportsKeysAndGetItem, Unused
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
Expand Down Expand Up @@ -48,7 +47,7 @@ class AbstractKeystoreEntry:
store_type: _KeystoreType | None
alias: str
timestamp: int
def __init__(self, *, store_type: _KeystoreType = ..., alias: str = ..., timestamp: int = ..., **kwargs: Any) -> None: ...
def __init__(self, *, store_type: _KeystoreType | None = None, alias: str, timestamp: int, **kwargs: Unused) -> None: ...
@classmethod
def new(cls, alias: str) -> Self: ...
def is_decrypted(self) -> bool: ...
Expand Down