Commit 68447bb556364efefc41a3af72a9455b6e43c137

Authored by Jay Berkenbilt
1 parent 04c203ae

change EncryptionData

include/qpdf/QPDF.hh
... ... @@ -223,8 +223,10 @@ class QPDF
223 223 // Encryption support
224 224  
225 225 enum encryption_method_e { e_none, e_unknown, e_rc4, e_aes };
226   - struct EncryptionData
  226 + class EncryptionData
227 227 {
  228 + public:
  229 +
228 230 // This class holds data read from the encryption dictionary.
229 231 EncryptionData(int V, int R, int Length_bytes, int P,
230 232 std::string const& O, std::string const& U,
... ... @@ -240,6 +242,22 @@ class QPDF
240 242 {
241 243 }
242 244  
  245 + int getV() const;
  246 + int getR() const;
  247 + int getLengthBytes() const;
  248 + int getP() const;
  249 + std::string const& getO() const;
  250 + std::string const& getU() const;
  251 + std::string const& getId1() const;
  252 + bool getEncryptMetadata() const;
  253 +
  254 + void setO(std::string const&);
  255 + void setU(std::string const&);
  256 +
  257 + private:
  258 + EncryptionData(EncryptionData const&);
  259 + EncryptionData& operator=(EncryptionData const&);
  260 +
243 261 int V;
244 262 int R;
245 263 int Length_bytes;
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -26,7 +26,67 @@ static unsigned char const padding_string[] = {
26 26 static unsigned int const O_key_bytes = sizeof(MD5::Digest);
27 27 static unsigned int const key_bytes = 32;
28 28  
  29 +int
  30 +QPDF::EncryptionData::getV() const
  31 +{
  32 + return this->V;
  33 +}
  34 +
  35 +int
  36 +QPDF::EncryptionData::getR() const
  37 +{
  38 + return this->R;
  39 +}
  40 +
  41 +int
  42 +QPDF::EncryptionData::getLengthBytes() const
  43 +{
  44 + return this->Length_bytes;
  45 +}
  46 +
  47 +int
  48 +QPDF::EncryptionData::getP() const
  49 +{
  50 + return this->P;
  51 +}
  52 +
  53 +std::string const&
  54 +QPDF::EncryptionData::getO() const
  55 +{
  56 + return this->O;
  57 +}
  58 +
  59 +std::string const&
  60 +QPDF::EncryptionData::getU() const
  61 +{
  62 + return this->U;
  63 +}
  64 +
  65 +std::string const&
  66 +QPDF::EncryptionData::getId1() const
  67 +{
  68 + return this->id1;
  69 +}
  70 +
  71 +bool
  72 +QPDF::EncryptionData::getEncryptMetadata() const
  73 +{
  74 + return this->encrypt_metadata;
  75 +}
  76 +
  77 +void
  78 +QPDF::EncryptionData::setO(std::string const& O)
  79 +{
  80 + this->O = O;
  81 +}
  82 +
29 83 void
  84 +QPDF::EncryptionData::setU(std::string const& U)
  85 +{
  86 + this->U = U;
  87 +}
  88 +
  89 +static void
30 90 pad_or_truncate_password(std::string const& password, char k1[key_bytes])
31 91 {
32 92 int password_bytes = std::min(key_bytes, (unsigned int)password.length());
... ... @@ -137,23 +197,25 @@ QPDF::compute_encryption_key(
137 197 MD5 md5;
138 198 md5.encodeDataIncrementally(
139 199 pad_or_truncate_password(password).c_str(), key_bytes);
140   - md5.encodeDataIncrementally(data.O.c_str(), key_bytes);
  200 + md5.encodeDataIncrementally(data.getO().c_str(), key_bytes);
141 201 char pbytes[4];
142   - pbytes[0] = (char) (data.P & 0xff);
143   - pbytes[1] = (char) ((data.P >> 8) & 0xff);
144   - pbytes[2] = (char) ((data.P >> 16) & 0xff);
145   - pbytes[3] = (char) ((data.P >> 24) & 0xff);
  202 + int P = data.getP();
  203 + pbytes[0] = (char) (P & 0xff);
  204 + pbytes[1] = (char) ((P >> 8) & 0xff);
  205 + pbytes[2] = (char) ((P >> 16) & 0xff);
  206 + pbytes[3] = (char) ((P >> 24) & 0xff);
146 207 md5.encodeDataIncrementally(pbytes, 4);
147   - md5.encodeDataIncrementally(data.id1.c_str(), (int)data.id1.length());
148   - if ((data.R >= 4) && (! data.encrypt_metadata))
  208 + md5.encodeDataIncrementally(data.getId1().c_str(),
  209 + (int)data.getId1().length());
  210 + if ((data.getR() >= 4) && (! data.getEncryptMetadata()))
149 211 {
150 212 char bytes[4];
151 213 memset(bytes, 0xff, 4);
152 214 md5.encodeDataIncrementally(bytes, 4);
153 215 }
154 216 MD5::Digest digest;
155   - iterate_md5_digest(md5, digest, ((data.R >= 3) ? 50 : 0));
156   - return std::string((char*)digest, data.Length_bytes);
  217 + iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0));
  218 + return std::string((char*)digest, data.getLengthBytes());
157 219 }
158 220  
159 221 static void
... ... @@ -171,7 +233,7 @@ compute_O_rc4_key(std::string const& user_password,
171 233 md5.encodeDataIncrementally(
172 234 pad_or_truncate_password(password).c_str(), key_bytes);
173 235 MD5::Digest digest;
174   - iterate_md5_digest(md5, digest, ((data.R >= 3) ? 50 : 0));
  236 + iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0));
175 237 memcpy(key, digest, O_key_bytes);
176 238 }
177 239  
... ... @@ -188,7 +250,8 @@ compute_O_value(std::string const& user_password,
188 250 char upass[key_bytes];
189 251 pad_or_truncate_password(user_password, upass);
190 252 iterate_rc4((unsigned char*) upass, key_bytes,
191   - O_key, data.Length_bytes, (data.R >= 3) ? 20 : 1, false);
  253 + O_key, data.getLengthBytes(),
  254 + (data.getR() >= 3) ? 20 : 1, false);
