ooxml_crypt 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7f876fbdff234101de69ca5a2b35cee3d12ad7cfb974548648f8e3d5abb7670
4
- data.tar.gz: 8db6f0212c4d93a32c84ecb9fb7337c7d94eab425381fb3b3c88cfc8b2bd7ce3
3
+ metadata.gz: '05192ad6823ce18fed6b0d5a177559c55e8279843f7535d4120e2ea2172d1873'
4
+ data.tar.gz: f32d9322fa1253d8323329d209cece850c29e6c729ed620dee63c833fd5aadf5
5
5
  SHA512:
6
- metadata.gz: 0bc0fa7f78518b6d82a5a82725793475dcadc5d819fed25ae8c26c69e4b19dc4022ed7e73b7c7f41c5f0818d5d8892eb969f1bc77593f82354b98ca1f7fa1999
7
- data.tar.gz: 9c6fb88936d15fbdf3a33b79604802a141be4f3f3c0c5bd643cd5794f9976ac29b140c37384cf075ccd22acf3eb8853c160f319d323384e3acdcff4703c7a33e
6
+ metadata.gz: 44bb1e1ef6792309bec5043f88a0785ae5a0810d63ef6e457d296f3d153d185cf3724c534bc94536848c4d567c0f6b87a4c7e683181440a04ca842a5fe146195
7
+ data.tar.gz: 73996d66386a8ff1d14a4c7322bab4fc30c6ff8ecfe7f877e0a2fddacb2606ad3a00668bdea15beb9f75d9770c9b6fa8516dd3316605ba553cb578a4499f135d
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OoxmlCrypt
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
data/ooxml_crypt.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.require_paths = ["lib"]
27
27
  spec.extensions = ["ext/ooxml_crypt/extconf.rb"]
28
28
 
29
- spec.add_development_dependency "bundler", "~> 2.2"
29
+ spec.add_development_dependency "bundler"
30
30
  spec.add_development_dependency "rake", "~> 13.0"
31
31
  spec.add_development_dependency "rake-compiler", "~> 1.1"
32
32
 
@@ -11,11 +11,15 @@
11
11
  #endif
12
12
  #include <stdio.h>
13
13
 
14
+ //#define CYBOZU_BENCH_CHRONO
15
+
14
16
  #ifdef __EMSCRIPTEN__
15
17
  #define CYBOZU_BENCH_USE_GETTIMEOFDAY
16
18
  #endif
17
19
 
18
- #ifdef CYBOZU_BENCH_USE_GETTIMEOFDAY
20
+ #ifdef CYBOZU_BENCH_CHRONO
21
+ #include <chrono>
22
+ #elif defined(CYBOZU_BENCH_USE_GETTIMEOFDAY)
19
23
  #include <sys/time.h>
20
24
  #elif !defined(CYBOZU_BENCH_DONT_USE_RDTSC)
21
25
  #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
@@ -59,10 +63,17 @@ static inline void setPutCallback(void (*f)(double))
59
63
  } // cybozu::bench
60
64
 
61
65
  class CpuClock {
66
+ #ifdef CYBOZU_BENCH_CHRONO
67
+ typedef std::chrono::high_resolution_clock::time_point Time;
68
+ #else
69
+ typedef uint64_t Time;
70
+ #endif
62
71
  public:
63
- static inline uint64_t getCpuClk()
72
+ static inline Time getCpuClk()
64
73
  {
65
- #ifdef CYBOZU_BENCH_USE_RDTSC
74
+ #ifdef CYBOZU_BENCH_CHRONO
75
+ return std::chrono::high_resolution_clock::now();
76
+ #elif defined(CYBOZU_BENCH_USE_RDTSC)
66
77
  #ifdef _MSC_VER
67
78
  return __rdtsc();
68
79
  #else
@@ -93,17 +104,25 @@ public:
93
104
  #endif
94
105
  }
95
106
  CpuClock()
96
- : clock_(0)
107
+ : begin_()
108
+ , end_()
109
+ , clock_(0)
97
110
  , count_(0)
98
111
  {
99
112
  }
100
113
  void begin()
101
114
  {
102
- clock_ -= getCpuClk();
115
+ begin_ = getCpuClk();
103
116
  }
104
117
  void end()
105
118
  {
106
- clock_ += getCpuClk();
119
+ end_ = getCpuClk();
120
+ #ifdef CYBOZU_BENCH_CHRONO
121
+ clock_ += std::chrono::duration_cast<std::chrono::nanoseconds>(end_ - begin_).count();
122
+ #else
123
+ clock_ += end_ - begin_;
124
+ #endif
125
+ begin_ = end_;
107
126
  count_++;
108
127
  }
109
128
  int getCount() const { return count_; }
@@ -147,6 +166,8 @@ public:
147
166
  static const uint64_t maxClk = (uint64_t)1e8;
148
167
  #endif
149
168
  private:
169
+ Time begin_;
170
+ Time end_;
150
171
  uint64_t clock_;
151
172
  int count_;
152
173
  };
@@ -16,16 +16,23 @@
16
16
  #ifdef __APPLE__
17
17
  #pragma GCC diagnostic push
18
18
  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
19
+ #ifndef CYBOZU_USE_COMMONCRYPTO
20
+ #define CYBOZU_USE_COMMONCRYPTO 1
21
+ #endif
19
22
  #endif
20
- #if 0 //#ifdef __APPLE__
23
+ #if CYBOZU_USE_COMMONCRYPTO == 1
24
+ // for OpenSSL compatibility
21
25
  #define COMMON_DIGEST_FOR_OPENSSL
22
26
  #include <CommonCrypto/CommonDigest.h>
23
27
  #include <CommonCrypto/CommonHMAC.h>
