RNCryptorTests.swift 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //
  2. // RNCryptorTests.swift
  3. //
  4. // Copyright © 2015 Rob Napier. All rights reserved.
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a
  7. // copy of this software and associated documentation files (the "Software"),
  8. // to deal in the Software without restriction, including without limitation
  9. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. // and/or sell copies of the Software, and to permit persons to whom the
  11. // Software is furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. // DEALINGS IN THE SOFTWARE.
  23. //
  24. import XCTest
  25. @testable import RNCryptor
  26. class RNCryptorTests: XCTestCase {
  27. func testRandomData() {
  28. let len = 1024
  29. let data = RNCryptor.randomDataOfLength(len)
  30. XCTAssertEqual(data.length, len)
  31. let secondData = RNCryptor.randomDataOfLength(len)
  32. XCTAssertNotEqual(data, secondData, "Random data this long should never be equal")
  33. }
  34. func testKDF() {
  35. let password = "a"
  36. let salt = "0102030405060708".dataFromHexEncoding!
  37. let key = V3.keyForPassword(password, salt: salt)
  38. let expect = "fc632b0c a6b23eff 9a9dc3e0 e585167f 5a328916 ed19f835 58be3ba9 828797cd".dataFromHexEncoding!
  39. XCTAssertEqual(key, expect)
  40. }
  41. func testEngine() {
  42. let data = RNCryptor.randomDataOfLength(1024)
  43. let encryptKey = RNCryptor.randomDataOfLength(V3.keySize)
  44. let iv = RNCryptor.randomDataOfLength(V3.ivSize)
  45. let encrypted = NSMutableData()
  46. do {
  47. let encryptor = Engine(operation: .Encrypt, key: encryptKey, iv: iv)
  48. encrypted.appendData(try encryptor.updateWithData(data))
  49. encrypted.appendData(try encryptor.finalData())
  50. } catch {
  51. XCTFail("Caught: \(error)")
  52. }
  53. do {
  54. let decryptor = Engine(operation: .Decrypt, key: encryptKey, iv: iv)
  55. let decrypted = NSMutableData(data:try decryptor.updateWithData(encrypted))
  56. decrypted.appendData(try decryptor.finalData())
  57. XCTAssertEqual(decrypted, data)
  58. } catch {
  59. XCTFail("Caught: \(error)")
  60. }
  61. }
  62. func testKeyEncryptor() {
  63. let encryptKey = "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f".dataFromHexEncoding!
  64. let hmacKey = "0102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00".dataFromHexEncoding!
  65. let iv = "02030405060708090a0b0c0d0e0f0001".dataFromHexEncoding!
  66. let plaintext = "01".dataFromHexEncoding!
  67. let ciphertext = "03000203 04050607 08090a0b 0c0d0e0f 0001981b 22e7a644 8118d695 bd654f72 e9d6ed75 ec14ae2a a067eed2 a98a56e0 993dfe22 ab5887b3 f6e3cdd4 0767f519 5eb5".dataFromHexEncoding!
  68. let encryptor = RNCryptor.EncryptorV3(encryptionKey: encryptKey, hmacKey: hmacKey, iv: iv)
  69. let encrypted = encryptor.encryptData(plaintext)
  70. XCTAssertEqual(encrypted, ciphertext)
  71. }
  72. func testKeyDecryptor() {
  73. let encryptKey = "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f".dataFromHexEncoding!
  74. let hmacKey = "0102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00".dataFromHexEncoding!
  75. let plaintext = "01".dataFromHexEncoding!
  76. let ciphertext = "03000203 04050607 08090a0b 0c0d0e0f 0001981b 22e7a644 8118d695 bd654f72 e9d6ed75 ec14ae2a a067eed2 a98a56e0 993dfe22 ab5887b3 f6e3cdd4 0767f519 5eb5".dataFromHexEncoding!
  77. let decryptor = RNCryptor.DecryptorV3(encryptionKey: encryptKey, hmacKey: hmacKey)
  78. do {
  79. let decrypted = try decryptor.decryptData(ciphertext)
  80. XCTAssertEqual(decrypted, plaintext)
  81. } catch {
  82. XCTFail("Caught: \(error)")
  83. }
  84. }
  85. func testPasswordEncryptor() {
  86. let password = "thepassword"
  87. let encryptionSalt = "0001020304050607".dataFromHexEncoding!
  88. let hmacSalt = "0102030405060708".dataFromHexEncoding!
  89. let iv = "02030405060708090a0b0c0d0e0f0001".dataFromHexEncoding!
  90. let plaintext = "01".dataFromHexEncoding!
  91. let ciphertext = "03010001 02030405 06070102 03040506 07080203 04050607 08090a0b 0c0d0e0f 0001a1f8 730e0bf4 80eb7b70 f690abf2 1e029514 164ad3c4 74a51b30 c7eaa1ca 545b7de3 de5b010a cbad0a9a 13857df6 96a8".dataFromHexEncoding!
  92. let encryptor = RNCryptor.EncryptorV3(password: password, encryptionSalt: encryptionSalt, hmacSalt: hmacSalt, iv: iv)
  93. let encrypted = encryptor.encryptData(plaintext)
  94. XCTAssertEqual(encrypted, ciphertext)
  95. }
  96. func testPasswordDecryptor() {
  97. let password = "thepassword"
  98. let plaintext = "01".dataFromHexEncoding!
  99. let ciphertext = "03010001 02030405 06070102 03040506 07080203 04050607 08090a0b 0c0d0e0f 0001a1f8 730e0bf4 80eb7b70 f690abf2 1e029514 164ad3c4 74a51b30 c7eaa1ca 545b7de3 de5b010a cbad0a9a 13857df6 96a8".dataFromHexEncoding!
  100. let decryptor = RNCryptor.Decryptor(password: password)
  101. do {
  102. let decrypted = try decryptor.decryptData(ciphertext)
  103. XCTAssertEqual(decrypted, plaintext)
  104. } catch {
  105. XCTFail("Caught: \(error)")
  106. }
  107. }
  108. func testOneShotKey() {
  109. let encryptionKey = RNCryptor.randomDataOfLength(V3.keySize)
  110. let hmacKey = RNCryptor.randomDataOfLength(V3.keySize)
  111. let data = RNCryptor.randomDataOfLength(1024)
  112. let ciphertext = RNCryptor.EncryptorV3(encryptionKey: encryptionKey, hmacKey: hmacKey).encryptData(data)
  113. let plaintext: NSData
  114. do {
  115. plaintext = try RNCryptor.DecryptorV3(encryptionKey: encryptionKey, hmacKey: hmacKey).decryptData(ciphertext)
  116. } catch {
  117. plaintext = NSData(bytes: [0xaa])
  118. XCTFail("Caught: \(error)")
  119. }
  120. XCTAssertEqual(plaintext, data)
  121. }
  122. func testOneShotPassword() {
  123. let password = "thepassword"
  124. let data = RNCryptor.randomDataOfLength(1024)
  125. let ciphertext = RNCryptor.Encryptor(password: password).encryptData(data)
  126. let plaintext: NSData
  127. do {
  128. plaintext = try RNCryptor.Decryptor(password: password).decryptData(ciphertext)
  129. } catch {
  130. plaintext = NSData(bytes: [0])
  131. XCTFail("Caught: \(error)")
  132. }
  133. XCTAssertEqual(plaintext, data)
  134. }
  135. func testMultipleUpdateWithData() {
  136. let password = "thepassword"
  137. let datas = (0..<10).map{ _ in RNCryptor.randomDataOfLength(1024) }
  138. let fullData = datas.reduce(NSMutableData()) { $0.appendData($1); return $0 }
  139. let encryptor = RNCryptor.Encryptor(password: password)
  140. let ciphertext = NSMutableData()
  141. for data in datas {
  142. ciphertext.appendData(encryptor.updateWithData(data))
  143. }
  144. ciphertext.appendData(encryptor.finalData())
  145. do {
  146. let decrypted = try RNCryptor.Decryptor(password: password).decryptData(ciphertext)
  147. XCTAssertEqual(fullData, decrypted)
  148. } catch {
  149. XCTFail("Caught: \(error)")
  150. }
  151. }
  152. func testBadFormat() {
  153. let data = NSMutableData(length: 1024)!
  154. do {
  155. try RNCryptor.Decryptor(password: "password").decryptData(data)
  156. XCTFail("Should not thrown")
  157. } catch let error as RNCryptorError {
  158. XCTAssertEqual(error, RNCryptorError.UnknownHeader)
  159. } catch {
  160. XCTFail("Threw wrong thing \(error)")
  161. }
  162. }
  163. func testBadFormatV3() {
  164. let data = NSMutableData(length: 1024)!
  165. do {
  166. try RNCryptor.DecryptorV3(password: "password").decryptData(data)
  167. XCTFail("Should not thrown")
  168. } catch let error as RNCryptorError {
  169. XCTAssertEqual(error, RNCryptorError.UnknownHeader)
  170. } catch {
  171. XCTFail("Threw wrong thing \(error)")
  172. }
  173. }
  174. }