ASN1Tests.swift 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. //
  2. // CryptoSwift
  3. //
  4. // Copyright (C) 2014-2021 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
  5. // This software is provided 'as-is', without any express or implied warranty.
  6. //
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  10. //
  11. // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
  12. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  13. // - This notice may not be removed or altered from any source or binary distribution.
  14. //
  15. import XCTest
  16. @testable import CryptoSwift
  17. final class ASN1Tests: XCTestCase {
  18. /// This test ensures that we get the same data out as we put in before and after encoding
  19. ///
  20. /// This test enforces that
  21. /// 1) The data provided to each of the `ASN1.Node`s is preserved across encoding and decoding.
  22. func testASN1NonDestructiveEncoding() throws {
  23. let arbitraryData = Data(hex: "0123456789")
  24. // Encode the serialized BigInteger
  25. let node: ASN1.Node = .sequence(nodes: [
  26. .integer(data: arbitraryData),
  27. .bitString(data: arbitraryData),
  28. .octetString(data: arbitraryData),
  29. .null,
  30. .objectIdentifier(data: arbitraryData)
  31. ])
  32. let encoded = ASN1.Encoder.encode(node)
  33. // Decode the Encoding
  34. let decoded = try ASN1.Decoder.decode(data: Data(encoded))
  35. guard case .sequence(let sequence) = decoded else {
  36. XCTFail("Failed to recover encoded SEQUENCE")
  37. return
  38. }
  39. XCTAssertEqual(sequence.count, 5)
  40. guard case .integer(let integerData) = sequence[0] else {
  41. XCTFail("Failed to recover encoded INTEGER")
  42. return
  43. }
  44. XCTAssertEqual(integerData, arbitraryData)
  45. guard case .bitString(let bitStringData) = sequence[1] else {
  46. XCTFail("Failed to recover encoded BITSTRING")
  47. return
  48. }
  49. XCTAssertEqual(bitStringData, arbitraryData)
  50. guard case .octetString(let octetData) = sequence[2] else {
  51. XCTFail("Failed to recover encoded OCTETSTRING")
  52. return
  53. }
  54. XCTAssertEqual(octetData, arbitraryData)
  55. guard case .null = sequence[3] else {
  56. XCTFail("Failed to recover encoded NULL")
  57. return
  58. }
  59. guard case .objectIdentifier(let objIDData) = sequence[4] else {
  60. XCTFail("Failed to recover encoded OBJECTIDENTIFIER")
  61. return
  62. }
  63. XCTAssertEqual(objIDData, arbitraryData)
  64. }
  65. /// The ASN1 Encoder / Decoder doesn't handle encoding / decoding Integers directly, it's your responsibility to accurately serialize your integers.
  66. /// - Note: In this example we're using BigInteger's serialization technique to encode / decode Integers, which isn't the default method for handling integers. https://www.strozhevsky.com/free_docs/asn1_by_simple_words.pdf
  67. ///
  68. /// This test enforces that
  69. /// 1) The data provided to the `ASN1.Node.integer` Node is preserved across encoding and decoding.
  70. func testASN1DecodePrimitiveInteger() throws {
  71. let tests = [
  72. 0,
  73. -0,
  74. 128,
  75. -128,
  76. 136,
  77. -136,
  78. 8388607,
  79. -8388607,
  80. 3409934108352718734,
  81. -3409934108352718734
  82. ]
  83. for test in tests {
  84. let number = BigInteger(test)
  85. // Encode the serialized Integer
  86. let encoded = ASN1.Encoder.encode(.integer(data: number.serialize()))
  87. // Ensure the Integer Prefix was added
  88. XCTAssertEqual(Array<UInt8>(arrayLiteral: 0x02), Array(encoded.prefix(1)))
  89. // Decode the Encoding
  90. let decoded = try ASN1.Decoder.decode(data: Data(encoded))
  91. guard case .integer(let num) = decoded else {
  92. XCTFail("Failed to recover encoded integer")
  93. return
  94. }
  95. // Ensure the original BigInteger was recovered
  96. XCTAssertEqual(BigInteger(num), number)
  97. }
  98. }
  99. /// Another test showing that Integers are stored as arbitrary data and the proper serialization and signage are the responsibilities of the user and their application.
  100. ///
  101. /// This test enforces that
  102. /// 1) The data provided to the `ASN1.Node.integer` Node is preserved across encoding and decoding.
  103. func testASN1DecodeLargeBigInteger() throws {
  104. // Because INTEGERS are stored as arbitrary data we should be able to store an integer that would otherwise overflow by using the BigInteger library
  105. let largeBigInt = BigInteger("1541235134652345698374107823450134507610354876134950342785028743653")
  106. // Encode the serialized BigInteger
  107. let encoded = ASN1.Encoder.encode(.integer(data: largeBigInt.serialize()))
  108. // Decode the Encoding
  109. let decoded = try ASN1.Decoder.decode(data: Data(encoded))
  110. guard case .integer(let num) = decoded else {
  111. XCTFail("Failed to recover encoded integer")
  112. return
  113. }
  114. // Ensure the original BigInteger was recovered
  115. XCTAssertEqual(BigInteger(num), largeBigInt)
  116. }
  117. /// This tests decodes an RSA Public Key from a Base64 DER Encoded representation
  118. ///
  119. /// This test enforces that
  120. /// 1) The decoding process yeilds the expected format.
  121. /// 2) The re-encoding of the data yeilds the exact same starting data.
  122. func testANS1DERDecodingPublicKey() throws {
  123. /// An example of an RSA Public Key ASN1 DER Encoding
  124. ///
  125. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1)
  126. /// ```
  127. /// =========================
  128. /// RSA PublicKey Structure
  129. /// =========================
  130. ///
  131. /// RSAPublicKey ::= SEQUENCE {
  132. /// modulus INTEGER, -- n
  133. /// publicExponent INTEGER, -- e
  134. /// }
  135. /// ```
  136. let publicDER = """
  137. MIGJAoGBAMGeZvIG84vyKAATwKkKz2g+PeNaZ63rxk/zEnLGxkMCVKnUZ6jPAtzYOKM24949yIhfxYBC/bOCPwRK4wbr4YyIx3WB2v+Zcqe8pRM/BThUpNIx3K2+jbJBhAopf1GXJ3i31RuiLMh9HWhxzkVamz1KnDjCuTZguCRRHIv+r3XTAgMBAAE=
  138. """
  139. guard let publicDERData = Data(base64Encoded: publicDER) else {
  140. XCTFail("Failed to convert base64 string into data for decoding.")
  141. return
  142. }
  143. let decoded = try ASN1.Decoder.decode(data: publicDERData)
  144. // Ensure the first node is of type Sequence
  145. guard case .sequence(let nodes) = decoded else {
  146. XCTFail("Expected the top level node to be a sequence and it wasn't")
  147. return
  148. }
  149. // Ensure there are two nodes within the top level sequence (our integers, n and e)
  150. XCTAssertEqual(nodes.count, 2)
  151. // Ensure that the first node within our sequence is of type Integer
  152. guard case .integer(let n) = nodes[0] else {
  153. XCTFail("Expected an integer within our sequence and it wasn't")
  154. return
  155. }
  156. // Ensure the second node within our sequence is of type Integer
  157. guard case .integer(let e) = nodes[1] else {
  158. XCTFail("Expected an integer within our sequence and it wasn't")
  159. return
  160. }
  161. // Ensure that n contains the data we expected
  162. XCTAssertEqual(n.toHexString(), "00c19e66f206f38bf2280013c0a90acf683e3de35a67adebc64ff31272c6c6430254a9d467a8cf02dcd838a336e3de3dc8885fc58042fdb3823f044ae306ebe18c88c77581daff9972a7bca5133f053854a4d231dcadbe8db241840a297f51972778b7d51ba22cc87d1d6871ce455a9b3d4a9c38c2b93660b824511c8bfeaf75d3")
  163. // Ensure that e contains the data we expected
  164. XCTAssertEqual(e.toHexString(), "010001") // 65537
  165. // Re Encode the data
  166. let asn1: ASN1.Node = .sequence(nodes: [
  167. .integer(data: n),
  168. .integer(data: e)
  169. ])
  170. let encoded = ASN1.Encoder.encode(asn1)
  171. // Ensure the re-encoded data matches the original exactly
  172. XCTAssertEqual(Data(encoded), publicDERData)
  173. XCTAssertEqual(encoded, publicDERData.bytes)
  174. XCTAssertEqual(encoded.toBase64(), publicDER)
  175. }
  176. /// This tests decodes an RSA Private Key from a Base64 DER Encoded representation
  177. ///
  178. /// This test enforces that
  179. /// 1) The decoding process yeilds the expected format.
  180. /// 2) The re-encoding of the data yeilds the exact same starting data.
  181. func testANS1DERDecodingPrivateKey() throws {
  182. /// An example of an RSA Private Key ASN1 DER Encoding
  183. ///
  184. /// [IETF Spec RFC2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.2)
  185. /// ```
  186. /// ==========================
  187. /// RSA PrivateKey Structure
  188. /// ==========================
  189. ///
  190. /// RSAPrivateKey ::= SEQUENCE {
  191. /// version Version,
  192. /// modulus INTEGER, -- n
  193. /// publicExponent INTEGER, -- e
  194. /// privateExponent INTEGER, -- d
  195. /// prime1 INTEGER, -- p
  196. /// prime2 INTEGER, -- q
  197. /// exponent1 INTEGER, -- d mod (p-1)
  198. /// exponent2 INTEGER, -- d mod (q-1)
  199. /// coefficient INTEGER, -- (inverse of q) mod p
  200. /// otherPrimeInfos OtherPrimeInfos OPTIONAL
  201. /// }
  202. /// ```
  203. let privateDER = """
  204. MIICXQIBAAKBgQDBnmbyBvOL8igAE8CpCs9oPj3jWmet68ZP8xJyxsZDAlSp1GeozwLc2DijNuPePciIX8WAQv2zgj8ESuMG6+GMiMd1gdr/mXKnvKUTPwU4VKTSMdytvo2yQYQKKX9Rlyd4t9UboizIfR1occ5FWps9Spw4wrk2YLgkURyL/q910wIDAQABAoGAGJkNLxZe/pqHJmtcAJ3U98NgjW/A2EGp8iJJZ7eFHKJBK0pG2RVjobb+iw3AKU3kGh9AsijQnmufoeX5rblt7/ojgpfVhS7NHsKCi8Nx7U92bNnP0RP4mogpvzGWVknUdv6jW7dX83FKgEywbNKa5CPQk1XinqXL33gNjWdOh/ECQQDjdE4kNdVwKA59ddWRShvJiOMOG8+TjE5HvcZzKQ+UMlBwbknL5tIJE7KnN9ZEfNihVmyrMAzJAfe2PCyZAip/AkEA2esFkG+ScgeVYlGrUqrqUkvzj1j6F8R+8rGvCjq2WnDL8TzO7NoT7qivW/+6E9osX1WwWAtj/84eN7dvLLxCrQJBAN7GomZq58MzKIYPLH9iI3cwAJtn99ZfHKi9oipW9DBFW23TR6pTSDKlvVx0nwNzeEYFPOgqZstVhwZRR6kRawcCQHx/u0QTmjUvg/cR9bFbGFhAMDxbdzaQ+n4paXmMpZXyD3IZbZb/2JdnJBiJd4PUB7nHuOH0UANbfQQT9p42SFkCQQCcdFRTZEZv5TjmcUn0GBUzRmnswiRc1YEg81DSDlvD3dEIVSl6PLkzcNNItrgD5SfC5MxCv6PIUlJVhnkavEjS
  205. """
  206. guard let privateDERData = Data(base64Encoded: privateDER) else {
  207. XCTFail("Failed to convert base64 string into data for decoding.")
  208. return
  209. }
  210. let decoded = try ASN1.Decoder.decode(data: privateDERData)
  211. // Ensure the first Node is of type SEQUENCE
  212. guard case .sequence(let nodes) = decoded else {
  213. XCTFail("Expected the top level node to be a sequence and it wasn't")
  214. return
  215. }
  216. // Ensure there are nine (9) Nodes within the top level SEQUENCE
  217. XCTAssertEqual(nodes.count, 9)
  218. // Deconstruct the parameters
  219. guard case .integer(let version) = nodes[0] else {
  220. XCTFail("Expected an integer within our sequence and it wasn't")
  221. return
  222. }
  223. XCTAssertEqual(version, Data(hex: "00"))
  224. guard case .integer(let n) = nodes[1] else {
  225. XCTFail("Expected an integer within our sequence and it wasn't")
  226. return
  227. }
  228. XCTAssertEqual(n, Data(hex: "00c19e66f206f38bf2280013c0a90acf683e3de35a67adebc64ff31272c6c6430254a9d467a8cf02dcd838a336e3de3dc8885fc58042fdb3823f044ae306ebe18c88c77581daff9972a7bca5133f053854a4d231dcadbe8db241840a297f51972778b7d51ba22cc87d1d6871ce455a9b3d4a9c38c2b93660b824511c8bfeaf75d3"))
  229. guard case .integer(let e) = nodes[2] else {
  230. XCTFail("Expected an integer within our sequence and it wasn't")
  231. return
  232. }
  233. XCTAssertEqual(e, Data(hex: "010001"))
  234. guard case .integer(let d) = nodes[3] else {
  235. XCTFail("Expected an integer within our sequence and it wasn't")
  236. return
  237. }
  238. XCTAssertEqual(d, Data(hex: "18990d2f165efe9a87266b5c009dd4f7c3608d6fc0d841a9f2224967b7851ca2412b4a46d91563a1b6fe8b0dc0294de41a1f40b228d09e6b9fa1e5f9adb96deffa238297d5852ecd1ec2828bc371ed4f766cd9cfd113f89a8829bf31965649d476fea35bb757f3714a804cb06cd29ae423d09355e29ea5cbdf780d8d674e87f1"))
  239. guard case .integer(let p) = nodes[4] else {
  240. XCTFail("Expected an integer within our sequence and it wasn't")
  241. return
  242. }
  243. XCTAssertEqual(p, Data(hex: "00e3744e2435d570280e7d75d5914a1bc988e30e1bcf938c4e47bdc673290f943250706e49cbe6d20913b2a737d6447cd8a1566cab300cc901f7b63c2c99022a7f"))
  244. guard case .integer(let q) = nodes[5] else {
  245. XCTFail("Expected an integer within our sequence and it wasn't")
  246. return
  247. }
  248. XCTAssertEqual(q, Data(hex: "00d9eb05906f927207956251ab52aaea524bf38f58fa17c47ef2b1af0a3ab65a70cbf13cceecda13eea8af5bffba13da2c5f55b0580b63ffce1e37b76f2cbc42ad"))
  249. guard case .integer(let exp1) = nodes[6] else {
  250. XCTFail("Expected an integer within our sequence and it wasn't")
  251. return
  252. }
  253. XCTAssertEqual(exp1, Data(hex: "00dec6a2666ae7c33328860f2c7f62237730009b67f7d65f1ca8bda22a56f430455b6dd347aa534832a5bd5c749f03737846053ce82a66cb5587065147a9116b07"))
  254. guard case .integer(let exp2) = nodes[7] else {
  255. XCTFail("Expected an integer within our sequence and it wasn't")
  256. return
  257. }
  258. XCTAssertEqual(exp2, Data(hex: "7c7fbb44139a352f83f711f5b15b185840303c5b773690fa7e2969798ca595f20f72196d96ffd897672418897783d407b9c7b8e1f450035b7d0413f69e364859"))
  259. guard case .integer(let coefficient) = nodes[8] else {
  260. XCTFail("Expected an integer within our sequence and it wasn't")
  261. return
  262. }
  263. XCTAssertEqual(coefficient, Data(hex: "009c74545364466fe538e67149f41815334669ecc2245cd58120f350d20e5bc3ddd10855297a3cb93370d348b6b803e527c2e4cc42bfa3c852525586791abc48d2"))
  264. // Ensure re-encoding the data yeilds the exact same starting data
  265. let asn: ASN1.Node = .sequence(nodes: [
  266. .integer(data: version),
  267. .integer(data: n),
  268. .integer(data: e),
  269. .integer(data: d),
  270. .integer(data: p),
  271. .integer(data: q),
  272. .integer(data: exp1),
  273. .integer(data: exp2),
  274. .integer(data: coefficient)
  275. ])
  276. // Encode the ASN1 Nodes
  277. let encodedData = ASN1.Encoder.encode(asn)
  278. // Ensure the re-encoded data matches the original data exactly
  279. XCTAssertEqual(Data(encodedData), privateDERData)
  280. XCTAssertEqual(encodedData, privateDERData.bytes)
  281. XCTAssertEqual(encodedData.toBase64(), privateDER.replacingOccurrences(of: "\n", with: ""))
  282. }
  283. /// This tests decodes an Encrypted RSA Private Key from a Base64 PEM Encoded representation
  284. ///
  285. /// This test enforces that
  286. /// 1) The decoding process yeilds the expected format.
  287. /// 2) The re-encoding of the data yeilds the exact same starting data.
  288. func testASN1DecodingEncryptedPEM() throws {
  289. /// ==========================
  290. /// Encrypted PEM Structure
  291. /// ==========================
  292. ///
  293. /// EncryptedPrivateKey ::= SEQUENCE {
  294. ///
  295. /// PEMStructure ::= SEQUENCE {
  296. /// pemObjID OBJECTIDENTIFIER
  297. ///
  298. /// EncryptionAlgorithms ::= SEQUENCE {
  299. ///
  300. /// PBKDFAlgorithms ::= SEQUENCE {
  301. /// pbkdfObjID OBJECTIDENTIFIER
  302. /// PBKDFParams ::= SEQUENCE {
  303. /// salt OCTETSTRING,
  304. /// iterations INTEGER
  305. /// }
  306. /// },
  307. ///
  308. /// CIPHERAlgorithms ::= SEQUENCE {
  309. /// cipherObjID OBJECTIDENTIFIER,
  310. /// iv OCTETSTRING
  311. /// }
  312. /// }
  313. /// }
  314. /// encryptedData OCTETSTRING
  315. /// }
  316. ///
  317. /// /*
  318. /// * Generated with
  319. /// * openssl genpkey -algorithm RSA
  320. /// * -pkeyopt rsa_keygen_bits:1024
  321. /// * -pkeyopt rsa_keygen_pubexp:65537
  322. /// * -out foo.pem
  323. /// * openssl pkcs8 -in foo.pem -topk8 -v2 aes-128-cbc -passout pass:mypassword
  324. /// */
  325. let encryptedPEMFormat = """
  326. MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIP5QK2RfqUl4CAggA
  327. MB0GCWCGSAFlAwQBAgQQj3OyM9gnW2dd/eRHkxjGrgSCAoCpM5GZB0v27cxzZsGc
  328. O4/xqgwB0c/bSJ6QogtYU2KVoc7ZNQ5q9jtzn3I4ONvneOkpm9arzYz0FWnJi2C3
  329. BPiF0D1NkfvjvMLv56bwiG2A1oBECacyAb2pXYeJY7SdtYKvcbgs3jx65uCm6TF2
  330. BylteH+n1ewTQN9DLfASp1n81Ajq9lQGaK03SN2MUtcAPp7N9gnxJrlmDGeqlPRs
  331. KpQYRcot+kE6Ew8a5jAr7mAxwpqvr3SM4dMvADZmRQsM4Uc/9+YMUdI52DG87EWc
  332. 0OUB+fnQ8jw4DZgOE9KKM5/QTWc3aEw/dzXr/YJsrv01oLazhqVHnEMG0Nfr0+DP
  333. q+qac1AsCsOb71VxaRlRZcVEkEfAq3gidSPD93qmlDrCnmLYTilcLanXUepda7ez
  334. qhjkHtpwBLN5xRZxOn3oUuLGjk8VRwfmFX+RIMYCyihjdmbEDYpNUVkQVYFGi/F/
  335. 1hxOyl9yhGdL0hb9pKHH10GGIgoqo4jSTLlb4ennihGMHCjehAjLdx/GKJkOWShy
  336. V9hj8rAuYnRNb+tUW7ChXm1nLq14x9x1tX0ciVVn3ap/NoMkbFTr8M3pJ4bQlpAn
  337. wCT2erYqwQtgSpOJcrFeph9TjIrNRVE7Zlmr7vayJrB/8/oPssVdhf82TXkna4fB
  338. PcmO0YWLa117rfdeNM/Duy0ThSdTl39Qd+4FxqRZiHjbt+l0iSa/nOjTv1TZ/QqF
  339. wqrO6EtcM45fbFJ1Y79o2ptC2D6MB4HKJq9WCt064/8zQCVx3XPbb3X8Z5o/6koy
  340. ePGbz+UtSb9xczvqpRCOiFLh2MG1dUgWuHazjOtUcVWvilKnkjCMzZ9s1qG0sUDj
  341. nPyn
  342. """
  343. guard let pemData = Data(base64Encoded: encryptedPEMFormat.replacingOccurrences(of: "\n", with: "")) else {
  344. XCTFail("Failed to convert base64 string to data")
  345. return
  346. }
  347. let asn = try ASN1.Decoder.decode(data: pemData)
  348. // Ensure the first node is a Sequence
  349. guard case .sequence(let encryptedPEMWrapper) = asn else {
  350. XCTFail("Expected top level Node to be a SEQUENCE object")
  351. return
  352. }
  353. // Ensure the first Sequence contains exactly 2 nodes (another Sequence and our OctetString of encrypted data)
  354. XCTAssertEqual(encryptedPEMWrapper.count, 2)
  355. // Ensure the first node within the top level sequence is another sequence
  356. guard case .sequence(let encryptionInfoWrapper) = encryptedPEMWrapper[0] else {
  357. XCTFail("Expected the first Node within our top level SEQUENCE to be a SEQUENCE object and it wasn't")
  358. return
  359. }
  360. // Ensure this sequence contains exactly two nodes (the PEMs ObjectIdentifier and another sequence that houses the encryption algorithms)
  361. XCTAssertEqual(encryptionInfoWrapper.count, 2)
  362. // Ensure the first Node is the PEM's OBJECTIDENTIFIER Node
  363. guard case .objectIdentifier(let pemObjID) = encryptionInfoWrapper[0] else {
  364. XCTFail("Expected an OBJECTIDENTIFIER and it wasn't")
  365. return
  366. }
  367. // Ensure the second Node is another SEQUENCE Node
  368. guard case .sequence(let encryptionAlgorithmsWrapper) = encryptionInfoWrapper[1] else {
  369. XCTFail("Expected another SEQUENCE Node and it wasn't")
  370. return
  371. }
  372. // Ensure this sequence contains exactly two nodes (the PEMs ObjectIdentifier and another sequence that houses the encryption algorithms)
  373. XCTAssertEqual(encryptionAlgorithmsWrapper.count, 2)
  374. // Ensure the first Node is another SEQUENCE Node
  375. guard case .sequence(let pbkdfAlgorithmWrapper) = encryptionAlgorithmsWrapper[0] else {
  376. XCTFail("Expected another SEQUENCE Node and it wasn't")
  377. return
  378. }
  379. // Ensure this sequence contains exactly two nodes (the PBKDF ObjectIdentifier and another sequence that houses the PBKDF params)
  380. XCTAssertEqual(pbkdfAlgorithmWrapper.count, 2)
  381. guard case .objectIdentifier(let pbkdfObjID) = pbkdfAlgorithmWrapper[0] else {
  382. XCTFail("Expected an OBJECTIDENTIFIER and it wasn't")
  383. return
  384. }
  385. guard case .sequence(let pbkdfParamsWrapper) = pbkdfAlgorithmWrapper[1] else {
  386. XCTFail("Expected an OCTETSTRING and it wasn't")
  387. return
  388. }
  389. // Ensure this sequence contains exactly two nodes (the PBKDF Salt as an OCTETSTRING and the PBKDF Iterations as an INTEGER)
  390. XCTAssertEqual(pbkdfParamsWrapper.count, 2)
  391. guard case .octetString(let pbkdfSalt) = pbkdfParamsWrapper[0] else {
  392. XCTFail("Expected an OCTETSTRING and it wasn't")
  393. return
  394. }
  395. guard case .integer(let pbkdfIterations) = pbkdfParamsWrapper[1] else {
  396. XCTFail("Expected an INTEGER and it wasn't")
  397. return
  398. }
  399. // Ensure the second Node is another SEQUENCE Node
  400. guard case .sequence(let cipherAlgorithmWrapper) = encryptionAlgorithmsWrapper[1] else {
  401. XCTFail("Expected another SEQUENCE Node and it wasn't")
  402. return
  403. }
  404. // Ensure this sequence contains exactly two nodes (the CIPHER ObjectIdentifier and an OCTETSTRING that contains the CIPHERs InitialVector)
  405. XCTAssertEqual(cipherAlgorithmWrapper.count, 2)
  406. guard case .objectIdentifier(let cipherObjID) = cipherAlgorithmWrapper[0] else {
  407. XCTFail("Expected an OBJECTIDENTIFIER and it wasn't")
  408. return
  409. }
  410. guard case .octetString(let cipherInitialVector) = cipherAlgorithmWrapper[1] else {
  411. XCTFail("Expected an OCTETSTRING and it wasn't")
  412. return
  413. }
  414. // Ensure the last (2nd) Node in the top level SEQUENCE Node is an OCTETSTRING that contains the encrypted key data
  415. guard case .octetString(let encryptedData) = encryptedPEMWrapper[1] else {
  416. XCTFail("Expected the last Node in the first SEQUENCE Node to be an OCTETSTRING and it wasn't")
  417. return
  418. }
  419. // Now lets ensure we can re encode the object and get back the exact same data
  420. let nodes: ASN1.Node = .sequence(nodes: [
  421. .sequence(nodes: [
  422. .objectIdentifier(data: pemObjID),
  423. .sequence(nodes: [
  424. .sequence(nodes: [
  425. .objectIdentifier(data: pbkdfObjID),
  426. .sequence(nodes: [
  427. .octetString(data: pbkdfSalt),
  428. .integer(data: pbkdfIterations)
  429. ])
  430. ]),
  431. .sequence(nodes: [
  432. .objectIdentifier(data: cipherObjID),
  433. .octetString(data: cipherInitialVector)
  434. ])
  435. ])
  436. ]),
  437. .octetString(data: encryptedData)
  438. ])
  439. // Encode the ASN1 Nodes
  440. let encodedData = ASN1.Encoder.encode(nodes)
  441. // Ensure the re-encoded data matches the original data exactly
  442. XCTAssertEqual(Data(encodedData), pemData)
  443. XCTAssertEqual(encodedData, pemData.bytes)
  444. XCTAssertEqual(encodedData.toBase64(), encryptedPEMFormat.replacingOccurrences(of: "\n", with: ""))
  445. }
  446. static let allTests = [
  447. ("testASN1NonDestructiveEncoding", testASN1NonDestructiveEncoding),
  448. ("testASN1DecodePrimitiveInteger", testASN1DecodePrimitiveInteger),
  449. ("testASN1DecodeLargeBigInteger", testASN1DecodeLargeBigInteger),
  450. ("testANS1DERDecodingPublicKey", testANS1DERDecodingPublicKey),
  451. ("testANS1DERDecodingPrivateKey", testANS1DERDecodingPrivateKey),
  452. ("testASN1DecodingEncryptedPEM", testASN1DecodingEncryptedPEM)
  453. ]
  454. }