28
+ #include <CommonCrypto/CommonCryptor.h>
24
29
  #define SHA1 CC_SHA1
25
30
  #define SHA224 CC_SHA224
26
31
  #define SHA256 CC_SHA256
27
32
  #define SHA384 CC_SHA384
28
33
  #define SHA512 CC_SHA512
34
+ #undef CYBOZU_USE_OPENSSL_NEW_HASH
35
+ #define CYBOZU_USE_OPENSSL_NEW_HASH 0
29
36
  #else
30
37
  #include <openssl/hmac.h>
31
38
  #include <openssl/evp.h>
@@ -239,22 +246,55 @@ public:
239
246
  };
240
247
 
241
248
  class Hmac {
249
+ #if CYBOZU_USE_COMMONCRYPTO == 1
250
+ CCHmacAlgorithm alg_;
251
+ size_t hashSize_;
252
+ #else
242
253
  const EVP_MD *evp_;
254
+ #endif
243
255
  public:
244
256
  explicit Hmac(Hash::Name name = Hash::N_SHA1)
245
257
  {
246
258
  switch (name) {
259
+ #if CYBOZU_USE_COMMONCRYPTO == 1
260
+ case Hash::N_SHA1:
261
+ alg_ = kCCHmacAlgSHA1;
262
+ hashSize_ = 160 / 8;
263
+ break;
264
+ case Hash::N_SHA224:
265
+ alg_ = kCCHmacAlgSHA224;
266
+ hashSize_ = 224 / 8;
267
+ break;
268
+ case Hash::N_SHA256:
269
+ alg_ = kCCHmacAlgSHA256;
270
+ hashSize_ = 256 / 8;
271
+ break;
272
+ case Hash::N_SHA384:
273
+ alg_ = kCCHmacAlgSHA384;
274
+ hashSize_ = 384 / 8;
275
+ break;
276
+ case Hash::N_SHA512:
277
+ alg_ = kCCHmacAlgSHA512;
278
+ hashSize_ = 512 / 8;
279
+ break;
280
+ #else
247
281
  case Hash::N_SHA1: evp_ = EVP_sha1(); break;
248
282
  case Hash::N_SHA224: evp_ = EVP_sha224(); break;
249
283
  case Hash::N_SHA256: evp_ = EVP_sha256(); break;
250
284
  case Hash::N_SHA384: evp_ = EVP_sha384(); break;
251
285
  case Hash::N_SHA512: evp_ = EVP_sha512(); break;
286
+ #endif
252
287
  default:
253
288
  throw cybozu::Exception("crypto:Hmac:") << name;
254
289
  }
255
290
  }
256
291
  std::string eval(const std::string& key, const std::string& data)
257
292
  {
293
+ #if CYBOZU_USE_COMMONCRYPTO == 1
294
+ std::string out(hashSize_, 0);
295
+ CCHmac(alg_, key.data(), key.size(), data.data(), data.size(), &out[0]);
296
+ return out;
297
+ #else
258
298
  std::string out(EVP_MD_size(evp_) + 1, 0);
259
299
  unsigned int outLen = 0;
260
300
  if (HMAC(evp_, key.c_str(), static_cast<int>(key.size()),
@@ -263,27 +303,43 @@ public:
263
303
  return out;
264
304
  }
265
305
  throw cybozu::Exception("crypto::Hamc::eval");
306
+ #endif
266
307
  }
267
308
  };
268
309
 
269
310
  class Cipher {
270
- const EVP_CIPHER *cipher_;
271
- EVP_CIPHER_CTX *ctx_;
272
311
  public:
273
312
  enum Name {
274
313
  N_AES128_CBC,
275
314
  N_AES192_CBC,
276
315
  N_AES256_CBC,
316
+ N_AES128_CTR,
317
+ N_AES192_CTR,
318
+ N_AES256_CTR,
277
319
  N_AES128_ECB, // be carefull to use
278
320
  N_AES192_ECB, // be carefull to use
279
321
  N_AES256_ECB, // be carefull to use
280
322
  };
323
+
324
+ private:
325
+ #if CYBOZU_USE_COMMONCRYPTO == 1
326
+ Name name_;
327
+ CCCryptorRef ctx_;
328
+ #else
329
+ const EVP_CIPHER *cipher_;
330
+ EVP_CIPHER_CTX *ctx_;
331
+ #endif
332
+
333
+ public:
281
334
  static inline size_t getSize(Name name)
282
335
  {
283
336
  switch (name) {
284
337
  case N_AES128_CBC: return 128;
285
338
  case N_AES192_CBC: return 192;
286
339
  case N_AES256_CBC: return 256;
340
+ case N_AES128_CTR: return 128;
341
+ case N_AES192_CTR: return 192;
342
+ case N_AES256_CTR: return 256;
287
343
  case N_AES128_ECB: return 128;
288
344
  case N_AES192_ECB: return 192;
289
345
  case N_AES256_ECB: return 256;
@@ -296,31 +352,93 @@ public:
296
352
  Encoding
297
353
  };
298
354
  explicit Cipher(Name name = N_AES128_CBC)
355
+ #if CYBOZU_USE_COMMONCRYPTO == 1
356
+ : name_(name)
357
+ , ctx_(0)
358
+ #else
299
359
  : cipher_(0)
300
360
  , ctx_(0)
361
+ #endif
301
362
  {
363
+ #if CYBOZU_USE_COMMONCRYPTO == 1
364
+ switch (name_) {
365
+ case N_AES128_CBC:
366
+ case N_AES192_CBC:
367
+ case N_AES256_CBC:
368
+ case N_AES128_CTR:
369
+ case N_AES192_CTR:
370
+ case N_AES256_CTR:
371
+ case N_AES128_ECB:
372
+ case N_AES192_ECB:
373
+ case N_AES256_ECB:
374
+ break;
375
+ default:
376
+ throw cybozu::Exception("crypto:Cipher:Cipher:name") << (int)name;
377
+ }
378
+ #else
302
379
  ctx_ = EVP_CIPHER_CTX_new();
303
380
  if (ctx_ == 0) throw cybozu::Exception("crypto:Cipher:EVP_CIPHER_CTX_new");
304
381
  switch (name) {
305
382
  case N_AES128_CBC: cipher_ = EVP_aes_128_cbc(); break;
306
383
  case N_AES192_CBC: cipher_ = EVP_aes_192_cbc(); break;
307
384
  case N_AES256_CBC: cipher_ = EVP_aes_256_cbc(); break;
385
+ case N_AES128_CTR: cipher_ = EVP_aes_128_ctr(); break;
386
+ case N_AES192_CTR: cipher_ = EVP_aes_192_ctr(); break;
387
+ case N_AES256_CTR: cipher_ = EVP_aes_256_ctr(); break;
308
388
  case N_AES128_ECB: cipher_ = EVP_aes_128_ecb(); break;
309
389
  case N_AES192_ECB: cipher_ = EVP_aes_192_ecb(); break;
310
390
  case N_AES256_ECB: cipher_ = EVP_aes_256_ecb(); break;
311
391
  default:
312
392
  throw cybozu::Exception("crypto:Cipher:Cipher:name") << (int)name;
313
393
  }
394
+ #endif
314
395
  }
315
396
  ~Cipher()
316
397
  {
398
+ #if CYBOZU_USE_COMMONCRYPTO == 1
399
+ if (ctx_) CCCryptorRelease(ctx_);
400
+ #else
317
401
  if (ctx_) EVP_CIPHER_CTX_free(ctx_);
402
+ #endif
318
403
  }
319
404
  /*
320
405
  @note don't use padding = true
321
406
  */
322
407
  void setup(Mode mode, const std::string& key, const std::string& iv, bool padding = false)
323
408
  {
409
+ #if CYBOZU_USE_COMMONCRYPTO == 1
410
+ const int keyLen = static_cast<int>(key.size());
411
+ const int expectedKeyLen = static_cast<int>(getSize(name_) / 8);
412
+ if (keyLen != expectedKeyLen) {
413
+ throw cybozu::Exception("crypto:Cipher:setup:keyLen") << keyLen << expectedKeyLen;
414
+ }
415
+ const bool isCtr = name_ == N_AES128_CTR || name_ == N_AES192_CTR || name_ == N_AES256_CTR;
416
+ const bool isEcb = name_ == N_AES128_ECB || name_ == N_AES192_ECB || name_ == N_AES256_ECB;
417
+ if (!isEcb) {
418
+ if (iv.size() < kCCBlockSizeAES128) {
419
+ throw cybozu::Exception("crypto:Cipher:setup:ivLen") << iv.size() << ">=" << kCCBlockSizeAES128;
420
+ }
421
+ }
422
+ if (ctx_) {
423
+ CCCryptorRelease(ctx_);
424
+ ctx_ = 0;
425
+ }
426
+ CCCryptorStatus status;
427
+ if (isCtr) {
428
+ status = CCCryptorCreateWithMode(mode == Encoding ? kCCEncrypt : kCCDecrypt,
429
+ kCCModeCTR, kCCAlgorithmAES128, ccNoPadding, iv.data(), key.data(), key.size(), 0, 0, 0,
430
+ kCCModeOptionCTR_BE, &ctx_);
431
+ } else {
432
+ CCOptions options = isEcb ? kCCOptionECBMode : 0;
433
+ if (padding) options |= kCCOptionPKCS7Padding;
434
+ const void *ivPtr = isEcb ? 0 : iv.data();
435
+ status = CCCryptorCreate(mode == Encoding ? kCCEncrypt : kCCDecrypt,
436
+ kCCAlgorithmAES128, options, key.data(), key.size(), ivPtr, &ctx_);
437
+ }
438
+ if (status != kCCSuccess) {
439
+ throw cybozu::Exception("crypto:Cipher:setup:CCCryptorCreate") << (int)status;
440
+ }
441
+ #else
324
442
  const int keyLen = static_cast<int>(key.size());
325
443
  const int expectedKeyLen = EVP_CIPHER_key_length(cipher_);
326
444
  if (keyLen != expectedKeyLen) {
@@ -342,6 +460,7 @@ public:
342
460
  throw cybozu::Exception("crypto:Cipher:setup:ivLen") << ivLen << expectedIvLen;
343
461
  }
344
462
  */
463
+ #endif
345
464
  }
346
465
  /*
347
466
  the size of outBuf must be larger than inBufSize + blockSize
@@ -350,10 +469,19 @@ public:
350
469
  */
351
470
  int update(char *outBuf, const char *inBuf, int inBufSize)
352
471
  {
472
+ #if CYBOZU_USE_COMMONCRYPTO == 1
473
+ if (ctx_ == 0) return -1;
474
+ size_t outLen = 0;
475
+ const CCCryptorStatus status = CCCryptorUpdate(ctx_, inBuf, static_cast<size_t>(inBufSize), outBuf,
476
+ static_cast<size_t>(inBufSize + kCCBlockSizeAES128), &outLen);
477
+ if (status != kCCSuccess) return -1;
478
+ return static_cast<int>(outLen);
479
+ #else
353
480
  int outLen = 0;
354
481
  int ret = EVP_CipherUpdate(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen, cybozu::cast<const uint8_t*>(inBuf), inBufSize);
355
482
  if (ret != 1) return -1;
356
483
  return outLen;
484
+ #endif
357
485
  }
358
486
  /*
359
487
  return -1 if padding
@@ -361,10 +489,18 @@ public:
361
489
  */
362
490
  int finalize(char *outBuf)
363
491
  {
492
+ #if CYBOZU_USE_COMMONCRYPTO == 1
493
+ if (ctx_ == 0) return -1;
494
+ size_t outLen = 0;
495
+ const CCCryptorStatus status = CCCryptorFinal(ctx_, outBuf, kCCBlockSizeAES128, &outLen);
496
+ if (status != kCCSuccess) return -1;
497
+ return static_cast<int>(outLen);
498
+ #else
364
499
  int outLen = 0;
365
500
  int ret = EVP_CipherFinal_ex(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen);
366
501
  if (ret != 1) return -1;
367
502
  return outLen;
503
+ #endif
368
504
  }
369
505
  };
370
506
 
@@ -9,6 +9,10 @@
9
9
  #include <cybozu/inttype.hpp>
10
10
  #include <string.h>
11
11
 
12
+ #ifdef _MSC_VER
13
+ #include <stdlib.h>
14
+ #endif
15
+
12
16
  namespace cybozu {
13
17
 
14
18
  #ifdef _MSC_VER
@@ -168,6 +168,26 @@ public:
168
168
  {
169
169
  return operator<<(cybozu::exception::wstr2str(s));
170
170
  }
171
+ #endif
172
+ #if CYBOZU_CPLUSPLUS >= 202002L
173
+ Exception& operator<<(char16_t x)
174
+ {
175
+ std::ostringstream os;
176
+ os << static_cast<unsigned int>(x);
177
+ return operator<<(os.str());
178
+ }
179
+ Exception& operator<<(char32_t x)
180
+ {
181
+ std::ostringstream os;
182
+ os << static_cast<unsigned int>(x);
183
+ return operator<<(os.str());
184
+ }
185
+ Exception& operator<<(wchar_t x)
186
+ {
187
+ std::ostringstream os;
188
+ os << static_cast<unsigned int>(x);
189
+ return operator<<(os.str());
190
+ }
171
191
  #endif
172
192
  template<class T>
173
193
  Exception& operator<<(const T& x)
@@ -57,8 +57,7 @@
57
57
  #endif
58
58
  #ifndef CYBOZU_ALLOCA
59
59
  #ifdef _MSC_VER
60
- #include <malloc.h>
61
- #define CYBOZU_ALLOCA(x) _malloca(x)
60
+ #define CYBOZU_ALLOCA(x) _alloca(x)
62
61
  #else
63
62
  #define CYBOZU_ALLOCA(x) __builtin_alloca(x)
64
63
  #endif
@@ -100,11 +99,18 @@
100
99
  #define CYBOZU_GNUC_PREREQ(major, minor) 0
101
100
  #endif
102
101
 
103
- #if (__cplusplus >= 201703)
102
+ // MSVC reports __cplusplus=199711 unless /Zc:__cplusplus is specified
103
+ #ifdef _MSC_VER
104
+ #define CYBOZU_CPLUSPLUS _MSVC_LANG
105
+ #else
106
+ #define CYBOZU_CPLUSPLUS __cplusplus
107
+ #endif
108
+
109
+ #if (CYBOZU_CPLUSPLUS >= 201703)
104
110
  #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP17
105
- #elif (__cplusplus >= 201402)
111
+ #elif (CYBOZU_CPLUSPLUS >= 201402)
106
112
  #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP14
107
- #elif (__cplusplus >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__GXX_EXPERIMENTAL_CXX0X__)
113
+ #elif (CYBOZU_CPLUSPLUS >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__GXX_EXPERIMENTAL_CXX0X__)
108
114
  #if defined(_MSC_VER) && (_MSC_VER <= 1600)
109
115
  #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_TR1
110
116
  #else
@@ -23,6 +23,11 @@
23
23
  #include <cybozu/exception.hpp>
24
24
  #include <cybozu/hash.hpp>
25
25
 
26
+ #if CYBOZU_CPLUSPLUS >= 202002L
27
+ #include <compare>
28
+ #endif
29
+
30
+
26
31
  // to deal with unicode literal(same macro defined in regex.hpp)
27
32
  #ifdef _MSC_VER
28
33
  #define CYBOZU_STR_WCHAR wchar_t
@@ -43,7 +48,7 @@ namespace cybozu {
43
48
  typedef unsigned short Char16; /* unsigned is necessary for gcc */
44
49
  #endif
45
50
  #else
46
- typedef int Char; //!< Char for Windows
51
+ typedef unsigned int Char; //!< Char for Windows
47
52
  typedef wchar_t Char16;
48
53
  #endif
49
54
 
@@ -1517,12 +1522,20 @@ public:
1517
1522
  get internal str(don't use this function)
1518
1523
  */
1519
1524
  BasicString& get() { return str_; }
1525
+ #if CYBOZU_CPLUSPLUS >= 202002L
1526
+ template<class T>bool operator==(const T& rhs) const { return compare(rhs) == 0; }
1527
+ template<class T>std::strong_ordering operator<=>(const T& rhs) const {
1528
+ int r = compare(rhs);
1529
+ return r < 0 ? std::strong_ordering::less : r > 0 ? std::strong_ordering::greater : std::strong_ordering::equal;
1530
+ }
1531
+ #else
1520
1532
  template<class T>bool operator==(const T& rhs) const { return compare(rhs) == 0; }
1521
1533
  template<class T>bool operator!=(const T& rhs) const { return compare(rhs) != 0; }
1522
1534
  template<class T>bool operator<=(const T& rhs) const { return compare(rhs) <= 0; }
1523
1535
  template<class T>bool operator>=(const T& rhs) const { return compare(rhs) >= 0; }
1524
1536
  template<class T>bool operator<(const T& rhs) const { return compare(rhs) < 0; }
1525
1537
  template<class T>bool operator>(const T& rhs) const { return compare(rhs) > 0; }
1538
+ #endif
1526
1539
  private:
1527
1540
  template<class Iterator>
1528
1541
  cybozu::Char getOneChar(Iterator& begin, const Iterator& end)
@@ -1570,6 +1583,7 @@ inline std::ostream& operator<<(std::ostream& os, const String& str)
1570
1583
  return os << str.toUtf8();
1571
1584
  }
1572
1585
 
1586
+ #if CYBOZU_CPLUSPLUS < 202002L
1573
1587
  inline bool operator==(const cybozu::Char* lhs, const String& rhs) { return rhs == lhs; }
1574
1588
  inline bool operator!=(const cybozu::Char* lhs, const String& rhs) { return rhs != lhs; }
1575
1589
  inline bool operator<=(const cybozu::Char* lhs, const String& rhs) { return rhs >= lhs; }
@@ -1605,6 +1619,7 @@ inline bool operator>=(const std::wstring& lhs, const String& rhs) { return rhs
1605
1619
  inline bool operator<(const std::wstring& lhs, const String& rhs) { return rhs > lhs; }
1606
1620
  inline bool operator>(const std::wstring& lhs, const String& rhs) { return rhs < lhs; }
1607
1621
  #endif
1622
+ #endif
1608
1623
 
1609
1624
  inline void swap(String& lhs, String& rhs) { lhs.swap(rhs); }
1610
1625
 
@@ -1,7 +1,7 @@
1
1
  #include <cybozu/test.hpp>
2
2
  #include <cybozu/crypto.hpp>
3
- #include <cybozu/sha2.hpp>
4
3
  #include <cybozu/itoa.hpp>
4
+ #include <cybozu/atoi.hpp>
5
5
 
6
6
  CYBOZU_TEST_AUTO(hashName)
7
7
  {
@@ -101,6 +101,159 @@ std::string toHexStr(const std::string& buf)
101
101
  return s;
102
102
  }
103
103
 
104
+ std::string fromHexStr(const std::string& hex)
105
+ {
106
+ if ((hex.size() & 1) != 0) {
107
+ throw cybozu::Exception("fromHexStr:bad size") << hex.size();
108
+ }
109
+ std::string out(hex.size() / 2, 0);
110
+ for (size_t i = 0; i < out.size(); i++) {
111
+ out[i] = static_cast<uint8_t>(cybozu::hextoi(&hex[i * 2], 2));
112
+ }
113
+ return out;
114
+ }
115
+
116
+ std::string evalCipher(cybozu::crypto::Cipher::Name name, cybozu::crypto::Cipher::Mode mode, const std::string& key, const std::string& iv, const std::string& input, bool padding = false)
117
+ {
118
+ cybozu::crypto::Cipher cipher(name);
119
+ cipher.setup(mode, key, iv, padding);
120
+ std::string out(input.size() + 32, 0);
121
+ int pos = cipher.update(&out[0], input.data(), static_cast<int>(input.size()));
122
+ CYBOZU_TEST_ASSERT(pos >= 0);
123
+ int last = cipher.finalize(&out[pos]);
124
+ CYBOZU_TEST_ASSERT(last >= 0);
125
+ out.resize(pos + last);
126
+ return out;
127
+ }
128
+
129
+ struct AesCbcTestVec {
130
+ cybozu::crypto::Cipher::Name name;
131
+ const char *keyHex;
132
+ const char *ivHex;
133
+ const char *plain;
134
+ const char *cipherHex;
135
+ bool isAscii;
136
+ };
137
+
138
+ const AesCbcTestVec aesCbcTbl[] = {
139
+ {
140
+ cybozu::crypto::Cipher::N_AES128_CBC,
141
+ "06a9214036b8a15b512e03d534120006",
142
+ "3dafba429d9eb430b422da802c9fac41",
143
+ "Single block msg",
144
+ "e353779c1079aeb82708942dbe77181a",
145
+ true,
146
+ },
147
+ {
148
+ cybozu::crypto::Cipher::N_AES128_CBC,
149
+ "c286696d887c9aa0611bbb3e2025a45a",
150
+ "562e17996d093d28ddb3ba695a2e6f58",
151
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
152
+ "d296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1",
153
+ false,
154
+ },
155
+ {
156
+ cybozu::crypto::Cipher::N_AES128_CBC,
157
+ "6c3ea0477630ce21a2ce334aa746c2cd",
158
+ "c782dc4c098c66cbd9cd27d825682c81",
159
+ "This is a 48-byte message (exactly 3 AES blocks)",
160
+ "d0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684",
161
+ true,
162
+ },
163
+ {
164
+ cybozu::crypto::Cipher::N_AES128_CBC,
165
+ "56e47a38c5598974bc46903dba290349",
166
+ "8ce82eefbea0da3c44699ed7db51b7d9",
167
+ "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf",
168
+ "c30e32ffedc0774e6aff6af0869f71aa0f3af07a9a31a9c684db207eb0ef8e4e35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55",
169
+ false,
170
+ },
171
+ };
172
+
173
+ struct AesCtrTestVec {
174
+ cybozu::crypto::Cipher::Name name;
175
+ const char *keyHex;
176
+ const char *counterHex;
177
+ const char *plain;
178
+ const char *cipherHex;
179
+ bool isAscii;
180
+ };
181
+
182
+ const AesCtrTestVec aesCtrTbl[] = {
183
+ {
184
+ cybozu::crypto::Cipher::N_AES128_CTR,
185
+ "ae6852f8121067cc4bf7a5765577f39e",
186
+ "00000030000000000000000000000001",
187
+ "Single block msg",
188
+ "e4095d4fb7a7b3792d6175a3261311b8",
189
+ true,
190
+ },
191
+ {
192
+ cybozu::crypto::Cipher::N_AES128_CTR,
193
+ "7e24067817fae0d743d6ce1f32539163",
194
+ "006cb6dbc0543b59da48d90b00000001",
195
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
196
+ "5104a106168a72d9790d41ee8edad388eb2e1efc46da57c8fce630df9141be28",
197
+ false,
198
+ },
199
+ {
200
+ cybozu::crypto::Cipher::N_AES128_CTR,
201
+ "7691be035e5020a8ac6e618529f9a0dc",
202
+ "00e0017b27777f3f4a1786f000000001",
203
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223",
204
+ "c1cf48a89f2ffdd9cf4652e9efdb72d74540a42bde6d7836d59a5ceaaef3105325b2072f",
205
+ false,
206
+ },
207
+ {
208
+ cybozu::crypto::Cipher::N_AES192_CTR,
209
+ "16af5b145fc9f579c175f93e3bfb0eed863d06ccfdb78515",
210
+ "0000004836733c147d6d93cb00000001",
211
+ "Single block msg",
212
+ "4b55384fe259c9c84e7935a003cbe928",
213
+ true,
214
+ },
215
+ {
216
+ cybozu::crypto::Cipher::N_AES192_CTR,
217
+ "7c5cb2401b3dc33c19e7340819e0f69c678c3db8e6f6a91a",
218
+ "0096b03b020c6eadc2cb500d00000001",
219
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
220
+ "453243fc609b23327edfaafa7131cd9f8490701c5ad4a79cfc1fe0ff42f4fb00",
221
+ false,
222
+ },
223
+ {
224
+ cybozu::crypto::Cipher::N_AES192_CTR,
225
+ "02bf391ee8ecb159b959617b0965279bf59b60a786d3e0fe",
226
+ "0007bdfd5cbd60278dcc091200000001",
227
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223",
228
+ "96893fc55e5c722f540b7dd1ddf7e758d288bc95c69165884536c811662f2188abee0935",
229
+ false,
230
+ },
231
+ {
232
+ cybozu::crypto::Cipher::N_AES256_CTR,
233
+ "776beff2851db06f4c8a0542c8696f6c6a81af1eec96b4d37fc1d689e6c1c104",
234
+ "00000060db5672c97aa8f0b200000001",
235
+ "Single block msg",
236
+ "145ad01dbf824ec7560863dc71e3e0c0",
237
+ true,
238
+ },
239
+ {
240
+ cybozu::crypto::Cipher::N_AES256_CTR,
241
+ "f6d66d6bd52d59bb0796365879eff886c66dd51a5b6a99744b50590c87a23884",
242
+ "00faac24c1585ef15a43d87500000001",
243
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
244
+ "f05e231b3894612c49ee000b804eb2a9b8306b508f839d6a5530831d9344af1c",
245
+ false,
246
+ },
247
+ {
248
+ cybozu::crypto::Cipher::N_AES256_CTR,
249
+ "ff7a617ce69148e4f1726e2f43581de2aa62d9f805532edff1eed687fb54153d",
250
+ "001cc5b751a51d70a1c1114800000001",
251
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223",
252
+ "eb6c52821d0bbbf7ce7594462aca4faab407df866569fd07f48cc0b583d6071f1ec0e6b8",
253
+ false,
254
+ },
255
+ };
256
+
104
257
  CYBOZU_TEST_AUTO(sha256)
105
258
  {
106
259
  for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(sha256Tbl); i++) {
@@ -120,3 +273,27 @@ CYBOZU_TEST_AUTO(sha512)
120
273
  CYBOZU_TEST_EQUAL(toHexStr(md), sha512Tbl[i].out);
121
274
  }
122
275
  }
276
+
277
+ CYBOZU_TEST_AUTO(aesCbcRfc3602)
278
+ {
279
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(aesCbcTbl); i++) {
280
+ const std::string key = fromHexStr(aesCbcTbl[i].keyHex);
281
+ const std::string iv = fromHexStr(aesCbcTbl[i].ivHex);
282
+ const std::string plain = aesCbcTbl[i].isAscii ? std::string(aesCbcTbl[i].plain) : fromHexStr(aesCbcTbl[i].plain);
283
+ const std::string cipher = fromHexStr(aesCbcTbl[i].cipherHex);
284
+ CYBOZU_TEST_EQUAL(evalCipher(aesCbcTbl[i].name, cybozu::crypto::Cipher::Encoding, key, iv, plain), cipher);
285
+ CYBOZU_TEST_EQUAL(evalCipher(aesCbcTbl[i].name, cybozu::crypto::Cipher::Decoding, key, iv, cipher), plain);
286
+ }
287
+ }
288
+
289
+ CYBOZU_TEST_AUTO(aesCtrRfc3686)
290
+ {
291
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(aesCtrTbl); i++) {
292
+ const std::string key = fromHexStr(aesCtrTbl[i].keyHex);
293
+ const std::string iv = fromHexStr(aesCtrTbl[i].counterHex);
294
+ const std::string plain = aesCtrTbl[i].isAscii ? std::string(aesCtrTbl[i].plain) : fromHexStr(aesCtrTbl[i].plain);
295
+ const std::string cipher = fromHexStr(aesCtrTbl[i].cipherHex);
296
+ CYBOZU_TEST_EQUAL(evalCipher(aesCtrTbl[i].name, cybozu::crypto::Cipher::Encoding, key, iv, plain), cipher);
297
+ CYBOZU_TEST_EQUAL(evalCipher(aesCtrTbl[i].name, cybozu::crypto::Cipher::Decoding, key, iv, cipher), plain);
298
+ }
299
+ }
@@ -7,16 +7,16 @@ CYBOZU_TEST_AUTO(env)
7
7
  std::string val;
8
8
  CYBOZU_TEST_ASSERT(!cybozu::QueryEnv(val, "aw3vraw3vasv"));
9
9
  #ifdef _WIN32
10
- const char *key = "SystemDrive";
11
- const char *assumeVal = "C:";
10
+ const char *key = "USERPROFILE";
11
+ const char *assumeVal = "C:\\Users";
12
12
  #elif defined(__APPLE__)
13
- const char *key = "OSTYPE";
14
- const char *assumeVal = "darwin";
13
+ const char *key = "HOME";
14
+ const char *assumeVal = "/Users";
15
15
  #else
16
- const char *key = "OSTYPE";
17
- const char *assumeVal = "linux";
16
+ const char *key = "HOME";
17
+ const char *assumeVal = "/home";
18
18
  #endif
19
19
  val = cybozu::GetEnv(key);
20
- CYBOZU_TEST_EQUAL(val, assumeVal);
20
+ CYBOZU_TEST_EQUAL(val.substr(0, strlen(assumeVal)), assumeVal);
21
21
  CYBOZU_TEST_EQUAL(cybozu::GetEnv("asvrifansevjase", "default"), "default");
22
22
  }
@@ -14,6 +14,7 @@ using namespace cybozu;
14
14
 
15
15
  #ifdef _MSC_VER
16
16
  #pragma warning(disable : 4309)
17
+ #pragma warning(disable : 4310)
17
18
  #endif
18
19
 
19
20
  ///////// iterator
@@ -221,7 +222,7 @@ CYBOZU_TEST_AUTO(string_constructor_surrogate_pair_test)
221
222
  const Char s[] = { 0x00003069, 0x00000061, 0x00000062, 0x00000063, 0x0000308c, 0x0002000b, 0 };
222
223
  std::stringstream ss;
223
224
  ss << a;
224
- CYBOZU_TEST_EQUAL(a, s);
225
+ CYBOZU_TEST_ASSERT(a == s);
225
226
  CYBOZU_TEST_EQUAL(ss.str(), "\xe3\x81\xa9" "abc" "\xe3\x82\x8c" "\xf0\xa0\x80\x8b");
226
227
  }
