NIOSSL+GRPC.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. #if canImport(NIOSSL)
  17. import NIOSSL
  18. extension NIOSSLSerializationFormats {
  19. fileprivate init(_ format: TLSConfig.SerializationFormat) {
  20. switch format.wrapped {
  21. case .pem:
  22. self = .pem
  23. case .der:
  24. self = .der
  25. }
  26. }
  27. }
  28. extension Sequence<TLSConfig.CertificateSource> {
  29. func sslCertificateSources() throws -> [NIOSSLCertificateSource] {
  30. var certificateSources: [NIOSSLCertificateSource] = []
  31. for source in self {
  32. switch source.wrapped {
  33. case .bytes(let bytes, let serializationFormat):
  34. switch serializationFormat.wrapped {
  35. case .der:
  36. certificateSources.append(
  37. .certificate(try NIOSSLCertificate(bytes: bytes, format: .der))
  38. )
  39. case .pem:
  40. let certificates = try NIOSSLCertificate.fromPEMBytes(bytes).map {
  41. NIOSSLCertificateSource.certificate($0)
  42. }
  43. certificateSources.append(contentsOf: certificates)
  44. }
  45. case .file(let path, let serializationFormat):
  46. switch serializationFormat.wrapped {
  47. case .der:
  48. certificateSources.append(
  49. .certificate(try NIOSSLCertificate(file: path, format: .der))
  50. )
  51. case .pem:
  52. let certificates = try NIOSSLCertificate.fromPEMFile(path).map {
  53. NIOSSLCertificateSource.certificate($0)
  54. }
  55. certificateSources.append(contentsOf: certificates)
  56. }
  57. }
  58. }
  59. return certificateSources
  60. }
  61. }
  62. extension NIOSSLPrivateKey {
  63. fileprivate convenience init(
  64. privateKey source: TLSConfig.PrivateKeySource
  65. ) throws {
  66. switch source.wrapped {
  67. case .file(let path, let serializationFormat):
  68. try self.init(
  69. file: path,
  70. format: NIOSSLSerializationFormats(serializationFormat)
  71. )
  72. case .bytes(let bytes, let serializationFormat):
  73. try self.init(
  74. bytes: bytes,
  75. format: NIOSSLSerializationFormats(serializationFormat)
  76. )
  77. }
  78. }
  79. }
  80. extension NIOSSLTrustRoots {
  81. fileprivate init(_ trustRoots: TLSConfig.TrustRootsSource) throws {
  82. switch trustRoots.wrapped {
  83. case .certificates(let certificateSources):
  84. let certificates = try certificateSources.map { source in
  85. switch source.wrapped {
  86. case .bytes(let bytes, let serializationFormat):
  87. return try NIOSSLCertificate(
  88. bytes: bytes,
  89. format: NIOSSLSerializationFormats(serializationFormat)
  90. )
  91. case .file(let path, let serializationFormat):
  92. return try NIOSSLCertificate(
  93. file: path,
  94. format: NIOSSLSerializationFormats(serializationFormat)
  95. )
  96. }
  97. }
  98. self = .certificates(certificates)
  99. case .systemDefault:
  100. self = .default
  101. }
  102. }
  103. }
  104. extension CertificateVerification {
  105. fileprivate init(
  106. _ verificationMode: TLSConfig.CertificateVerification
  107. ) {
  108. switch verificationMode.wrapped {
  109. case .doNotVerify:
  110. self = .none
  111. case .fullVerification:
  112. self = .fullVerification
  113. case .noHostnameVerification:
  114. self = .noHostnameVerification
  115. }
  116. }
  117. }
  118. extension TLSConfiguration {
  119. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  120. package init(_ tlsConfig: HTTP2ServerTransport.Posix.Config.TLS) throws {
  121. let certificateChain = try tlsConfig.certificateChain.sslCertificateSources()
  122. let privateKey = try NIOSSLPrivateKey(privateKey: tlsConfig.privateKey)
  123. self = TLSConfiguration.makeServerConfiguration(
  124. certificateChain: certificateChain,
  125. privateKey: .privateKey(privateKey)
  126. )
  127. self.minimumTLSVersion = .tlsv12
  128. self.certificateVerification = CertificateVerification(
  129. tlsConfig.clientCertificateVerification
  130. )
  131. self.trustRoots = try NIOSSLTrustRoots(tlsConfig.trustRoots)
  132. self.applicationProtocols = ["grpc-exp", "h2"]
  133. }
  134. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  135. package init(_ tlsConfig: HTTP2ClientTransport.Posix.Config.TLS) throws {
  136. self = TLSConfiguration.makeClientConfiguration()
  137. self.certificateChain = try tlsConfig.certificateChain.sslCertificateSources()
  138. if let privateKey = tlsConfig.privateKey {
  139. let privateKeySource = try NIOSSLPrivateKey(privateKey: privateKey)
  140. self.privateKey = .privateKey(privateKeySource)
  141. }
  142. self.minimumTLSVersion = .tlsv12
  143. self.certificateVerification = CertificateVerification(
  144. tlsConfig.serverCertificateVerification
  145. )
  146. self.trustRoots = try NIOSSLTrustRoots(tlsConfig.trustRoots)
  147. self.applicationProtocols = ["grpc-exp", "h2"]
  148. }
  149. }
  150. #endif