""" Java security.spec standard library APIs implemented in Python. java.security.spec package - KeySpec, AlgorithmParameterSpec, etc. """ from __future__ import annotations from .._core import Stub, AndroidOnlyError from .security import GeneralSecurityException, InvalidKeySpecException, InvalidParameterException from .lang import RuntimeException import math as _py_math __all__ = [ "KeySpec", "EncodedKeySpec", "PKCS8EncodedKeySpec", "X509EncodedKeySpec", "DSAPrivateKeySpec", "DSAPublicKeySpec", "RSAPrivateKeySpec", "RSAPublicKeySpec", "RSAPrivateCrtKeySpec", "RSAOtherPrimeInfo", "ECPrivateKeySpec", "ECPublicKeySpec", "ECField", "ECFieldF2m", "ECFieldFp", "EllipticCurve", "ECGenParameterSpec", "ECParameterSpec", "ECPoint", "AlgorithmParameterSpec", "IvParameterSpec", "OAEPParameterSpec", "PSSParameterSpec", "MGF1ParameterSpec", "PBEParameterSpec", "RC2ParameterSpec", "RC5ParameterSpec", "DHParameterSpec", "DHGenParameterSpec", "DHPrivateKeySpec", "DHPublicKeySpec", "DSAGenParameterSpec", ] # ============================================================ # KeySpec # ============================================================ class KeySpec(Stub): """java.security.spec.KeySpec""" pass class EncodedKeySpec(KeySpec): """java.security.spec.EncodedKeySpec""" def __init__(self, encoded_key): super().__init__() self._encoded_key = bytes(encoded_key) def getEncoded(self): return self._encoded_key def getFormat(self): raise NotImplementedError class PKCS8EncodedKeySpec(EncodedKeySpec): """java.security.spec.PKCS8EncodedKeySpec""" def __init__(self, encoded_key): super().__init__(encoded_key) def getFormat(self): return "PKCS#8" class X509EncodedKeySpec(EncodedKeySpec): """java.security.spec.X509EncodedKeySpec""" def __init__(self, encoded_key): super().__init__(encoded_key) def getFormat(self): return "X.509" # ============================================================ # DSA KeySpecs # ============================================================ class DSAPrivateKeySpec(KeySpec): """java.security.spec.DSAPrivateKeySpec""" def __init__(self, x, p, q, g): super().__init__() self._x = x self._p = p self._q = q self._g = g def getX(self): return self._x def getP(self): return self._p def getQ(self): return self._q def getG(self): return self._g class DSAPublicKeySpec(KeySpec): """java.security.spec.DSAPublicKeySpec""" def __init__(self, y, p, q, g): super().__init__() self._y = y self._p = p self._q = q self._g = g def getY(self): return self._y def getP(self): return self._p def getQ(self): return self._q def getG(self): return self._g # ============================================================ # RSA KeySpecs # ============================================================ class RSAPrivateKeySpec(KeySpec): """java.security.spec.RSAPrivateKeySpec""" 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 RSAPublicKeySpec(KeySpec): """java.security.spec.RSAPublicKeySpec""" 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 RSAPrivateCrtKeySpec(RSAPrivateKeySpec): """java.security.spec.RSAPrivateCrtKeySpec""" def __init__(self, modulus, public_exponent, private_exponent, prime_p, prime_q, prime_exponent_p, prime_exponent_q, crt_coefficient): super().__init__(modulus, private_exponent) self._public_exponent = public_exponent self._prime_p = prime_p self._prime_q = prime_q self._prime_exponent_p = prime_exponent_p self._prime_exponent_q = prime_exponent_q self._crt_coefficient = crt_coefficient def getPublicExponent(self): return self._public_exponent def getPrimeP(self): return self._prime_p def getPrimeQ(self): return self._prime_q def getPrimeExponentP(self): return self._prime_exponent_p def getPrimeExponentQ(self): return self._prime_exponent_q def getCrtCoefficient(self): return self._crt_coefficient class RSAOtherPrimeInfo(Stub): """java.security.spec.RSAOtherPrimeInfo""" def __init__(self, prime, exponent, coefficient): super().__init__() self._prime = prime self._exponent = exponent self._coefficient = coefficient def getPrime(self): return self._prime def getExponent(self): return self._exponent def getCrtCoefficient(self): return self._coefficient # ============================================================ # EC KeySpecs # ============================================================ class ECPoint(Stub): """java.security.spec.ECPoint""" def __init__(self, affine_x, affine_y): super().__init__() self._affine_x = affine_x self._affine_y = affine_y def getAffineX(self): return self._affine_x def getAffineY(self): return self._affine_y def equals(self, other): if not isinstance(other, ECPoint): return False return self._affine_x == other._affine_x and self._affine_y == other._affine_y def hashCode(self): return hash((self._affine_x, self._affine_y)) def toString(self): return f"ECPoint(x={self._affine_x}, y={self._affine_y})" POINT_INFINITY = None class ECField(Stub): """java.security.spec.ECField""" def getFieldSize(self): raise NotImplementedError class ECFieldFp(ECField): """java.security.spec.ECFieldFp""" def __init__(self, prime): super().__init__() self._prime = prime def getP(self): return self._prime def getFieldSize(self): return self._prime.bit_length() def equals(self, other): if not isinstance(other, ECFieldFp): return False return self._prime == other._prime def hashCode(self): return hash(self._prime) class ECFieldF2m(ECField): """java.security.spec.ECFieldF2m""" def __init__(self, m, ks=None, rp=None): super().__init__() self._m = m if ks is not None and rp is None: if isinstance(ks, int): self._ks = [ks] self._rp = None else: self._ks = list(ks) self._rp = None elif rp is not None: self._ks = None self._rp = rp else: self._ks = None self._rp = None def getM(self): return self._m def getKs(self): return self._ks def getFieldSize(self): return self._m def getReductionPolynomial(self): return self._rp def equals(self, other): if not isinstance(other, ECFieldF2m): return False return self._m == other._m and self._ks == other._ks and self._rp == other._rp def hashCode(self): return hash(self._m) class EllipticCurve(Stub): """java.security.spec.EllipticCurve""" def __init__(self, field, a, b, seed=None): super().__init__() self._field = field self._a = a self._b = b self._seed = seed def getField(self): return self._field def getA(self): return self._a def getB(self): return self._b def getSeed(self): return self._seed def equals(self, other): if not isinstance(other, EllipticCurve): return False return (self._field == other._field and self._a == other._a and self._b == other._b) def hashCode(self): return hash((self._field, self._a, self._b)) class ECParameterSpec(Stub): """java.security.spec.ECParameterSpec""" def __init__(self, curve, generator, order, cofactor): super().__init__() self._curve = curve self._generator = generator self._order = order self._cofactor = cofactor def getCurve(self): return self._curve def getGenerator(self): return self._generator def getOrder(self): return self._order def getCofactor(self): return self._cofactor def toString(self): return f"ECParameterSpec [order={self._order}]" class ECGenParameterSpec(Stub): """java.security.spec.ECGenParameterSpec""" def __init__(self, name): super().__init__() self._name = name def getName(self): return self._name def toString(self): return f"ECGenParameterSpec [name={self._name}]" class ECPrivateKeySpec(KeySpec): """java.security.spec.ECPrivateKeySpec""" def __init__(self, s, params): super().__init__() self._s = s self._params = params def getS(self): return self._s def getParams(self): return self._params class ECPublicKeySpec(KeySpec): """java.security.spec.ECPublicKeySpec""" def __init__(self, w, params): super().__init__() self._w = w self._params = params def getW(self): return self._w def getParams(self): return self._params # ============================================================ # AlgorithmParameterSpec # ============================================================ class AlgorithmParameterSpec(Stub): """java.security.spec.AlgorithmParameterSpec""" pass class IvParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.IvParameterSpec""" def __init__(self, iv, offset=0, length=None): super().__init__() if length is None: self._iv = bytes(iv[offset:]) else: self._iv = bytes(iv[offset:offset + length]) def getIV(self): return self._iv class OAEPParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.OAEPParameterSpec""" def __init__(self, md_name="SHA-256", mgf_name="MGF1", mgf_spec=None, p_src=None): super().__init__() self._md_name = md_name self._mgf_name = mgf_name self._mgf_spec = mgf_spec or MGF1ParameterSpec.SHA256 self._p_src = p_src def getDigestAlgorithm(self): return self._md_name def getMGFAlgorithm(self): return self._mgf_name def getMGFParameters(self): return self._mgf_spec def getPSource(self): return self._p_src DEFAULT = None class PSSParameterSpec(AlgorithmParameterSpec): """java.security.spec.PSSParameterSpec""" def __init__(self, md_name="SHA-256", mgf_name="MGF1", mgf_spec=None, salt_len=None, trailer_field=1): super().__init__() if isinstance(md_name, int): # Legacy constructor: PSSParameterSpec(int saltLen) self._salt_len = md_name self._md_name = "SHA-1" self._mgf_name = "MGF1" self._mgf_spec = MGF1ParameterSpec.SHA1 self._trailer_field = 1 else: self._md_name = md_name self._mgf_name = mgf_name self._mgf_spec = mgf_spec or MGF1ParameterSpec.SHA256 self._salt_len = salt_len if salt_len is not None else 32 self._trailer_field = trailer_field def getDigestAlgorithm(self): return self._md_name def getMGFAlgorithm(self): return self._mgf_name def getMGFParameters(self): return self._mgf_spec def getSaltLength(self): return self._salt_len def getTrailerField(self): return self._trailer_field DEFAULT = None TRAILER_FIELD_BC = 1 class MGF1ParameterSpec(AlgorithmParameterSpec): """java.security.spec.MGF1ParameterSpec""" def __init__(self, md_name): super().__init__() self._md_name = md_name def getDigestAlgorithm(self): return self._md_name def toString(self): return f"MGF1ParameterSpec [{self._md_name}]" SHA1 = None SHA224 = None SHA256 = None SHA384 = None SHA512 = None class PBEParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.PBEParameterSpec""" def __init__(self, salt, iteration_count): super().__init__() self._salt = bytes(salt) self._iteration_count = iteration_count def getSalt(self): return self._salt def getIterationCount(self): return self._iteration_count class RC2ParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.RC2ParameterSpec""" def __init__(self, effective_key_bits, iv=None, offset=0): super().__init__() self._effective_key_bits = effective_key_bits if iv is not None: self._iv = bytes(iv[offset:offset + 8]) if offset + 8 <= len(iv) else bytes(iv[offset:]) else: self._iv = None def getEffectiveKeyBits(self): return self._effective_key_bits def getIV(self): return self._iv def equals(self, other): if not isinstance(other, RC2ParameterSpec): return False return (self._effective_key_bits == other._effective_key_bits and self._iv == other._iv) def hashCode(self): return hash(self._effective_key_bits) ^ hash(self._iv) class RC5ParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.RC5ParameterSpec""" def __init__(self, version, rounds, word_size, iv=None, offset=0): super().__init__() self._version = version self._rounds = rounds self._word_size = word_size if iv is not None: self._iv = bytes(iv[offset:offset + 8]) if offset + 8 <= len(iv) else bytes(iv[offset:]) else: self._iv = None def getVersion(self): return self._version def getRounds(self): return self._rounds def getWordSize(self): return self._word_size def getIV(self): return self._iv def equals(self, other): if not isinstance(other, RC5ParameterSpec): return False return (self._version == other._version and self._rounds == other._rounds and self._word_size == other._word_size and self._iv == other._iv) def hashCode(self): return hash((self._version, self._rounds, self._word_size, bytes(self._iv) if self._iv else b"")) # ============================================================ # DH (Diffie-Hellman) Specs # ============================================================ class DHParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.DHParameterSpec""" def __init__(self, p, g, l=0): super().__init__() self._p = p self._g = g self._l = l def getP(self): return self._p def getG(self): return self._g def getL(self): return self._l class DHGenParameterSpec(AlgorithmParameterSpec): """javax.crypto.spec.DHGenParameterSpec""" def __init__(self, prime_size, exponent_size): super().__init__() self._prime_size = prime_size self._exponent_size = exponent_size def getPrimeSize(self): return self._prime_size def getExponentSize(self): return self._exponent_size class DHPrivateKeySpec(KeySpec): """javax.crypto.spec.DHPrivateKeySpec""" def __init__(self, x, p, g): super().__init__() self._x = x self._p = p self._g = g def getX(self): return self._x def getP(self): return self._p def getG(self): return self._g class DHPublicKeySpec(KeySpec): """javax.crypto.spec.DHPublicKeySpec""" def __init__(self, y, p, g): super().__init__() self._y = y self._p = p self._g = g def getY(self): return self._y def getP(self): return self._p def getG(self): return self._g # ============================================================ # DSAGenParameterSpec # ============================================================ class DSAGenParameterSpec(AlgorithmParameterSpec): """java.security.spec.DSAGenParameterSpec""" def __init__(self, prime_pl, subprime_ql, seed_len): super().__init__() self._prime_pl = prime_pl self._subprime_ql = subprime_ql self._seed_len = seed_len def getPrimePL(self): return self._prime_pl def getSubprimeQL(self): return self._subprime_ql def getSeedLen(self): return self._seed_len # ============================================================ # Initialize MGF1ParameterSpec constants # ============================================================ MGF1ParameterSpec.SHA1 = MGF1ParameterSpec("SHA-1") MGF1ParameterSpec.SHA224 = MGF1ParameterSpec("SHA-224") MGF1ParameterSpec.SHA256 = MGF1ParameterSpec("SHA-256") MGF1ParameterSpec.SHA384 = MGF1ParameterSpec("SHA-384") MGF1ParameterSpec.SHA512 = MGF1ParameterSpec("SHA-512") # ============================================================ # Initialize OAEPParameterSpec DEFAULT # ============================================================ OAEPParameterSpec.DEFAULT = OAEPParameterSpec( "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, None ) # ============================================================ # Initialize PSSParameterSpec DEFAULT # ============================================================ PSSParameterSpec.DEFAULT = PSSParameterSpec( "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1 ) # ============================================================ # ECPoint.POINT_INFINITY # ============================================================ ECPoint.POINT_INFINITY = ECPoint(None, None)