227
228
 
@@ -297,7 +298,7 @@ CYBOZU_TEST_AUTO(string_index_test_at)
297
298
  String s("\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xaf" "UTF-8 1");
298
299
  Char t = s.at(3);
299
300
  Char c = 'U';
300
- CYBOZU_TEST_EQUAL(t, c);
301
+ CYBOZU_TEST_ASSERT(t == c);
301
302
  }
302
303
 
303
304
  CYBOZU_TEST_AUTO(string_index_test_at_exception)
@@ -320,7 +321,7 @@ CYBOZU_TEST_AUTO(string_index_test_index)
320
321
  String s("\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xaf" "UTF-8 1");
321
322
  Char t = s[6];
322
323
  Char c = '-';
323
- CYBOZU_TEST_EQUAL(t, c);
324
+ CYBOZU_TEST_ASSERT(t == c);
324
325
  }
325
326
 
326
327
  //cybozu::String
@@ -614,7 +615,7 @@ CYBOZU_TEST_AUTO(string_utility_test_c_str)
614
615
  String s("abcdefg");
615
616
  const Char cs[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 0};
616
617
  for (int i = 0; i<8 ; i++) {
617
- CYBOZU_TEST_EQUAL(s.c_str()[i], cs[i]);
618
+ CYBOZU_TEST_ASSERT(s.c_str()[i] == cs[i]);
618
619
  }
