TLSEvaluationTests.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. // TLSEvaluationTests.swift
  2. //
  3. // Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. import Alamofire
  23. import Foundation
  24. import XCTest
  25. private struct TestCertificates {
  26. static let RootCA = TestCertificates.certificateWithFileName("root-ca-disig")
  27. static let IntermediateCA = TestCertificates.certificateWithFileName("intermediate-ca-disig")
  28. static let Leaf = TestCertificates.certificateWithFileName("testssl-expire.disig.sk")
  29. static func certificateWithFileName(fileName: String) -> SecCertificate {
  30. class Bundle {}
  31. let filePath = NSBundle(forClass: Bundle.self).pathForResource(fileName, ofType: "cer")!
  32. let data = NSData(contentsOfFile: filePath)!
  33. let certificate = SecCertificateCreateWithData(nil, data)!
  34. return certificate
  35. }
  36. }
  37. // MARK: -
  38. private struct TestPublicKeys {
  39. static let RootCA = TestPublicKeys.publicKeyForCertificate(TestCertificates.RootCA)
  40. static let IntermediateCA = TestPublicKeys.publicKeyForCertificate(TestCertificates.IntermediateCA)
  41. static let Leaf = TestPublicKeys.publicKeyForCertificate(TestCertificates.Leaf)
  42. static func publicKeyForCertificate(certificate: SecCertificate) -> SecKey {
  43. let policy = SecPolicyCreateBasicX509()
  44. var trust: SecTrust?
  45. SecTrustCreateWithCertificates(certificate, policy, &trust)
  46. let publicKey = SecTrustCopyPublicKey(trust!)!
  47. return publicKey
  48. }
  49. }
  50. // MARK: -
  51. class TLSEvaluationExpiredLeafCertificateTestCase: BaseTestCase {
  52. let URL = "https://testssl-expire.disig.sk/"
  53. let host = "testssl-expire.disig.sk"
  54. var configuration: NSURLSessionConfiguration!
  55. // MARK: Setup and Teardown
  56. override func setUp() {
  57. super.setUp()
  58. configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
  59. }
  60. // MARK: Default Behavior Tests
  61. func testThatExpiredCertificateRequestFailsWithNoServerTrustPolicy() {
  62. // Given
  63. let expectation = expectationWithDescription("\(URL)")
  64. let manager = Manager(configuration: configuration)
  65. var error: NSError?
  66. // When
  67. manager.request(.GET, URL)
  68. .response { _, _, _, responseError in
  69. error = responseError
  70. expectation.fulfill()
  71. }
  72. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  73. // Then
  74. XCTAssertNotNil(error, "error should not be nil")
  75. XCTAssertEqual(error?.code ?? -1, NSURLErrorServerCertificateUntrusted, "error should be NSURLErrorServerCertificateUntrusted")
  76. }
  77. // MARK: Server Trust Policy - Perform Default Tests
  78. func testThatExpiredCertificateRequestFailsWithDefaultServerTrustPolicy() {
  79. // Given
  80. let policies = [host: ServerTrustPolicy.PerformDefaultEvaluation(validateHost: true)]
  81. let manager = Manager(
  82. configuration: configuration,
  83. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  84. )
  85. let expectation = expectationWithDescription("\(URL)")
  86. var error: NSError?
  87. // When
  88. manager.request(.GET, URL)
  89. .response { _, _, _, responseError in
  90. error = responseError
  91. expectation.fulfill()
  92. }
  93. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  94. // Then
  95. XCTAssertNotNil(error, "error should not be nil")
  96. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  97. }
  98. // MARK: Server Trust Policy - Certificate Pinning Tests
  99. func testThatExpiredCertificateRequestFailsWhenPinningLeafCertificateWithCertificateChainValidation() {
  100. // Given
  101. let certificates = [TestCertificates.Leaf]
  102. let policies: [String: ServerTrustPolicy] = [
  103. host: .PinCertificates(certificates: certificates, validateCertificateChain: true, validateHost: true)
  104. ]
  105. let manager = Manager(
  106. configuration: configuration,
  107. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  108. )
  109. let expectation = expectationWithDescription("\(URL)")
  110. var error: NSError?
  111. // When
  112. manager.request(.GET, URL)
  113. .response { _, _, _, responseError in
  114. error = responseError
  115. expectation.fulfill()
  116. }
  117. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  118. // Then
  119. XCTAssertNotNil(error, "error should not be nil")
  120. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  121. }
  122. func testThatExpiredCertificateRequestFailsWhenPinningAllCertificatesWithCertificateChainValidation() {
  123. // Given
  124. let certificates = [TestCertificates.Leaf, TestCertificates.IntermediateCA, TestCertificates.RootCA]
  125. let policies: [String: ServerTrustPolicy] = [
  126. host: .PinCertificates(certificates: certificates, validateCertificateChain: true, validateHost: true)
  127. ]
  128. let manager = Manager(
  129. configuration: configuration,
  130. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  131. )
  132. let expectation = expectationWithDescription("\(URL)")
  133. var error: NSError?
  134. // When
  135. manager.request(.GET, URL)
  136. .response { _, _, _, responseError in
  137. error = responseError
  138. expectation.fulfill()
  139. }
  140. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  141. // Then
  142. XCTAssertNotNil(error, "error should not be nil")
  143. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  144. }
  145. func testThatExpiredCertificateRequestSucceedsWhenPinningLeafCertificateWithoutCertificateChainValidation() {
  146. // Given
  147. let certificates = [TestCertificates.Leaf]
  148. let policies: [String: ServerTrustPolicy] = [
  149. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  150. ]
  151. let manager = Manager(
  152. configuration: configuration,
  153. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  154. )
  155. let expectation = expectationWithDescription("\(URL)")
  156. var error: NSError?
  157. // When
  158. manager.request(.GET, URL)
  159. .response { _, _, _, responseError in
  160. error = responseError
  161. expectation.fulfill()
  162. }
  163. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  164. // Then
  165. XCTAssertNil(error, "error should be nil")
  166. }
  167. func testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCACertificateWithoutCertificateChainValidation() {
  168. // Given
  169. let certificates = [TestCertificates.IntermediateCA]
  170. let policies: [String: ServerTrustPolicy] = [
  171. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  172. ]
  173. let manager = Manager(
  174. configuration: configuration,
  175. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  176. )
  177. let expectation = expectationWithDescription("\(URL)")
  178. var error: NSError?
  179. // When
  180. manager.request(.GET, URL)
  181. .response { _, _, _, responseError in
  182. error = responseError
  183. expectation.fulfill()
  184. }
  185. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  186. // Then
  187. XCTAssertNil(error, "error should be nil")
  188. }
  189. func testThatExpiredCertificateRequestSucceedsWhenPinningRootCACertificateWithoutCertificateChainValidation() {
  190. // Given
  191. let certificates = [TestCertificates.RootCA]
  192. let policies: [String: ServerTrustPolicy] = [
  193. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  194. ]
  195. let manager = Manager(
  196. configuration: configuration,
  197. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  198. )
  199. let expectation = expectationWithDescription("\(URL)")
  200. var error: NSError?
  201. // When
  202. manager.request(.GET, URL)
  203. .response { _, _, _, responseError in
  204. error = responseError
  205. expectation.fulfill()
  206. }
  207. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  208. // Then
  209. XCTAssertNil(error, "error should be nil")
  210. }
  211. // MARK: Server Trust Policy - Public Key Pinning Tests
  212. func testThatExpiredCertificateRequestFailsWhenPinningLeafPublicKeyWithCertificateChainValidation() {
  213. // Given
  214. let publicKeys = [TestPublicKeys.Leaf]
  215. let policies: [String: ServerTrustPolicy] = [
  216. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: true, validateHost: true)
  217. ]
  218. let manager = Manager(
  219. configuration: configuration,
  220. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  221. )
  222. let expectation = expectationWithDescription("\(URL)")
  223. var error: NSError?
  224. // When
  225. manager.request(.GET, URL)
  226. .response { _, _, _, responseError in
  227. error = responseError
  228. expectation.fulfill()
  229. }
  230. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  231. // Then
  232. XCTAssertNotNil(error, "error should not be nil")
  233. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  234. }
  235. func testThatExpiredCertificateRequestSucceedsWhenPinningLeafPublicKeyWithoutCertificateChainValidation() {
  236. // Given
  237. let publicKeys = [TestPublicKeys.Leaf]
  238. let policies: [String: ServerTrustPolicy] = [
  239. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  240. ]
  241. let manager = Manager(
  242. configuration: configuration,
  243. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  244. )
  245. let expectation = expectationWithDescription("\(URL)")
  246. var error: NSError?
  247. // When
  248. manager.request(.GET, URL)
  249. .response { _, _, _, responseError in
  250. error = responseError
  251. expectation.fulfill()
  252. }
  253. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  254. // Then
  255. XCTAssertNil(error, "error should be nil")
  256. }
  257. func testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCAPublicKeyWithoutCertificateChainValidation() {
  258. // Given
  259. let publicKeys = [TestPublicKeys.IntermediateCA]
  260. let policies: [String: ServerTrustPolicy] = [
  261. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  262. ]
  263. let manager = Manager(
  264. configuration: configuration,
  265. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  266. )
  267. let expectation = expectationWithDescription("\(URL)")
  268. var error: NSError?
  269. // When
  270. manager.request(.GET, URL)
  271. .response { _, _, _, responseError in
  272. error = responseError
  273. expectation.fulfill()
  274. }
  275. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  276. // Then
  277. XCTAssertNil(error, "error should be nil")
  278. }
  279. func testThatExpiredCertificateRequestSucceedsWhenPinningRootCAPublicKeyWithoutCertificateChainValidation() {
  280. // Given
  281. let publicKeys = [TestPublicKeys.RootCA]
  282. let policies: [String: ServerTrustPolicy] = [
  283. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  284. ]
  285. let manager = Manager(
  286. configuration: configuration,
  287. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  288. )
  289. let expectation = expectationWithDescription("\(URL)")
  290. var error: NSError?
  291. // When
  292. manager.request(.GET, URL)
  293. .response { _, _, _, responseError in
  294. error = responseError
  295. expectation.fulfill()
  296. }
  297. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  298. // Then
  299. XCTAssertNil(error, "error should be nil")
  300. }
  301. // MARK: Server Trust Policy - Disabling Evaluation Tests
  302. func testThatExpiredCertificateRequestSucceedsWhenDisablingEvaluation() {
  303. // Given
  304. let policies = [host: ServerTrustPolicy.DisableEvaluation]
  305. let manager = Manager(
  306. configuration: configuration,
  307. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  308. )
  309. let expectation = expectationWithDescription("\(URL)")
  310. var error: NSError?
  311. // When
  312. manager.request(.GET, URL)
  313. .response { _, _, _, responseError in
  314. error = responseError
  315. expectation.fulfill()
  316. }
  317. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  318. // Then
  319. XCTAssertNil(error, "error should be nil")
  320. }
  321. // MARK: Server Trust Policy - Custom Evaluation Tests
  322. func testThatExpiredCertificateRequestSucceedsWhenCustomEvaluationReturnsTrue() {
  323. // Given
  324. let policies = [
  325. host: ServerTrustPolicy.CustomEvaluation { _, _ in
  326. // Implement a custom evaluation routine here...
  327. return true
  328. }
  329. ]
  330. let manager = Manager(
  331. configuration: configuration,
  332. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  333. )
  334. let expectation = expectationWithDescription("\(URL)")
  335. var error: NSError?
  336. // When
  337. manager.request(.GET, URL)
  338. .response { _, _, _, responseError in
  339. error = responseError
  340. expectation.fulfill()
  341. }
  342. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  343. // Then
  344. XCTAssertNil(error, "error should be nil")
  345. }
  346. func testThatExpiredCertificateRequestFailsWhenCustomEvaluationReturnsFalse() {
  347. // Given
  348. let policies = [
  349. host: ServerTrustPolicy.CustomEvaluation { _, _ in
  350. // Implement a custom evaluation routine here...
  351. return false
  352. }
  353. ]
  354. let manager = Manager(
  355. configuration: configuration,
  356. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  357. )
  358. let expectation = expectationWithDescription("\(URL)")
  359. var error: NSError?
  360. // When
  361. manager.request(.GET, URL)
  362. .response { _, _, _, responseError in
  363. error = responseError
  364. expectation.fulfill()
  365. }
  366. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  367. // Then
  368. XCTAssertNotNil(error, "error should not be nil")
  369. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  370. }
  371. }