Commit 68447bb556364efefc41a3af72a9455b6e43c137

Authored by Jay Berkenbilt
1 parent 04c203ae

change EncryptionData

include/qpdf/QPDF.hh
@@ -223,8 +223,10 @@ class QPDF @@ -223,8 +223,10 @@ class QPDF
223 // Encryption support 223 // Encryption support
224 224
225 enum encryption_method_e { e_none, e_unknown, e_rc4, e_aes }; 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 // This class holds data read from the encryption dictionary. 230 // This class holds data read from the encryption dictionary.
229 EncryptionData(int V, int R, int Length_bytes, int P, 231 EncryptionData(int V, int R, int Length_bytes, int P,
230 std::string const& O, std::string const& U, 232 std::string const& O, std::string const& U,
@@ -240,6 +242,22 @@ class QPDF @@ -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 int V; 261 int V;
244 int R; 262 int R;
245 int Length_bytes; 263 int Length_bytes;
libqpdf/QPDF_encryption.cc
@@ -26,7 +26,67 @@ static unsigned char const padding_string[] = { @@ -26,7 +26,67 @@ static unsigned char const padding_string[] = {
26 static unsigned int const O_key_bytes = sizeof(MD5::Digest); 26 static unsigned int const O_key_bytes = sizeof(MD5::Digest);
27 static unsigned int const key_bytes = 32; 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 void 83 void
  84 +QPDF::EncryptionData::setU(std::string const& U)
  85 +{
  86 + this->U = U;
  87 +}
  88 +
  89 +static void
30 pad_or_truncate_password(std::string const& password, char k1[key_bytes]) 90 pad_or_truncate_password(std::string const& password, char k1[key_bytes])
31 { 91 {
32 int password_bytes = std::min(key_bytes, (unsigned int)password.length()); 92 int password_bytes = std::min(key_bytes, (unsigned int)password.length());
@@ -137,23 +197,25 @@ QPDF::compute_encryption_key( @@ -137,23 +197,25 @@ QPDF::compute_encryption_key(
137 MD5 md5; 197 MD5 md5;
138 md5.encodeDataIncrementally( 198 md5.encodeDataIncrementally(
139 pad_or_truncate_password(password).c_str(), key_bytes); 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 char pbytes[4]; 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 md5.encodeDataIncrementally(pbytes, 4); 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 char bytes[4]; 212 char bytes[4];
151 memset(bytes, 0xff, 4); 213 memset(bytes, 0xff, 4);
152 md5.encodeDataIncrementally(bytes, 4); 214 md5.encodeDataIncrementally(bytes, 4);
153 } 215 }
154 MD5::Digest digest; 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 static void 221 static void
@@ -171,7 +233,7 @@ compute_O_rc4_key(std::string const& user_password, @@ -171,7 +233,7 @@ compute_O_rc4_key(std::string const& user_password,
171 md5.encodeDataIncrementally( 233 md5.encodeDataIncrementally(
172 pad_or_truncate_password(password).c_str(), key_bytes); 234 pad_or_truncate_password(password).c_str(), key_bytes);
173 MD5::Digest digest; 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 memcpy(key, digest, O_key_bytes); 237 memcpy(key, digest, O_key_bytes);
176 } 238 }
177 239
@@ -188,7 +250,8 @@ compute_O_value(std::string const& user_password, @@ -188,7 +250,8 @@ compute_O_value(std::string const& user_password,
188 char upass[key_bytes]; 250 char upass[key_bytes];
189 pad_or_truncate_password(user_password, upass); 251 pad_or_truncate_password(user_password, upass);
190 iterate_rc4((unsigned char*) upass, key_bytes, 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 return std::string(upass, key_bytes); 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,7 +266,7 @@ compute_U_value_R2(std::string const& user_password,
203 char udata[key_bytes]; 266 char udata[key_bytes];
204 pad_or_truncate_password("", udata); 267 pad_or_truncate_password("", udata);
205 iterate_rc4((unsigned char*) udata, key_bytes, 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 return std::string(udata, key_bytes); 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,11 +281,12 @@ compute_U_value_R3(std::string const& user_password,
218 MD5 md5; 281 MD5 md5;
219 md5.encodeDataIncrementally( 282 md5.encodeDataIncrementally(
220 pad_or_truncate_password("").c_str(), key_bytes); 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 MD5::Digest digest; 286 MD5::Digest digest;
223 md5.digest(digest); 287 md5.digest(digest);
224 iterate_rc4(digest, sizeof(MD5::Digest), 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 char result[key_bytes]; 290 char result[key_bytes];
227 memcpy(result, digest, sizeof(MD5::Digest)); 291 memcpy(result, digest, sizeof(MD5::Digest));
228 // pad with arbitrary data -- make it consistent for the sake of 292 // pad with arbitrary data -- make it consistent for the sake of
@@ -238,7 +302,7 @@ static std::string @@ -238,7 +302,7 @@ static std::string
238 compute_U_value(std::string const& user_password, 302 compute_U_value(std::string const& user_password,
239 QPDF::EncryptionData const& data) 303 QPDF::EncryptionData const& data)
240 { 304 {
241 - if (data.R >= 3) 305 + if (data.getR() >= 3)
242 { 306 {
243 return compute_U_value_R3(user_password, data); 307 return compute_U_value_R3(user_password, data);
244 } 308 }
@@ -253,8 +317,8 @@ check_user_password(std::string const& user_password, @@ -253,8 +317,8 @@ check_user_password(std::string const& user_password,
253 // Algorithm 3.6 from the PDF 1.7 Reference Manual 317 // Algorithm 3.6 from the PDF 1.7 Reference Manual
254 318
255 std::string u_value = compute_U_value(user_password, data); 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 static bool 324 static bool
@@ -267,9 +331,9 @@ check_owner_password(std::string& user_password, @@ -267,9 +331,9 @@ check_owner_password(std::string& user_password,
267 unsigned char key[O_key_bytes]; 331 unsigned char key[O_key_bytes];
268 compute_O_rc4_key(user_password, owner_password, data, key); 332 compute_O_rc4_key(user_password, owner_password, data, key);
269 unsigned char O_data[key_bytes]; 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 std::string new_user_password = 337 std::string new_user_password =
274 std::string((char*)O_data, key_bytes); 338 std::string((char*)O_data, key_bytes);
275 bool result = false; 339 bool result = false;
@@ -716,9 +780,10 @@ QPDF::compute_encryption_O_U( @@ -716,9 +780,10 @@ QPDF::compute_encryption_O_U(
716 std::string const& id1, std::string& O, std::string& U) 780 std::string const& id1, std::string& O, std::string& U)
717 { 781 {
718 EncryptionData data(V, R, key_len, P, "", "", id1, encrypt_metadata); 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 std::string const& 789 std::string const&