""" Java security standard library APIs implemented in Python. java.security package - MessageDigest, SecureRandom, KeyStore, Signature, etc. """ from .._core import Stub, AndroidOnlyError from .lang import RuntimeException import hashlib as _hashlib import os as _os GeneralSecurityException = type("GeneralSecurityException", (RuntimeException,), {}) IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) DigestException = type("DigestException", (GeneralSecurityException,), {}) InvalidAlgorithmParameterException = type("InvalidAlgorithmParameterException", (GeneralSecurityException,), {}) InvalidKeyException = type("InvalidKeyException", (GeneralSecurityException,), {}) InvalidKeySpecException = type("InvalidKeySpecException", (GeneralSecurityException,), {}) InvalidParameterException = type("InvalidParameterException", (IllegalArgumentException,), {}) KeyException = type("KeyException", (GeneralSecurityException,), {}) KeyManagementException = type("KeyManagementException", (KeyException,), {}) KeyStoreException = type("KeyStoreException", (GeneralSecurityException,), {}) NoSuchAlgorithmException = type("NoSuchAlgorithmException", (GeneralSecurityException,), {}) NoSuchProviderException = type("NoSuchProviderException", (GeneralSecurityException,), {}) ProviderException = type("ProviderException", (RuntimeException,), {}) SignatureException = type("SignatureException", (GeneralSecurityException,), {}) __all__ = [ "MessageDigest", "MessageDigestSpi", "SecureRandom", "SecureRandomSpi", "KeyStore", "KeyStoreSpi", "Key", "PrivateKey", "PublicKey", "KeyPair", "KeyPairGenerator", "KeyPairGeneratorSpi", "KeyFactory", "KeyFactorySpi", "KeySpec", "SecretKeySpec", "RSAPublicKeySpec", "RSAPrivateKeySpec", "PKCS8EncodedKeySpec", "X509EncodedKeySpec", "AlgorithmParameters", "AlgorithmParameterGenerator", "AlgorithmParameterGeneratorSpi", "AlgorithmParametersSpi", "Provider", "Security", "DigestInputStream", "DigestOutputStream", "Signature", "SignatureSpi", "CodeSigner", "CodeSource", "Policy", "Permission", "AllPermission", "BasicPermission", "PermissionCollection", "Principal", "CertPath", "CertPathBuilder", "CertPathBuilderSpi", "CertPathValidator", "CertPathValidatorSpi", "CertificateFactory", "CertificateFactorySpi", "CertStore", "CertStoreSpi", "CRL", "X509CRL", "X509Certificate", "X509Extension", "Guard", "GuardedObject", "Identity", "IdentityScope", "Signer", "Timestamp", "UnresolvedPermission", "GeneralSecurityException", "DigestException", "InvalidAlgorithmParameterException", "InvalidKeyException", "InvalidKeySpecException", "InvalidParameterException", "KeyException", "KeyManagementException", "KeyStoreException", "NoSuchAlgorithmException", "NoSuchProviderException", "ProviderException", "SignatureException", ] # ============================================================ # Key interfaces # ============================================================ class Key(Stub): def getAlgorithm(self): return "" def getFormat(self): return "" def getEncoded(self): return b"" class PrivateKey(Key): pass class PublicKey(Key): pass # ============================================================ # KeySpec / SecretKeySpec / RSA specs / EncodedKeySpecs # ============================================================ class KeySpec(Stub): pass class SecretKeySpec(KeySpec, Key): def __init__(self, key_bytes, algorithm): super().__init__() self._key = key_bytes self._algorithm = algorithm def getAlgorithm(self): return self._algorithm def getFormat(self): return "RAW" def getEncoded(self): return self._key def hashCode(self): return hash(self._key) ^ hash(self._algorithm) class RSAPublicKeySpec(KeySpec): def __init__(self, modulus, public_exponent): super().__init__() self._modulus = modulus self._public_exponent = public_exponent def getModulus(self): return self._modulus def getPublicExponent(self): return self._public_exponent class RSAPrivateKeySpec(KeySpec): def __init__(self, modulus, private_exponent): super().__init__() self._modulus = modulus self._private_exponent = private_exponent def getModulus(self): return self._modulus def getPrivateExponent(self): return self._private_exponent class PKCS8EncodedKeySpec(KeySpec): def __init__(self, encoded_key): super().__init__() self._encoded_key = encoded_key def getEncoded(self): return self._encoded_key def getFormat(self): return "PKCS#8" class X509EncodedKeySpec(KeySpec): def __init__(self, encoded_key): super().__init__() self._encoded_key = encoded_key def getEncoded(self): return self._encoded_key def getFormat(self): return "X.509" # ============================================================ # KeyPair # ============================================================ class KeyPair(Stub): def __init__(self, public_key, private_key): super().__init__() self._public = public_key self._private = private_key def getPublic(self): return self._public def getPrivate(self): return self._private # ============================================================ # KeyPairGenerator # ============================================================ class KeyPairGenerator(Stub): def __init__(self, algorithm): super().__init__() self._algorithm = algorithm self._keysize = 2048 @staticmethod def getInstance(algorithm, provider=None): return KeyPairGenerator(algorithm) def initialize(self, keysize_or_spec, random=None): if isinstance(keysize_or_spec, int): self._keysize = keysize_or_spec def generateKeyPair(self): return KeyPair(PublicKey(), PrivateKey()) def getAlgorithm(self): return self._algorithm def getProvider(self): return Provider("SUN", 1.0, "Default provider") # ============================================================ # KeyFactory # ============================================================ class KeyFactory(Stub): def __init__(self, algorithm): super().__init__() self._algorithm = algorithm @staticmethod def getInstance(algorithm, provider=None): return KeyFactory(algorithm) def generatePublic(self, key_spec): return PublicKey() def generatePrivate(self, key_spec): return PrivateKey() def getKeySpec(self, key, key_spec_cls): if key_spec_cls == X509EncodedKeySpec: return X509EncodedKeySpec(key.getEncoded()) raise InvalidKeySpecException("Unsupported key spec") def translateKey(self, key): return key def getAlgorithm(self): return self._algorithm # ============================================================ # KeyFactorySpi / KeyPairGeneratorSpi (stubs) # ============================================================ class KeyFactorySpi(Stub): pass class KeyPairGeneratorSpi(Stub): pass # ============================================================ # MessageDigest # ============================================================ class MessageDigest(Stub): _MD_MAP = { "MD5": "md5", "SHA-1": "sha1", "SHA": "sha1", "SHA-224": "sha224", "SHA-256": "sha256", "SHA-384": "sha384", "SHA-512": "sha512", } def __init__(self, algorithm): super().__init__() self._algorithm = algorithm algo_lower = algorithm.replace("-", "").lower() if algo_lower in ("md5", "sha1", "sha224", "sha256", "sha384", "sha512"): self._impl = _hashlib.new(algo_lower) else: self._impl = _hashlib.new("sha256") @staticmethod def getInstance(algorithm, provider=None): if algorithm not in MessageDigest._MD_MAP: raise NoSuchAlgorithmException(f"{algorithm} not available") return MessageDigest(algorithm) def update(self, data, offset=0, length=-1): if length < 0: self._impl.update(data) else: self._impl.update(data[offset:offset+length]) def digest(self, data=None): if data is not None: self._impl.update(data) return self._impl.digest() def toString(self): return f"MessageDigest: {self._algorithm}" def getAlgorithm(self): return self._algorithm def getProvider(self): return Provider("SUN", 1.0, "Default provider") def getDigestLength(self): return self._impl.digest_size @staticmethod def isEqual(digest_a, digest_b): return digest_a == digest_b def clone(self): md = MessageDigest(self._algorithm) md._impl = self._impl.copy() return md def reset(self): self._impl = _hashlib.new(self._algorithm.replace("-", "").lower()) class MessageDigestSpi(Stub): pass # ============================================================ # SecureRandom # ============================================================ class SecureRandom(Stub): def __init__(self, seed=None): super().__init__() import random as _random self._random = _random.Random() if seed is not None: self._random.seed(seed) def nextBytes(self, bytes_arr): data = _os.urandom(len(bytes_arr)) for i in range(len(bytes_arr)): bytes_arr[i] = data[i] def nextInt(self, bound=None): if bound is None: return int.from_bytes(_os.urandom(4), "big") return int.from_bytes(_os.urandom(4), "big") % bound def nextLong(self): return int.from_bytes(_os.urandom(8), "big") def nextBoolean(self): return int.from_bytes(_os.urandom(1), "big") % 2 == 0 def nextFloat(self): return int.from_bytes(_os.urandom(4), "big") / 4294967296.0 def nextDouble(self): return int.from_bytes(_os.urandom(8), "big") / 18446744073709551616.0 def nextGaussian(self): import random as _random return _random.gauss(0, 1) def generateSeed(self, num_bytes): return _os.urandom(num_bytes) def getAlgorithm(self): return "SHA1PRNG" def getProvider(self): return Provider("SUN", 1.0, "Default provider") def setSeed(self, seed): self._random.seed(seed) def getSeed(self, num_bytes): return _os.urandom(num_bytes) class SecureRandomSpi(Stub): pass # ============================================================ # Provider / Security # ============================================================ class Provider(Stub): def __init__(self, name, version, info): super().__init__() self._name = name self._version = version self._info = info self._properties = {} def getName(self): return self._name def getVersion(self): return self._version def getInfo(self): return self._info def getProperty(self, key): return self._properties.get(key) def setProperty(self, key, value): self._properties[key] = value def toString(self): return f"{self._name} v{self._version}" class Security(Stub): _providers = [Provider("SUN", 1.0, "SUN provider")] @staticmethod def getProvider(name): for p in Security._providers: if p.getName() == name: return p return None @staticmethod def getProviders(): return Security._providers @staticmethod def addProvider(provider): Security._providers.append(provider) return len(Security._providers) - 1 @staticmethod def removeProvider(name): for i, p in enumerate(Security._providers): if p.getName() == name: Security._providers.pop(i) return @staticmethod def getAlgorithms(service_name): if service_name == "MessageDigest": return list(MessageDigest._MD_MAP.keys()) return [] # ============================================================ # DigestInputStream / DigestOutputStream # ============================================================ class DigestInputStream(Stub): def __init__(self, stream, digest): super().__init__() self._stream = stream self._digest = digest def getMessageDigest(self): return self._digest def setMessageDigest(self, digest): self._digest = digest def read(self, b=None, off=0, length=0): if b is None: data = self._stream.read() else: data = self._stream.read(length) if data: self._digest.update(data) return data def toString(self): return f"DigestInputStream: {self._digest}" class DigestOutputStream(Stub): def __init__(self, stream, digest): super().__init__() self._stream = stream self._digest = digest def getMessageDigest(self): return self._digest def setMessageDigest(self, digest): self._digest = digest def write(self, b, off=0, length=0): if isinstance(b, (bytes, bytearray)): data = b if length == 0 else b[off:off+length] else: data = bytes([b]) self._digest.update(data) self._stream.write(data) def toString(self): return f"DigestOutputStream: {self._digest}" # ============================================================ # Signature # ============================================================ class Signature(Stub): def __init__(self, algorithm): super().__init__() self._algorithm = algorithm self._state = "UNINITIALIZED" self._impl = _hashlib.new("sha256") @staticmethod def getInstance(algorithm, provider=None): return Signature(algorithm) def initSign(self, private_key, random=None): self._state = "SIGN" def initVerify(self, public_key): self._state = "VERIFY" def update(self, data, off=0, length=-1): if length < 0: self._impl.update(data) else: self._impl.update(data[off:off+length]) def sign(self): self._state = "UNINITIALIZED" return self._impl.digest() def verify(self, signature): self._state = "UNINITIALIZED" return self._impl.digest() == signature def setParameter(self, param, value=None): pass def getParameters(self): return None def getAlgorithm(self): return self._algorithm def getProvider(self): return Provider("SUN", 1.0, "SUN provider") class SignatureSpi(Stub): pass # ============================================================ # KeyStore # ============================================================ class KeyStore(Stub): class PasswordProtection(Stub): def __init__(self, password): super().__init__() self._password = password def getPassword(self): return self._password class Entry(Stub): pass class PrivateKeyEntry(Entry): def __init__(self, private_key, cert_chain): super().__init__() self._private_key = private_key self._cert_chain = cert_chain def getPrivateKey(self): return self._private_key def getCertificateChain(self): return self._cert_chain class SecretKeyEntry(Entry): def __init__(self, secret_key): super().__init__() self._secret_key = secret_key def getSecretKey(self): return self._secret_key class TrustedCertificateEntry(Entry): def __init__(self, cert): super().__init__() self._cert = cert def getTrustedCertificate(self): return self._cert def __init__(self, type_name="JKS"): super().__init__() self._type = type_name self._entries = {} self._loaded = False @staticmethod def getInstance(type_name, provider=None): return KeyStore(type_name) def load(self, stream=None, password=None): self._loaded = True def store(self, stream, password): pass def setKeyEntry(self, alias, key, password, chain): self._entries[alias] = (key, chain) def setCertificateEntry(self, alias, cert): self._entries[alias] = cert def getKey(self, alias, password): entry = self._entries.get(alias) if isinstance(entry, tuple): return entry[0] return None def getCertificate(self, alias): entry = self._entries.get(alias) if isinstance(entry, tuple): return entry[1][0] if entry[1] else None return entry def getCertificateChain(self, alias): entry = self._entries.get(alias) if isinstance(entry, tuple): return entry[1] return None def getCertificateAliases(self, cert): return [] def aliases(self): return list(self._entries.keys()) def containsAlias(self, alias): return alias in self._entries def deleteEntry(self, alias): if alias in self._entries: del self._entries[alias] def size(self): return len(self._entries) def isCertificateEntry(self, alias): return alias in self._entries and not isinstance(self._entries[alias], tuple) def isKeyEntry(self, alias): return alias in self._entries and isinstance(self._entries[alias], tuple) def getType(self): return self._type def getProvider(self): return Provider("SUN", 1.0, "SUN provider") def getCreationDate(self, alias): from datetime import datetime return datetime.now() class KeyStoreSpi(Stub): pass # ============================================================ # X509Certificate # ============================================================ class X509Certificate(Stub): def __init__(self): super().__init__() self._encoded = b"" def getSubjectX500Principal(self): return Principal() def getIssuerX500Principal(self): return Principal() def getSerialNumber(self): return 0 def getNotBefore(self): from datetime import datetime return datetime.now() def getNotAfter(self): from datetime import datetime return datetime.now() def getSigAlgName(self): return "SHA256withRSA" def getSigAlgOID(self): return "1.2.840.113549.1.1.11" def getVersion(self): return 3 def getPublicKey(self): return PublicKey() def getEncoded(self): return self._encoded def verify(self, key): return True def checkValidity(self, date=None): return True def toString(self): return "X509Certificate" # ============================================================ # AlgorithmParameters / AlgorithmParameterGenerator (stubs) # ============================================================ class AlgorithmParameters(Stub): def __init__(self, algorithm): super().__init__() self._algorithm = algorithm @staticmethod def getInstance(algorithm, provider=None): return AlgorithmParameters(algorithm) def init(self, params, format=None): pass def getEncoded(self, format=None): return b"" def getAlgorithm(self): return self._algorithm def getProvider(self): return Provider("SUN", 1.0, "SUN provider") def toString(self): return f"{self._algorithm} parameters" class AlgorithmParametersSpi(Stub): pass class AlgorithmParameterGenerator(Stub): @staticmethod def getInstance(algorithm, provider=None): return AlgorithmParameterGenerator() def init(self, size_or_genparam, random=None): pass def generateParameters(self): return AlgorithmParameters("DSA") class AlgorithmParameterGeneratorSpi(Stub): pass # ============================================================ # Permission / AllPermission / BasicPermission (stubs) # ============================================================ class Permission(Stub): def __init__(self, name): super().__init__() self._name = name def getName(self): return self._name def getActions(self): return "" def implies(self, permission): return True def equals(self, obj): return isinstance(obj, Permission) and self._name == obj._name def hashCode(self): return hash(self._name) def toString(self): return f"({self.__class__.__name__} {self._name})" class AllPermission(Permission): def __init__(self): super().__init__("") class BasicPermission(Permission): def __init__(self, name, actions=None): super().__init__(name) class PermissionCollection(Stub): def __init__(self): super().__init__() self._permissions = [] def add(self, permission): self._permissions.append(permission) def implies(self, permission): return True def elements(self): return iter(self._permissions) def toString(self): return str(self._permissions) class UnresolvedPermission(Permission): def __init__(self, type_name, name, actions, certs): super().__init__(name) self._unresolved_type = type_name self._unresolved_actions = actions self._certs = certs def getUnresolvedType(self): return self._unresolved_type def getUnresolvedActions(self): return self._unresolved_actions def getUnresolvedCerts(self): return self._certs # ============================================================ # Principal / CodeSource / Policy (stubs) # ============================================================ class Principal(Stub): def __init__(self, name=""): super().__init__() self._name = name def getName(self): return self._name def toString(self): return self._name def equals(self, other): return isinstance(other, Principal) and self._name == other._name def hashCode(self): return hash(self._name) class CodeSource(Stub): def __init__(self, location, certs): super().__init__() self._location = location def getLocation(self): return self._location def getCertificates(self): return [] def implies(self, codesource): return True class Policy(Stub): _policy = None @staticmethod def getPolicy(): if Policy._policy is None: Policy._policy = Policy() return Policy._policy @staticmethod def setPolicy(policy): Policy._policy = policy def getPermissions(self, codesource): return PermissionCollection() def implies(self, cs, perm): return True def refresh(self): pass # ============================================================ # CertPath / CertPathBuilder / CertPathValidator (stubs) # ============================================================ class CertPath(Stub): def __init__(self, algorithm): super().__init__() self._algorithm = algorithm self._certs = [] def getCertificates(self): return self._certs def getType(self): return self._algorithm def getEncoded(self): return b"" def toString(self): return f"CertPath: {self._algorithm}" class CertPathBuilder(Stub): @staticmethod def getInstance(algorithm, provider=None): return CertPathBuilder() def build(self, params): return CertPath("X.509") class CertPathBuilderSpi(Stub): pass class CertPathValidator(Stub): @staticmethod def getInstance(algorithm, provider=None): return CertPathValidator() def validate(self, cert_path, params): return None class CertPathValidatorSpi(Stub): pass class CertificateFactory(Stub): @staticmethod def getInstance(algorithm, provider=None): return CertificateFactory() def generateCertificate(self, in_stream): return X509Certificate() def generateCertPath(self, in_stream): return CertPath("X.509") def getCertPathEncodings(self): return ["PKCS7"] class CertificateFactorySpi(Stub): pass class CertStore(Stub): @staticmethod def getInstance(type_name, params, provider=None): return CertStore() def getCertificates(self, selector): return [] def getCRLs(self, selector): return [] class CertStoreSpi(Stub): pass # ============================================================ # CRL / X509CRL (stubs) # ============================================================ class CRL(Stub): def __init__(self): super().__init__() def isRevoked(self, cert): return False def toString(self): return "CRL" class X509CRL(CRL): def __init__(self): super().__init__() def getEncoded(self): return b"" def verify(self, key): return True def getIssuerX500Principal(self): return Principal() def toString(self): return "X509CRL" class X509Extension(Stub): pass # ============================================================ # Guard / GuardedObject (stubs) # ============================================================ class Guard(Stub): def checkGuard(self, object): pass class GuardedObject(Stub): def __init__(self, object, guard): super().__init__() self._object = object def getObject(self): return self._object # ============================================================ # Identity / IdentityScope / Signer (stubs) # ============================================================ class Identity(Stub): def __init__(self, name, scope=None): super().__init__() self._name = name def getName(self): return self._name def getPublicKey(self): return PublicKey() def setPublicKey(self, key): pass def toString(self): return self._name def getScope(self): return None class IdentityScope(Identity): def __init__(self, name): super().__init__(name) def getIdentity(self, name): return None def addIdentity(self, identity): pass def removeIdentity(self, identity): pass def identities(self): return [] @staticmethod def getSystemScope(): return None def size(self): return 0 def toString(self): return self._name class Signer(Identity): def __init__(self, name): super().__init__(name) def getPrivateKey(self): return PrivateKey() def setKeyPair(self, pair): pass def toString(self): return self._name # ============================================================ # CodeSigner / Timestamp (stubs) # ============================================================ class Timestamp(Stub): def __init__(self, timestamp, signer_cert_path): super().__init__() self._timestamp = timestamp def getTimestamp(self): return self._timestamp def getSignerCertPath(self): return CertPath("X.509") def equals(self, other): return isinstance(other, Timestamp) def hashCode(self): return 0 def toString(self): return "Timestamp" class CodeSigner(Stub): def __init__(self, signer_cert_path, timestamp): super().__init__() self._signer_cert_path = signer_cert_path self._timestamp = timestamp def getSignerCertPath(self): return self._signer_cert_path def getTimestamp(self): return self._timestamp def equals(self, other): return isinstance(other, CodeSigner) def hashCode(self): return 0 def toString(self): return "CodeSigner"