/*
//
// ADOBE SYSTEMS INCORPORATED
// Copyright (C) 2000-2003 Adobe Systems Incorporated
// All rights reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file
// in accordance with the terms of the Adobe license agreement
// accompanying it. If you have received this file from a source other
// than Adobe, then your use, modification, or distribution of it
// requires the prior written permission of Adobe.
//
*/
/*
//
// Decryption.cpp
//
*/
#include <iostream>
#include <memory.h>
#include "Decryption.h"
#include "MyPDFLibUtils.h"
#include "stdlib.h"
#include "
ASExtraCalls.h"
#ifdef MAC_ENV
#include "macUtils.h"
#endif
using namespace std;
// default constructor: init PDFL and data member
Decryption::Decryption()
{
this->orgDoc =
NULL;
}
// constructor: init PDFL and attemp to authorize
// open permission on input encrypted document
Decryption::Decryption( const char *inputDoc)
{
#ifdef MAC_ENV
ASPathName asPath = GetMacPath(( char *)inputDoc);
#else
ASPathName asPath =
ASFileSysCreatePathName(
ASGetDefaultFileSys(),
ASAtomFromString( "Cstring" ),
( void *)inputDoc,
NULL);
#endif
ASErrorCode errCode = 0;
DURING
/* open encrypted document with an authorization callback proc */
this->orgDoc =
PDDocOpenEx(asPath,
ASGetDefaultFileSys(),
ASCallbackCreateProto(
PDAuthProcEx, &(this->ClientAuthUserProc)), 0, true );
HANDLER
errCode =
ERRORCODE;
END_HANDLER
ASFileSysReleasePath(
ASGetDefaultFileSys(), asPath);
if (errCode)
ASRaise(errCode);
}
// destrcutor: terminate PDFL and clean up if necessary
Decryption::~Decryption()
{
if (this->orgDoc)
PDDocClose(this->orgDoc);
}
// helper function to set contents extracted from the encrypted document
// to pages of the non-encrypted output document
void Decryption::SetPageContent(
PDPage pdPage,
PDEContent pdeContent)
{
PDEFilterArray filterRec;
memset( &filterRec, 0, sizeof (
PDEFilterArray) );
filterRec.
numFilters = 1;
filterRec.
spec[0].
name =
ASAtomFromString( "FlateDecode" );
CosObj cosPage =
PDPageGetCosObj(pdPage);
CosDoc cosDoc =
CosObjGetDoc(cosPage);
CosObj cosContents;
CosObj cosResources;
DURING
// extract content and resource objects from
// the page of the encrypted document
PDEContentToCosObj(pdeContent,
kPDEContentToPage, 0, 0, cosDoc, &filterRec,
&cosContents, &cosResources);
// place content and resource objects into page */
CosDictPut(cosPage,
ASAtomFromString( "Contents" ), cosContents);
CosDictPut(cosPage,
ASAtomFromString( "Resources" ), cosResources);
HANDLER
RERAISE();
END_HANDLER
}
// member function to operate on the decrypted document
// operation performed:
// extracting pages from the decrypted document and save
// them in reverse order to a new document with no security
// settings.
void Decryption::ProcessDocument( const char *outputDoc)
{
PDPage orgPage;
PDEContent orgContent;
DURING
// output document to save the extraced pages to
PDDoc newDoc =
PDDocCreate();
// loop through the pages of the originally encrypted
// document and set their contents to new pages of
// the new output document
for ( int i = 0; i <
PDDocGetNumPages(this->orgDoc); i++)
{
orgPage =
PDDocAcquirePage(this->orgDoc, i);
ASFixedRect mediaBox;
ASErrorCode errCode = 0;
PDPageGetMediaBox(orgPage, &mediaBox);
orgContent = PDPageAcquirePDEContent(orgPage, 0);
PDPage newPage =
PDDocCreatePage(newDoc,
PDBeforeFirstPage, mediaBox);
DURING
SetPageContent(newPage, orgContent);
HANDLER
errCode =
ERRORCODE;
END_HANDLER;
PDPageReleasePDEContent(orgPage, 0);
PDPageRelease(newPage);
PDPageRelease(orgPage);
if (errCode)
ASRaise(errCode);
}
#ifdef MAC_ENV
ASPathName asPath = GetMacPath(( char *)outputDoc);
#else
ASPathName asPath =
ASFileSysCreatePathName(
ASGetDefaultFileSys(),
ASAtomFromString( "Cstring" ),
( void *)outputDoc,
NULL);
//ASPathName asPath = ASPathFromPlatformPath((void *)outputDoc);
#endif
// save the new non-encrypted output document with pages
// in reverse order of the original
PDDocSave(newDoc,
PDSaveFull |
PDSaveLinearized |
PDSaveCollectGarbage,
asPath,
ASGetDefaultFileSys(), 0, 0);
ASFileSysReleasePath(
ASGetDefaultFileSys(), asPath);
HANDLER
RERAISE();
END_HANDLER
cout << "Decrypted document " << outputDoc << " generated successfully." << endl << endl;
}
static
ASBool useUTF = false ;
#define MAX_PWCHARS 255
void useUtf(
PDDoc pdDoc)
{
if (pdDoc !=
NULL) {
StdSecurityData secData = (
StdSecurityData)
PDDocGetNewSecurityData(pdDoc);
if (!secData)
secData = (
StdSecurityData)
PDDocGetSecurityData(pdDoc);
if (secData)
useUTF = (secData->
revision >= 5);
}
}
const
ASUTF16Val * GetPasswordFromFile( const char * input)
{
#ifdef MAC_ENV
ASPathName filePath = GetMacPath(( char *)input);
#else
ASPathName filePath =
ASFileSysCreatePathName(
ASGetDefaultFileSys(),
ASAtomFromString( "Cstring" ),( void *)input,
NULL);
#endif
const
ASUTF16Val * uniPwd = 0;
ASFile asFile;
ASErrorCode errCode;
DURING
errCode =
ASFileSysOpenFile(
NULL, filePath,
ASFILE_READ, &asFile);
if (!errCode)
{
char readPwd[
MAX_PWCHARS];
ASTArraySize bytesRead =
ASFileRead(asFile, readPwd,
MAX_PWCHARS);
ASFileClose(asFile);
ASText asReadPwd =
ASTextFromSizedPDText(readPwd, bytesRead);
uniPwd =
ASTextGetUnicodeCopy(asReadPwd, kUTF16HostEndian);
if (asReadPwd){
ASTextMakeEmptyClear(asReadPwd);
ASTextDestroy(asReadPwd);
}
}
HANDLER
errCode =
ERRORCODE;
END_HANDLER
ASFileSysReleasePath(
ASGetDefaultFileSys(), filePath);
if (errCode){
cerr << "Error in opening/reading of given password file" << endl;
ASRaise(errCode);
}
return uniPwd;
}
// PDAuthProcEx callback called by PDDocOpenEx to authorize open permission
ACCB1
ASBool ACCB2 Decryption::ClientAuthUserProc(
PDDoc pdDoc, void *clientData)
{
// supply the user password
//ASUCS_GetPasswordFromUnicode expects unicode password in utf-16 host-endian
//file containing password should be encoded in utf-16 big-endian with BOM
const char *userPwdFile = "../ExampleFiles/user-password.txt" ;
ASUTF16Val* userPwd = (
ASUTF16Val*)GetPasswordFromFile(userPwdFile);
//performing a check on security handler version
useUtf(pdDoc);
//Converts user input of a password to a form that can be used by PDFL to open a file.
void *prfldPasswd = 0;
ASUCS_GetPasswordFromUnicode(userPwd, ( void **)(&prfldPasswd), useUTF);
// request permission to change security settings
PDPermReqObj permReqObj =
PDPermReqObjDoc;
PDPermReqOpr permReqOpr =
PDPermReqOprOpen;
PDPermReqStatus permReqStatus;
DURING
/* Request Open permission by passing in the user password */
permReqStatus =
PDDocPermRequest(pdDoc, permReqObj, permReqOpr, ( void *)prfldPasswd);
HANDLER
if (prfldPasswd)
ASfree(prfldPasswd);
if (userPwd)
ASfree(userPwd);
RERAISE();
END_HANDLER
switch (permReqStatus)
{
case
PDPermReqGranted:
cout << "Password verified. Permission to open document granted!" << endl;
break ;
case
PDPermReqDenied:
cout << "Invalid user password.\nDocument open request denied!" << endl;
break ;
case
PDPermReqUnknownObject:
cout << "Target object unknown for the permisson request." << endl;
break ;
case
PDPermReqUnknownOperation:
cout << "Target operation unknown for the permission request." << endl;
break ;
default :
cout << "Something is wrong!" << endl;
}
if (prfldPasswd)
ASfree(prfldPasswd);
if (userPwd)
ASfree(userPwd);
return (permReqStatus ==
PDPermReqGranted);
}
// member function to authorize permissions to operate on the document
ACCB1
ASBool ACCB2 Decryption::ClientAuthMasterProc()
{
// provide the master password
//ASUCS_GetPasswordFromUnicode expects unicode password in utf-16 host-endian
//file containing password should be encoded in utf-16 big-endian with BOM
const char *masterPwdFile = "../ExampleFiles/master-password.txt" ;
ASUTF16Val* masterPwd = (
ASUTF16Val*)GetPasswordFromFile(masterPwdFile);
//Converts user input of a password to a form that can be used by PDFL to open a file.
void *prfldPasswd = 0;
ASUCS_GetPasswordFromUnicode(masterPwd, ( void **)(&prfldPasswd), useUTF);
// request permission to change security settings
PDPermReqObj permReqObj =
PDPermReqObjDoc;
PDPermReqOpr permReqOpr =
PDPermReqOprSecure;
PDPermReqStatus permReqStatus;
DURING
/* Request permission by passing in the master password */
permReqStatus =
PDDocPermRequest(this->orgDoc, permReqObj, permReqOpr, ( void *)prfldPasswd);
HANDLER
char errmsg[256];
cout << "ClientAuthMasterProc> Error " <<
ErrGetCode(
ERRORCODE) << ": " <<
ASGetErrorString(
ERRORCODE, errmsg, sizeof (errmsg)) << endl;
if (prfldPasswd)
ASfree(prfldPasswd);
if (masterPwd)
ASfree(masterPwd);
return false ;
END_HANDLER
switch (permReqStatus)
{
case
PDPermReqGranted:
cout << "Requested permissions granted!" << endl;
break ;
case
PDPermReqDenied:
cout << "Permission request denied!" << endl;
break ;
case
PDPermReqUnknownObject:
cout << "Target object unknown for the permisson request." << endl;
break ;
case
PDPermReqUnknownOperation:
cout << "Target operation unknown for the permission request." << endl;
break ;
default :
cout << "Something is wrong!" << endl;
}
if (prfldPasswd)
ASfree(prfldPasswd);
if (masterPwd)
ASfree(masterPwd);
return (permReqStatus ==
PDPermReqGranted);
}