ServerTrustEvaluatorTests.swift 60 KB

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