619
620
  }
620
621
 
@@ -624,7 +625,7 @@ CYBOZU_TEST_AUTO(string_utility_test_data)
624
625
  String s("abcdefg");
625
626
  const Char cs[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 0};
626
627
  for (int i = 0; i<7 ; i++) {
627
- CYBOZU_TEST_EQUAL(s.c_str()[i], cs[i]);
628
+ CYBOZU_TEST_ASSERT(s.c_str()[i] == cs[i]);
628
629
  }
629
630
  }
630
631
 
@@ -1547,7 +1548,7 @@ CYBOZU_TEST_AUTO(utf16)
1547
1548
  cybozu::ConvertUtf8ToUtf16(&s, utf8, utf8 + 12);
1548
1549
  CYBOZU_TEST_EQUAL(s.size(), 6u);
1549
1550
  for (int i = 0; i < 6; i++) {
1550
- CYBOZU_TEST_EQUAL(s[i], utf16[i]);
1551
+ CYBOZU_TEST_ASSERT(s[i] == utf16[i]);
1551
1552
  }
1552
1553
  std::string t;
1553
1554
  cybozu::ConvertUtf16ToUtf8(&t, utf16, utf16 + 6);
@@ -1565,7 +1566,7 @@ CYBOZU_TEST_AUTO(Utf8ref)
1565
1566
  cybozu::Char c;
