ServerTrustEvaluatorTests.swift 59 KB

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