Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ let package = Package(
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0"),
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.0.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.30.0"),
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.0.0"),
],
targets: [
Expand Down
90 changes: 87 additions & 3 deletions Sources/HTTPServer/HTTPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,41 @@ public final class Server<RequestHandler: HTTPServerRequestHandler> {
logger: logger
)

case .tls(let certificateChain, let privateKey):
let http2Config = NIOHTTP2Handler.Configuration(
httpServerHTTP2Configuration: configuration.http2
)

let certificateChain = try certificateChain
.map {
try NIOSSLCertificate(
bytes: $0.serializeAsPEM().derBytes,
format: .der
)
}
.map { NIOSSLCertificateSource.certificate($0) }
let privateKey = NIOSSLPrivateKeySource.privateKey(
try NIOSSLPrivateKey(
bytes: privateKey.serializeAsPEM().derBytes,
format: .der
)
)

var tlsConfiguration: TLSConfiguration = .makeServerConfiguration(
certificateChain: certificateChain,
privateKey: privateKey
)
tlsConfiguration.applicationProtocols = ["h2", "http/1.1"]

try await Self.serveSecureUpgrade(
bindTarget: configuration.bindTarget,
tlsConfiguration: tlsConfiguration,
handler: handler,
asyncChannelConfiguration: asyncChannelConfiguration,
http2Configuration: http2Config,
logger: logger
)

case .reloadingTLS(let certificateReloader):
let http2Config = NIOHTTP2Handler.Configuration(
httpServerHTTP2Configuration: configuration.http2
Expand All @@ -193,7 +228,7 @@ public final class Server<RequestHandler: HTTPServerRequestHandler> {
logger: logger
)

case .staticTLS(let certificateChain, let privateKey):
case .mTLS(let certificateChain, let privateKey, let trustRoots):
let http2Config = NIOHTTP2Handler.Configuration(
httpServerHTTP2Configuration: configuration.http2
)
Expand All @@ -213,9 +248,58 @@ public final class Server<RequestHandler: HTTPServerRequestHandler> {
)
)

var tlsConfiguration: TLSConfiguration = .makeServerConfiguration(
let nioTrustRoots: NIOSSLTrustRoots
if let trustRoots {
nioTrustRoots = .certificates(
try trustRoots.map {
try NIOSSLCertificate(
bytes: $0.serializeAsPEM().derBytes,
format: .der
)
}
)
} else {
nioTrustRoots = .default
}

var tlsConfiguration: TLSConfiguration = .makeServerConfigurationWithMTLS(
certificateChain: certificateChain,
privateKey: privateKey
privateKey: privateKey,
trustRoots: nioTrustRoots
)
tlsConfiguration.applicationProtocols = ["h2", "http/1.1"]

try await Self.serveSecureUpgrade(
bindTarget: configuration.bindTarget,
tlsConfiguration: tlsConfiguration,
handler: handler,
asyncChannelConfiguration: asyncChannelConfiguration,
http2Configuration: http2Config,
logger: logger
)

case .reloadingMTLS(let certificateReloader, let trustRoots):
let http2Config = NIOHTTP2Handler.Configuration(
httpServerHTTP2Configuration: configuration.http2
)

let nioTrustRoots: NIOSSLTrustRoots
if let trustRoots {
nioTrustRoots = .certificates(
try trustRoots.map {
try NIOSSLCertificate(
bytes: $0.serializeAsPEM().derBytes,
format: .der
)
}
)
} else {
nioTrustRoots = .default
}

var tlsConfiguration: TLSConfiguration = try .makeServerConfigurationWithMTLS(
certificateReloader: certificateReloader,
trustRoots: nioTrustRoots
)
tlsConfiguration.applicationProtocols = ["h2", "http/1.1"]

Expand Down
38 changes: 35 additions & 3 deletions Sources/HTTPServer/HTTPServerConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,20 @@ public struct HTTPServerConfiguration: Sendable {
public struct TransportSecurity: Sendable {
enum Backing {
case plaintext
case staticTLS(
case tls(
certificateChain: [Certificate],
privateKey: Certificate.PrivateKey
)
case reloadingTLS(certificateReloader: any CertificateReloader)

case mTLS(
certificateChain: [Certificate],
privateKey: Certificate.PrivateKey,
trustRoots: [Certificate]?
)
case reloadingMTLS(
certificateReloader: any CertificateReloader,
trustRoots: [Certificate]?
)
}

let backing: Backing
Expand All @@ -59,7 +67,7 @@ public struct HTTPServerConfiguration: Sendable {
privateKey: Certificate.PrivateKey
) -> Self {
Self(
backing: .staticTLS(
backing: .tls(
certificateChain: certificateChain,
privateKey: privateKey
)
Expand All @@ -69,6 +77,30 @@ public struct HTTPServerConfiguration: Sendable {
public static func tls(certificateReloader: any CertificateReloader) throws -> Self {
Self(backing: .reloadingTLS(certificateReloader: certificateReloader))
}

public static func mTLS(
certificateChain: [Certificate],
privateKey: Certificate.PrivateKey,
trustRoots: [Certificate]?
) -> Self {
Self(
backing: .mTLS(
certificateChain: certificateChain,
privateKey: privateKey,
trustRoots: trustRoots
)
)
}

public static func mTLS(
certificateReloader: any CertificateReloader,
trustRoots: [Certificate]?
) throws -> Self {
Self(backing: .reloadingMTLS(
certificateReloader: certificateReloader,
trustRoots: trustRoots
))
}
}

/// HTTP/2 specific configuration.
Expand Down
Loading