Commit 02333ba1e9670ff1f7fe7170d3e0cc229755dc7b
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
Showing
7 changed files
with
197 additions
and
9 deletions
include/qpdf/QPDF.hh
| @@ -123,6 +123,12 @@ class QPDF | @@ -123,6 +123,12 @@ class QPDF | ||
| 123 | }; | 123 | }; |
| 124 | 124 | ||
| 125 | DLL_EXPORT | 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 | static void trim_user_password(std::string& user_password); | 132 | static void trim_user_password(std::string& user_password); |
| 127 | DLL_EXPORT | 133 | DLL_EXPORT |
| 128 | static std::string compute_data_key( | 134 | static std::string compute_data_key( |
| @@ -137,8 +143,14 @@ class QPDF | @@ -137,8 +143,14 @@ class QPDF | ||
| 137 | int V, int R, int key_len, int P, | 143 | int V, int R, int key_len, int P, |
| 138 | std::string const& id1, | 144 | std::string const& id1, |
| 139 | std::string& O, std::string& U); | 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 | DLL_EXPORT | 152 | DLL_EXPORT |
| 141 | - std::string const& getUserPassword() const; | 153 | + std::string getTrimmedUserPassword() const; |
| 142 | 154 | ||
| 143 | // Linearization support | 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,7 +277,7 @@ QPDFWriter::copyEncryptionParameters() | ||
| 277 | encrypt.getKey("/O").getStringValue(), | 277 | encrypt.getKey("/O").getStringValue(), |
| 278 | encrypt.getKey("/U").getStringValue(), | 278 | encrypt.getKey("/U").getStringValue(), |
| 279 | this->id1, // this->id1 == the other file's id1 | 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,7 +443,23 @@ QPDF::compute_encryption_O_U( | ||
| 443 | 443 | ||
| 444 | DLL_EXPORT | 444 | DLL_EXPORT |
| 445 | std::string const& | 445 | std::string const& |
| 446 | -QPDF::getUserPassword() const | 446 | +QPDF::getPaddedUserPassword() const |
| 447 | { | 447 | { |
| 448 | return this->user_password; | 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,7 +43,8 @@ SRCS_libqpdf = \ | ||
| 43 | libqpdf/QPDF_optimization.cc \ | 43 | libqpdf/QPDF_optimization.cc \ |
| 44 | libqpdf/QTC.cc \ | 44 | libqpdf/QTC.cc \ |
| 45 | libqpdf/QUtil.cc \ | 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
qpdf/qpdf.cc
| @@ -168,18 +168,17 @@ void usage(std::string const& msg) | @@ -168,18 +168,17 @@ void usage(std::string const& msg) | ||
| 168 | static void show_encryption(QPDF& pdf) | 168 | static void show_encryption(QPDF& pdf) |
| 169 | { | 169 | { |
| 170 | // Extract /P from /Encrypt | 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 | std::cout << "File is not encrypted" << std::endl; | 173 | std::cout << "File is not encrypted" << std::endl; |
| 176 | } | 174 | } |
| 177 | else | 175 | else |
| 178 | { | 176 | { |
| 177 | + QPDFObjectHandle trailer = pdf.getTrailer(); | ||
| 178 | + QPDFObjectHandle encrypt = trailer.getKey("/Encrypt"); | ||
| 179 | QPDFObjectHandle P = encrypt.getKey("/P"); | 179 | QPDFObjectHandle P = encrypt.getKey("/P"); |
| 180 | std::cout << "P = " << P.getIntValue() << std::endl; | 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 | std::cout << "User password = " << user_password << std::endl; | 182 | std::cout << "User password = " << user_password << std::endl; |
| 184 | } | 183 | } |
| 185 | } | 184 | } |