192 255 return std::string(upass, key_bytes);
193 256 }
194 257  
... ... @@ -203,7 +266,7 @@ compute_U_value_R2(std::string const& user_password,
203 266 char udata[key_bytes];
204 267 pad_or_truncate_password("", udata);
205 268 iterate_rc4((unsigned char*) udata, key_bytes,
206   - (unsigned char*)k1.c_str(), data.Length_bytes, 1, false);
  269 + (unsigned char*)k1.c_str(), data.getLengthBytes(), 1, false);
207 270 return std::string(udata, key_bytes);
208 271 }
209 272  
... ... @@ -218,11 +281,12 @@ compute_U_value_R3(std::string const& user_password,
218 281 MD5 md5;
219 282 md5.encodeDataIncrementally(
220 283 pad_or_truncate_password("").c_str(), key_bytes);
221   - md5.encodeDataIncrementally(data.id1.c_str(), (int)data.id1.length());
  284 + md5.encodeDataIncrementally(data.getId1().c_str(),
  285 + (int)data.getId1().length());
222 286 MD5::Digest digest;
223 287 md5.digest(digest);
224 288 iterate_rc4(digest, sizeof(MD5::Digest),
225   - (unsigned char*) k1.c_str(), data.Length_bytes, 20, false);
  289 + (unsigned char*) k1.c_str(), data.getLengthBytes(), 20, false);
226 290 char result[key_bytes];
227 291 memcpy(result, digest, sizeof(MD5::Digest));
228 292 // pad with arbitrary data -- make it consistent for the sake of
... ... @@ -238,7 +302,7 @@ static std::string
238 302 compute_U_value(std::string const& user_password,
239 303 QPDF::EncryptionData const& data)
240 304 {
241   - if (data.R >= 3)
  305 + if (data.getR() >= 3)
242 306 {
243 307 return compute_U_value_R3(user_password, data);
244 308 }
... ... @@ -253,8 +317,8 @@ check_user_password(std::string const& user_password,
253 317 // Algorithm 3.6 from the PDF 1.7 Reference Manual
254 318  
255 319 std::string u_value = compute_U_value(user_password, data);
256   - int to_compare = ((data.R >= 3) ? sizeof(MD5::Digest) : key_bytes);
257   - return (memcmp(data.U.c_str(), u_value.c_str(), to_compare) == 0);
  320 + int to_compare = ((data.getR() >= 3) ? sizeof(MD5::Digest) : key_bytes);
  321 + return (memcmp(data.getU().c_str(), u_value.c_str(), to_compare) == 0);
258 322 }
259 323  
260 324 static bool
... ... @@ -267,9 +331,9 @@ check_owner_password(std::string& user_password,
267 331 unsigned char key[O_key_bytes];
268 332 compute_O_rc4_key(user_password, owner_password, data, key);
269 333 unsigned char O_data[key_bytes];
270   - memcpy(O_data, (unsigned char*) data.O.c_str(), key_bytes);
271   - iterate_rc4(O_data, key_bytes, key, data.Length_bytes,
272   - (data.R >= 3) ? 20 : 1, true);
  334 + memcpy(O_data, (unsigned char*) data.getO().c_str(), key_bytes);
  335 + iterate_rc4(O_data, key_bytes, key, data.getLengthBytes(),
  336 + (data.getR() >= 3) ? 20 : 1, true);
273 337 std::string new_user_password =
274 338 std::string((char*)O_data, key_bytes);
275 339 bool result = false;
... ... @@ -716,9 +780,10 @@ QPDF::compute_encryption_O_U(
716 780 std::string const& id1, std::string& O, std::string& U)
717 781 {
718 782 EncryptionData data(V, R, key_len, P, "", "", id1, encrypt_metadata);
719   - data.O = compute_O_value(user_password, owner_password, data);
720   - O = data.O;
721   - U = compute_U_value(user_password, data);
  783 + data.setO(compute_O_value(user_password, owner_password, data));
  784 + O = data.getO();
  785 + data.setU(compute_U_value(user_password, data));
  786 + U = data.getU();
722 787 }
723 788  
724 789 std::string const&
... ...