Config+TLS.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright 2024, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. extension HTTP2ServerTransport.Posix {
  17. /// The security configuration for this connection.
  18. public struct TransportSecurity: Sendable {
  19. package enum Wrapped: Sendable {
  20. case plaintext
  21. case tls(TLS)
  22. }
  23. package let wrapped: Wrapped
  24. /// This connection is plaintext: no encryption will take place.
  25. public static let plaintext = Self(wrapped: .plaintext)
  26. /// Secure connections with the given TLS configuration.
  27. public static func tls(_ tls: TLS) -> Self {
  28. Self(wrapped: .tls(tls))
  29. }
  30. /// Secure connections with TLS.
  31. ///
  32. /// - Parameters:
  33. /// - certificateChain: The certificates the server will offer during negotiation.
  34. /// - privateKey: The private key associated with the leaf certificate.
  35. /// - configure: A closure which allows you to modify the defaults before returning them.
  36. public static func tls(
  37. certificateChain: [TLSConfig.CertificateSource],
  38. privateKey: TLSConfig.PrivateKeySource,
  39. configure: (_ config: inout TLS) -> Void = { _ in }
  40. ) -> Self {
  41. let tlsConfig: TLS = .defaults(
  42. certificateChain: certificateChain,
  43. privateKey: privateKey,
  44. configure: configure
  45. )
  46. return .tls(tlsConfig)
  47. }
  48. /// Secure the connection with mutual TLS.
  49. ///
  50. /// - Parameters:
  51. /// - certificateChain: The certificates the client will offer during negotiation.
  52. /// - privateKey: The private key associated with the leaf certificate.
  53. /// - configure: A closure which allows you to modify the defaults before returning them.
  54. public static func mTLS(
  55. certificateChain: [TLSConfig.CertificateSource],
  56. privateKey: TLSConfig.PrivateKeySource,
  57. configure: (_ config: inout TLS) -> Void = { _ in }
  58. ) -> Self {
  59. let tlsConfig: TLS = .mTLS(
  60. certificateChain: certificateChain,
  61. privateKey: privateKey,
  62. configure: configure
  63. )
  64. return .tls(tlsConfig)
  65. }
  66. }
  67. }
  68. extension HTTP2ServerTransport.Posix.TransportSecurity {
  69. public struct TLS: Sendable {
  70. /// The certificates the server will offer during negotiation.
  71. public var certificateChain: [TLSConfig.CertificateSource]
  72. /// The private key associated with the leaf certificate.
  73. public var privateKey: TLSConfig.PrivateKeySource
  74. /// How to verify the client certificate, if one is presented.
  75. public var clientCertificateVerification: TLSConfig.CertificateVerification
  76. /// The trust roots to be used when verifying client certificates.
  77. public var trustRoots: TLSConfig.TrustRootsSource
  78. /// Whether ALPN is required.
  79. ///
  80. /// If this is set to `true` but the client does not support ALPN, then the connection will be rejected.
  81. public var requireALPN: Bool
  82. /// Create a new HTTP2 NIO Posix server transport TLS config.
  83. /// - Parameters:
  84. /// - certificateChain: The certificates the server will offer during negotiation.
  85. /// - privateKey: The private key associated with the leaf certificate.
  86. /// - clientCertificateVerification: How to verify the client certificate, if one is presented.
  87. /// - trustRoots: The trust roots to be used when verifying client certificates.
  88. /// - requireALPN: Whether ALPN is required.
  89. public init(
  90. certificateChain: [TLSConfig.CertificateSource],
  91. privateKey: TLSConfig.PrivateKeySource,
  92. clientCertificateVerification: TLSConfig.CertificateVerification,
  93. trustRoots: TLSConfig.TrustRootsSource,
  94. requireALPN: Bool
  95. ) {
  96. self.certificateChain = certificateChain
  97. self.privateKey = privateKey
  98. self.clientCertificateVerification = clientCertificateVerification
  99. self.trustRoots = trustRoots
  100. self.requireALPN = requireALPN
  101. }
  102. /// Create a new HTTP2 NIO Posix transport TLS config, with some values defaulted:
  103. /// - `clientCertificateVerificationMode` equals `doNotVerify`
  104. /// - `trustRoots` equals `systemDefault`
  105. /// - `requireALPN` equals `false`
  106. ///
  107. /// - Parameters:
  108. /// - certificateChain: The certificates the server will offer during negotiation.
  109. /// - privateKey: The private key associated with the leaf certificate.
  110. /// - configure: A closure which allows you to modify the defaults before returning them.
  111. /// - Returns: A new HTTP2 NIO Posix transport TLS config.
  112. public static func defaults(
  113. certificateChain: [TLSConfig.CertificateSource],
  114. privateKey: TLSConfig.PrivateKeySource,
  115. configure: (_ config: inout Self) -> Void = { _ in }
  116. ) -> Self {
  117. var config = Self(
  118. certificateChain: certificateChain,
  119. privateKey: privateKey,
  120. clientCertificateVerification: .noVerification,
  121. trustRoots: .systemDefault,
  122. requireALPN: false
  123. )
  124. configure(&config)
  125. return config
  126. }
  127. /// Create a new HTTP2 NIO Posix transport TLS config, with some values defaulted to match
  128. /// the requirements of mTLS:
  129. /// - `clientCertificateVerificationMode` equals `noHostnameVerification`
  130. /// - `trustRoots` equals `systemDefault`
  131. /// - `requireALPN` equals `false`
  132. ///
  133. /// - Parameters:
  134. /// - certificateChain: The certificates the server will offer during negotiation.
  135. /// - privateKey: The private key associated with the leaf certificate.
  136. /// - configure: A closure which allows you to modify the defaults before returning them.
  137. /// - Returns: A new HTTP2 NIO Posix transport TLS config.
  138. public static func mTLS(
  139. certificateChain: [TLSConfig.CertificateSource],
  140. privateKey: TLSConfig.PrivateKeySource,
  141. configure: (_ config: inout Self) -> Void = { _ in }
  142. ) -> Self {
  143. var config = Self(
  144. certificateChain: certificateChain,
  145. privateKey: privateKey,
  146. clientCertificateVerification: .noHostnameVerification,
  147. trustRoots: .systemDefault,
  148. requireALPN: false
  149. )
  150. configure(&config)
  151. return config
  152. }
  153. }
  154. }
  155. extension HTTP2ClientTransport.Posix {
  156. /// The security configuration for this connection.
  157. public struct TransportSecurity: Sendable {
  158. package enum Wrapped: Sendable {
  159. case plaintext
  160. case tls(TLS)
  161. }
  162. package let wrapped: Wrapped
  163. /// This connection is plaintext: no encryption will take place.
  164. public static let plaintext = Self(wrapped: .plaintext)
  165. /// Secure the connection with the given TLS configuration.
  166. public static func tls(_ tls: TLS) -> Self {
  167. Self(wrapped: .tls(tls))
  168. }
  169. /// Secure the connection with TLS using the default configuration.
  170. ///
  171. /// - Parameters:
  172. /// - configure: A closure which allows you to modify the defaults before returning them.
  173. public static func tls(
  174. configure: (_ config: inout TLS) -> Void = { _ in }
  175. ) -> Self {
  176. Self.tls(.defaults(configure: configure))
  177. }
  178. /// Secure the connection with TLS using the default configuration.
  179. public static var tls: Self {
  180. Self.tls(.defaults())
  181. }
  182. /// Secure the connection with mutual TLS.
  183. ///
  184. /// - Parameters:
  185. /// - certificateChain: The certificates the client will offer during negotiation.
  186. /// - privateKey: The private key associated with the leaf certificate.
  187. /// - configure: A closure which allows you to modify the defaults before returning them.
  188. public static func mTLS(
  189. certificateChain: [TLSConfig.CertificateSource],
  190. privateKey: TLSConfig.PrivateKeySource,
  191. configure: (_ config: inout TLS) -> Void = { _ in }
  192. ) -> Self {
  193. let tlsConfig: TLS = .mTLS(
  194. certificateChain: certificateChain,
  195. privateKey: privateKey,
  196. configure: configure
  197. )
  198. return .tls(tlsConfig)
  199. }
  200. }
  201. }
  202. extension HTTP2ClientTransport.Posix.TransportSecurity {
  203. public struct TLS: Sendable {
  204. /// The certificates the client will offer during negotiation.
  205. public var certificateChain: [TLSConfig.CertificateSource]
  206. /// The private key associated with the leaf certificate.
  207. public var privateKey: TLSConfig.PrivateKeySource?
  208. /// How to verify the server certificate, if one is presented.
  209. public var serverCertificateVerification: TLSConfig.CertificateVerification
  210. /// The trust roots to be used when verifying server certificates.
  211. public var trustRoots: TLSConfig.TrustRootsSource
  212. /// Create a new HTTP2 NIO Posix client transport TLS config.
  213. /// - Parameters:
  214. /// - certificateChain: The certificates the client will offer during negotiation.
  215. /// - privateKey: The private key associated with the leaf certificate.
  216. /// - serverCertificateVerification: How to verify the server certificate, if one is presented.
  217. /// - trustRoots: The trust roots to be used when verifying server certificates.
  218. public init(
  219. certificateChain: [TLSConfig.CertificateSource],
  220. privateKey: TLSConfig.PrivateKeySource?,
  221. serverCertificateVerification: TLSConfig.CertificateVerification,
  222. trustRoots: TLSConfig.TrustRootsSource
  223. ) {
  224. self.certificateChain = certificateChain
  225. self.privateKey = privateKey
  226. self.serverCertificateVerification = serverCertificateVerification
  227. self.trustRoots = trustRoots
  228. }
  229. /// Create a new HTTP2 NIO Posix transport TLS config, with some values defaulted:
  230. /// - `certificateChain` equals `[]`
  231. /// - `privateKey` equals `nil`
  232. /// - `serverCertificateVerification` equals `fullVerification`
  233. /// - `trustRoots` equals `systemDefault`
  234. ///
  235. /// - Parameters:
  236. /// - configure: A closure which allows you to modify the defaults before returning them.
  237. /// - Returns: A new HTTP2 NIO Posix transport TLS config.
  238. public static func defaults(
  239. configure: (_ config: inout Self) -> Void = { _ in }
  240. ) -> Self {
  241. var config = Self(
  242. certificateChain: [],
  243. privateKey: nil,
  244. serverCertificateVerification: .fullVerification,
  245. trustRoots: .systemDefault
  246. )
  247. configure(&config)
  248. return config
  249. }
  250. /// Create a new HTTP2 NIO Posix transport TLS config, with some values defaulted:
  251. /// - `certificateChain` equals `[]`
  252. /// - `privateKey` equals `nil`
  253. /// - `serverCertificateVerification` equals `fullVerification`
  254. /// - `trustRoots` equals `systemDefault`
  255. public static var defaults: Self { .defaults() }
  256. /// Create a new HTTP2 NIO Posix transport TLS config, with some values defaulted to match
  257. /// the requirements of mTLS:
  258. /// - `trustRoots` equals `systemDefault`
  259. /// - `serverCertificateVerification` equals `fullVerification`
  260. ///
  261. /// - Parameters:
  262. /// - certificateChain: The certificates the client will offer during negotiation.
  263. /// - privateKey: The private key associated with the leaf certificate.
  264. /// - configure: A closure which allows you to modify the defaults before returning them.
  265. /// - Returns: A new HTTP2 NIO Posix transport TLS config.
  266. public static func mTLS(
  267. certificateChain: [TLSConfig.CertificateSource],
  268. privateKey: TLSConfig.PrivateKeySource,
  269. configure: (_ config: inout Self) -> Void = { _ in }
  270. ) -> Self {
  271. var config = Self(
  272. certificateChain: certificateChain,
  273. privateKey: privateKey,
  274. serverCertificateVerification: .fullVerification,
  275. trustRoots: .systemDefault
  276. )
  277. configure(&config)
  278. return config
  279. }
  280. }
  281. }