1566
1567
  size_t i = 0;
1567
1568
  while (ref.next(&c)) {
1568
- CYBOZU_TEST_EQUAL(c, s[i]);
1569
+ CYBOZU_TEST_ASSERT(c == s[i]);
1569
1570
  i++;
1570
1571
  }
1571
1572
  CYBOZU_TEST_EQUAL(i, s.size());
@@ -1578,7 +1579,7 @@ CYBOZU_TEST_AUTO(Utf8ref_bad_char)
1578
1579
  cybozu::Utf8ref ref(utf8.c_str(), utf8.size());
1579
1580
  cybozu::Char c;
1580
1581
  CYBOZU_TEST_ASSERT(ref.next(&c));
1581
- CYBOZU_TEST_EQUAL(s[0], c);
1582
+ CYBOZU_TEST_ASSERT(s[0] == c);
1582
1583
  CYBOZU_TEST_EXCEPTION(ref.next(&c), std::exception);
1583
1584
  }
1584
1585
 
@@ -1590,7 +1591,7 @@ CYBOZU_TEST_AUTO(Utf8ref_ignore_bad_char)
1590
1591
  cybozu::Char c;
1591
1592
  size_t i = 0;
1592
1593
  while (ref.next(&c)) {
1593
- CYBOZU_TEST_EQUAL(c, s[i]);
1594
+ CYBOZU_TEST_ASSERT(c == s[i]);
1594
1595
  i++;
1595
1596
  }
