Commit 02333ba1e9670ff1f7fe7170d3e0cc229755dc7b

Authored by Jay Berkenbilt
1 parent 1285fa19

checkpoint -- first crack at C API, minor refactoring of encryption functions

git-svn-id: svn+q:///qpdf/trunk@720 71b93d88-0707-0410-a8cf-f5a4172ac649
include/qpdf/QPDF.hh
... ... @@ -123,6 +123,12 @@ class QPDF
123 123 };
124 124  
125 125 DLL_EXPORT
  126 + bool isEncrypted() const;
  127 +
  128 + // Helper function to trim padding from user password. Calling
  129 + // trim_user_password on the result of getPaddedUserPassword gives
  130 + // getTrimmedUserPassword's result.
  131 + DLL_EXPORT
126 132 static void trim_user_password(std::string& user_password);
127 133 DLL_EXPORT
128 134 static std::string compute_data_key(
... ... @@ -137,8 +143,14 @@ class QPDF
137 143 int V, int R, int key_len, int P,
138 144 std::string const& id1,
139 145 std::string& O, std::string& U);
  146 + // Return the full user password as stored in the PDF file. If
  147 + // you are attempting to recover the user password in a
  148 + // user-presentable form, call getTrimmedUserPassword() instead.
  149 + DLL_EXPORT
  150 + std::string const& getPaddedUserPassword() const;
  151 + // Return human-readable form of user password.
140 152 DLL_EXPORT
141   - std::string const& getUserPassword() const;
  153 + std::string getTrimmedUserPassword() const;
142 154  
143 155 // Linearization support
144 156  
... ...
include/qpdf/qpdf-c.h 0 → 100644
  1 +#ifndef __QPDF_C_H__
  2 +#define __QPDF_C_H__
  3 +
  4 +/*
  5 + * This file defines a basic "C" API for qpdf. It provides access to
  6 + * a subset of the QPDF library's capabilities to make them accessible
  7 + * to callers who can't handle calling C++ functions or working with
  8 + * C++ classes. This may be especially useful to Windows users who
  9 + * are accessing the qpdflib DLL directly or to other people
  10 + * programming in non-C/C++ languages that can call C code but not C++
  11 + * code.
  12 + */
  13 +
  14 +#include <qpdf/DLL.hh>
  15 +
  16 +#ifdef __cplusplus
  17 +extern "C" {
  18 +#endif
  19 +
  20 + typedef struct _qpdf_data* qpdf_data;
  21 +
  22 + /* Many functions return an integer error code. Codes are defined
  23 + * below. See ERROR REPORTING below.
  24 + */
  25 + typedef int QPDF_ERROR_CODE;
  26 +# define QPDF_SUCCESS 0
  27 +# define QPDF_WARNINGS 1
  28 +# define QPDF_ERRORS 2
  29 +
  30 + typedef int QPDF_BOOL;
  31 +# define QPDF_TRUE 1
  32 +# define QPDF_FALSE 0
  33 +
  34 + /* Returns dynamically allocated qpdf_data pointer; must be freed
  35 + * by calling qpdf_cleanup. Note that qpdf_data is not
  36 + * thread-safe: although you may access different qpdf_data
  37 + * objects from different threads, you may not access one
  38 + * qpdf_data simultaneously from multiple threads. Many functions
  39 + * defined below return char*. In all cases, the char* values
  40 + * returned are pointers to data inside the qpdf_data object. As
  41 + * such, they are always freed by qpdf_cleanup. In some cases,
  42 + * strings returned by functions here may be overwritten by
  43 + * additional function calls, so if you really want a string to
  44 + * last past the next qpdf call, you should make a copy of it.
  45 + */
  46 + DLL_EXPORT
  47 + qpdf_data qpdf_init();
  48 +
  49 + /* Pass a pointer to the qpdf_data pointer created by qpdf_init to
  50 + * clean up resoures.
  51 + */
  52 + DLL_EXPORT
  53 + void qpdf_cleanup(qpdf_data* qpdf);
  54 +
  55 + /* ERROR REPORTING */
  56 +
  57 + /* Returns 1 if there are any errors or warnings, and zero
  58 + * otherwise.
  59 + */
  60 + DLL_EXPORT
  61 + QPDF_BOOL qpdf_more_errors(qpdf_data qpdf);
  62 +
  63 + /* If there are any errors, returns a pointer to the next error.
  64 + * Otherwise returns a null pointer. The error value returned is
  65 + * a pointer to data inside the qpdf_data object. It will become
  66 + * valid the next time a qpdf function that returns a string is
  67 + * called or after a call to qpdf_cleanup.
  68 + */
  69 + DLL_EXPORT
  70 + char const* qpdf_next_error(qpdf_data qpdf);
  71 +
  72 + /* These functions are analogous to the "error" counterparts but
  73 + * apply to warnings.
  74 + */
  75 +
  76 + DLL_EXPORT
  77 + QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf);
  78 + DLL_EXPORT
  79 + char const* qpdf_next_warning(qpdf_data qpdf);
  80 +
  81 + /* READ PARAMETER FUNCTIONS */
  82 +
  83 + /* By default, warnings are written to stderr. Passing true to
  84 + this function will prevent warnings from being written to stderr.
  85 + They will still be available by calls to qpdf_next_warning.
  86 + */
  87 + DLL_EXPORT
  88 + void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL val);
  89 +
  90 + /* READ FUNCTIONS */
  91 +
  92 + /* POST-READ QUERY FUNCTIONS */
  93 +
  94 + /* These functions are invalid until after qpdf_read has been
  95 + * called. */
  96 +
  97 + /* Return the version of the PDF file. */
  98 + DLL_EXPORT
  99 + char const* qpdf_get_pdf_version(qpdf_data qpdf);
  100 +
  101 + /* Return the user password. If the file is opened using the
  102 + * owner password, the user password may be retrieved using this
  103 + * function. If the file is opened using the user password, this
  104 + * function will return that user password.
  105 + */
  106 + DLL_EXPORT
  107 + char const* qpdf_get_user_password(qpdf_data qpdf);
  108 +
  109 + /* Indicate whether the input file is linearized. */
  110 + DLL_EXPORT
  111 + QPDF_BOOL qpdf_is_linearized(qpdf_data qpdf);
  112 +
  113 + /* Indicate whether the input file is encrypted. */
  114 + DLL_EXPORT
  115 + QPDF_BOOL qpdf_is_encrypted(qpdf_data qpdf);
  116 +
  117 + /* WRITE FUNCTIONS */
  118 +
  119 + /* Set up for writing. No writing is actually performed until the
  120 + * call to qpdf_write().
  121 + */
  122 +
  123 + /* Supply the name of the file to be written and initialize the
  124 + * qpdf_data object to handle writing operations. This function
  125 + * also attempts to create the file. The PDF data is not written
  126 + * until the call to qpdf_write.
  127 + */
  128 + DLL_EXPORT
  129 + QPDF_ERROR_CODE qpdf_init_write(qpdf_data data, char const* filename);
  130 +
  131 + /* XXX Get public interface from QPDFWriter */
  132 +
  133 + /* Perform the actual write operation. */
  134 + DLL_EXPORT
  135 + QPDF_ERROR_CODE qpdf_write();
  136 +
  137 +#ifdef __cplusplus
  138 +}
  139 +#endif
  140 +
  141 +
  142 +#endif /* __QPDF_C_H__ */
