예제 #1
0
    def read(encryption_entry: DictionaryObject,
             first_id_entry: bytes) -> "Encryption":
        filter = encryption_entry.get("/Filter")
        if filter != "/Standard":
            raise NotImplementedError(
                "only Standard PDF encryption handler is available")
        if "/SubFilter" in encryption_entry:
            raise NotImplementedError("/SubFilter NOT supported")

        StmF = "/V2"
        StrF = "/V2"
        EFF = "/V2"

        V = encryption_entry.get("/V", 0)
        if V not in (1, 2, 3, 4, 5):
            raise NotImplementedError("Encryption V=%d NOT supported" % V)
        if V >= 4:
            filters = encryption_entry["/CF"]

            StmF = encryption_entry.get("/StmF", "/Identity")
            StrF = encryption_entry.get("/StrF", "/Identity")
            EFF = encryption_entry.get("/EFF", StmF)

            if StmF != "/Identity":
                StmF = filters[StmF]["/CFM"]  # type: ignore
            if StrF != "/Identity":
                StrF = filters[StrF]["/CFM"]  # type: ignore
            if EFF != "/Identity":
                EFF = filters[EFF]["/CFM"]  # type: ignore

            allowed_methods = ("/Identity", "/V2", "/AESV2", "/AESV3")
            if StmF not in allowed_methods:
                raise NotImplementedError("StmF Method {StmF} NOT supported!")
            if StrF not in allowed_methods:
                raise NotImplementedError(f"StrF Method {StrF} NOT supported!")
            if EFF not in allowed_methods:
                raise NotImplementedError(f"EFF Method {EFF} NOT supported!")

        R = cast(int, encryption_entry["/R"])
        return Encryption(V, R, encryption_entry, first_id_entry, StmF, StrF,
                          EFF)
예제 #2
0
    def __init__(
        self,
        algV: int,
        algR: int,
        entry: DictionaryObject,
        first_id_entry: bytes,
        StmF: str,
        StrF: str,
        EFF: str,
    ) -> None:
        # See TABLE 3.18 Entries common to all encryption dictionaries
        self.algV = algV
        self.algR = algR
        self.entry = entry
        self.key_size = entry.get("/Length", 40)
        self.id1_entry = first_id_entry
        self.StmF = StmF
        self.StrF = StrF
        self.EFF = EFF

        # 1 => owner password
        # 2 => user password
        self._password_type = PasswordType.NOT_DECRYPTED
        self._key: Optional[bytes] = None