RSASecKeyTests.swift 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. #if canImport(Security)
  16. import Security
  17. import XCTest
  18. @testable import CryptoSwift
  19. final class RSASecKeyTests: XCTestCase {
  20. // MARK: SecKey <-> RSA Interoperability
  21. /// From RSA -> External Representation -> SecKey
  22. func testRSAExternalRepresentationPrivate() throws {
  23. /// Generate a CryptoSwift RSA Key
  24. let rsaCryptoSwift = try RSA(keySize: 1024)
  25. /// Get the key's rawExternalRepresentation
  26. let rsaCryptoSwiftRawRep = try rsaCryptoSwift.privateKeyDER()
  27. /// We should be able to instantiate an RSA SecKey from this data
  28. let attributes: [String: Any] = [
  29. kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  30. kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
  31. kSecAttrKeySizeInBits as String: 1024,
  32. kSecAttrIsPermanent as String: false
  33. ]
  34. var error: Unmanaged<CFError>?
  35. guard let rsaSecKey = SecKeyCreateWithData(Data(rsaCryptoSwiftRawRep) as CFData, attributes as CFDictionary, &error) else {
  36. XCTFail("Error constructing SecKey from raw key data: \(error.debugDescription)")
  37. return
  38. }
  39. /// Get the SecKey's external representation
  40. var externalRepError: Unmanaged<CFError>?
  41. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  42. XCTFail("Failed to copy external representation for RSA SecKey")
  43. return
  44. }
  45. // Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
  46. XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
  47. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  48. }
  49. /// From RSA -> External Representation -> SecKey
  50. func testRSAExternalRepresentationPublic() throws {
  51. /// Generate a CryptoSwift RSA Key
  52. let rsaCryptoSwift = try RSA(keySize: 1024)
  53. /// Get the key's rawExternalRepresentation
  54. let rsaCryptoSwiftRawRep = try rsaCryptoSwift.publicKeyDER()
  55. /// We should be able to instantiate an RSA SecKey from this data
  56. let attributes: [String: Any] = [
  57. kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
  58. kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
  59. kSecAttrKeySizeInBits as String: 1024,
  60. kSecAttrIsPermanent as String: false
  61. ]
  62. var error: Unmanaged<CFError>?
  63. guard let rsaSecKey = SecKeyCreateWithData(Data(rsaCryptoSwiftRawRep) as CFData, attributes as CFDictionary, &error) else {
  64. XCTFail("Error constructing SecKey from raw key data: \(error.debugDescription)")
  65. return
  66. }
  67. /// Get the SecKey's external representation
  68. var externalRepError: Unmanaged<CFError>?
  69. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  70. XCTFail("Failed to copy external representation for RSA SecKey")
  71. return
  72. }
  73. // Ensure both the CryptoSwift Ext Rep and the SecKey Ext Rep match
  74. XCTAssertEqual(rsaSecKeyRawRep, Data(rsaCryptoSwiftRawRep))
  75. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.publicKeyExternalRepresentation())
  76. }
  77. /// SecKey -> External Representation -> CryptoSwift RSA
  78. func testSecKeyExternalRepresentationPrivate() throws {
  79. /// Generate a SecKey RSA Key
  80. let parameters: [CFString: Any] = [
  81. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  82. kSecAttrKeySizeInBits: 1024
  83. ]
  84. var error: Unmanaged<CFError>?
  85. // Generate the RSA SecKey
  86. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  87. XCTFail("Key Generation Error: \(error.debugDescription)")
  88. return
  89. }
  90. /// Lets grab the external representation
  91. var externalRepError: Unmanaged<CFError>?
  92. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKey, &externalRepError) as? Data else {
  93. XCTFail("Failed to copy external representation for RSA SecKey")
  94. return
  95. }
  96. // Ensure we can import the private RSA key into CryptoSwift
  97. let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
  98. XCTAssertNotNil(rsaCryptoSwift.d)
  99. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  100. }
  101. /// SecKey -> External Representation -> CryptoSwift RSA
  102. func testSecKeyExternalRepresentationPublic() throws {
  103. /// Generate a SecKey RSA Key
  104. let parameters: [CFString: Any] = [
  105. kSecAttrKeyType: kSecAttrKeyTypeRSA,
  106. kSecAttrKeySizeInBits: 1024
  107. ]
  108. var error: Unmanaged<CFError>?
  109. // Generate the RSA SecKey
  110. guard let rsaSecKey = SecKeyCreateRandomKey(parameters as CFDictionary, &error) else {
  111. XCTFail("Key Generation Error: \(error.debugDescription)")
  112. return
  113. }
  114. // Extract the public key from the private RSA SecKey
  115. guard let rsaSecKeyPublic = SecKeyCopyPublicKey(rsaSecKey) else {
  116. XCTFail("Public Key Extraction Error")
  117. return
  118. }
  119. /// Lets grab the external representation of the public key
  120. var externalRepError: Unmanaged<CFError>?
  121. guard let rsaSecKeyRawRep = SecKeyCopyExternalRepresentation(rsaSecKeyPublic, &externalRepError) as? Data else {
  122. XCTFail("Failed to copy external representation for RSA SecKey")
  123. return
  124. }
  125. // Ensure we can import the private RSA key into CryptoSwift
  126. let rsaCryptoSwift = try RSA(rawRepresentation: rsaSecKeyRawRep)
  127. XCTAssertNil(rsaCryptoSwift.d)
  128. XCTAssertEqual(rsaSecKeyRawRep, try rsaCryptoSwift.externalRepresentation())
  129. }
  130. }
  131. extension RSASecKeyTests {
  132. static func allTests() -> [(String, (RSASecKeyTests) -> () throws -> Void)] {
  133. let tests = [
  134. ("testRSAExternalRepresentationPrivate", testRSAExternalRepresentationPrivate),
  135. ("testRSAExternalRepresentationPublic", testRSAExternalRepresentationPublic),
  136. ("testSecKeyExternalRepresentationPrivate", testSecKeyExternalRepresentationPrivate),
  137. ("testSecKeyExternalRepresentationPublic", testSecKeyExternalRepresentationPublic)
  138. ]
  139. return tests
  140. }
  141. }
  142. #endif