2
0

ServerTrustEvaluatorTests.swift 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. //
  2. // ServerTrustPolicyTests.swift
  3. //
  4. // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // 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 NONINFRINGEMENT. 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 FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Alamofire
  25. import Foundation
  26. import XCTest
  27. private struct TestCertificates {
  28. // Root Certificates
  29. static let rootCA = TestCertificates.certificate(filename: "alamofire-root-ca")
  30. // Intermediate Certificates
  31. static let intermediateCA1 = TestCertificates.certificate(filename: "alamofire-signing-ca1")
  32. static let intermediateCA2 = TestCertificates.certificate(filename: "alamofire-signing-ca2")
  33. // Leaf Certificates - Signed by CA1
  34. static let leafWildcard = TestCertificates.certificate(filename: "wildcard.alamofire.org")
  35. static let leafMultipleDNSNames = TestCertificates.certificate(filename: "multiple-dns-names")
  36. static let leafSignedByCA1 = TestCertificates.certificate(filename: "signed-by-ca1")
  37. static let leafDNSNameAndURI = TestCertificates.certificate(filename: "test.alamofire.org")
  38. // Leaf Certificates - Signed by CA2
  39. static let leafExpired = TestCertificates.certificate(filename: "expired")
  40. static let leafMissingDNSNameAndURI = TestCertificates.certificate(filename: "missing-dns-name-and-uri")
  41. static let leafSignedByCA2 = TestCertificates.certificate(filename: "signed-by-ca2")
  42. static let leafValidDNSName = TestCertificates.certificate(filename: "valid-dns-name")
  43. static let leafValidURI = TestCertificates.certificate(filename: "valid-uri")
  44. static func certificate(filename: String) -> SecCertificate {
  45. class Locator {}
  46. let filePath = Bundle(for: Locator.self).path(forResource: filename, ofType: "cer")!
  47. let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
  48. let certificate = SecCertificateCreateWithData(nil, data as CFData)!
  49. return certificate
  50. }
  51. }
  52. // MARK: -
  53. private enum TestTrusts {
  54. // Leaf Trusts - Signed by CA1
  55. case leafWildcard
  56. case leafMultipleDNSNames
  57. case leafSignedByCA1
  58. case leafDNSNameAndURI
  59. // Leaf Trusts - Signed by CA2
  60. case leafExpired
  61. case leafMissingDNSNameAndURI
  62. case leafSignedByCA2
  63. case leafValidDNSName
  64. case leafValidURI
  65. // Invalid Trusts
  66. case leafValidDNSNameMissingIntermediate
  67. case leafValidDNSNameWithIncorrectIntermediate
  68. var trust: SecTrust {
  69. let trust: SecTrust
  70. switch self {
  71. case .leafWildcard:
  72. trust = TestTrusts.trustWithCertificates([TestCertificates.leafWildcard,
  73. TestCertificates.intermediateCA1,
  74. TestCertificates.rootCA])
  75. case .leafMultipleDNSNames:
  76. trust = TestTrusts.trustWithCertificates([TestCertificates.leafMultipleDNSNames,
  77. TestCertificates.intermediateCA1,
  78. TestCertificates.rootCA])
  79. case .leafSignedByCA1:
  80. trust = TestTrusts.trustWithCertificates([TestCertificates.leafSignedByCA1,
  81. TestCertificates.intermediateCA1,
  82. TestCertificates.rootCA])
  83. case .leafDNSNameAndURI:
  84. trust = TestTrusts.trustWithCertificates([TestCertificates.leafDNSNameAndURI,
  85. TestCertificates.intermediateCA1,
  86. TestCertificates.rootCA])
  87. case .leafExpired:
  88. trust = TestTrusts.trustWithCertificates([TestCertificates.leafExpired,
  89. TestCertificates.intermediateCA2,
  90. TestCertificates.rootCA])
  91. case .leafMissingDNSNameAndURI:
  92. trust = TestTrusts.trustWithCertificates([TestCertificates.leafMissingDNSNameAndURI,
  93. TestCertificates.intermediateCA2,
  94. TestCertificates.rootCA])
  95. case .leafSignedByCA2:
  96. trust = TestTrusts.trustWithCertificates([TestCertificates.leafSignedByCA2,
  97. TestCertificates.intermediateCA2,
  98. TestCertificates.rootCA])
  99. case .leafValidDNSName:
  100. trust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  101. TestCertificates.intermediateCA2,
  102. TestCertificates.rootCA])
  103. case .leafValidURI:
  104. trust = TestTrusts.trustWithCertificates([TestCertificates.leafValidURI,
  105. TestCertificates.intermediateCA2,
  106. TestCertificates.rootCA])
  107. case .leafValidDNSNameMissingIntermediate:
  108. trust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  109. TestCertificates.rootCA])
  110. case .leafValidDNSNameWithIncorrectIntermediate:
  111. trust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  112. TestCertificates.intermediateCA1,
  113. TestCertificates.rootCA])
  114. }
  115. return trust
  116. }
  117. static func trustWithCertificates(_ certificates: [SecCertificate]) -> SecTrust {
  118. let policy = SecPolicyCreateBasicX509()
  119. var trust: SecTrust?
  120. SecTrustCreateWithCertificates(certificates as CFTypeRef, policy, &trust)
  121. return trust!
  122. }
  123. }
  124. // MARK: - Basic X509 and SSL Exploration Tests -
  125. class ServerTrustPolicyTestCase: BaseTestCase {
  126. func setRootCertificateAsLoneAnchorCertificateForTrust(_ trust: SecTrust) {
  127. SecTrustSetAnchorCertificates(trust, [TestCertificates.rootCA] as CFArray)
  128. SecTrustSetAnchorCertificatesOnly(trust, true)
  129. }
  130. }
  131. // MARK: - SecTrust Extension
  132. extension SecTrust {
  133. /// Evaluates `self` and returns `true` if the evaluation succeeds with a value of `.unspecified` or `.proceed`.
  134. var isValid: Bool {
  135. var result = SecTrustResultType.invalid
  136. let status = SecTrustEvaluate(self, &result)
  137. return (status == errSecSuccess) ? (result == .unspecified || result == .proceed) : false
  138. }
  139. }
  140. // MARK: -
  141. class ServerTrustPolicyExplorationBasicX509PolicyValidationTestCase: ServerTrustPolicyTestCase {
  142. func testThatAnchoredRootCertificatePassesBasicX509ValidationWithRootInTrust() {
  143. // Given
  144. let trust = TestTrusts.trustWithCertificates([TestCertificates.leafDNSNameAndURI,
  145. TestCertificates.intermediateCA1,
  146. TestCertificates.rootCA])
  147. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  148. // When
  149. let policies = [SecPolicyCreateBasicX509()]
  150. SecTrustSetPolicies(trust, policies as CFTypeRef)
  151. // Then
  152. XCTAssertTrue(trust.isValid, "trust should be valid")
  153. }
  154. func testThatAnchoredRootCertificatePassesBasicX509ValidationWithoutRootInTrust() {
  155. // Given
  156. let trust = TestTrusts.leafDNSNameAndURI.trust
  157. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  158. // When
  159. let policies = [SecPolicyCreateBasicX509()]
  160. SecTrustSetPolicies(trust, policies as CFTypeRef)
  161. // Then
  162. XCTAssertTrue(trust.isValid, "trust should be valid")
  163. }
  164. func testThatCertificateMissingDNSNamePassesBasicX509Validation() {
  165. // Given
  166. let trust = TestTrusts.leafMissingDNSNameAndURI.trust
  167. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  168. // When
  169. let policies = [SecPolicyCreateBasicX509()]
  170. SecTrustSetPolicies(trust, policies as CFTypeRef)
  171. // Then
  172. XCTAssertTrue(trust.isValid, "trust should be valid")
  173. }
  174. func testThatExpiredCertificateFailsBasicX509Validation() {
  175. // Given
  176. let trust = TestTrusts.leafExpired.trust
  177. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  178. // When
  179. let policies = [SecPolicyCreateBasicX509()]
  180. SecTrustSetPolicies(trust, policies as CFTypeRef)
  181. // Then
  182. XCTAssertFalse(trust.isValid, "trust should not be valid")
  183. }
  184. }
  185. // MARK: -
  186. class ServerTrustPolicyExplorationSSLPolicyValidationTestCase: ServerTrustPolicyTestCase {
  187. func testThatAnchoredRootCertificatePassesSSLValidationWithRootInTrust() {
  188. // Given
  189. let trust = TestTrusts.trustWithCertificates([TestCertificates.leafDNSNameAndURI,
  190. TestCertificates.intermediateCA1,
  191. TestCertificates.rootCA])
  192. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  193. // When
  194. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  195. SecTrustSetPolicies(trust, policies as CFTypeRef)
  196. // Then
  197. XCTAssertTrue(trust.isValid, "trust should be valid")
  198. }
  199. func testThatAnchoredRootCertificatePassesSSLValidationWithoutRootInTrust() {
  200. // Given
  201. let trust = TestTrusts.leafDNSNameAndURI.trust
  202. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  203. // When
  204. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  205. SecTrustSetPolicies(trust, policies as CFTypeRef)
  206. // Then
  207. XCTAssertTrue(trust.isValid, "trust should be valid")
  208. }
  209. func testThatCertificateMissingDNSNameFailsSSLValidation() {
  210. // Given
  211. let trust = TestTrusts.leafMissingDNSNameAndURI.trust
  212. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  213. // When
  214. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  215. SecTrustSetPolicies(trust, policies as CFTypeRef)
  216. // Then
  217. XCTAssertFalse(trust.isValid, "trust should not be valid")
  218. }
  219. func testThatWildcardCertificatePassesSSLValidation() {
  220. // Given
  221. let trust = TestTrusts.leafWildcard.trust // *.alamofire.org
  222. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  223. // When
  224. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  225. SecTrustSetPolicies(trust, policies as CFTypeRef)
  226. // Then
  227. XCTAssertTrue(trust.isValid, "trust should be valid")
  228. }
  229. func testThatDNSNameCertificatePassesSSLValidation() {
  230. // Given
  231. let trust = TestTrusts.leafValidDNSName.trust
  232. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  233. // When
  234. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  235. SecTrustSetPolicies(trust, policies as CFTypeRef)
  236. // Then
  237. XCTAssertTrue(trust.isValid, "trust should be valid")
  238. }
  239. func testThatURICertificateFailsSSLValidation() {
  240. // Given
  241. let trust = TestTrusts.leafValidURI.trust
  242. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  243. // When
  244. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  245. SecTrustSetPolicies(trust, policies as CFTypeRef)
  246. // Then
  247. XCTAssertFalse(trust.isValid, "trust should not be valid")
  248. }
  249. func testThatMultipleDNSNamesCertificatePassesSSLValidationForAllEntries() {
  250. // Given
  251. let trust = TestTrusts.leafMultipleDNSNames.trust
  252. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  253. // When
  254. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString),
  255. SecPolicyCreateSSL(true, "blog.alamofire.org" as CFString),
  256. SecPolicyCreateSSL(true, "www.alamofire.org" as CFString)]
  257. SecTrustSetPolicies(trust, policies as CFTypeRef)
  258. // Then
  259. XCTAssertTrue(trust.isValid, "trust should not be valid")
  260. }
  261. func testThatPassingNilForHostParameterAllowsCertificateMissingDNSNameToPassSSLValidation() {
  262. // Given
  263. let trust = TestTrusts.leafMissingDNSNameAndURI.trust
  264. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  265. // When
  266. let policies = [SecPolicyCreateSSL(true, nil)]
  267. SecTrustSetPolicies(trust, policies as CFTypeRef)
  268. // Then
  269. XCTAssertTrue(trust.isValid, "trust should not be valid")
  270. }
  271. func testThatExpiredCertificateFailsSSLValidation() {
  272. // Given
  273. let trust = TestTrusts.leafExpired.trust
  274. setRootCertificateAsLoneAnchorCertificateForTrust(trust)
  275. // When
  276. let policies = [SecPolicyCreateSSL(true, "test.alamofire.org" as CFString)]
  277. SecTrustSetPolicies(trust, policies as CFTypeRef)
  278. // Then
  279. XCTAssertFalse(trust.isValid, "trust should not be valid")
  280. }
  281. }
  282. // MARK: - Server Trust Policy Tests -
  283. class ServerTrustPolicyPerformDefaultEvaluationTestCase: ServerTrustPolicyTestCase {
  284. // MARK: Do NOT Validate Host
  285. func testThatValidCertificateChainPassesEvaluationWithoutHostValidation() {
  286. // Given
  287. let host = "test.alamofire.org"
  288. let serverTrust = TestTrusts.leafValidDNSName.trust
  289. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  290. // When
  291. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  292. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  293. // Then
  294. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  295. }
  296. func testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation() {
  297. // Given
  298. let host = "test.alamofire.org"
  299. let serverTrust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  300. TestCertificates.intermediateCA2])
  301. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  302. // When
  303. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  304. // Then
  305. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  306. }
  307. func testThatMissingDNSNameLeafCertificatePassesEvaluationWithoutHostValidation() {
  308. // Given
  309. let host = "test.alamofire.org"
  310. let serverTrust = TestTrusts.leafMissingDNSNameAndURI.trust
  311. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  312. // When
  313. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  314. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  315. // Then
  316. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  317. }
  318. func testThatExpiredCertificateChainFailsEvaluationWithoutHostValidation() {
  319. // Given
  320. let host = "test.alamofire.org"
  321. let serverTrust = TestTrusts.leafExpired.trust
  322. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  323. // When
  324. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  325. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  326. // Then
  327. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  328. }
  329. func testThatMissingIntermediateCertificateInChainFailsEvaluationWithoutHostValidation() {
  330. // Given
  331. let host = "test.alamofire.org"
  332. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  333. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  334. // When
  335. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  336. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  337. // Then
  338. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  339. }
  340. // MARK: Validate Host
  341. func testThatValidCertificateChainPassesEvaluationWithHostValidation() {
  342. // Given
  343. let host = "test.alamofire.org"
  344. let serverTrust = TestTrusts.leafValidDNSName.trust
  345. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: true)
  346. // When
  347. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  348. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  349. // Then
  350. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  351. }
  352. func testThatNonAnchoredRootCertificateChainFailsEvaluationWithHostValidation() {
  353. // Given
  354. let host = "test.alamofire.org"
  355. let serverTrust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  356. TestCertificates.intermediateCA2])
  357. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: true)
  358. // When
  359. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  360. // Then
  361. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  362. }
  363. func testThatMissingDNSNameLeafCertificateFailsEvaluationWithHostValidation() {
  364. // Given
  365. let host = "test.alamofire.org"
  366. let serverTrust = TestTrusts.leafMissingDNSNameAndURI.trust
  367. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: true)
  368. // When
  369. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  370. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  371. // Then
  372. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  373. }
  374. func testThatWildcardedLeafCertificateChainPassesEvaluationWithHostValidation() {
  375. // Given
  376. let host = "test.alamofire.org"
  377. let serverTrust = TestTrusts.leafWildcard.trust
  378. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: true)
  379. // When
  380. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  381. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  382. // Then
  383. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  384. }
  385. func testThatExpiredCertificateChainFailsEvaluationWithHostValidation() {
  386. // Given
  387. let host = "test.alamofire.org"
  388. let serverTrust = TestTrusts.leafExpired.trust
  389. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: true)
  390. // When
  391. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  392. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  393. // Then
  394. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  395. }
  396. func testThatMissingIntermediateCertificateInChainFailsEvaluationWithHostValidation() {
  397. // Given
  398. let host = "test.alamofire.org"
  399. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  400. let serverTrustPolicy = DefaultTrustEvaluator(validateHost: false)
  401. // When
  402. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  403. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  404. // Then
  405. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  406. XCTAssertEqual(result.failure?.asAFError?.isServerTrustEvaluationError, true)
  407. }
  408. }
  409. // MARK: -
  410. class ServerTrustPolicyPerformRevokedEvaluationTestCase: ServerTrustPolicyTestCase {
  411. // MARK: Do NOT Validate Host
  412. func testThatValidCertificateChainPassesEvaluationWithoutHostValidation() {
  413. // Given
  414. let host = "test.alamofire.org"
  415. let serverTrust = TestTrusts.leafValidDNSName.trust
  416. let serverTrustPolicy = RevocationTrustEvaluator(validateHost: false)
  417. // When
  418. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  419. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  420. // Then
  421. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  422. }
  423. func testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation() {
  424. // Given
  425. let host = "test.alamofire.org"
  426. let serverTrust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  427. TestCertificates.intermediateCA2])
  428. let serverTrustPolicy = RevocationTrustEvaluator(validateHost: false)
  429. // When
  430. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  431. // Then
  432. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  433. }
  434. func testThatMissingDNSNameLeafCertificatePassesEvaluationWithoutHostValidation() {
  435. // Given
  436. let host = "test.alamofire.org"
  437. let serverTrust = TestTrusts.leafMissingDNSNameAndURI.trust
  438. let serverTrustPolicy = RevocationTrustEvaluator(validateHost: false)
  439. // When
  440. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  441. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  442. // Then
  443. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  444. }
  445. func testThatExpiredCertificateChainFailsEvaluationWithoutHostValidation() {
  446. // Given
  447. let host = "test.alamofire.org"
  448. let serverTrust = TestTrusts.leafExpired.trust
  449. let serverTrustPolicy = RevocationTrustEvaluator(validateHost: false)
  450. // When
  451. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  452. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  453. // Then
  454. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  455. }
  456. func testThatMissingIntermediateCertificateInChainFailsEvaluationWithoutHostValidation() {
  457. // Given
  458. let host = "test.alamofire.org"
  459. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  460. let serverTrustPolicy = RevocationTrustEvaluator(validateHost: false)
  461. // When
  462. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  463. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  464. // Then
  465. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  466. }
  467. // MARK: Validate Host
  468. func testThatValidCertificateChainPassesEvaluationWithHostValidation() {
  469. // Given
  470. let host = "test.alamofire.org"
  471. let serverTrust = TestTrusts.leafValidDNSName.trust
  472. let serverTrustPolicy = RevocationTrustEvaluator()
  473. // When
  474. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  475. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  476. // Then
  477. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  478. }
  479. func testThatNonAnchoredRootCertificateChainFailsEvaluationWithHostValidation() {
  480. // Given
  481. let host = "test.alamofire.org"
  482. let serverTrust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  483. TestCertificates.intermediateCA2])
  484. let serverTrustPolicy = RevocationTrustEvaluator()
  485. // When
  486. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  487. // Then
  488. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  489. }
  490. func testThatMissingDNSNameLeafCertificateFailsEvaluationWithHostValidation() {
  491. // Given
  492. let host = "test.alamofire.org"
  493. let serverTrust = TestTrusts.leafMissingDNSNameAndURI.trust
  494. let serverTrustPolicy = RevocationTrustEvaluator()
  495. // When
  496. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  497. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  498. // Then
  499. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  500. }
  501. func testThatWildcardedLeafCertificateChainPassesEvaluationWithHostValidation() {
  502. // Given
  503. let host = "test.alamofire.org"
  504. let serverTrust = TestTrusts.leafWildcard.trust
  505. let serverTrustPolicy = RevocationTrustEvaluator()
  506. // When
  507. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  508. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  509. // Then
  510. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  511. }
  512. func testThatExpiredCertificateChainFailsEvaluationWithHostValidation() {
  513. // Given
  514. let host = "test.alamofire.org"
  515. let serverTrust = TestTrusts.leafExpired.trust
  516. let serverTrustPolicy = RevocationTrustEvaluator()
  517. // When
  518. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  519. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  520. // Then
  521. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  522. }
  523. func testThatMissingIntermediateCertificateInChainFailsEvaluationWithHostValidation() {
  524. // Given
  525. let host = "test.alamofire.org"
  526. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  527. let serverTrustPolicy = RevocationTrustEvaluator()
  528. // When
  529. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  530. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  531. // Then
  532. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  533. }
  534. }
  535. // MARK: -
  536. class ServerTrustPolicyPinCertificatesTestCase: ServerTrustPolicyTestCase {
  537. // MARK: Validate Certificate Chain Without Validating Host
  538. func testThatPinnedLeafCertificatePassesEvaluationWithoutHostValidation() {
  539. // Given
  540. let host = "test.alamofire.org"
  541. let serverTrust = TestTrusts.leafValidDNSName.trust
  542. let certificates = [TestCertificates.leafValidDNSName]
  543. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  544. performDefaultValidation: false,
  545. validateHost: false)
  546. // When
  547. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  548. // Then
  549. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  550. }
  551. func testThatPinnedIntermediateCertificatePassesEvaluationWithoutHostValidation() {
  552. // Given
  553. let host = "test.alamofire.org"
  554. let serverTrust = TestTrusts.leafValidDNSName.trust
  555. let certificates = [TestCertificates.intermediateCA2]
  556. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  557. performDefaultValidation: false,
  558. validateHost: false)
  559. // When
  560. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  561. // Then
  562. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  563. }
  564. func testThatPinnedRootCertificatePassesEvaluationWithoutHostValidation() {
  565. // Given
  566. let host = "test.alamofire.org"
  567. let serverTrust = TestTrusts.leafValidDNSName.trust
  568. let certificates = [TestCertificates.rootCA]
  569. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  570. performDefaultValidation: false,
  571. validateHost: false)
  572. // When
  573. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  574. // Then
  575. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  576. }
  577. func testThatPinningLeafCertificateNotInCertificateChainFailsEvaluationWithoutHostValidation() {
  578. // Given
  579. let host = "test.alamofire.org"
  580. let serverTrust = TestTrusts.leafValidDNSName.trust
  581. let certificates = [TestCertificates.leafSignedByCA2]
  582. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  583. performDefaultValidation: true,
  584. validateHost: false)
  585. // When
  586. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  587. // Then
  588. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  589. }
  590. func testThatPinningIntermediateCertificateNotInCertificateChainFailsEvaluationWithoutHostValidation() {
  591. // Given
  592. let host = "test.alamofire.org"
  593. let serverTrust = TestTrusts.leafValidDNSName.trust
  594. let certificates = [TestCertificates.intermediateCA1]
  595. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, validateHost: false)
  596. // When
  597. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  598. // Then
  599. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  600. }
  601. func testThatPinningExpiredLeafCertificateFailsEvaluationWithoutHostValidation() {
  602. // Given
  603. let host = "test.alamofire.org"
  604. let serverTrust = TestTrusts.leafExpired.trust
  605. let certificates = [TestCertificates.leafExpired]
  606. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, validateHost: false)
  607. // When
  608. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  609. // Then
  610. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  611. }
  612. func testThatPinningIntermediateCertificateWithExpiredLeafCertificateFailsEvaluationWithoutHostValidation() {
  613. // Given
  614. let host = "test.alamofire.org"
  615. let serverTrust = TestTrusts.leafExpired.trust
  616. let certificates = [TestCertificates.intermediateCA2]
  617. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, validateHost: false)
  618. // When
  619. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  620. // Then
  621. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  622. }
  623. // MARK: Validate Certificate Chain and Host
  624. func testThatPinnedLeafCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation() {
  625. // Given
  626. let host = "test.alamofire.org"
  627. let serverTrust = TestTrusts.leafValidDNSName.trust
  628. let certificates = [TestCertificates.leafValidDNSName]
  629. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, acceptSelfSignedCertificates: true)
  630. // When
  631. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  632. // Then
  633. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  634. }
  635. func testThatPinnedIntermediateCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation() {
  636. // Given
  637. let host = "test.alamofire.org"
  638. let serverTrust = TestTrusts.leafValidDNSName.trust
  639. let certificates = [TestCertificates.intermediateCA2]
  640. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, acceptSelfSignedCertificates: true)
  641. // When
  642. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  643. // Then
  644. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  645. }
  646. func testThatPinnedRootCertificatePassesEvaluationWithSelfSignedSupportAndHostValidation() {
  647. // Given
  648. let host = "test.alamofire.org"
  649. let serverTrust = TestTrusts.leafValidDNSName.trust
  650. let certificates = [TestCertificates.rootCA]
  651. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates, acceptSelfSignedCertificates: true)
  652. // When
  653. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  654. // Then
  655. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  656. }
  657. func testThatPinningLeafCertificateNotInCertificateChainFailsEvaluationWithHostValidation() {
  658. // Given
  659. let host = "test.alamofire.org"
  660. let serverTrust = TestTrusts.leafValidDNSName.trust
  661. let certificates = [TestCertificates.leafSignedByCA2]
  662. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  663. performDefaultValidation: true,
  664. validateHost: true)
  665. // When
  666. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  667. // Then
  668. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  669. }
  670. func testThatPinningIntermediateCertificateNotInCertificateChainFailsEvaluationWithHostValidation() {
  671. // Given
  672. let host = "test.alamofire.org"
  673. let serverTrust = TestTrusts.leafValidDNSName.trust
  674. let certificates = [TestCertificates.intermediateCA1]
  675. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates)
  676. // When
  677. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  678. // Then
  679. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  680. }
  681. func testThatPinningExpiredLeafCertificateFailsEvaluationWithHostValidation() {
  682. // Given
  683. let host = "test.alamofire.org"
  684. let serverTrust = TestTrusts.leafExpired.trust
  685. let certificates = [TestCertificates.leafExpired]
  686. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates)
  687. // When
  688. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  689. // Then
  690. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  691. }
  692. func testThatPinningIntermediateCertificateWithExpiredLeafCertificateFailsEvaluationWithHostValidation() {
  693. // Given
  694. let host = "test.alamofire.org"
  695. let serverTrust = TestTrusts.leafExpired.trust
  696. let certificates = [TestCertificates.intermediateCA2]
  697. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates)
  698. // When
  699. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  700. // Then
  701. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  702. }
  703. // MARK: Do NOT Validate Certificate Chain or Host
  704. func testThatPinnedLeafCertificateWithoutCertificateChainValidationPassesEvaluation() {
  705. // Given
  706. let host = "test.alamofire.org"
  707. let serverTrust = TestTrusts.leafValidDNSName.trust
  708. let certificates = [TestCertificates.leafValidDNSName]
  709. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  710. performDefaultValidation: false,
  711. validateHost: false)
  712. // When
  713. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  714. // Then
  715. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  716. }
  717. func testThatPinnedIntermediateCertificateWithoutCertificateChainValidationPassesEvaluation() {
  718. // Given
  719. let host = "test.alamofire.org"
  720. let serverTrust = TestTrusts.leafValidDNSName.trust
  721. let certificates = [TestCertificates.intermediateCA2]
  722. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  723. performDefaultValidation: false,
  724. validateHost: false)
  725. // When
  726. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  727. // Then
  728. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  729. }
  730. func testThatPinnedRootCertificateWithoutCertificateChainValidationPassesEvaluation() {
  731. // Given
  732. let host = "test.alamofire.org"
  733. let serverTrust = TestTrusts.leafValidDNSName.trust
  734. let certificates = [TestCertificates.rootCA]
  735. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  736. performDefaultValidation: false,
  737. validateHost: false)
  738. // When
  739. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  740. // Then
  741. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  742. }
  743. func testThatPinningLeafCertificateNotInCertificateChainWithoutCertificateChainValidationFailsEvaluation() {
  744. // Given
  745. let host = "test.alamofire.org"
  746. let serverTrust = TestTrusts.leafValidDNSName.trust
  747. let certificates = [TestCertificates.leafSignedByCA2]
  748. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  749. performDefaultValidation: false,
  750. validateHost: false)
  751. // When
  752. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  753. // Then
  754. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  755. }
  756. func testThatPinningIntermediateCertificateNotInCertificateChainWithoutCertificateChainValidationFailsEvaluation() {
  757. // Given
  758. let host = "test.alamofire.org"
  759. let serverTrust = TestTrusts.leafValidDNSName.trust
  760. let certificates = [TestCertificates.intermediateCA1]
  761. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  762. performDefaultValidation: false,
  763. validateHost: false)
  764. // When
  765. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  766. // Then
  767. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  768. }
  769. func testThatPinningExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation() {
  770. // Given
  771. let host = "test.alamofire.org"
  772. let serverTrust = TestTrusts.leafExpired.trust
  773. let certificates = [TestCertificates.leafExpired]
  774. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  775. performDefaultValidation: false,
  776. validateHost: false)
  777. // When
  778. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  779. // Then
  780. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  781. }
  782. func testThatPinningIntermediateCertificateWithExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation() {
  783. // Given
  784. let host = "test.alamofire.org"
  785. let serverTrust = TestTrusts.leafExpired.trust
  786. let certificates = [TestCertificates.intermediateCA2]
  787. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  788. performDefaultValidation: false,
  789. validateHost: false)
  790. // When
  791. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  792. // Then
  793. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  794. }
  795. func testThatPinningRootCertificateWithExpiredLeafCertificateWithoutCertificateChainValidationPassesEvaluation() {
  796. // Given
  797. let host = "test.alamofire.org"
  798. let serverTrust = TestTrusts.leafExpired.trust
  799. let certificates = [TestCertificates.rootCA]
  800. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  801. performDefaultValidation: false,
  802. validateHost: false)
  803. // When
  804. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  805. // Then
  806. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  807. }
  808. func testThatPinningMultipleCertificatesWithoutCertificateChainValidationPassesEvaluation() {
  809. // Given
  810. let host = "test.alamofire.org"
  811. let serverTrust = TestTrusts.leafExpired.trust
  812. let certificates = [TestCertificates.leafMultipleDNSNames, // not in certificate chain
  813. TestCertificates.leafSignedByCA1, // not in certificate chain
  814. TestCertificates.leafExpired, // in certificate chain 👍🏼👍🏼
  815. TestCertificates.leafWildcard, // not in certificate chain
  816. TestCertificates.leafDNSNameAndURI // not in certificate chain
  817. ]
  818. let serverTrustPolicy = PinnedCertificatesTrustEvaluator(certificates: certificates,
  819. performDefaultValidation: false,
  820. validateHost: false)
  821. // When
  822. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  823. // Then
  824. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  825. }
  826. }
  827. // MARK: -
  828. class ServerTrustPolicyPinPublicKeysTestCase: ServerTrustPolicyTestCase {
  829. // MARK: Validate Certificate Chain Without Validating Host
  830. func testThatPinningLeafKeyPassesEvaluationWithoutHostValidation() {
  831. // Given
  832. let host = "test.alamofire.org"
  833. let serverTrust = TestTrusts.leafValidDNSName.trust
  834. let keys = [TestCertificates.leafValidDNSName].af.publicKeys
  835. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys, validateHost: false)
  836. // When
  837. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  838. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  839. // Then
  840. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  841. }
  842. func testThatPinningIntermediateKeyPassesEvaluationWithoutHostValidation() {
  843. // Given
  844. let host = "test.alamofire.org"
  845. let serverTrust = TestTrusts.leafValidDNSName.trust
  846. let keys = [TestCertificates.intermediateCA2].af.publicKeys
  847. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys, validateHost: false)
  848. // When
  849. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  850. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  851. // Then
  852. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  853. }
  854. func testThatPinningRootKeyPassesEvaluationWithoutHostValidation() {
  855. // Given
  856. let host = "test.alamofire.org"
  857. let serverTrust = TestTrusts.leafValidDNSName.trust
  858. let keys = [TestCertificates.rootCA].af.publicKeys
  859. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys, validateHost: false)
  860. // When
  861. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  862. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  863. // Then
  864. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  865. }
  866. func testThatPinningKeyNotInCertificateChainFailsEvaluationWithoutHostValidation() {
  867. // Given
  868. let host = "test.alamofire.org"
  869. let serverTrust = TestTrusts.leafValidDNSName.trust
  870. let keys = [TestCertificates.leafSignedByCA2].af.publicKeys
  871. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys, validateHost: false)
  872. // When
  873. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  874. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  875. // Then
  876. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  877. }
  878. func testThatPinningBackupKeyPassesEvaluationWithoutHostValidation() {
  879. // Given
  880. let host = "test.alamofire.org"
  881. let serverTrust = TestTrusts.leafValidDNSName.trust
  882. let keys = [TestCertificates.leafSignedByCA1, TestCertificates.intermediateCA1, TestCertificates.leafValidDNSName].af.publicKeys
  883. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys, validateHost: false)
  884. // When
  885. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  886. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  887. // Then
  888. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  889. }
  890. // MARK: Validate Certificate Chain and Host
  891. func testThatPinningLeafKeyPassesEvaluationWithHostValidation() {
  892. // Given
  893. let host = "test.alamofire.org"
  894. let serverTrust = TestTrusts.leafValidDNSName.trust
  895. let keys = [TestCertificates.leafValidDNSName].af.publicKeys
  896. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys)
  897. // When
  898. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  899. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  900. // Then
  901. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  902. }
  903. func testThatPinningIntermediateKeyPassesEvaluationWithHostValidation() {
  904. // Given
  905. let host = "test.alamofire.org"
  906. let serverTrust = TestTrusts.leafValidDNSName.trust
  907. let keys = [TestCertificates.intermediateCA2].af.publicKeys
  908. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys)
  909. // When
  910. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  911. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  912. // Then
  913. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  914. }
  915. func testThatPinningRootKeyPassesEvaluationWithHostValidation() {
  916. // Given
  917. let host = "test.alamofire.org"
  918. let serverTrust = TestTrusts.leafValidDNSName.trust
  919. let keys = [TestCertificates.rootCA].af.publicKeys
  920. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys)
  921. // When
  922. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  923. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  924. // Then
  925. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  926. }
  927. func testThatPinningKeyNotInCertificateChainFailsEvaluationWithHostValidation() {
  928. // Given
  929. let host = "test.alamofire.org"
  930. let serverTrust = TestTrusts.leafValidDNSName.trust
  931. let keys = [TestCertificates.leafSignedByCA2].af.publicKeys
  932. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys)
  933. // When
  934. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  935. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  936. // Then
  937. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  938. }
  939. func testThatPinningBackupKeyPassesEvaluationWithHostValidation() {
  940. // Given
  941. let host = "test.alamofire.org"
  942. let serverTrust = TestTrusts.leafValidDNSName.trust
  943. let keys = [TestCertificates.leafSignedByCA1, TestCertificates.intermediateCA1, TestCertificates.leafValidDNSName].af.publicKeys
  944. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys)
  945. // When
  946. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  947. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  948. // Then
  949. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  950. }
  951. // MARK: Do NOT perform default validation or validate host.
  952. func testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithMissingIntermediateCertificate() {
  953. // Given
  954. let host = "test.alamofire.org"
  955. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  956. let keys = [TestCertificates.leafValidDNSName].af.publicKeys
  957. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  958. performDefaultValidation: false,
  959. validateHost: false)
  960. // When
  961. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  962. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  963. // Then
  964. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  965. }
  966. func testThatPinningRootKeyWithoutCertificateChainValidationFailsEvaluationWithMissingIntermediateCertificate() {
  967. // Given
  968. let host = "test.alamofire.org"
  969. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  970. let keys = [TestCertificates.rootCA].af.publicKeys
  971. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  972. performDefaultValidation: false,
  973. validateHost: false)
  974. // When
  975. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  976. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  977. // Then
  978. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  979. }
  980. func testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithIncorrectIntermediateCertificate() {
  981. // Given
  982. let host = "test.alamofire.org"
  983. let serverTrust = TestTrusts.leafValidDNSNameWithIncorrectIntermediate.trust
  984. let keys = [TestCertificates.leafValidDNSName].af.publicKeys
  985. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  986. performDefaultValidation: false,
  987. validateHost: false)
  988. // When
  989. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  990. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  991. // Then
  992. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  993. }
  994. func testThatPinningLeafKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate() {
  995. // Given
  996. let host = "test.alamofire.org"
  997. let serverTrust = TestTrusts.leafExpired.trust
  998. let keys = [TestCertificates.leafExpired].af.publicKeys
  999. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  1000. performDefaultValidation: false,
  1001. validateHost: false)
  1002. // When
  1003. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  1004. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  1005. // Then
  1006. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1007. }
  1008. func testThatPinningIntermediateKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate() {
  1009. // Given
  1010. let host = "test.alamofire.org"
  1011. let serverTrust = TestTrusts.leafExpired.trust
  1012. let keys = [TestCertificates.intermediateCA2].af.publicKeys
  1013. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  1014. performDefaultValidation: false,
  1015. validateHost: false)
  1016. // When
  1017. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  1018. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  1019. // Then
  1020. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1021. }
  1022. func testThatPinningRootKeyWithoutCertificateChainValidationPassesEvaluationWithExpiredLeafCertificate() {
  1023. // Given
  1024. let host = "test.alamofire.org"
  1025. let serverTrust = TestTrusts.leafExpired.trust
  1026. let keys = [TestCertificates.rootCA].af.publicKeys
  1027. let serverTrustPolicy = PublicKeysTrustEvaluator(keys: keys,
  1028. performDefaultValidation: false,
  1029. validateHost: false)
  1030. // When
  1031. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  1032. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  1033. // Then
  1034. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1035. }
  1036. }
  1037. // MARK: -
  1038. class ServerTrustPolicyDisableEvaluationTestCase: ServerTrustPolicyTestCase {
  1039. func testThatCertificateChainMissingIntermediateCertificatePassesEvaluation() throws {
  1040. // Given
  1041. let host = "test.alamofire.org"
  1042. let serverTrust = TestTrusts.leafValidDNSNameMissingIntermediate.trust
  1043. let serverTrustPolicy = DisabledEvaluator()
  1044. // When
  1045. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  1046. // Then
  1047. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1048. }
  1049. func testThatExpiredLeafCertificatePassesEvaluation() throws {
  1050. // Given
  1051. let host = "test.alamofire.org"
  1052. let serverTrust = TestTrusts.leafExpired.trust
  1053. let serverTrustPolicy = DisabledEvaluator()
  1054. // When
  1055. let result = Result { try serverTrustPolicy.evaluate(serverTrust, forHost: host) }
  1056. // Then
  1057. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1058. }
  1059. }
  1060. // MARK: -
  1061. class ServerTrustPolicyCompositeTestCase: ServerTrustPolicyTestCase {
  1062. func testThatValidCertificateChainPassesDefaultAndRevocationCompositeChecks() throws {
  1063. // Given
  1064. let host = "test.alamofire.org"
  1065. let serverTrust = TestTrusts.leafValidDNSName.trust
  1066. let defaultPolicy = DefaultTrustEvaluator(validateHost: false)
  1067. let revocationPolicy = RevocationTrustEvaluator(validateHost: false)
  1068. let compositePolicy = CompositeTrustEvaluator(evaluators: [defaultPolicy, revocationPolicy])
  1069. // When
  1070. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  1071. let result = Result { try compositePolicy.evaluate(serverTrust, forHost: host) }
  1072. // Then
  1073. XCTAssertTrue(result.isSuccess, "server trust should pass evaluation")
  1074. }
  1075. func testThatNonAnchoredRootCertificateChainFailsEvaluationWithoutHostValidation() throws {
  1076. // Given
  1077. let host = "test.alamofire.org"
  1078. let serverTrust = TestTrusts.trustWithCertificates([TestCertificates.leafValidDNSName,
  1079. TestCertificates.intermediateCA2])
  1080. let defaultPolicy = DefaultTrustEvaluator(validateHost: false)
  1081. let revocationPolicy = RevocationTrustEvaluator(validateHost: false)
  1082. let compositePolicy = CompositeTrustEvaluator(evaluators: [defaultPolicy, revocationPolicy])
  1083. // When
  1084. let result = Result { try compositePolicy.evaluate(serverTrust, forHost: host) }
  1085. // Then
  1086. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  1087. }
  1088. func testThatExpiredLeafCertificateFailsDefaultAndRevocationComposite() throws {
  1089. // Given
  1090. let host = "test.alamofire.org"
  1091. let serverTrust = TestTrusts.leafExpired.trust
  1092. let defaultPolicy = DefaultTrustEvaluator(validateHost: false)
  1093. let revocationPolicy = RevocationTrustEvaluator(validateHost: false)
  1094. let compositePolicy = CompositeTrustEvaluator(evaluators: [defaultPolicy, revocationPolicy])
  1095. // When
  1096. setRootCertificateAsLoneAnchorCertificateForTrust(serverTrust)
  1097. let result = Result { try compositePolicy.evaluate(serverTrust, forHost: host) }
  1098. // Then
  1099. XCTAssertFalse(result.isSuccess, "server trust should not pass evaluation")
  1100. }
  1101. }
  1102. // MARK: -
  1103. class ServerTrustPolicyCertificatesInBundleTestCase: ServerTrustPolicyTestCase {
  1104. func testOnlyValidCertificatesAreDetected() {
  1105. // Given
  1106. // Files present in bundle in the form of type+encoding+extension [key|cert][DER|PEM].[cer|crt|der|key|pem]
  1107. // certDER.cer: DER-encoded well-formed certificate
  1108. // certDER.crt: DER-encoded well-formed certificate
  1109. // certDER.der: DER-encoded well-formed certificate
  1110. // certPEM.*: PEM-encoded well-formed certificates, expected to fail: Apple API only handles DER encoding
  1111. // devURandomGibberish.crt: Random data, should fail
  1112. // keyDER.der: DER-encoded key, not a certificate, should fail
  1113. // When
  1114. let certificates = Bundle(for: ServerTrustPolicyCertificatesInBundleTestCase.self).af.certificates
  1115. // Then
  1116. // Expectation: 19 well-formed certificates in the test bundle plus 4 invalid certificates.
  1117. #if os(macOS)
  1118. // For some reason, macOS is allowing all certificates to be considered valid. Need to file a
  1119. // rdar demonstrating this behavior.
  1120. if #available(macOS 10.12, *) {
  1121. XCTAssertEqual(certificates.count, 19, "Expected 19 well-formed certificates")
  1122. } else {
  1123. XCTAssertEqual(certificates.count, 23, "Expected 23 well-formed certificates")
  1124. }
  1125. #else
  1126. XCTAssertEqual(certificates.count, 19, "Expected 19 well-formed certificates")
  1127. #endif
  1128. }
  1129. }