TLSEvaluationTests.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  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(
  76. error?.code ?? -1,
  77. NSURLErrorServerCertificateUntrusted,
  78. "error should be NSURLErrorServerCertificateUntrusted"
  79. )
  80. }
  81. // MARK: Server Trust Policy - Perform Default Tests
  82. func testThatExpiredCertificateRequestFailsWithDefaultServerTrustPolicy() {
  83. // Given
  84. let policies = [host: ServerTrustPolicy.PerformDefaultEvaluation(validateHost: true)]
  85. let manager = Manager(
  86. configuration: configuration,
  87. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  88. )
  89. let expectation = expectationWithDescription("\(URL)")
  90. var error: NSError?
  91. // When
  92. manager.request(.GET, URL)
  93. .response { _, _, _, responseError in
  94. error = responseError
  95. expectation.fulfill()
  96. }
  97. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  98. // Then
  99. XCTAssertNotNil(error, "error should not be nil")
  100. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  101. }
  102. // MARK: Server Trust Policy - Certificate Pinning Tests
  103. func testThatExpiredCertificateRequestFailsWhenPinningLeafCertificateWithCertificateChainValidation() {
  104. // Given
  105. let certificates = [TestCertificates.Leaf]
  106. let policies: [String: ServerTrustPolicy] = [
  107. host: .PinCertificates(certificates: certificates, validateCertificateChain: true, validateHost: true)
  108. ]
  109. let manager = Manager(
  110. configuration: configuration,
  111. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  112. )
  113. let expectation = expectationWithDescription("\(URL)")
  114. var error: NSError?
  115. // When
  116. manager.request(.GET, URL)
  117. .response { _, _, _, responseError in
  118. error = responseError
  119. expectation.fulfill()
  120. }
  121. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  122. // Then
  123. XCTAssertNotNil(error, "error should not be nil")
  124. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  125. }
  126. func testThatExpiredCertificateRequestFailsWhenPinningAllCertificatesWithCertificateChainValidation() {
  127. // Given
  128. let certificates = [TestCertificates.Leaf, TestCertificates.IntermediateCA, TestCertificates.RootCA]
  129. let policies: [String: ServerTrustPolicy] = [
  130. host: .PinCertificates(certificates: certificates, validateCertificateChain: true, validateHost: true)
  131. ]
  132. let manager = Manager(
  133. configuration: configuration,
  134. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  135. )
  136. let expectation = expectationWithDescription("\(URL)")
  137. var error: NSError?
  138. // When
  139. manager.request(.GET, URL)
  140. .response { _, _, _, responseError in
  141. error = responseError
  142. expectation.fulfill()
  143. }
  144. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  145. // Then
  146. XCTAssertNotNil(error, "error should not be nil")
  147. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  148. }
  149. func testThatExpiredCertificateRequestSucceedsWhenPinningLeafCertificateWithoutCertificateChainValidation() {
  150. // Given
  151. let certificates = [TestCertificates.Leaf]
  152. let policies: [String: ServerTrustPolicy] = [
  153. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  154. ]
  155. let manager = Manager(
  156. configuration: configuration,
  157. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  158. )
  159. let expectation = expectationWithDescription("\(URL)")
  160. var error: NSError?
  161. // When
  162. manager.request(.GET, URL)
  163. .response { _, _, _, responseError in
  164. error = responseError
  165. expectation.fulfill()
  166. }
  167. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  168. // Then
  169. XCTAssertNil(error, "error should be nil")
  170. }
  171. func testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCACertificateWithoutCertificateChainValidation() {
  172. // Given
  173. let certificates = [TestCertificates.IntermediateCA]
  174. let policies: [String: ServerTrustPolicy] = [
  175. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  176. ]
  177. let manager = Manager(
  178. configuration: configuration,
  179. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  180. )
  181. let expectation = expectationWithDescription("\(URL)")
  182. var error: NSError?
  183. // When
  184. manager.request(.GET, URL)
  185. .response { _, _, _, responseError in
  186. error = responseError
  187. expectation.fulfill()
  188. }
  189. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  190. // Then
  191. XCTAssertNil(error, "error should be nil")
  192. }
  193. func testThatExpiredCertificateRequestSucceedsWhenPinningRootCACertificateWithoutCertificateChainValidation() {
  194. // Given
  195. let certificates = [TestCertificates.RootCA]
  196. let policies: [String: ServerTrustPolicy] = [
  197. host: .PinCertificates(certificates: certificates, validateCertificateChain: false, validateHost: true)
  198. ]
  199. let manager = Manager(
  200. configuration: configuration,
  201. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  202. )
  203. let expectation = expectationWithDescription("\(URL)")
  204. var error: NSError?
  205. // When
  206. manager.request(.GET, URL)
  207. .response { _, _, _, responseError in
  208. error = responseError
  209. expectation.fulfill()
  210. }
  211. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  212. // Then
  213. XCTAssertNil(error, "error should be nil")
  214. }
  215. // MARK: Server Trust Policy - Public Key Pinning Tests
  216. func testThatExpiredCertificateRequestFailsWhenPinningLeafPublicKeyWithCertificateChainValidation() {
  217. // Given
  218. let publicKeys = [TestPublicKeys.Leaf]
  219. let policies: [String: ServerTrustPolicy] = [
  220. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: true, validateHost: true)
  221. ]
  222. let manager = Manager(
  223. configuration: configuration,
  224. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  225. )
  226. let expectation = expectationWithDescription("\(URL)")
  227. var error: NSError?
  228. // When
  229. manager.request(.GET, URL)
  230. .response { _, _, _, responseError in
  231. error = responseError
  232. expectation.fulfill()
  233. }
  234. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  235. // Then
  236. XCTAssertNotNil(error, "error should not be nil")
  237. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  238. }
  239. func testThatExpiredCertificateRequestSucceedsWhenPinningLeafPublicKeyWithoutCertificateChainValidation() {
  240. // Given
  241. let publicKeys = [TestPublicKeys.Leaf]
  242. let policies: [String: ServerTrustPolicy] = [
  243. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  244. ]
  245. let manager = Manager(
  246. configuration: configuration,
  247. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  248. )
  249. let expectation = expectationWithDescription("\(URL)")
  250. var error: NSError?
  251. // When
  252. manager.request(.GET, URL)
  253. .response { _, _, _, responseError in
  254. error = responseError
  255. expectation.fulfill()
  256. }
  257. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  258. // Then
  259. XCTAssertNil(error, "error should be nil")
  260. }
  261. func testThatExpiredCertificateRequestSucceedsWhenPinningIntermediateCAPublicKeyWithoutCertificateChainValidation() {
  262. // Given
  263. let publicKeys = [TestPublicKeys.IntermediateCA]
  264. let policies: [String: ServerTrustPolicy] = [
  265. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  266. ]
  267. let manager = Manager(
  268. configuration: configuration,
  269. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  270. )
  271. let expectation = expectationWithDescription("\(URL)")
  272. var error: NSError?
  273. // When
  274. manager.request(.GET, URL)
  275. .response { _, _, _, responseError in
  276. error = responseError
  277. expectation.fulfill()
  278. }
  279. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  280. // Then
  281. XCTAssertNil(error, "error should be nil")
  282. }
  283. func testThatExpiredCertificateRequestSucceedsWhenPinningRootCAPublicKeyWithoutCertificateChainValidation() {
  284. // Given
  285. let publicKeys = [TestPublicKeys.RootCA]
  286. let policies: [String: ServerTrustPolicy] = [
  287. host: .PinPublicKeys(publicKeys: publicKeys, validateCertificateChain: false, validateHost: true)
  288. ]
  289. let manager = Manager(
  290. configuration: configuration,
  291. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  292. )
  293. let expectation = expectationWithDescription("\(URL)")
  294. var error: NSError?
  295. // When
  296. manager.request(.GET, URL)
  297. .response { _, _, _, responseError in
  298. error = responseError
  299. expectation.fulfill()
  300. }
  301. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  302. // Then
  303. XCTAssertNil(error, "error should be nil")
  304. }
  305. // MARK: Server Trust Policy - Disabling Evaluation Tests
  306. func testThatExpiredCertificateRequestSucceedsWhenDisablingEvaluation() {
  307. // Given
  308. let policies = [host: ServerTrustPolicy.DisableEvaluation]
  309. let manager = Manager(
  310. configuration: configuration,
  311. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  312. )
  313. let expectation = expectationWithDescription("\(URL)")
  314. var error: NSError?
  315. // When
  316. manager.request(.GET, URL)
  317. .response { _, _, _, responseError in
  318. error = responseError
  319. expectation.fulfill()
  320. }
  321. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  322. // Then
  323. XCTAssertNil(error, "error should be nil")
  324. }
  325. // MARK: Server Trust Policy - Custom Evaluation Tests
  326. func testThatExpiredCertificateRequestSucceedsWhenCustomEvaluationReturnsTrue() {
  327. // Given
  328. let policies = [
  329. host: ServerTrustPolicy.CustomEvaluation { _, _ in
  330. // Implement a custom evaluation routine here...
  331. return true
  332. }
  333. ]
  334. let manager = Manager(
  335. configuration: configuration,
  336. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  337. )
  338. let expectation = expectationWithDescription("\(URL)")
  339. var error: NSError?
  340. // When
  341. manager.request(.GET, URL)
  342. .response { _, _, _, responseError in
  343. error = responseError
  344. expectation.fulfill()
  345. }
  346. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  347. // Then
  348. XCTAssertNil(error, "error should be nil")
  349. }
  350. func testThatExpiredCertificateRequestFailsWhenCustomEvaluationReturnsFalse() {
  351. // Given
  352. let policies = [
  353. host: ServerTrustPolicy.CustomEvaluation { _, _ in
  354. // Implement a custom evaluation routine here...
  355. return false
  356. }
  357. ]
  358. let manager = Manager(
  359. configuration: configuration,
  360. serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
  361. )
  362. let expectation = expectationWithDescription("\(URL)")
  363. var error: NSError?
  364. // When
  365. manager.request(.GET, URL)
  366. .response { _, _, _, responseError in
  367. error = responseError
  368. expectation.fulfill()
  369. }
  370. waitForExpectationsWithTimeout(defaultTimeout, handler: nil)
  371. // Then
  372. XCTAssertNotNil(error, "error should not be nil")
  373. XCTAssertEqual(error?.code ?? -1, NSURLErrorCancelled, "error should be NSURLErrorCancelled")
  374. }
  375. }