2025-03-18 00:17:27 +05:30
|
|
|
import base64
|
|
|
|
from enum import Enum
|
|
|
|
from uuid import UUID
|
|
|
|
from typing import Union
|
|
|
|
|
|
|
|
|
|
|
|
class Key:
|
|
|
|
class KeyType(Enum):
|
|
|
|
INVALID = 0x0000
|
|
|
|
AES_128_CTR = 0x0001
|
|
|
|
RC4_CIPHER = 0x0002
|
|
|
|
AES_128_ECB = 0x0003
|
|
|
|
COCKTAIL = 0x0004
|
|
|
|
AES_128_CBC = 0x0005
|
|
|
|
UNKNOWN = 0xffff
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _missing_(cls, value):
|
|
|
|
return cls.UNKNOWN
|
|
|
|
|
|
|
|
class CipherType(Enum):
|
|
|
|
INVALID = 0x0000
|
|
|
|
RSA_1024 = 0x0001
|
|
|
|
CHAINED_LICENSE = 0x0002
|
|
|
|
ECC_256 = 0x0003
|
|
|
|
ECC_256_WITH_KZ = 0x0004
|
2025-03-18 00:23:51 +05:30
|
|
|
SCALABLE = 0x0005
|
2025-03-18 00:17:27 +05:30
|
|
|
UNKNOWN = 0xffff
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _missing_(cls, value):
|
|
|
|
return cls.UNKNOWN
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
key_id: UUID,
|
|
|
|
key_type: int,
|
|
|
|
cipher_type: int,
|
|
|
|
key_length: int,
|
|
|
|
key: bytes
|
|
|
|
):
|
|
|
|
self.key_id = key_id
|
|
|
|
self.key_type = self.KeyType(key_type)
|
|
|
|
self.cipher_type = self.CipherType(cipher_type)
|
|
|
|
self.key_length = key_length
|
|
|
|
self.key = key
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def kid_to_uuid(kid: Union[str, bytes]) -> UUID:
|
|
|
|
"""
|
|
|
|
Convert a Key ID from a string or bytes to a UUID object.
|
|
|
|
At first, this may seem very simple, but some types of Key IDs
|
|
|
|
may not be 16 bytes and some may be decimal vs. hex.
|
|
|
|
"""
|
|
|
|
if isinstance(kid, str):
|
|
|
|
kid = base64.b64decode(kid)
|
|
|
|
if not kid:
|
|
|
|
kid = b"\x00" * 16
|
|
|
|
|
|
|
|
if kid.decode(errors="replace").isdigit():
|
|
|
|
return UUID(int=int(kid.decode()))
|
|
|
|
|
|
|
|
if len(kid) < 16:
|
|
|
|
kid += b"\x00" * (16 - len(kid))
|
|
|
|
|
|
|
|
return UUID(bytes=kid)
|