//========================================================================
//
// 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>

#include "GooString.h"
#include "PDFDoc.h"
#include "Decrypt.h"
#include "Error.h"
#include "GlobalParams.h"
#include "SecurityHandler.h"

#include <limits.h>

//------------------------------------------------------------------------
// SecurityHandler
//------------------------------------------------------------------------

SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
  SecurityHandler *secHdlr;

  Object filterObj = encryptDictA->dictLookup("Filter");
  if (filterObj.isName("Standard")) {
    secHdlr = new StandardSecurityHandler(docA, encryptDictA);
  } else if (filterObj.isName()) {
    error(errSyntaxError, -1, "Couldn't find the '{0:s}' security handler", filterObj.getName());
    secHdlr = nullptr;
  } 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(const GooString *ownerPassword,
				       const 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(const GooString *ownerPassword,
					    const GooString *userPassword) {
  return new StandardAuthData(ownerPassword ? ownerPassword->copy()
			                    : nullptr,
			      userPassword ? userPassword->copy()
			                   : 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;
}

