@@ -20,7 +20,6 @@ import NIOSSL
20
20
/// the form of a `NIOSSLContextConfigurationOverride`, which will be used when performing a TLS handshake in NIO.
21
21
/// Each implementation can choose how to observe for changes, but they all require an ``sslContextConfigurationOverride``
22
22
/// to be exposed.
23
- @available ( macOS 11 . 0 , iOS 14 , tvOS 14 , watchOS 7 , * )
24
23
public protocol CertificateReloader : Sendable {
25
24
/// A `NIOSSLContextConfigurationOverride` that will be used as part of the NIO application's TLS configuration.
26
25
/// Its certificate and private key will be kept up-to-date via whatever mechanism the specific ``CertificateReloader``
@@ -29,10 +28,53 @@ public protocol CertificateReloader: Sendable {
29
28
}
30
29
31
30
extension TLSConfiguration {
31
+ /// Errors thrown when creating a ``NIOSSL/TLSConfiguration`` with a ``CertificateReloader``.
32
+ public struct CertificateReloaderError : Error {
33
+ private enum _Backing {
34
+ case missingCertificateChain
35
+ case missingPrivateKey
36
+ }
37
+
38
+ private let backing : _Backing
39
+
40
+ private init ( backing: _Backing ) {
41
+ self . backing = backing
42
+ }
43
+
44
+ /// The given ``CertificateReloader`` could not provide a certificate chain with which to create this config.
45
+ public static let missingCertificateChain : Self = . init( backing: . missingCertificateChain)
46
+
47
+ /// The given ``CertificateReloader`` could not provide a private key with which to create this config.
48
+ public static let missingPrivateKey : Self = . init( backing: . missingPrivateKey)
49
+ }
50
+
51
+ /// Create a ``NIOSSL/TLSConfiguration`` for use with server-side contexts, with certificate reloading enabled.
52
+ /// - Parameter certificateReloader: A ``CertificateReloader`` to watch for certificate and key pair updates.
53
+ /// - Returns: A ``NIOSSL/TLSConfiguration`` for use with server-side contexts, that reloads the certificate and key
54
+ /// used in its SSL handshake.
55
+ public static func makeServerConfiguration(
56
+ certificateReloader: some CertificateReloader
57
+ ) throws -> Self {
58
+ let override = certificateReloader. sslContextConfigurationOverride
59
+
60
+ guard let certificateChain = override. certificateChain else {
61
+ throw CertificateReloaderError . missingCertificateChain
62
+ }
63
+
64
+ guard let privateKey = override. privateKey else {
65
+ throw CertificateReloaderError . missingPrivateKey
66
+ }
67
+
68
+ var configuration = Self . makeServerConfiguration (
69
+ certificateChain: certificateChain,
70
+ privateKey: privateKey
71
+ )
72
+ return configuration. setCertificateReloader ( certificateReloader)
73
+ }
74
+
32
75
/// Configure a ``CertificateReloader`` to observe updates for the certificate and key pair used.
33
76
/// - Parameter reloader: A ``CertificateReloader`` to watch for certificate and key pair updates.
34
- /// - Returns: A `TLSConfiguration` that reloads the certificate and key used in its SSL handshake.
35
- @available ( macOS 11 . 0 , iOS 14 , tvOS 14 , watchOS 7 , * )
77
+ /// - Returns: A ``NIOSSL/TLSConfiguration`` that reloads the certificate and key used in its SSL handshake.
36
78
mutating public func setCertificateReloader( _ reloader: some CertificateReloader ) -> Self {
37
79
self . sslContextCallback = { _, promise in
38
80
promise. succeed ( reloader. sslContextConfigurationOverride)
0 commit comments