NIOSSL+GRPC.swift 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. package init(_ tlsConfig: HTTP2ServerTransport.Posix.Config.TLS) throws {
  120. let certificateChain = try tlsConfig.certificateChain.sslCertificateSources()
  121. let privateKey = try NIOSSLPrivateKey(privateKey: tlsConfig.privateKey)
  122. self = TLSConfiguration.makeServerConfiguration(
  123. certificateChain: certificateChain,
  124. privateKey: .privateKey(privateKey)
  125. )
  126. self.minimumTLSVersion = .tlsv12
  127. self.certificateVerification = CertificateVerification(
  128. tlsConfig.clientCertificateVerification
  129. )
  130. self.trustRoots = try NIOSSLTrustRoots(tlsConfig.trustRoots)
  131. self.applicationProtocols = ["grpc-exp", "h2"]
  132. }
  133. package init(_ tlsConfig: HTTP2ClientTransport.Posix.Config.TLS) throws {
  134. self = TLSConfiguration.makeClientConfiguration()
  135. self.certificateChain = try tlsConfig.certificateChain.sslCertificateSources()
  136. if let privateKey = tlsConfig.privateKey {
  137. let privateKeySource = try NIOSSLPrivateKey(privateKey: privateKey)
  138. self.privateKey = .privateKey(privateKeySource)
  139. }
  140. self.minimumTLSVersion = .tlsv12
  141. self.certificateVerification = CertificateVerification(
  142. tlsConfig.serverCertificateVerification
  143. )
  144. self.trustRoots = try NIOSSLTrustRoots(tlsConfig.trustRoots)
  145. self.applicationProtocols = ["grpc-exp", "h2"]
  146. }
  147. }
  148. #endif