def securityFileSourceFile(cntlr, ownerObject, filepath, binary, stripDeclaration): # handle FileSource file requests which can return encrypted contents if ownerObject.hasEncryption: for entrypointfile in ownerObject.entrypointfiles: if (filepath == entrypointfile.get("file") or any(filepath == ixfile.get("file") for ixfile in entrypointfile.get("ixds",())) ) and "key" in entrypointfile and "iv" in entrypointfile: ownerObject.cipherIv = base64.decodebytes(entrypointfile["iv"].encode()) ownerObject.cipherKey = base64.decodebytes(entrypointfile["key"].encode()) break # set new iv, key based on entrypointfiles # may be a non-entry file (xsd, linkbase, jpg) using entry's iv, key if os.path.exists(filepath + ENCRYPTED_FILE_SUFFIX) and ownerObject.cipherKey is not None and ownerObject.cipherIv is not None: encrdata = io.open(filepath + ENCRYPTED_FILE_SUFFIX, "rb").read() cipher = AES.new(ownerObject.cipherKey, AES.MODE_CBC, iv=ownerObject.cipherIv) bytesdata = cipher.decrypt(encrdata) encrdata = None # dereference before decode operation if binary: # return bytes return (FileSource.FileNamedBytesIO(filepath, bytesdata[0:-bytesdata[-1]]), ) # trim AES CBC padding # detect encoding if there is an XML header encoding = XmlUtil.encoding(bytesdata[0:512], default=cntlr.modelManager.disclosureSystem.defaultXmlEncoding if cntlr else 'utf-8') # return decoded string text = bytesdata[0:-bytesdata[-1]].decode(encoding or 'utf-8') # trim AES CBC padding and decode bytesdata = None # dereference before text operation if stripDeclaration: # file source may strip XML declaration for libxml xmlDeclarationMatch = FileSource.XMLdeclaration.search(text) if xmlDeclarationMatch: # remove it for lxml start,end = xmlDeclarationMatch.span() text = text[0:start] + text[end:] return (FileSource.FileNamedStringIO(filepath, initial_value=text), encoding) return None