diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/poppler/SecurityHandler.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-src/poppler/SecurityHandler.cc | 439 |
1 files changed, 0 insertions, 439 deletions
diff --git a/Build/source/libs/poppler/poppler-src/poppler/SecurityHandler.cc b/Build/source/libs/poppler/poppler-src/poppler/SecurityHandler.cc deleted file mode 100644 index bdfd89f8650..00000000000 --- a/Build/source/libs/poppler/poppler-src/poppler/SecurityHandler.cc +++ /dev/null @@ -1,439 +0,0 @@ -//======================================================================== -// -// SecurityHandler.cc -// -// Copyright 2004 Glyph & Cog, LLC -// -//======================================================================== - -//======================================================================== -// -// Modified under the Poppler project - http://poppler.freedesktop.org -// -// All changes made under the Poppler project to this file are licensed -// under GPL version 2 or later -// -// Copyright (C) 2010, 2012, 2015, 2017, 2018 Albert Astals Cid <aacid@kde.org> -// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com> -// Copyright (C) 2014 Fabio D'Urso <fabiodurso@hotmail.it> -// Copyright (C) 2016 Alok Anand <alok4nand@gmail.com> -// -// To see a description of the changes please see the Changelog file that -// came with your tarball or type make ChangeLog if you are building from git -// -//======================================================================== - -#include <config.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include "GooString.h" -#include "PDFDoc.h" -#include "Decrypt.h" -#include "Error.h" -#include "GlobalParams.h" -#ifdef ENABLE_PLUGINS -# include "XpdfPluginAPI.h" -#endif -#include "SecurityHandler.h" - -#include <limits.h> - -//------------------------------------------------------------------------ -// SecurityHandler -//------------------------------------------------------------------------ - -SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) { - SecurityHandler *secHdlr; -#ifdef ENABLE_PLUGINS - XpdfSecurityHandler *xsh; -#endif - - Object filterObj = encryptDictA->dictLookup("Filter"); - if (filterObj.isName("Standard")) { - secHdlr = new StandardSecurityHandler(docA, encryptDictA); - } else if (filterObj.isName()) { -#ifdef ENABLE_PLUGINS - if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) { - secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh); - } else { -#endif - error(errSyntaxError, -1, "Couldn't find the '{0:s}' security handler", - filterObj.getName()); - secHdlr = nullptr; -#ifdef ENABLE_PLUGINS - } -#endif - } else { - error(errSyntaxError, -1, - "Missing or invalid 'Filter' entry in encryption dictionary"); - secHdlr = nullptr; - } - return secHdlr; -} - -SecurityHandler::SecurityHandler(PDFDoc *docA) { - doc = docA; -} - -SecurityHandler::~SecurityHandler() { -} - -GBool SecurityHandler::checkEncryption(GooString *ownerPassword, - GooString *userPassword) { - void *authData; - GBool ok; - int i; - - if (ownerPassword || userPassword) { - authData = makeAuthData(ownerPassword, userPassword); - } else { - authData = nullptr; - } - ok = authorize(authData); - if (authData) { - freeAuthData(authData); - } - for (i = 0; !ok && i < 3; ++i) { - if (!(authData = getAuthData())) { - break; - } - ok = authorize(authData); - if (authData) { - freeAuthData(authData); - } - } - if (!ok) { - if (!ownerPassword && !userPassword) { - GooString dummy; - return checkEncryption(&dummy, &dummy); - } else { - error(errCommandLine, -1, "Incorrect password"); - } - } - return ok; -} - -//------------------------------------------------------------------------ -// StandardSecurityHandler -//------------------------------------------------------------------------ - -class StandardAuthData { -public: - - StandardAuthData(GooString *ownerPasswordA, GooString *userPasswordA) { - ownerPassword = ownerPasswordA; - userPassword = userPasswordA; - } - - ~StandardAuthData() { - if (ownerPassword) { - delete ownerPassword; - } - if (userPassword) { - delete userPassword; - } - } - - StandardAuthData(const StandardAuthData &) = delete; - StandardAuthData& operator=(const StandardAuthData &) = delete; - - GooString *ownerPassword; - GooString *userPassword; -}; - -StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA, - Object *encryptDictA): - SecurityHandler(docA) -{ - ok = gFalse; - fileID = nullptr; - ownerKey = nullptr; - userKey = nullptr; - ownerEnc = nullptr; - userEnc = nullptr; - fileKeyLength = 0; - - Object versionObj = encryptDictA->dictLookup("V"); - Object revisionObj = encryptDictA->dictLookup("R"); - Object lengthObj = encryptDictA->dictLookup("Length"); - Object ownerKeyObj = encryptDictA->dictLookup("O"); - Object userKeyObj = encryptDictA->dictLookup("U"); - Object ownerEncObj = encryptDictA->dictLookup("OE"); - Object userEncObj = encryptDictA->dictLookup("UE"); - Object permObj = encryptDictA->dictLookup("P"); - if (permObj.isInt64()) { - unsigned int permUint = permObj.getInt64(); - int perms = permUint - UINT_MAX - 1; - permObj = Object(perms); - } - Object fileIDObj = doc->getXRef()->getTrailerDict()->dictLookup("ID"); - if (versionObj.isInt() && - revisionObj.isInt() && - permObj.isInt() && - ownerKeyObj.isString() && - userKeyObj.isString()) { - encVersion = versionObj.getInt(); - encRevision = revisionObj.getInt(); - if ((encRevision <= 4 && - ownerKeyObj.getString()->getLength() == 32 && - userKeyObj.getString()->getLength() == 32) || - ((encRevision == 5 || encRevision == 6) && - // the spec says 48 bytes, but Acrobat pads them out longer - ownerKeyObj.getString()->getLength() >= 48 && - userKeyObj.getString()->getLength() >= 48 && - ownerEncObj.isString() && - ownerEncObj.getString()->getLength() == 32 && - userEncObj.isString() && - userEncObj.getString()->getLength() == 32)) { - encAlgorithm = cryptRC4; - // revision 2 forces a 40-bit key - some buggy PDF generators - // set the Length value incorrectly - if (encRevision == 2 || !lengthObj.isInt()) { - fileKeyLength = 5; - } else { - fileKeyLength = lengthObj.getInt() / 8; - } - encryptMetadata = gTrue; - //~ this currently only handles a subset of crypt filter functionality - //~ (in particular, it ignores the EFF entry in encryptDictA, and - //~ doesn't handle the case where StmF, StrF, and EFF are not all the - //~ same) - if ((encVersion == 4 || encVersion == 5) && - (encRevision == 4 || encRevision == 5 || encRevision == 6)) { - Object cryptFiltersObj = encryptDictA->dictLookup("CF"); - Object streamFilterObj = encryptDictA->dictLookup("StmF"); - Object stringFilterObj = encryptDictA->dictLookup("StrF"); - if (cryptFiltersObj.isDict() && - streamFilterObj.isName() && - stringFilterObj.isName() && - !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) { - if (!strcmp(streamFilterObj.getName(), "Identity")) { - // no encryption on streams or strings - encVersion = encRevision = -1; - } else { - Object cryptFilterObj = cryptFiltersObj.dictLookup(streamFilterObj.getName()); - if (cryptFilterObj.isDict()) { - Object cfmObj = cryptFilterObj.dictLookup("CFM"); - if (cfmObj.isName("V2")) { - encVersion = 2; - encRevision = 3; - Object cfLengthObj = cryptFilterObj.dictLookup("Length"); - if (cfLengthObj.isInt()) { - //~ according to the spec, this should be cfLengthObj / 8 - fileKeyLength = cfLengthObj.getInt(); - } - } else if (cfmObj.isName("AESV2")) { - encVersion = 2; - encRevision = 3; - encAlgorithm = cryptAES; - Object cfLengthObj = cryptFilterObj.dictLookup("Length"); - if (cfLengthObj.isInt()) { - //~ according to the spec, this should be cfLengthObj / 8 - fileKeyLength = cfLengthObj.getInt(); - } - } else if (cfmObj.isName("AESV3")) { - encVersion = 5; - // let encRevision be 5 or 6 - encAlgorithm = cryptAES256; - Object cfLengthObj = cryptFilterObj.dictLookup("Length"); - if (cfLengthObj.isInt()) { - //~ according to the spec, this should be cfLengthObj / 8 - fileKeyLength = cfLengthObj.getInt(); - } - } - } - } - } - Object encryptMetadataObj = encryptDictA->dictLookup("EncryptMetadata"); - if (encryptMetadataObj.isBool()) { - encryptMetadata = encryptMetadataObj.getBool(); - } - } - permFlags = permObj.getInt(); - ownerKey = ownerKeyObj.getString()->copy(); - userKey = userKeyObj.getString()->copy(); - if (encVersion >= 1 && encVersion <= 2 && - encRevision >= 2 && encRevision <= 3) { - if (fileIDObj.isArray()) { - Object fileIDObj1 = fileIDObj.arrayGet(0); - if (fileIDObj1.isString()) { - fileID = fileIDObj1.getString()->copy(); - } else { - fileID = new GooString(); - } - } else { - fileID = new GooString(); - } - if (fileKeyLength > 16 || fileKeyLength < 0) { - fileKeyLength = 16; - } - ok = gTrue; - } else if (encVersion == 5 && (encRevision == 5 || encRevision == 6)) { - fileID = new GooString(); // unused for V=R=5 - if (ownerEncObj.isString() && userEncObj.isString()) { - ownerEnc = ownerEncObj.getString()->copy(); - userEnc = userEncObj.getString()->copy(); - if (fileKeyLength > 32 || fileKeyLength < 0) { - fileKeyLength = 32; - } - ok = gTrue; - } else { - error(errSyntaxError, -1, "Weird encryption owner/user info"); - } - } else if (!(encVersion == -1 && encRevision == -1)) { - error(errUnimplemented, -1, - "Unsupported version/revision ({0:d}/{1:d}) of Standard security handler", - encVersion, encRevision); - } - } else { - error(errSyntaxError, -1, "Invalid encryption key length"); - } - } else { - error(errSyntaxError, -1, "Weird encryption info"); - } -} - -StandardSecurityHandler::~StandardSecurityHandler() { - if (fileID) { - delete fileID; - } - if (ownerKey) { - delete ownerKey; - } - if (userKey) { - delete userKey; - } - if (ownerEnc) { - delete ownerEnc; - } - if (userEnc) { - delete userEnc; - } -} - -GBool StandardSecurityHandler::isUnencrypted() { - if (!ok) { - return gTrue; - } - return encVersion == -1 && encRevision == -1; -} - -void *StandardSecurityHandler::makeAuthData(GooString *ownerPassword, - GooString *userPassword) { - return new StandardAuthData(ownerPassword ? ownerPassword->copy() - : (GooString *)nullptr, - userPassword ? userPassword->copy() - : (GooString *)nullptr); -} - -void *StandardSecurityHandler::getAuthData() { - return nullptr; -} - -void StandardSecurityHandler::freeAuthData(void *authData) { - delete (StandardAuthData *)authData; -} - -GBool StandardSecurityHandler::authorize(void *authData) { - GooString *ownerPassword, *userPassword; - - if (!ok) { - return gFalse; - } - if (authData) { - ownerPassword = ((StandardAuthData *)authData)->ownerPassword; - userPassword = ((StandardAuthData *)authData)->userPassword; - } else { - ownerPassword = nullptr; - userPassword = nullptr; - } - if (!Decrypt::makeFileKey(encVersion, encRevision, fileKeyLength, - ownerKey, userKey, ownerEnc, userEnc, - permFlags, fileID, - ownerPassword, userPassword, fileKey, - encryptMetadata, &ownerPasswordOk)) { - return gFalse; - } - return gTrue; -} - -#ifdef ENABLE_PLUGINS - -//------------------------------------------------------------------------ -// ExternalSecurityHandler -//------------------------------------------------------------------------ - -ExternalSecurityHandler::ExternalSecurityHandler(PDFDoc *docA, - Object *encryptDictA, - XpdfSecurityHandler *xshA): - SecurityHandler(docA) -{ - encryptDictA->copy(&encryptDict); - xsh = xshA; - encAlgorithm = cryptRC4; //~ this should be obtained via getKey - ok = gFalse; - - if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA, - (XpdfObject)encryptDictA, &docData)) { - return; - } - - ok = gTrue; -} - -ExternalSecurityHandler::~ExternalSecurityHandler() { - (*xsh->freeDoc)(xsh->handlerData, docData); -} - -void *ExternalSecurityHandler::makeAuthData(GooString *ownerPassword, - GooString *userPassword) { - char *opw, *upw; - void *authData; - - opw = ownerPassword ? ownerPassword->getCString() : (char *)NULL; - upw = userPassword ? userPassword->getCString() : (char *)NULL; - if (!(*xsh->makeAuthData)(xsh->handlerData, docData, opw, upw, &authData)) { - return NULL; - } - return authData; -} - -void *ExternalSecurityHandler::getAuthData() { - void *authData; - - if (!(*xsh->getAuthData)(xsh->handlerData, docData, &authData)) { - return NULL; - } - return authData; -} - -void ExternalSecurityHandler::freeAuthData(void *authData) { - (*xsh->freeAuthData)(xsh->handlerData, docData, authData); -} - -GBool ExternalSecurityHandler::authorize(void *authData) { - char *key; - int length; - - if (!ok) { - return gFalse; - } - permFlags = (*xsh->authorize)(xsh->handlerData, docData, authData); - if (!(permFlags & xpdfPermissionOpen)) { - return gFalse; - } - if (!(*xsh->getKey)(xsh->handlerData, docData, &key, &length, &encVersion, &encRevision)) { - return gFalse; - } - if ((fileKeyLength = length) > 16) { - fileKeyLength = 16; - } - memcpy(fileKey, key, fileKeyLength); - (*xsh->freeKey)(xsh->handlerData, docData, key, length); - return gTrue; -} - -#endif // ENABLE_PLUGINS |