1596
1597
  CYBOZU_TEST_EQUAL(i, s.size());
@@ -1605,11 +1606,11 @@ CYBOZU_TEST_AUTO(equal)
1605
1606
  CYBOZU_TEST_EQUAL(a, a);
1606
1607
  CYBOZU_TEST_EQUAL(a, b);
1607
1608
  CYBOZU_TEST_EQUAL(a, c);
1608
- CYBOZU_TEST_EQUAL(a, d);
1609
+ CYBOZU_TEST_ASSERT(a == d);
1609
1610
 
1610
1611
  CYBOZU_TEST_EQUAL(b, a);
1611
1612
  CYBOZU_TEST_EQUAL(c, a);
1612
- CYBOZU_TEST_EQUAL(d, a);
1613
+ CYBOZU_TEST_ASSERT(d == a);
1613
1614
 
1614
1615
  CYBOZU_TEST_ASSERT(!(a != a));
1615
1616
  CYBOZU_TEST_ASSERT(!(a != b));
@@ -1621,8 +1622,8 @@ CYBOZU_TEST_AUTO(equal)
1621
1622
  CYBOZU_TEST_ASSERT(!(d != a));
1622
1623
  #ifdef _MSC_VER
1623
1624
  const wchar_t e[] = L"abc";
1624
- CYBOZU_TEST_EQUAL(a, e);
1625
- CYBOZU_TEST_EQUAL(e, a);
1625
+ CYBOZU_TEST_ASSERT(a == e);
1626
+ CYBOZU_TEST_ASSERT(e == a);
1626
1627
  CYBOZU_TEST_ASSERT(!(a != e));
