ServerTrustEvaluatorTests.swift 60 KB

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