... ...
libqpdf/QPDFWriter.cc
... ... @@ -277,7 +277,7 @@ QPDFWriter::copyEncryptionParameters()
277 277 encrypt.getKey("/O").getStringValue(),
278 278 encrypt.getKey("/U").getStringValue(),
279 279 this->id1, // this->id1 == the other file's id1
280   - pdf.getUserPassword());
  280 + pdf.getPaddedUserPassword());
281 281 }
282 282 }
283 283  
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -443,7 +443,23 @@ QPDF::compute_encryption_O_U(
443 443  
444 444 DLL_EXPORT
445 445 std::string const&
446   -QPDF::getUserPassword() const
  446 +QPDF::getPaddedUserPassword() const
447 447 {
448 448 return this->user_password;
449 449 }
  450 +
  451 +DLL_EXPORT
  452 +std::string
  453 +QPDF::getTrimmedUserPassword() const
  454 +{
  455 + std::string result = this->user_password;
  456 + trim_user_password(result);
  457 + return result;
  458 +}
  459 +
  460 +DLL_EXPORT
  461 +bool
  462 +QPDF::isEncrypted() const
  463 +{
  464 + return this->encrypted;
  465 +}
... ...
libqpdf/build.mk
... ... @@ -43,7 +43,8 @@ SRCS_libqpdf = \
43 43 libqpdf/QPDF_optimization.cc \
44 44 libqpdf/QTC.cc \
45 45 libqpdf/QUtil.cc \
46   - libqpdf/RC4.cc
  46 + libqpdf/RC4.cc \
  47 + libqpdf/qpdf-c.cc
47 48  
48 49 # -----
49 50  
... ...
libqpdf/qpdf-c.cc 0 → 100644
  1 +#include <qpdf/qpdf-c.h>
  2 +
  3 +class _qpdf_data
  4 +{
  5 +};
  6 +
  7 +DLL_EXPORT
  8 +qpdf_data qpdf_init()
  9 +{
  10 + return new _qpdf_data();
  11 +}
  12 +
  13 +DLL_EXPORT
  14 +void qpdf_cleanup(qpdf_data* qpdf)
  15 +{
  16 + delete *qpdf;
  17 + *qpdf = 0;
  18 +}
... ...
qpdf/qpdf.cc
... ... @@ -168,18 +168,17 @@ void usage(std::string const&amp; msg)
168 168 static void show_encryption(QPDF& pdf)
169 169 {
170 170 // Extract /P from /Encrypt
171   - QPDFObjectHandle trailer = pdf.getTrailer();
172   - QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
173   - if (encrypt.isNull())
  171 + if (! pdf.isEncrypted())
174 172 {
175 173 std::cout << "File is not encrypted" << std::endl;
176 174 }
177 175 else
178 176 {
  177 + QPDFObjectHandle trailer = pdf.getTrailer();
  178 + QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
179 179 QPDFObjectHandle P = encrypt.getKey("/P");
180 180 std::cout << "P = " << P.getIntValue() << std::endl;
181   - std::string user_password = pdf.getUserPassword();
182   - QPDF::trim_user_password(user_password);
  181 + std::string user_password = pdf.getTrimmedUserPassword();
183 182 std::cout << "User password = " << user_password << std::endl;
184 183 }
185 184 }
... ...