NIOSSL+GRPC.swift 5.0 KB

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