from _typeshed import FileDescriptorOrPath, SupportsKeysAndGetItem, Unused
from collections.abc import Iterable
from struct import Struct
from typing import Final, Literal, TypeAlias
from typing_extensions import Self

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 | None = None, alias: str, timestamp: int, **kwargs: Unused) -> 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: ...