1627
1628
  CYBOZU_TEST_ASSERT(!(e != a));
1628
1629
  #endif
@@ -11,14 +11,14 @@ ifeq ($(OLD_OPENSSL),1)
11
11
  CFLAGS+=-DCYBOZU_USE_OPENSSL_NEW_HASH=0
12
12
  endif
13
13
 
14
- LDFLAGS = -lcrypto
15
14
  UNAME_S=$(shell uname -s)
16
15
  ifeq ($(UNAME_S),Darwin)
17
- EXT_DIR?=/opt/homebrew/
18
- CFLAGS+=-I$(EXT_DIR)/include
19
- LDFLAGS+=-L$(EXT_DIR)/lib
20
- LIB_SUF=dylib
16
+ # EXT_DIR?=/opt/homebrew/
17
+ # CFLAGS+=-I$(EXT_DIR)/include
18
+ # LDFLAGS+=-L$(EXT_DIR)/lib
19
+ # LIB_SUF=dylib
21
20
  else
21
+ LDFLAGS = -lcrypto
22
22
  LIB_SUF=so
23
23
  endif
24
24
 
@@ -38,7 +38,7 @@ endif
38
38
 
39
39
  TOPDIR:=$(realpath $(dir $(lastword $(MAKEFILE_LIST))))/
40
40
  CFLAGS+= -I$(TOPDIR)include -I$(TOPDIR)../cybozulib/include
41
- LDFLAGS+= -L$(TOPDIR)lib -lcrypto -lpthread
41
+ LDFLAGS+= -L$(TOPDIR)lib
42
42
  ifneq ($(UNAME_S),Darwin)
43
43
  LDFLAGS+=-lrt
44
44
  endif
@@ -192,7 +192,14 @@ bool decode(const char *data, uint32_t dataSize, const String& outFile, const st
192
192
  ms::cfb::CompoundFile cfb(data, dataSize);
193
193
  cfb.put();
194
194
 
195
+ #if defined(__GNUC__) && __GNUC__ >= 13 && !defined(__clang__)
196
+ #pragma GCC diagnostic push
197
+ #pragma GCC diagnostic ignored "-Wdangling-reference"
198
+ #endif
195
199
  const std::string& encryptedPackage = GetContensByName(cfb, "EncryptedPackage"); // data
200
+ #if defined(__GNUC__) && __GNUC__ >= 13 && !defined(__clang__)
201
+ #pragma GCC diagnostic pop
202
+ #endif
196
203
  const EncryptionInfo info(GetContensByName(cfb, "EncryptionInfo")); // xml
197
204
  if (pSpinCount) {
198
205
  *pSpinCount = info.spinCount;
@@ -2,7 +2,7 @@ include ../common.mk
2
2
 
3
3
  TARGET=$(TEST_FILE)
4
4
 
5
- SRC=msoffice-crypt.cpp attack.cpp
5
+ SRC=msoffice-crypt.cpp #attack.cpp
6
6
 
7
7
  all: $(TARGET) $(SRC)
8
8
 
metadata CHANGED
@@ -1,28 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ooxml_crypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashish Kulkarni
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '2.2'
18
+ version: '0'
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '2.2'
25
+ version: '0'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rake
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -337,7 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
337
  - !ruby/object:Gem::Version
338
338
  version: '0'
339
339
  requirements: []
340
- rubygems_version: 3.6.2
340
+ rubygems_version: 3.6.9
341
341
  specification_version: 4
342
342
  summary: Library for encrypting/decrypting password-protected Microsoft Office XML
343
343
  (OOXML) files (e.g. .docx, .xlsx, .pptx)